 Olá pessoal, sejam bem-vindos e bem-vindas à terceira sessão do nosso curso comunitário do Projeto NFCore, Coste Next Flow. Vamos começar fazendo um recap rápido aqui, do que nós vimos até agora, certo? Então no primeiro dia a gente teve aquela introdução, uma palestra em si, o uso do resto da introdução e depois da sessão de introdução do nosso material de treinamento. Depois o capítulo da prova de conceito do pipeline de Arnecique. Em vários momentos sempre falavam, ó, processo, canal, operador, vejam que é parte prática, compreendam o efeito disso como funciona e depois vamos voltar e ver a parte teórica, digamos assim, né? O segundo dia foi a mesma coisa. Falei sobre o projeto do NFCore em mais detalhes, falei das ferramentas do NFCore, NFCore Tools para usuário, para desenvolvedor, falamos um pouquinho de módulos, sub-workflows, mas mais uma vez falando, não se esqueçam, não foque muito na parte teórica agora, foque em entender o que é feito e depois a gente volta e entre mais detalhes. Então hoje é esse dia. Então a gente falou um pouquinho de docker, por exemplo, no primeiro dia. Vamos hoje ver mais detalhes, o que é o docker, as tecnologias de container, como é que se configura isso com mais detalhes. Vamos ver a parte mais teórica sobre canais, processador, processos, operadores. Vamos ver um pouquinho de groovy também, que eu falei no primeiro dia que o nextflow, ele está em cima, o nextflow como linguagem, ele está em cima de uma outra linguagem de programação, chamada groovy. Então você programa em nextflow em si, mas é interessante, em alguns momentos, saber algumas coisas de groovy. Então hoje vamos ter também uma introdução rápida, groovy. E por último, isso tudo, como eu falei ontem, está ao material treinamento, cada um desses são capítulos no nosso material treinamento. E a modularização, que é o último, vai dar toda a base para entender melhor o que eu comentei ontem sobre módulos e subworkflows do NFCore, certo? O último dia e manhã vamos falar mais sobre configuração, gostar de implotação, cache, resume, um pouquinho mais aprofundado. Mas hoje é talvez um dos dias mais importantes em termos de conteúdo teórico, certo? Repito, o endereço é o training.nextflow.io para ter esse conteúdo, certo? Seguiremos utilizando o vtpod, voltando ao que usamos no primeiro dia, o repósito do treinamento, não mais do NFCore, certo? E as perguntas, mais uma vez, tem vários canais, o Slack do NFCore, se você pode perguntar qual é o canal que acha cabível e relação com sua dúvida, mas a gente está dando uma ênfase para responder as perguntas desses canais no treinamento. Então você tem mais chances de receber uma resposta rápida durante o treinamento perguntando nesses canais. Depois, as semanas, as canais serão arquivadas, mas por hora, tem pessoas lá esperando para responder as suas dúvidas, certo? Sem contar que nós temos esses canais em vários idiomas. Então o canal, para perguntar em português, que tem agora é esse. Tem um canal que é o Region Latin America, onde a gente fala em português e espanhol e também pode responder em português e espanhol. Mais uma vez, o que a gente coloca nessa semana é fazer perguntas nesse canal, o Mar Min 3 Train Português, para essa sessão que é em português, lembrando que esse é o sessão que está acontecendo em Hindi, em francês, em inglês e em espanhol também. Vamos lá, então, voltar, certo? Esse é o mais treinamento que vocês já viram, que é o training.nextload.io. A gente pode clicar aqui para você abrir o Gitpod ou, como a gente vira no primeiro dia, né? Vem aqui em setado, clicar em abrir o Gitpod. Então, como a gente vira no primeiro dia vai ser um pouco mais rápido, porque a gente já utilizou isso. Então, quem fez o primeiro dia do treinamento já tem uma máquina virtual pronta, certo? E aí eu poderá consultar e perguntar se você quer criar uma nova ou se você quer continuar, que você estava utilizando anteriormente. Eu posso vir aqui no meu Gitpod IO e aqui no meu dashboard, certo? E aqui ele vai ter algumas máquinas virtuais com a que a gente utilizou ontem, né? Ficou, né? Mas aqui é o treinamento. Então, eu vou usar esse aqui, treinamento, porque ela não é a começa que eu estou abrindo agora, que é zerada, certo? Eu quero seguir de onde eu parei. A gente modificou alguns arquivos, certo? Colocou o Docker.enable.true no nextload.config. Então, agora, continuar daquele formato, daquela estágia, né? Outra coisa aqui no comecinho, a gente setou para a versão do nextflow ser uma específica, né? Então, esse aqui, o treinamento, o treinamento é feito para funcionar com essa versão. Então, bora ver se, de fato, é essa versão que está sendo utilizada ainda, né? V2, 0, 4, 5. O bem-quanto ele abre aqui minha máquina virtual do Gitpod para eu trabalhar o material treinamento, né? Então, lembrando que o Gitpod, ele desse ambiente para a gente usar máquina virtual na nuvem, com tudo instalado e configurado para a gente já começar a praticar do zero, sem ter que estar brigando com o computador para instalar, configurar o que for. Geralmente é muito simples, é um comando para acelar o nextflow, mas vai que você tem uma versão de Java com tempo, não sei. Aqui vai ficar bem mais prático que a gente não perde tempo trabalhando com isso, certo? Então, eu vou dar um nextflow, um traço ver? Lembrando que um traço é a opção do nextflow, dois traços do pipeline, né? Teotena de 2.10. Então, beleza, eu vou digitar aquele comandinho que a gente viu. E agora, quando eu for dar um nextflow, ele vai baixar a versão que eu tinha configurado. Qualquer comando que você der na hora em que você setou essa variável de ambiente, né? Que a versão que você setou, né? Então, para a gente não ver a versão que está agora, é o 2.04.5. Beleza, está na versão que eu quero. Então, entrar aqui no bárbio básico, está aqui em português, já vimos sempre de bem-vindo, com a configuração ambiente e produção para o clima da UNICIC. Hoje vamos ver GLC, Dependency, Containers, Canais, Processos, Operadores, Introdução ao Groovy e modularização, certo? Como antes, eu vou clicar aqui nesse processos, operadores, introdução ao groovy e modularização, certo? Como antes, eu vou clicar nesse explorer aqui para fechar, tem mais espaço de tela e vamos começar a seguir o material, certo? Vamos lá, clicar aqui em Gerenci, Dependences e Containers. A primeira coisa é o docker, é a principal pequeno vídeo de container que a gente tem hoje no mercado. Mas que eu cheguei a falar brevemente essa ideia de você dentro do seu computador criar um computador isolado que ele tem o seu bicho, o seu mandio arquivos, o seu memório, tudo isoladinho, certo? Bibliotecas, o que permite que eu possa ter uma versão X de biblioteca nesse computador, nesse container, uma outra versão em outros containers, uma outra versão da minha máquina, se tudo funciona realmente, certo? O docker, ele é o motor de container mais famoso, né? Então, ele tem um problema de linha de comando, que já está instalado aqui, ele cresceu no primeiro dia, então está instalado. E assim o tacto, você executar um container para você pegar uma imagem, uma descrição, né? E executá-la, é muito simples, docker, run e o nome da imagem no container. Eu gosto muito de analogia entre algumas coisas do nextflow e de container, porque o seguinte, você descreve um processo, que é um etápio do pipeline, né? Mas ele é só a descrição. Quando ele está sendo executado, de fato, uma instância de processo, a gente mora de tarefa. Então, se tem um processo para colocar a palavra maiúscula e eu mando dez palavras para ele, esse processo vai ter dez instâncias, dez tarefas, certo? Então, ele é só a descrição. Mesma coisa aqui, a imagem é só a descrição. Quando você executa a imagem e ela vira um ambiente de computação, digamos assim, você tem um container, certo? E eu posso executar a imagem várias vezes, só instâncias dela em execução, a gente mora de container. O docker, ele já tem um container, uma imagem, né? Padrão para brincar dele funcionando, que é o Hello World. Então, vamos lá brincar aqui. Vamos aqui dar um docker, que é o nome da Poguen, pronto. Run, Hello World, que ele mostra aqui, né? Você vai copiar e colar, se eu quiser. Como vocês podem ver, ele viu que não encontrou essa imagem Hello World, localmente, né? Ele adiciona para um padrão, um rótulo de leites que é outra versão, eu posso escolher uma versão da imagem aqui, se não coloquei nada, ele pega a última. Ele falou, não encontrei outra versão, nem nenhuma imagem com esse nome na Hello World, na sua máquina, no teu computador. É o que ele faz. Ele procura no docker hub, que é um repositório oficial do docker. Ele procura lá. Você pode falar um hub diferente, né? Tem várias plataformas, como QIO e outras, mas você não fala nada, ele procura um docker hub, que é o principal. Aí ele encontrou e aquele, tá, ó, o pulling, nem o nextflow pull, que ele viu ontem baixar pipeline, ele dá um pull que ele baixa a imagem. Terminando de baixar a imagem, como eu falei no docker run, ele vai executar essa imagem, porque ela faz basicamente falar algumas coisas aqui, ah, hello from docker, falar algumas coisinhas. Beleza, eu posso agora digitar docker image, por exemplo, para listar todas as imagens que eu tenho localmente na minha máquina. Eu tenho a Hello World, que ela foi criada há muito tempo atrás, né? Mas ela acabou de ser baixada, certo? E essa Arnecique que a gente utilizou ontem, antes de ontem, no pipeline de Arnecique, né? É pra hora de conceito. Então, essas duas estão na minha máquina. Aqui tem o tamanho delas, vai ter que falar um pouco sobre boas práticas, idealmente essas imagens não devem ser muito grandes, essa aqui é muito grande, por exemplo, 2 giga, quase 3 giga, mas tem a poca gente que é sobre isso. Então, beleza. Mas sério, eu não quero executar o container da imagem, eu não quero baixar a imagem, eu quero apenas baixar. Beleza, se dá um docker, é pull. É que nem o nextflow, mesmo que a gente tenha o nextflow run, hello, eu tenho o nextflow pull. O run ele baixa e executa, eu quero apenas baixar. Então, esse comando aqui, ó, eu quero baixar uma imagem chamada Debian, certo? Como eu não falei nada de onde vai ser baixado, ele vai procurar o dockerhub e o rótulo é stretch slim, que tem várias imagens do Debian, essa aqui é uma delas. Então, vou dar comando de ver aqui, vamos baixar essa imagem. Então, ele não vai executar dessa imagem, ele vai apenas baixar. Então, para ali. Não é como antes que ele baixou e executou aqui em um docker, né? Só baixou. Eu posso digitar um docker images. Perdão, images. Vocês vão ver aqui agora tem também aqui, ó, a Debian com o rótulo stretch slim, tamanho de 55 mega. Então, Marcelo, eu conheço o sistema operacional, já instalei Linux e tal. Geralmente são gigabytes, um instalador, né? O samba operacional, o Windows também. Como é que pode que esse 55 mega, o Debian, o Linux? Essa é a questão do container, ele faz um uso inteligente do infraestrutura computacional. Então, o que tá embaixo e post utilizado do sistema hospedeiro que a gente fala, que é a máquina que a gente tá utilizando, ele usa. Então, ele vai, o container vai ter apenas um diferente, o que precisa de isolamento. Por isso que ele é tão pequenininho, só 55 mega. Mas esse é um sistema operacional em teoria completa, certo? Beleza, Marcelo. Mas agora eu quero dar a que eu baixei. Então, você vai dar um Docker run, Debian e o rótulo que você quer. O que vai acontecer aqui? Nada. Mas é como assim, nada? Ele tá executando, eu não tô vendo nada. Ele tá executando, certo? Após dar um ps pra ver os contextos, ele executou e morreu, digamos assim, né? Não apareceu nada. E se eu quiser executar esse container, se tá um Docker, ele mostra também o que já pronto, ele mostra aqui, ó, como que é a 16 segundos, ele vem e fechou. Porque essa imagem, ela não tem nada, digamos assim. Se você aprende a executá-la, ela liga, não tem nenhum comando, nem dá pra fazer, ela fecha. Então, o ps menos a, ele mostra os contêneres, não só os contêneres, como a teve os que já morreram, né? Já foram parados. Então, tem aqui o Hello World, que a gente usou há pouco tempo e tá medo de Debian agora, né, Marcelo? Mas Marcelo, eu quero criar o container e entrar nele interativamente e interagir com ele como se fosse um computador normal. Você vai usar o Docker One, como a gente utilizou, mas agora tem o minus e t, né? Que é uma execução interativa, certo? O nome aqui, mas no final eu vou dar pra cuidar um bash, porque abre o container, eu quero dar dentro dele mais como, execute um comando, que é o bash, que é o comando que abre o terminal, certo? Então, usando esse Docker One, minus e t, o nome da imagem e o bash no final, ele abre o container e eu estou dentro do container, certo? Posso dar um ls aqui, você vê que as passas são diferentes das que a gente tá raivendo aqui, porque ele tem seus termos de arquivos independentes, certo? Aqui eu tenho outro nome que no caso é root, se eu der um exit pra sair e der um group pra saber quem eu sou, a Git pode a conta. Então, dar um ls são os arquivos que a gente tá vendo aqui. Então, ele de fato tem uns termos de arquivos independentes. Se eu der aqui um Docker PS, não tem mais porque eu fechei, né? Eu dei um exit, eu fechei e matei a máquina. Menos a já tem duas vezes aqui, ó. Executamos duas vezes esse container, né? Então, a mesma imagem, mas já gerou dois containers, pois executaram duas vezes, certo? Já falei pra sair da um exit. Mas Marcel, se eu quiser criar uma imagem do Docker, a gente fala que se cria um arquivo do Dockerfile que tem a descrição, pensa a ideia de processo, tem uma descrição de como é essa imagem e aí você vai montar a tua imagem com base à descrição, certo? Uma coisa interessante falar é que quando você cria, eu cria um Dockerfile, a gente vai ver daqui a pouquinho e depois eu falo, beleza Docker, munte uma imagem de container com base a esse Dockerfile. Ele vale mais em consideração os arquivos daquele diretório. Então, se você tem vários arquivos nada a ver aqui, então, ali, a imagem fica um pouco maior do que precisaria, certo? Então, se você quiser, você pode criar um aqui o Dockerignore pra falar pra ele que é o Demo Gnore, você pode criar uma pasta, né? Entrar nela e, dentro dela, criar o Dockerfile depois montar. O que vamos fazer agora? Eu vou dar um, um稳mo aqui do Dockerfile pra abrir um arquivo que vou gravar, certo? E ele já dá aqui um exemplo de um container muito simples, de uma imagem muito simples. As imagens, elas começam em cima de uma base, então tem aqui o Debia StressLink, caso dele, um límus bem cruco, pouquíssimas coisas. Então, eu falo, comece a parte disso, você pode dar alguma formação de roto do nome do autor que for, e aqui o run, são comandos. Então, assim, roda o comando, o ptget, que é um gênero de pacote, do línio, que é certo, para atualizar a minha árvore de pacote, o que tem lá, instalar o curve e o calcê. São dois programas de línio de comando, certo? Então, vou copiar aqui, vou salvar nesse file, certo? E o comando para montar sua imagem é o docker build, para montar, "-t", para dar um nome à minha imagem, e o ponto que se refere ao diretor atual, onde está o docker file. Então, vamos fazer isso. Então, dá um ls aqui, tem meu docker file, eu posso dar um cat para o meu conteúdo dele, que a gente já sabe, porque a gente acabou de escrever ele, certo? E vou dar aqui um docker build para montar, "-t", o nome da minha imagem. Eu chamei de minha imagem e ponto para o diretor atual. Então, ele veio aqui, camada a camada, ele construindo o teu imagem e aqui ele instalando os programas que você pediu, certo? No final, terminou aqui, ele criou a nossa imagem, que eu chamei de minha imagem, como eu não coloquei nenhuma tag, ele apenas colocou latest, certo? E eu posso digitar docker images e ele vai aqui, minha imagem. Tendemos uma nova imagem, local, com 130 mega, que era o 55 do dev, a imagem base, e as coisas que eu criacionei em cima, certo? Eu posso agora, como fiz antes, executar o docker run, minha imagem. Mas se eu não falar nada, ele abre o container, fecha o container, aconteceu nada. Então, eu vou falar, em vez de bash, eu não quero executar um terminal que fica aberto só, eu quero rodar um programa calcei, que é um programa calcei, que ele faz uma vaquinha, apareceu dizendo que você colocou como string depois, certo? Se eu rodar aqui nessa máquina, não está instalado, porque eu não instalei o calcei, também o MacroGate pode, mas tendo, perdão, mas no container imagem, porque o created container está instalado. Então, eu vou querer uma instância dessa imagem, vou executar um container, rodando o calcei e dizendo olá docker. Então, ele rodou o container e imprimiu minha tela, olá docker, a vaquinha falando, certo? A mação, eu quero adicionar mais programas. Beleza. O docker file aqui adiciona o que eu quero. Então, eu coloquei o run, mais uma vez o run, e ele dá aqui como você instalar o Salmon, que é o programa que a gente utilizou para fazer a criação de índice, de transcrição de referência e quantificar a expressão genérica no primeiro dia do treinamento, naquela prova de conceito de pipeline, de RNA-6, certo? Então, aqui a gente vai usar essa imagem gigante, a gente vai ter escrito 2 giga pronta. Vamos fazer uma imagem mais simples. Volto pra cá, adiciono aqui, a gente instalou o crawl. Isso não entra a isso, porque o crawl ele baixa o arquivo, certo? Então, aqui o endereço, diria que está o arquivo do Salmon, descompact, coloque os arquivos, os binários executáveis, nas fases corretas e beleza, é isso. Eu vou salvar aqui o docker file e eu vou dar um build novamente, né? Eu poderia criar um nova tag, aqui outra coisa, mas vamos deixar só assim. Vamos sobrescrever a nossa imagem, aí é o que ele fala, olha, várias coisas estão em cache aqui, né? Não tem o que fazer aqui, o using cache ele mostra, porque a gente adicionou uma última camada, como ele não anda lá em cima, ele vai aproveitando o que já tinha, vai apenas fazer o trabalho dessa outra etapa, certo? Que é instalar o Salmon. Tendo feito isso agora, eu posso fazer o que a gente tem feito, que é o quê? Crie uma instância da imagem, crie um container, execute ele e quando você executá-lo, eu quero que você rode o comando Salmon para seu traço virtual, eu quero ver a versão dele e apareceu aqui, Salmon 1.5.2, certo? Ah, Marcelo, mas eu quero agora entrar interativamente e dentro dele brincar com o Salmon, beleza? A gente aprendeu que tem que usar o menos it para você entrar no container e falar uma interativa e o bash passou a terminar o que você vai utilizar para interagir lá dentro. Então, bora fazer isso. Entrei aqui, ele já viu que é diferente, ele é um arquivo que a gente baixou, ele foi deixado aqui, eu poderia ter apagado, mas tá aí e eu posso agora dar um Salmon traço-traço, virtual, de fato, nós temos o Salmon. Se eu sair do container e digitar Salmon aqui fora da maquina do Gitpod, não tem Salmon, ele não está instalado, certo? Beleza, então bora agora fazer o que a gente vê lá atrás, a gente viu, abri aqui aquele script set, o comando no processo de índex, né? Ele é o Salmon, índex, va, va, va, vamos lá, eu quero executar isso na mão. Esqueço o nextProp por um segundo. Eu quero rodar a minha imagem, executar o Salmon com o comando que a gente viu a pouco, que é o índex, menos t, o transcripto de referência e o nome do diretório, onde eu quero que esse índice e outros arquivos sejam Salmos. Vou executar isso aqui. Vamos lá. Ele deu alguma informação aqui de adaptar o Salmon, beleza? No final, terminou, né? Show de bola. Só que tem um problema aqui. Ele fala aqui no finalzinho, ó, o arquivo pra, que é o transcripto de referência, né? Ele não parece existir. Esse pra Marcelo, claro que existe aqui, ó, dele pra atual, data, beleza, na verdade, isso já ia, você é que tem um erro mesmo na verdade, que esse comando é esperado que se ia feito na pasta, onde tá a pasta data, né? Então, tem que se rodar aqui fora. Mas ainda assim ele vai dar errado, certo? Deu aqui a mesma coisa, ó, não parece existir esse comando. Marcelo, é errado, isso existe aqui, ó. Vamos ver aqui, status pra ver isso, dado sobre o arquivo, né? PWD, que é a pasta atual, data, GGAL, transcripto de referência, né? O transcriptome, quanta FA? Existe o arquivo. Como que o arquivo existe? Mas quando eu rodo um docker, ele disse que não existe. Ele dá aquele erro. Ó, daqui não pra vocês verem. Ele falou, o arquivo tá correto, endereço aqui, ó, não existe. Por que? Como eu falei, os sistemas de arquivos, eles são isolados. Os temas de arquivos do contêndio na execução e dos termos pedeiro, eles são independentes. Por natureza, né? Por padrão, não tem como eu escrever dentro do contêndio, nem o contêndio escrever dentro do sistema operacional, os pedeiro. Então, pra fazer, pra funcionar, tem algumas estratégias, uma das mais conhecidas é criar volumes. O que você fala, olha, eu quero que essa parte seja vista lá dentro, o que é lá dentro, posso escrever pra cá. Então, o que eu vou fazer aqui é rodar o mesmo comando, mas criando um volume, dizendo, ó, eu quero que esse arquivo que tá aqui no pedeiro, que é com esse endereço, ele seja visto lá dentro do contêndio, na raiz, como transcription.fa. Beleza. Vamos rodar esse comando aqui que ele tá pedindo. Show de bola. Funcionou aqui, está vendo pelo output, né? O sound, ele conseguiu ler o resumo de referência, criou o index. Cadê o index? Cadê a pasta, o transcript index que o nosso comando aqui, ó? Colocou, o menúcio de prostituto index. Cadê a pasta? Era pra tá aqui. Quando a gente criou o volume, a gente falou que o docker conseguia enxergar aquele arquivo, mas a gente não falou que o docker, o contêndio do docker poderia escrever de volta no sistema os pedeiro. Então, o que é pra fazer agora? Isso também é isso. Vou falar, ó, foi o seguinte, não só esse arquivo é visto lá, essa pasta que eu tô inteira, ela vai ser vista lá. De modo que como ela é vista lá, eu posso escrever lá e aparecer aqui também. Então, que eu tenho um PWD, né? Que é uma variável de ambiente pra print, working directory, né? Imprimo o diretor de trabalho atual onde eu tô. Ele dá a dizer que o diretor do trabalho é aqui também, então, a pasta work, né? Pra o nexon, mas enfim, é necessário isso aqui, minha imagem e o comando que a gente tem visto. Ao rodar isso aqui, agora sim vai funcionar como a gente tem imaginado. Ele conseguiu ler o arquivo lá, como já conseguiu no início, mas agora eu tenho a pasta aqui, ó. Transcript pra sua index. Então, eu posso dar o tree, transcript pra ver a variadora, né? E tem todos os arquivos aqui de fato que a gente precisa o índice do som pra fazer alimento, alimento, expressão, o que for, certo? Um outro modo é definir uma pasta que você queira montar como variável de ambiente. Então, eu falo, ó, que é variável de ambiente data aqui, essa é a pasta, e eu vou fazer a mesma coisa, mas eu vou colocar o PWD pra ser o diretor atual, porque aquela pasta que eu tinha visto lá e o que eu escrevi nessa pasta dentro do content apareça na minha, aqui, na minha noção para assinar os pedelos, certo? Então, como é que eu posso fazer assim? Uma coisa interessante se mostrar é assim, como eu falei, eu dei o RUMI, a Gitpod, deu um state, script set, Gitpod. E já se eu der um state, transcript, foi criado pelo container, é root. Porque, como vocês viram pra gente dentro do container e der um runa, a conta é root. Então, eu não posso, por exemplo, vim aqui e querer, sei lá, apagar esse info, ponto de JSON. Tem que ser negado, porque é root. Então, tem outros modos de conseguir impedir que esse sucesso de definir lado. O importante é saber essa questão de usuários lá dentro de frente, aqui fora, certo? Mais uma vez, você pode, no começo do nextflow, vim aqui em docker, um container, eu acho, na verdade, docker e tem vários parâmetros, né? O docker enable, igual ao tour, rende-a-view, certo? Mas não apenas isso. Eu posso ter um container pra cada imagem, vamos ver aqui um pouquinho sobre isso, que ia ver na verdade isso. Então, aqui, o scope do docker na configuração. Então, eu quero que o docker executa como root, eu posso com esse run options falar que eu quero alguma versão específica, enfim, alguma configuração específica, eu posso colocar aqui pra corrigir a questão de, enfim, tem várias opções que você pode adicionar, certo? Com o docker. Voltando. A gente viu que dá pra baixar as imagens, como ele baixou a imagem do docker hub, assim, com queio e outros registradores de container, container registers, que a gente fala, arquivadores de repositórios de imagens, né? Aqui tem uma nozinho rápida e como você enviar pra tua conta pessoal, o docker hub, uma imagem. E por que eu farei isso e meter na minha máquina? Porque eu vou enviar, verdade, porque eu vou enviar pra um repositório de imagens, né? Na hora que eu tenho uma imagem preto ela, pra um repositório de imagem, qualquer pessoa com essa endereça e com internet, consegue baixar a minha imagem e usar no computador dela. Então, eu irei usar um docker login pra me autenticar com o docker hub, vou dar uma tag pra essa imagem, certo? Tem meu nome de usuário, que é a emberudantas, e aí tendo feito isso, eu consegui dar um push pra enviar pra lá essa imagem. E, uma vez estando lá, eu posso pegar de volta, né? Então, eu já tive emberudantas, uma imagem com o nome, minha imagem. Eu posso dar um docker pull, emberudantas, varra minha imagem, ele encontrou, mas foi aquela, já existe essa parte aqui, uma coisa que a gente mudou não, ele tá construindo, mas eu tenho agora, baixei essa minha imagem. Marcelo, eu já tinha, né? Uma imagem aqui nessa máquina, chamaram de imagem. Agora você tem duas, por que? Porque tem a minha imagem que a gente criou, mas também tem a mrb que eu baixei do docker hub, certo? E o interessante é que essas imagens elas têm os seus ideias, né? Que é tipo um cpf da imagem. Você pode até utilizar, aqui o próprio chá que ele mostra quando tá baixando, você pode querer utilizar com esse arroba aqui, pra falar, ó, eu quero baixar a imagem arnecique pra sua nf do namespace nextflow do docker hub, mas pode ser que tenha uma versão nova, pode ser que ninguém tenha adoteirado a imagem, quando você coloca essa chave, essa é exatamente o que você quer. Se não tiver, eu vou falar que não tem mais essa imagem, e se tiverem adoteirado, você não vai pegar adoteirado, porque você deu um cpfzinho, eu quero essa imagem, que essa versão, digamos assim, certo? Então beleza, já vimos aqui como é que faz pra criar a imagem, pra enviar, pra puxar, pra executar, pra entrar pra uma interativa, pra mandar um content executar uma tarefa, certo? Então, vamos agora fazer o que a gente vê no primeiro dia, que é rodar o programa de conceito de arnecique, com docker, né? Então, eu vou abrir aqui o script 2, pra lembrar o que tem dele, ele é bem simples, ele tem aquelas questões parâmetros, que imprimem algumas coisas na tela, tem uma etapa de index, certo? Tem o nosso processo de index, que é uma etapa, que vai rodar o sumo index, certo? Então, eu posso vir aqui, o nextflow run, script 2, com tnf, eu espero que o docker não seja ativado pra ele não utilizar, mas como eu peguei beleza, não tá com docker ativado, tudo bom, eu dei um e aqui, eu não penso, como é que eu resolvo isso? Deixa eu ver como é que tá aqui o nextflow.configue ele disse que tem um content, mas ele não fala pra utilizar o docker, tem que ter que a gente vir no primeiro dia, o docker enable e go through, pra gente falar o docker, eu vou apagar isso aqui, certo? Vamos rodar do, não vai funcionar, porque não tem nenhum content sendo especificado, não fala pra usar docker, tá me mandando rodar localmente, vai dar um erro, não tem salmo, e o que eu vou fazer agora é mandar usar com o docker, se eu desci, ele dizer, ó, tem que especificar um content, não é uma imagem, mas eu vou dizer o minha imagem que a gente construiu, né, que eu baixei, que a gente construiu aqui na aula de hoje, certo? Vou executar e vai funcionar, porque eu já vi a versão do salmo, então aqui ele funcionou, de fato, se eu der um tree em work, ele é mostrar aqui, né, deixa eu rodar a noite pra pegar o diretor do trabalho, o diretor de tarefa, né? Então vai ser, ó, 48, então aqui eu vou dar um tree work, 48, set 9, dar um tab pra completar o diretório, e vai ter aqui a pasta salmo index, né, o tudo e essa etapa gerou. Então por que? Porque a gente coloca aqui no final menos e salmo index. Então vimos que conseguimos criar nossa imagem com os programas que precisam praquele processo e rodamos um pipeline do nextflow dizendo, ó, utiliza essa imagem, cria um content com ela, e executa a tarefa ali dentro porque tem os programas que você precisa. Então isso é parece simples, mas é extremamente poderoso, certo? Pra você conseguir, de fato, utilizar, ter um pipeline reproduzível, que ele tem um ambiente isolado com tudo protegido, com os programas que precisam na versão correta, e tudo mais. O docker, pode ser já o motor de content mais conhecido, certo? Mais utilizado, um dos primeiros que foi, tem lá na escala, ele não é o único, tem vários, na verdade. E até no primeiro dia quando eu dei aquela palestra, eu mostrei que na real a gente tem vários suportes nativos do nextflow, Charlie Cloud, Podman, que é muito conhecido, Singularity, o docker, em vários, certo? Em alguns ambientes, em HPC, em computação de desempenho, em clusters, porém de questões, geralmente o docker não é permitido. Então não tem um docker instalado. Muitas razões é porque, de início, o docker ele tem algumas questões de permissão, que abrem a porta pra falar de segurança, certo? E acabou que você criou outras soluções, como o Singularity, como o Podman, o Podman, ele é quase que um clone do docker, com algumas modificações importantes, mas pequenas, entendeu? Acabou que, em clases, é muito mais comum você ter o Podman instalado, o Singularity, o Charlie Cloud e outros. E alguns aqui tem o docker também, mas não é tão comum, certo? Então é bom a gente dar, uma pincelada rápida aqui, o Singularity, certo? Ele é um motor de continentalização, assim como o docker, você também tem um arquivo de texto que você descreve a tua imagem do Singularity, seu arquivo do Singularity. O Singularity também permite converter imagens do docker, então você vai ter uma imagem do docker e utilizar o Singularity para converter para um arquivo do Singularity e criar o container, certo? A sintax é ligeiramente diferente, mas é muito parecido. E eu posso rodar o Singularity, construir o nome da imagem do Singularity, ele vai funcionar, certo? Não tem o Singularity instalado aqui, eu acho que eu comentei em alguma aula, a gente não tem instalado o Singularity no Gitpod, então não vai ter nenhuma parte prática que a gente viu o resultado, mas vocês podem ver que é muito parecido. O vc é um run, vai ser um exec, certo? Você consegue dar o shell para entrar de forma interativa. Aqui, enfim, não tem essa questão do root que o docker tem, certo? Como eu falei, para utilizar uma imagem do docker para rodar um container com o Singularity e o nextflow funciona muito parecido com o suporte dele ao Singularity e ao Charlie Cloud, ele é muito parecido com o suporte do docker.enableTrue vai ser o docker, vai ser um Singularity .enableTrue, Charlie Cloud, Podman, isso é a mesma coisa. O nome do comando era traçoWeef, traço docker vai ser traçoWeef, traço Singularity, traçoWeef e com conda spec e assim por diante, certo? Então a sintaxa é muito parecida, de modo que se você souber utilizar o nextflow com a tecnologia de container, vai ser muito provavelmente com todas, que a sintaxa é a mesma funcionamento, é a mesma, certo? Quando que a gente tem o dockerhub o PAYO e outros repositórios de imagens de container, o Singularity também, tem o que eles são bibliotecas de container, certo? E aqui é só mais um exemplo o foco realmente do docker, que é apenas mostrar que existe o Singularity mas tem o podman, o Charlie Cloud, que tem vários docker, certo? Você foi na documentação aqui do nextflow e foi em contenders, você vai ver que a gente tem o Charlie Cloud, tem o docker, tem vários, certo? Em termos de de pacotes, a gente vai ter o conda, que eu vou falar já, tem o spec também, que ainda não está na comunitação, mas tem suporte, certo? Então tem bastante tecnologias diferentes que o nextflow tem suporte nativo. Lembrando que o suporte nativo significa o que? Você não tem que se preocupar em ficar rodando comando do docker. Talvez tenha ficado um pouco confuso aqui quando eu demonstrei os exemplos, eu mostrei o docker puro, mas você escreve o teu pipeline nextflow, você utiliza de alguém e acabou. Você precisa falar nextflow, pra esse processo, eu quero que você utilize essa imagem de contêiner e você não tem que fazer mais nada. O nextflow que vai baixar e mais você precisa baixar, executar, criar volume, é o nextflow que se vira com isso. Mesma coisa pro singular, pro podman, pro shifter, pra todos os tecnologias e tudo o que o nextflow tem suporte nativo. Ele toma conta, ele se preocupe e resolve boa parte dos problemas, pra como eu falei nos contêiner, no que é importante, que é a NADS e a criação do pipeline e assim por diante, certo? Tendo falar um pouquinho agora do contêiner, agora falar de ambientes e gêneros de pacote, certo? Então, a gente utilizou a ptget dentro da nossa imagem pra instalar o curl e o calcê, mas ele é muito específico do Linux, então, tem um gênero do pacote muito conhecido na área do V-formatica, mas não só nela, que é o conda que ele funciona no Linux, macOS, então, o que você faz? Agora começar um pro com o conda de início, né? Então, o conda ele tá instalado aqui no gate pod, certo? Um pouquinho aqui pra gente ter mais tela e a primeira coisa que você tem que fazer depois que você instala o conda, você pode ir no site do conda e instalá-lo, certo? É digitar conda init pra iniciar. Tendo feito isso, né? Você vai digitar um bash pra abrir um outro terminal e se envesse seu pra ele começar já levando a operação que o conda tá iniciado e configurado. E você vai ver que isso mudou porque ele aparece aqui um base na frente, que é um ambiente básico do conda, porque ele já aparece aqui um base, certo? Então, agora nós estamos com conda. Vão ter programas que eu posso instalar aqui que eu vou conseguir utilizar como salmo, que na hora que eu der um exit e voltar pro meu bash anterior, não vai estar mais funcionando, então, lembrando que não tem salmo aqui, certo? Então, vamos lá. Ah, bash. Voltei aqui. O computador é uma coisa que você configura isso, pode ser que você configura pra que sempre que você ler o computador já tá com o conda ativado, certo? Aí é uma opção sua. Aqui a gente não colocou um padrão, tem que depois que dar um init, abrir um novo bash pra carregar o git pod. Beleza. Vamos criar um ambiente. Vou criar um ambiente do conda, que quando eu ative ele, eu tenho algumas coisas, alguns programas instalados. Então, ele vai ter o conda, ele tem repositórios onde cada um tem alguns programas. O bio conda é um famoso repositório de recessos do conda pra área de informática, certo? E eu falo que esse meu ambiente tem essas dependências, ou seja, esses são os programas que eu quero que instala o salmo, o fastqc, o multiqc e o tbb. Eu falo também qual o repositório é pra procurar esse arquivo, quer dizer, eu posso ter um programa em mais de um repositório, sem um até ligeiramente diferente, versões que a gente acabou, eu falo que eu canto e procuro no bio conda, e eu falo que a versão que eu quero é essa aqui. Se ele não encontrar essa versão, ele vai falar, eu não consigo instalar porque eu não tenho essa versão. Esse aqui já existe, certo? Esse formato de syntax em ML, esse aqui já existe. Ops, cold. Eu não preciso digitar porque ele já tá criado aqui. O que eu vou fazer é conda. Cri esse ambiente pra mim. E 8 pra criar, eu dou o nome do arquivo que é um env.inm. Essa parte demora um pouco, certo? Porque ele vai entender o que eu falei, eu quero esses arquivos, esses repositórios, essa versão. Ele vai ver essas dependências que eu coloquei, se elas têm dependências. Então, o salmo beleza, aqui é o salmo, mas pra o salmo funcionar, tem que ter instalado esses dois programas aqui. E pra esses dois funcionarem, tem que ter instalado esses quatro e assim por diante. Então, demora que ele vai checar toda a dependência pra resolver e garantir que vai criar um ambiente do conda onde esses quatro programas irão funcionar como esperado. Então, essa parte de criar um ambiente do conda geralmente demora um pouco, alguns minutos, entendeu? Ao menos. Então, enquanto cria aqui, ele tá pegando metadata, né? Dados nos pacotes pra resolver essas dependências, vamos avançar um pouquinho. Na real, eu não vou baixar muito. Não, vou voltar aqui pra a documentação e aproveitar e mostrar umas coisinhas. Vamos vir aqui em conda environments. Ele vai falar um pouco sobre esses ambientes e tudo mais. Você pode clicar aqui no mini conda ou conda, né? Vai levar pro site onde você pode instalá-lo. Então, pra instalar, é por aqui, certo? Tem os executas que você baixa pra cada um, pra Windows, macOS, Windows que for. Então, os instaladores, um pá, enfim, tem vários programas que você vai, é bastante simples instalar o conda ou o mini conda, certo? O mini condo é uma versão mínima do conda. Tem uma na conda, que bem maior, enfim, com vários programas, interface e gráfica, você quer o mais simples. O mini conda geralmente é mais o que é suficiente, certo? Então, se elas são mínimas, mas que costumam ser mais o que é suficiente, porque a gente precisa. Por exemplo, se você instalar, a gente consegue fazer o que tá fazendo aqui. O conda init, pra começar a criar a estrutura do conda, certo? E aí, vamos usar o conda init create pra criar. Então, olha, ele coletou todos os dados que precisa de todas essas dependências e suas dependências e, respectivamente, suas dependências. E agora ele tá resolvendo o init. Quer dizer, ó, precisa disso ou disse isso? O que é o mínimo necessário pra esse ambiente funcionado é isso aqui. Tendo terminar essa etapa, ele vai instalar esses pacotes, certo? Esperar por enquanto ele faz isso. Lembrando que, além do conda, o nextflow também suporta o spec, que é um outro gerenciador de pacote muito conhecido pra quem trabalha com computação de ódio desempenho. É muito comum ter o spec nos clusters, certo? Então, eu tinha que falar aqui no tutorial, porque ele ia falar sobre todas as ferraments que podem trabalhar com o nextflow, né? A gente pegou o docker pra focar pra parte de container e o conda pra focar na parte de gerenciamento de pacote. E daqui a pouco, vamos ver o mamba, que é um pouquinho diferente, junto com o docker pra fechar com chave de ouro essa parte de gerenciamento de dependências e containers, certo? Aqui, como vocês podem ver, tem vários programas que precisam instalar, certo? Alguma parte tá oculta, aqui, inclusive, ele tá instando todos os pacotes que precisa pra criar nosso ambiente. Vamos resolver e tal. Terminando aqui, eu posso dar esse comando aqui do conda envelis, que é pra listar os ambientes que tem nessa máquina, certo? E ele mostra que tem o base que ocultava o padrão, certo? E agora tem a citar o DNF pra tutorial, que é o que a gente criou. Lembre-se no começo da receita que deu o DNF tutorial. Pra ativar esse ambiente, eu vou digitar conda Activate, DNF tutorial. Deslourei aqui no comecinho, vocês vão notar que mudou o nome, certo? E agora se eu digitar um Salmon Virgin e remostrar, se eu der um conda de Activate pra sair, né? Deu um Salmon pra ser nosso version e não tem Salmon. Se eu sair, der um Salmon, não tem Salmon, certo? Então, de fato, é só nesse ambiente que a gente criou, que é o tutorial, DNF tutorial, que o Salmon está instalado, certo? Beleza. Então, agora, em vez de rodar o nosso script, com o Docker, eu vou rodar com o conda. Então, não era trás o Docker, agora é trás o VIF, trás o conda, eu vou dar aqui a pasta do meu ambiente, certo? E é o script set que me lembra se é o pipeline completar nesse que a gente criou, né? Criando índice, quantificação, controle de qualidade. Então, tudo funcionando aqui, por mais que no diretório que a gente tá, não tem Salmon, né? Então, aqui até tem o Salmon, né? Como eu falei, que eu tô com o o ambiente, certo? Não tem Salmon, mas se eu rodar, vai funcionar porquê? Porque o próprio nextflow, na hora da tarefa, pra cada tarefa específica, o ambiente roda tudo e desativa no final. Então, como vocês viram, eu dei aqui um Salmon, não existe, rodou o nextflow sem estar no ambiente, mas o próprio nextflow, ele vai ativar o ambiente pra mim. É isso que eu falo quando eu digo que o nextflow se preocupe e resolve todo esse problema, certo? Então, como vocês podem ver aqui, ele tá ativando e gerenciando esse ambiente do conda. Eu não preciso necessariamente utilizar assim com o VIF conda, assim como eu não preciso utilizar com o Docker, né? Então, a gente viu aqui que o nextflow, mesmo jeito que eu poderia vir aqui com o nextflow, nem colocar aqui um Docker enable true, pra poder colocar um conda enable true. Mesmo que antes tinha um process container igual, né? Todos os processos vai ver essa parte de configuração de novo. Vamos ver amanhã com mais detalhes, certo? Mas aqui fica apreensente que na parte de que eu tô falando, todos os processos vão ter que ter mais uma container que vai ser esse aqui. Eu poderia colocar um process conda e aqui no meu pacote, certo? Vamos ver aqui na documentação como é que ele mostra. Aqui, ó, eu posso, no colo do process no pipeline, eu posso colocar uma diretiva, né? Que são essas que essas opcionais no começo do bloco de processos. Eu quero que você instale com conda pra essa tarefa, o BWA, o Santos e o ModeQC. Ou eu poderia colocar aqui um endereço do ambiente que a gente mostrou, a versão repositório, certo? Aqui, por exemplo, é um exemplo utilizando uma receita pra criar ou poderia ser um diretor já do ambiente criado, certo? Como tá aqui. Então, aqui na documentação tem bastante informação de como utilizar com mais detalhes, né? O conda aqui, ó, conda, process, do mais, um perfil, né? Vamos ver o mesmo com mais calma, essa parte de configuração. Vou mostrar pra vocês como é tudo muito parecido. O Docker enable with Docker, with conda, process container, process conda e assim por de ano, certo? Então beleza, vimos o Docker pra criar esse ambiente isolado, de fato com o sistema de arquivo isolado, tudo mais. E o conda, que ele criou um ambiente isolado, mas não é tão isolado, porque ele compartilhou o sistema de arquivos, as bibliotecas são as mesmas, então eu não posso ter a boa biblioteca internacional que são compartilhadas com o ambiente do conda, então não tem um isolamento de verdade, mas ele é muito bom pra instalar o conda, certo? Embora seja um pouco lento. Aí qual foi a saída, assim, a mistura que dá o perfeito, digamos assim, o mais prós do ideal e veio utilizar o conda pra instalar uma utilização micromamba, que ele é muito mais rápido do que o conda, mas ainda assim ele instala pacotes do conda, repostores do conda, receites do conda e você não conduz, mas ele é muito mais rápido, certo? Então eu vou utilizar o micromamba pra fazer isso, então vou inclusive aqui usar o mesmo arquivo que a gente tem no cliente.nl, certo? Só que eu não vou criar no seu operacional ospedeiro, eu vou criar uma imagem do Docker que dentro dela, ao invés de utilizar o apt-get, como a gente usou naquela vez, vamos utilizar agora um micromamba pra instalar. Então bora voltar aqui pra aquele diretor do teste, certo? Eu vou apagar esse Dockerfile que a gente tinha, então tá vazia, né? E eu vou criar um novo Dockerfile que ele, a base dele não é mais o Debbie, a base é um micromamba agora, posso colocar o meu nome, enfim, eu copio esse copy, a instrução do Docker, eu vou copiar o ak-win.inl que a gente criou, eu vou copiar ele pra dentro da imagem, certo? Vou usar o micromamba pra criar um ambiente e vou instalar nesse ambiente essa receita que a gente tem, certo? Então basicamente é isso que ele faz. Então, criei esse Dockerfile eu vou copiar aqui pra dentro wav.inl que a gente criou, que já tava criado, na verdade e to aqui dentro de mim agora, wav.inl e o Dockerfile. E eu vou usar o comando que a gente já viu, que é o Dockerbuild-t minha imagem. Eu vou colocar minha imagem mamba pra gente saber que ela é um pouco diferente, né? Então beleza, ele tá aqui pegando do zero, não tem nada de cache, ele nunca utilizou uma imagem dessa máquina começando com a imagem mamba. Então desde o comecinho, ele faz tudo, certo? E aqui vai rodar o comando pra instalar, vai instalar nesse ambiente NF pra tutorial com essa receita que a gente, o que era, o micromamba, ele funciona com a receita do ponda. Então é isso, vamos criar a imagem um preto isolado, assim, de aqui e aqui no mais, mas que os pacotes foram gerenciados, instalados utilizando o micromamba que usou a receita do ponda. Então isso é um padrão ouro, na minha opinião, certo? Encontre ele vai instalar, vou adentrar um pouquinho mas você fala assim, como esse tb terminado eu posso rodar como antes, né? E dá essa nova imagem agora, que vai ser a imagem como antes, tinha o salmão mas a diferença é que agora contém, né? Utilizando o salmão que foi gerenciado e instalado com o micromamba, certo? E aí a gente vai tranquilamente executar o doker aqui dando esse novo, minha imagem mamba, né? Então vamos terminar aqui Enquanto isso, já vou editando aqui o nextflow.config Vou falar aqui, olha, eu quero que você utilize esse container para todos os processos e o container é minha imagem mamba que a gente criou agora, certo? Fecha ele e vou mandar esse comandinho aqui e vou abrir um outro terminal aquela variável de ambiente ela não foi pegada então está começando com 2.10 aqui como é, a gente cai ainda com 0,4 mas enfim, isso também está funcionando, né? Estou utilizando eu posso saber aqui de novo, né? Estou com o config estou usando essa nova imagem minha imagem mamba que a gente criou agora que é um container doker mas que foi a instalação ao invés de utilizar aquele curva, baixar um arquivo da internet que pode mudar de canto eu vou utilizar um micromamba para baixar do repositório do condom o salmão, o module QC instalar nesse container e a gente consegue utilizar esse container ainda assim, Marcelo o modo trabalhando, né? Tem que criar a imagem de modo, ninguém, o modo QC são programas super utilizáveis ninguém via uma imagem para utilizar a prontinha já é aí que entra o biocontainers o biocontainers é um projeto que ele busca ter uma imagem pronta para você utilizar para cada receita que ele protocola, pacote que tem nos repositórios do condom, certo? Então ele tem, por exemplo, uma imagem pronta para você do fastQC, nas versões que existem então aqui esse comando, ele baixa uma imagem do fastQC 0.0.11.5 certo? Então você não tem que criar mais a imagem Marcelo, mas porra, uma imagem só com um arquivo, essa é a questão é, tem 2 mãos que você pode fazer eu posso ter uma imagem que você utilizou no primeiro dia que é uma imagem do Docker com tudo o que o apelete precisa ou eu posso ter uma imagem para cada tarefa é muito mais fácil você manter e criar uma imagem para tudo só que tem vários problemas com relação a isso então na hora que acontece um problema, por exemplo é difícil identificar um tal problema porque é uma imagem com tudo então alguma tarefa deu problema será que qual o fato dessa imagem que tem o problema certo? Sem contar que todo vez que você cria uma tarefa você vai criar uma nova imagem do Docker desculpa, vai rodar um novo contêiner se a imagem for muito grande, demora mais tempo, mais ramco, mais disco se você está fazendo compração na nuvem você tem que baixa essa imagem, baixa o arquivo você paga por essa transferência entendeu? Então é muito mais custoso demorado e ineficiente imagens grandes então o padrão ouro que a gente indica é que cada tarefa tem uma imagem do Docker que faça o mínimo que a cada tarefa precisa para serem mais muito rápidas de carregar de fechar, de baixar, de transferir e assim por diante e o meio contêiner também faz muito bem isso ele tem as imagens especificamente para a ferramenta, entendeu? Então o exercício que ele tem aqui, ele coloca é você justamente conseguir erradar o script 2, certo? Então bora, o que tem o script 2? Ele tem só o processo de índex muito simples, eu utilizo o Salmon para criar um índex, então eu vou abrir aqui o meu nextflow.conf eu vou apagar essa instrução para utilizar esse conteúdo do Docker então se eu rodar não vai funcionar mas aí o que ele fala, o exercício que a pergunta, não é? Utilizo o biocontêiner em vez de criar a imagem e a gente sabe que no Cuié Otauspedado, pode procurar lá no site tem uma imagem do biocontêiner para o Salmon, eu vou rodar, dizer, e eu dou essa imagem, como só tem um processo que é o índex, ele vai fazer essa imagem e aqui vai funcionar, certo? Demando um pouquinho, porque ele está baixando a imagem, porque ele não utilizou ela, então ele está baixando a imagem ele pagou tudo aqui ele está baixando a imagem, certo? Demando um pouquinho é, tem abaixado, e agora está executando. O outro exercício é você fazer isso com o script 5 não só para o Salmon, como a gente fez agora, mas também para o FastQC Então, se vocês querem pausar o vídeo, tenta fazer, pausa aí e vamos ver agora o resultado, porque o resultado é só você ir no arquivo do processo, né? Aqui eu escrevi 5 e tem aqui o processo de índex e o processo de quantificação então eu só vim aqui e adicionar uma diretiva, aquele container e colocar o nome desse container, certo? Então para o FastQC, esse é o que a gente faz para o FastQC e essa aqui, que é eu do Salmon, certo? E você pode muito bem checar até aqui para ver direitinho o que está acontecendo dentro de cada tarefa, como eu mostrei aqui então o code o work, 53, 0bd comando.run você consegue ver aqui a linha que o docker utiliza, né? Então docker run, CPUs por padrão, a diretiva de CPU é um, a gente falou no primeiro dia sobre isso criando aqui o volume do volume, o detral de trabalho um entry point que é o bash as permissões, o nome e aqui o nome da imagem, certo? Então dá para checar direitinho se está como você gosta de que fosse. E aqui nós chegamos ao fim da sessão, certo? de gerenciamento de dependências e containers, quando a gente viu um pouquinho de docker, como criar baixar, configurar containers e como instalar pacotes e gerenciar as instalações com o conda e o micromamba e terminou juntando os dois, né? como utilizar containers cujos pacotes instalados são gerenciados pelo conda ou para o micromamba e o micromamba que entra nesse de graça para você, tudo pronto, né? Então você deve fazer uma pausa, tomar uma aula dar uma revista no material treinamento podem pausar o vídeo, certo? Fica parecendo como se de fato ter alguma falso para mim, vocês podem parar o vídeo e fazer um intervalo pra vocês. Então, agora continuar, certo? Aqui, o próximo capítulo, que é o de canais Esse conceito é importantíssimo. A gente viu no primeiro dia, assim como no segundo, um pipeline, um fluxo de trabalho, né? Que se olhar composto de processos, são etapas e canais que comuniquem esses processos Aqui, tamo um exemplo, né? A primeira é a tarefa alfa, é a saída dela, tudo que uma tarefa emite e você fala que é a saída dela é implicitamente convertido canal, então aqui eu tenho uma saída de cada uma das tarefas, o primeiro foi uma saída X, depois um V, depois um Z, ele transforma isso em um canal que é uma fila acícrona, certo? Unidirecional, sempre, da saída de um processo para entrar de outro, e ele vai entrar aqui na tarefa beta, certo? Então tem os dois processos com um canal entre eles para permitir essa comunicação. Os canais eles têm basicamente dois tipos, tem os canais de fila e os canais de valor, certo? Os canais de fila é o que a gente tem que falar até aqui, então é uma fila, o primeiro elemento é sair, desculpa, o primeiro elemento é entrar, o primeiro elemento é sair, ele é um direcional, ele é acícrona, beleza. Existem uma coisa, uma das fábricas de canais que são metas, são funções que criam canais para a gente. Quando os canais não são criados impriscitamente, quando eu quero criar de forma explícita, eu vou utilizar uma fábrica de canal e tem várias, a mais famosa talvez seja o channel.ov, que é um canal de alguma coisa, pode criar um canal de qualquer coisa com essa fábrica de canal, certo? Quando aparecer esses bloquinhos de código com mais, você pode ficar no mais para ter uma descrição, certo? Então aqui eu estou falando, vou utilizar a fábrica do canal channel.ov para criar um canal que tem três elementos, o número um, o número dois e o número três. E eu vou salvar esse canal em uma variável chamada canal, passei o nome que eu quiser, aqui eu coloquei canal. Quando você digitar o príncipe do canal, ele vai mostrar o conteúdo do canal de forma crua de membros assim, em programação, a ver algumas coisinhas, certo? Mas quando eu quero de fato ver os elementos do canal, que eles sejam emitidos elementos por elemento, eu vou utilizar uma função chamada view, que é o que é o operador do canal. O que é um operador do canal? São funções que atuam sobre canais. Geralmente emitem canais, né? Então o view vai imprimir o conteúdo, vai ser um, dois, três, ele imprime o conteúdo do canal. O print é o mais bruto, é o conteúdo cru, digamos assim. Então aqui eu vou inserir isso muito simples, né, para criar um arquivo, agora criar aqui um exemplo, o .nf, não precisa ser .nf, mas o padrão utiliza isso, certo? Eu gosto de usar com indentação assim, e essas são os espaçamentos, né? Eu acho que é mais fácil de ver. Então vou colocar um, dois, três, certo? Vou criar um elemento com um canal com três elementos, e eu já vou emendar aqui o view. Eu não preciso salvar uma variável para depois vê-la, eu posso dizer assim, ou se puder, eu posso já engatinhar tudo, eu quero criar um canal com um, dois, três, eu quero ver o conteúdo. Então, ops. Então eu venho aqui e vou rodar um nextflow, run, meu exemplo, .nf, ele vai imprimir um, dois, três, porque é isso que a função view faz, certo? Vou criar esse aqui, um, dois e três. Eu poderia muito bem também salvar o print, porque não é um operador em canal, então ele não é um sobre canal, assim, como eu estou falando com esse ponto, né? Então eu posso falar que eu tenho um canal, salvar, sim, e vou dar um print canal. Então aparece uma coisa mais feia, digamos assim, porque ele imprime o conteúdo, de fato, cru do canal, certo? Ele tem aqui um dataflow, que é essa, um dataflow stream, você raramente vai utilizar o print para que meu canal, 99,9% das vezes, se você quiser fazer alguma coisa com um canal, você vai utilizar um operador de canal, 99,9% quase sempre, você vai querer utilizar um operador de canal para interagir com o canal, certo? Então isso é um canal de fila, porque fila, porque é uma fila de elementos. O segundo tipo de canal, também como o canal singleton, é um canal de valor. E ele tem esse nome porque ele é um canal que tem apenas um valor. Para criá-lo, você vai usar fabricando canal channel.value, certo? Mas também qualquer operador de canal, perdão, qualquer operador de canal que eleimita apenas um elemento, ele implicitamente também vai gerar um canal de valor, certo? Então a gente pode fazer aqui um experimento, criar esse pipeline aqui, ele cria dois canais, um canal um e canal dois, um tem três valores, o outro tem um, o nome do processo que eu coloquei são, a entrada são duas variáveis, x de dois elementos, x de nítido, eles são valores, pode ser qualquer coisa aqui, um valor, a saída é o extender auto-cube, saída padrão, a tela, certo? E o que ele vai fazer é o script, ele basicamente vai somar essas duas variáveis, que é para escapar, para o BESH executar essa soma, certo? E aí do fluxo trabalho, eu vou dizer como é que é o primeiro dia, como vai ser qual o processo utilizado, o que for, e eu vou falar, eu quero rodar o processo de samba com o canal um e dois, certo? E vou chamar o meu para sair desse canal. Como eu falei, tudo que um processo emite, implicitamente vira um canal, então vai sair um canal desse processo samba e eu quero ver o conteúdo dele. Então eu moro a vir aqui para o exemplo .nf, e agora eu substituí com isso aqui, e eu vou executar esse pipeline, esse exemplo com .nf. Comi um pouquinho aqui para ter tela, e ele vai dar essa dois, por que dois? Eu coloquei aqui um, dois, três e um. Você pode imaginar que se eu quero somar os dois, isso seria um mais dois, mais três, certo? E aí que entra uma coisa interessante, se você executar com esse processo, menos 10 que é um, que é um padrão antigo da linguagem, do Nexford, do TCL, né? Ele não utiliza mais, mas é interessante poder fazer isso, porque você vai ver o conteúdo do canal do fão mais crua aí, do que é mostrado hoje, certo? Vou dar um pouquinho de alterado aqui, para dar um print ali ali no canal um, print ali ali no canal dois, porque o conteúdo crua desses canais, certo? Não é verdade que tem que ser bem diferente aqui, porque a DSM mudou, isso aqui não iria funcionar. Então, vamos salvar, vou dar um clear aqui, para ele limpar a tela e executar o nosso pipeline, está muito simples, é criar dois canais e imprimir o que eles têm com o print ali ali, certo? Então, vocês vão ver que o que acontece, eu tenho aqui o meu primeiro elemento, que é um, dois, três, e eu tenho uma pila de veneno, um poison pill, aqui também, um e poison pill. Todo canal de, todo canal de fila, ele tem um poison pill, que é o que entra no Nexford, que parou ali. Então, quando você chama um processo para criar uma tarefa, ele verifica se todas as entradas não são poison pill. Se todas as entradas têm novos elementos, eles executam a tarefa. Se uma delas tem um poison pill, ele para aí. Por isso que a saída desse pipeline aqui, ele é dois, por isso que a saída é dois, porque ele fez um, mais um, rodou. Na próxima vez que ele chama esse processo para gerar uma nova tarefa, ele fala, olha, o xim é C2, mas o Y, poison pill. E aí a tarefa não executa. Marcel, mas se eu quiser fazer um, mais um, mais dois, mais três, aí você vai criar um canal de valor. Que é um canal de valor, que ele tem apenas um elemento, ele não tem pila de veneno. Então ele pode ser chamado inúmeras vezes. A gente fala que ele pode ser consumido, o canal pode emitir o valor inúmeras vezes. E é o que a gente vai fazer. Ah, aqui assim. Vou voltar aqui para o exemplo. Vou colocar o velho aqui, certo? Vamos rodar o pipeline. Agora, como esse é um canal de valor, ele vai fazer um mais um, um mais dois, um mais três, e vamos ver aqui a saída. Salve com o ximple. Vou ver esse exemplo. Vou ter aqui o volume. Esse é o pipeline que vai rodar agora. O ximple.nf. Jesus. De novo, a reivindicação. Ximple. Agora eu vou mostrar o dois, três, quatro, um mais um, dois, mais um, um, três, mais um. Dois, três, quatro. Beleza. Aqui tem até um force da verdade. Por quê? Porque eu poderia deixar como o OV, que é um canal de fila. Mas como o operador force, ele é um operador que emite um canal com apenas um valor, que é o primeiro elemento daquele canal, ele automaticamente vira um canal de valor. Lembre-se que eu falei. Ele é um canal de valor, que é channel.value ou eu posso chamar um operador que emite um elemento e automaticamente esse canal de um elemento virará um canal de valor. O que aconteceu aqui? Eu peguei o canal dois, que ele é de fila. Utilizei o first, ele virou de valor e rodei. Então, é como fazer agora. Porque antes eu tinha colocado channel value aqui, como vocês viram. No canal de valor. Uma outra coisa que ele pode fazer é também dar só um... Acho assim funcionar também. Um único valor, uma variável normal. E quando eu dou um valor de uma variável normal para um processo, automaticamente esse valor é convertido em um canal de valor. Eu acho funcionar também. Vou dar um parâmetro, por exemplo, coincidindo com uma coisa, automaticamente, como é um valor só, uma variável normal, uma variável de valor, certo? Então, como já falamos, nas fábricas de canais são funções ou métodos que criam canais a partir de dados que não são canais, né? Então, o value de aviut, o channel value eu posso criar aqui, tem um valor que é nada, um valor que é um string, olha você, um valor que é uma coleção, é uma lista com cinco itens, mas é um elemento só, esse canal tem um elemento. O of, que é bastante prático, você pode criar o que você quiser. Strings, números aqui, se quiser. E aqui eu posso utilizar o view e utilizando uma closure, que já lembrai o que são clausuras, né? É um operador e eu quero não apenas mostrar o número, um, dois, três, um, três, cinco, sete aqui, né? Eu quero que antes tenham esse string falando número e eu vou utilizar o it pra cada um desses iteráveis, né? Mais uma vez, vamos deixar já essa sessão de Groovy, onde ser falado com mais detalhes, por hora, não se preocupe nisso. Com isso, apenas sabe que você pode fazer isso aqui pra aparecer número um, número três, número cinco, sete, certo? Você pode utilizar essas faixas, né? Então eu quero de um a vinte e três, pra eu ter que digitar tudo, quando é que você vai completar esse canal que tem vinte e três, de quatro, vinte e cinco elementos, né? Números e strings. Você pode misturar tipos de dados diferentes. O from list, ele vai pegar uma lista, né? Uma coleção, aqui eu tenho uma lista com dois itens, a partir dessa lista, e o viewer vai imprimir, olá, um mundo, que são cada um dos itens. Vamos ver como é que fica isso aqui. exemplo.nf substituir nextflow run example.nf O que isso vai acontecer? Se você dá um pausa no vídeo, vamos lá. Olá mundo, então ele tem uma lista, ele converteu essa lista pra um canal, onde cada item da lista é um veramento do meu canal, certo? O from path, que você utiliza aí quando você vai ter um canal de pastas ou arquivos, mas eu tô falando que o channel.all você quiser no channel.all, mas pra arquivos, o mais indicado é o from path, porque aí sim, o nextflow vai entender que não é só o nome de um arquivo, é um arquivo de fato, e aí você pode pegar partes do arquivo, sua extensão, tem algumas funções, né, métodos que ajudam você a trabalhar com isso. Então você espera, né, ao menos um globe, né, que no caso eu vou pegar todos os arquivos desse diretório que terminam com o .csv, então cada aqui vai ser um elemento do meu canal, certo? E se você colocar todas as teriasis, ele vai também pra dentro de outros subdiretórios, né, cada pasta.Temos opções aqui, certo? Você pode adicionar essa fabrica do canal, geralmente as fabricas do canal, elas têm opções, né, então checa a sua arquivo exige, você vai ver mais detalhes, aqui é o globe, que são esses padrões que se colocam com símbolos pra completar, né. E aqui ele tem um exercício. Utiliza o metro channel from path, pra criar um canal, emitindo todos os arquivos com o subpixel.fq no diretório data.gl E qualquer subdiretório, então eu acabei de falar, né, quando tem os dois esteriscos, ele vai percorrer os subdiretórios dentro também. Então já é uma parte da resposta, essa pergunta. Além dos arquivos ocultos, escondidos, né, geralmente tem um ponto na frente no límite do seu macOS. Aqui tem justamente uma opção, que é o hidden. Quando o hidden for true, ele inclui aqui os ocultos nos caminhos resultantes da expressão que você colocou, né. Então quem quiser tá fazendo, pausa o vídeo e vamos pra solução agora. Então eu vou dar um channel.from path com dois esteriscos, eu quero que ele percorre os subdiretórios e hidden true. Então bora criar, agora aqui o nosso exemplo.nf e bora fazer aqui, como eu gosto, né, limpaçãozinha organizada, é um canal de caminho e eu quero todos os arquivos .fk, dentro dessa pasta e subdiretórios desta, e eu quero incluir os arquivos ocultos. O next flow, run exemplo.nf e ele vai mostrar como é um canal, o teu view por linha, cada elemento do canal, certo. Vamos ver como os elementos tem nesse canal, tem uns seis aqui, né, isso. Que eu langue um e dois, liguei um e dois, gate um e dois. Beleza, aprendemos já como é que utiliza o channel from path, que é bastante utilizado essa fabrica de canal. Tem também o from file pairs que a gente viu no primeiro dia na nossa prova de conceito, Garnc, certo? Então você dá uma expressão deste formato aqui e ele vai pegar o gate um, gate dois, liguei um, liguei dois e vai criar com a tupla, onde o primeiro item desse elemento, essa tupla é o ID, a par do nome e o segundo item é uma lista dos pares e arquivos, certo, a gente tem a saída, lever, tem o endereço do um, endereço do dois, gut, tem aqui o endereço do gut e o caminho do gut dois, e assim por diante, certo. Nesse caso, eu acabei falando aqui no from path, tem que ter um logo, na verdade me enganei, não precisa ter um asteris no from path, mas o from file pairs, ele tem que ter pelo menos um carácter poringa, estrela, né, que são qualquer arquivo que termine assim as opções aqui. Você pode ter com mais calma. Aquele path utilizando isso, mas utilizando meio flat true, que que é essa opção de flat true? Ele gera, os arquivos mais profundos como únicos elementos nas tuplas repetidas, né, para dar uma olhadinha e ver como é que isso aparece, vamos para ver isso assim, sem o flat e com o flat true, certo? Então, eu vou dar, não precisa ser, só para organização, você não pode ter tudo em uma linha se quiser, né, você pode ter o flat true, certo? E por executar isso aqui. Então, vai ter as tuplas, com o identificado do arquivo e os pares. Então, gut, e aí tem o segundo elemento que é uma lista, tá? Aqui, eu estou selecionada com gut e gut 2. Se eu der a opção aqui de flat true, que é para planificar, por exemplo assim, vai ficar um pouquinho diferente. São, não são mais dois, dois itens no meu elemento, né, que seria o id e o segundo item que são os arquivos. Ele tem agora três itens do elemento, que é o gut, o arquivo e o arquivo, você não tem mais a tupla, né, ele é um elemento só. Aliás, você até tem uma tupla, mas não são dois, não são dois itens, id e arquivos, são três itens, id, arquivo, um, arquivo dois, certo? Você tem que ser uma tupla que são uma variável, uma variável com vários elementos, né? Então, o from as array, o as array, ele tem uma base de dados do NCBI, ou alguns arquivos de informática, então você pode usar o from as array usando o id e configurando a api, aqui tem como você configurar o api do NCBI, né, para baixar esses arquivos. Então, se você não tem que ler os arquivos no teu computador, você fala, olha, eu vou fazer um estudo, com esses as arrays aí diz aqui, baixa para mim, boda, que vai baixar, colocar um arquivo correto, alimentar para os processos e assim por diante. Aqui ele tem um exemplo, né, from as array, api, que você consegue ver os arquivos que ele baixou no from file pairs, id, arquivo um, arquivo dois, que aqui é para random, certo? Então, mais uma vez, esses, esses, esses as fabricas de canais, assim como outras coisas que tem suporte na tribunal nextflow, você não tem que se preocupar com baixar o arquivo, colocar o nome, ele já faz esse tratamento para você. Arquivos de texto também podem ser lios, certo? E transformados em canais, em elementos de canais, aqui eu tenho um app, e eu vou utilizar o operador de canal, certo? Não é uma fábrica, né, ele é um operador de canal, a fábrica está aqui, que é o from path, o operador de canal split text, ele vai separar o meu texto por linha, né? Mais uma vez, pode ficar nos mais aqui da minha informação e pode ir diretamente, não dá para começar no nextflow, tanto aqui em channels, ver todos os channel factories, todas as fábricas de canais, certo? Eu posso ver em operadores e ver em text. Posso ver em ele, e ele fala, vai separar, assim, assado, eu posso, ah, a cara 10, e a cara 10 linhas eu quero um elemento, certo? Vamos olhar aqui por linha. Beleza. Então, aqui ele fala, utilizar o by2, né, para fazer, a gente pode rodar, porque esse aqui ele está aqui no repositório, então posso executar ele para ver o que vai acontecer. Então, eu coloquei by2, então vai fazer um elemento do meu canal, ele vai ser duas linhas, aqui é duas linhas, duas linhas, duas linhas, e essa função subscribe, ela é interessante, porque ela aplica a função de sua escolha para cada elemento emitido do meu canal, então sempre que foi emitido em prima, é um elemento, mas adiciona em fim do globo também, eu poderei colocar aqui by3, e ele me daria blocos de três linhas, cada três linhas do arquivo de texto é um elemento do meu canal, seria bom, nós temos aqui três linhas, três linhas, como se eu tenho sete linhas de arquivo no final, ficou com um, certo? Eu posso ter dez, e aí eu posso também fazer uma clausura aqui, mais uma vez, vamos ver mais detalhes, clausuras são blocos de códigos que são passados como argumentos para funções de programação, certo? Aqui eu estou apenas falando que, para cada elemento desse canal, é o bit, que a gente viu, que é o iterável, para cada elemento desse canal, ele é um arquivo de texto, converta para uppercase, coloca em maiúsculo, certo? Eu poderia colocar um contador, que eu coloquei em zero aqui, sempre cada linha, um, dois, três, quatro, e não só colocar em maiúsculo, mas remover também espaço em branco, você pode ir acrescentando várias funções para cada elemento, certo? Aqui, modo mais simples fazer isso, os arquivos CSV, que são arquivos tabulares, os elementos, os valores são vírgula, vírgula, vírgula, comma separate value. Então, você pode utilizar o split CSV, que é um outro operador, vamos ver mais detalhes já, já, um outro operador, que ele pega um arquivo de texto, ou dados, né, o que for, e ele vai separar, ou usa mesmos com base nessas vírgulas, né, a gente pode primeiro ver o que tem nesse data, meta, page 101, o que tem aqui dentro? É um arquivo de texto, quando tem valores separados por vírgula, que tem aqui em cima, até o nome da coluna, é o deiri paciente, ao giro, as 3D, beleza. Se eu pegar esse código aqui, e salmanha.nf e rodar, vai fazer o quê? Pegar esse arquivo de texto que a gente viu, ele vai usar o split CSV para interpretar como um arquivo com valores separados por vírgula e eu vou dar o view para ver os elementos do meu canal. Embora, aqui eu vou dar apenas a primeira e a quarta coluna, como você diz ela, os índices. Quando você não dá nenhum nome por padrão, é o it, que a gente já viu it nas clausuras, mas você dá um nome e só colocar antes o nome para essa setinha, o que é chamado de linha, a primeira coluna da primeira de cada linha e a terceira luna de cada linha. Se eu dar um cat aqui, vocês vão lembrar que a primeira tem esses idês e as quartas, um, dois, três, quatro, vai ser esse número aqui, três, que está aparecendo aqui, né? Então eu peguei um arquivo CSV e eu estou imprimindo de cada linha a primeira e a quarta coluna, assim que esse operador funciona, certo? Também posso trabalhar com vários exemplos, você utilizando o cabeçalho para utilizar o nome, aqui o patient ID, em vez de zero, um, dois, você pode colocar o nome da coluna em si, certo? Também dá para trabalhar com TSV que são valores separados por tabulação, portabe, então você vai usar o split CSV, mas vai usar a opção sepe de separador e faraca separação, é o tabulador, um carácter de tabulação, pode vir aqui no operators, split CSV e vai encontrar aqui todas as opções dele que a gente está vendo, certo? De separador, de cool, de buy e assim por diante. Tem aqui um exercício que ele pede, que para você ver um pouquinho, deixa você testar e fazer esses exercícios sozinhos posteriormente, depois checar a solução sempre é bom testar, realmente tentar fazer, se não conseguir aí, ou quando conseguir viver a solução, ouvir no select e perguntar se estiveria com a dúvida, certo? Então aqui tem os filmados de arquivos mais complexos do que o CSV, o texto puro, tem o JSON, e aqui tem uma função para poder trabalhar com isso, certo? Conseguir extrair os dados no formato JSON, também tem o EM, o EM foi o que a gente viu do condo, eu sei que isso é do condo, eles são inscritos em email, porque eu consigo interpretar um arquivo do email com essas funções, e uma outra coisa legal é, eu já comecei a dar uma pinceladazinha em módulos, é a empresa, essas funções aqui para trabalhar com email, essa função para trabalhar com JSON, você pode muito bem salvá-la como um módulo fora do teu código, do pipeline e você apenas chama ele, certo? Então eu posso criar um arquivo para fazer isso aqui, então aqui no exemplo do email, por exemplo, eu vou no exemplo, vou em F, colocar aqui, o arquivo existe, esse arquivo data meta regions com o email, e aqui algumas regiões com o formato email, ele vai carregar e vai imprimir a tela, agora eu vou dar aqui, beleza, eu vou direto com o arquivo aqui, graças o traço feature, separando o page da ID, beleza, digamos que eu nunca fazer isso, eu vou fazer um pipeline completo, em vez de dentro do código colocar, o que a gente viu, eu vou criar dentro do diretório módulos, criá-lo um arquivo do parça, né, analisadores, vou colocar aqui dentro, como fazer isso com email, certo? E aí no meu arquivo de exemplo, eu apenas importo essa função, não é verdade nem isso que vai ser feito, vamos lá, vou colocar aqui o pipeline, o arquivo módulo já está criado e dentro dele já tem o password, né, que aqui dentro vai ter, no caso, o código aqui do, do pro email, do Jesus Lerper, beleza, ele criou aqui de bola, no pipeline, em vez de escrever, traduzindo, ele apenas vai importar desse arquivo, essa função, e aí você vai conseguir já pegar os dados desse arquivo de JSON, fazer o parsing, a interpretação com o formato de JSON, e aí você vai passar pra função um pouco, vai trabalhar com ele, certo? É nessa etapa que a gente termina a sessão de canais, falar um pouco de operadores, ficar um pouco confuso porque você aprofundou um pouco mais sem reinterpretar em detalhes, mas eu tenho que saber aqui que os canais são o módulo de se comunicar entre os processos, os elementos na série de um processo criam um canal, e vai adicionando os valores da saída desse canal que vai entrar no próximo processo. Canais, eles são implicitamente criados quando você dá um valor único, certo? Ou quando você tem um canal de fila, mas você usa um operador que retorna um valor, então ele vira um canal de valor, tem essas construções implícitas, e também tem criação de canais explícitas, e quando você utiliza uma fábrica de canais, com os channel factors, e as fábricas de canais, channel from path, channel value, e assim por diante. Então tem as criações explícitas e implícitas de canais, que são fundamentais porque os processos só recebem canais e só emitem canais. Obviamente dentro do processo da tarefa vão ter elementos, mas para entrar nele tem o canal e na saída vai ter um canal, certo? A próxima sessão, ele é de processos, certo? Então no nextflow ele é a primitiva mais básica, a etapa de um pipeline que no nextflow é um processo, então cada etapa é um processo, é muito importante entender direitinho como utilizar esses processos, certo? E nós temos aqui um exemplo muito simples, que é um processo chamado gigaolá, não tem entrada, ele não colocou saída, apenas ele tem, o que ele vai fazer é dar um eco, olá mundo, certo? Mas na verdade, na vida real, digamos assim, os processos são bem mais complexos, eles podem ter até cinco blocos de definição do primeiro bloco de diretiva, que a gente já viu um pouco container, condas, CPUs, são diretivas, são declarações do primeiro bloco do processo com departos opcionais, tem o bloco de entrada, que é onde você especifica os elementos dos canais que você espera que entre nesse canal, tem o bloco de saída que vai dizer como são os elementos que vão sair desse processo e vão ser incorporados em um canal de saída, certo? Tem o bloco de entrada, que é a expressão loja que diz quando aquele processo vai ser executado, então se eu tenho elementos e mando para um processo por mais que tenha elementos para entrar no processo, se a expressão do when for falsa, o processo não vai gerar instâncias, não vai gerar tarefas para aqueles elementos. E o último bloco é o bloco de script, que define o que de fato vai ser feio naquela etapa, que vai ser executado. Então aqui diretivas tem que ser antes do bloco de script, que temos as coisas que já vão ver, você script, showexec e a gente vê isso, certo? O bloco de script, ele é um dos principais, porque ali que acontece a mágica, lembrando assim, ele se for várias linhas, você vai ter que utilizar três aspas duplas e fechar com três aspas duplas ou três aspas simples. Se for apenas uma linha, não, se não mudiramente são várias linhas, você vai ter uma string mutilinha que tem que ser, como essa série, um dos modos, né? Um dos três aspas simples. E aqui o bloco de workflow chamando esse processo. O padrão, tudo que você coloca no bloco de script, ele vai interpretar como bash, programas de linhas de comando, expressões de bash, expressões de shell, o padrão é isso que ele vai esperar que tenha ali. Mas obviamente, até como é o primeiro dia, esses paipilares costumam ter escritos em Python, ER, bash, programas, compiladas, enfim. Como é que faz? Uma outra linguagem interpretada, você vai utilizar o Shibang daquela linguagem, que eu já falei no número dia, que é uma expressão que indica qual programa utilizar para interpretar aquele código de script. Aqui eu tenho um programa em Python, eu coloco a Shibang do Python. Se fosse em ER, eu cheguei a Shibang do ER e ia sim podiante, certo? Lembrando que, geralmente, quando essas existências começam a ficar muito longas, programas mais longos, o ideal é que não fique na mesma pasta do seu arquivo.nf. E lá dentro de Ertobin, você coloca os scripts que você quer utilizar de permissão de execução para eles e, aí, tendo colocado na pasta bin, automaticamente o nextflow consegue encontrar esses arquivos como se fossem programas normais, certo? Você pode acessar variáveis dentro do bloco de script utilizando o cifrão, né? Então, aqui eu tenho um parâmetro de linha de comando, que é o dado, pelo compadrão dele é mundo, mas eu posso definir para salvar esse aqui exemplo.nf Então, eu vou criar um parâmetro para o dado, que o pelo compadrão é mundo, um processo full, que eu vou chamar, em que ele apenas imprime olá, mundo. Vamos rodar aqui nextflow, run, exemplo, nf. Eu acho que já mostrei que, quando você ver esse modo, ele não imprime nada até, ele imprime no arquivo de log. Se você quiser que imprime aqui, de fato, você digita um debug.true, que é uma directiva que fala, eu estou debugando, eu quero que tudo que seja impresso para a tela, apareça na saída do mainline. Então, ele vai colocar olá e esse parâmetro dado vai ser mundo, olá, mundo. Se eu passar aqui um traço-traço, dado, Marcel, ele vai dizer o quê? O que você acha que vai acontecer? Olá, Marcel, que é assim que a gente acessa parâmetros, né? É uma boa prática sempre ter valores padrões para os parâmetros, por quê? Se eu não tiver nada aqui e rodar novo, vai funcionar porque eu estou dando aqui um parâmetro Marcel, então vai ser dizendo olá Marcel, mas se eu não der nenhum parâmetro para esse dado, o que eu vou fazer agora? Não der nenhum parâmetro, como eu não coloquei um valor padrão? Aqui ele vai dar um e eu falando, olha, não tem valor para esse parâmetro, né? Aqui, ó, acesso ao parâmetro indefinido, que tem que inicializar ele para algum valor. Então, ficou Lú, olá Lú, porque eu não tenho um valor padrão e eu também não dei nenhum padrão nenhum valor na linha de comando, certo? Aqui ele tem um outro exemplo que eu utilizando um avaliado de ambiente, não sei se sabe, pelo Bash, Cifrão PWD, ele vai mostrar o dentro da atual, que eu poderia muito bem vim aqui e fazer PWD do modo como está aqui. A questão é que o modo como está aqui, o próprio NetFlow vai expandir isso de que modo? Que vai aparecer a pasta que a gente está agora. Por que? Eu estou rodando o NetFlow Run, aqui ele chega no script, tem o Cifrão, tem aspas duplas, ele já expande isso aqui. Então, se eu der um catwork, varro89, varro05, comando esse h, o que o NetFlow vai rodar, já está preenchido. O NetFlow, ele não vai expandir isso aqui, porque o próprio Bash já expandiu. Então, já está pronto aqui para se executar assim. Às vezes não é isso que você quer. Você quer que, só na hora da execução, que essa variável seja expandida. Então, você posar um contra bar aqui, antes do Cifrão, para impedir que isso aconteça. E aí, quando você rodar o NetFlow Run, ele vai no ponto comando com o dsh, vai estar esse PWD e só na hora da execução, que ele de fato vai rodar o que é a pasta da tarefa, dentro do work, e não a pasta, onde foi rodado. Então, se eu der aqui um catworkadf59, ponto comando esse h, ele vai mostrar a variável ainda, e não ela já expandida. Uma outra coisa que você pode fazer, em vez de usar o contra bar, é usar aspas simples, porque as aspas simples, elas não expandem as variáveis, certo? Você pode rodar isso aqui também, sem a contra bar do Cifrão, e ele também não vai expandir, e vai mostrar a pasta da tarefa. Em vez de ser a pasta, eu não estou executando o NetFlow, certo? Então, essa é uma diferença importante entre aspas simples e aspas duplas. Aqui, a pasta do trabalho de fato, aspas simples e aspas duplas, ela expande aspas simples, não. Uma outra coisa que às vezes você vai ter variáveis, vou botar aqui esse parâmetro mesmo, é um parâmetro aqui palavra, mas vai ser mundo, vou dizer que o meu processo, ele vai esperar uma entrada, que é um valor, eu não sei o que, mas é um valor, eu vou chamar de valor, o nome dele, e a saída vai para o standard output, beleza? O script, ele vai imprimir o valor e eu vou chamar aqui parâmetro palavra. Então, isso aqui não é um canal, é um valor, mas automaticamente ele vai converter isso em um canal de valor, certo? Então, vou rodar isso aqui, vou falar nada, porque já tem um valor padrão de palavra que é mundo, e lembro ir muito na tela. Tem que ter aspas duplas, expandir, ele substituir valor beleza, mundo. E se eu quiser a pasta, também veria a pasta, que eu estou executando o nextflow, coloco o cifrão, um pedame dele, beleza? A questão é que fazendo isso, não sei se está claro para vocês, está um pouco confuso o que é variável do nextflow e o que é variável do bash, de ambiente, do terminal. E aqui é igual, cifrão é igual, às vezes isso não fica tão claro, e aí o que é variável fazer? Tem gente que prefere ver usar o script, usar o shell. Como você usa shell, você consegue utilizar as variáveis do nextflow? Você não ganhou assim, ganhou branco. É. Desse modo, com exclamação, chaves, o que é do nextflow e o cifrão, o que é do bash. Então, eu alterei de script, que é o padrão, se não tiver nada é script, se estiver de script é script, mas você pode colocar o shell também você vai parecer a mesma coisa aqui é apenas a questão de saber que você consegue diferenciar no olho o que é variável do nextflow e o que é variável do bash, porque o símbolo ele é diferente, certo? Ah, a gente tem procurando interessante falar que... Outra coisa interessante é o seguinte eu poderia muito bem para a parâmetro, às vezes, é interessante fazer isso. Eu não tenho nenhum input, certo? No processo, mas eu quero utilizar um parâmetro. Eu quero fazer isso. Beleza. O que vai acontecer aqui se a gente rodar um pipeline? No entanto, como você pode utilizar essas chaves para deixar claro o que e isso é uma variável. Por que? Às vezes vão ter alguns métodos que você pode utilizar, como o que é variável. Eu quero que o mundo fique maiúsculo. Então, vamos lá. Quero dar o echo, essa variável e coloque em maiúsculo. Então, aqui, beleza, porque ele vai entender que isso é uma variável. Isso tem que ser assim. É do contrário. Aqui está o porquê, porque ele fala isso é uma variável e aplique uma função para essa variável. Então, às vezes, a interessa que você tem esse modo de utilizar e chamar uma variável do nextflow com as chaves, certo? Eu pensei que ia ter um exemplo aqui, mas não encontrei um exemplo com as chaves, mas enfim. Ah, eu acho que apareceu aqui no pipeline de Arnesic por introdução. Ele mostrou um exemplo, acho que eu já falei. Então, que ele fala aqui, ó. É, aqui ele fala os de va e vá com um exemplo variável. Um exemplo que ele dá aqui é aquele chamando para deixar claro que esse ponto aqui ele é relacionado ao nome da variável e não uma função sendo aplicada ou algo do tipo, certo? Um outro coisa legal é script condicionais. Você pode ter vários blocos de script. Um processo, ele só pode executar um bloco de script por vez, você pode ter vários blocos que você escolhe dependendo de alguma expressão lógica, certo? Então, aqui nesse exemplo é bem legal, eu gosto bastante. Esse exemplo aqui acontece. Ele fala, ó, eu tenho um processo full, que ele recebe um arquivo com entrada, certo? O que acontece? No bloco de script eu tenho três blocos de script na verdade. Verdão 2, né? Que é o quê? Se a variável paramos ponto compresso, né? Se o parâmetro compressa, o compressor por gzip vai ser esse bloco que é utilizando um programa gzip para compactar. Se não, se for bzip 2 vai ser esse bloco de script que é utilizando bzip 2 para compactar meu arquivo. Se não, se não for nem bzip 2, né? gzip joga uma exceção, você tem que terminar imediatamente o pipeline e vai dizer uma coisa e ele vai dizer, ó, o compressor paramos ponto compresso, né? Que você informou, ou é o padrão gzip, ou você falou traço-traço compressor na linha de comando que é conhecido, certo? E aqui eu chamo, né? O processo full passando a esse valor que vai virar um canal do valor. Então, olhando aqui para processos como a gente tá agora, a estrutura do processo, né? Os processos que tem um processo, ele tem um canal de entrada ou canais de entradas e cada elemento desse canal vai gerar necessariamente uma tarefa, né? Que é uma instância daquele processo. E ao final vai ter uma saída, um elemento de saída, que ele vai ligar a um canal de saída, de forma bonita, você não tem que se preocupar com isso. O próprio processo vai criar um canal de saída e vai enfileirando os elementos de saída que vão saindo, certo? O bloco de input, vamos começar a gravar com mais detalhes que a gente já usou várias vezes, né? O bloco de input, ele começa com o que a gente chama de qualificador, que ele vai dizer que tipo de elemento esse elemento é, e o nome dessa, da variável que vai se referir a esse elemento, chamado num, que tem três números, um dois três, são três elementos. Eu vou, no meu que falou, chamar um processo chamado exemplo básico, passando esse canal, esses três elementos, ele vai ter que o debug truque aparecer na tela e no input vai dizer que, ó, é um valor dessa variável, chamado de x, e ela contém um elemento do canal e vai colocar a tarefa, você vai sair um do processo, dois do processo, três do processo e assim por diante. É como está aparecendo aqui, né? Beleza. Com a consideração do seguinte, os canais, eles garantem que as entradas elas sejam entreves da mesma ordem que foram enviadas, certo? Então, se eu falar que o canal é um, dois, três, eu vou estudar primeiro o processo com um, vai gerar uma tarefa, né? Depois uma tarefa com dois, depois uma tarefa com três. A questão que não garantia que essas tarefas termine a mesma ordem. Então eu posso, por exemplo, passar um arquivo gigante com a tarefa com dois, e isso acaba causando que a tarefa dois acaba antes da um. Então, no canal de saída, que vai ser criar de uma família implísta, o primeiro elemento vai ser o dois. Depois um e assim por diante. E ele fará revir aqui, tarefa três, um, dois. Então, a ordem no canal de saída não é garantida, certo? Sem apontante em mente, por hora. Hum... E aqui eu vou ter, eh, trabalhando com arquivos e caminhos de entrada, então vai ser o pé, em vez do arquivo de aspas, eu estou dizendo que é esse o nome do arquivo, poderia ser uma variável que vai ser preenchida pelo nome do elemento, né? Mas aqui ele diz não, aqui é esse nome de entrada ou esse nome de saída, certo? E aqui no bloco de script, eu vou ter de fato o que eu quero que esse processo faça. E aqui eu tenho, justamente, chamando esse processo full com esses arquivos de leitura, certo? Ah, aqui eu tenho um exemplo parecido, mas utilizando uma variável, em vez do nome de arquivo. Aqui eu tenho exatamente a entrada, eu vou se chamar amostra para o processo de arquivo, aqui não. Aqui o nome eu não sei qual é, mas eu vou me referenciar a ele como amostra variável, beleza? Em alguns casos, você pode ter vários arquivos, então você tem vários elementos, meu canal tem 10 elementos no canal, mas eu não quero 10 tarefas, cada um com um canal. Então, você vai utilizar o que a gente chama de um operador, chamado collect, ele pega todos os elementos de um canal, cria uma lista que é só um elemento e transforma esses elementos em itens. Então, eu vou ter um canal com um elemento que é uma lista com 10 itens, por exemplo, certo? No passado, para quem utilizava o DSN1, para quem já conhece no actual tempo, tinha um qualificador que era o file para trabalhar com arquivos, mas ele é o melhor se utilizado, você geralmente vai querer utilizar o path, tanto para pastas como para arquivos. Então, você, por uma parte do tempo, não é o file que você vai querer usar, é o path, certo? É aquele que é um exercício, aquele que quer que você crie um canal contendo todas as leituras correspondentes ao padrão tal, certo? Então, ele quer que você faça isso com um processo e concatene em um único arquivo e imprime as minhas 20 linhas. Vou produzir-lo, fiquem à vontade e eu vou mostrar agora a solução. Então, eu vou criar leituras, um valor padrão que é uma pasta que a gente já conhece, certo? Ou você pode substituir essa pasta dando traço-traço leituras com outro globe, aqui seria gut1, liver1, lung1, eu posso querer o 2, 1 e 2 e se por diante. Eu vou criar o canal aqui, o channel é uma fabrica de canal de caminho, porque eu vou dar um caminho para ele com um globo que vai ser todos os arquivos naquele caminho e eu tanto posso usar no comecinho o nome do canal igual à fabrica eu posso utilizar o ponto 7 é uma questão de estilo, eu prefiro o ponto 7 acho que eu gosto dessa ideia de criar um canal assim assado, com isso, com as esperanças e no final salve para esse nome, eu gosto dessa ordem com o 7, certo? E aí eu vou criar aqui um processo que eu chamo ele concatene como a gente viu lá no pipeline da Arnecique, né, para fazer um conceito, eu posso usar essa direita de tag para dar um nomezinho para ficar aparecendo no log, né ele vai receber vários arquivos, certo? Então, eu coloquei o astelesco entre as que eu falo, eu não sei qual o nome eu sei que são vários, um ou mais, né a saída não é um arquivo e o nome deles você top em andeline 10 andeline linhas beleza e aqui eu vou pegar todos esses arquivos dar um cat o conteúdo de todos eles vou salvar em um arquivo que é um arquivo criado, certo? E vou depois utilizar o programa head para ter as primeiras 10 linhas desse arquivo e salvar num arquivo que é o topo 10 linhas então como vocês podem ver como vocês podem ver, ele tem aqui dois arquivos criados e o que acontece? Esse é um arquivo intermediário o nectron não está preocupado com isso ele está preocupado com a saída que você falou que é o topo andeline 10 linhas é isso que ele vai entregar o próximo processo e aí aqui tem o bloco de ouro cloco vai dizer ó, use o processo com catene para passe o processo com catene, o canal canal leituras com operador coléctrico quero só um elemento com todos os arquivos e no final imprima a saída para mostrar as primeiras 10 linhas, certo? Você pode também utilizar operadores para combinar canais, né então eu tenho aqui por exemplo o canal 1 que tem um, dois, três e o canal 2 que tem abc eu posso utilizar aqui combinar canais, perdão meio que bloquendo, nem a razão de operadores eu posso ter vários canais de entrada para o mesmo processo aqui eu vou passar esses dois canais, um e dois para o processo full, certo? e vai ter que o valor x, o valor y imprima x e y e vai imprimir você pode passar inúmeros canais para um processo tanto o canal de entrada como de saída também imprima aqui um a dois b, três c, certo? aqui beleza então a gente já viu no comecinho um problema que acontece quando os canais não tem a mesma cardinalidade, ou seja eu tenho dois canais de fila e o número de elementos é diferente, então após um pil de um canal vai bater mais cedo que ali outro e ele não vai continuar lendo aquele canal o modo de resolva isso a gente joga um canal de valor, aqui tem um exemplo um e dois e aqui a bcd dois canais de fila, um tem quatro elementos o outro tem dois elementos então quando eu imprimi isso aqui ele não vai imprimir o a bcd vai ser apenas um a, dois b porque chegou após um pil do primeiro certo? então beleza que ele mostra aqui quando você usa o canal de valor aí vai ser um a, um b, um c beleza tem um exercício aqui que é para você fazer um processo que vai criar uma tarefa para cada arquivo de leitura correspondendo a um padrão pau aqui e utilizar o teus canais de referência para todo ele certo? Então aqui tem a solução crie meu canal de leituras beleza, ele vai sempre receber esse comando aqui o canal leituras, né? Que tem as leituras e um parâmetro que aquele transcriptomo aqui come um valor ele vai virar um canal de valor e aí nesse caso não vai bater em pós um pil que é um canal de valor e ele vai rodar esse comando para essas leituras com esse transcriptomo. Então você consegue passar canais diferentes, tipos diferentes inclusive para um mesmo processo um outro coisa legal é esse qualificador de repetição que é o it, certo? O que ele faz? Você consegue ter aqui uma sequência sequência, porque hoje o frontpref tem vários arquivos aqui, certo? Posso dar um ls data prods, fa tem vários arquivos aqui, certo? E eu tenho uma variável que é uma lista de opções que eu chamo de métros, que eu tenho regular, expressos type off e eu vou chamar meu processo, eu vou passar para ele as sequências, os métros mas no qualificador eu vou falar olha esse modo, eu chamo de modo, né? Mas pela ordem, no caso do nextflow, é posicional os argumentos dos processos. O segundo é o métros, eu vou chamar de modo aqui dentro. Você vai colocar o itch o que significa isso? Que ele vai pegar essa tarefa esse processo e vai criar uma tarefa para cada um desses modos, então ele vai rodar a primeira sequência tem três sequências, então a primeira delas vai ser com os três modos e depois com três tarefas os outros três modos, três tarefas e assim por diante Então você pode até mostrar que vai ser muito saídas porque eu tenho um número rasuado aqui de sequências e eu tenho três modos para executar cada proteína dessa em um dos três modos Então a gente está aqui um pouquinho até o pé a gente vê, então tem 18 tarefas, né? Você pode ver aqui que esse arquivo BB11001 ele foi uma vez com saikoff uma vez com expresso, uma vez com regular Então às vezes você quer que ah eu quero com essa mostra ali com salmão e ali com high set Então eu quero que várias coisas podem ser como essa mostra, você vai ter um emite para ele repetir a tarefa para cada um desses modos para cada um das amostras Aqui a gente vai seguindo, tem mais um exercício que vocês podem fazer, beleza? Nosso canal de saída, mais uma vez como é que ele funciona? Vai ter um qualificador vai ter um nome e você pode dar um nome que vai ser fora do processo um modo de referenciar aquele canal saída que eu vou usar o emite não é obrigatório, mas muitas vezes não é obrigatório Então aqui eu vou ter o mesmo modo que eu tenho um valx eu vou ter um valx, eu quero que esse canal elemita um valor e aí esse valor eu vou conseguir pegar no próximo processo, certo? Então muito parecido com a variável de entrada eu posso aqui também ter um arquivo na saída, beleza? Ele salva aqui estou usando essa barra para ver como ele já viu com o PWD certo? Beleza Eu posso também, assim como eu posso ter muitos entradas, eu posso ter múltiplos arquivos de saída, então eu falo, vai ter um pé, começa com pedaço mas vão ser vários arquivos, um não mais não é só um, pode ser um, pode ser dois, três, quatro, dez, vinte mil isso aqui é muito parecido com o exemplo que ele viu no comecinho, para pegar uma frase que era o Lamundo, e ele quebrando em pedacinhos e tantos caracteres e aí no final, o que vai acontecer aqui, né? Vai separar em letras então eu posso rodar aqui vou colocar isso aqui, olá mundo, ele só olá, um pouco mais longo você não estava falando um pouco mais longa hoje mas eu acho que é importante a gente ter esses conselhos muito bem explicados, certo? mais claros possíveis então que você viu que ele separou o olá mundo um caracté que é um elemento e aqui é fundamental esse flat map que é ele que faz isso se eu tirar esse flat map aqui, que ele dá essa planificação se ele dá essa planificação vai ser um pouco diferente do resultado então ele fica uma saída aqui, ele é um canal você vê com alguns elementos que ficou cada arquivozinho e aqui na hora que o flat map, ele vai aplicar para cada elemento uma função que é de aplicar e aí a gente consegue a saída inicial que a gente viu aqui que é arquivo, o nome do arquivo e o conteúdo do arquivo que é uma letra de cada vez mais um exemplo mostrando operadores de arquivos que a gente vai ver com mais detalhes então começa a correr um pouco para não ficar ainda mais longo do que vai ficar aqui você vai ter nomes dinâmicos para arquivo de saída eu quero que o arquivo de saída nem só seja o que vai aparecer aqui dentro eu quero que seja parte de outra variável então o valor x que eu vou receber ele vai ser parte do nome do arquivo de saída, você consegue fazer isso a gente chama de nomes dinâmicos de arquivo de saída, certo? e aí pode ter entrada, saída composto, que são as tuplas que a gente fala, é quando eu passo um canal o canal é o que for, mas que cada elemento dele tem mais de um item não é um elemento que é um caractere ele pode ser um elemento que é uma lista de tuplas, então eu não sei se essas tradições composto, são as tuplas que a gente fala então tem que ter o qualificador de tupla e os qualificadores de cada item desse elemento aqui eu tenho, por exemplo, aquele fronfile que a gente viu, o primeiro item do elemento é o identificador e o segundo item é uma lista com arquivos então eu falo, ó, vai ser uma tupla o identificador é um valor, eu vou chamar de D amostra e o segundo item, ele é um caminho na verdade é uma lista de caminhos e eu conheci apenas um arquivo que é amostra.ban, então aqui eu vou dar esse exemplo trabalhando com isso, certo? tem aqui mais uma vez um exemplo que vocês fiquem voltando para resolver tem a solução, beleza? o bloco-vent que eu falei brevemente ele é uma expressão lógica, caso falsa, o processo não é executado então por mais que eu tenha um canal com vários elementos, se eu chamei o processo e a expressão ela falhou, não tem nenhuma tarefa gerada desse processo então eu posso falar que, ah, se os elementos eles são menores do que tanto ou começam com tal valor ou são assim, assado não execute, tranquilo, não vai executar ele tem um exemplo disso bem interessante chegam nas inventivas, certo? que são justamente esses valores do comecinho do bloco de processos funcionais, aqui ele tem um exemplo eu quero, eu quero para cada tarefa desse processo, dois núcleos lojas de processamento eu quero um giga de RAM, eu quero que utilize esse container, essa imagem de container para esse tarefa, esse processo para esse outro processo, eu quero uma outra imagem de container, eu quero usar o conda e assim por diante, certo? tem um almoço completo de diretivas manda eu começar do nextflow e aqui temos os exemplos das principais, né? uma coisa legal, a gente também viu isso na forma de concedir a NSIC, é que às vezes, eu não quero assim, tem aquela mesma passagem de trabalho ao work, um card de arquivo, mas tem muito arquivo intermediário, muito arquivo que eu quero de fato, de resultado, mas as passas são meio críticas, né? E pode ser que na verdade eu quero alguns desses arquivos últimos e eu quero salvar no local para ficar com os resultados bonitinhos, a gente fez isso no meu pipeline de NSIC, né? Se eu utiliza a direita de publish que eu falo, ó, esse processo blastsec especificamente, eu quero os arquivos que batem com algum padrão, aqui eu botei tudo nesse processo, mas eu quero que esses arquivos sejam salvos aqui, nesse local, e eu quero que esses arquivos sejam salvos, não apenas um atalho, que é que sejam copiados, beleza? Vou ter aqui um exemplo passando brevemente, porque a gente já viu de fato, no primeiro dia, certo? Na prova de concedir o pipeline da NSIC aqui você pode ter por exemplo, eu quero que na pasta raiz, esteja os arquivos desse processo, né? Terminazinha FQ aqui eu quero os terminas de contagem, nessa outra pasta, os empandoramas, você consegue organizar dentro da pasta de resultados e em contagem. E assim a gente chegou o fim, a exceção de processo, certo? Próxima, vai ser de operadores, certo? Então, aqui, eu tenho números operadores inúmeros, porque eles são muitos de fato, deixa eu forver aqui como se eles viram na verdade, né? Da argumentação, tem vários de vários operadores, isso é grande, aqui tem uma lista menor, mas ele é assim bastante grande, mas a ideia é que vocês saibam que operadores são finais, certo? E tem vários tipos, operadores de filtragem, transformação, divisão, combinação, bifurcação, operadores de matemáticos e outros também. Eu vou escolher alguns específicos bastante comuns aqui, porque a lógica é ser muito parecida. Você vai utilizar um canal e vai sair um canal e vai fazer alguma coisa. São muitos, então vou colocar em alguns que eu acho que são muito interessantes. O view, se já vira fundamental, ele vai fazer um operador mais importante. O que o MAP faz? Você tem um canal com elementos, quando você aplica o MAP a ele, ele vai aplicar uma função para cada elemento daquele canal. Então é um exemplo muito interessante aqui, eu criei um canal chamado NAMS, que tem quatro elementos, o número um, o dois, o três e o quatro. E eu falo, olha, NAMS, ponto MAP, aplicou o operador MAP nesse canal e eu quero que cada elemento tenha um seu que é, eu uso o valor padrão que é o it aqui, eu quero que você para cada elemento multiplique ele por ele mesmo, criei um novo canal e coloque esse resultado. E esse novo canal vai se chamar de quadrados, que é o que essa imagem mostra. Eu tenho um canal de números, eu vou multiplicar cada número por ele mesmo e eu vou ter um novo canal chamado quadrados, que é o quadrado de cada um desses números. Então isso é poderosíssimo, você pode fazer uma infinidade de coisas com cada elemento. Eu posso, por exemplo, ter uma tupla, onde tem o ID e os arquivos, você vai ter apenas os arquivos, ou apenas o ID e o segundo arquivo, ou o ID e a extensão do segundo arquivo e a passa do pai, entendeu? Você faz o que você quiser, é poderosíssimo. Isso talvez seja o meu operador mais poderoso da minha opinião. O Viu, a gente conhece que ele imprime os elementos consumidos, né? Ative o outro interessante aqui, aquele que tem mais exemplos do MAP, tem um canal com dois elementos, onde um elemento é o lá e outro elemento, onde cada elemento, ele vai ser repetindo sua ordem, ele vai ser aqui alô e vai ser ordem num, né? Ao invés desses números. Ou aqui eu falo, olha, eu quero, eu vou chamar de palavra, não vou chamar de it, porque eu acho mais legal, mas claro pra explicar, vai ser palavra, cada elemento e eu vou criar uma tupla. Então em vez de ter um canal com dois elementos, eu vou ter um canal com duas tuplas, onde o primeiro elemento da tupla é a palavra que já vem mesmo, mas o segundo elemento sai aqui. Então você faz coisas poderosíssimas, né? Com o MAP. O MIX, ele vai apenas combinar, porque eu tenho três canais, eu uso o MIX e eu tenho agora um canal com os elementos desses três canais juntos, né? O FLAT, a gente já viu no primeiro dia ele vai planificar, em vez de ter aqui dois elementos, cada um com três itens, eu vou ter seis elementos, ele planifica, né? O COLLECT, a gente já viu também, ele tem aqui quatro elementos, eu vou usar um elemento, que tem quatro itens, então o COLLECT, ele meu viu contrário do FLATEN, o FLAT, ele planifica o COLLECT, ele agrupa, né? O GRIPTUMP é bem legal, porque é muito comum, como você tem, por exemplo, vários arquivos, eu tenho um ID e eu quero agrupar por ID. Então eu tenho aqui, por exemplo, um canal com vários elementos, né? Cada lista aqui é um elemento, mas eles têm sua chave, um, dois, três. Então o GRIPTUMP é uma chave, eu posso usar uma opção para dizer qual que é o elemento da posição da chave, né? Por padrão aqui, a primeira ele ficou um, ABC dois, é o C e o A e o três é o B e o D. Então tem que agrupar por tuba, né? Então o join tem vários itens, o branch, eu gosto muito, que o branch, ele permite que você crie vários canais, dependendo de alguma condição lógica. Então eu tenho aqui, por exemplo, o canal que tem cinco elementos, um, dois, o branch e eu falo, olha, os elementos desse canal, que foram em menor que 10, eu quero que eles sejam colocados em um novo canal que eu vou chamar de pequeno. E os que sejam maiores do que 10, o maior é igual a 10, o que for, coloca no canal grande e esse canal vai ser o resultado. Só que esse resultado não é um canal, ele é um muti-canal. Como é que eu acesso ele? Resultado ponto pequeno vai ser o canal daqueles valores pequenos, o grande vai ser o grande. Tem também um elemento do canal anterior, eu quero que estejam nesse próximo, certo? Essas são tradições ao groove, né? É tudo que a gente já viu, mas talvez um pouco mais abstrato, talvez ele mostra o println, certo? Como fazer comentários em nextflow? Um comentário de uma linha é só um barra-barra e um comentário com várias linhas, você utiliza a barra com asterisco, certo? Eu tenho aqui as variáveis, são um estando aqui em cima. Eu posso comer ele agora, né? Então, as variáveis, vocês já viram que é só dizer um nome dela e o valor, só que com isso tem um pouco de problema, porque são variáveis globais, é um estando complicado, geralmente o que você quer é uma variável local, você coloca o def x pra dizer que é só naquele ambiente é o x, pode eu falar em x, em outro campo você é outro x, né? As listas já viram que elas podem acessar elementos da lista, ou com isso, né, coloque de zero, você vai pegar aquela primeira posição por elemento, ou a função get, você pode usar o com size pra pegar o comprimento de uma lista, certo? Tem que ver se a função acerta pra você comparar expressões, a lista é igual a 10 e vai falar nada, se não for ele dá um erro, certo? Então, aqui é muito breve como criar mapas com chaves, você vai usar uma letra que focou com dois pontos, com o nome dessa chave você pega o elemento, certo? Então, eu acho que não vale a pena perder muito tempo aqui, porque é uma coisa que a gente tá falando muito tempo, né? De como usar uma variável com o cifrão, né? O print, enfim, as faz simples e duplas, a diferença de expandir ou não, né? Aqui tá com as faz simples, então ele mostrou $x e $y, se fosse com as duas, ele daria um erro, porque ele falaria, ó, pra gente, no que você não definiu. Então, ele já falou sobre praticamente tudo que tem aqui, né? Você pode definir estrenes também com barras, estrenes com barras, porque elas são iniciadas com barras, as várias lentes de avil que tem com as faz duplas ou simples aqui com barras, então, não tem muito que falar aqui, a expressão é muito parecida com outras linguagens de programação, que é o if, é expressamente parêntese e o bloco lógico é entre chaves, você tem o else, né? Se não, se for apenas uma condição, não precisa colocar de chaves, eu tô indo rápido, porque aqui não é muito que se geralmente você faz um DID com o next flow, certo? É um material de consulta, pra você consultar, mas eu acho que não vale a pena repender muito tempo no treinamento, com essa parte, certo? Os laços, você também não vai utilizar muito isso, mas se precisar em uma situação excepcional, é um laço muito comum, como em outras linguagens de programação, né? Você pode criar suas funções, como a gente quer criar uma função, e as clausuras, que vale a pena gastar um tempinho. Eu já falei brevemente que as clausuras, elas são blocos de código, que são passados para funções como argumentos. E as clausuras são identificadas pelos colchetes, perdão, pelas chaves, certo? Então, eu posso bem falar aqui, o quadrado, ele é uma clausura que, o que você passar pra ele, que vai multiplicar esse elemento por ele mesmo. E aí, eu posso chamar o quadrado aqui com 9, vai dar o T1, que eu tô falando, que chama de função de anônimo, mas também, entendeu? O legal, na verdade, é pra você passar as clausuras pra operadores e canais, e é aí que o poder é fenomenal. Acho que tem um exemplo aqui, aqui não tem um exemplo, mas em operadores, tem umas coisas legais que dá pra ver. A gente pode voltar agora aqui pra ver uma clausura. Aqui um exemplo, né? O MAP pega cada elemento do tipo por ele mesmo. O mais legal, talvez, seja isso aqui. Tem chaves, então é clausura. Então, pra cada elemento desse canal, o que tem nele é, eu vou chamar de palavra, pode ser uma lista, um elemento, um extremo, o que for. Eu vou chamar de palavra, o chamado que eu quiser, certo? E aí, depois da chave seta e maior que, né? Então, na setinha, o que eu vou fazer com isso? Eu vou criar uma tupla, que o primeiro elemento, o que já tem lá, pode ser o segundo elemento, ele vai ser a tela, ele vai ser o tamanho número de caracteres, o número de elementos que for ali, o número do que for, certo? Então, clausuras são poderosíssimas. Então, o português aqui não tem muito o que perder tempo aqui, digamos assim, porque geralmente, quando a pessoa tem que usar a grúvia, acaba mais atrapalhando do que ajudando, na minha opinião. Você tenta fazer o básico do básico com o Nexclor funciona muito bem, certo? Que o pessoal começa a querer trabalhar com variável e, como vocês já viram, o Nexclor trabalha em torno de processos e canais. Não é possível ter dor de cabeça. Então, geralmente, quando a pessoa quer insistir muito no Groovy, dá problema no Spiderlines. Então, tenta focar mais no Nexclor mesmo. Então, a última sessão de hoje, que é de modularização, a gente já viu um pouquinho de módulos no primeiro dia, um pouquinho de módulos do segundo, que ele viu os módulos do NFCore, né? Hoje, não vê um pouco mais cuidado. O que a gente viu no primeiro dia, tinha um arquivo que era o Relo, no capítulo de introdução, Relo.nf, que era muito simples, ele tinha um parâmetro por padrão, ou então você dava ele com dois traços, né? Traços gritting e você dava uma expressão. Ele transformava isso em um canal passada para um um processo, um processo de split-ledders, que ele separava em blocos de seis caracteres e salvava um arquivo e passava isso para o converto upper, que dia colocar em maiúscula essas extremes de seis caracteres. Depois ele mexeu com isso, até colocou o Rev, em vez de colocar para maiúsculo, ele inverter a ordem, os caracteres, beleza. Vamos agora tentar brincar um pouquinho com módulos. Quem vai fazer? Vamos criar um arquivo, chamada Módius.nf no mesmo diretor do nosso Relo.nf, então lá Módius.nf depois eu vou copiar e colar os processos que tem no nosso Relo.nf, beleza, então vamos lá copiar aqui process e o converter, então eu vou copiar e recordar, vou recortar na verdade, tirar daqui e vou colocar no nosso Módius, Módius.nf, salvei com a próxima instrução, remover, beleza e vou importar esses processos do meu módulo. Como é que eu faço isso? Com essa expressão que vou vir em Relo. Eu posso chamar isso em qualquer lugar, que seja antes de quando eu chamar esses processos, então aqui eu chamei, eu vou incluir esses split letters do diretório, do arquivo Módius, do diretor atual, por isso tem um ponto e uma barra, e o converto upper também. Então eu consigo executar, eu poderia muito bem deixar assim e isso vai dar um erro, certo? Ele vai dizer, eu não sei quem é esse tal de split letters converto upper, eu não conheço esses processos. Vai dar um erro aqui. Ele fala, tá faltando um processo, eu não sei o que é isso, mas na hora que você inclui desse aqui o Módius.nf agora sim, ele irá funcionar como a gente vê que funcionava, pegar o Relo.nf separa em blocos e cês caracteres coloca em maiústula e imprime na tela. Não funcionou o Relo.nf blocos e cê eleita, beleza. Então esse aqui, um exercício que ele fala com um arquivo, com esse processo remova o Relo.nf o que a gente acabou de fazer, tá aqui. E aqui vai estar o conteúdo do Módius.nf. Outro que você pode fazer, em vez de como é que são processos de um mesmo arquivo de módulo, eu posso muito bem separar ele, em vez de ficar com esse arquivo de uma vez só incluir os dois. Eu também posso dar um apelido. O cara que criou esse módulo lá no NFCore, beleza, ele chamou de split letters, mas eu gosto de português, então vai ser separe as letras, separe em letras, né, coisa assim. E aí eu vim aqui e coloco o nome que eu quero. Continuou de novo, mas agora o Módulo lá, o processo, ele é chamado de split letters, mas eu gosto de português. É que embora você possa pegar o mesmo canal com os elementos e passar para vários processos, você não pode chamar dois, você não pode chamar um processo duas vezes. Então se você chamou um processo, pegar um canal, passar um processo e ele tá rodando, você não pode pegar outro canal e passar com o outro, mesmo processo. Você não pode fazer isso. O que você pode é criar 4 processos, 2. E aí você consegue repetir isso. E aqui como é que vai acontecer, é que nós vamos ter repetido o que a gente tá havendo, um word hello duas vezes, hello world. Ele reiniciou o safário, aí voltou para a versão 22.10, mas se você quiser voltar para 22.05, era só dar o exporto lá. Então agora são aqui 4 processos, né, ele dobrado. Então, ah, eu quero Marcel passar um canal para ter um clone aí com esse incluido usando apelido, certo? E aí você vai conseguir. Aqui é pra adivinhar, a gente vai saber que é dobrado, né, beleza. E aqui ele dá uma dica, né, mas agora pra se separar de combinado. A gente viu até ontem na verdade, né, como o Anefcoli tem esses módulos, né, então a gente pode ver aqui um exemplo do Arnecic, que é o que a gente viu ontem, ele tem várias pastas, cada pasta é que vai ter o Meta, o Yena, né, o Man, que vai ter os processos, o Man, que viu, você pode organizar como você quiser, o que vai mudar apenas é como você vai incluir, né, como vai usar o incluido, certo? Ah, o que eu quero dizer aqui? Sim, aqui a gente tá utilizando, salvando sempre a série variável, né, eu crie um canal, esse é o nome, chama um processo com esse canal, vou salvar com esse nome variável, vou usar também o ponto Out, então em vez de falar, eu quero essa variável que pegou a série do Split Letters, não, eu só rolo Split Letters, eu falo, olha, eu quero pegar a saída do Split Letters, então ponto Out. Se o meu processo tiver várias saídas, eu uso o colcheio pra zero, um, dois, três, né, a primeira saída, a segunda saída é a terceira saída, e é aqui que entra o emite, que a gente falou há pouco tempo, que é quando eu quero dar um nome com emite pra um chamar de exemplo um, e aí eu dou um ponto Out aqui, ponto, aqui eu vou mostrar com um colcheio, né, pra oposicional e com emite aqui, ó, eu falo, ó, vai ser Upper, então eu vou chamar de Out, ponto Upper, pra escolher o canal específico de saída desse processo, que poderia ter várias saídas, aqui tem apenas um, certo? Você pode utilizar também Pipes, tem gente que acha que vai mais sentido, fica mais legítimo, você pode usar a Pipes pra ficar encadeando as saídas do processo, certo, com operadores, com outros processos e assim por diante, e não só você pode ter módulos, você pode também subir fluxos de trabalho, sub-workflows, que a gente fala, né, então eu chamei aqui o módulo, importei o split leds de converter to Upper, mas eu vou ter um fluxo de trabalho específico, que ele faz algumas coisas, e eu vou ter o fluxo de trabalho que a gente fala, não nomeado, o que ele sempre é chamado, que é workflow, e é aqui eu tô sendo que o workflow chama esse cara, mas eu poderia sub-workflows, o meu pipeline, o pipeline 2, o pipeline de noite, e aí aqui nesse gloco não nomeado de workflow, eu falo, se for de noite chama esse sub-workflow, se for outra coisa, vou ver sub-workflow, então é aqui que vai ficar lógico de qual sub-workflow você é chamado, ou até se todos vão ser chamados, você pode chamar mais do que um, e aí, como você tem sub-workflows, você pode também ter ele recebendo entradas, né, com o take, quando tem o take, você vai precisar colocar o main pra explicar onde são as variáveis que estão entrando nos canais e o restante. E também pode ter um saída que mais um abandon, o em emite, eu vou receber um greeting, então vou chamar o fluxo de trabalho, eu vou chamar esse sub-fluxo de trabalho com essa entrada. Então tá aqui o que ele está pegando, take, aqui o que ele vai fazer é chamar os processos e no final ele vai salvar essa saída aqui, ponto A pra que a gente viu lá que deu para lembrar, por exemplo, que a gente viu, eu vou pegar a saída desse workflow com o ponto alt. Então, você porta esse workflow com a entrada-saída, que é uma coisa que eu falei pouco ontem na sessão de o NFCore, mas eu tenho esse sub-workflows que ele também pode ter entrada e saída, certo? Só que ele tem um exemplo, né? Vai sair assim, é o auto.upper, que é essa saída desse cara aqui, e eu vou imprimir com meus dados. Eu imprimi um pouco com meus dados à saída, eu não quero utilizar esse, não, eu quero usar um nome com meus dados. Beleza. A questão é um exemplo que eu tenho, eu não nomeado e eu posso chamar dois sub-workflows pra querer organizar o pipeline em termos de sub-workflows que por sua vez chamam modus, você pode pra eu fazer isso, é uma questão de preferência, certo? Mas eu também posso, pela linha de comando, falar, olha, eu quero só chamar hoje o sub-workflow A. Você consegue ir utilizando a opção entry, traço entry, começar um traço é do nextflow, né? Utiliza só o sub-workflow, meu pipeline, e aí ele não vai rodá-lo, não nomeado, ele vai direto no meu pipeline, ele vai rodar só isso aqui, certo? Ah, em relação a escopos de parâmetro da rendia view, né? Como aqui tem esses parâmetros com parâmetros pontos, você consegue definir, o que tem aqui a questão de escopo é qual vai ser utilizado, se eu colocar aqui, hello world, beleza, vai sair, hello world, tranquilo, rendia view esse exemplo, quando eu tenho incorporando em um módulo, beleza, independente do que eu estou vendo nesse módulo, ah, dentro do módulo eu tenho um parâmetro ponto, foi um parâmetro ponto B, que é hello world, meu amigo, não importa, ele vai usar o do script principal do pipeline que está incorporando esses módulos, hello world, ah, Marcelo, mas eu quero que venha o de lá, ou eu quero que venha um outro, então você pode aqui, ó, botar esse add parents, olá, e aí ele vai ignorar esse daqui, vai ficar hello world, que vem de C com H, você pode esse add parents para ele adicionar, sobre escrever isso aqui, certo? Isso aqui, assim, se você nunca trabalhou com o nextflow, não podia dizer o nextflow, eu recomendo que você nem abra esse link aqui, que pode ser um motivo de confusão. Para quem usa o nextflow ao mais tempo, ou usa o DSL1, que é a versão antiga da linguagem, aí vale a pena abrir aqui para ver, ah, esse aqui eu lembrava saber como que era, ah, assim, então para DSL2, então é muito bom para migrar, quem nunca viu DSL1, eu recomendo que nem abra, porque é só se confundir, porque muita coisa mudou, certo? Então, pessoal, hoje a gente para por aqui, certo? Então, lembrando que é sândia, a gente viu um pouquinho de como o que é com tenda, tecnologia de contêiner, como gerenciar contêiner, como instalar pacotes com conda, com micromamba, como criar imagens de contêiner utilizando o micromamba, o conda, que tem meio esse singular que pode, outras tecnologias de contêiner, outros gerenciadores de pacote, como a pentegete, o Spark, beleza. Depois vimos canais, que são esses modos de comunicação e de processos, que é o único modo de processos do nextflow, se comunicar com partilho de informações, é através desses canais, certo? Vimos os processos, que são esses etapas de metiobásica do nextflow, e os operadores, que são funções que trabalham especificamente em cima de canais. Então, o que eu queria com vocês nessa sessão que estivesse engravado na cabeça é todas as etapas de um pipeline do nextflow, eles têm que ser processos. Os processos, eles só recebem e só emitem canais. E esses canais só são operados por operadores. Você aprendeu isso aqui, já vai poupar você de muitos erros. Porque se você não entender isso, não entrar direitinho em isso, que é assim que tem que ser, você vai querer criar função para mexer com elemento de canal, vai querer criar função em vez de processo e não vai entender porque não está paralelizando, não está funcionando. O processo está encontrando o arquivo. Então, por isso que eu acho que o Groove, às vezes, atrapalha um pouco. Foca em toda etapa, é um processo. Toda a comunicação é através do canal e toda a manipulação do canal é através de operadores. Aprender isso aqui já é quase tudo, digamos assim, certo? Um pouquinho de Groove, apenas porque é interessante entender o poder de clausuras e também como fazer algumas expressões condicionais, quando a gente viu lá os inscritos condicionais, cada processo executa um e um bloco de script. Mas ele pode ter vários com as condições de qual vai ser. Aí ali é um bloco de if que é Groove. É o next flow usando Groove. Então, é interessante saber algumas coisas de Groove também. E essa modularização, que é como eu posso deixar o meu pipeline, o código do fluxo de trabalho mais limpo, onde os processos estão em arquivos de módulos. Onde eu posso agrandar um pipeline, insube fluxos de trabalho que são chamados de ecotolão condição, certo? Então essa parte de modularização, ela é muito mais para a organização do teu pipeline e também para facilitar que você consiga incorporar o teu pipeline. Coisas de outras pessoas, sub-workflows de outros pipelines, módulos de outros pipelines, e que também outras pessoas possam aproveitar o teu pipeline e pegar pedaços deles para o mais fácil possível, que é só incorporar o módulo, só incorporar um sub-workflow e assim por diante. Assim a gente encerra a sessão de hoje, que é a terceira sessão. Lembrando que amanhã, como vem mais detalhes de configuração, que já pensou em vários momentos, vamos ver com mais detalhes as configurações, vamos ver se ainda as implantação, que até agora a gente testou muito, local, na máquina. Amanhã vamos ver na nuvem, clúster, vamos ver um pouquinho disso. A gente já viu a reentrânsia, que é o Nectl retomar um pipeline de onde parou. Vamos ver mais detalhes, como funciona a reentranção. Há alguns problemas que podem acontecer, como resolvê-los, e um pouquinho do Nectl Outower, que é uma plataforma web que ajuda a monitorar os teus pipelines, então espero que tenham gostado. Mais uma vez, a semana inteira, termos do canal de dúvidas lá do Português, aqui, dispondo para vocês perguntarem, e posteriormente, essa semana, eles vão estar disponíveis em qualquer canal do NFCore ou do select do Nectl Outower também, para qualquer pergunta que vocês vejam a ter, tem todo um suporte para o monetário lá, ponem enquanto não perguntando. Esses vídeos, eles seguirão online, então, quem achou que foi um pouco rápido, ou não pôs de percepção muito bem hoje, vocês poderão assistir esse vídeo outras vezes em outros momentos, não tem um menor problema, certo? E é isso, pessoal. Então, para compartilhar aqui a tela, a gente se vê amanhã para o nosso último dia da sessão, e até mais. Tchau, tchau.