diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 59b498464e973523f9ea95f9d55ca5ba9cd50847..6458ae9769f0a701550abcec6f9e4f0b960939f7 100755
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -108,10 +108,11 @@ func-test-ubuntu:
     - ./make
   script:
     - py.test test/test_functional/test_prepare* -vx
-    - py.test test/test_functional/test_pangenome* -vx
+    - py.test test/test_functional/test_pangenome.py -vx
+    - py.test test/test_functional/test_pangenome-parser.py -vx
     - py.test test/test_functional/test_corepers* -vx
-    # - py.test test/test_functional/test_align* -vx
     - py.test test/test_functional/test_align-parser.py -vx
+    - py.test test/test_functional/test_align.py -vx
     - py.test test/test_functional/test_tree* -vx
     - py.test test/test_functional/test_annote-parser.py -vx
     - py.test test/test_functional/test_annote.py -xv
diff --git a/PanACoTA/__init__.py b/PanACoTA/__init__.py
index 318e01994a20fd88276abb6d070a971128142caf..ca40ae1e4c833e995559dcaa8e9457988b460cf5 100755
--- a/PanACoTA/__init__.py
+++ b/PanACoTA/__init__.py
@@ -1,3 +1,4 @@
 """PanACoTA"""
 
-__version__ = "1.0.1-2"
+__version__ = "1.2-dev"
+
diff --git a/PanACoTA/align_module/get_seqs.py b/PanACoTA/align_module/get_seqs.py
index 19c8ce77d019b1ca397eca999137410055cd1b33..f9c79de4edd452a3b65e937c9e351cd639459335 100755
--- a/PanACoTA/align_module/get_seqs.py
+++ b/PanACoTA/align_module/get_seqs.py
@@ -80,7 +80,7 @@ def get_all_seqs(all_genomes, dname, dbpath, listdir, aldir, all_fams, quiet):
     bar = None
     curnum = 1
     if not quiet:
-        widgets = ['Gene and Protein extraction:',
+        widgets = ['Extraction:',
                    progressbar.Bar(marker='â–ˆ', left='', right='', fill=' '),
                    ' ', progressbar.Counter(), "/{}".format(nbgen), ' (',
                    progressbar.Percentage(), ") - ", progressbar.Timer(), ' ',
diff --git a/PanACoTA/align_module/post_align.py b/PanACoTA/align_module/post_align.py
index c0149a34dba8b05415506fe07f1f95a4b3f61088..4cc4c1a9299386b73f7b1c41d9b3e057b7ee527e 100755
--- a/PanACoTA/align_module/post_align.py
+++ b/PanACoTA/align_module/post_align.py
@@ -76,9 +76,11 @@ def post_alignment(fam_nums, all_genomes, prefix, outdir, dname, quiet):
     all_alns, status = concat_alignments(fam_nums, prefix, quiet)
     treedir = os.path.join(outdir, "Phylo-" + dname)
     os.makedirs(treedir, exist_ok=True)
-    res = launch_group_by_genome(all_genomes, all_alns, status, treedir, dname, quiet)
+    outfile = os.path.join(treedir, dname + ".grp.aln")
+    res = launch_group_by_genome(all_genomes, all_alns, status, outfile, dname, quiet)
     if not res:
         logger.error("An error occurred. We could not group sequences by genome.")
+    return outfile
 
 
 def concat_alignments(fam_nums, prefix, quiet):
@@ -124,7 +126,7 @@ def concat_alignments(fam_nums, prefix, quiet):
     return output, "Done"
 
 
-def launch_group_by_genome(all_genomes, all_alns, status, treedir, dname, quiet):
+def launch_group_by_genome(all_genomes, all_alns, status, outfile, dname, quiet):
     """
     Function calling group_by_genome in a pool, while giving information to user
     (time elapsed)
@@ -137,8 +139,8 @@ def launch_group_by_genome(all_genomes, all_alns, status, treedir, dname, quiet)
         path to file containing all alignments concatenated
     status : str
         "OK" if concatenation file already existed before running, "Done" if just did concatenation
-    treedir : str
-        path to tree directory
+    outfile : str
+        file containing all families align by genome
     dname : str
         name of dataset
     quiet : bool
@@ -150,13 +152,17 @@ def launch_group_by_genome(all_genomes, all_alns, status, treedir, dname, quiet)
         - True if everything went well or was already done
         - False if error occurred in at least one step
     """
-    outfile = os.path.join(treedir, dname + ".grp.aln")
+    # Status = Done means that we just did the concatenation. So, if grouped by genome
+    # file already exists, remove it.
     if status == "Done":
-        utils.remove(outfile)
+        if os.path.isfile(outfile):
+            utils.remove(outfile)
+    # Status was not 'Done' (it was 'ok', concat file already existed). And by_genome file
+    # also already exists. Warn user
     if os.path.isfile(outfile):
         logger.info("Alignments already grouped by genome")
-        logger.warning(("Alignments already grouped by genome in {}. "
-                        "Program will end. ").format(outfile))
+        logger.warning((f"Alignments already grouped by genome in {outfile}. "
+                        "Program will end. "))
         return True
     logger.info("Grouping alignments per genome")
     bar = None
diff --git a/PanACoTA/annotate_module/general_format_functions.py b/PanACoTA/annotate_module/general_format_functions.py
index 1a1e30ce50e9c203fb3f6bcf9ef80e74f8f38966..0532b0a56cadd5375353323327bf885a8b35a64b 100644
--- a/PanACoTA/annotate_module/general_format_functions.py
+++ b/PanACoTA/annotate_module/general_format_functions.py
@@ -119,7 +119,7 @@ def format_genomes(genomes_ok, res_path, annot_path, prodigal_only, threads=1, q
                    progressbar.Bar(marker='â–ˆ', left='', right=''),
                    ' ', progressbar.Counter(), "/{}".format(nbgen), ' (',
                    progressbar.Percentage(), ") - ", progressbar.Timer()]
-        bar = progressbar.ProgressBar(widgets=widgets, max_value=nbgen, term_width=100).start()
+        bar = progressbar.ProgressBar(widgets=widgets, max_value=nbgen, term_width=79).start()
     # Create a Queue to put logs from processes, and handle them after from a single thread
     m = multiprocessing.Manager()
     q = m.Queue()
diff --git a/PanACoTA/annotate_module/genome_seq_functions.py b/PanACoTA/annotate_module/genome_seq_functions.py
index dbb8a2b3a006bd9f78e29e65fd1b0accd95757a1..269f660251a727206e9baf50475fa08b86c661d6 100755
--- a/PanACoTA/annotate_module/genome_seq_functions.py
+++ b/PanACoTA/annotate_module/genome_seq_functions.py
@@ -101,7 +101,7 @@ def analyse_all_genomes(genomes, dbpath, tmp_path, nbn, soft, logger, quiet=Fals
                    progressbar.Percentage(), ') - ', progressbar.Timer(), ' - ',
                    progressbar.ETA()
                    ]
-        bar = progressbar.ProgressBar(widgets=widgets, max_value=nbgen, term_width=100).start()
+        bar = progressbar.ProgressBar(widgets=widgets, max_value=nbgen, term_width=79).start()
         curnum = 1
     toremove = []
     # Analyse genomes 1 by 1
diff --git a/PanACoTA/bin/run_panacota.py b/PanACoTA/bin/run_panacota.py
index a4d3c97271dd9df5aaa83bb10f29fc7fa2e4e867..4872244e2b63af633d62732261939d89b6673db7 100755
--- a/PanACoTA/bin/run_panacota.py
+++ b/PanACoTA/bin/run_panacota.py
@@ -40,6 +40,7 @@ from textwrap import dedent
 
 from PanACoTA import __version__ as version
 
+from PanACoTA.subcommands import all_modules
 from PanACoTA.subcommands import prepare
 from PanACoTA.subcommands import annotate
 from PanACoTA.subcommands import pangenome
@@ -98,6 +99,18 @@ def parse_arguments(argv):
     actions = {}  # to add the action to do according to the subparser called
     checks = {}  # to add the function to call to check the subparser arguments
 
+    # Running all modules at once. Start with ASCII art title, + small description of subcommand
+    parser_all = subparsers.add_parser('all',
+                                        formatter_class=argparse.RawDescriptionHelpFormatter,
+                                        description=(dedent(header) +
+                                        "\n=> Run all PanACoTA modules"),
+                                        epilog=footer,
+                                        help="Run all PanACoTA modules",
+                                        add_help=False)
+    all_modules.build_parser(parser_all)
+    actions["all"] = all_modules.main_from_parse
+    # checks["all_modules"] = all_modules.check_args
+
     # Preparation part. Start with ASCII art title, + small description of subcommand
     parser_prepare = subparsers.add_parser('prepare',
                                             formatter_class=argparse.RawDescriptionHelpFormatter,
diff --git a/PanACoTA/pangenome_module/mmseqs_functions.py b/PanACoTA/pangenome_module/mmseqs_functions.py
index b57bbc141ff3eb594b8bd42de352804d252a9301..af42e1aad27d91f4012f39498071e6ea054173db 100755
--- a/PanACoTA/pangenome_module/mmseqs_functions.py
+++ b/PanACoTA/pangenome_module/mmseqs_functions.py
@@ -245,7 +245,8 @@ def run_mmseqs_clust(args):
     mmseqdb, mmseqclust, tmpdir, logmmseq, min_id, threads, clust_mode = args
     cmd = ("mmseqs cluster {} {} {} --min-seq-id {} --threads {} --cluster-mode "
            "{}").format(mmseqdb, mmseqclust, tmpdir, min_id, threads, clust_mode)
-    msg = "Problem while clustering proteins with mmseqs. See log in {logmmseq}"
+    logger.details(f"MMseqs command: {cmd}")
+    msg = f"Problem while clustering proteins with mmseqs. See log in {logmmseq}"
     with open(logmmseq, "a") as logm:
         utils.run_cmd(cmd, msg, eof=False, stdout=logm, stderr=logm)
 
@@ -279,7 +280,7 @@ def mmseqs_to_pangenome(mmseqdb, mmseqclust, logmmseq, start, outfile=None):
     """
     cmd = f"mmseqs createtsv {mmseqdb} {mmseqdb} {mmseqclust} {mmseqclust}.tsv"
     msg = "Problem while trying to convert mmseq result file to tsv file"
-    logger.info(f"MMseqs command: {cmd}")
+    logger.details(f"MMseqs command: {cmd}")
     with open(logmmseq, "a") as logf:
         utils.run_cmd(cmd, msg, eof=True, stdout=logf, stderr=logf)
     # Convert the tsv file to a 'pangenome' file: one line per family
diff --git a/PanACoTA/prepare_module/download_genomes_func.py b/PanACoTA/prepare_module/download_genomes_func.py
index e820316cc89e4c6f6f2003667a5ac284a583d6a0..ffda095829407a3e106c25f841cda23c5b88d2e6 100644
--- a/PanACoTA/prepare_module/download_genomes_func.py
+++ b/PanACoTA/prepare_module/download_genomes_func.py
@@ -142,7 +142,6 @@ def download_from_refseq(species_linked, NCBI_species, NCBI_taxid, levels, outdi
         logger.error(error_message)
         sys.exit(1)
     nb_gen, db_dir = to_database(outdir)
-    logger.info(f"Downloaded {nb_gen} genomes.")
     return db_dir, nb_gen
 
 
diff --git a/PanACoTA/prepare_module/filter_genomes.py b/PanACoTA/prepare_module/filter_genomes.py
index aa3d71678a0005dc8e62819f8076a96ee2b8e638..b56e9a185c69db12037472c2860244c633f3ebb6 100755
--- a/PanACoTA/prepare_module/filter_genomes.py
+++ b/PanACoTA/prepare_module/filter_genomes.py
@@ -227,7 +227,7 @@ def iterative_mash(sorted_genomes, genomes, outdir, species_linked, min_dist, ma
                    progressbar.Counter(), "/{}".format(nbgen), ' ',
                    progressbar.Timer(), ' - '
                   ]
-        bar = progressbar.ProgressBar(widgets=widgets, max_value=len(to_try), term_width=100).start()
+        bar = progressbar.ProgressBar(widgets=widgets, max_value=len(to_try), term_width=79).start()
         done = 0
 
     while len(to_try) > 1:
@@ -504,4 +504,4 @@ def write_outputfiles(genomes, sorted_genomes, genomes_removed, outdir, gspecies
             disf.write(utils.list_to_str([genome] + info))
     logger.info(f"Final list of genomes in the dataset: {list_file}")
     logger.info(f"List of genomes discarded by minhash steps: {discard_file}")
-    return 0
+    return list_file
diff --git a/PanACoTA/subcommands/align.py b/PanACoTA/subcommands/align.py
index 0000d3f6bc36a041e1bb9cd0c7da7d744d748867..76d7c1abd8fbd7f41c36fa40226dc95368af4385 100755
--- a/PanACoTA/subcommands/align.py
+++ b/PanACoTA/subcommands/align.py
@@ -141,9 +141,9 @@ def main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force, ver
         sys.exit(1)
 
     # post-process alignment files
-    post.post_alignment(fam_nums, all_genomes, prefix, outdir, dname, quiet)
+    align_file = post.post_alignment(fam_nums, all_genomes, prefix, outdir, dname, quiet)
     logger.info("END")
-    return 0
+    return align_file
 
 
 def build_parser(parser):
diff --git a/PanACoTA/subcommands/all_modules.py b/PanACoTA/subcommands/all_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..62fb3fa7476c4b1374a1605d3f3b268534a5e471
--- /dev/null
+++ b/PanACoTA/subcommands/all_modules.py
@@ -0,0 +1,337 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+# ###############################################################################
+# This file is part of PanACOTA.                                                #
+#                                                                               #
+# Authors: Amandine Perrin                                                      #
+# Copyright © 2018-2020 Institut Pasteur (Paris).                               #
+# See the COPYRIGHT file for details.                                           #
+#                                                                               #
+# PanACOTA is a software providing tools for large scale bacterial comparative  #
+# genomics. From a set of complete and/or draft genomes, you can:               #
+#    -  Do a quality control of your strains, to eliminate poor quality         #
+# genomes, which would not give any information for the comparative study       #
+#    -  Uniformly annotate all genomes                                          #
+#    -  Do a Pan-genome                                                         #
+#    -  Do a Core or Persistent genome                                          #
+#    -  Align all Core/Persistent families                                      #
+#    -  Infer a phylogenetic tree from the Core/Persistent families             #
+#                                                                               #
+# PanACOTA is free software: you can redistribute it and/or modify it under the #
+# terms of the Affero GNU General Public License as published by the Free       #
+# Software Foundation, either version 3 of the License, or (at your option)     #
+# any later version.                                                            #
+#                                                                               #
+# PanACOTA is distributed in the hope that it will be useful, but WITHOUT ANY   #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS     #
+# FOR A PARTICULAR PURPOSE. See the Affero GNU General Public License           #
+# for more details.                                                             #
+#                                                                               #
+# You should have received a copy of the Affero GNU General Public License      #
+# along with PanACOTA (COPYING file).                                           #
+# If not, see <https://www.gnu.org/licenses/>.                                  #
+# ###############################################################################
+
+"""
+'all' is a module of PanACoTA, allowing to run the whole pipeline at once.
+
+
+@author gem
+October 2020
+"""
+
+import os
+import sys
+from termcolor import colored
+import sys
+
+from PanACoTA import utils
+from PanACoTA.subcommands import prepare
+from PanACoTA.subcommands import annotate
+from PanACoTA.subcommands import pangenome
+from PanACoTA.subcommands import corepers
+from PanACoTA.subcommands import align
+from PanACoTA.subcommands import tree
+from PanACoTA import __version__ as version
+
+
+def main_from_parse(args):
+    """
+    Call main function from the arguments given by parser
+
+    Parameters
+    ----------
+    args : argparse.Namespace
+        result of argparse parsing of all arguments in command line
+    """
+    cmd = "PanACoTA " + ' '.join(args.argv)
+    main(cmd, args.outdir, args.threads, args.NCBI_species_taxid, args.NCBI_species,
+         args.levels, args.cutn, args.l90, args.nbcont, args.name, args.prodigal_only, args.min_id,
+         args.tol, args.multi, args.mixed, args.soft, verbose=args.verbose, quiet=args.quiet)
+
+
+def main(cmd, outdir, threads, NCBI_species_taxid, NCBI_species, levels, cutn, l90, nbcont,
+         name, prodigal_only, min_id, tol, multi, mixed, soft, verbose=0, quiet=False):
+    """
+    Call all modules, one by one, using output of one as input for the next one
+    """
+    os.makedirs(outdir, exist_ok=True)
+    # Initialize logger
+    import logging
+    # set level of logger: level is the minimum level that will be considered.
+    if verbose <= 1:
+        level = logging.INFO
+    # for verbose = 2, ignore only debug
+    if verbose >= 2 and verbose < 15:
+        level = utils.detail_lvl() # int corresponding to detail level
+    # for verbose >= 15, write everything
+    if verbose >= 15:
+        level = logging.DEBUG
+    logfile_base = os.path.join(outdir, "PanACoTA-all_modules")
+    logfile_base = utils.init_logger(logfile_base, level, name='all_modules',
+                                     verbose=verbose, quiet=quiet)
+    logger = logging.getLogger('all_modules')
+    logger.info(f'PanACoTA version {version}')
+    logger.info("Command used\n \t > " + cmd)
+
+    # Run prepare module
+    outdir_prepare = os.path.join(outdir, "1-prepare_module")
+    tmp_dir = ""
+    no_refseq = False
+    db_dir = ""
+    only_mash = False
+    info_file = ""
+    min_dist = 1e-4
+    max_dist = 0.06
+
+    info_file = prepare.main("PanACoTA prepare", NCBI_species, NCBI_species_taxid, levels,
+                             outdir_prepare, tmp_dir, threads, no_refseq, db_dir, only_mash,
+                             info_file, l90, nbcont, cutn, min_dist, max_dist, verbose, quiet)
+
+    # Run annotate module
+    list_file = ""
+    db_path = ""
+    outdir_annotate = os.path.join(outdir, "2-annotate_module")
+    import time
+    date = time.strftime("%m%y")
+    force = False
+    qc_only = False
+    tmp_dir = ""
+    res_annot_dir = None
+    small = False
+
+    lstinfo, nbgenomes = annotate.main("PanACoTA annotate", list_file, db_path, outdir_annotate,
+                                       name, date, l90, nbcont, cutn, threads, force, qc_only,
+                                       info_file, tmp_dir, res_annot_dir, verbose, quiet,
+                                       prodigal_only, small)
+
+    # Pangenome step
+    name_pan = f"{name}_{nbgenomes}"
+    outdir_pan = os.path.join(outdir, "3-pangenome_module")
+    clust_mode = 1
+    spe_dir = ""
+    dbpath = os.path.join(outdir_annotate, "Proteins")
+    panfile = pangenome.main("PanACoTA pangenome", lstinfo, name, dbpath, min_id, outdir_pan,
+                             clust_mode, spe_dir, threads, outfile=None, verbose=verbose,
+                             quiet=quiet)
+
+    # Coregenome step
+    outdir_corpers = os.path.join(outdir, "4-corepers_module")
+    corepers_file = corepers.main("PanACoTA corepers", panfile, tol, multi, mixed, outdir_corpers,
+                                  verbose=verbose, quiet=quiet)
+
+    # Align step
+    outdir_align = os.path.join(outdir, "5-align_module")
+    force = False
+    align_file = align.main("PanACoTA align", corepers_file, lstinfo, name_pan, outdir_annotate,
+                            outdir_align, threads, force, verbose, quiet)
+    print(align_file)
+
+    # Tree step
+    # models_fastme = {"p-distance": "p", "RY-symetric": "Y", "RY": "R",
+    #                  "JC69": "J", "K2P": "K", "F81": "1", "F84": "4",
+    #                  "TN93": "T", "LogDet": "L"}
+    # models_fasttree = {"GTR": "-gtr", "JC": ""}
+    # models_iqtree = set(["HKY", "JC", "F81", "K2P", "K3P", "K81uf",
+    #                      "TNef", "TIM", "TIMef", "TVM", "TVMef", "SYM", "GTR"])
+    # models_iqtree = {mod: mod for mod in models_iqtree}
+    if soft == "fasttree":
+        model = "-gtr"
+    elif soft =="iqtree" or soft == "iqtree2":
+        model = "GTR"
+    elif soft == "quicktree":
+        model = ""
+    elif soft == "fastme":
+        model = "T"
+    else:
+        logger.error(f"Soft {soft} is not possible.")
+        sys.exit(1)
+    outdir_tree = os.path.join(outdir, "6-tree_module")
+    tree.main("PanACoTA tree", align_file, outdir_tree, soft, model, threads, boot=False,
+              write_boot=False, memory=False, fast=False, verbose=verbose, quiet=quiet)
+
+    logger.info("All modules of PanACOTA are finished.")
+
+
+def build_parser(parser):
+    """
+    Method to create a parser for command-line options
+
+    Parameters
+    ----------
+    parser : argparse.ArgumentParser
+        The parser to configure
+
+    """
+    import argparse
+    from PanACoTA import utils_argparse
+
+    # Create command-line parser for all options and arguments to give
+    general = parser.add_argument_group("General arguments")
+    general.add_argument("-o", dest="outdir", required=True,
+                          help=("Path to your output folder, where all results "
+                                "from all 6 modules will be saved.")
+                          )
+    general.add_argument("--threads", dest="threads", type=utils_argparse.thread_num, default=1,
+                          help="Specify how many threads can be used (default=1)")
+
+    prepare = parser.add_argument_group("'prepare' module arguments")
+    prepare.add_argument("-t", dest="NCBI_species_taxid", default="",
+                          help=("Species taxid to download, corresponding to the "
+                                "'species taxid' provided by the NCBI. A comma-separated "
+                                "list of taxid can also be provided.")
+                         )
+    prepare.add_argument("-s", dest="NCBI_species", default="",
+                          help=("Species to download, corresponding to the "
+                                "'organism name' provided by the NCBI. Give name between "
+                                "quotes (for example \"escherichia coli\")")
+                        )
+    prepare.add_argument("-l", "--assembly_level", dest="levels", default="",
+                          help=("Assembly levels of genomes to download (default: all). "
+                                "Possible levels are: 'all', 'complete', 'chromosome', "
+                                "'scaffold', 'contig'."
+                                "You can also provide a comma-separated list of assembly "
+                                "levels. For ex: 'complete,chromosome'")
+                          )
+    prepare_annote = parser.add_argument_group("Common arguments to 'prepare' "
+                                               "and 'annotate' modules")
+    prepare_annote.add_argument("--cutn", dest="cutn", type=utils_argparse.positive_int, default=5,
+                          help=("By default, each genome will be cut into new contigs when "
+                                "at least 5 'N' in a row are found in its sequence. "
+                                "If you don't want to "
+                                "cut genomes into new contigs when there are rows of 'N', "
+                                "put 0 to this option. If you want to cut from a different number "
+                                "of 'N' in a row, put this value to this option.")
+                          )
+    prepare_annote.add_argument("--l90", dest="l90", type=int, default=100,
+                                help=("Maximum value of L90 allowed to keep a genome. "
+                                      "Default is 100.")
+                                )
+    prepare_annote.add_argument("--nbcont", dest="nbcont", type=utils_argparse.cont_num,
+                                default=999, help=("Maximum number of contigs allowed to "
+                                                   "keep a genome. Default is 999."))
+
+    # build_parser(prepare)
+    # args_prepare = parser.parse_args(argu)
+    # prepare.check_args(prepare_annote, args_prepare)
+    # OPTIONS = parse(my_parser, sys.argv[1:])
+
+    annote = parser.add_argument_group("'annotate' module arguments")
+    annote.add_argument("--prodigal", dest="prodigal_only", action="store_true", default=False,
+                        help="Add this option if you only want syntactical annotation, given "
+                             "by prodigal, and not functional annotation requiring prokka and "
+                             "is slower.")
+    annote.add_argument("-n", dest="name", required=True, type=utils_argparse.gen_name,
+                        help=("Choose a name for your annotated genomes. This name should "
+                              "contain 4 alphanumeric characters. Generally, they correspond "
+                              "to the 2 first letters of genus, and 2 first letters of "
+                              "species, e.g. ESCO for Escherichia Coli."))
+
+    pangenome = parser.add_argument_group("'pangenome' module arguments")
+    pangenome.add_argument("-i", dest="min_id", type=utils_argparse.perc_id, default=0.8,
+                           help=("Minimum sequence identity to be considered in the same "
+                                 "cluster (float between 0 and 1). Default is 0.8."))
+
+    corepers = parser.add_argument_group("'corepers' module arguments")
+    corepers.add_argument("--tol", dest="tol", type=utils_argparse.percentage, default=1,
+                          help=("min %% of genomes having at least 1 member in a family to "
+                                "consider the family as persistent (between 0 and 1, "
+                                "default is 1 = 100%% of genomes = Core genome)."
+                                "By default, the minimum number of genomes will be "
+                                "ceil('tol'*N) (N being the total number of genomes). If "
+                                "you want to use floor('tol'*N) instead, add the '-F' option."))
+    corepers.add_argument("-M", dest="multi", action='store_true',
+                          help=("Add this option if you allow several members in any genome "
+                                "of a family. By default, only 1 (or 0 if tol<1) member "
+                                "per genome are allowed in all genomes. If you want to allow "
+                                "exactly 1 member in 'tol'%% of the genomes, and 0, 1 "
+                                "or several members in the '1-tol'%% left, use the option -X "
+                                "instead of this one: -M and -X options are not compatible."))
+    corepers.add_argument("-X", dest="mixed", action='store_true',
+                          help="Add this option if you want to allow families having several "
+                               "members only in '1-tol'%% of the genomes. In the other genomes, "
+                               "only 1 member exactly is allowed. This option is not compatible "
+                               "with -M (which is allowing multigenic families: having several "
+                               "members in any number of genomes).")
+
+    tree = parser.add_argument_group("'tree' module arguments")
+    softs = ["fasttree", "fastme", "quicktree", "iqtree", "iqtree2"]
+    tree.add_argument("--soft", dest="soft", choices=softs, default="iqtree",
+                      help=("Choose with which software you want to infer the "
+                            "phylogenetic tree. Default is IQtree."))
+
+    helper = parser.add_argument_group('Others')
+    helper.add_argument("-v", "--verbose", dest="verbose", action="count", default=0,
+                        help="Increase verbosity in stdout/stderr.")
+    helper.add_argument("-q", "--quiet", dest="quiet", action="store_true", default=False,
+                        help=("Do not display anything to stdout/stderr. log files will "
+                              "still be created."))
+    helper.add_argument("-h", "--help", dest="help", action="help",
+                        help="show this help message and exit")
+
+
+def parse(parser, argu):
+    """
+    arse arguments given to parser
+
+    Parameters
+    ----------
+    parser : argparse.ArgumentParser
+        the parser used
+    argu : [str]
+        command-line given by user, to parse using parser
+
+    Returns
+    -------
+    argparse.Namespace
+        Parsed arguments
+    """
+    import argparse
+
+    args = parser.parse_args(argu)
+    return args
+    # return check_args(parser, args)
+
+
+if __name__ == '__main__':
+    import argparse
+    from textwrap import dedent
+    header = '''
+     ___                 _____  ___         _____  _____
+    (  _`\              (  _  )(  _`\      (_   _)(  _  )
+    | |_) )  _ _   ___  | (_) || ( (_)   _   | |  | (_) |
+    | ,__/'/'_` )/' _ `\|  _  || |  _  /'_`\ | |  |  _  |
+    | |   ( (_| || ( ) || | | || (_( )( (_) )| |  | | | |
+    (_)   `\__,_)(_) (_)(_) (_)(____/'`\___/'(_)  (_) (_)
+
+
+       Large scale comparative genomics tools
+
+     -------------------------------------------
+     '''
+    my_parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
+                                        description=dedent(header), add_help=False)
+    build_parser(my_parser)
+    OPTIONS = parse(my_parser, sys.argv[1:])
+    main_from_parse(OPTIONS)
diff --git a/PanACoTA/subcommands/annotate.py b/PanACoTA/subcommands/annotate.py
index 616c2a1c19edd4e6ef20ae70321003019a27c25c..ad4ed1470688c5474d7aaed14ebb1ff4bc3ea71c 100755
--- a/PanACoTA/subcommands/annotate.py
+++ b/PanACoTA/subcommands/annotate.py
@@ -340,7 +340,6 @@ def main(cmd, list_file, db_path, res_dir, name, date, l90=100, nbcont=999, cutn
         # Here, both are the same, as we take given sequences as is.
         genomes = utils.read_genomes_info(from_info, name, date, logger)
 
-
     # STEP 2. keep only genomes with 'good' (according to user thresholds) L90 and nb_contigs
     # genomes = {genome: [spegenus.date, orig_seq, path_to_splitSequence, size, nbcont, l90]}
     # Plot L90 and nb_contigs distributions
@@ -353,7 +352,7 @@ def main(cmd, list_file, db_path, res_dir, name, date, l90=100, nbcont=999, cutn
 
     if not kept_genomes:
         logger.info("No genome kept for annotation.")
-        return 0
+        return "", 0
     # Info on folder containing original sequences
     if not from_info:
         logger.info(f"-> Original sequences folder ('orig_name' column): {db_path} ")
@@ -373,14 +372,14 @@ def main(cmd, list_file, db_path, res_dir, name, date, l90=100, nbcont=999, cutn
         # orig_name, to_annnote, gsize, nb_conts, L90
         utils.write_genomes_info(genomes, [], list_file, res_dir, qc=True)
         logger.info("QC only done.")
-        return 0
+        return "", 0
 
     # STEP 3. Rename genomes kept, ordered by decreasing quality
     gfunc.rename_all_genomes(kept_genomes)
     # kept_genomes = {genome: [gembase_name, path_to_origfile, path_split_gembase,
     #                 gsize, nbcont, L90]}
     # Write lstinfo file (list of genomes kept with info on L90 etc.)
-    utils.write_lstinfo(list_file, kept_genomes, res_dir)
+    outlst = utils.write_lstinfo(list_file, kept_genomes, res_dir)
 
     # STEP 4. Annotate all kept genomes
     results = pfunc.run_annotation_all(kept_genomes, threads, force, res_annot_dir,
@@ -409,13 +408,12 @@ def main(cmd, list_file, db_path, res_dir, name, date, l90=100, nbcont=999, cutn
     # Generate database (folders Proteins, Genes, Replicons, LSTINFO)
     skipped_format = ffunc.format_genomes(results_ok, res_dir, res_annot_dir,
                                           prodigal_only, threads, quiet=quiet)
-    print(skipped_format)
     # At least one genome could not be formatted -> warn user
     if skipped_format:
         utils.write_warning_skipped(skipped_format, do_format=True, prodigal_only=prodigal_only,
                                     logfile = logfile_base)
     logger.info("Annotation step done.")
-    return 0
+    return outlst, len(kept_genomes) - len(skipped) - len(skipped_format)
 
 
 def build_parser(parser):
diff --git a/PanACoTA/subcommands/corepers.py b/PanACoTA/subcommands/corepers.py
index d9e97bde1b6f200e4cd567bc019e5d472275ed60..5104d1446fd42d8aabb027c413feaa49f1fe887a 100755
--- a/PanACoTA/subcommands/corepers.py
+++ b/PanACoTA/subcommands/corepers.py
@@ -144,6 +144,7 @@ def main(cmd, pangenome, tol, multi, mixed, outputdir, floor=False, verbose=0, q
     # Write persistent genome to file
     pers.write_persistent(fams, outputfile)
     logger.info("Persistent genome step done.")
+    return outputfile
 
 
 def get_info(tol, multi, mixed, floor):
@@ -200,18 +201,7 @@ def build_parser(parser):
         parser to configure in order to extract command-line arguments
     """
     import argparse
-
-    def percentage(param):
-        try:
-            param = float(param)
-        except Exception:
-            msg = "argument -t tol: invalid float value: {}".format(param)
-            raise argparse.ArgumentTypeError(msg)
-        if param < 0 or param > 1:
-            msg = ("The minimum %% of genomes required in a family to be persistent must "
-                   "be in [0, 1]. Invalid value: {}".format(param))
-            raise argparse.ArgumentTypeError(msg)
-        return param
+    from PanACoTA import utils_argparse
 
     # Create command-line parser for all options and arguments to give
     required = parser.add_argument_group('Required arguments')
@@ -221,7 +211,7 @@ def build_parser(parser):
                           help=("Specify the output directory for your core/persistent genome."),
                           default=".")
     optional = parser.add_argument_group('Optional arguments')
-    optional.add_argument("-t", "--tol", dest="tol", default=1, type=percentage,
+    optional.add_argument("-t", "--tol", dest="tol", default=1, type=utils_argparse.percentage,
                           help=("min %% of genomes having at least 1 member in a family to "
                                 "consider the family as persistent (between 0 and 1, "
                                 "default is 1 = 100%% of genomes = Core genome)."
diff --git a/PanACoTA/subcommands/pangenome.py b/PanACoTA/subcommands/pangenome.py
index 202b15e50249127bc308b4dfafee806ddfb67bd9..e74e040014e5358010705e678f8de42d675d597b 100755
--- a/PanACoTA/subcommands/pangenome.py
+++ b/PanACoTA/subcommands/pangenome.py
@@ -129,7 +129,7 @@ def main(cmd, lstinfo, name, dbpath, min_id, outdir, clust_mode, spe_dir, thread
         level = logging.DEBUG
     # name logfile, add timestamp if already existing
     logfile_base = os.path.join(outdir, "PanACoTA-pangenome_" + name)
-    utils.init_logger(logfile_base, level, '', verbose=verbose, quiet=quiet)
+    utils.init_logger(logfile_base, level, '', verbose=verbose, quiet=quiet, log_details=True)
     logger = logging.getLogger("pangenome")
     logger.info(f'PanACoTA version {version}')
     logger.info("Command used\n \t > " + cmd)
@@ -142,6 +142,8 @@ def main(cmd, lstinfo, name, dbpath, min_id, outdir, clust_mode, spe_dir, thread
                                               prt_path, threads, outfile, quiet)
     # Create matrix pan_quali, pan_quanti and summary file
     pt.post_treat(families, panfile)
+    logger.info("DONE")
+    return panfile
 
 
 def build_parser(parser):
@@ -154,37 +156,7 @@ def build_parser(parser):
         parser to configure in order to extract command-line arguments
     """
     import argparse
-    import multiprocessing
-
-    def perc_id(param):
-        try:
-            param = float(param)
-        except Exception:
-            msg = "argument -i percentage_id: invalid float value: {}".format(param)
-            raise argparse.ArgumentTypeError(msg)
-        if param < 0 or param > 1:
-            msg = ("The minimum %% of identity must be in [0, 1]. Invalid value: {}".format(param))
-            raise argparse.ArgumentTypeError(msg)
-        return param
-
-    def thread_num(param):
-        try:
-            param = int(param)
-        except Exception:
-            msg = "argument --threads threads: invalid int value: {}".format(param)
-            raise argparse.ArgumentTypeError(msg)
-        nb_cpu = multiprocessing.cpu_count()
-        if param > nb_cpu:
-            msg = ("You have {} threads on your computer, you cannot ask for more: "
-                   "invalid value: {}").format(nb_cpu, param)
-            raise argparse.ArgumentTypeError(msg)
-        elif param < 0:
-            msg = ("Please provide a positive number of threads (or 0 for all threads): "
-                   "Invalid value: {}").format(param)
-            raise argparse.ArgumentTypeError(msg)
-        elif param == 0:
-            return multiprocessing.cpu_count()
-        return param
+    from PanACoTA import utils_argparse
 
     # Create command-line parser for all options and arguments to give
     required = parser.add_argument_group('Required arguments')
@@ -210,7 +182,7 @@ def build_parser(parser):
                                 "(including tmp folder)"))
 
     optional = parser.add_argument_group('Optional arguments')
-    optional.add_argument("-i", dest="min_id", type=perc_id, default=0.8,
+    optional.add_argument("-i", dest="min_id", type=utils_argparse.perc_id, default=0.8,
                           help=("Minimum sequence identity to be considered in the same "
                                 "cluster (float between 0 and 1). Default is 0.8."))
     optional.add_argument("-f", dest="outfile",
@@ -226,7 +198,7 @@ def build_parser(parser):
                           help=("use this option if you want to save the concatenated protein "
                                 "databank in another directory than the one containing all "
                                 "individual protein files ('Proteins' folder)."))
-    optional.add_argument("--threads", dest="threads", default=1, type=thread_num,
+    optional.add_argument("--threads", dest="threads", default=1, type=utils_argparse.thread_num,
                           help=("add this option if you want to parallelize on several threads. "
                                 "Indicate on how many threads you want to parallelize. "
                                 "By default, it uses 1 thread. Put 0 if you want to use "
diff --git a/PanACoTA/subcommands/prepare.py b/PanACoTA/subcommands/prepare.py
index ebe85ea69753ca1d6e2bac136df10d14f4a635e9..9f4d221b3115bf42cec79b2e2ff849fd94636939 100644
--- a/PanACoTA/subcommands/prepare.py
+++ b/PanACoTA/subcommands/prepare.py
@@ -266,8 +266,10 @@ def main(cmd, NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads, no_ref
     removed = fg.iterative_mash(sorted_genomes, genomes, outdir, species_linked,
                                 min_dist, max_dist, threads, quiet)
     # Write list of genomes kept, and list of genomes discarded by mash step
-    fg.write_outputfiles(genomes, sorted_genomes, removed, outdir, species_linked, min_dist, max_dist)
+    info_file = fg.write_outputfiles(genomes, sorted_genomes, removed, outdir, species_linked,
+                                     min_dist, max_dist)
     logger.info("End")
+    return info_file
 
 
 def build_parser(parser):
diff --git a/PanACoTA/subcommands/tree.py b/PanACoTA/subcommands/tree.py
index a5568ce7303c2fead4998685926595d011e3b029..b0d24abe17c96296a613a9bdf33340cb34e35cc5 100755
--- a/PanACoTA/subcommands/tree.py
+++ b/PanACoTA/subcommands/tree.py
@@ -147,7 +147,7 @@ def main(cmd, align, outdir, soft, model, threads, boot=False, write_boot=False,
     if verbose >= 15:
         level = logging.DEBUG
 
-    utils.init_logger(logfile_base, level, 'tree', verbose=verbose, quiet=quiet)
+    utils.init_logger(logfile_base, level, 'tree', verbose=verbose, quiet=quiet, log_details=True)
     logger = logging.getLogger("tree")
     logger.info(f'PanACoTA version {version}')
     logger.info("Command used\n \t > " + cmd)
@@ -167,26 +167,7 @@ def build_parser(parser):
         parser to configure in order to extract command-line arguments
     """
     import argparse
-    import multiprocessing
-
-    def thread_num(param):
-        try:
-            param = int(param)
-        except Exception:
-            msg = "argument --threads threads: invalid int value: {}".format(param)
-            raise argparse.ArgumentTypeError(msg)
-        nb_cpu = multiprocessing.cpu_count()
-        if param > nb_cpu:
-            msg = ("You have {} threads on your computer, you cannot ask for more: "
-                   "invalid value: {}").format(nb_cpu, param)
-            raise argparse.ArgumentTypeError(msg)
-        elif param < 0:
-            msg = ("Please provide a positive number of threads (or 0 for all threads): "
-                   "Invalid value: {}").format(param)
-            raise argparse.ArgumentTypeError(msg)
-        elif param == 0:
-            return nb_cpu
-        return param
+    from PanACoTA import utils_argparse
 
 
     # Create command-line parser for all options and arguments to give
@@ -210,7 +191,7 @@ def build_parser(parser):
                                 "default, no bootstrap is calculated. For IQtree, it "
                                 "will use ultrafast bootstrap (>=1000)."))
 
-    optional.add_argument("--threads", dest="threads", default=1, type=thread_num,
+    optional.add_argument("--threads", dest="threads", default=1, type=utils_argparse.thread_num,
                           help=("add this option if you want to parallelize on several threads. "
                                 "Indicate on how many threads you want to parallelize. "
                                 "By default, it uses 1 thread. Put 0 if you want to use "
diff --git a/PanACoTA/tree_module/fasttree_func.py b/PanACoTA/tree_module/fasttree_func.py
index e761204cef109f1308c0b264e07fa712958bcdc6..47665301696601e264406dd740785ebdc0d6d73a 100755
--- a/PanACoTA/tree_module/fasttree_func.py
+++ b/PanACoTA/tree_module/fasttree_func.py
@@ -113,7 +113,7 @@ def run_fasttree(alignfile, boot, outdir, model, quiet):
     logfile = os.path.join(outdir, align_name + ".fasttree.log")
     treefile = os.path.join(outdir, align_name + ".fasttree_tree.nwk")
     cmd = f"FastTreeMP -nt {model} -noml -nocat {bootinfo} -log {logfile} {alignfile}"
-    logger.info("Fasttree command: " + cmd)
+    logger.details("Fasttree command: " + cmd)
     if quiet:
         fnull = open(os.devnull, 'w')
     else:
@@ -121,5 +121,4 @@ def run_fasttree(alignfile, boot, outdir, model, quiet):
     stdout = open(treefile, "w")
     error = ("Problem while running Fasttree. See log file ({}) for "
              "more information.").format(logfile)
-    logger.details(cmd)
     utils.run_cmd(cmd, error, stdout=stdout, eof=True, logger=logger, stderr=fnull)
diff --git a/PanACoTA/tree_module/iqtree_func.py b/PanACoTA/tree_module/iqtree_func.py
index 73d4ad8511e7861f381b5de7f473598588a4639d..980f0ab68eb901fad8be86d96640951e2f9df279 100644
--- a/PanACoTA/tree_module/iqtree_func.py
+++ b/PanACoTA/tree_module/iqtree_func.py
@@ -126,12 +126,11 @@ def run_tree(alignfile, boot, outdir, quiet, threads, **kwargs):
         prefix = f"--prefix {treefile}"
     cmd = (f"{soft} -s {alignfile} {threadinfo} -m {model} {mem_info} {bootinfo} {wb_info} "
     	   f"{seqtype} {prefix} -quiet {fast}")
-    logger.info("IQtree command: " + cmd)
+    logger.details("IQtree command: " + cmd)
     if quiet:
         fnull = open(os.devnull, 'w')
     else:
         fnull = None
     error = (f"Problem while running IQtree. See log file ({logfile}) for "
              "more information.")
-    logger.details(cmd)
     utils.run_cmd(cmd, error, eof=True, logger=logger, stderr=fnull)
diff --git a/PanACoTA/utils.py b/PanACoTA/utils.py
index 9828d464b413ea503e7cf1a27daf808c623028ed..11a099d23451a04592daface2e40f68bdbe49b98 100755
--- a/PanACoTA/utils.py
+++ b/PanACoTA/utils.py
@@ -522,6 +522,8 @@ def write_lstinfo(list_file, genomes, outdir):
         for genome, values in sorted(genomes.items(), key=sort_genomes_byname_l90_nbcont):
             gembase, _, to_annote, gsize, nbcont, l90 = [str(x) for x in values]
             outf.write("\t".join([gembase, genome, to_annote, gsize, nbcont, l90]) + "\n")
+    return outlst
+
 
 def sort_genomes_by_name(x):
     """
@@ -943,7 +945,7 @@ def cat(list_files, output, title=None):
         widgets = [title + ': ', progressbar.Bar(marker='â–ˆ', left='', right='', fill=' '),
                    ' ', progressbar.Counter(), f"/{nbfiles}" ' (',
                    progressbar.Percentage(), ") - ", progressbar.Timer()]
-        bar = progressbar.ProgressBar(widgets=widgets, max_value=nbfiles, term_width=100).start()
+        bar = progressbar.ProgressBar(widgets=widgets, max_value=nbfiles, term_width=79).start()
         curnum = 1
     with open(output, "w") as outf:
         for file in list_files:
diff --git a/PanACoTA/utils_argparse.py b/PanACoTA/utils_argparse.py
index f553a571f80c99d7e5ed42793dd165306558f03b..8882571aeb08def7a18131a7f1424d7e90460d11 100644
--- a/PanACoTA/utils_argparse.py
+++ b/PanACoTA/utils_argparse.py
@@ -43,6 +43,7 @@ April 2017
 from PanACoTA import utils
 import argparse
 
+
 def gen_name(param):
     if not utils.check_format(param):
         msg = ("The genome name must contain 4 characters. For example, this name can "
@@ -123,3 +124,28 @@ def mash_dist(param):
         msg = f"error: mash distance must be between 0 and 1: invalid value: '{param}'"
         raise argparse.ArgumentTypeError(msg)
     return param
+
+
+def percentage(param):
+        try:
+            param = float(param)
+        except Exception:
+            msg = "argument -t tol: invalid float value: {}".format(param)
+            raise argparse.ArgumentTypeError(msg)
+        if param < 0 or param > 1:
+            msg = ("The minimum %% of genomes required in a family to be persistent must "
+                   "be in [0, 1]. Invalid value: {}".format(param))
+            raise argparse.ArgumentTypeError(msg)
+        return param
+
+
+def perc_id(param):
+    try:
+        param = float(param)
+    except Exception:
+        msg = "argument -i percentage_id: invalid float value: {}".format(param)
+        raise argparse.ArgumentTypeError(msg)
+    if param < 0 or param > 1:
+        msg = ("The minimum %% of identity must be in [0, 1]. Invalid value: {}".format(param))
+        raise argparse.ArgumentTypeError(msg)
+    return param
diff --git a/README.md b/README.md
index 94b1fc51309cc9ff12761a09eb5845cbfd9cdca4..9afd2f2f6cfb8a71c9a0dd1f0ce59b8699b263ab 100755
--- a/README.md
+++ b/README.md
@@ -164,7 +164,7 @@ Or, if you used singularity, just remove the downloaded image: `rm -r panacota.i
 
 `PanACoTA` contains 6 different subcommands:
 
-- `prepare` (download genomes from refseq if you want to, or give your input database, to run a filtering quality control)
+- `prepare` (download genomes from refseq if you want to, or give your input database, to run a filtering quality control). To help you find NCBI species taxid you need, you can use their [taxonomy browser](https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi).
 - `annotate` (annotate all genomes of the dataset, after a quality control)
 - `pangenome` (generate pan-genome)
 - `corepers` (generate core-genome or persistent-genome)
@@ -185,6 +185,8 @@ When using singularity, just replace `PanACoTA` by `./panacota.img`:
     ./panacota.img <subcommand_name> <arguments_for_subcommand>  
     ./panacota.img -h 
 
+It also provides a subcommand `PanACoTA all` to run all modules in a row.
+
 ## <a name="example"></a> Examples
 
 We provide a folder, `Examples`, containing genomic sequences (in `Examples/genomes`) and examples of input files (in `Examples/input_files`) for the software.
diff --git a/doc/source/develop.rst b/doc/source/develop.rst
index 971a5e575c8f8408004565fe83d5a15172ad66ab..83678eb1352cfa2eae357402fae65b1423326630 100755
--- a/doc/source/develop.rst
+++ b/doc/source/develop.rst
@@ -3,18 +3,13 @@ Work on PanACoTA code
 =====================
 
 This part is for people who want to work on developing `PanACoTA` package: adding new features, correcting bugs etc.
-
 PanACoTA is also hosted in gitlab, where all CI is done. Here is the link: https://gitlab.pasteur.fr/aperrin/pipeline_annotation
 
 
 Installing ``PanACoTA`` in development mode
 ===========================================
 
-If you want to install ``PanACoTA`` while still working on modifying the scripts, type:
-
-.. code-block:: bash
-
-    ./make develop
+If you want to install ``PanACoTA`` while still working on modifying the scripts, use ``./make develop`` instead of ``./make install`` once you have cloned the git repository.
 
 Your changes will then be taken into account. As you installed the package, you will be able to run it from any directory in your computer.
 
@@ -54,7 +49,7 @@ If you want to run only a specific test, run::
 
     py.test test/test_<unit or functional>/<test_file.py>::<test_name>
 
-When you run tests (all of them or individual ones), it will also always generate the coverage report. Open ``htmlcov/index.html`` on your browser if you want to check code coverage of your new function/module. The online version can be found `here <http://aperrin.pages.pasteur.fr/pipeline_annotation/htmlcov/>`_, and is automatically updated at each push on master branch.
+When you run tests (all of them or individual ones), it will also always generate the coverage report. Open ``htmlcov/index.html`` on your browser if you want to check code coverage of your new function/module. The online version can be found `here <http://aperrin.pages.pasteur.fr/pipeline_annotation/htmlcov/>`_, and is automatically updated at each push on master branch of the gitlab repository.
 
 .. warning:: If you add new features, or modify existing scripts please complete/update the tests!
 
diff --git a/doc/source/index.rst b/doc/source/index.rst
index daace7a793f32ceda51c2dde75d791a9478a840d..b987a7b3451644172b4833b4fd4a08da15d73025 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -15,8 +15,8 @@ Amandine PERRIN, Eduardo P.C. ROCHA (2020). PanACoTA: A modular tool for massive
 
    whatis
    starting
-   examples
    usage
+   examples
    about
 
 
diff --git a/doc/source/starting.rst b/doc/source/starting.rst
index 0f2f4b08f6515b9c267cd6fbb9123bb420b7b26e..cc4dc5dc59dd958fbb84d1ba51687f57ee9014d3 100755
--- a/doc/source/starting.rst
+++ b/doc/source/starting.rst
@@ -6,12 +6,15 @@ Starting with PanACoTA
 ``PanACoTA`` is a Python package, developed in Python 3.6.
 
 
-Dependencies
+Installation
 ============
 
+Dependencies
+------------
+
 ``PanACoTA`` is written in **python3**. So, you need python3 (and pip3 for installation) to run it.
 
-There are several external dependencies, and you can install only the ones you need for your study:
+Then, ``PanACoTA`` has several external dependencies. If you use :ref:`Singularity <singularity>` installation (for ex. to run on a cluster), you do not need to install any dependency. Otherwise, install only the one(s) you need, according to the module(s) you want to use:
 
 - For prepare module: `mash <https://mash.readthedocs.io/en/latest/>`_ (to filter genomes)
 - For annotate module: `prokka <https://github.com/tseemann/prokka>`_  and/or `prodigal <https://github.com/hyattpd/Prodigal>`_  (to uniformly annotate your genomes)
@@ -41,83 +44,123 @@ For FastTree, we advise to download C code from `here <http://www.microbesonline
 
 You can then add the output ``FastTreeMP`` to your ``$PATH`` to be able to run it from everywhere.
 
-Installation:
-=============
-
-Downloading and updating
+Installation and update:
 ------------------------
 
+You have different possibilities to install ``PanACoTa``.
+
+.. warning:: If you plan to work on the scripts, choose the development installation (see :doc:`Developer documentation <develop>`).
+
+
+From pip
+********
+
+|pip|
 
-You can get ``PanACoTA`` source code by downloading an archive of a given release (zip, tar.gz), or by cloning its github repository. By cloning the github repository, you will then be able to update the code to new versions very easily and quickly. Here is how to clone the repository:
+.. |pip| image:: https://badge.fury.io/py/PanACoTA.svg
+    :target: https://badge.fury.io/py/PanACoTA
+
+A very simple way to install the last stable version. This will install files in your python site-packages folder.
+
+.. code-block:: bash
+
+    pip install panacota
+
+And to get new version
+
+.. code-block:: bash
+
+    pip install panacota --upgrade
+
+If you have permission issues, you can either use 'sudo' before the previous command lines to install it as root, or add the ``--user`` option to install it locally.
+
+
+From Github repository
+**********************
+
+.. _clone:
+
+This allows you to get the very last version, and be able to test the last enhancements before they are uploaded to the other platforms (pip, conda, singularity...). For that, go to where you want to install it ``(<your_dir>)``, and type:
 
 .. code-block:: bash
 
     git clone https://github.com/gem-pasteur/PanACoTA.git
-ve your github login, and password.
 
-This will create a repository called ``PanACoTA``. Go inside this repository (``cd PanACoTA``) to install the software, as described hereafter.
+This will create a repository called ``PanACoTA``, containing the content of this Github repository. To install PanACoTA, and be able to launch it from anywhere:
+
+.. code-block:: bash
+
+    cd PanACoTA
+    ./make
 
-If a new version of ``PanACoTA`` is released, and you want to use it, type the following command to update the source code:
+
+If you have permission issues, you can either use 'sudo' before the previous command lines to install it as root, or add the ``--user`` option to install it locally.
+
+To upload to new version, go back to your repository:
 
 .. code-block:: bash
 
+    cd <your_dir>/PanACoTA
     git pull
+    ./make upgrade
 
-Then, you will be able to upgrade to the new version (see :ref:`Upgrade section <upgrade>`).
+From singularity image
+**********************
 
+.. _singularity:
 
-.. _installing:
+|singularity|
 
-Installing ``PanACoTA``
---------------------------
+.. |singularity| image:: https://www.singularity-hub.org/static/img/hosted-singularity--hub-%23e32929.svg
+   :target: https://singularity-hub.org/collections/4724
 
-To install ``PanACoTA``, from its directory, type:
+Very useful if you do not have permission rights on the computer, such as, for example, on a cluster. The other advantage is that you do not need to install any dependence (except singularity itself of course). Singularity image includes all of them. You just have to download 1 file, and nothing will be installed anywhere on your computer.
+
+First, download the singularity image:
 
 .. code-block:: bash
 
-    ./make
+    singularity pull --name panacota.img shub://gem-pasteur/PanACoTA[:<version>]
+
+If you want a specific version, like version 1.0, specify ``shub://gem-pasteur/PanACoTA:1.0``.
 
-or
+To get latest version:
 
 .. code-block:: bash
 
-    ./make install
+    singularity pull --name panacota.img shub://gem-pasteur/PanACoTA
 
-You will then be able to use the package from any directory in your computer,
-just as any other software.
+(This is the same as ``singularity pull --name panacota.img shub://gem-pasteur/PanACoTA:latest``)
 
-.. note:: If you have permission issues, you can either use ``sudo`` before the previous command lines to install it as root, or, if you do not have root access (or prefer a local installation), use ``./make --user`` to install it locally.
+It will replace your file ``panacota.img`` by a new one corresponding to the latest version.
 
-.. warning:: If you plan to work on the scripts, choose the development installation (see :doc:`Developer documentation <develop>`).
 
-.. _uninstall:
+From zip version
+****************
 
-Uninstalling ``PanACoTA``
-----------------------------
+For people wanting to download source code of a specific version, we provide releases. You can download last one here:
 
-If you don't want ``PanACoTA`` anymore, uninstall it by typing:
+|zip|
 
-.. code-block:: bash
+.. |zip| image:: https://img.shields.io/github/release/gem-pasteur/PanACoTA.svg
+    :target: https://github.com/gem-pasteur/PanACoTA/releases
 
-    ./make uninstall
 
-.. note:: If you have permission issues, and installed the package as root, use ``sudo`` before the previous command line to uninstall it.
+.. _installing:
 
-.. _upgrade:
+Uninstalling ``PanACoTA``
+-------------------------
 
-Upgrade to new version
-----------------------
+.. _uninstall:
 
-If you want to install a new version of ``PanACoTA``:
+If you don't want ``PanACoTA`` anymore uninstall it by typing:
 
 .. code-block:: bash
 
-    git pull         # update source code to the new version
-    ./make upgrade   # upgrade to the new version
-
-.. note:: If you have permission issues, and installed the package as root, use ``sudo`` before the second command line (``sudo ./make upgrade``) to upgrade. Or, if you installed the package locally, use ``./make upgrade --user`` to upgrade this local version.
+    pip uninstall panacota   # If you installed from pip
+    ./make uninstall         # If you installed from github repository
 
-If you installed it by downloading a zip file, :ref:`Uninstall it <uninstall>`, and install the new version (by cloning gitlab repository, or downloading the new zip file).
+Or, if you used singularity, just remove the downloaded image: ``rm -r panacota.img``.
 
 
 Quick run
@@ -125,7 +168,7 @@ Quick run
 
 ``PanACoTA`` contains 6 different subcommands:
 
-- ``prepare`` (download genomes from refseq if you want to, or give your input database, to run a filtering quality control)
+- ``prepare`` (download assemblies from refseq if you want to, or give your input database, to run a filtering quality control). To help you find NCBI species taxid you need, you can use their `taxonomy browser <https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi>`_
 - ``annotate`` (annotate all genomes of the dataset, after a quality control)
 - ``pangenome`` (generate pan-genome)
 - ``corepers`` (generate core-genome or persistent-genome)
@@ -144,20 +187,11 @@ Each subcommand has its own options and inputs. To get the list of required argu
 
     PanACoTA <subcommand> -h
 
-Running with singularity image
-==============================
-
-We provide a singularity image, to help running PanACoTA on a cluster.
-
-First, download the singularity image::
-
-    singularity pull --name panacota.img shub://gem-pasteur/PanACoTA[:version]
-
-If you want a specific version, like version 1.0, specify ``shub://gem-pasteur/PanACoTA:1.0``. If you want the latest version, use ``shub://gem-pasteur/PanACoTA`` or ``shub://gem-pasteur/PanACoTA:latest``.
-
-Then, you can run PanACoTA in the same way as previously, using:
+When using singularity, just replace ``PanACoTA`` by ``./panacota.img``:
 
 .. code-block:: bash
 
-    ./panacota.img -h  # to get help on the whole PanACoTA program
-    ./panacota.img <subcommand_name> <arguments_for_subcommand>  # to run a module of PanACoTA on your data.
+    ./panacota.img <subcommand_name> <arguments_for_subcommand>
+    ./panacota.img -h
+
+It also provides a subcommand ``PanACoTA all`` to run all modules in a row.
diff --git a/doc/source/usage.rst b/doc/source/usage.rst
index 087b3e0e863a06b14bb09f07203587a58dbdf0d4..5bce06db7639cdf7570b4c6f49aaa0655411fdb7 100755
--- a/doc/source/usage.rst
+++ b/doc/source/usage.rst
@@ -4,14 +4,16 @@ Running PanACoTA - help by module
 
 ``PanACoTA`` contains 6 subcommands, for the different steps:
 
-    - ``prepare`` (download genomes from refseq if you want to, or give your input database, to run a filtering quality control)
+    - ``prepare`` (download genomes from refseq if you want to, or give your input database, to run a filtering quality control). To help you find NCBI species taxid you need, you can use their `taxonomy browser <https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi>`_
     - ``annotate`` (annotate all genomes of the dataset, after a quality control)
     - ``pangenome`` (generate pan-genome)
     - ``corepers`` (generate core-genome or persistent-genome)
     - ``align`` (align core/persistent families)
     - ``tree`` (infer phylogenetic tree from persistent genome)
 
-You can run them by typing::
+We also provide a subommand ``all`` to run all modules in a row.
+
+You can run each subcommand by typing::
 
     PanACoTA <subcommand_name> <arguments_for_subcommand>
 
@@ -19,32 +21,34 @@ Each subcommand has its own options and inputs. To get the list of required argu
 
     PanACoTA <subcommand> -h
 
+General information
+===================
+
+Here are the options shared by all subcommands:
 
-.. note:: In the example command lines, we put ``<>`` around the fields that you have to replace by the information corresponding to what you want. 
+    - ``-h`` or ``--help``: show help on subcommand, as described here above.
+    - ``--quiet``: do not write anything in stdout nor stderr. Log files are still created, so you can check what is running.
+    - ``-v`` or ``--verbose``: be more verbose:
+
+        + ``-v`` will add warnings in stderr (by default, only errors are displayed in stderr, warnings are just in log files),
+        + ``-vv`` will do the same as ``-v``, and also add details to stdout (by default, only info is written to stdout)
+
+.. note:: In the example command lines, we put ``<>`` around the fields that you have to replace by the information corresponding to what you want.
 
 For example, if we write ``command -D <seqfile>`` and the sequence file you want to use is in your current directory and is called ``my_sequence.fa``, then you should write ``command -D my_sequence.fa``.
 
-.. note:: In the example command lines, commands between ``[]`` are optional, meaning that you can run the command line without this part. 
+.. note:: In the example command lines, commands between ``[]`` are optional, meaning that you can run the command line without this part.
 
 Example: your sequence file is the same as previously, and the default parameters are ``-t=10`` and ``-i=0.5``. Therefore, if we write ``command -D <seqfile> [-t <num> -i <percentage>]``. You can run either:
 
-    - ``command -D my_sequence`` (using default parameters for both options: 10 and 0.5) 
-    - ``command -D my_sequence -t 8`` (specifying ``t=8`` option and default ``i=0.5``) 
+    - ``command -D my_sequence`` (using default parameters for both options: 10 and 0.5)
+    - ``command -D my_sequence -t 8`` (specifying ``t=8`` option and default ``i=0.5``)
     - ``command -D my_sequence -i 0.9`` (default ``t=10`` and specified ``i=0.9``)
     - ``command -D my_sequence -t 8 -i 0.9`` (specifying both options: ``t=8`` and ``i=0.9``)
 
 according to your needs (if default values are ok, you do not need to specify the option).
 
 
-Here are the options shared by all subcommands:
-
-    - ``-h`` or ``--help``: show help on subcommand, as described here above.
-    - ``--quiet``: do not write anything on stdout nor stderr. Log files are still created, so you can check what is running.
-    - ``-v`` or ``--verbose``: be more verbose:
-
-        + ``-v`` will add warnings in stderr (by default, only errors are displayed in stderr, warnings are just in log files),
-        + ``-vv`` will do the same as ``-v``, and also add details to stdout (by default, only info is written to stdout)
-
 We will now describe each subcommand, with its options.
 
 
@@ -57,8 +61,8 @@ You can see all required arguments and available options with::
 
 The ``prepare`` module works in 3 steps:
 
-    1) Downloading sequences from refseq
-    2) Quality control to filter genomes in terms of sequence quality
+    1) Downloading assemblies from refseq
+    2) Quality control to filter assemblies in terms of sequence quality
     3) Filtering step dedicated to remove redundant and miss-classified genomes, based on Mash genetic distance.
 
 You can choose to skip steps 1 and 2. Here, we describe how to run this module, starting from step 1, skipping step 1 (starting from step 2), and skipping steps 1 and 2 (starting from step 3).
@@ -66,9 +70,9 @@ You can choose to skip steps 1 and 2. Here, we describe how to run this module,
 Inputs
 ------
 
-Your input will depend on the step from which you are starting. 
+Your input will depend on the step from which you are starting.
 
-- If your start from the beginning, your input is a NCBI taxid and/or a NCBI species.
+- If your start from the beginning, your input is a NCBI taxid and/or a NCBI species. You can also specify which assembly level(s) you want to download
 - If you start from step 2, your input will be a database of fasta sequences, in :ref:`sequences format <seq>`.
 - If you start from step 3, your input will be the database as previously, as well as the LSTINFO output of :ref:`step 2 <step2>`.
 
@@ -78,17 +82,20 @@ Outputs
 
 Genome sequences
 ^^^^^^^^^^^^^^^^
+
+
 All sequences are in fasta format, as described in :ref:`sequences format <seq>`.
 
 In your output directory, you will find:
 
-- Only if you started from step 1: A folder called ``refseq/bacteria``, containing 1 folder per genome (called with the genome accession number), and, inside, the genome sequence in fasta.gz format, and the MD5SUMS of this file.
-- Only if you started from step 1: A folder called ``Database_init``, containing all genomes downloaded in fasta format
+- Only if you started from step 1: A folder called ``refseq/bacteria``, containing 1 folder per assembly (called with the assembly accession number), and, inside, the assembly sequence in fasta.gz format, and the MD5SUMS of this file.
+- Only if you started from step 1: A folder called ``Database_init``, containing all assemblies downloaded from refseq in fasta format
 - Only if you started from step 1 or 2: A folder called ``tmp_files`` containing your genomic sequences, split at each stretch of at least 5 ``N`` (see :ref:`sequences format <seq>` for more details on the splitting part).
 
 
 Discarded files
 ^^^^^^^^^^^^^^^
+
 ``discarded-by-L90_nbcont-<datasetname>.lst``
 
 This file contains the list of genomes discarded by the quality control step:
@@ -104,8 +111,8 @@ Example:
 .. code-block:: text
 
     orig_name                                          to_annotate                                                    gsize   nb_conts    L90
-    <outdir>/Database_init/genome1.fst                 <outdir>/<tmp>/genome1.fst_prepare-split5N.fna                 9808    2           2  
-    <outdir>/Database_init/genome3-chromo.fst-all.fna  <outdir>/<tmp>/genome3-chromo.fst-all.fna_prepare-split5N.fna  8817    3           3   
+    <outdir>/Database_init/genome1.fst                 <outdir>/<tmp>/genome1.fst_prepare-split5N.fna                 9808    2           2
+    <outdir>/Database_init/genome3-chromo.fst-all.fna  <outdir>/<tmp>/genome3-chromo.fst-all.fna_prepare-split5N.fna  8817    3           3
     <outdir>/Database_init/genome2.fst                 <outdir>/<tmp>/genome2.fst_prepare-split5N.fna                 10711   4           4
     <outdir>/Database_init/genome4.fst                 <outdir>/<tmp>/genome4.fst_prepare-split5N.fna                 7134    1           1
 
@@ -114,9 +121,9 @@ Example:
 
 This file contains the list of genomes discarded by the filtering step:
 
-1. path to the genome original sequence
-2. path to the genome which discarded genome 1.
-3. distance between genome 1. and genome 2. (which is not inside the given thresholds)
+- path to the genome original sequence
+- path to the genome which discarded genome 1.
+- distance between genome 1. and genome 2. (which is not inside the given thresholds)
 
 Example:
 
@@ -156,23 +163,37 @@ Running from step 1
 
 To download genomes, and then process them by the `prepare` filters, run::
 
-    PanACoTA prepare [-t <NCBI taxid> -s <NCBI species]
+    PanACoTA prepare [-t <NCBI species taxid> -s <NCBI species> -l <assembly_level(s)>]
+
+Give at least one of ``-t`` or ``-s`` parameters. With:
+
+- ``-t <NCBI taxid>``: the taxid provided by the NCBI for the species you want to study.
+- ``-s <NCBI species>``: the name of the species, as written by the NCBI. Give name between quotes.
+
+If you do not want to download all assemblies in refseq, but only genomes with specific assembly levels, use option ``-l <level(s)>``. Give it a comma separated list of assembly levels you want to download, between 'all', 'complete', 'chromosome', 'scaffold', 'contig' (default is 'all').
+
+For example, if we want to download refseq assemblies of *Acetobacter orleanensis*. With the `taxonomy browser <https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=104099&lvl=3&p=has_linkout&p=blast_url&p=genome_blast&lin=f&keep=1&srchmode=1&unlock>`_, we can find its corresponding NCBI species taxid: "104099".
+To download all assembly levels::
+
+    PanACoTA prepare -t 104099 -s "Acetobacter orleanensis"
+
+Or, to download only complete and scaffold assemblies::
+
+    PanACoTA prepare -s "Acetobacter orleanensis" -l complete,scafflod
 
-Give at least one of those 2 parameters. With:
+Only one of 'species taxid' and 'species name' argument is enough.
 
-- ``-t <NCBI taxid>``: the taxid provided by the NCBI for the species you want to study. For example, taxid for *E. coli* is 562 (see `NCBI taxonomy browser <https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?lvl=0&id=562>`_)
-- ``-s <NCBI species>``: the name of the species, as written by the NCBI. Give name between quotes (for example "escherichia coli")
 
 Running from step 2
 -------------------
 
-If you already have your genomes, run::
+If you already have your assemblies and/or genomes, run::
 
     PanACoTA prepare --norefseq -o <outdir> [-d <db_dir>]
 
 With:
 
-- ``<outdir>``: the directory where you want to save your results (no need to create the directory before, the program will do it). 
+- ``<outdir>``: the directory where you want to save your results (no need to create the directory before, the program will do it).
 - ``<db_dir>``: directory where your database sequences are. By default, it will search to `<outdir>/Database_init`. So, if your sequences are already there, you do not need to add this option.
 
 
@@ -553,21 +574,21 @@ All other information than the genome names in the first columns will be ignored
 protein files
 ^^^^^^^^^^^^^
 
-Each genome in your list_file corresponds to a protein file in ``dbdir``. This protein file is in multi-fasta format, 
-and the headers must follow this format: 
-``<genome-name_without_space_nor_dot>_<numeric_chars>``. 
-For example ``my-genome-1_00056`` or ``my_genome_1_00056`` are valid protein headers. 
+Each genome in your list_file corresponds to a protein file in ``dbdir``. This protein file is in multi-fasta format,
+and the headers must follow this format:
+``<genome-name_without_space_nor_dot>_<numeric_chars>``.
+For example ``my-genome-1_00056`` or ``my_genome_1_00056`` are valid protein headers.
 
 .. warning:: All proteins of a genome must have the same ``<genome-name_without_space_nor_dot>``. Otherwise, they won't be considered in the same genome, which will produce errors in your core or persistent genome!
 
-Ideally, you should follow the 'gembase_format', ``<name>.<date>.<strain_num>.<contig><place>_<num>`` 
-(as it is described in :ref:`LSTINFO folder format <lstf>`, field "name of the sequence annotated"), 
+Ideally, you should follow the 'gembase_format', ``<name>.<date>.<strain_num>.<contig><place>_<num>``
+(as it is described in :ref:`LSTINFO folder format <lstf>`, field "name of the sequence annotated"),
 where the genome name, shared by all proteins of the genome.
 
 If your protein files were generated by ``PanACoTA annotate``, they are already in this format!
 
-Those fields will be used to sort genes inside pangenome families. They are sorted by species ``<genome-name_without_space_nor_dot>`` 
-(if you do a pangenome containing different species), 
+Those fields will be used to sort genes inside pangenome families. They are sorted by species ``<genome-name_without_space_nor_dot>``
+(if you do a pangenome containing different species),
 strain number ``<strain_num>`` (inside a same species), and protein number ``<num>`` (inside a same strain). If you do not use gembase format,
 families will only be sorted by protein number (the ``<numeric_chars>`` part).
 
@@ -596,14 +617,14 @@ This fictive pangenome contains 4 families. Family 1 contains 4 proteins, family
 Qualitative matrix
 ^^^^^^^^^^^^^^^^^^
 
-You will also find a qualitative matrix corresponding to your pangenome. 
-Its columns correspond to the different families, and its lines to the different genomes. 
-In each cell, there is a 1 if the genome has a member in the family, or 0 if not. 
+You will also find a qualitative matrix corresponding to your pangenome.
+Its columns correspond to the different families, and its lines to the different genomes.
+In each cell, there is a 1 if the genome has a member in the family, or 0 if not.
 For example, the qualitative matrix corresponding to the pangenome example just above is:
 
 .. code-block:: text
 
-    fam_num           1     2     3     4    
+    fam_num           1     2     3     4
     ESCO.0217.00001   1     1     0     0
     ESCO.0217.00002   1     0     0     0
     ESCO.1216.00003   1     0     0     0
@@ -618,13 +639,13 @@ This file can be used as an input to do GWAS analysis with `treeWAS <https://git
 Quantitative matrix
 ^^^^^^^^^^^^^^^^^^^
 
-You will also find a quantitative matrix. As for the qualitative matrix, columns correspond to the different families, 
-and lines to the different genomes. But here, each cell contains the number of members from the given genome in the given family. 
+You will also find a quantitative matrix. As for the qualitative matrix, columns correspond to the different families,
+and lines to the different genomes. But here, each cell contains the number of members from the given genome in the given family.
 Here is the quantitative matrix corresponding to the pangenome example above:
 
 .. code-block:: text
 
-    fam_num           1     2     3     4    
+    fam_num           1     2     3     4
     ESCO.0217.00001   1     1     0     0
     ESCO.0217.00002   2     0     0     0
     ESCO.1216.00003   1     0     0     0
@@ -676,8 +697,8 @@ with:
     - ``-i <min_id>``: minimum percentage of identity required to put 2 proteins in the same family. When doing a pangenome at the species level, we commonly use a threshold of 80% of identity.
 
 
-This will create (if not already existing) your ``outdir``, and, after execution, this directory will contain your pangenome file, 
-as well as other useful files. If you did not specify a pangenome filename (``-f`` option), the default pangenome name will be 
+This will create (if not already existing) your ``outdir``, and, after execution, this directory will contain your pangenome file,
+as well as other useful files. If you did not specify a pangenome filename (``-f`` option), the default pangenome name will be
 ``Pangenome-<dataset_name>.All.prt-clust-<min_id>-mode<mode_num_given>_<current_date_and_time>.tsv.lst``:
 
     - ``<pangenome_file or default>``: your pangenome file, which format is described :ref:`here above<panfile>`
@@ -956,7 +977,7 @@ Corresponding to this phylogenetic tree:
 Do tree
 -------
 
-By default, 'tree' subcommand will use `IQtree <http://www.iqtree.org/>`_ software to infer the phylogenetic tree. 
+By default, 'tree' subcommand will use `IQtree <http://www.iqtree.org/>`_ software to infer the phylogenetic tree.
 To infer the tree from your alignment file, run:
 
 .. code-block:: bash
diff --git a/test/test_functional/test_align.py b/test/test_functional/test_align.py
index cd9eb9bbe40bc7b8b425b474e623b86aa8bf5d5e..7af9683820b8926d08c46a0fb381a4341ff961a2 100755
--- a/test/test_functional/test_align.py
+++ b/test/test_functional/test_align.py
@@ -43,172 +43,172 @@ def setup_teardown_module():
     print("teardown")
 
 
-# def test_main():
-#     """
-#     Test that when giving a database, a persistent genome and a list of genomes, it extracts
-#     expected proteins by family, aligns each family, back-translates them, concatenates all
-#     families into one file and groups them by genome.
-#     """
-#     corepers = os.path.join(TESTPATH, "test_pers0.99FX.lst")
-#     list_genomes = os.path.join("test", "data", "pangenome", "test_files", "list_to_pan.txt")
-#     dname = "TEST4"
-#     dbpath = os.path.join("test", "data", "pangenome", "test_files", "example_db")
-#     outdir = GENEPATH
-#     threads = 1
-#     force = False
-#     cmd = "cmd"
-#     al.main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force)
-#     # Check creation of the 3 subdirectories
-#     aldir = os.path.join(outdir, "Align-" + dname)
-#     listdir = os.path.join(outdir, "List-" + dname)
-#     treedir = os.path.join(outdir, "Phylo-" + dname)
-#     assert os.path.isdir(aldir)
-#     assert os.path.isdir(listdir)
-#     assert os.path.isdir(treedir)
-#     # Check content of listdir
-#     genomes = ["GEN2.1017.00001", "GEN4.1111.00001", "GENO.1017.00001", "GENO.1216.00002"]
-#     for gen in genomes:
-#         assert os.path.isfile(os.path.join(listdir, f"{dname}-getEntry_gen_{gen}.txt"))
-#         assert os.path.isfile(os.path.join(listdir, f"{dname}-getEntry_prt_{gen}.txt"))
-#     # Check content of aldir
-#     fams = [1, 4, 6, 8, 10, 11, 13, 14]
-#     for fam in fams:
-#         assert os.path.isfile(os.path.join(aldir, f'{dname}-current.{fam}.gen'))
-#         assert os.path.isfile(os.path.join(aldir, f'{dname}-current.{fam}.prt'))
-#         assert os.path.isfile(os.path.join(aldir, f'{dname}-current.{fam}.miss.lst'))
-#         assert os.path.isfile(os.path.join(aldir, f'{dname}-mafft-align.{fam}.aln'))
-#         assert os.path.isfile(os.path.join(aldir, f'{dname}-mafft-prt2nuc.{fam}.aln'))
-#     out_concat = os.path.join(aldir, dname + "-complete.cat.aln")
-#     exp_concat = os.path.join(EXPPATH, "exp_pers4genome-complete.cat.aln")
-#     assert tutil.compare_order_content(out_concat, exp_concat)
-#     # Check content of treedir
-#     out_grp = os.path.join(treedir, dname + ".grp.aln")
-#     exp_grp = os.path.join(EXPPATH, "exp_pers4genomes.grp.aln")
-#     assert tutil.compare_order_content(out_grp, exp_grp)
-#     # Check presence of log files, and log.err is empty
-#     base_log = os.path.join(outdir, "PanACoTA-align_" + dname + ".log")
-#     assert os.path.isfile(base_log)
-#     assert os.path.isfile(base_log + ".details")
-#     assert os.path.isfile(base_log + ".err")
-#     with open(base_log + ".err", "r") as bf:
-#         assert bf.readlines() == []
-#     # Check logs
-#     with open(base_log + ".details", "r") as lc:
-#         log_content = lc.readlines()
-#     assert ("Reading PersGenome and constructing lists of missing genomes in "
-#             "each family") in " ".join(log_content)
-#     assert "Extracting proteins and genes from all genomes" in " ".join(log_content)
-#     for gen in genomes:
-#         assert "Extracting proteins and genes from {}".format(gen) in " ".join(log_content)
-#     assert ("Starting alignment of all families: protein alignment, back-translation to "
-#             "nucleotides, and add missing genomes in the family") in " ".join(log_content)
-#     for fam in fams:
-#         assert "Checking extractions for family {}".format(fam) in " ".join(log_content)
-#         assert "Aligning family {}".format(fam) in " ".join(log_content)
-#         assert "Back-translating family {}".format(fam) in " ".join(log_content)
-#     assert "Concatenating all alignment files" in " ".join(log_content)
-#     assert "Grouping alignments per genome" in " ".join(log_content)
-#     assert "END" in " ".join(log_content)
+def test_main():
+    """
+    Test that when giving a database, a persistent genome and a list of genomes, it extracts
+    expected proteins by family, aligns each family, back-translates them, concatenates all
+    families into one file and groups them by genome.
+    """
+    corepers = os.path.join(TESTPATH, "test_pers0.99FX.lst")
+    list_genomes = os.path.join("test", "data", "pangenome", "test_files", "list_to_pan.txt")
+    dname = "TEST4"
+    dbpath = os.path.join("test", "data", "pangenome", "test_files", "example_db")
+    outdir = GENEPATH
+    threads = 1
+    force = False
+    cmd = "cmd"
+    al.main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force)
+    # Check creation of the 3 subdirectories
+    aldir = os.path.join(outdir, "Align-" + dname)
+    listdir = os.path.join(outdir, "List-" + dname)
+    treedir = os.path.join(outdir, "Phylo-" + dname)
+    assert os.path.isdir(aldir)
+    assert os.path.isdir(listdir)
+    assert os.path.isdir(treedir)
+    # Check content of listdir
+    genomes = ["GEN2.1017.00001", "GEN4.1111.00001", "GENO.1017.00001", "GENO.1216.00002"]
+    for gen in genomes:
+        assert os.path.isfile(os.path.join(listdir, f"{dname}-getEntry_gen_{gen}.txt"))
+        assert os.path.isfile(os.path.join(listdir, f"{dname}-getEntry_prt_{gen}.txt"))
+    # Check content of aldir
+    fams = [1, 4, 6, 8, 10, 11, 13, 14]
+    for fam in fams:
+        assert os.path.isfile(os.path.join(aldir, f'{dname}-current.{fam}.gen'))
+        assert os.path.isfile(os.path.join(aldir, f'{dname}-current.{fam}.prt'))
+        assert os.path.isfile(os.path.join(aldir, f'{dname}-current.{fam}.miss.lst'))
+        assert os.path.isfile(os.path.join(aldir, f'{dname}-mafft-align.{fam}.aln'))
+        assert os.path.isfile(os.path.join(aldir, f'{dname}-mafft-prt2nuc.{fam}.aln'))
+    out_concat = os.path.join(aldir, dname + "-complete.cat.aln")
+    exp_concat = os.path.join(EXPPATH, "exp_pers4genome-complete.cat.aln")
+    assert tutil.compare_order_content(out_concat, exp_concat)
+    # Check content of treedir
+    out_grp = os.path.join(treedir, dname + ".grp.aln")
+    exp_grp = os.path.join(EXPPATH, "exp_pers4genomes.grp.aln")
+    assert tutil.compare_order_content(out_grp, exp_grp)
+    # Check presence of log files, and log.err is empty
+    base_log = os.path.join(outdir, "PanACoTA-align_" + dname + ".log")
+    assert os.path.isfile(base_log)
+    assert os.path.isfile(base_log + ".details")
+    assert os.path.isfile(base_log + ".err")
+    with open(base_log + ".err", "r") as bf:
+        assert bf.readlines() == []
+    # Check logs
+    with open(base_log + ".details", "r") as lc:
+        log_content = lc.readlines()
+    assert ("Reading PersGenome and constructing lists of missing genomes in "
+            "each family") in " ".join(log_content)
+    assert "Extracting proteins and genes from all genomes" in " ".join(log_content)
+    for gen in genomes:
+        assert "Extracting proteins and genes from {}".format(gen) in " ".join(log_content)
+    assert ("Starting alignment of all families: protein alignment, back-translation to "
+            "nucleotides, and add missing genomes in the family") in " ".join(log_content)
+    for fam in fams:
+        assert "Checking extractions for family {}".format(fam) in " ".join(log_content)
+        assert "Aligning family {}".format(fam) in " ".join(log_content)
+        assert "Back-translating family {}".format(fam) in " ".join(log_content)
+    assert "Concatenating all alignment files" in " ".join(log_content)
+    assert "Grouping alignments per genome" in " ".join(log_content)
+    assert "END" in " ".join(log_content)
 
 
-# def test_main_exist_ok():
-#     """
-#     Test main all files exist and are ok, no force -> end without error, with warnings on re-use
-#     """
-#     corepers = os.path.join(TESTPATH, "test_pers0.99FX.lst")
-#     list_genomes = os.path.join("test", "data", "pangenome", "test_files", "list_to_pan.txt")
-#     dname = "TEST4exists"
-#     dbpath = os.path.join("test", "data", "pangenome", "test_files", "example_db")
-#     outdir = os.path.join(GENEPATH, "test_main_exist_ok")
-#     threads = 1
-#     force = False
-#     cmd = "cmd test_main_exist_ok"
-#     # Create output directories and files
-#     aldir = os.path.join(outdir, "Align-" + dname)
-#     listdir = os.path.join(outdir, "List-" + dname)
-#     treedir = os.path.join(outdir, "Phylo-" + dname)
-#     os.makedirs(aldir)
-#     os.makedirs(listdir)
-#     os.makedirs(treedir)
-#     # Create content of listdir
-#     ex_listdir = os.path.join(EXPPATH, "exp_listdir-pers")
-#     genomes = ["GEN2.1017.00001", "GEN4.1111.00001", "GENO.1017.00001", "GENO.1216.00002"]
-#     for gen in genomes:
-#         outgen = os.path.join(listdir, f"{dname}-getEntry_gen_{gen}.txt")
-#         refgen = os.path.join(ex_listdir, f"getEntry_gen_{gen}")
-#         shutil.copyfile(refgen, outgen)
-#         outprt = os.path.join(listdir, f"{dname}-getEntry_prt_{gen}.txt")
-#         refprt = os.path.join(ex_listdir, f"getEntry_prt_{gen}")
-#         shutil.copyfile(refprt, outprt)
-#     # Create content of aldir
-#     ex_aldir = os.path.join(EXPPATH, "exp_aldir-pers")
-#     fams = [1, 4, 6, 8, 10, 11, 13, 14]
-#     for fam in fams:
-#         outgen = os.path.join(aldir, f'{dname}-current.{fam}.gen')
-#         refgen = os.path.join(ex_aldir, f"current.{fam}.gen")
-#         shutil.copyfile(refgen, outgen)
-#         outprt = os.path.join(aldir, f'{dname}-current.{fam}.prt')
-#         refprt = os.path.join(ex_aldir, f"current.{fam}.prt")
-#         shutil.copyfile(refprt, outprt)
-#         outmiss = os.path.join(aldir, f'{dname}-current.{fam}.miss.lst')
-#         refmiss = os.path.join(ex_aldir, f"current.{fam}.miss.lst")
-#         shutil.copyfile(refmiss, outmiss)
-#         outaln = os.path.join(aldir, f'{dname}-mafft-align.{fam}.aln')
-#         refaln = os.path.join(ex_aldir, f"mafft-align.{fam}.aln")
-#         shutil.copyfile(refaln, outaln)
-#         outbtr = os.path.join(aldir, f'{dname}-mafft-prt2nuc.{fam}.aln')
-#         refbtr = os.path.join(ex_aldir, f"mafft-prt2nuc.{fam}.aln")
-#         shutil.copyfile(refbtr, outbtr)
-#     outcat = os.path.join(aldir, dname + "-complete.cat.aln")
-#     refcat = os.path.join(EXPPATH, "exp_pers4genome-complete.cat.aln")
-#     shutil.copyfile(refcat, outcat)
-#     # Create content of treedir
-#     outgrp = os.path.join(treedir, dname + ".grp.aln")
-#     refgrp = os.path.join(EXPPATH, "exp_pers4genomes.grp.aln")
-#     shutil.copyfile(refgrp, outgrp)
-#     # Run align module
-#     al.main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force)
-#     # Check logs
-#     logfile = os.path.join(outdir, "PanACoTA-align_TEST4exists.log.details")
-#     with open(logfile, "r") as lc:
-#         log_content = lc.readlines()
-#     assert ("Reading PersGenome and constructing lists of missing genomes in "
-#             "each family") in " ".join(log_content)
-#     for gen in genomes:
-#         assert (f"For genome {gen}, test/data/align/generated_by_func_tests/test_main_exist_ok/"
-#                 f"List-TEST4exists/TEST4exists-getEntry_prt_{gen}.txt and test/data/align/"
-#                 "generated_by_func_tests/test_main_exist_ok/List-TEST4exists/"
-#                 f"TEST4exists-getEntry_gen_{gen}.txt already exist. The program "
-#                 "will use them to extract proteins and genes. If you prefer to rewrite "
-#                 "them, use option -F ") in " ".join(log_content)
-#     assert ("Starting alignment of all families: protein alignment, back-translation to "
-#             "nucleotides, and add missing genomes in the family") in " ".join(log_content)
-#     for fam in fams:
-#         assert "Checking extractions for family {}".format(fam) in " ".join(log_content)
-#         assert ("Alignment already done for family {}. The program will use it for next "
-#                 "steps").format(fam) in " ".join(log_content)
-#     assert ("All extraction files already existing (see detailed log for more "
-#             "information)") in " ".join(log_content)
-#     assert ("All prt and gene files for all families already exist. The program will use them "
-#             "for the next step. If you want to re-extract a given family, remove its prt and "
-#             "gen extraction files. If you want to re-extract all families, use option -F "
-#             "(or --force).") in " ".join(log_content)
-#     assert ("Alignments already concatenated in "
-#             "test/data/align/generated_by_func_tests/test_main_exist_ok/Align-TEST4exists/"
-#             "TEST4exists-complete.cat.aln. Program will "
-#             "use it for next steps. If you want to redo it, remove it before "
-#             "running.") in " ".join(log_content)
-#     assert ("Alignments already grouped by genome in "
-#             "test/data/align/generated_by_func_tests/test_main_exist_ok/Phylo-TEST4exists/"
-#             "TEST4exists.grp.aln. Program will "
-#             "end.") in " ".join(log_content)
-#     assert "END" in " ".join(log_content)
+def test_main_exist_ok():
+    """
+    Test main all files exist and are ok, no force -> end without error, with warnings on re-use
+    """
+    corepers = os.path.join(TESTPATH, "test_pers0.99FX.lst")
+    list_genomes = os.path.join("test", "data", "pangenome", "test_files", "list_to_pan.txt")
+    dname = "TEST4exists"
+    dbpath = os.path.join("test", "data", "pangenome", "test_files", "example_db")
+    outdir = os.path.join(GENEPATH, "test_main_exist_ok")
+    threads = 1
+    force = False
+    cmd = "cmd test_main_exist_ok"
+    # Create output directories and files
+    aldir = os.path.join(outdir, "Align-" + dname)
+    listdir = os.path.join(outdir, "List-" + dname)
+    treedir = os.path.join(outdir, "Phylo-" + dname)
+    os.makedirs(aldir)
+    os.makedirs(listdir)
+    os.makedirs(treedir)
+    # Create content of listdir
+    ex_listdir = os.path.join(EXPPATH, "exp_listdir-pers")
+    genomes = ["GEN2.1017.00001", "GEN4.1111.00001", "GENO.1017.00001", "GENO.1216.00002"]
+    for gen in genomes:
+        outgen = os.path.join(listdir, f"{dname}-getEntry_gen_{gen}.txt")
+        refgen = os.path.join(ex_listdir, f"getEntry_gen_{gen}")
+        shutil.copyfile(refgen, outgen)
+        outprt = os.path.join(listdir, f"{dname}-getEntry_prt_{gen}.txt")
+        refprt = os.path.join(ex_listdir, f"getEntry_prt_{gen}")
+        shutil.copyfile(refprt, outprt)
+    # Create content of aldir
+    ex_aldir = os.path.join(EXPPATH, "exp_aldir-pers")
+    fams = [1, 4, 6, 8, 10, 11, 13, 14]
+    for fam in fams:
+        outgen = os.path.join(aldir, f'{dname}-current.{fam}.gen')
+        refgen = os.path.join(ex_aldir, f"current.{fam}.gen")
+        shutil.copyfile(refgen, outgen)
+        outprt = os.path.join(aldir, f'{dname}-current.{fam}.prt')
+        refprt = os.path.join(ex_aldir, f"current.{fam}.prt")
+        shutil.copyfile(refprt, outprt)
+        outmiss = os.path.join(aldir, f'{dname}-current.{fam}.miss.lst')
+        refmiss = os.path.join(ex_aldir, f"current.{fam}.miss.lst")
+        shutil.copyfile(refmiss, outmiss)
+        outaln = os.path.join(aldir, f'{dname}-mafft-align.{fam}.aln')
+        refaln = os.path.join(ex_aldir, f"mafft-align.{fam}.aln")
+        shutil.copyfile(refaln, outaln)
+        outbtr = os.path.join(aldir, f'{dname}-mafft-prt2nuc.{fam}.aln')
+        refbtr = os.path.join(ex_aldir, f"mafft-prt2nuc.{fam}.aln")
+        shutil.copyfile(refbtr, outbtr)
+    outcat = os.path.join(aldir, dname + "-complete.cat.aln")
+    refcat = os.path.join(EXPPATH, "exp_pers4genome-complete.cat.aln")
+    shutil.copyfile(refcat, outcat)
+    # Create content of treedir
+    outgrp = os.path.join(treedir, dname + ".grp.aln")
+    refgrp = os.path.join(EXPPATH, "exp_pers4genomes.grp.aln")
+    shutil.copyfile(refgrp, outgrp)
+    # Run align module
+    al.main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force)
+    # Check logs
+    logfile = os.path.join(outdir, "PanACoTA-align_TEST4exists.log.details")
+    with open(logfile, "r") as lc:
+        log_content = lc.readlines()
+    assert ("Reading PersGenome and constructing lists of missing genomes in "
+            "each family") in " ".join(log_content)
+    for gen in genomes:
+        assert (f"For genome {gen}, test/data/align/generated_by_func_tests/test_main_exist_ok/"
+                f"List-TEST4exists/TEST4exists-getEntry_prt_{gen}.txt and test/data/align/"
+                "generated_by_func_tests/test_main_exist_ok/List-TEST4exists/"
+                f"TEST4exists-getEntry_gen_{gen}.txt already exist. The program "
+                "will use them to extract proteins and genes. If you prefer to rewrite "
+                "them, use option -F ") in " ".join(log_content)
+    assert ("Starting alignment of all families: protein alignment, back-translation to "
+            "nucleotides, and add missing genomes in the family") in " ".join(log_content)
+    for fam in fams:
+        assert "Checking extractions for family {}".format(fam) in " ".join(log_content)
+        assert ("Alignment already done for family {}. The program will use it for next "
+                "steps").format(fam) in " ".join(log_content)
+    assert ("All extraction files already existing (see detailed log for more "
+            "information)") in " ".join(log_content)
+    assert ("All prt and gene files for all families already exist. The program will use them "
+            "for the next step. If you want to re-extract a given family, remove its prt and "
+            "gen extraction files. If you want to re-extract all families, use option -F "
+            "(or --force).") in " ".join(log_content)
+    assert ("Alignments already concatenated in "
+            "test/data/align/generated_by_func_tests/test_main_exist_ok/Align-TEST4exists/"
+            "TEST4exists-complete.cat.aln. Program will "
+            "use it for next steps. If you want to redo it, remove it before "
+            "running.") in " ".join(log_content)
+    assert ("Alignments already grouped by genome in "
+            "test/data/align/generated_by_func_tests/test_main_exist_ok/Phylo-TEST4exists/"
+            "TEST4exists.grp.aln. Program will "
+            "end.") in " ".join(log_content)
+    assert "END" in " ".join(log_content)
 
 
 def test_main_exist_emptygrp(capsys):
     """
     test main all files exist but empty grp -> does nothing, grp is not checked if everything
-    before was ok
+    before was ok. grp must still be empty
     """
     corepers = os.path.join(TESTPATH, "test_pers0.99FX.lst")
     list_genomes = os.path.join("test", "data", "pangenome", "test_files", "list_to_pan.txt")
@@ -262,6 +262,8 @@ def test_main_exist_emptygrp(capsys):
     open(outgrp, "w").close()
     # Run align module
     al.main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force, verbose=2)
+    # Check grp still empty
+    assert os.stat(outgrp).st_size == 0
     # Check logs
     out, err = capsys.readouterr()
     logfile = os.path.join(outdir, "PanACoTA-align_TEST4empty-grp.log.details")
@@ -355,6 +357,11 @@ def test_main_exist_emptycat(capsys):
         outf.write("It's me !!")
     # Run align module
     al.main(cmd, corepers, list_genomes, dname, dbpath, outdir, threads, force, verbose=16)
+    # Check concat and grp did not change
+    with open(outcat, "r") as of:
+        assert of.readlines() == ["Hello !!"]
+    with open(outgrp, "r") as of:
+        assert of.readlines() == ["It's me !!"]
     # Check logs
     out, err = capsys.readouterr()
     logfile = os.path.join(outdir, "PanACoTA-align_TEST4empty-cat.log.details")
diff --git a/test/test_functional/test_annote.py b/test/test_functional/test_annote.py
index e4c3ca1c21d6124c2010968289cc6f30d02ca45c..40547be15f40ed35977c7100f1bb658c12cb05d1 100755
--- a/test/test_functional/test_annote.py
+++ b/test/test_functional/test_annote.py
@@ -126,8 +126,9 @@ def test_main_given_tmp_verbose3(capsys):
     l90 = 10
     date = "0417"
     verbose = 3
-    annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, l90,
-               cutn=3, tmp_dir=tmpdir, verbose=verbose)
+    info_file = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-default.lst")
+    assert annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, l90,
+                      cutn=3, tmp_dir=tmpdir, verbose=verbose) == (info_file, 3)
     out, err = capsys.readouterr()
     # Check that warnings are written to stderr
     assert "WARNING" in err
@@ -164,7 +165,8 @@ def test_main_all_discard_nbcont(capsys):
     nbcont = 0
     cutn = 0
     date = "0417"
-    annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, nbcont=nbcont, cutn=cutn)
+    assert annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, nbcont=nbcont,
+                      cutn=cutn) == ("", 0)
     # check that there are the 2 concatenated genomes in tmppath.
     # The third genome is listfile is composed of only 1 file, so no need to concatenate, nor
     # to change the file as we do not use cutn
@@ -189,8 +191,8 @@ def test_main_qc():
     date = "0417"
     force = False
     qc_only = True
-    annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, l90=l90,
-                            cutn=cutn, qc_only=qc_only)
+    assert annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, l90=l90,
+                      cutn=cutn, qc_only=qc_only) == ("", 0)
     # Check files are here
     lstfile = os.path.join(GENEPATH, "ALL-GENOMES-info-list_genomes-func-test-default.lst")
     exp_lstfile = os.path.join(EXP_DIR, "exp_ALL-GENOMES-QC.lst")
@@ -223,13 +225,14 @@ def test_main_existresdirforce(capsys):
     date = "0417"
     l90 = 5
     cutn = 3
-    annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, force=True, l90=l90,
-               prodigal_only=True, cutn = cutn, small=True)
+    info_file = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-default.lst")
+    assert annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, force=True, l90=l90,
+                      prodigal_only=True, cutn = cutn, small=True) == (info_file, 4)
     out, err = capsys.readouterr()
 
     # Check that tmp files exist in the right folder
     # -> 2 fna files created (concatenations)
-    # -> + 3 files created (split 5N)
+    # -> + 4 files created (split 3N)
     assert os.path.isfile(os.path.join(GENEPATH, "tmp_files", "A_H738.fasta-all.fna"))
     assert os.path.isfile(os.path.join(GENEPATH, "tmp_files", "H299_H561.fasta-all.fna"))
     assert len(glob.glob(os.path.join(GENEPATH, "tmp_files", '*.fna'))) == 6
@@ -296,14 +299,14 @@ def test_main_onexistingprokkadir(capsys):
     list_file = os.path.join(TEST_DIR, "list_genomes-func-test-exist_dir.txt")
     name = "ESCO"
     date = "0417"
-    annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, cutn=0, res_annot_dir=EXP_DIR,
-               verbose=3)
+    lstout = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-exist_dir.lst")
+    lstexp = os.path.join(EXP_DIR, "exp_LSTINFO-func-annot_exists-prokkadir.lst")
+    assert annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, cutn=0,
+                      res_annot_dir=EXP_DIR, verbose=3) == (lstout, 2)
     out, err = capsys.readouterr()
     # Check that tmp files folder is empty (prokka res are somewhere else)
     assert len(os.listdir(os.path.join(GENEPATH, "tmp_files"))) == 0
     # Test that result files are in result dir
-    lstout = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-exist_dir.lst")
-    lstexp = os.path.join(EXP_DIR, "exp_LSTINFO-func-annot_exists-prokkadir.lst")
     assert os.path.isfile(lstout)
     assert tutil.compare_order_content(lstout, lstexp)
     logfile = os.path.join(GENEPATH,
@@ -335,14 +338,14 @@ def test_main_onexistingprodigaldir(capsys):
     list_file = os.path.join(TEST_DIR, "list_genomes-func-test-exist_dir.txt")
     name = "ESCO"
     date = "0417"
-    annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, cutn=0, res_annot_dir=EXP_DIR,
-               verbose=3, prodigal_only=True)
+    lstout = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-exist_dir.lst")
+    lstexp = os.path.join(EXP_DIR, "exp_LSTINFO-func-annot_exists-prokkadir.lst")
+    assert annot.main("cmd", list_file, GEN_PATH, GENEPATH, name, date, cutn=0,
+                      res_annot_dir=EXP_DIR, verbose=3, prodigal_only=True) == (lstout, 2)
     out, err = capsys.readouterr()
     # Check that tmp files folder is empty (prokka res are somewhere else)
     assert len(os.listdir(os.path.join(GENEPATH, "tmp_files"))) == 0
     # Test that result files are in result dir
-    lstout = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-exist_dir.lst")
-    lstexp = os.path.join(EXP_DIR, "exp_LSTINFO-func-annot_exists-prokkadir.lst")
     assert os.path.isfile(lstout)
     assert tutil.compare_order_content(lstout, lstexp)
     logfile = os.path.join(GENEPATH,
@@ -390,8 +393,9 @@ def test_main_existing_prokkadir_errorannot():
     # # Run annotation
     name = "ESCO"
     date = "0417"
-    annot.main("cmd", list_file, genome_path_used, GENEPATH, name, date, cutn=0,
-               res_annot_dir=genome_path_used)
+    info_file = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-exist_dir.lst")
+    assert annot.main("cmd", list_file, genome_path_used, GENEPATH, name, date, cutn=0,
+                      res_annot_dir=genome_path_used) == (info_file, 1)
 
     # Check that only 1 genome was formated (the other one had problems with prokka)
     prot_dir = os.path.join(GENEPATH, "Proteins")
@@ -515,8 +519,9 @@ def test_main_existing_prokkadir_errorformat():
     # Run annotation
     name = "ESCO"
     date = "0417"
-    annot.main("cmd", list_file, genome_path_used, GENEPATH, name, date, cutn=0,
-               res_annot_dir=genome_path_used)
+    info_file = os.path.join(GENEPATH, "LSTINFO-list_genomes-func-test-exist_dir.lst")
+    assert annot.main("cmd", list_file, genome_path_used, GENEPATH, name, date, cutn=0,
+               res_annot_dir=genome_path_used) == (info_file, 1)
 
     # Check that genome 1 is not formatted, while no error with prokka
     logfile = os.path.join(GENEPATH,
@@ -547,8 +552,9 @@ def test_main_frominfo(capsys):
     name = "TOTO"
     date = "1205"
     infofile = os.path.join(TEST_DIR, "lstinfo.lst")
-    annot.main("cmd", listfile, dbpath, GENEPATH, name, date, from_info=infofile,
-               prodigal_only=True, small=True)
+    out_infofile = os.path.join(GENEPATH, "LSTINFO-lstinfo.lst")
+    assert annot.main("cmd", listfile, dbpath, GENEPATH, name, date, from_info=infofile,
+                      prodigal_only=True, small=True) == (out_infofile, 3)
     out, err = capsys.readouterr()
     # Check logs
     assert ("Generating distribution of L90 and #contigs graphs.") in out
diff --git a/test/test_functional/test_corepers.py b/test/test_functional/test_corepers.py
index 9d07b7999f5b76afe15585021d3f08d875b11567..6cb5b858bab57f5b790b0cfcb4cc117affd62f05 100755
--- a/test/test_functional/test_corepers.py
+++ b/test/test_functional/test_corepers.py
@@ -52,11 +52,11 @@ def test_main_default(capsys):
     multi = False
     mixed = False
     cmd = "cmd"
-    corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH)
+    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_1.lst")
+    assert corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH) == out_pers
     # Check creation of binary file for pangenome, and remove it
     assert os.path.isfile(UPAN + ".bin")
     # Check presence of persistent genome, and its content, and remove it
-    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_1.lst")
     exp_pers = os.path.join(EXP_PATH, "exp_coregenome.txt")
     assert os.path.isfile(out_pers)
     assert tutil.compare_order_content(out_pers, exp_pers)
@@ -81,11 +81,11 @@ def test_main_pers(capsys):
     multi = False
     mixed = False
     cmd = "cmd"
-    corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH)
+    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_0.99.lst")
+    assert corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH) == out_pers
     # Check creation of binary file for pangenome, and remove it
     assert os.path.isfile(UPAN + ".bin")
     # Check presence of persistent genome, and its content, and remove it
-    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_0.99.lst")
     exp_pers = os.path.join(EXP_PATH, "exp_coregenome.txt")
     assert os.path.isfile(out_pers)
     assert tutil.compare_order_content(out_pers, exp_pers)
@@ -117,11 +117,12 @@ def test_main_pers_floor_verbose2(capsys):
     floor = True
     cmd = "cmd"
     floor = True
-    corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH, floor=floor, verbose=2)
+    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_F0.99.lst")
+    assert corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH,
+                         floor=floor, verbose=2) == out_pers
     # Check creation of binary file for pangenome, and remove it
     assert os.path.isfile(UPAN + ".bin")
     # Check presence of persistent genome, and its content, and remove it
-    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_F0.99.lst")
     exp_pers = os.path.join(EXP_PATH, "exp_pers-floor-strict.txt")
     assert os.path.isfile(out_pers)
     assert tutil.compare_order_content(out_pers, exp_pers)
@@ -153,11 +154,12 @@ def test_main_pers_floor_mixed_debug(capsys):
     mixed = True
     floor = True
     cmd = "cmd"
-    corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH, floor=floor, verbose = 15)
+    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_F0.99-mixed.lst")
+    assert corepers.main(cmd, UPAN, tol, multi, mixed, GENEPATH,
+                         floor=floor, verbose = 15) == out_pers
     # Check creation of binary file for pangenome, and remove it
     assert os.path.isfile(UPAN + ".bin")
     # Check presence of persistent genome, and its content, and remove it
-    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_F0.99-mixed.lst")
     exp_pers = os.path.join(EXP_PATH, "exp_pers-floor-mixed.txt")
     assert os.path.isfile(out_pers)
     assert tutil.compare_order_content(out_pers, exp_pers)
@@ -191,11 +193,11 @@ def test_main_pers_floor_multi(capsys):
     floor = True
     cmd = "cmd"
     outdir = os.path.join(GENEPATH, "outdir")
-    corepers.main(cmd, UPAN, tol, multi, mixed, outdir, floor=floor)
+    out_pers = os.path.join(outdir, "PersGenome_pangenome.lst_F0.99-multi.lst")
+    assert corepers.main(cmd, UPAN, tol, multi, mixed, outdir, floor=floor) == out_pers
     # Check creation of binary file for pangenome, and remove it
     assert os.path.isfile(UPAN + ".bin")
     # Check presence of persistent genome, and its content, and remove it
-    out_pers = os.path.join(outdir, "PersGenome_pangenome.lst_F0.99-multi.lst")
     exp_pers = os.path.join(EXP_PATH, "exp_pers-floor-multi.txt")
     assert os.path.isfile(out_pers)
     assert tutil.compare_order_content(out_pers, exp_pers)
@@ -237,9 +239,9 @@ def test_main_from_parse(capsys):
     corepers.main_from_parse(args)
 
     # Check creation of binary file for pangenome, and remove it
+    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_1.lst")
     assert os.path.isfile(UPAN + ".bin")
     # Check presence of persistent genome, and its content, and remove it
-    out_pers = os.path.join(GENEPATH, "PersGenome_pangenome.lst_1.lst")
     exp_pers = os.path.join(EXP_PATH, "exp_coregenome.txt")
     assert os.path.isfile(out_pers)
     assert tutil.compare_order_content(out_pers, exp_pers)
diff --git a/test/test_functional/test_pangenome.py b/test/test_functional/test_pangenome.py
index 25b342bb56d905ebb6f45d3b6796281d94447ff0..089ef6555526b5aa679e5db502d9fca7f0b4598a 100755
--- a/test/test_functional/test_pangenome.py
+++ b/test/test_functional/test_pangenome.py
@@ -116,8 +116,9 @@ def test_main(caplog):
     used_dbpath = os.path.join(GENEPATH, "database")
     # copy db_path folder to output folder, as it will modify it
     shutil.copytree(DBPATH, used_dbpath)
-    pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
-             threads, verbose=2)
+    out_panfile = os.path.join(outdir, "PanGenome-testPAN4.All.prt-clust-0.8-mode1_")
+    assert pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode,
+                    spe_dir, threads, verbose=2).startswith(out_panfile)
     # Checl creation of prt bank
     prtbank = os.path.join(used_dbpath, "testPAN4.All.prt")
     assert os.path.isfile(prtbank)
@@ -181,8 +182,9 @@ def test_main_prt_exist(caplog):
     dest_prt_bank = os.path.join(used_dbpath, "test2PAN4.All.prt")
     shutil.copyfile(src_prt_bank, dest_prt_bank)
 
-    pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
-             threads, verbose=15)
+    out_panfile = os.path.join(outdir, "PanGenome-test2PAN4.All.prt-clust-0.8-mode1_")
+    assert pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
+                    threads, verbose=15).startswith(out_panfile)
 
     # Check presence of mmseq DB files
     msdb = os.path.join(GENEPATH, "test2PAN4.All.prt-msDB")
@@ -251,8 +253,9 @@ def test_main_spedir(caplog):
     # copy db_path folder to output folder, as it will modify it
     shutil.copytree(DBPATH, used_dbpath)
 
-    pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
-             threads, verbose=15)
+    out_panfile = os.path.join(outdir, "PanGenome-test3PAN4.All.prt-clust-0.8-mode1_")
+    assert pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
+                    threads, verbose=15).startswith(out_panfile)
     # Checl creation of prt bank
     prtbank = os.path.join(spe_dir, "test3PAN4.All.prt")
     assert os.path.isfile(prtbank)
@@ -322,8 +325,8 @@ def test_main_outfile(caplog):
     # copy db_path folder to output folder, as it will modify it
     shutil.copytree(DBPATH, used_dbpath)
 
-    pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
-             threads, outfile=outfile)
+    assert pan.main(cmd, lstinfo, name, used_dbpath, min_id, outdir, clust_mode, spe_dir,
+                    threads, outfile=outfile) == os.path.join(outdir, outfile)
 
     prtbank = os.path.join(used_dbpath, "test4PAN4.All.prt")
     assert os.path.isfile(prtbank)
diff --git a/test/test_functional/test_prepare.py b/test/test_functional/test_prepare.py
index 4a84da725e45cc45dea21e0b0ddbaeccc2dd5f06..d04ee928aa32d3c15eb3665c196db13125fb4d88 100644
--- a/test/test_functional/test_prepare.py
+++ b/test/test_functional/test_prepare.py
@@ -117,9 +117,10 @@ def test_main_not_only_mash_infoexists():
     max_dist = 0.06
     verbose = 2
     quiet = False
-    prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads, no_refseq,
-                 db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist, max_dist,
-                 verbose, quiet)
+    out_info_file = os.path.join(outdir, "LSTINFO-104099-filtered-0.0001_0.06.txt")
+    assert prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir,
+                        threads, no_refseq, db_dir, only_mash, info_file, l90, nbcont,
+                        cutn, min_dist, max_dist, verbose, quiet) == out_info_file
 
     # Check output files
     summary =  os.path.join(GENEPATH, "assembly_summary-104099.txt")
@@ -316,9 +317,10 @@ def test_main_norefseq_nodefault_dbdir_but_refseq(capsys):
     verbose = 2
     quiet = False
     info_file = ""
-    prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads, no_refseq,
-                 db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist, max_dist,
-                 verbose, quiet)
+    out_info_file = os.path.join(outdir, f"LSTINFO-123-filtered-0.0001_0.06.txt")
+    assert prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads,
+                        no_refseq, db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist,
+                        max_dist, verbose, quiet) == out_info_file
     out, err = capsys.readouterr()
     assert ("You asked to skip refseq downloads") in err
     assert ("Database folder test/data/prepare/generated_by_func-tests/"
@@ -372,9 +374,10 @@ def test_main_norefseq_defaultdbdir(capsys):
     verbose = 2
     quiet = False
     info_file = ""
-    prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads, no_refseq,
-                 db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist, max_dist,
-                 verbose, quiet)
+    out_info_file = os.path.join(outdir, "LSTINFO-123-filtered-0.0001_0.06.txt")
+    assert prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads,
+                        no_refseq, db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist,
+                        max_dist, verbose, quiet) == out_info_file
     out, err = capsys.readouterr()
     assert ("You asked to skip refseq downloads") in err
     assert ("Total number of genomes for 123: 5") in out
@@ -421,9 +424,10 @@ def test_main_norefseq_givendbdir(capsys):
     verbose = 2
     quiet = False
     info_file = ""
-    prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads, no_refseq,
-                 db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist, max_dist,
-                 verbose, quiet)
+    out_info_file = os.path.join(outdir, "LSTINFO-NA-filtered-0.0001_0.06.txt")
+    assert prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads,
+                        no_refseq, db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist,
+                        max_dist, verbose, quiet) == out_info_file
     out, err = capsys.readouterr()
     assert ("You asked to skip refseq downloads") in err
     assert ("Total number of genomes for NA: 5") in out
@@ -462,9 +466,10 @@ def test_only_mash(capsys):
     max_dist = 0.06
     verbose = 1
     quiet = False
-    prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads, no_refseq,
-                 db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist, max_dist,
-                 verbose, quiet)
+    out_info_file = os.path.join(outdir, "LSTINFO-NA-filtered-0.0001_0.06.txt")
+    assert prepare.main("cmd", NCBI_species, NCBI_taxid, levels, outdir, tmp_dir, threads,
+                        no_refseq, db_dir, only_mash, info_file, l90, nbcont, cutn, min_dist,
+                        max_dist, verbose, quiet) == out_info_file
     out, err = capsys.readouterr()
     assert ("You asked to run only mash steps") in err
     assert ("You want to run only mash steps. Getting information from "
diff --git a/test/test_functional/test_tree-parser.py b/test/test_functional/test_tree-parser.py
index f70f2d8b18a39c7459c2a7a8a93c03c930b9dd2c..f598701fabb01ac31dcae3d818923d05e17afe15 100755
--- a/test/test_functional/test_tree-parser.py
+++ b/test/test_functional/test_tree-parser.py
@@ -93,7 +93,7 @@ def test_parser_quicktree_parallel(capsys):
     parser = argparse.ArgumentParser(description="Tree", add_help=False)
     tree.build_parser(parser)
     with pytest.raises(SystemExit):
-        tree.parse(parser, "-a align -s quicktree --threads 5 -o outdir".split())
+        tree.parse(parser, "-a align -s quicktree --threads 2 -o outdir".split())
     _, err = capsys.readouterr()
     assert ("You cannot run quicktree with multiple threads. Choose another software, or remove "
             "the --threads option.") in err
@@ -317,14 +317,16 @@ def test_parser_threads_ok():
     """
     parser = argparse.ArgumentParser(description="Tree", add_help=False)
     tree.build_parser(parser)
-    args = tree.parse(parser, "-a align -o outdir --threads 5".split())
+    import multiprocessing
+    nb = multiprocessing.cpu_count()
+    args = tree.parse(parser, f"-a align -o outdir --threads {nb}".split())
     assert args.alignment == "align"
     assert args.boot is None
     assert args.outdir == "outdir"
     assert args.soft == "iqtree"
     assert args.model == "GTR"
     assert args.write_boot is False
-    assert args.threads == 5
+    assert args.threads == nb
     assert args.verbose == 0
     assert args.quiet == False
 
diff --git a/test/test_functional/test_tree.py b/test/test_functional/test_tree.py
index 6215f493d7c6881ddfe3b90d994b0b3b56bd4004..df0b9867663e54654e461b5489925027061d2988 100755
--- a/test/test_functional/test_tree.py
+++ b/test/test_functional/test_tree.py
@@ -33,7 +33,8 @@ def setup_teardown_module():
     - remove all log files
     - remove directory with generated results
     """
-    os.mkdir(GENEPATH)
+    if not os.path.isdir(GENEPATH):
+        os.mkdir(GENEPATH)
     print("setup")
 
     yield
@@ -50,9 +51,10 @@ def test_main_default(capsys):
     soft = "iqtree"
     model = "GTR"
     threads = 1
+    verbose = 3
 
     cmd = "cmd test_main_default"
-    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads)
+    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads, verbose=verbose)
     # Check output files
     iq_log_file = os.path.join(outdir, "exp_pers4genomes.grp.aln.iqtree_tree.log")
     assert os.path.isfile(iq_log_file)
@@ -73,6 +75,7 @@ def test_main_default(capsys):
     assert os.path.isfile(logs_base + ".err")
     # Check logs
     out, err = capsys.readouterr()
+    print(out)
     assert "Running IQtree..." in out
     assert ("IQtree command: iqtree -s test/data/align/exp_files/exp_pers4genomes.grp.aln "
             "-nt 1 -m GTR    -st DNA -pre test/data/tree/generated_by_func_tests/"
@@ -118,6 +121,43 @@ def test_main_quicktree(capsys):
     assert "END" in out
 
 
+def test_main_quicktree_notverbose(capsys):
+    """
+    Test that when giving the alignment file, running with quicktree, no bootstraps,
+    it creates expected files
+    """
+    outdir = GENEPATH
+    soft = "quicktree"
+    model = None
+    threads = 1
+    cmd = "cmd: test_main_quicktree"
+    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads)
+    # Check output files
+    # stockholm alignments
+    stockholm = os.path.join(outdir, "exp_pers4genomes.grp.aln.stockholm")
+    assert os.path.isfile(stockholm)
+    # quicktree logfile
+    log_file = stockholm + ".quicktree.log"
+    assert os.path.isfile(log_file)
+    with open(log_file, "r") as logf:
+        assert logf.readlines() == []
+    # tree file
+    tree_file = stockholm + ".quicktree_tree.nwk"
+    assert os.path.isfile(tree_file)
+    assert tutils.is_tree_lengths(tree_file)
+    assert not tutils.is_tree_bootstrap(tree_file)
+    # log files
+    logs_base = os.path.join(outdir, "PanACoTA-tree-quicktree.log")
+    assert os.path.isfile(logs_base)
+    assert os.path.isfile(logs_base + ".details")
+    assert os.path.isfile(logs_base + ".err")
+    # Check logs
+    out, err = capsys.readouterr()
+    assert "Converting fasta alignment to stockholm format." in out
+    assert "Running Quicktree..." in out
+    assert "END" in out
+
+
 def test_main_fastme(capsys):
     """
     Test that when giving the alignment file, running with fastme, no bootstraps,
@@ -182,7 +222,7 @@ def test_main_fasttree(capsys):
     threads = 1
     boot = 100
     cmd = "cmd: test_main_fasttree"
-    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads, boot=boot)
+    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads, boot=boot, verbose=2)
     # Check output files
     # fastme logfile
     log_file = os.path.join(outdir, "exp_pers4genomes.grp.aln.fasttree.log")
@@ -201,11 +241,12 @@ def test_main_fasttree(capsys):
     # log files
     logs_base = os.path.join(outdir, "PanACoTA-tree-fasttree.log")
     assert os.path.isfile(logs_base)
-    assert not os.path.isfile(logs_base + ".details")
+    assert os.path.isfile(logs_base + ".details")
     assert not os.path.isfile(logs_base + ".debug")
     assert os.path.isfile(logs_base + ".err")
     # Check logs
     out, err = capsys.readouterr()
+    print(out)
     assert "Running FasttreeMP..." in out
     assert ("Fasttree command: FastTreeMP -nt -gtr -noml -nocat -boot 100 "
             "-log test/data/tree/generated_by_func_tests/exp_pers4genomes.grp.aln.fasttree.log "
@@ -224,7 +265,8 @@ def test_main_iqtree2_newdir(capsys):
     threads = 1
 
     cmd = "cmd test_main_default"
-    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads, boot=1000, write_boot=True)
+    tree.main(cmd, ALIGNMENT, outdir, soft, model, threads, boot=1000, write_boot=True,
+              verbose=2)
     # Check output files
     # Check iqtree logfile
     iq_log_file = os.path.join(outdir, "exp_pers4genomes.grp.aln.iqtree_tree.log")
@@ -254,6 +296,7 @@ def test_main_iqtree2_newdir(capsys):
     logs_base = os.path.join(outdir, "PanACoTA-tree-iqtree2.log")
     assert os.path.isfile(logs_base)
     assert os.path.isfile(logs_base + ".err")
+    assert os.path.isfile(logs_base + ".details")
     # Check logs
     out, err = capsys.readouterr()
     assert "Running IQtree..." in out
@@ -278,7 +321,7 @@ def test_main_from_parse(capsys):
     args.model = "HKY"
     args.write_boot = False
     args.threads = 1
-    args.verbose = 1
+    args.verbose = 2
     args.quiet = False
     args.memory = False
     args.fast = False
diff --git a/test/test_unit/test_align/test_postalign.py b/test/test_unit/test_align/test_postalign.py
index b921e3f42aa6b4fb510e5b18c120d3bd3a1bbbd6..32b41dca205af6b5a916ce1a180d24a74e4600b8 100755
--- a/test/test_unit/test_align/test_postalign.py
+++ b/test/test_unit/test_align/test_postalign.py
@@ -201,7 +201,7 @@ def test_launch_gbg(caplog):
     open(out_grp, "w").close()
     dname = "TESTlaunch"
     quiet = False
-    assert pal.launch_group_by_genome(all_genomes, alnfile, status, treedir, dname, quiet) is True
+    assert pal.launch_group_by_genome(all_genomes, alnfile, status, out_grp, dname, quiet) is True
     exp_grp = os.path.join(EXPPATH, "exp_pers4genomes.grp.aln")
     assert tutil.compare_order_content(out_grp, exp_grp)
     assert "Grouping alignments per genome" in caplog.text
@@ -224,7 +224,7 @@ def test_launch_gbg_existsempty(caplog):
     open(out_grp, "w").close()
     dname = "TESTlaunch"
     quiet = False
-    assert pal.launch_group_by_genome(all_genomes, alnfile, status, treedir, dname, quiet) is True
+    assert pal.launch_group_by_genome(all_genomes, alnfile, status, out_grp, dname, quiet) is True
     assert "Grouping alignments per genome" not in caplog.text
     with open(out_grp, "r") as outf:
         assert outf.readlines() == []
@@ -246,7 +246,7 @@ def test_launch_gbg_ok_notexist(caplog):
     out_grp = os.path.join(treedir, "TESTlaunch.grp.aln")
     dname = "TESTlaunch"
     quiet = False
-    assert pal.launch_group_by_genome(all_genomes, alnfile, status, treedir, dname, quiet) is True
+    assert pal.launch_group_by_genome(all_genomes, alnfile, status, out_grp, dname, quiet) is True
     exp_grp = os.path.join(EXPPATH, "exp_pers4genomes.grp.aln")
     assert tutil.compare_order_content(out_grp, exp_grp)
     assert "Grouping alignments per genome" in caplog.text
diff --git a/test/test_unit/test_prepare/test_filter.py b/test/test_unit/test_prepare/test_filter.py
index b47a4932edfead06ff763c448b174ba2db1639b0..86d907fb252f355b1b9f3f172e2f220b87e194ed 100755
--- a/test/test_unit/test_prepare/test_filter.py
+++ b/test/test_unit/test_prepare/test_filter.py
@@ -124,11 +124,12 @@ def test_write_output():
     max_dist = 0.06
 
     # Check everything works without error
+    list_file = os.path.join(outdir, "LSTINFO-Acetobacter_fabarum-filtered-0.0001_0.06.txt")
     assert filterg.write_outputfiles(genomes, sorted_genomes,
-                                     genomes_removed, outdir, gspecies, min_dist, max_dist) == 0
+                                     genomes_removed, outdir, gspecies,
+                                     min_dist, max_dist) == list_file
 
     # Check outfiles exist
-    list_file = os.path.join(outdir, "LSTINFO-Acetobacter_fabarum-filtered-0.0001_0.06.txt")
     discard_file = os.path.join(outdir, "discarded-by-minhash-Acetobacter_fabarum-0.0001_0.06.txt")
     assert os.path.isfile(list_file)
     assert os.path.isfile(discard_file)
@@ -181,11 +182,12 @@ def test_write_output_no_discard():
     max_dist = 0.06
 
     # Check everything works without error
+    list_file = os.path.join(outdir, "LSTINFO-Acetobacter_fabarum-filtered-0.0001_0.06.txt")
     assert filterg.write_outputfiles(genomes, sorted_genomes,
-                                     genomes_removed, outdir, gspecies, min_dist, max_dist) == 0
+                                     genomes_removed, outdir, gspecies,
+                                     min_dist, max_dist) == list_file
 
     # Check outfiles exist
-    list_file = os.path.join(outdir, "LSTINFO-Acetobacter_fabarum-filtered-0.0001_0.06.txt")
     discard_file = os.path.join(outdir, "discarded-by-minhash-Acetobacter_fabarum-0.0001_0.06.txt")
     assert os.path.isfile(list_file)
     assert os.path.isfile(discard_file)
@@ -231,11 +233,12 @@ def test_write_output_no_genome():
     max_dist = 0.06
 
     # Check everything works without error
+    list_file = os.path.join(outdir, "LSTINFO-Acetobacter_fabarum-filtered-0.0001_0.06.txt")
     assert filterg.write_outputfiles(genomes, sorted_genomes,
-                                     genomes_removed, outdir, gspecies, min_dist, max_dist) == 0
+                                     genomes_removed, outdir, gspecies,
+                                     min_dist, max_dist) == list_file
 
     # Check outfiles exist
-    list_file = os.path.join(outdir, "LSTINFO-Acetobacter_fabarum-filtered-0.0001_0.06.txt")
     discard_file = os.path.join(outdir, "discarded-by-minhash-Acetobacter_fabarum-0.0001_0.06.txt")
     assert os.path.isfile(list_file)
     assert os.path.isfile(discard_file)