Skip to content

Commit 85a9b31

Browse files
committed
fixes #15
1 parent a1ea4d4 commit 85a9b31

File tree

6 files changed

+87
-73
lines changed

6 files changed

+87
-73
lines changed

covviz/bed.py

+24-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import csv
22
import logging
3-
import warnings
43
import os
54
import sys
5+
import warnings
66
from collections import defaultdict
77
from itertools import groupby
88

@@ -99,8 +99,10 @@ def get_traces(data, samples, outliers, distance_threshold, slop):
9999
)
100100
except IndexError as e:
101101
# x_values[0] is the first data point
102-
print("index error: %s\nindex_values[0]: %d, distance_idx: %d" % (
103-
e, index_values[0], distance_idx))
102+
print(
103+
"index error: %s\nindex_values[0]: %d, distance_idx: %d"
104+
% (e, index_values[0], distance_idx)
105+
)
104106
break
105107
extension_length -= (
106108
data["x"][index_values[0] - distance_idx + 1]
@@ -167,6 +169,7 @@ def parse_sex_groups(filename, sample_col, sex_col):
167169
groups[row[sex_col]].append(row[sample_col])
168170
return groups
169171

172+
170173
def normalize_depths(path, sex_chroms, median_window=7):
171174
filename, ext = os.path.splitext(path)
172175
if ext == ".gz":
@@ -183,32 +186,37 @@ def normalize_depths(path, sex_chroms, median_window=7):
183186

184187
extras = []
185188
for s in sex_chroms:
186-
if s.startswith("chr"): extras.append(s[3:])
187-
else: extras.append("chr" + s)
189+
if s.startswith("chr"):
190+
extras.append(s[3:])
191+
else:
192+
extras.append("chr" + s)
188193
sex_chroms = sex_chroms + extras
189194

190195
# median per site
191196
autosome = ~np.asarray(df.iloc[:, 0].isin(sex_chroms))
192197

193198
with warnings.catch_warnings():
194-
warnings.filterwarnings('ignore', r'All-NaN (slice|axis) encountered')
199+
warnings.filterwarnings("ignore", r"All-NaN (slice|axis) encountered")
195200
site_median = np.nanmedian(df.iloc[:, 3:], axis=1)
196201

197-
with np.errstate(invalid='ignore'):
202+
with np.errstate(invalid="ignore"):
198203
site_median[np.isnan(site_median) | (site_median < 0.03)] = 1
199204
# divide autosomes by median at each site so a given block is centered at
200205
# middle sample.
201206
for i in range(3, df.shape[1]):
202207
df.iloc[:, i] = np.where(autosome, df.iloc[:, i] / site_median, df.iloc[:, i])
203208
if median_window > 1:
204-
df.iloc[:, i] = df.iloc[:, i].rolling(median_window).median() #pd.rolling_median(df.iloc[:, i], median_window)
209+
df.iloc[:, i] = (
210+
df.iloc[:, i].rolling(median_window).median()
211+
) # pd.rolling_median(df.iloc[:, i], median_window)
205212
inan = np.asarray(np.isnan(df.iloc[:, i]))
206213
df.iloc[inan, i] = 0.0
207-
#df.to_csv(path_or_buf=output_bed, sep="\t", na_rep=0.0, index=False,
214+
# df.to_csv(path_or_buf=output_bed, sep="\t", na_rep=0.0, index=False,
208215
# compression='gzip',
209216
# float_format="%.2f")
210217
return df
211-
#return output_bed
218+
# return output_bed
219+
212220

213221
def identify_outliers(a, threshold=3.5):
214222
a = np.asarray(a, dtype=np.float32)
@@ -269,7 +277,7 @@ def parse_bed(
269277
slop=500000,
270278
min_samples=8,
271279
skip_norm=False,
272-
window=1
280+
window=1,
273281
):
274282
bed_traces = dict()
275283
# chromosomes, in order of appearance
@@ -286,15 +294,13 @@ def parse_bed(
286294
else:
287295
df = normalize_depths(path, sex_chroms, median_window=window)
288296

289-
if True: # temporary to get sane diff.
297+
if True: # temporary to get sane diff.
290298
header = list(df.columns)
291299
samples = header[3:]
292300
if groups:
293301
valid = validate_samples(samples, groups)
294302
if not valid:
295-
logger.critical(
296-
"sample ID mismatches exist between ped and bed"
297-
)
303+
logger.critical("sample ID mismatches exist between ped and bed")
298304
sys.exit(1)
299305
for chr, entries in df.groupby(header[0], as_index=False, sort=False):
300306

@@ -334,8 +340,9 @@ def parse_bed(
334340
bounds["upper"].append([])
335341
bounds["lower"].append([])
336342
if all_points:
337-
sample_values = np.minimum(3, np.asarray(row[3:],
338-
dtype=np.float32))
343+
sample_values = np.minimum(
344+
3, np.asarray(row[3:], dtype=np.float32)
345+
)
339346
for i, s in enumerate(samples):
340347
data[s].append(float(sample_values[i]))
341348
else:

covviz/templates/covviz.html

+54-51
Original file line numberDiff line numberDiff line change
@@ -417,57 +417,60 @@ <h5>Problematic low and non-uniform coverage bins</h5>
417417
// annotation tracks
418418
let y_offset = -0.10
419419
let track_idx = 0
420-
for (const tracktype of Object.keys(data[chr].annotations)) {
421-
for (const track of data[chr].annotations[tracktype]) {
422-
let trackname = track[0]
423-
let track_color = dark2[track_idx % dark2.length]
424-
let track_depth = 0
425-
if (tracktype == "gff" || tracktype == "bed") {
426-
let intervals = plot_intervals(track[1], y_offset)
427-
track_depth = intervals.track_depth
428-
scaled_traces.push({
429-
x: intervals.x,
430-
y: intervals.y,
431-
text: intervals.text,
432-
type: "scattergl",
433-
name: trackname,
434-
tracktype: tracktype,
435-
connectgaps: false,
436-
showlegend: false,
437-
line: { width: 2, color: track_color },
438-
mode: "lines+markers",
439-
hoverinfo: "text+x+name",
440-
hoverlabel: { namelength: -1 },
441-
marker: {
442-
size: 6,
443-
symbol: "square",
444-
color: track_color,
445-
line: { width: 1, color: "white" },
446-
},
447-
})
448-
} else {
449-
scaled_traces.push({
450-
x: track[1].x,
451-
y: Array(track[1].x.length).fill(y_offset),
452-
mode: "markers",
453-
type: "scattergl",
454-
name: trackname,
455-
text: track[1].text.map((i) => {
456-
return i.replaceAll(";", "<br>")
457-
}),
458-
hoverinfo: "text+x+name",
459-
hoverlabel: { namelength: -1 },
460-
marker: {
461-
size: 6,
462-
symbol: "square",
463-
color: track_color,
464-
line: { width: 1, color: "white" },
465-
},
466-
tracktype: tracktype,
467-
})
420+
421+
if ("annotations" in data[chr]) {
422+
for (const tracktype of Object.keys(data[chr].annotations)) {
423+
for (const track of data[chr].annotations[tracktype]) {
424+
let trackname = track[0]
425+
let track_color = dark2[track_idx % dark2.length]
426+
let track_depth = 0
427+
if (tracktype == "gff" || tracktype == "bed") {
428+
let intervals = plot_intervals(track[1], y_offset)
429+
track_depth = intervals.track_depth
430+
scaled_traces.push({
431+
x: intervals.x,
432+
y: intervals.y,
433+
text: intervals.text,
434+
type: "scattergl",
435+
name: trackname,
436+
tracktype: tracktype,
437+
connectgaps: false,
438+
showlegend: false,
439+
line: { width: 2, color: track_color },
440+
mode: "lines+markers",
441+
hoverinfo: "text+x+name",
442+
hoverlabel: { namelength: -1 },
443+
marker: {
444+
size: 6,
445+
symbol: "square",
446+
color: track_color,
447+
line: { width: 1, color: "white" },
448+
},
449+
})
450+
} else {
451+
scaled_traces.push({
452+
x: track[1].x,
453+
y: Array(track[1].x.length).fill(y_offset),
454+
mode: "markers",
455+
type: "scattergl",
456+
name: trackname,
457+
text: track[1].text.map((i) => {
458+
return i.replaceAll(";", "<br>")
459+
}),
460+
hoverinfo: "text+x+name",
461+
hoverlabel: { namelength: -1 },
462+
marker: {
463+
size: 6,
464+
symbol: "square",
465+
color: track_color,
466+
line: { width: 1, color: "white" },
467+
},
468+
tracktype: tracktype,
469+
})
470+
}
471+
y_offset = track_depth - 0.10
472+
track_idx += 1
468473
}
469-
y_offset = track_depth - 0.10
470-
track_idx += 1
471474
}
472475
}
473476

@@ -849,7 +852,7 @@ <h5>PCA 1 vs 3</h5>
849852
let seen = new Set()
850853

851854
for (const chr of data.chromosomes) {
852-
if ("gff" in data[chr].annotations) {
855+
if ("annotations" in data[chr] && "gff" in data[chr].annotations) {
853856
for (const gff of data[chr].annotations.gff) {
854857
let filename = gff[0]
855858
let gene_data = gff[1]

covviz/utils.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ def compare_array(a, b):
1717
b = np.pad(b, (0, len_a - len_b), mode="constant")
1818
elif len_b > len_a:
1919
a = np.pad(a, (0, len_b - len_a), mode="constant")
20-
return a[: np.nonzero(a != b)[0][0]]
20+
try:
21+
return a[: np.nonzero(a != b)[0][0]]
22+
except IndexError:
23+
# case: a == b
24+
return a
2125

2226

2327
def find_common_start(items):

docker/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ RUN apt-get update && apt-get install -y procps
44
RUN conda create -n env -c conda-forge python=3.7 numpy>=1.16.2 jinja2>=2.10.1
55
RUN echo "source activate env" > ~/.bashrc
66
ENV PATH /opt/conda/envs/env/bin:$PATH
7-
RUN /opt/conda/envs/env/bin/pip install --no-cache-dir covviz==1.3.0
7+
RUN /opt/conda/envs/env/bin/pip install --no-cache-dir covviz==1.3.1
88
RUN wget -qO /usr/bin/goleft https://github.com/brentp/goleft/releases/download/v0.2.3/goleft_linux64
99
RUN chmod +x /usr/bin/goleft

nextflow.config

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ process {
2525
errorStrategy = { task.exitStatus in [1,143,137,104,134,139] ? 'retry' : 'terminate' }
2626
maxRetries = 3
2727
maxErrors = '-1'
28-
container = 'brwnj/covviz:v1.3.0'
28+
container = 'brwnj/covviz:v1.3.1'
2929
withLabel: 'indexcov' {
3030
memory = { 8.GB * task.attempt }
3131
cache = 'deep'
@@ -62,7 +62,7 @@ manifest {
6262
name = 'brwnj/covviz'
6363
author = 'Joe Brown'
6464
description = "find large, coverage-based variations on chromosomes"
65-
version = '1.3.0'
65+
version = '1.3.1'
6666
nextflowVersion = '>=0.32.0'
6767
homePage = 'https://github.com/brwnj/covviz'
6868
mainScript = 'main.nf'

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
EMAIL = "brwnjm@gmail.com"
1919
AUTHOR = "Joe Brown"
2020
REQUIRES_PYTHON = ">=3.6.0"
21-
VERSION = "1.3.0"
21+
VERSION = "1.3.1"
2222

2323
# What packages are required for this module to be executed?
2424
REQUIRED = ["Jinja2", "numpy", "pandas"]

0 commit comments

Comments
 (0)