Skip to content

Commit bf5aa03

Browse files
committed
after black linting
1 parent e37d8ef commit bf5aa03

File tree

9 files changed

+639
-266
lines changed

9 files changed

+639
-266
lines changed

src/minkemap/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
2-
__version__ = "0.1.0"
1+
__version__ = "0.1.0"

src/minkemap/cli.py

Lines changed: 120 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,119 @@
1212
level=logging.INFO,
1313
format="%(asctime)s - %(levelname)s - %(message)s",
1414
datefmt="%H:%M:%S",
15-
handlers=[logging.StreamHandler(sys.stderr)]
15+
handlers=[logging.StreamHandler(sys.stderr)],
1616
)
1717
logger = logging.getLogger("MinkeMap")
1818

19+
1920
def main():
20-
parser = argparse.ArgumentParser(description="MinkeMap: Circular Genome Visualization Tool")
21-
21+
parser = argparse.ArgumentParser(
22+
description="MinkeMap: Circular Genome Visualization Tool"
23+
)
24+
2225
# Meta
23-
parser.add_argument("-v", "--version", action="version", version=f"MinkeMap v{__version__}")
24-
26+
parser.add_argument(
27+
"-v", "--version", action="version", version=f"MinkeMap v{__version__}"
28+
)
29+
2530
# Input / Output
26-
parser.add_argument("-r", "--reference", required=True, help="Reference genome (FASTA or GenBank)")
27-
parser.add_argument("-i", "--input", nargs="+", help="Input sequencing files (FASTQ/FASTA)")
28-
parser.add_argument("-f", "--input-file", help="Manifest CSV file (cols: sample,read1,read2,type)")
29-
parser.add_argument("-o", "--output", default="minkemap_plot.png", help="Output filename")
30-
parser.add_argument("--outdir", default="minkemap_results", help="Directory to save all output files")
31-
31+
parser.add_argument(
32+
"-r", "--reference", required=True, help="Reference genome (FASTA or GenBank)"
33+
)
34+
parser.add_argument(
35+
"-i", "--input", nargs="+", help="Input sequencing files (FASTQ/FASTA)"
36+
)
37+
parser.add_argument(
38+
"-f", "--input-file", help="Manifest CSV file (cols: sample,read1,read2,type)"
39+
)
40+
parser.add_argument(
41+
"-o", "--output", default="minkemap_plot.png", help="Output filename"
42+
)
43+
parser.add_argument(
44+
"--outdir",
45+
default="minkemap_results",
46+
help="Directory to save all output files",
47+
)
48+
3249
# Aesthetics
33-
parser.add_argument("--track-width", type=float, default=6, help="Width of each track ring (default: 6)")
34-
parser.add_argument("--track-gap", type=float, default=4, help="Gap between tracks (default: 4)")
50+
parser.add_argument(
51+
"--track-width",
52+
type=float,
53+
default=6,
54+
help="Width of each track ring (default: 6)",
55+
)
56+
parser.add_argument(
57+
"--track-gap", type=float, default=4, help="Gap between tracks (default: 4)"
58+
)
3559
parser.add_argument("--palette", default="whale", help="Color palette")
3660
parser.add_argument("--dpi", type=int, default=300, help="Image resolution")
3761
parser.add_argument("--title", help="Plot title")
38-
parser.add_argument("--no-legend", action="store_true", help="Hide the sample legend")
39-
parser.add_argument("--no-backbone", action="store_true", help="Hide the black reference backbone")
40-
parser.add_argument("--label-size", type=int, default=6, help="Font size for gene/annotation labels")
41-
62+
parser.add_argument(
63+
"--no-legend", action="store_true", help="Hide the sample legend"
64+
)
65+
parser.add_argument(
66+
"--no-backbone", action="store_true", help="Hide the black reference backbone"
67+
)
68+
parser.add_argument(
69+
"--label-size", type=int, default=6, help="Font size for gene/annotation labels"
70+
)
71+
4272
# Features
43-
parser.add_argument("--annotations", help="CSV file for custom regions (cols: reference,start,stop,label,color)")
44-
parser.add_argument("--highlights", help="CSV file for background wedges (cols: start,end,color,label)")
45-
parser.add_argument("--gc-skew", action="store_true", help="Add a GC Skew track to the center")
46-
parser.add_argument("--no-save-data", action="store_true", help="Do not generate BED/CSV data files")
47-
73+
parser.add_argument(
74+
"--annotations",
75+
help="CSV file for custom regions (cols: reference,start,stop,label,color)",
76+
)
77+
parser.add_argument(
78+
"--highlights",
79+
help="CSV file for background wedges (cols: start,end,color,label)",
80+
)
81+
parser.add_argument(
82+
"--gc-skew", action="store_true", help="Add a GC Skew track to the center"
83+
)
84+
parser.add_argument(
85+
"--no-save-data", action="store_true", help="Do not generate BED/CSV data files"
86+
)
87+
4888
# Filters
49-
parser.add_argument("--min-identity", type=float, default=0, help="Minimum identity %% (0-100)")
50-
parser.add_argument("--min-coverage", type=float, default=0, help="Minimum query coverage %% (0-100)")
51-
parser.add_argument("--exclude-genes", help="Comma-separated list of terms to exclude from gene track (e.g. 'hypothetical,putative')")
89+
parser.add_argument(
90+
"--min-identity", type=float, default=0, help="Minimum identity %% (0-100)"
91+
)
92+
parser.add_argument(
93+
"--min-coverage",
94+
type=float,
95+
default=0,
96+
help="Minimum query coverage %% (0-100)",
97+
)
98+
parser.add_argument(
99+
"--exclude-genes",
100+
help="Comma-separated list of terms to exclude from gene track (e.g. 'hypothetical,putative')",
101+
)
52102
parser.add_argument("--verbose", action="store_true", help="Enable debug logging")
53103

54104
args = parser.parse_args()
55-
105+
56106
if args.verbose:
57107
logger.setLevel(logging.DEBUG)
58108

59109
min_id_decimal = args.min_identity / 100.0
60110
min_cov_decimal = args.min_coverage / 100.0
61111
should_save = not args.no_save_data
62-
112+
63113
# 1. Create Output Directory & Log File
64114
try:
65115
os.makedirs(args.outdir, exist_ok=True)
66116
# Add File Handler to log to disk
67117
log_path = os.path.join(args.outdir, "minkemap.log")
68-
file_handler = logging.FileHandler(log_path, mode='w')
69-
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
118+
file_handler = logging.FileHandler(log_path, mode="w")
119+
file_handler.setFormatter(
120+
logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
121+
)
70122
logger.addHandler(file_handler)
71-
123+
72124
if args.outdir != ".":
73125
logger.info(f"Output directory: {args.outdir}/")
74126
logger.info(f"Log file: {log_path}")
75-
127+
76128
except OSError as e:
77129
logger.error(f"Error creating directory {args.outdir}: {e}")
78130
sys.exit(1)
@@ -84,26 +136,30 @@ def main():
84136
sys.exit(1)
85137

86138
total_tracks = len(samples)
87-
if args.gc_skew: total_tracks += 1
88-
total_tracks += 1 # Genes
89-
if args.annotations: total_tracks += 1
90-
139+
if args.gc_skew:
140+
total_tracks += 1
141+
total_tracks += 1 # Genes
142+
if args.annotations:
143+
total_tracks += 1
144+
91145
# 3. Init Ring
92146
ring = GenomeRing(
93-
args.reference,
147+
args.reference,
94148
outdir=args.outdir,
95149
track_width=args.track_width,
96150
track_gap=args.track_gap,
97151
palette=args.palette,
98152
total_tracks=total_tracks,
99153
no_backbone=args.no_backbone, # <--- New Arg
100-
label_size=args.label_size # <--- New Arg
154+
label_size=args.label_size, # <--- New Arg
101155
)
102-
156+
103157
logger.info(f"Reference loaded. Mapping {len(samples)} samples...")
104158
if args.min_identity > 0 or args.min_coverage > 0:
105-
logger.info(f" (Filters: Identity >= {args.min_identity}%, Coverage >= {args.min_coverage}%)")
106-
159+
logger.info(
160+
f" (Filters: Identity >= {args.min_identity}%, Coverage >= {args.min_coverage}%)"
161+
)
162+
107163
# 4. Features
108164
if args.highlights:
109165
ring.add_highlights(args.highlights)
@@ -114,36 +170,45 @@ def main():
114170
# 5. Map & Draw
115171
for sample in samples:
116172
hits = map_sample(
117-
ring.ref_path,
118-
sample,
119-
min_identity=min_id_decimal,
120-
min_coverage=min_cov_decimal
173+
ring.ref_path,
174+
sample,
175+
min_identity=min_id_decimal,
176+
min_coverage=min_cov_decimal,
121177
)
122-
123-
is_reads = sample.seq_type.lower() in ["nanopore", "illumina", "illumina_paired_end", "pacbio", "hifi"]
178+
179+
is_reads = sample.seq_type.lower() in [
180+
"nanopore",
181+
"illumina",
182+
"illumina_paired_end",
183+
"pacbio",
184+
"hifi",
185+
]
124186
plot_mode = "coverage" if is_reads else "rect"
125-
187+
126188
ring.add_track(
127-
sample.name,
128-
hits,
129-
plot_type=plot_mode,
189+
sample.name,
190+
hits,
191+
plot_type=plot_mode,
130192
min_identity=min_id_decimal,
131193
min_coverage=min_cov_decimal,
132-
save_data=should_save
194+
save_data=should_save,
133195
)
134196

135197
# 6. Genes (with filtering)
136-
exclude_list = [x.strip() for x in args.exclude_genes.split(',')] if args.exclude_genes else []
198+
exclude_list = (
199+
[x.strip() for x in args.exclude_genes.split(",")] if args.exclude_genes else []
200+
)
137201
ring.add_genes_track(exclude_list=exclude_list)
138-
202+
139203
if args.annotations:
140204
ring.add_custom_track(args.annotations)
141205

142206
# 7. Save
143207
ring.save(args.output, dpi=args.dpi, title=args.title, no_legend=args.no_legend)
144-
208+
145209
full_output_path = os.path.join(args.outdir, args.output)
146210
logger.info(f"Done! Saved to {full_output_path}")
147211

212+
148213
if __name__ == "__main__":
149-
main()
214+
main()

0 commit comments

Comments
 (0)