@jbrowse/bandage-core 0.1.20 → 4.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/chunks/{chunk-3XDR3ZBS.js → chunk-B5ZHLU4N.js} +603 -41
- package/dist/cli/figure.js +61 -56
- package/dist/index.js +89 -273
- package/dist/types/cli/figure.d.ts +8 -8
- package/dist/types/figure.d.ts +3 -1
- package/dist/types/gbzCut.d.ts +33 -0
- package/dist/types/genes/geneFiles.d.ts +10 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/labelLayout.d.ts +14 -0
- package/dist/types/overlayLabels.d.ts +1 -0
- package/dist/types/referenceStrip.d.ts +11 -8
- package/dist/types/version.d.ts +1 -0
- package/dist/types/walkKey.d.ts +1 -0
- package/package.json +3 -2
package/dist/cli/figure.js
CHANGED
|
@@ -1,38 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
HPRC_GBZ,
|
|
4
|
+
cutGbzRegion,
|
|
5
|
+
featuresOnBackbone,
|
|
4
6
|
figureSvg,
|
|
5
7
|
forceLayout,
|
|
6
|
-
|
|
8
|
+
genesFromBed,
|
|
9
|
+
genesFromGff3Lines,
|
|
10
|
+
genesFromText,
|
|
11
|
+
graphBackbone,
|
|
7
12
|
layoutModeByValue,
|
|
8
13
|
loadBandage,
|
|
9
14
|
loadGraph,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "../chunks/chunk-3XDR3ZBS.js";
|
|
15
|
+
openGbz,
|
|
16
|
+
parseRegion
|
|
17
|
+
} from "../chunks/chunk-B5ZHLU4N.js";
|
|
14
18
|
|
|
15
19
|
// src/cli/figure.ts
|
|
16
20
|
import { open, readFile, writeFile } from "node:fs/promises";
|
|
17
21
|
import path from "node:path";
|
|
18
22
|
import { parseArgs } from "node:util";
|
|
19
23
|
import { gunzipSync } from "node:zlib";
|
|
20
|
-
import {
|
|
21
|
-
var HPRC = {
|
|
22
|
-
db: "https://s3-us-west-2.amazonaws.com/human-pangenomics/pangenomes/freeze/release2/minigraph-cactus/v2.1/hprc-v2.1-mc-grch38/hprc-v2.1-mc-grch38.gbz.db",
|
|
23
|
-
index: "https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38.haplotype-index.anchored.db"
|
|
24
|
-
};
|
|
25
|
-
var WALK_LIMIT = 1e5;
|
|
26
|
-
function parseRegion(text) {
|
|
27
|
-
const m = /^\s*([^:\s]+):([\d,]+)-([\d,]+)\s*$/.exec(text);
|
|
28
|
-
if (!m) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
`"${text}" is not a region like chr6:160,614,798-160,647,758`
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
const n = (s) => Number(s.replaceAll(",", ""));
|
|
34
|
-
return { refName: m[1], start: n(m[2]), end: n(m[3]) };
|
|
35
|
-
}
|
|
24
|
+
import { TabixIndexedFile } from "@gmod/tabix";
|
|
36
25
|
var isUrl = (s) => /^https?:\/\//.test(s);
|
|
37
26
|
function byteSource(location) {
|
|
38
27
|
if (isUrl(location)) {
|
|
@@ -64,36 +53,40 @@ function byteSource(location) {
|
|
|
64
53
|
}
|
|
65
54
|
};
|
|
66
55
|
}
|
|
67
|
-
async function
|
|
56
|
+
async function text(location) {
|
|
68
57
|
const bytes = isUrl(location) ? new Uint8Array(await (await fetch(location)).arrayBuffer()) : await readFile(location);
|
|
69
58
|
const gzipped = bytes[0] === 31 && bytes[1] === 139;
|
|
70
59
|
return new TextDecoder().decode(gzipped ? gunzipSync(bytes) : bytes);
|
|
71
60
|
}
|
|
72
|
-
async function
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
61
|
+
async function readGenes(genes, graph, resolve) {
|
|
62
|
+
const backbone = graphBackbone(graph);
|
|
63
|
+
if (!backbone) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const file = resolve(genes.file);
|
|
67
|
+
const format = genes.format ?? (/\.bed(\.gz)?$/i.test(genes.file) ? "bed" : "gff3");
|
|
68
|
+
if (!genes.index) {
|
|
69
|
+
return featuresOnBackbone(genesFromText(await text(file)), backbone);
|
|
70
|
+
}
|
|
71
|
+
const index = resolve(genes.index);
|
|
72
|
+
const csi = index.endsWith(".csi");
|
|
73
|
+
const tabix = new TabixIndexedFile(
|
|
74
|
+
isUrl(file) ? { url: file, ...csi ? { csiUrl: index } : { tbiUrl: index } } : { path: file, ...csi ? { csiPath: index } : { tbiPath: index } }
|
|
77
75
|
);
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
throw new Error(`${sample} has no indexed path named ${region.refName}`);
|
|
76
|
+
const indexed = new Set(await tabix.getReferenceSequenceNames());
|
|
77
|
+
const lines = [];
|
|
78
|
+
for (const contig of backbone.contigs) {
|
|
79
|
+
const refName = [contig.contig, contig.refName].find((n) => indexed.has(n));
|
|
80
|
+
if (refName !== void 0) {
|
|
81
|
+
await tabix.getLines(refName, contig.start, contig.end, {
|
|
82
|
+
lineCallback: (line) => lines.push(line)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
88
85
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
limit: WALK_LIMIT,
|
|
94
|
-
...wanted ? { keep: (name) => haplotypeWanted(name, wanted) } : {}
|
|
95
|
-
});
|
|
96
|
-
return { text, region, name: `${sample} ${gbz.region}` };
|
|
86
|
+
return featuresOnBackbone(
|
|
87
|
+
format === "gff3" ? genesFromGff3Lines(lines) : genesFromBed(lines.join("\n")),
|
|
88
|
+
backbone
|
|
89
|
+
);
|
|
97
90
|
}
|
|
98
91
|
var engine = async (request) => {
|
|
99
92
|
const bandage = await loadBandage();
|
|
@@ -101,15 +94,26 @@ var engine = async (request) => {
|
|
|
101
94
|
const result = bandage.computeLayout(request.graph, request.options);
|
|
102
95
|
return { result, duration: performance.now() - start };
|
|
103
96
|
};
|
|
104
|
-
async function renderSpec(spec, base
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
async function renderSpec(spec, base) {
|
|
98
|
+
const resolve = (location) => isUrl(location) ? location : path.resolve(base, location);
|
|
99
|
+
let source;
|
|
100
|
+
if (spec.gbz) {
|
|
101
|
+
const { db, index } = spec.gbz.db === "hprc" ? HPRC_GBZ : spec.gbz;
|
|
102
|
+
const cut = await cutGbzRegion(
|
|
103
|
+
await openGbz(
|
|
104
|
+
byteSource(resolve(db)),
|
|
105
|
+
index ? byteSource(resolve(index)) : void 0
|
|
106
|
+
),
|
|
107
|
+
spec.gbz
|
|
108
|
+
);
|
|
109
|
+
source = { ...cut, name: `${cut.sample} ${spec.gbz.region}` };
|
|
110
|
+
} else if (spec.gfa) {
|
|
111
|
+
source = {
|
|
112
|
+
text: await text(resolve(spec.gfa)),
|
|
113
|
+
name: path.basename(spec.gfa),
|
|
114
|
+
region: spec.region ? parseRegion(spec.region) : void 0
|
|
115
|
+
};
|
|
116
|
+
} else {
|
|
113
117
|
throw new Error("a spec names its graph as `gfa` or `gbz`");
|
|
114
118
|
}
|
|
115
119
|
const graph = loadGraph(source.text, source.name, {
|
|
@@ -128,7 +132,8 @@ async function renderSpec(spec, base = ".") {
|
|
|
128
132
|
...spec,
|
|
129
133
|
walks: spec.walks?.map((w) => typeof w === "string" ? { walk: w } : w),
|
|
130
134
|
region: source.region,
|
|
131
|
-
|
|
135
|
+
genes: spec.genes ? await readGenes(spec.genes, graph, resolve) : void 0,
|
|
136
|
+
spec
|
|
132
137
|
});
|
|
133
138
|
}
|
|
134
139
|
async function main() {
|