Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.0 #106

Merged
merged 1 commit into from
Mar 29, 2024
Merged

v1.0 #106

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
- dev
workflow_dispatch:
workflow_dispatch:
pull_request:
branches-ignore: []
schedule:
Expand Down
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,15 @@ of the sequana wrappers and will use the official sequana github repository by d
(https://github.com/sequana/sequana-wrappers). This may be overwritten. For instance, you may use a local clone. To do
so, you will need to create an environment variable::

export SEQUANA_WRAPPERS="git+file:///home/user/github/sequana-wrappers
export SEQUANA_WRAPPERS="git+file:///home/user/github/sequana-wrappers"

If you decide to use singularity/apptainer, one common error on a cluster is that non-standard paths are not found. You can bind them using the -B option but a more general set up is to create thos environment variable::

export SINGULARITY_BINDPATH=" /path_to_bind"
export SINGULARITY_BINDPATH="/path_to_bind"

for Singularity setup, or ::

export APPTAINER_BINDPATH=" /path_to_bind"
export APPTAINER_BINDPATH="/path_to_bind"

for Apptainer setup.

Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
#maintainer ?#maintainer email
[tool.poetry]
name = "sequana_pipetools"
version = "0.17.3"
version = "1.0.0"
description = "A set of tools to help building or using Sequana pipelines"
authors = ["Sequana Team"]
license = "BSD-3"
Expand All @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Scientific/Engineering :: Bio-Informatics",
"Topic :: Scientific/Engineering :: Information Analysis",
Expand All @@ -34,7 +35,7 @@ packages = [

[tool.poetry.dependencies]
python = ">=3.8,<4.0"
easydev = ">=0.12.1"
easydev = ">=0.12"
parse = ">=1.19.0"
"ruamel.yaml" = ">=0.18.5"
packaging = ">=23.1"
Expand Down
3 changes: 1 addition & 2 deletions sequana_pipetools/scripts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import sys

import rich_click as click
from pkg_resources import DistributionNotFound

from sequana_pipetools import version
from sequana_pipetools.misc import url2hash
Expand Down Expand Up @@ -227,7 +226,7 @@ def main(**kwargs):
try:
c = ClickComplete(name)
c.save_completion_script()
except DistributionNotFound: # pragma: no cover
except Exception: # pragma: no cover
click.echo(f"# Warning {name} could not be imported. Nothing done")
finally:
click.echo("Please source the files using:: \n")
Expand Down
12 changes: 5 additions & 7 deletions sequana_pipetools/sequana_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ def __init__(self):
)

if self.options.apptainer_prefix: # pragma: no cover
self.apptainer_prefix = self.options.apptainer_prefix
self.apptainer_prefix = Path(self.options.apptainer_prefix).resolve()
if self.apptainer_prefix.exists() is False:
logger.error(f"{self.apptainer_prefix} does not exist")
sys.exit(1)
self.local_apptainers = False
else: # pragma: no cover
self.apptainer_prefix = os.environ.get("SEQUANA_SINGULARITY_PREFIX", f"{self.workdir}/.sequana/apptainers")
Expand Down Expand Up @@ -218,12 +221,7 @@ def setup(self):
if self.local_apptainers:
self.command += " --singularity-prefix .sequana/apptainers"
else:
if Path(self.apptainer_prefix).is_absolute():
self.command += f" --singularity-prefix {self.apptainer_prefix} "
else:
# if we set prefix to e.g. ./images then in the pipeline/script.sh,
# the prefix is also ./images whereas it should be ../images
self.command += f" --singularity-prefix ../{self.apptainer_prefix} "
self.command += f" --singularity-prefix {self.apptainer_prefix} "

# set up core/jobs options
if self.options.profile == "local":
Expand Down
2 changes: 2 additions & 0 deletions sequana_pipetools/snaketools/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def __init__(self, *args, **kwargs):

def status(self, working_directory="./", logs_directory="logs"):

print("\n\u274C one or several errors were detected. Please check carefully the above message, or the logs/ directory (for HPC/cluster usage). In the later case, some hints may be provided here below. " )

# we allows slurm to be detected even though we are not on a cluster
# this allows users to debug slurm job through NFS mounting
try: # let us try to introspect the slurm files
Expand Down
15 changes: 12 additions & 3 deletions sequana_pipetools/snaketools/pipeline_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,12 @@ def clean_multiqc(self, filename):

def onerror(self):
"""Try to report error from slurm"""
p = PipeError(self.name)
p.status()
try:
p = PipeError(self.name)
p.status()
print(f"\nIf you encoutered an error using sequana_{self.name}, please copy paste the above message and create a New Issue on https://github.com/sequana/{self.name}/issues")
except Exception as err:
print

def teardown(self, extra_dirs_to_remove=[], extra_files_to_remove=[], outdir="."):
# add a Makefile
Expand All @@ -164,6 +168,11 @@ def teardown(self, extra_dirs_to_remove=[], extra_files_to_remove=[], outdir="."
version = "unknown"
fout.write(f"{dep}\t{version}\n")

if os.path.exists("summary.html"):
print("\u2705 Another successful analysis. Open summary.html in your browser. Have fun.")
else:
print("\u2705 Another successful analysis. Have fun.")

def get_html_summary(self, float="left", width=30):
import pandas as pd

Expand Down Expand Up @@ -252,7 +261,7 @@ class PipelineManager(PipelineManagerBase):
a so-called read-tag to identify the first and second file. Traditionnally, e.g.,
with illumina sequencers the read tag are _R1_ and _R2_ or a trailing _1 and _2
Note that samples names have sometimes this tag included. Consider e.g.
sample_replicate_1_R1_.fastq.gz or sample_replicate_1_1.fastq.gz then you can imagine that
`sample_replicate_1_R1_.fastq.gz` or `sample_replicate_1_1.fastq.gz` then you can imagine that
it is tricky to handle.

The sample names are extracted by cutting filenames on the first dot that is encoutered
Expand Down
21 changes: 18 additions & 3 deletions sequana_pipetools/snaketools/profile.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
""" Setting up profile to setup """
import importlib.resources as pkg_resources

try:
import importlib.resources as resources
except ImportError: # pragma: no cover
# Try backported to PY<37 `importlib_resources`.
import importlib_resources as resources


from pathlib import Path


def create_profile(workdir: Path, profile: str, **kwargs) -> str:
"""Create profile config in working directory."""
with pkg_resources.path("sequana_pipetools.resources", f"{profile}.yaml") as slurm_file:
slurm_text = slurm_file.read_text().format(**kwargs)
try:
slurm_file = resources.files("sequana_pipetools.resources").joinpath(f"{profile}.yaml")
with open(slurm_file, "r") as fin:
slurm_text = fin.read()
slurl_text = slurm_text.format(**kwargs)
except AttributeError:
# python 3.8 support for back compatibility
with resources.path("sequana_pipetools.resources", f"{profile}.yaml") as slurm_file:
slurm_text = slurm_file.read_text().format(**kwargs)

outfile = workdir / f".sequana/profile_{profile}" / "config.yaml"
outfile.parent.mkdir(parents=True, exist_ok=True)
outfile.write_text(slurm_text)
Expand Down
10 changes: 7 additions & 3 deletions sequana_pipetools/snaketools/sequana_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
from pykwalify.core import Core, CoreError, SchemaError

try:
import importlib.resources as pkg_resources
import importlib.resources as resources
except ImportError: # pragma: no cover
# Try backported to PY<37 `importlib_resources`.
import importlib_resources as pkg_resources
import importlib_resources as resources

import colorlog

Expand Down Expand Up @@ -182,8 +182,12 @@ def check_config_with_schema(self, schemafile):

"""
# add custom extensions
with pkg_resources.path("sequana_pipetools.resources", "ext.py") as ext_name:
try:
ext_name = resources.files("sequana_pipetools.resources").joinpath("ext.py")
extensions = [str(ext_name)]
except AttributeError:
with resources.path("sequana_pipetools.resources", "ext.py") as ext_name:
extensions = [str(ext_name)]

# causes issue with ruamel.yaml 0.12.13. Works for 0.15
warnings.simplefilter("ignore", ruamel.yaml.error.UnsafeLoaderWarning)
Expand Down
2 changes: 1 addition & 1 deletion sequana_pipetools/snaketools/slurm.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def __repr__(self):
def _report(self):
N = len(self.errors)
message = "#" * 33 + " DEBUG REPORT " + "#" * 33 + "\n\n"
message += f"The analysis reached {self.percent}. A total of {N} error(s) has been found.\n"
message += f"The analysis reached {self.percent}. A total of {N} known error(s) have been found.\n"
if N > 0:
message += f"Errors are comming from rule(s): {','.join(set([e['rule'] for e in self.errors]))}\n\n"

Expand Down
9 changes: 1 addition & 8 deletions tests/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
from sequana_pipetools import SequanaConfig
#from sequana_pipetools.sequana_manager import get_pipeline_location

import pkg_resources
from packaging.version import parse as parse_version


from . import test_dir
Expand Down Expand Up @@ -164,12 +162,7 @@ def test_pipeline_parse_containers(tmpdir):
pm = SequanaManager(dd, "fastqc")
# fastqc uses 3 apptainers:

fastqc_version = pkg_resources.get_distribution("sequana_fastqc").version

if parse_version(fastqc_version) >= parse_version("1.6.0"):
assert len(pm._get_section_content(pm.module.snakefile, "container:")) in [2, 3,4]
else:
assert len(pm._get_section_content(pm.module.snakefile, "container:")) == 0
len(pm._get_section_content(pm.module.snakefile, "container:")) in [2, 3,4]


def test_multiple_downloads(tmpdir):
Expand Down
Loading