@jbrowse/cli 5.0.0-beta.1 → 5.0.0-beta.10
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 +149 -44
- package/dist/commands/add-track-utils/adapter-utils.js +47 -31
- package/dist/commands/add-track-utils/track-config.js +5 -7
- package/dist/commands/add-track.js +31 -9
- package/dist/commands/admin-server/index.js +13 -5
- package/dist/commands/admin-server/utils.js +8 -6
- package/dist/commands/make-density/density-generator.js +180 -0
- package/dist/commands/make-density/index.js +139 -0
- package/dist/commands/make-pif/index.js +62 -27
- package/dist/commands/make-pif/pif-generator.js +98 -132
- package/dist/commands/shared/density.js +12 -0
- package/dist/commands/text-index/adapter-utils.js +17 -7
- package/dist/commands/text-index/aggregate.js +5 -5
- package/dist/commands/text-index/command.js +3 -1
- package/dist/commands/text-index/config-utils.js +7 -7
- package/dist/commands/text-index/indexing-utils.js +21 -49
- package/dist/commands/validate/configManifest.generated.js +4064 -1845
- package/dist/commands/validate/configSchema.generated.js +20400 -0
- package/dist/commands/validate/index.js +21 -5
- package/dist/commands/validate/liftConfig.js +34 -0
- package/dist/commands/validate/markRules/aggregateFieldName.js +9 -0
- package/dist/commands/validate/markRules/autoBin.js +27 -0
- package/dist/commands/validate/markRules/colorScale.js +244 -0
- package/dist/commands/validate/markRules/cssColorsLevel4.js +162 -0
- package/dist/commands/validate/markRules/jexlStrings.js +23 -0
- package/dist/commands/validate/markRules/markProblems.js +532 -0
- package/dist/commands/validate/markRules/markRuleFacts.js +6 -0
- package/dist/commands/validate/markRules/markSpecs.js +96 -0
- package/dist/commands/validate/markRules/markVocabulary.js +57 -0
- package/dist/commands/validate/markRules/shapeNameList.js +7 -0
- package/dist/commands/validate/markRules/stepChannels.js +55 -0
- package/dist/commands/validate/schemaValidate.js +425 -0
- package/dist/commands/validate/validateConfig.js +304 -259
- package/dist/index.js +5 -0
- package/dist/version.js +1 -1
- package/package.json +6 -10
- package/bin/run +0 -4
- package/bundle/index.js +0 -1569
- package/dist/commands/make-pif/cigar-utils.js +0 -67
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ or by using a script file.
|
|
|
13
13
|
|
|
14
14
|
A simple script that does not use @jbrowse/cli at all may just look like this
|
|
15
15
|
|
|
16
|
-
```
|
|
16
|
+
```js
|
|
17
17
|
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
|
|
18
18
|
// do something with config.tracks, config.assemblies, etc.
|
|
19
19
|
fs.writeFileSync('config.json', JSON.stringify(config, null, 2))
|
|
@@ -43,7 +43,7 @@ npx @jbrowse/cli create myfolder
|
|
|
43
43
|
It is likely preferable in most cases to install the tools globally with
|
|
44
44
|
`npm install @jbrowse/cli -g` however
|
|
45
45
|
|
|
46
|
-
```
|
|
46
|
+
```text
|
|
47
47
|
|
|
48
48
|
JBrowse CLI
|
|
49
49
|
|
|
@@ -59,6 +59,7 @@ COMMANDS
|
|
|
59
59
|
admin-server Start up a small admin server for JBrowse configuration
|
|
60
60
|
upgrade Upgrades JBrowse 2 to latest version
|
|
61
61
|
make-pif Creates pairwise indexed PAF (PIF), with bgzip and tabix
|
|
62
|
+
make-density Counts feature starts per bin into a bigWig density sidecar, with bedGraphToBigWig
|
|
62
63
|
sort-gff Sort a GFF/GTF for tabix: sort -k1,1 -k4,4n, header kept on top
|
|
63
64
|
sort-bed Sort a BED for tabix: sort -k1,1 -k2,2n, header kept on top
|
|
64
65
|
add-connection Add a connection to a JBrowse 2 configuration
|
|
@@ -77,7 +78,7 @@ Use "jbrowse <command> --help" for more information about a command.
|
|
|
77
78
|
|
|
78
79
|
## jbrowse create
|
|
79
80
|
|
|
80
|
-
```
|
|
81
|
+
```text
|
|
81
82
|
Downloads and installs the latest JBrowse 2 release
|
|
82
83
|
|
|
83
84
|
Usage: jbrowse create [localPath] [options]
|
|
@@ -122,7 +123,7 @@ $ jbrowse create --listVersions
|
|
|
122
123
|
|
|
123
124
|
## jbrowse add-assembly
|
|
124
125
|
|
|
125
|
-
```
|
|
126
|
+
```text
|
|
126
127
|
Add an assembly to a JBrowse 2 configuration
|
|
127
128
|
|
|
128
129
|
Usage: jbrowse add-assembly <sequence> [options]
|
|
@@ -241,7 +242,7 @@ $ jbrowse add-assembly GRCh38.fa --load copy --config '{"sequence":{"formatAbout
|
|
|
241
242
|
|
|
242
243
|
## jbrowse add-track
|
|
243
244
|
|
|
244
|
-
```
|
|
245
|
+
```text
|
|
245
246
|
Add a track to a JBrowse 2 configuration
|
|
246
247
|
|
|
247
248
|
Usage: jbrowse add-track <track> [options]
|
|
@@ -263,9 +264,9 @@ Options:
|
|
|
263
264
|
-a, --assemblyNames Assembly name or names for track as comma separated
|
|
264
265
|
string. For pairwise synteny tracks the order is
|
|
265
266
|
query,target (reverse of minimap2/nucmer argument
|
|
266
|
-
order); for
|
|
267
|
-
(
|
|
268
|
-
every assembly the file covers, in any order
|
|
267
|
+
order); for the multi-genome PAF adapters
|
|
268
|
+
(MultiGenomePAFAdapter/MultiGenomeIndexedPAFAdapter)
|
|
269
|
+
list every assembly the file covers, in any order
|
|
269
270
|
|
|
270
271
|
--category Optional comma separated string of categories to
|
|
271
272
|
group tracks
|
|
@@ -279,7 +280,7 @@ Options:
|
|
|
279
280
|
displayDefaults
|
|
280
281
|
|
|
281
282
|
--displayDefaults Inline JSON merged into the track displayDefaults
|
|
282
|
-
(labels, mouseover,
|
|
283
|
+
(labels, mouseover, filter, etc.)
|
|
283
284
|
|
|
284
285
|
--multiwig Build a MultiQuantitativeTrack from several BigWigs
|
|
285
286
|
(in place of the positional track arg): a
|
|
@@ -310,6 +311,11 @@ Options:
|
|
|
310
311
|
|
|
311
312
|
--bed2 Used only for mcscan anchors/simpleAnchors types
|
|
312
313
|
|
|
314
|
+
--density Path or URL of a features-per-bin bigWig (jbrowse
|
|
315
|
+
make-density) to attach as the adapter's
|
|
316
|
+
densityAdapter. A local <file>.density.bw beside
|
|
317
|
+
the track file is attached without this flag
|
|
318
|
+
|
|
313
319
|
Notes:
|
|
314
320
|
|
|
315
321
|
--load controls how the data file is placed relative to config.json: copy, move,
|
|
@@ -329,7 +335,7 @@ text-index.
|
|
|
329
335
|
JSON. Wrap the value in single quotes and use double quotes inside a jexl
|
|
330
336
|
callback so nothing needs escaping, e.g. --color
|
|
331
337
|
'jexl:feature.strand==1?"blue":"red"'. --displayDefaults takes inline JSON for
|
|
332
|
-
any other appearance setting (labels, mouseover,
|
|
338
|
+
any other appearance setting (labels, mouseover, filter).
|
|
333
339
|
|
|
334
340
|
--multiwig bundles several BigWigs into one MultiQuantitativeTrack, in place of
|
|
335
341
|
the positional track argument: pass a comma-separated list of BigWig files/URLs,
|
|
@@ -337,11 +343,18 @@ or a .json file with an array of BigWig locations or subadapter objects (each
|
|
|
337
343
|
carrying its own name/color/group). With --load, local list entries are copied
|
|
338
344
|
like any other track file.
|
|
339
345
|
|
|
346
|
+
--density attaches a features-per-bin bigWig (jbrowse make-density) as the
|
|
347
|
+
adapter's densityAdapter, the band a display draws where the region is too large
|
|
348
|
+
to fetch features. A local <file>.density.bw beside the track file is attached
|
|
349
|
+
without the flag; a URL cannot be probed, so a remote sidecar needs it. The
|
|
350
|
+
adapters carrying the slot are BamAdapter, CramAdapter, HtsgetBamAdapter,
|
|
351
|
+
Gff3TabixAdapter, GtfTabixAdapter, BedTabixAdapter, BigBedAdapter,
|
|
352
|
+
VcfTabixAdapter and SplitVcfTabixAdapter.
|
|
353
|
+
|
|
340
354
|
For pairwise synteny adapters (PAF/Delta/Chain) --assemblyNames is query,target
|
|
341
|
-
— the reverse of the minimap2/nucmer input order. For the
|
|
342
|
-
(
|
|
343
|
-
assemblies the file covers, in any order
|
|
344
|
-
pair.
|
|
355
|
+
— the reverse of the minimap2/nucmer input order. For the multi-genome PAF
|
|
356
|
+
adapters (MultiGenomePAFAdapter, MultiGenomeIndexedPAFAdapter) it is instead the
|
|
357
|
+
full list of assemblies the file covers, in any order.
|
|
345
358
|
|
|
346
359
|
Examples:
|
|
347
360
|
|
|
@@ -371,12 +384,15 @@ $ jbrowse add-track --multiwig a.bw,b.bw,c.bw --load copy --name "Coverage"
|
|
|
371
384
|
|
|
372
385
|
# ...or from a sources.json carrying per-row name/color for each BigWig
|
|
373
386
|
$ jbrowse add-track --multiwig sources.json --name "CATlas ATAC"
|
|
387
|
+
|
|
388
|
+
# attach a remote density sidecar (a local genes.gff3.density.bw needs no flag)
|
|
389
|
+
$ jbrowse add-track https://mywebsite.com/genes.gff3.gz --density https://mywebsite.com/genes.gff3.density.bw
|
|
374
390
|
```
|
|
375
391
|
|
|
376
392
|
|
|
377
393
|
## jbrowse validate
|
|
378
394
|
|
|
379
|
-
```
|
|
395
|
+
```text
|
|
380
396
|
Check a JBrowse configuration for errors, including the ones JBrowse itself
|
|
381
397
|
accepts silently
|
|
382
398
|
|
|
@@ -397,19 +413,35 @@ nothing. That is what this command is mainly for.
|
|
|
397
413
|
|
|
398
414
|
Two levels are reported:
|
|
399
415
|
|
|
400
|
-
error JBrowse
|
|
401
|
-
slot, a
|
|
416
|
+
error JBrowse silently does the wrong thing, or refuses to load it — an
|
|
417
|
+
unknown slot, a key a defaultSession view or display does not
|
|
418
|
+
declare, a track naming an assembly the config never defines, a
|
|
402
419
|
defaultSession naming a trackId that does not exist, a duplicate
|
|
403
420
|
trackId. Exits 1.
|
|
404
421
|
|
|
405
422
|
warning JBrowse will complain by itself on load, or handles it — a type name
|
|
406
423
|
the core plugins do not register (expected if one of your plugins
|
|
407
|
-
registers it), or a legacy key a migration rewrites
|
|
408
|
-
the run.
|
|
424
|
+
registers it), or a legacy key a migration rewrites, such as a view
|
|
425
|
+
nesting its settings under "init". Never fails the run.
|
|
426
|
+
|
|
427
|
+
A LinearMarkDisplay loads whenever its keys and value types are right and says
|
|
428
|
+
what it cannot draw in a corner notice rather than refusing the track. This
|
|
429
|
+
command runs the display's own rule list over every "marks" list in the file: an
|
|
430
|
+
error where a mark draws nothing, never draws or a step cannot run, and a
|
|
431
|
+
warning where a slot waits unread or the marks draw in an arrangement the author
|
|
432
|
+
may not have meant. With --json each finding carries the stable "rule" id of the
|
|
433
|
+
rule that made it.
|
|
409
434
|
|
|
410
435
|
Types registered by plugins are not known to this command, so they come through
|
|
411
436
|
as warnings rather than errors.
|
|
412
437
|
|
|
438
|
+
The same checks are published as a JSON Schema at
|
|
439
|
+
https://jbrowse.org/jb2/schema/v5/config.json: a "$schema" line naming it at the
|
|
440
|
+
top of a config.json gives an editor completion and validation for every slot.
|
|
441
|
+
This command runs that schema first, then the cross-references a schema cannot
|
|
442
|
+
express — a trackId a session names that no track defines, an assembly a track
|
|
443
|
+
names that none defines.
|
|
444
|
+
|
|
413
445
|
Examples:
|
|
414
446
|
|
|
415
447
|
# check the config.json in the current directory
|
|
@@ -426,7 +458,7 @@ $ jbrowse validate config.json --json
|
|
|
426
458
|
|
|
427
459
|
## jbrowse text-index
|
|
428
460
|
|
|
429
|
-
```
|
|
461
|
+
```text
|
|
430
462
|
Make a text-indexing file for any given track(s).
|
|
431
463
|
|
|
432
464
|
Usage: jbrowse text-index [options]
|
|
@@ -499,7 +531,8 @@ GtfAdapter, GtfTabixAdapter, VcfAdapter, VcfTabixAdapter) are indexed; tracks
|
|
|
499
531
|
with other adapter types are skipped automatically.
|
|
500
532
|
|
|
501
533
|
GTF has no Name/ID attributes, so the default --attributes also match their GTF
|
|
502
|
-
spellings (gene_name, transcript_name, gene_id, transcript_id).
|
|
534
|
+
spellings (gene_name, transcript_name, gene_id, transcript_id). A GFF3 row with
|
|
535
|
+
no Name, as in GENCODE, is named by its own gene_name or transcript_name.
|
|
503
536
|
|
|
504
537
|
--exclude names types not to index; --include names the only types to index.
|
|
505
538
|
Reach for --include when the file draws from a vocabulary you do not control: an
|
|
@@ -536,7 +569,7 @@ $ jbrowse text-index --file myfile.gff3.gz --file myfile.vcfgz --out indexes
|
|
|
536
569
|
|
|
537
570
|
## jbrowse admin-server
|
|
538
571
|
|
|
539
|
-
```
|
|
572
|
+
```text
|
|
540
573
|
Start up a small admin server for JBrowse configuration
|
|
541
574
|
|
|
542
575
|
Usage: jbrowse admin-server [options]
|
|
@@ -547,6 +580,9 @@ Options:
|
|
|
547
580
|
-p, --port Specified port to start the server on (default:
|
|
548
581
|
9090)
|
|
549
582
|
|
|
583
|
+
--host Interface to bind to (default: 127.0.0.1). Use
|
|
584
|
+
0.0.0.0 to accept connections from other machines
|
|
585
|
+
|
|
550
586
|
--root Path to the root of the JB2 installation
|
|
551
587
|
|
|
552
588
|
--bodySizeLimit Size limit of the update message (default: 25mb)
|
|
@@ -554,9 +590,10 @@ Options:
|
|
|
554
590
|
Notes:
|
|
555
591
|
|
|
556
592
|
The admin-server lets a browser session write changes back to config.json on
|
|
557
|
-
disk, authorized by a one-time key printed in the startup URL. It
|
|
558
|
-
|
|
559
|
-
|
|
593
|
+
disk, authorized by a one-time key printed in the startup URL. It binds to
|
|
594
|
+
127.0.0.1 so only this machine can reach it. The key gates the config routes,
|
|
595
|
+
but the rest of the JBrowse directory is served unauthenticated, so widen --host
|
|
596
|
+
only on a trusted network.
|
|
560
597
|
|
|
561
598
|
Examples:
|
|
562
599
|
|
|
@@ -571,12 +608,15 @@ $ jbrowse admin-server --root /path/to/jb2/
|
|
|
571
608
|
|
|
572
609
|
# raise the body size limit for very large config updates
|
|
573
610
|
$ jbrowse admin-server --bodySizeLimit 100mb
|
|
611
|
+
|
|
612
|
+
# accept connections from other machines on the network
|
|
613
|
+
$ jbrowse admin-server --host 0.0.0.0
|
|
574
614
|
```
|
|
575
615
|
|
|
576
616
|
|
|
577
617
|
## jbrowse upgrade
|
|
578
618
|
|
|
579
|
-
```
|
|
619
|
+
```text
|
|
580
620
|
Upgrades JBrowse 2 to latest version
|
|
581
621
|
|
|
582
622
|
Usage: jbrowse upgrade [localPath] [options]
|
|
@@ -624,7 +664,7 @@ $ jbrowse upgrade --nightly
|
|
|
624
664
|
|
|
625
665
|
## jbrowse make-pif
|
|
626
666
|
|
|
627
|
-
```
|
|
667
|
+
```text
|
|
628
668
|
creates pairwise indexed PAF (PIF), with bgzip and tabix
|
|
629
669
|
|
|
630
670
|
Usage: jbrowse make-pif <file> [options]
|
|
@@ -637,16 +677,22 @@ Options:
|
|
|
637
677
|
|
|
638
678
|
--csi Create a CSI index for the PIF file instead of TBI
|
|
639
679
|
|
|
640
|
-
--coarse
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
680
|
+
--coarse Accuracy bound (bp) of the coarse tier. A coarse
|
|
681
|
+
row replaces its CIGAR with a coarse CIGAR (cr:Z:)
|
|
682
|
+
that keeps every indel longer than half this length
|
|
683
|
+
and folds the rest into runs, each run staying
|
|
684
|
+
within this many bp of the real alignment. Defaults
|
|
685
|
+
to 10000. The coarse tier (prefix T/Q) is emitted
|
|
686
|
+
alongside the per-row CIGAR fine tier by default so
|
|
687
|
+
whole-genome synteny views can auto-switch to it;
|
|
688
|
+
pass --no-coarse to omit it.
|
|
689
|
+
|
|
690
|
+
--no-coarse Do not emit the coarse tier; write only the per-row
|
|
691
|
+
CIGAR fine tier.
|
|
647
692
|
|
|
648
|
-
--
|
|
649
|
-
|
|
693
|
+
--threads Compression threads for bgzip. Defaults to 4. Raise
|
|
694
|
+
it on a machine with cores to spare, or set 1 to
|
|
695
|
+
leave the rest of the machine alone.
|
|
650
696
|
|
|
651
697
|
Notes:
|
|
652
698
|
|
|
@@ -666,17 +712,76 @@ $ jbrowse make-pif input.paf --out output.pif.gz
|
|
|
666
712
|
# use a CSI index for assemblies with chromosomes longer than ~512 Mb
|
|
667
713
|
$ jbrowse make-pif input.paf --csi
|
|
668
714
|
|
|
669
|
-
#
|
|
670
|
-
$ jbrowse make-pif input.paf --coarse
|
|
715
|
+
# a looser coarse tier: runs within 50kb of the alignment, indels over 25kb kept
|
|
716
|
+
$ jbrowse make-pif input.paf --coarse 50000
|
|
671
717
|
|
|
672
718
|
# emit only the per-row CIGAR fine tier, skipping the coarse tier
|
|
673
719
|
$ jbrowse make-pif input.paf --no-coarse
|
|
720
|
+
|
|
721
|
+
# give bgzip more (or fewer) compression threads than the default 4
|
|
722
|
+
$ jbrowse make-pif input.paf --threads 8
|
|
674
723
|
```
|
|
675
724
|
|
|
676
725
|
|
|
677
|
-
## jbrowse
|
|
726
|
+
## jbrowse make-density
|
|
727
|
+
|
|
728
|
+
```text
|
|
729
|
+
Counts feature starts per bin into a bigWig, the density sidecar a track draws
|
|
730
|
+
where the region is too large to fetch its features
|
|
731
|
+
|
|
732
|
+
Usage: jbrowse make-density <file> [options]
|
|
733
|
+
|
|
734
|
+
Options:
|
|
735
|
+
-h, --help Show help
|
|
736
|
+
|
|
737
|
+
--bin Width of each bin, in bp [default: 1000]
|
|
738
|
+
|
|
739
|
+
--chrom-sizes Two-column reference name and length table for the
|
|
740
|
+
assembly the file is on
|
|
741
|
+
|
|
742
|
+
--assembly FASTA of the assembly the file is on; its .fai
|
|
743
|
+
supplies the reference lengths, in place of
|
|
744
|
+
--chrom-sizes
|
|
745
|
+
|
|
746
|
+
--out Where to write the bigWig. Defaults to
|
|
747
|
+
<file>.density.bw beside the input, which is where
|
|
748
|
+
add-track looks for it
|
|
749
|
+
|
|
750
|
+
Notes:
|
|
751
|
+
|
|
752
|
+
The sidecar is attached to a track through its adapter's densityAdapter slot,
|
|
753
|
+
which BamAdapter, CramAdapter, HtsgetBamAdapter, Gff3TabixAdapter,
|
|
754
|
+
GtfTabixAdapter, BedTabixAdapter, BigBedAdapter, VcfTabixAdapter and
|
|
755
|
+
SplitVcfTabixAdapter declare. add-track attaches it on its own when the default
|
|
756
|
+
<file>.density.bw sits beside the track file, so building it before adding the
|
|
757
|
+
track is all it takes; --density attaches one by path or URL.
|
|
758
|
+
|
|
759
|
+
GFF3 counts only top-level features — a line whose attributes carry no Parent= —
|
|
760
|
+
so a gene is one count rather than one per exon. GTF, BED and VCF have no parent
|
|
761
|
+
link to follow, so every record counts.
|
|
762
|
+
|
|
763
|
+
BAM and CRAM are out of scope: read depth is not feature density, and the tools
|
|
764
|
+
that compute it already write bigWig. Point add-track --density at what they
|
|
765
|
+
produce.
|
|
766
|
+
|
|
767
|
+
Requires bedGraphToBigWig (UCSC) on the PATH.
|
|
768
|
+
|
|
769
|
+
Examples:
|
|
770
|
+
|
|
771
|
+
# writes genes.gff3.density.bw beside the input, in 1kb bins
|
|
772
|
+
$ jbrowse make-density genes.gff3.gz --chrom-sizes hg38.chrom.sizes
|
|
773
|
+
|
|
774
|
+
# take the reference lengths from the assembly FASTA index instead
|
|
775
|
+
$ jbrowse make-density variants.vcf.gz --assembly hg38.fa
|
|
678
776
|
|
|
777
|
+
# coarser bins, and a name of your own
|
|
778
|
+
$ jbrowse make-density genes.gff3.gz --assembly hg38.fa --bin 10000 --out genes.10kb.bw
|
|
679
779
|
```
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
## jbrowse sort-gff
|
|
783
|
+
|
|
784
|
+
```text
|
|
680
785
|
Sort a GFF or GTF for tabix — the two share a refname/start column layout. It is
|
|
681
786
|
`sort -k1,1 -k4,4n` with LC_ALL=C and a tab separator, plus every line starting
|
|
682
787
|
with # kept at the top rather than sorted into the data. Takes a file, or the
|
|
@@ -704,7 +809,7 @@ $ tabix -p gff sorted.gtf.gz
|
|
|
704
809
|
|
|
705
810
|
## jbrowse sort-bed
|
|
706
811
|
|
|
707
|
-
```
|
|
812
|
+
```text
|
|
708
813
|
Sort a BED file for tabix. It is `sort -k1,1 -k2,2n` with LC_ALL=C and a tab
|
|
709
814
|
separator, plus every line starting with # kept at the top rather than sorted
|
|
710
815
|
into the data. Takes a file, or the same data on stdin
|
|
@@ -726,7 +831,7 @@ $ tabix sorted.bed.gz
|
|
|
726
831
|
|
|
727
832
|
## jbrowse add-connection
|
|
728
833
|
|
|
729
|
-
```
|
|
834
|
+
```text
|
|
730
835
|
Add a connection to a JBrowse 2 configuration
|
|
731
836
|
|
|
732
837
|
Usage: jbrowse add-connection <connectionUrlOrPath> [options]
|
|
@@ -782,7 +887,7 @@ $ jbrowse add-connection https://mysite.com/path/to/hub.txt --connectionId newId
|
|
|
782
887
|
|
|
783
888
|
## jbrowse add-track-json
|
|
784
889
|
|
|
785
|
-
```
|
|
890
|
+
```text
|
|
786
891
|
Add a track configuration directly from a JSON hunk to the JBrowse 2
|
|
787
892
|
configuration
|
|
788
893
|
|
|
@@ -825,7 +930,7 @@ $ jbrowse add-track-json track.json --out /path/to/jb2/
|
|
|
825
930
|
|
|
826
931
|
## jbrowse remove-track
|
|
827
932
|
|
|
828
|
-
```
|
|
933
|
+
```text
|
|
829
934
|
Remove a track configuration from a JBrowse 2 configuration. Be aware that this
|
|
830
935
|
can cause crashes in saved sessions that refer to this track!
|
|
831
936
|
|
|
@@ -854,7 +959,7 @@ $ jbrowse remove-track my_track_id --target /path/to/jb2/config.json
|
|
|
854
959
|
|
|
855
960
|
## jbrowse set-default-session
|
|
856
961
|
|
|
857
|
-
```
|
|
962
|
+
```text
|
|
858
963
|
Set a default session with views and tracks
|
|
859
964
|
|
|
860
965
|
Usage: jbrowse set-default-session [options]
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { adapterTypesToTrackTypeMap, formats, matchFormat, resolveIndexType, trackTypeForAdapter, } from '@jbrowse/add-track-core';
|
|
2
|
+
import { adapterTypesToTrackTypeMap, formats, matchFormat, resolveIndexType, sidecarCandidateNames, trackTypeForAdapter, } from '@jbrowse/add-track-core';
|
|
3
|
+
import { isURL } from '../../types/common.js';
|
|
4
|
+
import { densitySidecarPath } from '../shared/density.js';
|
|
5
|
+
import { configManifest } from '../validate/configManifest.generated.js';
|
|
3
6
|
function hasLocField(spec) {
|
|
4
7
|
return 'locField' in spec;
|
|
5
8
|
}
|
|
@@ -9,24 +12,6 @@ for (const { spec } of formats) {
|
|
|
9
12
|
adapterTypeToSpec[spec.adapterType] = spec;
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
|
-
// What else the sidecar with this suffix can be named. `.csi` is htslib's
|
|
13
|
-
// alternative for a BAI or a TBI — required for a reference over 512 Mb, and
|
|
14
|
-
// written on request at any size. `stripped` is the form Picard and GATK write:
|
|
15
|
-
// `reads.bai` beside `reads.bam`, where samtools writes `reads.bam.bai`.
|
|
16
|
-
//
|
|
17
|
-
// Per-suffix because the alternatives are: a `.crai` has no CSI form, and
|
|
18
|
-
// stripping the extension off `calls.vcf.gz` would name `calls.vcf.tbi`, which
|
|
19
|
-
// nothing writes. A `.fai`/`.gzi` has neither and so is absent here.
|
|
20
|
-
//
|
|
21
|
-
// This is `indexCandidateNames` in `@jbrowse/core/util/indexCandidates`, which
|
|
22
|
-
// the add-track widget and jbrowse-img share and this CLI cannot import — it
|
|
23
|
-
// carries no `@jbrowse/core` dependency, so `npm i -g @jbrowse/cli` stays a CLI
|
|
24
|
-
// rather than a copy of the app. Change one, change the other.
|
|
25
|
-
const ALTERNATE_SPELLINGS = {
|
|
26
|
-
'.bai': { csi: true, stripped: true },
|
|
27
|
-
'.crai': { stripped: true },
|
|
28
|
-
'.tbi': { csi: true },
|
|
29
|
-
};
|
|
30
15
|
/**
|
|
31
16
|
* The sidecar actually sitting beside `location`, or the conventional name when
|
|
32
17
|
* none of the spellings is there — so a missing index still reports the file
|
|
@@ -35,22 +20,53 @@ const ALTERNATE_SPELLINGS = {
|
|
|
35
20
|
* Probed with `existsSync`, which is false for every candidate of a URL and so
|
|
36
21
|
* leaves a remote track with exactly the conventional guess it had before this
|
|
37
22
|
* existed. A remote `.csi` still wants `--indexFile`.
|
|
38
|
-
*
|
|
39
|
-
* The guard on the stripped spelling is load-bearing: `replace` hands back the
|
|
40
|
-
* subject unchanged when the pattern does not match, so `--adapterType
|
|
41
|
-
* BamAdapter` on a file named with no extension at all would offer the data
|
|
42
|
-
* file as its own index — and that file certainly exists.
|
|
43
23
|
*/
|
|
44
24
|
export function siblingSidecar(location, suffix) {
|
|
45
|
-
const
|
|
46
|
-
const strippedName = location.replace(/\.[^./\\]+$/, suffix);
|
|
47
|
-
const candidates = [
|
|
48
|
-
`${location}${suffix}`,
|
|
49
|
-
...(csi ? [`${location}.csi`] : []),
|
|
50
|
-
...(stripped && strippedName !== location ? [strippedName] : []),
|
|
51
|
-
];
|
|
25
|
+
const candidates = sidecarCandidateNames(location, suffix);
|
|
52
26
|
return candidates.find(c => fs.existsSync(c)) ?? candidates[0];
|
|
53
27
|
}
|
|
28
|
+
// The adapters that declare a `densityAdapter` slot, read off the generated
|
|
29
|
+
// manifest `jbrowse validate` uses. The hand-written list missed `GWASAdapter`,
|
|
30
|
+
// which inherits the slot through `bedTabixConfigSchema` instead of spreading
|
|
31
|
+
// `densityAdapterConfigSchemaFields`, so `--density` on a Pan-UKBB file was
|
|
32
|
+
// refused by a message that listed nine adapters and not the tenth.
|
|
33
|
+
const densityAdapterTypes = new Set(Object.entries(configManifest.adapters)
|
|
34
|
+
.filter(([, entry]) => entry.slots.some(s => s.name === 'densityAdapter'))
|
|
35
|
+
.map(([name]) => name)
|
|
36
|
+
.sort());
|
|
37
|
+
/**
|
|
38
|
+
* The adapter with its density sidecar attached, and the local file to load
|
|
39
|
+
* beside the config when there is one.
|
|
40
|
+
*
|
|
41
|
+
* An explicit `--density` is taken as given, since a URL cannot be probed;
|
|
42
|
+
* otherwise the conventional `<file>.density.bw` counts only when it is
|
|
43
|
+
* actually there, the way `siblingSidecar` probes an index.
|
|
44
|
+
*/
|
|
45
|
+
export function withDensityAdapter({ adapter, location, density, makeLocation, }) {
|
|
46
|
+
const supported = densityAdapterTypes.has(adapter.type);
|
|
47
|
+
if (density !== undefined && !supported) {
|
|
48
|
+
throw new Error(`--density has no slot on ${adapter.type}. The adapters carrying a density sidecar are: ${[...densityAdapterTypes].join(', ')}`);
|
|
49
|
+
}
|
|
50
|
+
const probed = location !== undefined && fs.existsSync(densitySidecarPath(location))
|
|
51
|
+
? densitySidecarPath(location)
|
|
52
|
+
: undefined;
|
|
53
|
+
if (probed !== undefined && !supported) {
|
|
54
|
+
console.warn(`Warning: ${probed} sits beside the track file but ${adapter.type} has no densityAdapter slot, so it is not attached. The adapters carrying one are indexed: bgzip and tabix the file, then add it.`);
|
|
55
|
+
}
|
|
56
|
+
const file = density === undefined ? (supported ? probed : undefined) : density;
|
|
57
|
+
return file === undefined
|
|
58
|
+
? { adapter }
|
|
59
|
+
: {
|
|
60
|
+
adapter: {
|
|
61
|
+
...adapter,
|
|
62
|
+
densityAdapter: {
|
|
63
|
+
type: 'BigWigAdapter',
|
|
64
|
+
bigWigLocation: makeLocation(file),
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
file: isURL(file) ? undefined : file,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
54
70
|
// builds the adapter object and the list of source files for a spec in one
|
|
55
71
|
// place, so the config it writes and the files add-track copies can never drift
|
|
56
72
|
function buildFromSpec(spec, { location, index, bed1, bed2, makeLocation }) {
|
|
@@ -29,10 +29,8 @@ export function buildTrackConfig({ trackType, trackId, name, assemblyNames, cate
|
|
|
29
29
|
// nothing was supplied, so the track omits displayDefaults entirely.
|
|
30
30
|
//
|
|
31
31
|
// Takes `trackType` so it can refuse a key none of that track's displays
|
|
32
|
-
// declares
|
|
33
|
-
//
|
|
34
|
-
// key with a console warning, and the command otherwise wrote the dead setting
|
|
35
|
-
// and exited 0.
|
|
32
|
+
// declares: expandTrackConfigShorthand drops an unmatched key with a console
|
|
33
|
+
// warning, and the command otherwise wrote the dead setting and exited 0.
|
|
36
34
|
export function mergeDisplayDefaults({ configObj, color, height, displayDefaults, trackType, }) {
|
|
37
35
|
const fromJson = displayDefaults
|
|
38
36
|
? parseJsonFlag(displayDefaults, '--displayDefaults')
|
|
@@ -56,9 +54,9 @@ export function mergeDisplayDefaults({ configObj, color, height, displayDefaults
|
|
|
56
54
|
// An unknown track type accepts everything: it is a plugin's, and this manifest
|
|
57
55
|
// is only the core plugins'.
|
|
58
56
|
//
|
|
59
|
-
// The message names the display
|
|
60
|
-
//
|
|
61
|
-
//
|
|
57
|
+
// The message names the display where the track offers exactly one, and the
|
|
58
|
+
// track otherwise: the keys checked are the union over its displays, so
|
|
59
|
+
// naming one of several would send the reader to look in the wrong place.
|
|
62
60
|
function checkDisplayDefaultKeys(merged, trackType) {
|
|
63
61
|
const { displayTypes, keys } = displayDefaultsForTrackType(trackType);
|
|
64
62
|
if (keys.length === 0) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { parseArgs } from 'node:util';
|
|
3
3
|
import { printHelp, readConfigFile, resolveConfigPath } from '../utils.js';
|
|
4
|
-
import { guessTrack, guessTrackType, makeLocationProtocol, } from './add-track-utils/adapter-utils.js';
|
|
4
|
+
import { guessTrack, guessTrackType, makeLocationProtocol, withDensityAdapter, } from './add-track-utils/adapter-utils.js';
|
|
5
5
|
import { loadFiles } from './add-track-utils/file-operations.js';
|
|
6
6
|
import { buildMultiWiggle } from './add-track-utils/multiwig.js';
|
|
7
7
|
import { addSyntenyAssemblyNames, buildTrackConfig, mapLocationForFiles, mergeDisplayDefaults, } from './add-track-utils/track-config.js';
|
|
@@ -39,7 +39,7 @@ export async function run(args) {
|
|
|
39
39
|
assemblyNames: {
|
|
40
40
|
type: 'string',
|
|
41
41
|
short: 'a',
|
|
42
|
-
description: 'Assembly name or names for track as comma separated string. For pairwise synteny tracks the order is query,target (reverse of minimap2/nucmer argument order); for
|
|
42
|
+
description: 'Assembly name or names for track as comma separated string. For pairwise synteny tracks the order is query,target (reverse of minimap2/nucmer argument order); for the multi-genome PAF adapters (MultiGenomePAFAdapter/MultiGenomeIndexedPAFAdapter) list every assembly the file covers, in any order',
|
|
43
43
|
},
|
|
44
44
|
category: {
|
|
45
45
|
type: 'string',
|
|
@@ -59,7 +59,7 @@ export async function run(args) {
|
|
|
59
59
|
},
|
|
60
60
|
displayDefaults: {
|
|
61
61
|
type: 'string',
|
|
62
|
-
description: 'Inline JSON merged into the track displayDefaults (labels, mouseover,
|
|
62
|
+
description: 'Inline JSON merged into the track displayDefaults (labels, mouseover, filter, etc.)',
|
|
63
63
|
},
|
|
64
64
|
multiwig: {
|
|
65
65
|
type: 'string',
|
|
@@ -104,6 +104,10 @@ export async function run(args) {
|
|
|
104
104
|
type: 'string',
|
|
105
105
|
description: 'Used only for mcscan anchors/simpleAnchors types',
|
|
106
106
|
},
|
|
107
|
+
density: {
|
|
108
|
+
type: 'string',
|
|
109
|
+
description: "Path or URL of a features-per-bin bigWig (jbrowse make-density) to attach as the adapter's densityAdapter. A local <file>.density.bw beside the track file is attached without this flag",
|
|
110
|
+
},
|
|
107
111
|
};
|
|
108
112
|
const { values: flags, positionals } = parseArgs({
|
|
109
113
|
args,
|
|
@@ -128,17 +132,23 @@ export async function run(args) {
|
|
|
128
132
|
'a jexl callback so nothing needs escaping, e.g. ' +
|
|
129
133
|
'--color \'jexl:feature.strand==1?"blue":"red"\'. --displayDefaults takes ' +
|
|
130
134
|
'inline JSON for any other appearance setting (labels, mouseover, ' +
|
|
131
|
-
'
|
|
135
|
+
'filter).\n\n' +
|
|
132
136
|
'--multiwig bundles several BigWigs into one MultiQuantitativeTrack, in ' +
|
|
133
137
|
'place of the positional track argument: pass a comma-separated list of ' +
|
|
134
138
|
'BigWig files/URLs, or a .json file with an array of BigWig locations or ' +
|
|
135
139
|
'subadapter objects (each carrying its own name/color/group). With --load, ' +
|
|
136
140
|
'local list entries are copied like any other track file.\n\n' +
|
|
141
|
+
'--density attaches a features-per-bin bigWig (jbrowse make-density) as the ' +
|
|
142
|
+
"adapter's densityAdapter, the band a display draws where the region is too " +
|
|
143
|
+
'large to fetch features. A local <file>.density.bw beside the track file is ' +
|
|
144
|
+
'attached without the flag; a URL cannot be probed, so a remote sidecar needs ' +
|
|
145
|
+
'it. The adapters carrying the slot are BamAdapter, CramAdapter, ' +
|
|
146
|
+
'HtsgetBamAdapter, Gff3TabixAdapter, GtfTabixAdapter, BedTabixAdapter, ' +
|
|
147
|
+
'BigBedAdapter, VcfTabixAdapter and SplitVcfTabixAdapter.\n\n' +
|
|
137
148
|
'For pairwise synteny adapters (PAF/Delta/Chain) --assemblyNames is ' +
|
|
138
149
|
'query,target — the reverse of the minimap2/nucmer input order. For the ' +
|
|
139
|
-
'
|
|
140
|
-
'instead the full list of assemblies the file covers, in any order
|
|
141
|
-
'one all-vs-all file backs every pair.';
|
|
150
|
+
'multi-genome PAF adapters (MultiGenomePAFAdapter, MultiGenomeIndexedPAFAdapter) it is ' +
|
|
151
|
+
'instead the full list of assemblies the file covers, in any order.';
|
|
142
152
|
const examples = [
|
|
143
153
|
'# copy /path/to/my.bam and /path/to/my.bam.bai to current directory and adds track to config.json',
|
|
144
154
|
'$ jbrowse add-track /path/to/my.bam --load copy',
|
|
@@ -166,6 +176,9 @@ export async function run(args) {
|
|
|
166
176
|
'',
|
|
167
177
|
'# ...or from a sources.json carrying per-row name/color for each BigWig',
|
|
168
178
|
'$ jbrowse add-track --multiwig sources.json --name "CATlas ATAC"',
|
|
179
|
+
'',
|
|
180
|
+
'# attach a remote density sidecar (a local genes.gff3.density.bw needs no flag)',
|
|
181
|
+
'$ jbrowse add-track https://mywebsite.com/genes.gff3.gz --density https://mywebsite.com/genes.gff3.density.bw',
|
|
169
182
|
];
|
|
170
183
|
if (flags.help) {
|
|
171
184
|
printHelp({
|
|
@@ -187,7 +200,7 @@ export async function run(args) {
|
|
|
187
200
|
const mapLocation = (p) => wrap(mapLocationForFiles(p, load, subDir));
|
|
188
201
|
// build the adapter (and the set of files to load) up front, so the track-arg
|
|
189
202
|
// and load validation runs before we touch the config on disk
|
|
190
|
-
const { adapter, files, trackType, trackId } = multiwig
|
|
203
|
+
const { adapter: builtAdapter, files, trackType, trackId, } = multiwig
|
|
191
204
|
? buildMultiWiggleTrack({
|
|
192
205
|
sources: multiwig,
|
|
193
206
|
mapLocation,
|
|
@@ -207,6 +220,15 @@ export async function run(args) {
|
|
|
207
220
|
trackType: flags.trackType,
|
|
208
221
|
trackId: flags.trackId,
|
|
209
222
|
});
|
|
223
|
+
const { adapter, file: densityFile } = withDensityAdapter({
|
|
224
|
+
adapter: builtAdapter,
|
|
225
|
+
location,
|
|
226
|
+
density: flags.density,
|
|
227
|
+
makeLocation: mapLocation,
|
|
228
|
+
});
|
|
229
|
+
if (densityFile !== undefined && !load) {
|
|
230
|
+
throw new Error(`--density names a local file (${densityFile}); pass --load to say how it is placed beside the config`);
|
|
231
|
+
}
|
|
210
232
|
const baseConfigObj = config ? parseConfigFlag(config) : undefined;
|
|
211
233
|
const displayDefaults = mergeDisplayDefaults({
|
|
212
234
|
configObj: baseConfigObj,
|
|
@@ -245,7 +267,7 @@ export async function run(args) {
|
|
|
245
267
|
});
|
|
246
268
|
const updatedConfig = { ...configContents, tracks };
|
|
247
269
|
await loadFiles({
|
|
248
|
-
files,
|
|
270
|
+
files: [...files, densityFile],
|
|
249
271
|
destDir: configDir,
|
|
250
272
|
mode: load,
|
|
251
273
|
subDir,
|