 Hola, bienvenidos a esta cuarta y última sesión del curso online de Nexlo y NFCOR. Me llamo Yidra Gabernet y soy bioinformática en el Quantitatis Biology Center, Centro de Biología Computacional de Tübingen, de la Universidad de Tübingen en Alemania. Y les voy a guiar hoy en esta última sesión. Vamos a recopilar un poco lo que ya aprendieron estos últimos días. En la primera sesión tuvieron una bienvenida, introducción a NexFlow y hicieron una prueba de concepto con una pipeline para analizar datos de RNA-seq. En la sesión dos tuvieron ya una introducción a NFCOR para usuarios y para desarrolladores y aprendieron un poco cómo funcionan los módulos y su workflow en NFCOR. En la sesión tres aprendieron a gestionar dependencias y a utilizar contenedores dentro de pipelines de NexFlow. Aprendieron lo que son canales, procesos y operadores, hicieron una introducción a Groovy y aprendieron un poco más en general cómo funciona la modulización de pipelines de workflows de NexFlow. Y en esta última sesión vamos a hablar de configuración. Vamos a hablar de cómo ejecutar pipelines en distintos escenarios de implementación, cómo funcionan el cache y el resume y en general cómo resolver problemas que uno puede encontrar en correr una pipeline de NexFlow. Y tendremos también una introducción en cómo utilizar NexFlow Tower. Si tienen algunas preguntas ya saben que pueden unirse al Slack de NFCOR donde hay un canal específicamente para responder preguntas en español. Y durante este curso están varios voluntarios para ayudar durante el evento y responder estas preguntas. Así que vamos a empezar con esta sesión. Dónde pueden ir todos los días a training.nexflow.io y esto es lo que van a ver este curso de NexFlow. Como los otros días también tienen que clicar aquí para abrir este entorno de ejecución de GitPot. Esto es lo que yo también he hecho. Y se va a cargar esta página y pueden también aquí especificar qué versión de NexFlow vamos a usar durante esta sesión para que todo el mundo tenga los mismos resultados. Así que vamos a exportar la versión de NexFlow con esta export.nexf.on.theScore.ver. 22.0.5 y vamos a comprobar que esto esté correcto. Se está bajando ahora esta versión de NexFlow y vemos que efectivamente se ha bajado la versión que necesitamos para este curso. Entonces, otra vez aquí en la página de NexFlow podemos ir directamente aquí a empezar el training y hoy vamos a empezar con configuración. Ya han visto en la sesión 2 que es posible de pasar distintas configuraciones a NexFlow que NexFlow busca en distintos lugares para ficheros de configuración. Para ver esto más en más detalle podemos ir a la documentación oficial de NexFlow donde que está aquí en NexFlow.io y ahí se especifica más detalles sobre estos ficheros de configuración. Aquí se especifican, por ejemplo, siete maneras distintas de pasar configuraciones a NexFlow y aquí están ordenadas por su prioridad. Por ejemplo, pasando parámetros especificados en el comando cuando se corre NexFlow es lo que tiene más prioridad y esto va a sobrescribir todo otro tipo de configuración como pueden ser otro fichero pasado con el parámetro menos manos T o el fichero de configuración que ya vieron en la sesión 2, NexFlow.config que está en el directorio donde se ejecuta la pipeline o el fichero de NexFlow.config que está en el directorio donde está el resto del código de la pipeline de NexFlow. Entonces vamos a ver esto un poco directamente en ejemplos aquí o cómo funciona esta configuración directamente con ejemplos. Primero la sintaxis es muy fácil, se puede especificar el nombre del parámetro de configuración y herir su valor de esta manera. Y otra propiedad importante es que se puede hacer que algunas valores de configuración dependan de otros por ejemplo en este caso la propiedad 1 se especifica así y esta otra propiedad depende de la 1 y se puede proporcionar el valor de la 1 con ese sintaxis utilizando este signo de dólar. En los ficheros de configuración, comentarios se pueden escribir de la misma manera que se escriben comentarios en cualquier otro fichero de NexFlow así para una sola línea y así para múltiples líneas. Y otra propiedad importante de la configuración es que existen lo que se llama scopes o ámbitos en español que son distintos ámbitos para los que se puede aplicar configuración y para ver unos cuantos ejemplos de esos ámbitos también podemos ir a la configuración oficial en NexFlow donde se están especificados aquí cuantos ámbitos distintos existen o scopes. Ahí podemos ver que existen una grande variedad y estos ámbitos por ejemplo tienen que ver con el entorno de ejecución por ejemplo si se está ejecutando la pipeline en AWS o utilizando conda environments o utilizando especificos contenedores por ejemplo singularity o docker pero también hay algunos ámbitos que son específicos de NexFlow por ejemplo el ámbito del proceso eso es como se pueden proporcionar distintos variables para los procesos y también es importante el ámbito de los parámetros y esto y ahora vamos a ver algunos ejemplos de esto en este curso. Entonces empezando con el ámbito de parámetros vamos a intentar ejecutar este ejemplo aquí tenemos un workflow script en NexFlow en el que se especifica el parámetro var y el parámetro foo directamente dentro del script de NexFlow y lo único que hace este workflow es imprimir estos parámetros entonces vamos a copiarlo y vamos a probarlo aquí en GitPot le voy a llamar de la misma manera para un punto en F y aquí lo tenemos y podemos ejecutar el root tal y como está NexFlow run Brahms.nf y vamos a ver que lo único que hace este workflow es imprimir estos parámetros hello world ahora lo que vamos a hacer es sobrescribir estos parámetros proporcionándolos en este bichero de configuración NexFlow.config que ya estaba aquí en esta carpeta y vamos a ver como NexFlow sin tener que proporcionar nada en el command line siempre va a leer todos los NexFlow.config que estén en el directorio en el que se ejecuta la pipeline o en el directorio en el que está el código de la pipeline. Entonces vamos a sobrescribir estos parámetros con esto con este ejemplo que nos ponen aquí y vamos a proporcionar a sobrescribir este parámetro con BurnJewel y Lemont. Si ahora ejecutamos otra vez el parámetro.config sin tener que proporcionar nada extra entonces NexFlow pues lees de este bichero de configuración y como este todo tiene más prioridad que pasar los parámetros directamente en este parámetro.config pues ahora los valores se han cambiado para ver también cómo funciona la sintaxis de los scopes. Vamos a ver que es lo mismo proporcionar los parámetros así params.foo params.bar que dentro de estos paréntesis dentro de la configuración así que podemos proporcionarlo de esta manera también y vamos a ver cómo es totalmente equivalente hecho en error no es params sino params ahora sí vamos a ver que es totalmente equivalente y otra manera de proporcionar estos parámetros como ya saben es también con el command line y eso es el que tiene más prioridad así que vamos a probar de pasar estos valores con el command line y vamos a ver entonces si ejecutamos este mismo workflow se sobrescriben estos valores y ahora se está imprimiendo hola mundo. Entonces esas son unas maneras básicas de proporcionar configuración. Para ver otro ejemplo de ámbito vamos a ver el ámbito enf que lo que con el ámbito enf se puede proporcionar a variables de entorno o environment variables que van a estar disponibles en el momento en el que se ejecuta el proceso. Vamos a ver esto con otro ejemplo. Bueno aquí también copiar este código y vamos a verlo otra vez en pitpot. Yo lo he copiado ya en este fichero que se llama foo.nf y he corregido ya algunas cosas porque estas son las sintaxis un poco antiguas la que está en el training y podemos cambiar eco para debug si no tenemos un warning porque se ha cambiado la sintaxis a debug y podemos también es buena práctica de proporcionar aquí este shell antes de que haya la parte del código que ejecuta, que se ejecutará en el proceso. Entonces tenemos este workflow que es un proceso foo que lo que hace es toma todas las variables de entorno o environment variables y busca las que se llaman alfa o beta. Entonces este en un principio si ejecutamos solo este proceso en un principio tenemos error porque no encuentra ninguna variable que se llame alfa o beta pero podemos proporcionarlas estos variables con otra manera de proporcionar ficheros de configuración que es con el parámetro menos de entonces podemos crear un nuevo archivo aquí que se llama en punto config por ejemplo y vamos a copiar aquí otra vez este ejemplo esta otra manera de proporcionar las variables de entorno o environment variables y las podemos proporcionar así con este parámetro menos c y esta es una manera adicional de proporcionar configuración que lo que no sobreescribe el next.config sino que añade adicionalmente todas las variables que se especifican en este fichero y ahora vemos cómo se ha encontrado las estas variables alfa y beta cuando se ejecuta el proceso otro ámbito de configuración que es importante de conocer es el ámbito de proceso y el ámbito de proceso tiene lo que se llama directivas que hace posible de especificar de cintas variables o configuraciones para ejecutar este proceso como por ejemplo el número de CPUs la memoria o qué contenedor se tiene que utilizar para ejecutar el proceso dentro del ámbito de proceso si se proporciona sin especificar qué proceso exactamente esto proporciona valores que se van a utilizar por default en todos los procesos en este caso por ejemplo si especificamos esto en el next.config pues por default se van a utilizar 10 CPUs 8 gigabytes de memoria y este contenedor para ejecutar este proceso en realidad estas directivas también se pueden proporcionar directamente cuando se define un proceso por ejemplo en este ejemplo que teníamos de este workflow foo aquí esto no es otra cosa que una directiva de proceso y aquí también podríamos especificar el número de CPUs que se necesitan para ejecutar este proceso lo que pasa es que generalmente queremos ejecutar una pipeline no sólo en un entorno de ejecución sino que igual queremos ejecutarla localmente o en un cluster y entonces es mejor proporcionar estos valores en un fichero de configuración que directamente en el código de la pipeline porque se va a tener que sobrescribir dependiendo de dónde se ejecuta esta pipeline si regresamos al training pues aquí se ve si se proporciona estos valores como directivas de un proceso en específico la sintaxis es un poco distinta que en la configuración aquí la sintaxis es que no hay un signo de igual que sino que se especifica directamente la memoria aquí se ha especificado en dentro de una closure ya han conocido closures en las sesiones anteriores y aquí lo que significa es que la memoria va a ser dependiente de cuántas CPUs se han pedido para este proceso así se pueden también especificar memoria o otros parámetros de una manera dinámica mientras que si se especifica la memoria para un proceso dentro de específico dentro del fichero de configuración se puede especificar con esta cláusula con dentro del del scope o ámbito de process process podemos especificar a qué proceso se tiene que aplicar a esta configuración con lo que se llama process selectors o seleccionadores de procesos y esto lo vamos a ver con más detalle un poco más tarde hoy pero esto significa que esta configuración solo se va a aplicar a este proceso en específico y cuando se proporciona la configuración dentro del un fichero de configuración la sintaxis es un poco distinta y ahí sí tenemos que poner el signo de igual que de la misma manera pues podemos proporcionar distintos tipos de configuración y para ver dos ejemplos más de ámbitos de configuración podemos ver por ejemplo el ámbito que específico para docker o el ámbito específico para singularity en este ejemplo que tenemos ya aquí cargado de next flow.config en el git pot podemos ver cómo se especifica por ejemplo algunas opciones para correr docker también podríamos aquí especificamente directamente docker for enabled true que significa que utilizaría docker port default para correr la plana en este ejercicio que se proporciona aquí en el training invita a correr la pipeline con singularity en vez de docker pero este environment de git pot no contiene singularity así que este ejercicio no va a funcionar directamente aquí pero si uno lo quiere probar localmente se puede probar localmente si uno tiene singularity instalado aquí también se especifica por ejemplo si uno quiere utilizar environments de contenedores para ejecutar un proceso en específico pues así llegamos al final de la parte de configuración y vamos a continuar con escenarios de ejecución o deployment escenarios en esta parte vamos a ver cómo utilizar la configuración de la que hablamos de una manera más práctica para poder ejecutar next flow workflows en distintos escenarios o en distintas infraestructuras esto es una cosa que ocurre muy a menudo cuando corremos next flow workflows en casos reales porque en la mayoría de las aplicaciones genómicas de bioinformática o en otros ámbitos de bioinformática se necesita la ejecución de miles de tareas y para hacer esto de una manera efectiva en paralelo normalmente se utilizan clases de computación de alto rendimiento la ventaja de utilizar next flow para ello es que next flow es directamente compatible con la mayoría de schedulers que se utilizan en estos clásteres para distribuir las tareas en los distintos nodos entonces no se tiene que modificar el código directamente sino que se puede solo pues especificar la configuración adecuada para poder ejecutar las pipelines en distinta infraestructura así que para ver esto con un poco más de detalles pues se puede alterar la configuración para poder ejecutar next flow en distintas infraestructuras y next flow proporciona o es directamente compartible con distintos schedulers de distintos clases por ejemplo slurm, pbs y también para computaciones en la nube como por ejemplo en amazon cloud o en google cloud o en otras nubes que utilizan clases de Kubernetes para especificar dónde queremos ejecutar el workflow de next flow se tiene que especificar la variable de executor dentro de la scope de process entonces por ejemplo si vamos a ejecutar una pipeline en un cláster que tiene slurm como scheduler podemos especificar process.executor equals slurm para poder ejecutar pipelines en la mayoría de clásteres se tiene que especificar no solo el executor sino también otros de los recursos que uno requiere para cada una de las tareas como por ejemplo la cola donde se quiere ejecutar las tareas aquí en inglés o el número de CPUs en la memoria o el tiempo máximo que se requiere para completar la tarea como hemos visto anteriormente todo eso se puede especificar para todos los procesos esto serían los default values que se requieren entonces para todos los procesos de la pipeline pero hemos visto antes también que en la mayoría de los casos queremos especificar o cada uno de los procesos va a tener unos requerimientos individuales entonces también podemos especificar individualmente para cada uno de los procesos cuáles son los requerimientos para ejecutar este proceso aquí por ejemplo para software pues podemos especificar con esto con este syntax with name foo dentro del process scope las CPUs memoria y cola donde se tiene que ejecutar y lo mismo con el proceso bar vamos a ver esto en práctica cambiando en los estos valores para el proceso de cuantificación de un script que hemos preparado ya en la sesión 2 entonces si vamos a gitbot vamos a ver este script número 7 que tenemos aquí está mini workflow para procesar datos de RNA-seq y vemos este proceso de cuantificación y no está especificado aquí los CPUs o la memoria que necesita entonces podemos especificar ello especificándolo en la nextflow.config aquí tenemos esto de un ejercicio anterior que vamos a eliminar y lo que podemos hacer es especificar aquí dentro del process scope aquí vemos que ya habíamos especificado el contenedor lo vamos a introducir aquí también directamente para tener todo lo que corresponde al el process scope aquí todo junto en el ejercicio me parece que nos pedían 5 CPUs y vamos a ver si ejecutamos ahora con nextflow run script 7.f vamos a ver que se han ejecutado todos los procesos sin ningún error y lo que podemos hacer es corroborar que realmente se han hecho el recuerdo de estos recursos eso siempre lo podemos corroborar yendo dentro de la carpeta del work directory donde se ha ejecutado este proceso este es el SHA podemos autocompletar y aquí vemos pues en el .commandos.sh que se ha especificado el comando por ejemplo hemos especificado 5 CPUs y aquí vemos como los threads se han especificado a 5 que es lo que corresponde a los tasks de CPUs que habíamos especificado aquí en el proceso pero como pueden ver esto puede ser un poco tedioso si tenemos que especificar los recursos para cada uno de los procesos individualmente así que existe otra manera de especificar los recursos incluyendo labels este pues el label también se puede también es una directiva del proceso que se puede especificar para cada uno de los procesos y esto pues facilita poder especificar los recursos para una multitud de procesos todos los por ejemplo si tenemos procesos que necesitan más CPUs y más memoria le podemos poner el label long o si tenemos muchos procesos que necesitan menos recursos pues el label short eso es algo que utilizamos muy a menudo o para todas las pipelines de nscore y podemos ir a ver un ejemplo ahora en una de las pipelines de nscore como se especifica eso si vamos al ejemplo de la pipeline sarec esto está especificado en el base.config así que vemos que aquí se especifica por ejemplo los defaults para todos los procesos pero entonces tenemos también distintos labels especificados para procesos que solo necesitan unas CPU por ejemplo con procesing single procesos que no necesitan muchos recursos por eso es lo etcétera etcétera aquí en esta especificación de nscore es un poco más complicado porque también se utiliza una una función muy específica para estar frente al score y además el número de memoria y perdón en la memoria que se especifica aquí depende del número de ejecución de este proceso si se ha ejecutado este proceso dos veces porque ha fallado anteriormente pues se va a doblar la memoria aquí estos labels vamos a ver cómo se especifican en los procesos aquí vamos a ver uno de los módulos de sarec bueno este es un módulo un poco especial vamos a ver otro ah esto es la configuración perdón vamos a ver a los módulos aquí local por ejemplo de modo local este no tiene label especificado pero los de nscore seguro que todos lo tiene entonces vamos a ver el proceso este de cat y por ejemplo tenemos aquí especificado con esta directiva en el proceso label process law que es un proceso pues que en teoría no necesitan muchos recursos de la misma manera se pueden especificar distintos containers para distintos procesos y otra cosa que queríamos especificar aquí es el uso de perfiles de configuración perfiles de configuración se pueden definir en lo que se llama el profile scope y el perfiles de configuración nos dan otra cosa que darle un nombre a un conjunto de parámetros de configuración aquí por ejemplo tenemos un ejemplo donde se especifican pues tres perfiles distintos uno para que se llama standard en el que el ejecutor es local pero tenemos otros dos profiles o no para ejecutar la pipeline on cluster en el que se especifica un ejecutor que es el scheduler del cluster y se especifica mayor memoria y otros parámetros o un perfil para poder ejecutar la pipeline en este caso en el amazon cloud el uso de perfiles también se encuentra muy a menudo o en todas las pipelines de netcode vamos a ver un ejemplo aquí para el pipeline de zarek los perfiles están definidos en la nextload.config y lo que vemos por ejemplo es que encontramos distintos perfiles pues para poder ejecutar pipeline usando konda usando docker otros distintos containers y también vemos un perfil especial que se llama test o distintos perfiles que empiezan por test y este perfil lo vemos está integrado dentro de la carpeta está con y no es otra cosa que una colección de parámetros y especificación de recursos que se necesitan para poder correr test de las pipelines de esa manera se puede especificar de forma muy fácil como correr un test de la pipeline por ejemplo ya habrán visto en la sesión 2 que se puede especificar pues nextload run el nombre de la pipeline minus profile test com a docker por ejemplo entonces de una manera muy fácil se puede hacer un test de la pipeline con los parámetros más básicos esto también implica lo que acabo de decir que se pueden especificar todos perfiles a la vez separándolos con una coma en este caso podríamos especificar por ejemplo minus profile test com a docker para correr los test usando como container engine docker aquí en esta página van a encontrar más información como especificar los la configuración para correr la pipeline en distintos clusters y en AWS cloud por ejemplo pero ahí no vamos a entrar más en detalle porque ahora en este curso no lo podemos probar directamente sólo mencionar que también se pueden tener se pueden ejecutar distintos procesos de la pipeline en distintas infraestructuras por ejemplo si un proceso requiere de mucha de mucha computación poder computación al que no está disponible en nuestro cluster local pues se puedes especificar que uno de los procesos se ejecuta por ejemplo en AWS cloud y aquí hay un ejemplo de esta configuración entonces seguidamente vamos a hablar del mecanismo de caching y resume en next flow resume significa cómo reanudar un workflow una pipeline desde el punto en el que ha sucedido un error el mecanismo de caching en next flow permite justamente esto reanudar la ejecución de un workflow una pipeline desde el proceso en el que ha sucedido un error sin necesitar de ejecutar todos los procesos anteriores y en práctica cómo funciona eso es porque se genera un identificador único para acudar uno de los procesos de un workflow y este identificador es nuestra cosa que un hash de 128 bits que se calcula a partir de los inputs los inputs de un proceso ya sean valores o sean ficheros y del comando que se utiliza para ejecutar la tarea de ese proceso ya se habrán dado cuenta en ejecutar anteriormente los ejemplos de este tutorial que cuando se ejecuta una pipeline se crea un directorio que se llama work o el directorio de trabajo y dentro de este directorio los resultados input files de cada una de las tareas están organizados en subdirectorios que contienen este hash de aquí que hemos hablado entonces para para cada uno de los procesos de la pipeline existe un subdirectorio aquí que contiene este hash y dentro de cada uno de estos directores existen en principio todos los input files que se necesitan para ejecutar este proceso y el comando para ejecutar la tarea también y una vez se ha computado la tarea también todos los output files o los ficheros de output perdón en práctica cómo funciona el reanudar workflows con resum es solo proporcionando la opción resum en cuando se ejecuta la fichería o el workflow de nextflow pero como como esto funciona realmente es que nextflow vuelve a ejecutar toda la pipeline desde el principio pero en vez de ejecutar una tarea dentro de un proceso lo primero que hace es computar este identificador o hash desde los inputs desde el comando y también ver si el proceso sea ejecutado sin errores anteriormente o sea que el exit state sea un exit state de fero y que todos los ficheros que se esperan en el output de este proceso estén presentes y si todo esto se cumple entonces nextflow no vuelve a ejecutar esta tarea sino que pasa a la siguiente y si es cómo funciona en práctica es el mecanismo de resum. Aquí hay un poco más de especificación sobre el directorio este de trabajo que es que se puede cambiar donde se genera este directorio de trabajo en que paz y también su nombre con esta opción menos duve y aquí sólo una puntualización de que este hash del que hemos hablado en realidad se genera no sólo con el input file sino con el el path completo de este fichero también su su tamaño y el time stamp o el momento o sea el momento en el que se ha modificado por última vez por eso si sólo vamos a ejecutar el comando de touch en un fichero que se necesita como input a uno de estos procesos esto ya va a invalidar la reambulación pero basta de teoría y vamos a ver esto un poco más en práctica entonces volvemos a hip hop ahí tengo unos tés anteriores vamos a ejecutar tarde nuevo el script número 7 que contiene este esta mini pipeline de RNA-seq si la ejecutamos como siempre vamos a ver que se empieza a ejecutar desde el principio se ejecutan todas las tareas y ahora vamos a probar ejecutarlo de nuevo proporcionando el parámetro de resum lo que vamos a ver es que ahora va mucho más rápido y además aquí nos indica que no se ha ejecutado realmente este proceso sino que se ha hecho un cache este proceso y pues sea en este caso se han podido hacer un cache de todos los procesos porque ya se habían ejecutado anteriormente lo que podemos probar de hace ahora es que pasa a ver qué pasa si hacemos un touch de uno de los ficheros que se necesitan aquí para en el proceso de cuantificación para empezar a correr la pipeline desde el principio vamos a tocar sólo uno de ellos entonces volvemos a probar de reanudar la tarea por el workflow en puertón y lo que vamos a ver es que en este caso sólo se ha podido hacer un cache del proceso que genera el index porque el index no necesita estos past few files sino pero no se ha podido reanudar los procesos de cuantificación porque el time stamp en el que se ha modificado por última vez este fichero ha cambiado por eso vuelve a ejecutar la pipeline desde este proceso seguidamente vamos a ver algunas algunas tips o algunas recomendaciones de cómo organizar distintos experimentos utilizando pipelines de next feed podemos aquí se nos indica de que se puede utilizar el comando nextflow lock para ver todas las veces que se ha ejecutado un workflow determinado en un directorio determinado entonces vamos a ver cómo se ve esto en nuestro directorio yo he hecho algunos tips anteriormente y si utilizo el comando nextflow lock puedo ver que se ha podido el este workflow pues seis veces algunas veces con errores y algunas veces con una ejecución correcta y aquí se puede ver también el comando que se ha utilizado pues aquí habíamos utilizado sin resum y aquí con resum lo que se puede hacer también es reanudar un uno de estos una de estas ejecuciones determinadas y para eso se puede proporcionar o el nombre del run run name o la session ID está es un poco más fácil con el con el run name entonces vamos a probarlo en vez de reanudar esta ejecución aquí la última ejecución vamos a reanudar la anterior hay otros tips de utilizar el comando de nextflow lock que pueden ser interesantes y es que puede por ejemplo por proporcionar información sobre los procesos que uno de estos runs ha ejecutado con su con otras características por ejemplo el exit code el hash id y la duración de cada uno de los procesos vamos a probar cómo se ve eso aquí tenemos que cambiar el nombre del proceso vamos a verlo en un mismo anterior amazing y vemos aquí que en este proceso pues se han ejecutado estos procesos con este exit code este hash y han tardado tanto tiempo a ejecutarse y aquí si siguen el tutorial van a ver que proporciona más información sobre poder crear unos reports bonitos con estos logs pero vamos a pasar al apartado siguiente en el que vamos a ver un poco cómo solucionar problemas que podemos encontrarnos cuando queremos reanudar un workflow a veces no nos va a funcionar reanudar un workflow y hay distintas razones por eso una de las más comunes es si cambia el input file de este proceso si este proceso cambia el input file a este proceso ha cambiado entonces no se puede reanudar la tarea como hemos visto anteriormente esto puede ocurrir por ejemplo cuando uno de los procesos modifica directamente el input file, queremos siempre evitar eso para evitar que no se puedan reanudar workflows también puede ocurrir a veces cuando se utilizan clústeres de computación que el timestamp de estos de los ficheros que se generan es inconsistente y entonces puede también tener un exprop problema problemas en reanudar esas tareas y lo que se puede puede ocurrir también cuando ocurren lo que se llama race conditions. Race conditions ocurren cuando se define o cuando se modifica una variable dentro por ejemplo con operadores a un canal que tiene el mismo nombre en dos canales que pueden que se definen individualmente aquí tenemos un ejemplo de eso por ejemplo aquí tenemos dos canales se generan de los inputs 1, 2, 3 en este primer canal se utiliza en el operador de map que lo que hace es añadir dos al valor inicial y aquí podemos visualizar el resultado y en este otro canal es muy similar pero en vez de añadir dos se multiplica por dos pero lo que pasa es que los dos canales operan sobre una variable que tiene exactamente el mismo nombre en los dos casos así que vamos a ver qué ocurre cuando ejecutamos eso, voy a cambiar aquí y vamos a ver qué ocurre nextflow run, que vamos a ver el resultado que se ha generado primero con el canal 2, 2, 4 y 6 y con el canal 1, 3, 4 y 5, vamos a ver qué ocurre si lo ejecutamos otra vez ahí vemos que en el canal 1, 3, 4 y 5 con el canal 2, 2, 4 y 6 ahí se han generado los mismos valores vamos a probar otra vez pues si lo he tenido que ejecutar bastantes diferentes veces así que lo he cortado pero finalmente me han salido resultados distintos y me sale 2, 4, 6, 3, 4, 5 y aquí tenemos 6, 4, 6, 3, 4, 5 así que esto no asegura que salgan siempre los mismos resultados si lo que queremos realmente es que salgan siempre los mismos resultados en los dos canales lo que tenemos que hacer es definir variables como locales entonces para eso utilizamos aquí este síntax con def x y así aseguramos que salen siempre los mismos resultados aquí vemos otro ejemplo en el que tenemos canales de input, input channels que no son determinísticos en este ejemplo se generan canales en los que se asigna un index pero como no sabemos no se sabe a priori o cambia siempre el orden en el que se generan estos canales no se puede no se asignará siempre el número 1 a la letra a y el 2 a la b el 3 a la c 4 a b vamos a probarlo esto en práctica también a ver cuántas veces tengo que ejecutarlo esta vez para que funcione en esta ejecución hemos visto que 1 se genera 1 a 2 b 3 c 4 d vamos a ver si lo ejecutamos de nuevo bueno pues yo no he tenido mucha suerte me han salido siempre los mismos resultados pero es saber que en teoría estos resultados pueden ser distintos cada vez entonces tenemos que tomar medidas para evitar tener resultados distintos y esto es lo que nos interesa vamos a ver otro ejemplo en práctico donde nos podemos encontrar por uno de estos casos en los que queremos combinar ficheros o valores de dos canales distintos en un siempre en un orden determinado que por ejemplo tenemos dos input files a un proceso en formato van y estos requieren de su su índice específico aquí por ejemplo queremos para el fichero van de la primera muestra el índice correspondiente de la primera muestra lo que se puede utilizar en estos casos es proporcionar lo que se llama un metamap o un map como parte de un array en este metamap se pueden especificar key value pairs no sé cómo se llamará esto en español por ejemplo hay y el nombre de la muestra y en el otro canal lo mismo y entonces lo que se puede utilizar es un operador determinado que se llama join y lo que este operador hará es siempre combinar el van y el bay que tienen el mismo ahí así evitamos que se puedan ocurrir errores porque se proporcionan los canales en ordenes distintos si proporcionar metamaps no es posible otra manera de asegurar que siempre se escuten los canales en el mismo orden es proporcionando una una directiva en un proceso del proceso que se llama hacer si siguen este enlace van a encontrar más detalles sobre ello en la documentación de nexlo entonces seguimos a la siguiente sección que es cómo hacer troubleshooting o cómo solucionar errores que ocurren en ejecutar by plants en exflow lo primero que tenemos que hacer es entender un poco cómo se está estructurado el mensaje de error en exflow aquí empieza con la palabra error y luego nos indica en qué proceso exactamente ha corrido este error en este caso en el proceso que se llama index aquí nos indica la causa del error que ha terminado con un exit status que no es el usual no es el cero sino 127 y aquí nos indica que copando se ha ejecutado en este caso pues el comando de salmón index que hemos visto anteriormente aquí nos indica específicamente el exit status otra vez estos exit status son son comunes y se pueden también buscar el google que ayuda mucho a veces y aquí si el la tarea que se ha ejecutado hubiera generado algún mensaje de output antes de suceder el error aquí estaría indicado pero en este caso y aquí nos indica qué mensaje de error ha generado esa tarea este caso que el comando o el tool de salmón no se ha encontrado finalmente también nos indica en qué directorio exactamente se ha ejecutado esta tarea que también es muy útil en intentar buscar cuál ha sido la razón para este error entonces vamos a ver esto en práctica vamos a ir a kit pot hecho algunos test y voy a limpiar este directorio de trabajo porque contiene ahora muchos runs anteriores para eso solo tenemos que eliminarlo y también me no me he olvidado de decirlo antes pero si se elimina el directorio de trabajo no se pueden resumir los los runs otra vez no se puede utilizar el comando más menospreción entonces vamos a inducir un error en el en este script en el que comentamos esta parte de tocker dot enabled true entonces el next row no sabe dónde encontrar las tools que se necesitan para ejecutar nuestros script anterior vamos a ejecutar este script el número 7 es lo gran script 7 y vamos a ver que inmediatamente inmediatamente se genera un error muy similar a la anterior en este caso en otro proceso vemos que este error ha ocurrido el proceso que ha terminado con exit status 127 y vamos a acubilar que es esto de exit status 127 el comando no found que es que no se encuentra el tool que estamos intentando de ejecutar en en el path donde el next row busca pues tools para ejecutar los procesos perdón volvemos aquí pot que es el comando que se ha ejecutado aquí también lo pone el mismo exit status otra vez fastwares y comando no found y nos indica también el directorio exactamente dentro del del work directory donde sé de este proceso vamos a ver que que hay ahí dentro pues sería el que empieza con 72 y sigue así donde dentro de este work directory tenemos una una variedad de ficheros primero como ya hemos visto antes tenemos los input files que se necesitan para ejecutar el proceso pero otros ficheros también que next row ha generado el dot comando error donde se dirige los mensajes de error el comando loc donde contiene los mensajes de output y los mensajes de error todo el comando de out sólo contiene los mensajes de output en este caso no se ha podido generar ningún output y otros dos también importantes el comando tron y el comando desech empezamos por el comando desech este contiene exactamente el comando que hemos especificado en el en este proceso pero ya con todas las variables sustitucidas por ejemplo vamos a ver por el proceso de fastqc si miramos en el script 7 vamos a ver que en el proceso de fastqc teníamos especificado que en makedir pues una variable que contiene el sample id y en fastqc también y también los reads pero como si vemos otra vez el comando todo desech vemos que estas variables ya han sido sustituidas entonces también es interesante mirar aquí si ha ocurrido un error que se hayan sustituido las variables conectamente también genera nextflow el comando tron que es son es un wrapper en de esta de este comando desech con todo lo que necesita nextflow para reproducir para ejecutar esta tarea y se puede intentar reproducir el error también localmente ejecutando este fichero con sólo bash command punto tron ahora no está no está aquí no tenemos bash aquí en ditbot pero esto localmente funcionaría entonces bueno estos son los puntos más importantes en intentar solucionar un error pues uno puede ir ahí al work directory y ver que es que en todos los ficheros correctamente y mirar a ver si se ha sustituido el comando correctamente que tenemos un poco más explicación de lo que ya he comentado de los distintos ficheros que genera nextflow a veces lo que ocurre es que nos interesa ignorar algunos errores por ejemplo cuando estamos procesando muchas muestras a la vez y algunas de ellas pues el input file tiene algunos problemas pero queremos que el resto de muestras sigan entonces es posible especificar esto con una directiva de proceso que se llama error strategy si queremos ignorar los errores podemos los errores de un proceso determinado podemos incluir esta directiva error strategy ignore como hemos visto antes en el en la sección de configuración esto también se puede especificar en el config file de esta manera a veces no nos interesa ignorar errores pero nos interesa que se vuelva a ejecutar la tarea cuando ocurre un error esto puede ser por ejemplo cuando ocurren errores que ocurren algunas veces y algunas no y nos interesa pues que se vuelva a ejecutar este proceso esto se se consigue con el error strategy retry otras veces nos interesa que se puede ejecutar otra vez este proceso pero esperando un poco antes de la sección esto ocurre a menudo cuando queremos acceder web servers y por ejemplo en algún momento determinado no están disponibles debido a que tienen pues hay una cogestión de red como pone aquí en este caso es posible de especificar que antes de utilizar de utilizar este retry se espera un tiempo determinado aquí está especificado así el tiempo que tiene que esperar next flow antes de volver a ejecutar esta tarea y también se puede especificar cuantas veces uno quiere que se vuelva a intentar de ejecutar esta tarea otro otro caso que se encuentra a menudo es que por ejemplo un proceso tiene errores debido a que no hay suficiente memoria para ejecutar esta tarea en este caso es muy útil utilizar también este error strategy que permite volver a ejecutar esta tarea pero en vez de volver a ejecutar con los mismos recursos ejecuta incrementar los recursos que están disponibles para ejecutar esta tarea por ejemplo si este proceso ha terminado con error 140 que significa que no tiene suficiente memoria volvemos queremos reanudar la ejecución pero asignando más memoria y esto se puede hacer multiplicando el número de memoria por la variable que se llama task.attempt que es el número de veces que se ha intentado este retry esto es una síntasis que se utiliza en todas las pipelines de netcore como hemos visto también anteriormente para asignar procesos recursos a los procesos de estas pipelines vemos que tanto las tp bus memoria o tiempo están multiplicados en muchas veces por el task.attempt pero está por default que solo se reintende una vez entonces si uno quiere puede incrementar este número de max repriser a tres por ejemplo pues eso sería todo en cuanto a la resolución de errores que ocurren corriendo workflows de nextflow y en el siguiente apartado vamos a ver lo que es nextflow tower y cómo utilizarlo para correr pipelines de nextflow. Por último hoy vamos a hablar de nextflow tower. Nextflow tower es un producto de secral apps que es la empresa que desarrolla nextflow. Nextflow tower tiene muchas funciones pero una de las principales es facilitar el lanzamiento de workflows de nextflow en distintas infraestructuras y también el seguimiento de esos workflows y vamos a ver un poco en práctica cómo funciona eso todo esto que voy a explicar ahora también está explicado aquí en detalle en este tutorial pero yo voy a seguir directamente en tower.f entonces podemos ir a la página web de tower que es cloud.tower.f y tenemos primero de todo un poco de marketing de nextflow tower que si incrementa la productividad, reduce los costes, etcétera etcétera muy importante también es el precio. Secral apps ofrece una versión de tower cloud que también la tiene directamente en sus servers gratuitamente y esta es la que vamos a utilizar hoy pero para empresas también es posible pues contratar un servicio profesional que está también en los servers de server.cral apps o un servicio que se llama tower enterprise en el que la empresa instala directamente tower en su infraestructura para para estar seguros de tener una infraestructura totalmente con privacidad. Entonces vamos a ver un poco cómo funciona tower con esta versión que es gratuita para ello solo tenemos que registrarnos aquí en signing como ya hemos utilizado anteriormente signing with github para pitpod pues podemos usar el mismo método y entonces vamos a llegar a una página como esa en el que tenemos distintos tabs aquí a la arriba a la izquierda. Esperemos todo en el launchpad que es desde donde se pueden ejecutar workflows pipelines de nextflow desde este web interface. Luego el tab de runs es donde vamos a ver todos los runs que hemos ejecutado anteriormente desde nuestro usuario ahí seguramente estará vacío para ustedes y para mí pues pone todos los workflows que he ejecutado anteriormente. Luego está actions que permite la ejecución automática de workflows dependiendo de integración con con otros elementos en los que nos vamos a entrar ahora en detalle y luego está el apartado de compute environments que es desde donde se pueden definir distintos compute environments donde se van a ejecutar estas pipelines ya he mencionado anteriormente que facilita la ejecución de pipelines en distintas infraestructuras así que aquí podríamos tener por ejemplo compute environments form de distintas infraestructuras de las que tenemos disponibles para ejecutar nuestras pipelines por ejemplo Amazon Batch o un cluster de Kubernetes o nuestro cluster que tenemos nuestra infraestructura y finalmente el apartado de settings donde se pueden modificar por ejemplo los labels en donde vamos a ver cómo podemos ejecutar una pipeline de nextflow desde nuestro hip hop como hemos hecho hasta ahora pero ver la ejecución aquí también en nextflow tower para ellos lo tenemos que crear un token que nextflow va a utilizar para para poder entonces comunicarse con tower para eso tenemos que ir ahí a nuestro usuario your tokens y crear un token nuevo pues yo voy a llamarlo tower token aquí tenemos el token lo vamos a copiar y vamos a ir a la instancia de github donde hemos estado hasta ahora voy a limpiar un poco eso y lo único que tenemos que hacer como nos pone aquí también en la documentación es darle el valor de este token a la variable en the environment tower access token y esto se hace de la siguiente manera export tower access token igual a y le pegamos aquí el token que hemos copiado esto es todo lo que nextflow necesita para poder comunicarse con nextflow tower entonces si queremos ejecutar un workflow de nextflow y que se aparezca en nuestra instancia del tower lo que tenemos que hacer es proporcionar la opción with tower si que vamos a correr nuestro script número 7 nextflow done script.nx con la opción with tower y vemos que ahora se ha aceptado el mismo script de la misma manera con el error que habíamos introducido anteriormente pero ahora aparece un mensaje nuevo que dice pues se puede monitorizar la ejecución a este link si seguimos el link nos va a llevar a tower otra vez y vemos que este run va a aparecer aquí en el tab de runs en este caso el proceso que ha terminado con errores podemos intentar de arreglar este error otra vez teníamos este error aquí de enabled true que nos faltaba vamos a ejecutarlo otra vez para tenerlo más bonito en tower y ahora si termina bonito y podemos seguir la ejecución aquí en nextflow tower vemos que este workflow está corriendo vemos aquí justo ahora terminado vemos que todas las tareas se han ejecutado correctamente succeeded y podemos ver distinta información sobre sobre esta ejecución primero de todo podemos ver el comand line que pone el comand en completo que se ha utilizado para ejecutar esta pipeline luego en parámetros podríamos ver todos los parámetros que se definen dentro del workflow toda la configuración que se ha definido dentro del workflow aquí podemos ver por ejemplo la configuración de docker y aquí vemos también por ejemplo una configuración especial que es la configuración de tower y es que en vez de pasar el parámetro with tower cuando ejecutamos un workflow también podemos ponerlo en la configuración dentro del scope o ámbito tower enable typos true y así todos los workflows por default o los workflows que tengan esta configuración se podrán seguir en tower y hay otra opción aquí que son pipeline reports que no tenemos no tenemos ningún reporta ahora que definido en nuestro workflow luego tenemos también una información más general un identificador por este run concreto de este workflow el nombre que le ha dado next flow a este run cuando se ha empezado la ejecución del workflow y otra información por ejemplo el el work directory que es sistema de contenedores se ha utilizado para ejecutar el workflow que pone que se ha utilizado docker como contenedor y exactamente el contenedor que se ha utilizado luego donde se ha ejecutado este workflow por ejemplo localmente en este caso en kitbot y la versión de next flow que sea que sea que está instalada luego para uno cada uno de los procesos podemos ver cuántas veces se ha ejecutado cada proceso ahí sólo tenemos principio una muestra y si clicamos dentro de un proceso indeterminado también podemos ver más información sobre este proceso y hasta más información si clicamos aquí en este más podemos ver por ejemplo pues lo mismo que veíamos en el mensaje de error el comando en el status de compresión del proceso el work directory otra vez y otra información que puede ser útil por ejemplo la memoria recuest también tenemos por ejemplo el número de CPUs y memoria de para cada uno de los procesos de un modo un poco más gráfico para poder comparar pues los distintos procesos cuantos CPUs necesitan cuanta memoria la duración de cada uno de los procesos esto nos puede ayudar también si queremos optimizar uno de los workflows a que tarden menos tiempo o utilicen menos memoria por último otra cosa que queríamos comentar de next flow tower es que hay existe la posibilidad de especificar workspaces y los workspaces en una manera de compartir runs de next flow con otros grupos otra gente por ejemplo dentro de una empresa pero también otras comunidades por ejemplo tenemos la comunidad de nf core en la que compartimos workflows también vamos a ver ahí que tenemos en la comunidad de nf core en nf core tenemos el workspace este de aws megates que está organizado o de manera que se puedan ejecutar todas las pipelines de nf core en todas todas las veces que se hace un release en aws batch aquí tenemos distintos environments compute environments definidos muchos de ellos dependen de aws batch y esto es solo para probar que todos los pipelines de nf core pues funcionan correctamente también cuando se ejecutan en aws batch y justo ahora también estamos empezando a configurar esto para probar todos las pipelines en azure cloud entonces si vamos a runs aquí de nf core de 10 megates podemos ver que todas las pipelines pues van pasando o si hay errores de ejecución en aws batch entonces vamos a probar de hacer un workspace propio para compartir nuestros runs con otros usuarios esto también lo podemos hacer aquí primero de todo tenemos que crear una organización una organización disculpen por mi español lo hacer por ejemplo una organización que se llame test organization podemos poner también this organization y tendríamos podríamos añadir también más información pero de momento lo vamos a dejar así entonces dentro de una organización podemos invitar colaboradores con los que queremos compartir nuestros runs lo que podemos también hacer es crear un workspace dentro de esta organización por ejemplo vimos pues tenemos que seguir en este workspace todos los runs que ocurren en nuestro cluster os le llamaremos a este workspace cluster voy a repetir aquí el nombre y lo vamos a poner a privado por ahora entonces lo que también podemos hacer es que directamente todos los runs que corremos en nuestro cluster o aquí en este ejemplo en gitbot pues aparezcan directamente en este workspace para que nuestros colaboradores lo puedan ver entonces para eso sólo necesitamos configurar otra variable de que la tenemos aquí escrita vamos a ver esto ya lo hemos hecho ahora ya estamos en la parte de workspace y vamos a tener que definir la variable de todo el workspace id y el id nosotra cosa que este id que nos pone aquí vamos a probarlo es fort como se llamaba tower workspace id iguala y este es el id entonces probamos de ejecutar esta nuestro script número 7 otra vez con tower y lo que deberíamos ver es que aquí ya vemos aquí en el link que este estaría en el espacio mío privado pero aquí después de exportar el workspace id vemos que este run va a aparecer en el workspace de test organization gitbot cluster vamos a ver si es verdad si vamos dentro del workspace los tabs aquí son muy similares a los que viamos antes por nuestro workspace privado y vemos que efectivamente este run aparece dentro de este workspace bueno pues esto es en la introducción la introducción rápida nextflow tower para lo que también podemos probar es cómo utilizar el launchpad para ejecutar workflows fácilmente desde esta web interface para eso tendríamos que definir aquí un compute environment y un launchpad run y para evitar eso lo que vamos a hacer es ir al community showcase showcase donde ya están algunos definidos lo que podemos ver aquí en este launchpad del community showcase es que se ha preparado la ejecución de distintas pipelines la mayoría de ellas de nevco para que los usuarios puedan ejecutarlas directamente desde esta web interface entonces vamos a ver cómo se ve eso para la pipeline de rna sick vemos que todos los parámetros que se necesitan para configurar la ejecución de la pipeline de rna sick están aquí concretados aquí también hay distintas secciones que coleccionan estos parámetros y se pueden pues añadir los valores directamente aquí en esta web interface por ejemplo podemos cambiar el nombre del del out tier cambiar distintas opciones con humis sin humis y pues ver también muy fácilmente todas las opciones que están disponibles para ejecutar esta pipeline aquí también lo que vemos es que en este launchpad se ha rellenado directamente los inputs que tower que se quiera el apps también ofrece directamente para poder ejecutar una versión fácil de esta pipeline podemos poner podemos dar a launch y veremos que son los datasets que se necesitan para poder ejecutar a pipeline y vemos que por ejemplo miran ahora y ha empezado y veremos donde corresteran directamente por ejemplo aquí como como se quiera el apps lo tiene organizado es que estos launches del community de la community showcase pues se ejecutan todos en amazon batch a irland bueno este se tardaría un rato pero podemos ver un rana anterior por ejemplo de la n por mac pipeline la que vemos ahí pues todos los procesos que se han ejecutado algunos estera un rambut version así que estos se marcan como cast se han reanudado y vemos los procesos nuevos y aquí podemos ver pues lo mismo que antes más información pero como esta es una pipeline más complicada pues ayuda más tener aquí este report de los recursos donde se pueden comparar por proceso cuáles son los procesos que utilizan más memoria más tiempo más que te guste etcétera etcétera pues eso es un poco lo que hemos probado ya el launchpad rellenar los parámetros del launchpad sólo mencionar también que en explota ahora viene con una api o api en la que se puede que se puede hacer todo eso también programáticamente y además también proporciona una una comand line tool que se puede instalar entonces se puede hacer esto también desde el comand line esto también lo hemos ya hablado los workspace las organizaciones y pues ya hemos cubierto toda la parte de nextflow tower y aquí pues les quería agradecer mucho su atención espero que haya ayudado a poder ver este tutorial directamente grabado les pido disculpas por mi español que está un poco oxidado desde que digo muchas años en alemania pero espero que hayan podido seguir este curso y que hayan aprendido mucho de nextflow de nextflow tower y de todo lo que hemos enseñado aquí