def get_rule_doc_snakemake(name): """Decode and return lines of the docstring(s) for the object.""" from sequana import Module import snakemake rule = Module(name) wf = snakemake.Workflow(rule.path + "/%s.rules" % name) wf.include(rule.path + "/%s.rules" % name) docstring = list(wf.rules)[0].docstring return docstring
def test_sequana_config(): s = snaketools.Module("compressor") config = snaketools.SequanaConfig(s.config) assert config.config.get("compressor")["source"] == "fastq.gz" assert config.config.get("kraken:dummy") == None # --------------------------------- tests different constructors config = snaketools.SequanaConfig() config = snaketools.SequanaConfig({"test": 1}) assert config.config.test == 1 # with a dictionary config = snaketools.SequanaConfig(config.config) # with a sequanaConfig instance config = snaketools.SequanaConfig(config) # with a non-yaml file try: json = sequana_data('test_summary_fastq_stats.json') config = snaketools.SequanaConfig(json) assert False except: assert True try: config = snaketools.SequanaConfig("dummy_dummy") assert False except: assert True # Test an exception s = snaketools.Module("compressor") config = snaketools.SequanaConfig(s.config) config._recursive_update(config._yaml_code, {"input_directory_dummy": "test"}) #config.check_config_with_schema(s.schema_config) # loop over all pipelines, read the config, save it and check the content is # identical. This requires to remove the templates. We want to make sure the # empty strings are kept and that "no value" are kept as well # # field1: "" # field2: # # is unchanged from easydev import TempFile output = TempFile(suffix=".yaml") for pipeline in snaketools.pipeline_names: config_filename = Module(pipeline)._get_config() cfg1 = SequanaConfig(config_filename) cfg1.cleanup() # remove templates and strip strings cfg1.save(output.name) cfg2 = SequanaConfig(output.name) assert cfg2._yaml_code == cfg1._yaml_code cfg2._update_config() assert cfg1.config == cfg2.config output.delete()
def get_rule_doc(name): """Decode and return the docstring(s) of a sequana/snakemake rule.""" url = "https://raw.githubusercontent.com/sequana/sequana_{}/master/README.rst".format(name) data = urllib.request.urlopen(url).read().decode("utf8") try: from sequana import Module m = Module(name) version = m.version except: version = "?" docstring = "**current version**:{}\n\n{}".format(version, data) return docstring
def test_import_config_from_menu(qtbot): widget = sequana_gui.SequanaGUI(ipython=True) qtbot.addWidget(widget) assert widget.sequana_factory._imported_config is None # while an existing config file should # First, we simulate selection of quality control pipeline index = widget.sequana_factory._choice_button.findText("quality_control") widget.sequana_factory._choice_button.setCurrentIndex(index) widget.ui.tabs_pipeline.setCurrentIndex(0) # set sequana pipeline mode widget._update_sequana("quality_control") qc = Module("quality_control") widget.menuImportConfig(qc.config) assert widget.sequana_factory._imported_config is not None widget.close()
def get_rule_doc(name): """Decode and return the docstring(s) of a sequana/snakemake rule.""" try: from sequana import Module rule = Module(name) filename = rule.path + "/%s.rules" % name data = open(filename, "r").read() except ValueError: # a local file ? data = open(name, "r").read() # Try to identify the rule and therefore possible docstring # It may be a standard rule or a dynamic rule ! # standard one if name.endswith("_dynamic"): name = name[:-8] rulename_tag = "rule %s" % name if rulename_tag in data: data = data.split(rulename_tag, 1)[1] else: return "no docstring found for %s " % name # Find first """ or ''' after the rule definition single = data.find("'''") double = data.find('"""') if single > 0 and double > 0: if single > double: quotes = '"""' else: quotes = "'''" elif single > 0: quotes = "'''" elif double > 0: quotes = '"""' else: return "no docstring found for %s " % name start = data.find(quotes) end = data[start + 3:].find(quotes) + start + 3 if end == -1 or end < start: return "no end of docstring found for %s " % name docstring = data[start + 3:end] return docstring
def test_pipeline_manager(): # test missing input_directory cfg = SequanaConfig({}) try: pm = snaketools.PipelineManager("custom", cfg) assert False except: assert True # normal behaviour but no input provided: config = Module("quality_control")._get_config() cfg = SequanaConfig(config) cfg.cleanup() # remove templates try: pm = snaketools.PipelineManager("custome", cfg) assert False except: assert True cfg = SequanaConfig(config) cfg.cleanup() # remove templates file1 = sequana_data("Hm2_GTGAAA_L005_R1_001.fastq.gz") file2 = sequana_data("Hm2_GTGAAA_L005_R2_001.fastq.gz") cfg.config.input_samples['file1'] = file1 cfg.config.input_samples['file2'] = file2 pm = snaketools.PipelineManager("custome", cfg) assert pm.paired == True cfg = SequanaConfig(config) cfg.cleanup() # remove templates file1 = sequana_data("Hm2_GTGAAA_L005_R1_001.fastq.gz") cfg.config.input_samples['file1'] = file1 pm = snaketools.PipelineManager("custome", cfg) assert pm.paired == False pm.getlogdir("fastqc") pm.getwkdir("fastqc") pm.getrawdata() pm.getreportdir("test") pm.getname("fastqc")
def sequana_init(options): import sequana from sequana.misc import textwrap from sequana import SequanaConfig, sequana_data sa = Tools(verbose=options.verbose) # Check that the pipeline is well defined module = Module(options.pipeline) if os.path.exists(options.target_dir): txt = "Will override the following files if present: %s.rules " +\ "config.yaml, runme.sh, ..." sa.blue(txt % options.pipeline) if options.force is True: choice = "y" else: choice = input( red("Do you want to proceed (to avoid this " + " message, use --force)? [y]/n:")) if choice == "n": sys.exit(0) # Copying snakefile logger.info("Copying snakefile") sa.mkdir(options.target_dir) shutil.copy(module.snakefile, options.target_dir + os.sep + options.pipeline + ".rules") # Creating README to print on the screen and in a file txt = "User command::\n\n" txt += " %s \n\n" % " ".join(sys.argv) txt += "You can now run snakemake yourself or type::" txt += purple(""" snakemake -s %s.rules --stats stats.txt -p -j 4 """ % options.pipeline) txt += """ # -j 4 means you will use 4 cores # -p prints the commands used # --stats stats.txt must be used since stats.txt is expected to be found. or just run the bash script:: sh runme.sh EDIT THE config.yaml if needed Once finished with success, the report/ directory contains a summary.html and relevant files (depends on the pipeline). """ logger.info("Creating README") with open(options.target_dir + os.sep + "README", "w") as fh: fh.write(txt.replace("\x1b[35m", "").replace("\x1b[39;49;00m", "")) # Creating Config file logger.info("Creating the config file") # Create (if needed) and update the config file config_filename = options.target_dir + os.sep + "config.yaml" if options.config: # full existing path if os.path.exists(options.config): shutil.copy(options.config, config_filename) else: # or a sequana config file in the module path ? raise (IOError("Config file %s not found locally" % options.config)) else: copy_config_from_sequana(module, "config.yaml", config_filename) # Copy multiqc if it is available multiqc_filename = options.target_dir + os.sep + "multiqc_config.yaml" copy_config_from_sequana(module, "multiqc_config.yaml", multiqc_filename) cluster_cfg_filename = options.target_dir + os.sep + "cluster_config.json" copy_config_from_sequana(module, "cluster_config.json", cluster_cfg_filename) # The input cfg = SequanaConfig(config_filename) cfg.config.input_directory = options.input_directory cfg.config.input_pattern = options.pattern cfg.config.input_extension = options.extension cfg.config.input_samples.file1 = options.file1 cfg.config.input_samples.file2 = options.file2 cfg.config.input_readtag = options.input_readtag # Dedicated section for quality control section if options.pipeline == "quality_control": if options.design: shutil.copy(options.design, options.target_dir + os.sep) cfg.config['cutadapt'].design_file = os.path.basename( options.design) if options.kraken: cfg.config.kraken.database_directory = os.path.abspath( options.kraken) cfg.config.kraken.do = True else: cfg.config.kraken.do = False cfg.config['cutadapt'].fwd = options.adapter_fwd cfg.config['cutadapt'].rev = options.adapter_rev cfg.config['cutadapt'].adapter_type = options.adapters # Foir all pipeline using BWA if options.reference: cfg.config.bwa_mem.reference = os.path.abspath(options.reference) if options.pipeline == "variant_calling": if options.reference: cfg.config.bwa_mem_ref.reference = os.path.abspath( options.reference) if options.pipeline in ["rnaseq", "smallrnaseq"]: if options.design: shutil.copy(options.design, options.target_dir + os.sep) cfg.config['cutadapt'].design_file = os.path.basename( options.design) cfg.config['cutadapt'].fwd = options.adapter_fwd cfg.config['cutadapt'].rev = options.adapter_rev cfg.config['cutadapt'].adapter_choice = options.adapters cfg.copy_requirements(target=options.target_dir) # FIXME If invalid, no error raised if options.config_params: params = [this.strip() for this in options.config_params.split(",")] for param in params: if param.count(":") not in [1, 2, 3]: txt = "incorrect format following --config-params" txt += "Expected at least one : sign or at most 2 of them" txt += "Config file section such as :\n" txt += "project: tutorial\n" txt += "should be encoded project:tutorial" raise ValueError(txt) if param.count(":") == 1: k, v = param.split(':') cfg.config[k] = v elif param.count(":") == 2: k1, k2, v = param.split(":") cfg.config[k1][k2] = v elif param.count(":") == 3: k1, k2, k3, v = param.split(":") cfg.config[k1][k2][k3] = v # important to update yaml with content of config cfg._update_yaml() cfg.save(config_filename) # Creating a unique runme.sh file runme_filename = options.target_dir + os.sep + "runme.sh" with open(runme_filename, "w") as fout: cmd = "#!/bin/sh\n" cmd += "# generated with sequana version %s with this command:\n" % sequana.version cmd += "# %s\n" % " ".join(sys.argv) cmd += "snakemake -s %(project)s.rules --stats stats.txt -p -j %(jobs)s --nolock" if options.forceall: cmd += " --forceall " if options.cluster: # Do we want to include the cluster config option ? cluster_config = Module(options.pipeline).cluster_config if options.ignore_cluster_config is True: cluster_config = None if cluster_config is None: cmd += ' --cluster "%s"' % options.cluster else: cmd += ' --cluster "%s" --cluster-config %s' %\ (options.cluster, os.path.basename(cluster_config)) if options.redirection: cmd += " 1>run.out 2>run.err" fout.write( cmd % { 'project': options.pipeline, 'jobs': options.jobs, "version": sequana.version }) # change permission of runme.sh to 755 st = os.stat(runme_filename) os.chmod(runme_filename, st.st_mode | 0o755) sa.green("Initialisation of %s succeeded" % options.target_dir) sa.green("Please, go to the project directory ") sa.purple("\n cd %s\n" % options.target_dir) sa.green("Check out the README and config.yaml files") sa.green("A basic script to run the analysis is named runme.sh ") sa.purple("\n sh runme.sh\n") sa.purple("On a slurm cluster, you may type:") sa.purple("\n srun --qos normal runme.sh\n") sa.green( "In case of trouble, please post an issue on https://github.com/sequana/sequana/issue " ) sa.green( "or type sequana --issue and fill a post with the error and the config file (NO DATA PLEASE)" ) # Change permission try: #python 3 os.chmod(runme_filename, 0o755) except: logger.info( "Please use Python3. Change the mode of %s manually to 755" % runme_filename)
def main(args=None): """Mostly checking the options provided by the user and then call :func:`sequana_init` function to create the pre-filled config file + snakemake + README +runme.sh in a dedicated project directory. """ import sequana if args is None: args = sys.argv[:] user_options = Options(prog="sequana") # If --help or no options provided, show the help if len(args) == 1: sa = Tools() sa.purple("Welcome to Sequana standalone application") logger.critical("You must use --pipeline <valid pipeline name>\nuse " "--show-pipelines or --help for more information. ") return else: options = user_options.parse_args(args[1:]) # these imports must be local. This also speed up the --help sa = Tools(verbose=options.verbose) sa.purple("Welcome to Sequana standalone application") # Those options are mutually exclusive flag = int( "%s%s%s%s%s%s" % (int(bool(options.issue)), int(bool(options.version)), int(bool(options.info)), int(bool(options.show_pipelines)), int(bool(options.pipeline)), int(bool(options.get_config))), 2) if flag not in [1, 2, 4, 8, 16, 3, 32]: logger.critical("You must use one of --pipeline, --info, " "--show-pipelines, --issue, --version, --get-config") sys.exit(1) # OPTIONS that gives info and exit if options.issue: onweb('https://github.com/sequana/sequana/issues') return if options.version: sa.purple("Sequana version %s" % sequana.version) return if options.show_pipelines: sa.purple("Valid pipeline names:") for this in sorted(valid_pipelines): m = Module(this) sa.green(" - " + this) print(textwrap(m.overview, indent=8)) return if options.info: module = Module(options.info) module.onweb() return if options.pipeline: # check validity of the pipeline name if options.pipeline not in valid_pipelines: txt = "".join([" - %s\n" % this for this in valid_pipelines]) logger.critical("%s not a valid pipeline name. Use of one:\n" % options.pipeline + txt) sys.exit(1) # copy locally the request config file from a specific pipeline if flag == 3: #--get-config and --pipeline used module = Module(options.pipeline) copy_config_from_sequana(module) return # pipeline should be defined by now. Let us start the real work here Module("dag").check("warning") Module(options.pipeline).check("warning") # If user provides file1 and/or file2, check the files exist if options.file1 and os.path.exists(options.file1) is False: raise ValueError("%s does not exist" % options.file1) if options.file2 and os.path.exists(options.file2) is False: raise ValueError("%s does not exist" % options.file2) if options.kraken and os.path.exists(options.kraken) is False: raise ValueError("%s does not exist" % options.kraken) if options.input_directory and os.path.exists( options.input_directory) is False: raise ValueError("%s does not exist" % options.input_directory) # check valid combo of arguments flag = int( "%s%s%s%s%s" % ( int(bool(options.pattern)), int(bool(options.input_directory)), int(bool(options.file1)), int(bool(options.file2)), int(bool(options.config)), ), 2) # config file has flag 1, others have flag 2,4,8,16 # config file alone : 1 # --input-directory alone: 2 # --file1 alone: 4 # --file1 + --file2 : 2+4=6 # --input-pattern alone: 16 # none of those options redirect to input_directory=local if flag not in [0, 1, 2, 4, 6, 8, 16]: logger.critical(help_input + "\n\nUse --help for more information") sys.exit(1) assert options.extension in ["fastq", "fq", "fastq.gz", "fq.gz", "bam"] # Note that we use abspath to make it more robust and easier to debug # If no options, we use input_directory and set it to "." if flag == 0 or options.input_directory: if flag == 0: options.input_directory = "." options.input_directory = os.path.abspath(options.input_directory) data = options.input_directory + os.sep + "*" + options.extension options.file1 = "" options.file2 = "" options.pattern = "" if options.verbose: logger.info("Looking for sample files matching %s" % data) elif options.pattern: options.pattern = os.path.abspath(options.pattern) data = os.path.abspath(options.pattern) options.input_directory = "" options.extension = "" options.file1 = "" options.file2 = "" elif options.config: pass elif options.file1: data = [options.file1] options.file1 = os.path.abspath(options.file1) if options.file2: data = [options.file2] options.file2 = os.path.abspath(options.file2) options.input_directory = "" options.pattern = "" options.extension = "" if options.extension == 'bam' or options.pattern.endswith('bam') or \ options.pattern.endswith('bed'): ff = FileFactory(data) else: ff = FastQFactory(data, read_tag=options.input_readtag, verbose=options.verbose) if options.pipeline == 'quality_control' or options.pipeline == 'rnaseq': # check combo flag = int( "%s%s%s%s%s" % (int(bool(options.no_adapters)), int(bool(options.design)), int(bool(options.adapters)), int(bool( options.adapter_fwd)), int(bool(options.adapter_rev))), 2) if flag not in [16, 12, 6, 4, 2, 3]: logger.critical( "You must use a design experimental file using --design" " and --adapters to indicate the type of adapters (PCRFree" " or Nextera), or provide the adapters directly as a " " string (or a file) using --adapter_fwd (AND --adapter_" "rev for paired-end data). A third way is to set --adapters" " to either Nextera, PCRFree, Rubicon or universal in which case " " all adapters will be used (slower). Finally, you may use " " --no-adapters for testing purpose or if you know there " " is no adapters") sys.exit(1) # flag 12 (design + adapters when wrong args provided) if options.design and options.adapters not in adapters_choice: raise ValueError( "When using --design, you must also " "provide the type of adapters using --adapters (set to " "one of %s )" % adapters_choice) if options.design and options.adapters: from sequana import FindAdaptersFromDesign fa = FindAdaptersFromDesign(options.design, options.adapters) fa.check() # flag 12 (design + adapters with correct args) elif options.design and options.adapters in adapters_choice: options.adapters_fwd = options.adapters options.adapters_rev = options.adapters elif options.no_adapters: options.adapter_fwd = "XXXX" options.adapter_rev = "XXXX" else: if options.adapter_fwd is None: if options.adapters not in ["universal"] + adapters_choice: msg = "Incorrect adapter choice %s. " % options.adapters msg += "Correct values are :\n" for this in ['universal'] + adapters_choice: msg += " - {}\n ".format(this) logger.error(msg) raise ValueError # flag 4 if options.adapters == "universal": options.adapter_fwd = "GATCGGAAGAGCACACGTCTGAACTCCAGTCACCGATGTATCTCGTATGCCGTCTTCTGC" options.adapter_rev = "TCTAGCCTTCTCGCAGCACATCCCTTTCTCACATCTAGAGCCACCAGCGGCATAGTAA" # flag 4 else: # Let the pipeline handle the names options.adapter_fwd = options.adapters options.adapter_rev = options.adapters # flag 2/3 else: if options.adapter_fwd: # Could be a string or a file. If a file, check the format if os.path.exists(options.adapter_fwd): AdapterReader(options.adapter_fwd) options.adapter_fwd = "file:%s" % options.adapter_fwd if options.adapter_rev: # Could be a string or a file. If a file, check the format if os.path.exists(options.adapter_rev): AdapterReader(options.adapter_rev) options.adapter_rev = "file:%s" % options.adapter_rev if options.design: # Just check the format adapter_finder = FindAdaptersFromDesign(options.design, options.adapters) # If all options are valid, we can now create the tree structure sequana_init(options)
def test_md5(): from sequana import Module m = Module("quality_control") data = m.md5()
def main(args=None): user_options = Options(prog="sequana") if args is None: args = sys.argv # If --help or no options provided, show the help if len(args) == 1: user_options.parse_args(["prog", "--help"]) else: options = user_options.parse_args(args[1:]) if options.version: import sequana print(sequana.version) sys.exit() if options.jobs > 20 and options.bypass is False: raise ValueError('The number of jobs is limited to 20. You can ' + 'force this limit by using --bypass-job-limit') if misc.on_cluster("tars-") and options.unlock is False: if options.cluster is None: raise ValueError("You are on TARS (Institut Pasteur). You " + " must use --cluster option to provide the scheduler " + " options (typically ' --cluster 'sbatch --qos normal' )") # valid codecs: valid_extensions = [("fastq." + ext2).rstrip(".") for ext2 in ['', 'bz2', 'gz', 'dsrc']] valid_extensions += [("fq." + ext2).rstrip(".") for ext2 in ['', 'bz2', 'gz', 'dsrc']] valid_combos = [(x, y) for x in valid_extensions for y in valid_extensions if x!=y] if (options.source, options.target) not in valid_combos: raise ValueError("""--target and --source combo not valid. Must be one of fastq, fastq.gz, fastq.bz2 or fastq.dsrc""") # Create the config file locally module = Module("compressor") with TempFile(suffix=".yaml", dir=".") as temp: cfg = SequanaConfig(module.config) cfg.config.compressor.source = options.source cfg.config.compressor.target = options.target cfg.config.compressor.recursive = options.recursive cfg.config.compressor.verbose = options.verbose cfg.config.compressor.threads = options.threads cfg._update_yaml() cfg.save(filename=temp.name) # The Snakefile can stay in its original place: rule = module.path + os.sep + "compressor.rules" # Run the snakemake command itself. cmd = 'snakemake -s %s --configfile %s -j %s ' % \ (rule, temp.name, options.jobs) if options.dryrun: cmd += " --dryrun " if options.verbose is False: cmd += " --quiet " else: cmd += " -p " # for slurm only: --cores-per-socket if options.cluster: cluster = ' --cluster "%s" ' % options.cluster cmd += cluster if options.snakemake: if " -s " in options.snakemake or " -j " in options.snakemake: raise ValueError("-s or -j cannot be used in " + " --snakemake-options (already used internally") cmd += options.snakemake if options.unlock: cmd += " --unlock " if options.verbose: print(cmd) # On travis, snakemake.shell command from snakemake fails. # Most probably because travis itself uses a subprocess. # excute from easydev uses pexpect.spawn, which seems to work well from easydev import execute execute(cmd, showcmd=False)
def module(): return Module("quality_control")
def test_md5(): from sequana import Module m = Module("compressor") data = m.md5()
def test_pipeline_manager(): # test missing input_directory cfg = SequanaConfig({}) try: pm = snaketools.PipelineManager("custom", cfg) assert False except: assert True # normal behaviour but no input provided: config = Module("compressor")._get_config() cfg = SequanaConfig(config) cfg.cleanup() # remove templates try: pm = snaketools.PipelineManager("custome", cfg) assert False except: assert True cfg = SequanaConfig(config) cfg.cleanup() # remove templates file1 = sequana_data("Hm2_GTGAAA_L005_R1_001.fastq.gz") cfg.config.input_directory, cfg.config.input_pattern = os.path.split(file1) #file2 = sequana_data("Hm2_GTGAAA_L005_R2_001.fastq.gz") pm = snaketools.PipelineManager("custom", cfg) assert pm.paired == False cfg = SequanaConfig(config) cfg.cleanup() # remove templates cfg.config.input_directory, cfg.config.input_pattern = os.path.split(file1) cfg.config.input_pattern = "Hm*gz" #file1 = sequana_data("Hm2_GTGAAA_L005_R1_001.fastq.gz") pm = snaketools.PipelineManager("custom", cfg) pm.plot_stats() assert pm.paired == True pm.getlogdir("fastqc") pm.getwkdir("fastqc") pm.getrawdata() pm.getreportdir("test") pm.getname("fastqc") # Test different configuration of input_directory, input_readtag, # input_pattern # Test the _R[12]_ paired with tempfile.TemporaryDirectory() as tmpdir: cfg = SequanaConfig() cfgname = tmpdir + "/config.yaml" cfg.config.input_pattern = "*fastq.gz" cfg.config.input_directory = tmpdir cfg.config.input_readtag = "_R[12]_" cfg._update_yaml() cfg.save(cfgname) cmd = "touch {}/test_R1_.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) cmd = "touch {}/test_R2_.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) pm = snaketools.PipelineManager("test", cfgname) assert pm.paired == True # Test the _[12]_ paired with tempfile.TemporaryDirectory() as tmpdir: cfg = SequanaConfig() cfgname = tmpdir + "/config.yaml" cfg.config.input_pattern = "*fastq.gz" cfg.config.input_directory = tmpdir cfg.config.input_readtag = "_[12]." cfg._update_yaml() cfg.save(cfgname) cmd = "touch {}/test_1.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) cmd = "touch {}/test_2.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) pm = snaketools.PipelineManager("test", cfgname) assert pm.paired is True # Test the _R[12]_ single end with tempfile.TemporaryDirectory() as tmpdir: cfg = SequanaConfig() cfgname = tmpdir + "/config.yaml" cfg.config.input_pattern = "*fastq.gz" cfg.config.input_directory = tmpdir cfg.config.input_readtag = "_R[12]_" cfg._update_yaml() cfg.save(cfgname) cmd = "touch {}/test_R1_.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) pm = snaketools.PipelineManager("test", cfgname) assert pm.paired is False # Test the _R[12]_ single end with tempfile.TemporaryDirectory() as tmpdir: cfg = SequanaConfig() cfgname = tmpdir + "/config.yaml" cfg.config.input_pattern = "*fq.gz" # wrong on purpose cfg.config.input_directory = tmpdir cfg.config.input_readtag = "_R[12]_" cfg._update_yaml() cfg.save(cfgname) cmd = "touch {}/test_R1_.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) try: pm = snaketools.PipelineManager("test", cfgname) assert False except: assert True # Test the _R[12]_ single end with tempfile.TemporaryDirectory() as tmpdir: cfg = SequanaConfig() cfgname = tmpdir + "/config.yaml" cfg.config.input_pattern = "*fastq.gz" cfg.config.input_directory = tmpdir cfg.config.input_readtag = "R[12]_" cfg._update_yaml() cfg.save(cfgname) cmd = "touch {}/testR1_.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) cmd = "touch {}/testR2_.fastq.gz".format(tmpdir) subprocess.call(cmd.split()) try: pm = snaketools.PipelineManager("test", cfgname) assert False except: assert True
def test_module_version(): Module("snpeff/1.0").version == "1.0"
def test_check_config_with_schema(): schema = Module("compressor").schema_config SequanaConfig(Module("compressor").config).check_config_with_schema(schema)