Commit c7aa5233 authored by mmassaviol's avatar mmassaviol
Browse files

Workflow generated with WAW repository

parent 47b6dcdc
FROM mbbteam/mbb_workflows_base:latest as alltools
RUN apt -y update && apt install -y fastqc=0.11.5+dfsg-6
RUN cd /opt/biotools \
&& wget http://www.usadellab.org/cms/uploads/supplementary/Trimmomatic/Trimmomatic-0.38.zip \
&& unzip Trimmomatic-0.38.zip \
&& echo -e '#!/bin/bash java -jar /opt/biotools/Trimmomatic-0.38/trimmomatic-0.38.jar' > bin/trimmomatic \
&& chmod 777 bin/trimmomatic \
&& rm Trimmomatic-0.38.zip
RUN apt -y update && apt install -y openjdk-8-jre
RUN cd /opt/biotools \
&& wget -O FLASH-1.2.11.tar.gz https://sourceforge.net/projects/flashpage/files/FLASH-1.2.11.tar.gz \
&& tar -xvzf FLASH-1.2.11.tar.gz \
&& cd FLASH-1.2.11 \
&& make \
&& mv flash ../bin \
&& cd .. \
&& rm -r FLASH-1.2.11 FLASH-1.2.11.tar.gz
RUN apt-get install -y parallel
RUN cd /opt/biotools \
&& wget -O velvet-1.2.10.tar.gz https://github.com/dzerbino/velvet/archive/v1.2.10.tar.gz \
&& tar -xvzf velvet-1.2.10.tar.gz \
&& cd velvet-1.2.10 \
&& make -j 10 \
&& mv velvet* ../bin \
&& cd .. \
&& rm -r velvet-1.2.10 velvet-1.2.10.tar.gz
RUN cd /opt/biotools \
&& wget -O lastz-1.04.03.tar.gz http://www.bx.psu.edu/~rsharris/lastz/lastz-1.04.03.tar.gz \
&& tar -xvzf lastz-1.04.03.tar.gz \
&& cd lastz-distrib-1.04.03/src \
&& make -j 10 \
&& mv lastz* /opt/biotools/bin/ \
&& cd ../.. \
&& rm -r lastz-distrib-1.04.03 lastz-1.04.03.tar.gz
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
#This part is necessary to run on ISEM cluster
RUN mkdir -p /share/apps/bin \
&& mkdir -p /share/apps/lib \
&& mkdir -p /share/apps/gridengine \
&& mkdir -p /share/bio \
&& mkdir -p /opt/gridengine \
&& mkdir -p /export/scrach \
&& mkdir -p /usr/lib64 \
&& ln -s /bin/bash /bin/mbb_bash \
&& ln -s /bin/bash /bin/isem_bash \
&& /usr/sbin/groupadd --system --gid 400 sge \
&& /usr/sbin/useradd --system --uid 400 --gid 400 -c GridEngine --shell /bin/true --home /opt/gridengine sge
EXPOSE 3838
CMD ["Rscript", "-e", "setwd('/sagApp/'); shiny::runApp('/sagApp/app.R',port=3838 , host='0.0.0.0')"]
FROM alltools
COPY files /workflow
COPY sagApp /sagApp
#!/bin/bash
#This script will help to run a workflow in a docker image.
if [ $# -lt 4 ]
then
echo usage : $0 dataDir resultsDir configFile nbCores '[dockerHub|local]'
exit
fi
# Docker volumes
# MBB Workflows reads data from /Data and write results to /Results
Data=$1
Results=$2
if [ ! -d "$Data" ]; then
echo "can't find $Data directory !"
exit;
fi
mkdir -p $Results
DOCK_VOL+=" --mount type=bind,src=$Data,dst=/Data"
DOCK_VOL+=" --mount type=bind,src=$Results,dst=/Results"
# config file must be in /Data or /Results !
config=$3
cores=$4
if [ $# -lt 5 ]
then
APP_IMG="mbbteam/capture_uce:latest"
else
IMG_SRC=$5
case $IMG_SRC in
dockerHub )
APP_IMG="mbbteam/capture_uce:latest" ;;
local)
docker build . -t capture_uce:latest
APP_IMG="capture_uce:latest" ;;
mbb)
#APP_IMG="X.X.X.X:5000/capture_uce:latest" ;;
esac
fi
docker run --rm $DOCK_VOL --cidfile="CID.txt" $APP_IMG snakemake -s /workflow/Snakefile all --configfile $config --cores $cores
CONTAINER_ID=$(cat CID.txt)
if [ $CONTAINER_ID ]
then
echo " "
echo Results were written to : $2
echo " "
else
echo Failed to run the docker container !!
fi
#!/bin/bash
#This script will help a deployment of a docker image on an MBB bigmem machine
if [ $# -lt 2 ]
then
echo usage : $0 dataDir resultsDir '[dockerHub|local]'
exit
fi
#nginx
##### nginx install #####
#sudo apt-get install -y nginx
# HOST_NAME="192.168.100.49"
# HTTP_ENDP="https://$HOST_NAME"
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/C=FR/ST=LR/L=Montpellier/O=CNRS/OU=CNRS-ISEM/CN=mbb.univ-montp2.fr"
# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
# mkdir -p /etc/nginx/snippets
# echo "ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;" > /etc/nginx/snippets/self-signed.conf
# echo "ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;" >> /etc/nginx/snippets/self-signed.conf
# cp system/nginx_snippets_ssl-params.conf /etc/nginx/snippets/ssl-params.conf
# cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
# cp system/nginx_sites-available_default /etc/nginx/sites-available/default
# sed -i "s|server_domain_or_IP|$HOST_NAME|" /etc/nginx/sites-available/default
# useradd nginx
# cp system/nginx_nginx.conf /etc/nginx/nginx.conf
# cp system/nginx_conf.d_10-rstudio.conf /etc/nginx/conf.d/10-rstudio.conf
# sed -i "s|example.com|$HOST_NAME|" /etc/nginx/conf.d/10-rstudio.conf
# systemctl restart nginx
# systemctl enable nginx
#essayer une plage de ports entre 8787 et 8800
#APP_PORT=$2
APP_PORT=8787
while [[ $(ss -tulw | grep $APP_PORT) != "" && $APP_PORT < 8800 ]]
do
APP_PORT=$(( $APP_PORT + 1))
done
if [[ $(ss -tulw | grep $APP_PORT) != "" ]]
then
echo "No tcp port available !!"
exit -1
fi
# Docker volumes
# MBB Workflows reads data from /Data and write results to /Results
if [ $SUDO_USER ]; then realUSER=$SUDO_USER; else realUSER=`whoami`; fi
Data=$1
Results=$2
mkdir -p $Data
mkdir -p $Results
DOCK_VOL+=" --mount type=bind,src=$Data,dst=/Data"
DOCK_VOL+=" --mount type=bind,src=$Results,dst=/Results"
if [ $# -lt 3 ]
then
APP_IMG="mbbteam/capture_uce:latest"
else
IMG_SRC=$3
case $IMG_SRC in
dockerHub )
APP_IMG="mbbteam/capture_uce:latest" ;;
local)
docker build . -t capture_uce:latest
APP_IMG="capture_uce:latest" ;;
mbb)
#APP_IMG="X.X.X.X:5000/capture_uce:latest" ;;
esac
fi
CONTAINER_ID=$( docker run --rm -d -p $APP_PORT:3838 $DOCK_VOL $APP_IMG )
if [ $CONTAINER_ID ]
then
echo " "
echo You have to put your Data on : $1
echo " "
echo Results will be written to : $2
echo " "
hostname -I | grep -E -o "162.38.181.[0-9]{1,3}" | awk -v port=$APP_PORT '{print "You can access the workflow interface at : http://"$1":"port}'
echo " "
echo To start a Bash session inside the container : docker exec -it $CONTAINER_ID /bin/bash
else
echo Failed to run the docker container !!
fi
#!/bin/bash
# This script is executed on the virtual machine during the *Deployment* phase.
# It is used to apply parameters specific to the current deployment.
# It is executed secondly during a cloud deployement in IFB-Biosphere, after the *Installation* phase.
if [ $# -lt 1 ]
then
APP_IMG="mbbteam/capture_uce:latest"
else
IMG_SRC=$1
case $IMG_SRC in
ifb)
APP_IMG="gitlab-registry.in2p3.fr/ifb-biosphere/apps/capture_uce:master" ;;
docker )
APP_IMG="mbbteam/capture_uce:latest" ;;
local)
docker build . -t capture_uce:latest
APP_IMG="capture_uce:latest" ;;
mbb)
#APP_IMG="X.X.X.X:5000/capture_uce:latest" ;;
esac
fi
# Tuning if site proxy or not
#CLOUD_SERVICE = $(ss-get cloudservice)
#CLOUD_SERVICE="ifb-genouest-genostack"
#HOST_NAME=$( ss-get --timeout=3 hostname )
HOST_NAME="192.168.100.49"
#if [ "$CLOUD_SERVICE" == "ifb-genouest-genostack" ]; then
# Cloud site WITH a site proxy
# APP_PORT=80
# PROXIED_IP=$( echo $HOST_NAME | sed "s|\.|-|g")
# HOST_NAME="openstack-${PROXIED_IP}.genouest.org"
# HTTP_ENDP="https://$HOST_NAME"
# systemctl stop nginx
#else
# Cloud site WOUT a site proxy
APP_PORT=8787
HTTP_ENDP="https://$HOST_NAME"
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/C=FR/ST=AURA/L=Lyon/O=IFB/OU=IFB-biosphere/CN=myrstudio.biosphere.france-bioinformatique.fr"
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
mkdir -p /etc/nginx/snippets
echo "ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;" > /etc/nginx/snippets/self-signed.conf
echo "ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;" >> /etc/nginx/snippets/self-signed.conf
cp system/nginx_snippets_ssl-params.conf /etc/nginx/snippets/ssl-params.conf
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
cp system/nginx_sites-available_default /etc/nginx/sites-available/default
sed -i "s|server_domain_or_IP|$HOST_NAME|" /etc/nginx/sites-available/default
useradd nginx
cp system/nginx_nginx.conf /etc/nginx/nginx.conf
cp system/nginx_conf.d_10-rstudio.conf /etc/nginx/conf.d/10-rstudio.conf
sed -i "s|example.com|$HOST_NAME|" /etc/nginx/conf.d/10-rstudio.conf
systemctl restart nginx
systemctl enable nginx
#fi
# Docker volumes
# mydatalocal: from the system disk or ephemeral one
IFB_DATADIR="/ifb/data/"
source /etc/profile.d/ifb.sh
VOL_NAME="mydatalocal"
VOL_DEV=$(readlink -f -n $IFB_DATADIR/$VOL_NAME )
DOCK_VOL=" --mount type=bind,src=$VOL_DEV,dst=$IFB_DATADIR/$VOL_NAME"
# MBB Workflows reads data from /Data and write results to /Results
mkdir ${VOL_DEV}/Data
mkdir ${VOL_DEV}/Results
DOCK_VOL+=" --mount type=bind,src=$VOL_DEV/Data,dst=/Data"
DOCK_VOL+=" --mount type=bind,src=$VOL_DEV/Results,dst=/Results"
# NFS mounts: from ifb_share configuration in autofs
IFS_ORI=$IFS
while IFS=" :" read VOL_NAME VOL_TYPE VOL_IP VOL_DEV ; do
DOCK_VOL+=" --mount type=volume,volume-driver=local,volume-opt=type=nfs,src=$VOL_NAME,dst=$IFB_DATADIR/$VOL_NAME,volume-opt=device=:$VOL_DEV,volume-opt=o=addr=$VOL_IP"
done < /etc/auto.ifb_share
IFS=$IFS_ORI
CONTAINER_ID=$( docker run -d -p $APP_PORT:3838 $DOCK_VOL $APP_IMG )
VM_IP=$(curl bot.whatismyipaddress.com)
if [ $CONTAINER_ID ]
then
echo " "
echo You have to put your Data on : ${VOL_DEV}/Data
echo " "
echo Results will be written to : ${VOL_DEV}/Results
echo " "
echo You can access the workflow interface at : https://${VM_IP}
echo " "
echo To start a Bash session inside the container : docker exec -it $CONTAINER_ID /bin/bash
echo " "
echo To run the workflow without the interface : docker exec -it $CONTAINER_ID snakemake -s /workflow/Snakefile all --configfile config --cores XX
echo " "
echo config est un fichier de configuration qui doit être dans un sous dossier de ${VOL_DEV}/Data ou ${VOL_DEV}/Results
echo " "
echo ex. si fichier dans ${VOL_DEV}/Data/run1/maconfig1.yml : docker exec -it $CONTAINER_ID snakemake -s /workflow/Snakefile all --configfile /Data/run1/maconfig1.yml --cores XX
echo " "
echo Vous pouvez utiliser l''interface graphique pour générer un fichier de configuration.
echo " "
echo XX étant le nombre de coeurs qui seront utilisés par le workflow.
else
echo Failed to run the docker container !!
fi
from tools import *
from raw_reads import raw_reads
# File generate with generate_workflow_snakefile.py
import os
import re
import snakemake.utils
import csv
#############
# Wildcards #
#############
STEPS = config["steps"]
PREPARE_REPORT_OUTPUTS = config["prepare_report_outputs"]
PREPARE_REPORT_SCRIPTS = config["prepare_report_scripts"]
OUTPUTS = config["outputs"]
PARAMS_INFO = config["params_info"]
config = config["params"]
##########
# Inputs #
##########
# raw_inputs function call
raw_reads = raw_reads(config['results_dir'], config['sample_dir'], config['SeOrPe'])
config.update(raw_reads)
SAMPLES = raw_reads['samples']
def get_individus():
if (config["demultiplexing"] == "null"):
return SAMPLES
else:
with open(config["demultiplexing_astrid_cruaud_barcodes"], mode="r") as infile:
reader = csv.reader(infile,delimiter='\t')
next(reader, None) # remove header (first line)
return [row[0] for row in reader]
INDIVIDUS = get_individus()
# Tools inputs functions
def fastqc_PE_inputs():
inputs = dict()
inputs["read"] = raw_reads["read"]
inputs["read2"] = raw_reads["read2"]
return inputs
def fastqc_SE_inputs():
inputs = dict()
inputs["read"] = raw_reads["read"]
return inputs
def trimmomatic_PE_inputs():
inputs = dict()
inputs["read"] = raw_reads["read"]
inputs["read2"] = raw_reads["read2"]
return inputs
def trimmomatic_SE_inputs():
inputs = dict()
inputs["read"] = raw_reads["read"]
return inputs
def flash_inputs():
inputs = dict()
inputs["read"] = rules.trimmomatic_PE.output.readFP
inputs["read2"] = rules.trimmomatic_PE.output.readRP
return inputs
def demultiplexing_astrid_cruaud_inputs():
inputs = dict()
inputs["extended_frags"] = expand(rules.flash.output.extendedFrags, sample=SAMPLES)
return inputs
def velvet_inputs():
inputs = dict()
inputs["merged_reads"] = config["results_dir"]+"/"+config["demultiplexing_astrid_cruaud_output_dir"]+"/{sample}_fq"
return inputs
def lastz_inputs():
inputs = dict()
inputs["contigs"] = rules.velvet.output.contigs
return inputs
def prepare_report_inputs():
inputs = list()
for step in STEPS:
inputs.extend(step_outputs(step["name"]))
return inputs
def prepare_report_scripts():
scripts = list()
for step in STEPS:
tool = config[step["name"]]
prefix = tool+".prepare.report."
if type(PREPARE_REPORT_SCRIPTS) == type(""):
if prefix in PREPARE_REPORT_SCRIPTS:
scripts.append("/workflow/scripts/"+PREPARE_REPORT_SCRIPTS)
else :
script = [s for s in PREPARE_REPORT_SCRIPTS if prefix in s]
if (len(script)==1):
scripts.append("/workflow/scripts/"+script[0])
return scripts
def prepare_report_outputs():
outputs = list()
outputs.append(config["results_dir"] + "/outputs_mqc.csv")
for step in STEPS:
tool = config[step["name"]]
if (tool in PREPARE_REPORT_OUTPUTS.keys()):
if type(PREPARE_REPORT_OUTPUTS[tool]) == type(""):
outputs.append(config["results_dir"]+"/"+tool+"/"+PREPARE_REPORT_OUTPUTS[tool])
else:
for output in PREPARE_REPORT_OUTPUTS[tool]:
outputs.append(config["results_dir"]+"/"+tool+"/"+output)
return outputs
def multiqc_inputs():
# Need prepare_report inputs and outputs in case prepare_reports has no outputs
return prepare_report_outputs()
###########
# Outputs #
###########
def step_outputs(step):
outputs = list()
if (step == "quality_control" and config['SeOrPe'] == 'PE' ):
outputs = expand(rules.fastqc_PE.output, sample=SAMPLES)
if (step == "qcfilter_adaptertrim" and config['SeOrPe'] == 'PE' ):
outputs = expand(rules.trimmomatic_PE.output, sample=SAMPLES)
if (step == "merge_overlapps" ):
outputs = expand(rules.flash.output, sample=SAMPLES)
if (step == "demultiplexing" ):
outputs = rules.demultiplexing_astrid_cruaud.output
if (step == "assembling" ):
outputs = expand(rules.velvet.output, sample=INDIVIDUS)
if (step == "contigmaptouce" ):
outputs = expand(rules.lastz.output, sample=INDIVIDUS)
if (step == "all"):
outputs = list(rules.multiqc.output)
return outputs
# get outputs for each choosen tools
def workflow_outputs(step):
outputs = list()
outputs.extend(step_outputs(step))
return outputs
#########
# Rules #
#########
rule fastqc_SE:
input:
**fastqc_SE_inputs()
output:
html = config["results_dir"]+'/'+config["fastqc_SE_output_dir"]+'/{sample}'+config["sample_suffix"].split(".")[0]+'_fastqc.html',
zip = config["results_dir"]+'/'+config["fastqc_SE_output_dir"]+'/{sample}'+config["sample_suffix"].split(".")[0]+'_fastqc.zip',
log: config["results_dir"]+'/logs/fastqc/{sample}_fastqc_log.txt'
threads: 1
params:
command = config["fastqc_SE_command"],
output_dir = config["results_dir"]+'/'+config["fastqc_SE_output_dir"]
shell:
"{params.command} "
"{input.read} "
"-t {threads} "
"-o {params.output_dir} "
"--quiet "
"|& tee {log}"
rule fastqc_PE:
input:
**fastqc_PE_inputs()
output:
html1 = config["results_dir"]+'/'+config["fastqc_PE_output_dir"]+'/{sample}_R1'+config["sample_suffix"].split(".")[0]+'_fastqc.html',
zip1 = config["results_dir"]+'/'+config["fastqc_PE_output_dir"]+'/{sample}_R1'+config["sample_suffix"].split(".")[0]+'_fastqc.zip',
html2 = config["results_dir"]+'/'+config["fastqc_PE_output_dir"]+'/{sample}_R2'+config["sample_suffix"].split(".")[0]+'_fastqc.html',
zip2 = config["results_dir"]+'/'+config["fastqc_PE_output_dir"]+'/{sample}_R2'+config["sample_suffix"].split(".")[0]+'_fastqc.zip',
log: config["results_dir"]+'/logs/fastqc/{sample}_fastqc_log.txt'
threads: 2
params:
command = config["fastqc_PE_command"],
output_dir = config["results_dir"]+'/'+config["fastqc_PE_output_dir"]
shell:
"{params.command} "
"{input.read} "
"{input.read2} "
"-t {threads} "
"-o {params.output_dir} "
"--quiet "
"|& tee {log}"
ruleorder: fastqc_PE > fastqc_SE
rule trimmomatic_PE:
input:
**trimmomatic_PE_inputs()
output:
readFP = config["results_dir"]+"/"+config["trimmomatic_PE_output_dir"]+"/{sample}_forward_paired.fq.gz",
readFU = config["results_dir"]+"/"+config["trimmomatic_PE_output_dir"]+"/{sample}_forward_unpaired.fq.gz",
readRP = config["results_dir"]+"/"+config["trimmomatic_PE_output_dir"]+"/{sample}_reverse_paired.fq.gz",
readRU = config["results_dir"]+"/"+config["trimmomatic_PE_output_dir"]+"/{sample}_reverse_unpaired.fq.gz",
log:
config["results_dir"]+'/logs/trimmomatic/{sample}_trimmomatic_log.txt'
params:
command = config["trimmomatic_PE_command"],
qc_score = config["trimmomatic_qc_score"],
ILLUMINACLIP = "ILLUMINACLIP:" + config["trimmomatic_fastaWithAdapters"] + ":" + config["trimmomatic_illuminaclip"] if (config["trimmomatic_fastaWithAdapters"] != "") else "",
otherparams = config["trimmomatic_otherparams"]
threads:
config["trimmomatic_threads"]
shell:
"{params.command} "
"{params.qc_score} "
"-threads {threads} "
"{input.read} "
"{input.read2} "
"{output.readFP} "
"{output.readFU} "
"{output.readRP} "
"{output.readRU} "
"{params.ILLUMINACLIP} "
"{params.otherparams} "
"|& tee {log}"
rule trimmomatic_SE:
input:
**trimmomatic_SE_inputs()
output:
read = config["results_dir"]+"/"+config["trimmomatic_SE_output_dir"]+"/{sample}_trimmed.fq.gz",
log:
config["results_dir"]+'/logs/trimmomatic/{sample}_trimmomatic_log.txt'
params:
command = config["trimmomatic_SE_command"],
qc_score = config["trimmomatic_qc_score"],
ILLUMINACLIP = "ILLUMINACLIP:" + config["trimmomatic_fastaWithAdapters"] + ":" + config["trimmomatic_illuminaclip"] if (config["trimmomatic_fastaWithAdapters"] != "") else "",
otherparams = config["trimmomatic_otherparams"]
threads:
config["trimmomatic_threads"]
shell:
"{params.command} "
"{params.qc_score} "
"-threads {threads} "
"{input} "
"{output} "
"{params.ILLUMINACLIP} "
"{params.otherparams} "
"|& tee {log}"
ruleorder: trimmomatic_PE > trimmomatic_SE
rule flash:
input:
**flash_inputs()
output:
extendedFrags = config["results_dir"] + "/" + config["flash_output_dir"] + "/{sample}.extendedFrags.fastq",
notCombined_1 = config["results_dir"] + "/" + config["flash_output_dir"] + "/{sample}.notCombined_1.fastq",
notCombined_2 = config["results_dir"] + "/" + config["flash_output_dir"] + "/{sample}.notCombined_2.fastq",
hist = config["results_dir"] + "/" + config["flash_output_dir"] + "/{sample}.hist",
histogram = config["results_dir"] + "/" + config["flash_output_dir"] + "/{sample}.histogram",
params:
output_dir = config["results_dir"] + "/" + config["flash_output_dir"],
command = config["flash_command"],
min_overlap = config["flash_min_overlap"],
max_overlap = config["flash_max_overlap"],
max_mismatch_density = config["flash_max_mismatch_density"],
log:
config["results_dir"]+"/logs/flash/{sample}_flash_log.txt"
threads: config["flash_threads"]
shell:
"{params.command} "
"-x {params.max_mismatch_density} "
"-m {params.min_overlap} "
"-M {params.max_overlap} "
"-d {params.output_dir} "
"-o {wildcards.sample} "
"-t {threads} "
"{input.read} "
"{input.read2} "
"|& tee {log}"
rule demultiplexing_astrid_cruaud:
input:
**demultiplexing_astrid_cruaud_inputs()
output:
demultiplexed = expand(config["results_dir"] + "/" + config["demultiplexing_astrid_cruaud_output_dir"] + "/{sample}_fq", sample=INDIVIDUS),
stats = config["results_dir"] + "/" + config["demultiplexing_astrid_cruaud_output_dir"] + "/stat_demultiplexing.txt",
params:
output_dir = config["results_dir"] + "/" + config["demultiplexing_astrid_cruaud_output_dir"],
barcodes = config["demultiplexing_astrid_cruaud_barcodes"]