• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sequana / sequana / 16568275773

28 Jul 2025 11:51AM UTC coverage: 69.115% (-0.6%) from 69.722%
16568275773

push

github

web-flow
Merge pull request #870 from cokelaer/dev

add threshold parameter in G4 module

1 of 2 new or added lines in 1 file covered. (50.0%)

725 existing lines in 17 files now uncovered.

14389 of 20819 relevant lines covered (69.11%)

2.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.36
/sequana/scripts/main/fasta.py
1
#  This file is part of Sequana software
2
#
3
#  Copyright (c) 2016-2020 - Sequana Development Team
4
#
5
#  Distributed under the terms of the 3-clause BSD license.
6
#  The full license is in the LICENSE file, distributed with this software.
7
#
8
#  website: https://github.com/sequana/sequana
9
#  documentation: http://sequana.readthedocs.io
10
#
11
##############################################################################
12
import glob
3✔
13
import os
3✔
14
import subprocess
3✔
15
import sys
3✔
16

17
import colorlog
3✔
18
import rich_click as click
3✔
19

20
from sequana.fasta import FastA
3✔
21
from sequana.scripts.utils import CONTEXT_SETTINGS
3✔
22

23
logger = colorlog.getLogger(__name__)
3✔
24

25

26
@click.command(context_settings=CONTEXT_SETTINGS)
3✔
27
@click.argument("filename", type=click.STRING, nargs=-1)
3✔
28
@click.option(
3✔
29
    "-o",
30
    "--output",
31
    help="filename where to save results. to be used with --merge;, --save-contig-name",
32
)
33
@click.option("--count-sequences", is_flag=True, help="prints number of sequences")
3✔
34
@click.option(
3✔
35
    "--to-chrom-size", is_flag=True, help="extract name and size and print on stdout, or save in a file (--output)"
36
)
37
@click.option("--merge", is_flag=True, help="merge all compressed input fasta files into a single file")
3✔
38
@click.option("--save-contig-name", help="save sequence corresponding to this contig name")
3✔
39
@click.option("--explode", is_flag=True, help="Create a fasta file for each sequence found in the original files")
3✔
40
@click.option("--reverse-complement", is_flag=True, help="Create a fasta file with reversed complement sequence")
3✔
41
def fasta(**kwargs):
3✔
42
    """Set of useful utilities for FastA manipulation."""
UNCOV
43
    filenames = kwargs["filename"]
×
44
    # users may provide a wildcards such as "A*gz" or list of files.
UNCOV
45
    if len(filenames) == 1:
×
46
        # if existing files or glob, a glob would give the same answer.
47
        filenames = glob.glob(filenames[0])
×
48
    for filename in filenames:
×
UNCOV
49
        os.path.exists(filename)
×
50

51
    # could be simplified calling count_reads only once
52
    if kwargs["count_sequences"]:
×
53
        for filename in filenames:
×
54
            f = FastA(filename)
×
55
            Nreads = len(f)
×
56
            print(f"Number of reads in {filename}: {Nreads}")
×
57
    elif kwargs["to_chrom_size"]:
×
58
        output_filename = kwargs["output"]
×
59
        f = FastA(filename)
×
60
        if output_filename is None:
×
61
            for name, seq in zip(f.names, f.sequences):
×
UNCOV
62
                print(name, len(seq))
×
63
        else:
64
            with open(output_filename, "w") as fout:
×
65
                for name, seq in zip(f.names, f.sequences):
×
UNCOV
66
                    fout.write(f"{name}\t{len(seq)}\n")
×
67

UNCOV
68
    elif kwargs["merge"]:
×
69
        # merge all input files (assuming gz extension)
70
        extensions = [filename.split(".")[-1] for filename in filenames]
×
71
        if set(extensions) != set(["gz"]):
×
72
            raise ValueError("Your input FastA files must be zipped")
×
73
        output_filename = kwargs["output"]
×
74
        if output_filename is None:
×
75
            logger.error("You must use --output filename.gz")
×
76
            sys.exit(1)
×
77
        if output_filename.endswith(".gz") is False:
×
78
            raise ValueError("your output file must end in .gz")
×
79
        p1 = subprocess.Popen(["zcat"] + list(filenames), stdout=subprocess.PIPE)
×
80
        fout = open(output_filename, "wb")
×
81
        subprocess.run(["pigz"], stdin=p1.stdout, stdout=fout)
×
82
    elif kwargs["explode"]:
×
83
        for filename in filenames:
×
84
            f = FastA(filename)
×
85
            f.explode()
×
86
    elif kwargs["save_contig_name"]:
×
87
        f = FastA(filename)
×
88
        outname = kwargs["output"]
×
UNCOV
89
        f.save_ctg_to_fasta(kwargs["save_contig_name"], outname)
×
UNCOV
90
    elif kwargs["reverse_complement"]:
×
UNCOV
91
        f = FastA(filename)
×
UNCOV
92
        from sequana import reverse_complement
×
93

UNCOV
94
        outname = kwargs["output"]
×
UNCOV
95
        with open(outname, "w") as fout:
×
UNCOV
96
            for name, seq in zip(f.names, f.sequences):
×
UNCOV
97
                seq = reverse_complement(seq)
×
UNCOV
98
                fout.write(f">{name}\n{seq}\n")
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc