Ana içeriğe geç

Bölüm 2: Hello'yu nf-core için yeniden yazma

Yapay zeka destekli çeviri - daha fazla bilgi ve iyileştirme önerileri

Bu Hello nf-core eğitim kursunun ikinci bölümünde, Hello Nextflow başlangıç kursu tarafından üretilen pipeline'ın nf-core uyumlu bir versiyonunu nasıl oluşturacağınızı gösteriyoruz.

Bunu iki aşamada gerçekleştireceğiz: önce nf-core araçlarını kullanarak bir pipeline iskeleti oluşturacağız, ardından mevcut 'normal' pipeline kodunu bu iskelet üzerine aşılayacağız.

Eğer Hello pipeline'ına aşina değilseniz veya hatırlatmaya ihtiyacınız varsa, bu bilgi sayfasına bakın.

İpucu

Kursun bu bölümü, Hello Nextflow giriş kursunda ele alınmayan iki önemli Nextflow mekanizmasını tanıtacaktır: meta maps ve workflows of workflows. Her ikisi de bağlantılı Side Quest'lerde ayrıntılı olarak ele alınmaktadır.

Aşağıdaki talimatlar, bu mekanizmaların nf-core bağlamında nasıl kullanıldığını anlamanız için gereken temel bilgileri içermektedir; ancak bunların hepsini bir anda kavramak biraz fazla gelebilir. Zamanınız varsa, önce iki Side Quest'i tamamlamanızı öneririz (herhangi bir sırayla):

Not

Terminalinizde hello-nf-core dizininde olduğunuzdan emin olun.


1. Pipeline kod yapısını inceleme

nf-core projesi, pipeline'ların nasıl yapılandırılacağı, kodun nasıl organize edileceği, yapılandırılacağı ve belgeleneceği konusunda güçlü yönergeler uygular.

Pipeline oluşturma projemize başlamadan önce bu yapıyı ve organizasyonu anlamamız gerekiyor. O halde, Bölüm 1'de oluşturduğumuz pipelines sembolik bağlantısını kullanarak nf-core/demo repository'sindeki pipeline kodunun nasıl organize edildiğine bir göz atalım.

Hatırlatma olarak, nf-core/demo dizinini bulmak ve açmak için tree komutunu ya da dosya gezginini kullanabilirsiniz.

tree -L 1 pipelines/nf-core/demo
Dizin içeriği
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

Şimdilik özellikle pipeline kod bileşenlerine (main.nf, workflows, subworkflows, modules) ve bunların birbirleriyle nasıl ilişkili olduğuna odaklanacağız.

1.1. nf-core iş akışlarının modüler yapısı

Standart nf-core pipeline kod organizasyonu, Hello Nextflow kursunun 4. Bölümü olan Hello Modules'da 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ı subworkflow'ları yoğun biçimde kullanır; yani bir üst iş akışı tarafından içe aktarılan iş akışı betiklerini.

Bu biraz soyut gelebilir, o yüzden nf-core/demo pipeline'ında bunun pratikte nasıl kullanıldığına bakalım.

main.nf dosyasının içine bakarsanız, workflows/demo.nf'den DEMO adlı bir iş akışını ve bazı modüller ile subworkflow'ları içe aktardığını göreceksiniz.

İlgili kod bileşenleri arasındaki ilişkiler şöyle görünmektedir:

subworkflows/workflows/demo.nffastqc/main.nfmultiqc/main.nfseqtk/trim/main.nfmain.nfincludeincludemodules/nf-core/local/utils_nfcore_demo_pipeline/main.nfnf-core/utils_*/main.nf

main.nf içindeki adsız iş akışına giriş noktası betiği denir. Bu betik, iki tür iç içe iş akışı için bir sarmalayıcı görevi görür: workflows/demo.nf içinde yer alan ve gerçek analiz mantığını içeren DEMO iş akışı ve subworkflows/ altında bulunan bir dizi yardımcı iş akışı. demo.nf iş akışı, modules/ altındaki modülleri çağırır; bu modüller, gerçek analiz adımlarını gerçekleştirecek süreçleri içerir.

Not

Subworkflow'lar yalnızca yardımcı işlevlerle sınırlı değildir ve süreç modüllerini kullanabilirler.

Burada gösterilen nf-core/demo pipeline'ı spektrumun daha basit tarafında yer almaktadır; ancak diğer nf-core pipeline'ları (örneğin nf-core/rnaseq) gerçek analizde yer alan subworkflow'ları kullanır.

Şimdi bu bileşenleri ayrıntılı olarak inceleyelim.

1.2. Giriş noktası betiği: main.nf

main.nf betiği, nextflow run nf-core/demo komutunu ç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 main.nf betiğini otomatik olarak bulup çalıştırdığı anlamına gelir. Bu, yalnızca nf-core pipeline'ları için değil, bu geleneksel adlandırma ve yapıyı izleyen herhangi bir Nextflow pipeline'ı için geçerlidir.

Bir giriş noktası betiği kullanmak, gerçek analiz betiği çalıştırılmadan önce ve sonra standart 'yardımcı' subworkflow'ların kolayca çalıştırılmasını sağlar. Gerçek analiz iş akışını ve modüllerini inceledikten sonra bunları ele alacağız.

1.3. Analiz betiği: workflows/demo.nf

workflows/demo.nf iş akışı, pipeline'ın merkezi mantığının saklandığı yerdir. Normal bir Nextflow iş akışına çok benzer şekilde yapılandırılmıştır; ancak bir üst iş akışından çağrılmak üzere tasarlanmıştır ve bu da birkaç ek özellik gerektirir. Bu kursta, basit Hello pipeline'ını Hello Nextflow'dan nf-core uyumlu bir forma dönüştürme işlemini ele aldığımızda ilgili farklılıkları ele alacağız.

demo.nf iş akışı, modules/ altındaki modülleri çağırır; bunları bir sonraki adımda inceleyeceğiz.

Not

Bazı nf-core analiz iş akışları, alt düzey subworkflow'ları çağırarak ek iç içe geçme seviyeleri gösterir. Bu, genellikle birlikte sıkça 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 göz atarak bazı örnekleri görebilirsiniz.

Analiz betiği subworkflow'lar kullandığında, bunlar subworkflows/ dizini altında saklanır.

1.4. Modüller

Modüller, Hello Nextflow eğitim kursunun 4. Bölümünde açıklandığı gibi, süreç kodunun bulunduğu yerdir.

nf-core projesinde modüller, hem kökenlerini hem de içeriklerini yansıtan çok düzeyli iç içe bir yapı kullanılarak organize edilir. En üst düzeyde modüller, nf-core veya local (nf-core projesinin parçası olmayan) olarak ayrılır ve ardından sardıkları araç(lar)ın adını taşıyan bir dizine yerleştirilir. Araç bir araç takımına aitse (yani birden fazla araç içeren bir pakete), araç takımının adını taşıyan ara bir dizin düzeyi bulunur.

Bunu nf-core/demo pipeline modüllerine uygulanmış halde görebilirsiniz:

tree -L 3 pipelines/nf-core/demo/modules
Dizin içeriği
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ülleri içinde en üst düzeyde yer aldığını, trim modülünün ise ait olduğu araç takımı olan seqtk altında bulunduğunu görüyorsunuz. Bu durumda local modül bulunmamaktadır.

Süreci tanımlayan modül kod dosyası her zaman main.nf olarak adlandırılır ve şimdilik görmezden geleceğimiz testler ile .yml dosyaları ile birlikte gelir.

Giriş noktası iş akışı, analiz iş akışı ve modüller bir arada, pipeline'ın 'ilginç' kısımlarını çalıştırmak için yeterlidir. Ancak içinde yardımcı subworkflow'ların da bulunduğunu biliyoruz, o halde şimdi bunlara bakalım.

1.5. Yardımcı 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ıyla birlikte kendi iç içe dizin yapısı vardır.

tree -L 3 pipelines/nf-core/demo/subworkflows
Dizin içeriği
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'ı analize özgü herhangi bir subworkflow içermez; bu nedenle burada gördüğümüz tüm subworkflow'lar, adlarındaki utils_ önekiyle belirtilen 'yardımcı' veya 'araç' iş akışlarıdır. Bu subworkflow'lar, diğer yardımcı işlevlerin yanı sıra konsol çıktısındaki şık nf-core başlığını üreten yapılardır.

İpucu

Adlandırma kalıplarının yanı sıra, bu subworkflow'ların gerçek anlamda analize ilişkin bir işlev yerine getirmediğinin bir başka göstergesi, hiçbir süreci çağırmamasıdır.

Bu, nf-core/demo pipeline'ını oluşturan temel kod bileşenlerinin incelemesini tamamlar.

Özetle

Artık nf-core pipeline'larının modüler yapısı hakkında üst düzey bir anlayışa sahipsiniz.

Sırada ne var?

nf-core araçlarını kullanarak bir pipeline iskeleti oluşturun.


2. Yeni bir pipeline projesi oluşturma

Gördüğünüz gibi, nf-core pipeline'ları çok sayıda yardımcı dosya ile standartlaştırılmış bir yapıyı takip eder. 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.

2.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.

nf-core pipelines create

Bu komutu çalıştırmak, pipeline oluşturma için bir Metin Kullanıcı Arayüzü (TUI) açacaktır:

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 featureskapalı 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.

Komut çıktısı
                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 3.5.2 - 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.

tree core-hello
Dizin içeriği
core-hello/
├── README.md
├── assets
│   ├── samplesheet.csv
│   └── schema_input.json
├── conf
│   ├── base.config
│   ├── modules.config
│   ├── test.config
│   └── test_full.config
├── docs
│   ├── README.md
│   ├── output.md
│   └── usage.md
├── main.nf
├── modules.json
├── nextflow.config
├── nextflow_schema.json
├── 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

15 directories, 34 files

Bu çok fazla dosya! Biraz kaybolmuş hissediyorsanız endişelenmeyin; önemli kısımları kısa süre içinde ve ardından kursun geri kalanında adım adım birlikte inceleyeceğiz.

Genel olarak bu, nf-core/demo pipeline'ı için gözlemlediğimiz kod yapısına benzer görünmeli; tek fark burada modules dizininin olmamasıdır.

2.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.

nextflow run ./core-hello -profile docker,test --outdir core-hello-results
Komut çıktısı
N E X T F L O W   ~  version 25.10.4

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:

tree core-hello-results
Dizin içeriği
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; cevap şu: hiçbir şey!

boş yürütme zaman çizelgesi raporu

Kutunun içinde gerçekte ne olduğuna daha yakından bakalım.

2.3. İskelet yapısını inceleme

nf-core/demo pipeline'ının yapısını hatırlıyorsanız, DEMO iş akışını saran bir giriş noktası iş akışı içeren bir main.nf dosyası vardı. Şimdi yeni oluşturduğunuz projedeki main.nf dosyasını açarsanız, workflows/hello.nf'den HELLO adlı bir iş akışını içe aktardığını göreceksiniz. Bu, DEMO iş akışının doğrudan eşdeğeridir; ancak şu an için yalnızca bir yer tutucudur.

Buna göre, pipeline iskeletinin genel yapısı şöyle görünmektedir:

subworkflows/workflows/hello.nfmain.nfincludelocal/utils_nfcore_demo_pipeline/main.nfnf-core/utils_*/main.nf

Bu size nf-core/demo pipeline yapısını hatırlatmalı! Tek gerçek fark, DEMO iş akışının modüllerden süreçler içermesiydi. Burada ise eşdeğer HELLO iş akışı henüz herhangi bir süreç içermiyor.

Daha yakından bakalım.

2.4. Yer tutucu iş akışını inceleme

Bu, bazı nf-core işlevleri zaten yerinde olan analiz iş akışımız için yer tutucu olarak hizmet eder.

core-hello/workflows/hello.nf
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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 // kanal: --input parametresinden okunan samplesheet
    main:

    ch_versions = channel.empty()

    //
    // Yazılım sürümlerini derle ve kaydet
    //
    def topic_versions = Channel.topic("versions")
        .distinct()
        .branch { entry ->
            versions_file: entry instanceof Path
            versions_tuple: true
        }

    def topic_versions_string = topic_versions.versions_tuple
        .map { process, tool, version ->
            [ process[process.lastIndexOf(':')+1..-1], "  ${tool}: ${version}" ]
        }
        .groupTuple(by:0)
        .map { process, tool_versions ->
            tool_versions.unique().sort()
            "${process}:\n${tool_versions.join('\n')}"
        }

    softwareVersionsToYAML(ch_versions.mix(topic_versions.versions_file))
        .mix(topic_versions_string)
        .collectFile(
            storeDir: "${params.outdir}/pipeline_info",
            name:  'hello_software_'  + 'versions.yml',
            sort: true,
            newLine: true
        ).set { ch_collated_versions }


    emit:
    versions       = ch_versions                 // kanal: [ path(versions.yml) ]

}

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    THE END
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

Hello Nextflow'da geliştirilen temel bir Nextflow iş akışına kıyasla, burada yeni olan birkaç şey fark edeceksiniz (yukarıdaki vurgulanan satırlar):

  • İş akışı bloğunun bir adı var
  • İş akışı girdileri take: anahtar kelimesi kullanılarak bildirilir ve kanal oluşturma üst iş akışına taşınır
  • İş akışı içeriği bir main: bloğunun içine yerleştirilir
  • Çıktılar emit: anahtar kelimesi kullanılarak bildirilir

Bunlar, iş akışını birleştirilebilir yapan Nextflow'un isteğe bağlı özellikleridir; yani başka bir iş akışı içinden çağrılabilir.

Channel.topic bloğu
  1. satırdan başlayan def topic_versions = Channel.topic("versions") bloğunu fark etmiş olabilirsiniz. Bu, tüm modüllerden yazılım sürümü bilgilerini otomatik olarak toplayan standart bir temizlik kodudur. nf-core bu mekanizmayı 2026 yılında tüm pipeline'lara yaygınlaştırmaktadır; dolayısıyla ilerleyen süreçte tüm yeni pipeline'larda bunu göreceksiniz. Bu kursun 4. Bölümü nasıl çalıştığını ayrıntılı olarak açıklamaktadır.

İlgilendiğimiz iş akışından ilgili mantığı bu yapıya eklememiz gerekecek.

Özetle

Artık nf-core araçlarını kullanarak bir pipeline iskeleti oluşturmayı ve bunu demo pipeline yapısıyla karşılaştırmayı biliyorsunuz.

Sırada ne var?

Basit bir iş akışını nf-core uyumlu hale getirmenin bir ön adımı olarak nasıl birleştirilebilir yapacağınızı öğrenin.


3. Birleştirilebilir bir Hello Nextflow iş akışı oluşturma

Şimdi iş akışımızı nf-core iskeletine entegre etmek için çalışma zamanı.

Hatırlatma olarak, Hello Nextflow eğitim kursumuzdaki iş akışı ile çalışıyoruz. Bu iş akışı, kendi başına çalıştırılabilen basit bir adsız iş akışı olarak yazılmıştır.

Orijinal iş akışının hangi parçalarının nf-core iskeletinde nereye gideceğini net bir şekilde belirleyebilmek için, nf-core şablonunun gerektirdiği gibi bir üst iş akışı içinden çalıştırılabilecek birleştirilebilir bir iş akışına dönüştürerek başlayacağız.

Şu an oluşturmaya çalıştığımız şey budur:

hello.nfsayHello.nfconvertToUpper.nfcollectGreetings.nfcowpy.nfmain.nfincludeincludemodules/

Temelde, nf-core iskeletinin modüler yapısını taklit etmek istiyoruz; ancak başlangıçta daha az karmaşıklıkla.

Size, tamamlanmış Hello Nextflow iş akışının 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.

tree original-hello/
Dizin içeriği
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:

nextflow run original-hello/hello.nf
Komut çıktısı
N E X T F L O W   ~  version 25.10.4

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 ✔

Bu sizin için çalışıyorsa, kodu incelemeye hazırsınız.

3.1. Orijinal Hello iş akışını değiştirme

Kodu incelemek için hello.nf iş akışı dosyasını açalım; aşağıda tam olarak gösterilmiştir (modüller içinde olan süreçler sayılmaz):

original-hello/hello.nf
#!/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 iş akışı kendi başına çalıştırılabilen basit bir adsız iş akışı olarak yazılmıştır. Bunu birleştirilebilir yapmak için aşağıdaki değişiklikleri yapacağız:

  1. İş akışına ad verme
  2. Kanal oluşturmayı take: ile değiştirme
  3. İş akışı işlemlerinin önüne main: ifadesi ekleme
  4. emit: ifadesi ekleme

Gerekli değişiklikleri tek tek inceleyelim.

3.1.1. İş akışına ad verme

İlk olarak, iş akışına bir üst iş akışından ona başvurabilmek için bir ad verelim.

original-hello/hello.nf
workflow HELLO {
original-hello/hello.nf
workflow {

İş akışı adları için modül adlarında olduğu gibi aynı kurallar geçerlidir.

3.1.2. Kanal oluşturmayı take ile değiştirme

Şimdi, kanal oluşturmayı beklenen girdileri bildiren basit bir take ifadesi ile değiştirin.

original-hello/hello.nf
    take:
    // channel of greetings
    greeting_ch
original-hello/hello.nf
    // 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 iş akışına bırakır.

Bu arada, params.greeting = 'greetings.csv' satırını da yorum satırı yapabiliriz:

original-hello/hello.nf
3
4
5
6
7
8
    /*
    * Pipeline parametreleri
    */
    //params.greeting = 'greetings.csv'
    params.batch = 'test-batch'
    params.character = 'turkey'
original-hello/hello.nf
3
4
5
6
7
8
    /*
    * Pipeline parametreleri
    */
    params.greeting = 'greetings.csv'
    params.batch = 'test-batch'
    params.character = 'turkey'

Not

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.

3.1.3. İş akışı işlemlerinin önüne main ifadesi ekleme

Ardından, iş akışı gövdesinde çağrılan işlemlerin geri kalanından önce bir main ifadesi ekleyin.

original-hello/hello.nf
    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)
original-hello/hello.nf
    // 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 iş akışının yaptığı budur' der.

3.1.4. emit ifadesi ekleme

Son olarak, iş akışının son çıktılarının ne olduğunu bildiren bir emit ifadesi ekleyin.

original-hello/hello.nf
    emit:
    cowpy_hellos = cowpy.out

Bu, orijinal iş akışına kıyasla koda tamamen yeni bir eklentidir.

3.1.5. Tamamlanan değişikliklerin özeti

Tüm değişiklikleri açıklandığı gibi yaptıysanız, iş akışınız şimdi şöyle görünmelidir:

original-hello/hello.nf
#!/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ı iş akışı olarak da adlandırılan üst iş akışında tanımlanacaktır.

3.2. Kukla bir giriş noktası iş akışı yapma

Birleştirilebilir iş akışımızı karmaşık nf-core iskeletine entegre etmeden önce, doğru çalıştığını doğrulayalım. Birleştirilebilir iş akışını izole bir şekilde test etmek için basit bir kukla giriş noktası iş akışı yapabiliriz.

Aynı original-hello dizininde main.nf adında boş bir dosya oluşturun.

touch original-hello/main.nf

Aşağıdaki kodu main.nf dosyasına kopyalayın.

original-hello/main.nf
#!/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 iş akışını çağırma sözdizimi, modülleri çağırma sözdizimi ile esasen aynıdır.
  • Girdileri iş akışına çekmeyle ilgili her şey (girdi parametresi ve kanal oluşturma) artık bu üst iş akışında bildirilir.

Not

Giriş noktası iş akışı dosyasını main.nf olarak adlandırmak bir kural, bir gereklilik değildir.

Bu kurala uyarsanız, nextflow run komutunuzda iş akışı dosya adını belirtmeyi atlayabilirsiniz. Nextflow, yürütme dizininde main.nf adlı bir dosyayı otomatik olarak arayacaktır.

Ancak, isterseniz giriş noktası iş akışı dosyasını başka bir şey olarak adlandırabilirsiniz. Bu durumda, nextflow run komutunuzda iş akışı dosya adını belirttiğinizden emin olun.

3.3. İş akışının çalıştığını test etme

Sonunda birleştirilebilir iş akışının çalıştığını doğrulamak için ihtiyacımız olan tüm parçalara sahibiz. Hadi çalıştıralım!

nextflow run ./original-hello

Burada main.nf adlandırma kuralını kullanmanın avantajını görüyorsunuz. Giriş noktası iş akışını 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.

Komut çıktısı
N E X T F L O W   ~  version 25.10.4

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 iş akışımızı başarıyla birleştirilebilir hale getirdiğimiz anlamına gelir.

Özetle

Bir iş akışını adlandırarak ve take, main ve emit ifadeleri ekleyerek nasıl birleştirilebilir yapacağınızı ve bir giriş noktası iş akışından nasıl çağıracağınızı biliyorsunuz.

Sırada ne var?

Temel bir birleştirilebilir iş akışını nf-core iskeletine nasıl aşılayacağınızı öğrenin.


4. Güncellenmiş iş akışı mantığını yer tutucu iş akışına uydurma

Artık birleştirilebilir iş akışımızın doğru çalıştığını doğruladığımıza göre, 1. bölümde oluşturduğumuz nf-core pipeline iskeletine geri dönelim. Az önce geliştirdiğimiz birleştirilebilir iş akışını nf-core şablon yapısına entegre etmek istiyoruz; böylece sonuç şuna benzer bir şey olmalıdır.

subworkflows/workflows/hello.nfmain.nfincludeincludemodules/local/local/utils_nfcore_demo_pipeline/main.nfnf-core/utils_*/main.nfsayHello.nfconvertToUpper.nfcollectGreetings.nfcowpy.nf

Peki bunu nasıl gerçekleştiririz? core-hello/workflows/hello.nf içindeki (nf-core iskeleti) HELLO iş akışının mevcut içeriğine bir göz atalım.

core-hello/workflows/hello.nf
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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 // kanal: --input parametresinden okunan samplesheet
    main:

    ch_versions = channel.empty()

    //
    // Yazılım sürümlerini derle ve kaydet
    //
    def topic_versions = Channel.topic("versions")
        .distinct()
        .branch { entry ->
            versions_file: entry instanceof Path
            versions_tuple: true
        }

    def topic_versions_string = topic_versions.versions_tuple
        .map { process, tool, version ->
            [ process[process.lastIndexOf(':')+1..-1], "  ${tool}: ${version}" ]
        }
        .groupTuple(by:0)
        .map { process, tool_versions ->
            tool_versions.unique().sort()
            "${process}:\n${tool_versions.join('\n')}"
        }

    softwareVersionsToYAML(ch_versions.mix(topic_versions.versions_file))
        .mix(topic_versions_string)
        .collectFile(
            storeDir: "${params.outdir}/pipeline_info",
            name:  'hello_software_'  + 'versions.yml',
            sort: true,
            newLine: true
        ).set { ch_collated_versions }


    emit:
    versions       = ch_versions                 // kanal: [ path(versions.yml) ]

}

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    THE END
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

Vurgulanan satırlar birleştirilebilir iş akışı yapısını tanımlar: workflow HELLO {, take:, main: ve emit:. 17–34. satırlar arasındaki büyük blok daha önemlidir: nf-core'un 2026 yılında tüm pipeline'lara yaygınlaştırdığı bir mekanizma olan topic kanallarını kullanarak yazılım sürümü yakalamayı yönetir. Bunu 4. Bölümde açıklayacağız; şimdilik dokunmadan bırakabileceğiniz standart bir şablon kodu olarak değerlendirin.

  1. bölümde geliştirdiğimiz orijinal iş akışının 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. İş akışı mantığını main bloğuna ekleme
  4. emit bloğunu güncelleme

Not

Bu ilk geçiş için versiyon yakalama bloğunu görmezden geliyoruz. 4. Bölüm nasıl çalıştığını açıklamaktadır.

4.1. Modülleri kopyalama ve modül import'larını kurma

Hello Nextflow iş akışımızdaki dört süreç, 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 iş akışı dosyasına import ifadeleri eklememiz gerekiyor.

İlk olarak modül dosyalarını original-hello/'dan core-hello/'ya kopyalayalım:

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.

tree core-hello/modules
Dizin içeriği
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 iş akışındaki import ifadeleriydi:

original-hello/hello.nf
// 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.

core-hello/workflows/hello.nf
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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'
core-hello/workflows/hello.nf
1
2
3
4
5
6
7
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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.

4.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.

core-hello/workflows/hello.nf
    take:
    ch_samplesheet // kanal: --input parametresinden okunan samplesheet

Girdi işleme bu iş akışının yukarısında yapılacaktır (bu kod dosyasında değil).

4.3. İş akışı mantığını main bloğuna ekleme

Şimdi modüllerimiz iş akışına açık olduğuna göre, iş akışı mantığını main bloğuna ekleyebiliriz.

Hatırlatma olarak, orijinal iş akışındaki ilgili kod şudur; birleştirilebilir yaptığımızda pek değişmedi (sadece main: satırını ekledik):

original-hello/hello.nf
    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 iş akışının yeni versiyonuna kopyalamamız gerekiyor.

Orada zaten iş akışı 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 iş akışı mantığımızı ekleyeceğiz; versiyon harmanlama kodunu sonda tutacağız. Bu sıralama mantıklıdır çünkü gerçek bir pipeline'da, süreçler iş akışı çalışırken ch_versions kanalına eklenecek sürüm bilgisi yayar.

core-hello/workflows/hello.nf
workflow HELLO {

    take:
    ch_samplesheet // kanal: --input parametresinden okunan samplesheet

    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
    //
    def topic_versions = Channel.topic("versions")
        .distinct()
        .branch { entry ->
            versions_file: entry instanceof Path
            versions_tuple: true
        }

    def topic_versions_string = topic_versions.versions_tuple
        .map { process, tool, version ->
            [ process[process.lastIndexOf(':')+1..-1], "  ${tool}: ${version}" ]
        }
        .groupTuple(by:0)
        .map { process, tool_versions ->
            tool_versions.unique().sort()
            "${process}:\n${tool_versions.join('\n')}"
        }

    softwareVersionsToYAML(ch_versions.mix(topic_versions.versions_file))
        .mix(topic_versions_string)
        .collectFile(
            storeDir: "${params.outdir}/pipeline_info",
            name:  'hello_software_'  + 'versions.yml',
            sort: true,
            newLine: true
        ).set { ch_collated_versions }


    emit:
    versions       = ch_versions                 // kanal: [ path(versions.yml) ]

}
core-hello/workflows/hello.nf
workflow HELLO {

    take:
    ch_samplesheet // kanal: --input parametresinden okunan samplesheet
    main:

    ch_versions = channel.empty()

    //
    // Collate and save software versions
    //
    def topic_versions = Channel.topic("versions")
        .distinct()
        .branch { entry ->
            versions_file: entry instanceof Path
            versions_tuple: true
        }

    def topic_versions_string = topic_versions.versions_tuple
        .map { process, tool, version ->
            [ process[process.lastIndexOf(':')+1..-1], "  ${tool}: ${version}" ]
        }
        .groupTuple(by:0)
        .map { process, tool_versions ->
            tool_versions.unique().sort()
            "${process}:\n${tool_versions.join('\n')}"
        }

    softwareVersionsToYAML(ch_versions.mix(topic_versions.versions_file))
        .mix(topic_versions_string)
        .collectFile(
            storeDir: "${params.outdir}/pipeline_info",
            name:  'hello_software_'  + 'versions.yml',
            sort: true,
            newLine: true
        ).set { ch_collated_versions }


    emit:
    versions       = ch_versions                 // kanal: [ 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() sürecine 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.

core-hello/workflows/hello.nf
    // bir selamlama yayınla (samplesheet'ler için nf-core kuralını kullanacak şekilde güncellendi)
    sayHello(ch_samplesheet)
core-hello/workflows/hello.nf
    // bir selamlama yayınla
    sayHello(greeting_ch)

Şimdi iş akışı mantığı doğru şekilde bağlandı.

4.4. emit bloğunu güncelleme

Son olarak, iş akışının son çıktılarının bildirimini içerecek şekilde emit bloğunu güncellememiz gerekiyor.

core-hello/workflows/hello.nf
    emit:
    cowpy_hellos   = cowpy.out
    versions       = ch_versions                 // kanal: [ path(versions.yml) ]
core-hello/workflows/hello.nf
    emit:
    versions       = ch_versions                 // kanal: [ path(versions.yml) ]

Bu, HELLO iş akışının kendisinde yapmamız gereken değişiklikleri tamamlar. Bu noktada, uygulamaya koymayı amaçladığımız genel kod yapısına ulaştık.

Özetle

Birleştirilebilir bir iş akışının temel parçalarını bir nf-core yer tutucu iş akışına 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.


5. Girdi işlemeyi uyarlama

Artık iş akışı 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.

5.1. Girdilerin nerede işlendiğini belirleme

İlk adım, girdi işlemenin nerede yapıldığını bulmaktır.

Hello Nextflow iş akışını birleştirilebilir olacak şekilde yeniden yazdığımızda, girdi parametresi bildirimini bir seviye yukarı, main.nf giriş noktası iş akışına taşıdığımızı hatırlayabilirsiniz. O halde, pipeline iskeleti kapsamında oluşturulan üst düzey main.nf giriş noktası iş akışına bir göz atalım:

core-hello/main.nf
#!/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 // kanal: --input parametresinden okunan samplesheet

    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,
        params.help,
        params.help_full,
        params.show_hidden
    )

    //
    // 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 iş akışı tanımlanmıştır:

  • CORE_HELLO, core-hello/workflows/hello.nf içinde az önce uyarlamayı bitirdiğimiz HELLO iş akışını ç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 iş akışı.

İşte birbirleriyle nasıl ilişkili olduklarının bir diyagramı:

PIPELINE_INITIALISATIONPIPELINE_COMPLETIONCORE_HELLO { HELLO}samplesheetdata filesoutput filespipeline reportsunnamed workflow in main.nf

Ö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:

core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf
    //
    // params.input aracılığıyla sağlanan girdi dosyasından kanal oluştur
    //

    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 iş akışı tarafından tüketilmeye hazır bir biçimde ileten kanal fabrikasıdır.

Not

Yukarıdaki sözdizimi daha önce kullandığımızdan biraz farklı, ancak temelde bu:

channel.<...>.set { ch_samplesheet }

şuna eşdeğerdir:

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.

5.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 iş akışında 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):

solutions/composable-hello/main.nf
    // 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 iş akışına 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).

core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf
    //
    // params.input aracılığıyla sağlanan girdi dosyasından kanal oluştur
    //

    ch_samplesheet = channel.fromPath(params.input)
        .splitCsv()
        .map { line -> line[0] }

    emit:
    samplesheet = ch_samplesheet
    versions    = ch_versions
core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf
    //
    // params.input aracılığıyla sağlanan girdi dosyasından kanal oluştur
    //

    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.

5.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.

5.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.

cp greetings.csv core-hello/assets/.

Şimdi greetings.csv dosyası test girdisi olarak kullanılmaya hazır.

5.3.2. test.config dosyasını güncelleme

Şimdi test.config dosyasını aşağıdaki gibi güncelleyebiliriz:

core-hello/conf/test.config
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'
}
core-hello/conf/test.config
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 iş akışı 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, pipeline ile birlikte gelen 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:

core-hello/conf/test.config
process {
    resourceLimits = [
        cpus: 2,
        memory: '4.GB',
        time: '1.h'
    ]
}
core-hello/conf/test.config
process {
    resourceLimits = [
        cpus: 4,
        memory: '15.GB',
        time: '1.h'
    ]
}

Bu, yapmamız gereken kod değişikliklerini tamamlar.

5.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).

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.

Komut çıktısı
 N E X T F L O W   ~  version 25.10.4

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-

Gördüğünüz gibi, başlatma alt iş akışı sayesinde başlangıçta tipik nf-core özeti üretildi ve her modül için satırlar artık tam PIPELINE:WORKFLOW:modül adlarını gösteriyor.

5.5. Pipeline çıktılarını bulma

Şimdi soru şu: pipeline'ın çıktıları nerede? Ve cevap oldukça ilginç: sonuçlara bakmak için artık iki farklı yer var.

Daha önce hatırlayabileceğiniz gibi, yeni oluşturulan iş akışının ilk çalıştırması çeşitli yürütme raporları ve meta veriler içeren core-hello-results/ adlı bir dizin oluşturmuştu.

tree core-hello-results
Dizin içeriği
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

İş akışı henüz yalnızca bir yer tutucu iken ilk çalıştırmada elde ettiklerimize ek olarak başka bir yürütme raporu seti aldığımızı görebilirsiniz. Bu sefer beklendiği gibi çalıştırılan tüm görevleri görüyorsunuz.

Hello pipeline'ı için yürütme zaman çizelgesi raporu

Not

Bir kez daha görevler paralel olarak çalıştırılmadı çünkü Github Codespaces'te minimalist bir makinede çalışıyoruz. Bunların paralel çalıştığını görmek için, codespace'inizin CPU tahsisini ve test yapılandırmasındaki kaynak limitlerini artırmayı deneyin.

Bu harika, ama gerçek pipeline sonuçlarımız orada değil!

İşte olan: modüllerin kendilerinde hiçbir şeyi değiştirmedik; bu nedenle modül düzeyindeki publishDir yönergeleri tarafından işlenen çıktılar hala orijinal pipeline'da belirtildiği gibi bir results dizinine gidiyor.

tree results
Dizin içeriği
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
├── Hola-output.txt
├── UPPER-Bonjour-output.txt
├── UPPER-Hello-output.txt
└── UPPER-Hola-output.txt

0 directories, 10 files

Ah, işte buradalar; orijinal Hello pipeline'ının önceki çalıştırmalarının çıktılarıyla karışmış halde.

Bunların demo pipeline'ının çıktıları gibi düzgün bir şekilde organize edilmesini istiyorsak, çıktıların nasıl yayımlanacağını değiştirmemiz gerekecek. Bunu bu eğitim kursunun ilerleyen bölümlerinde nasıl yapacağınızı göstereceğiz.

İşte bu kadar! Orijinal pipeline ile aynı sonucu elde etmek için çok fazla iş gibi görünebilir, ancak tüm bu güzel raporları otomatik olarak oluşturuyorsunuz ve artık girdi doğrulama ve daha sonraki bir bölümde ele alacağımız bazı düzenli meta veri işleme yetenekleri dahil olmak üzere nf-core'un ek özelliklerinden yararlanmak için sağlam bir temele sahipsiniz.


Özetle

nf-core şablonunu kullanarak normal bir Nextflow pipeline'ını nf-core stili bir pipeline'a nasıl dönüştüreceğinizi biliyorsunuz. Bu süreçte, bir iş akışını nasıl birleştirilebilir yapacağınızı ve özel bir nf-core stili pipeline geliştirirken en yaygın olarak uyarlanması gereken nf-core şablon öğelerini nasıl belirleyeceğinizi öğrendiniz.

Sırada ne var?

Bir mola verin, bu zorlu bir çalışmaydı! Hazır olduğunuzda, nf-core/modules deposundan topluluk tarafından bakımı yapılan modülleri nasıl kullanacağınızı öğrenmek için Bölüm 3: Bir nf-core modülü kullanma bölümüne geçin.