From 87dc7ab3aa013b4b6a009a1c82df71e80fc1fed5 Mon Sep 17 00:00:00 2001 From: Colin Diesh Date: Fri, 21 Oct 2022 15:46:10 -0600 Subject: [PATCH] Remove unnecessary expanded region query and small optimizations+performance improvements for alignments tracks (#3279) --- .../renderers/BoxRendererType.ts | 6 +- .../core/util/layouts/GranularRectLayout.ts | 109 ++++++--------- packages/core/util/layouts/MultiLayout.ts | 12 +- .../alignments/src/BamAdapter/BamAdapter.ts | 78 +++++------ .../alignments/src/CramAdapter/CramAdapter.ts | 132 +++++++++--------- .../src/HtsgetBamAdapter/HtsgetBamAdapter.ts | 37 +++-- .../src/PileupRenderer/PileupRenderer.tsx | 14 +- ...-features-test-tsx-color-by-tag-1-snap.png | Bin 22372 -> 22133 bytes ...eloads-alignments-track-bam-404-1-snap.png | Bin 6769 -> 5541 bytes ...loads-alignments-track-crai-404-1-snap.png | Bin 6769 -> 5541 bytes .../tests/__image_snapshots__/snapshot.svg | 2 +- ...mation-pileup-force-load-to-see-1-snap.png | Bin 75940 -> 75047 bytes ...stimation-pileup-zoom-in-to-see-1-snap.png | Bin 48583 -> 47788 bytes .../__snapshots__/ExportSvg.test.tsx.snap | 2 +- 14 files changed, 182 insertions(+), 210 deletions(-) diff --git a/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts b/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts index 90fbdb57e5..fae674fc81 100644 --- a/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts +++ b/packages/core/pluggableElementTypes/renderers/BoxRendererType.ts @@ -1,7 +1,12 @@ import deepEqual from 'fast-deep-equal' + +// layouts import GranularRectLayout from '../../util/layouts/GranularRectLayout' import MultiLayout from '../../util/layouts/MultiLayout' +import { SerializedLayout, BaseLayout } from '../../util/layouts/BaseLayout' import PrecomputedLayout from '../../util/layouts/PrecomputedLayout' + +// other import FeatureRendererType, { RenderArgs as FeatureRenderArgs, RenderArgsSerialized as FeatureRenderArgsSerialized, @@ -11,7 +16,6 @@ import FeatureRendererType, { ResultsDeserialized as FeatureResultsDeserialized, } from './FeatureRendererType' import { getLayoutId, Region, Feature } from '../../util' -import { SerializedLayout, BaseLayout } from '../../util/layouts/BaseLayout' import { readConfObject, AnyConfigurationModel } from '../../configuration' import SerializableFilterChain from './util/serializableFilterChain' import RpcManager from '../../rpc/RpcManager' diff --git a/packages/core/util/layouts/GranularRectLayout.ts b/packages/core/util/layouts/GranularRectLayout.ts index 340395baa0..b94193f08e 100644 --- a/packages/core/util/layouts/GranularRectLayout.ts +++ b/packages/core/util/layouts/GranularRectLayout.ts @@ -34,30 +34,19 @@ interface RowState { } // a single row in the layout class LayoutRow { - private padding: number + private padding = 1 private allFilled?: Record | string - private widthLimit: number + private widthLimit = 1_000_000 private rowState?: RowState - constructor() { - this.padding = 1 - this.widthLimit = 1000000 - - // this.rowState.offset is the offset of the bits array relative to the genomic coordinates - // (modified by pitchX, but we don't know that in this class) - // this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset) - // this.rowState.min is the leftmost edge of all the rectangles we have in the layout - // this.rowState.max is the rightmost edge of all the rectangles we have in the layout - } - - // log(msg: string): void { - // // if (this.rowNumber === 0) - // // eslint-disable-next-line no-console - // console.log(`r${this.rowNumber}: ${msg}`) - // } + // this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset) + // this.rowState.min is the leftmost edge of all the rectangles we have in the layout + // this.rowState.max is the rightmost edge of all the rectangles we have in the layout + // this.rowState.offset is the offset of the bits array relative to the genomic coordinates + // (modified by pitchX, but we don't know that in this class) setAllFilled(data: Record | string): void { this.allFilled = data @@ -67,56 +56,42 @@ class LayoutRow { if (this.allFilled) { return this.allFilled } - if (!this.rowState) { - return undefined - } - - if (this.rowState.min === undefined) { - return undefined - } - if (x < this.rowState.min) { - return undefined - } - if (x >= this.rowState.max) { + if ( + this.rowState?.min === undefined || + x < this.rowState.min || + x >= this.rowState.max + ) { return undefined } - const offset = x - this.rowState.offset - // if (offset < 0) - // debugger - // if (offset >= this.rowState.bits.length) - // debugger - return this.rowState.bits[offset] + return this.rowState.bits[x - this.rowState.offset] } - isRangeClear(left: number, right: number): boolean { + isRangeClear(left: number, right: number) { if (this.allFilled) { return false } - if (!this.rowState) { - return true - } - - const { min, max } = this.rowState - - if (right <= min || left >= max) { + if ( + this.rowState === undefined || + right <= this.rowState.min || + left >= this.rowState.max + ) { return true } + const { min, max, offset, bits } = this.rowState - // TODO: check right and middle before looping - const maxX = Math.min(max, right) - let x = Math.max(min, left) - for (; x < right && x < maxX; x += 1) { - if (this.getItemAt(x)) { - return false - } + const maxX = Math.min(max, right) - offset + let flag = true + for (let x = Math.max(min, left) - offset; x < maxX && flag; x++) { + flag = bits[x] === undefined } - return true + return flag } + // NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are + // interbase coordinates initialize(left: number, right: number): RowState { - // NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are interbase coordinates const rectWidth = right - left return { offset: left - rectWidth, @@ -124,7 +99,6 @@ class LayoutRow { max: right, bits: new Array(3 * rectWidth), } - // this.log(`initialize ${this.rowState.min} - ${this.rowState.max} (${this.rowState.bits.length})`) } addRect(rect: Rectangle, data: Record | string): void { @@ -415,13 +389,13 @@ export default class GranularRectLayout implements BaseLayout { return top * this.pitchY } - collides(rect: Rectangle, top: number): boolean { + collides(rect: Rectangle, top: number) { const { bitmap } = this const maxY = top + rect.h for (let y = top; y < maxY; y += 1) { const row = bitmap[y] - if (row && !row.isRangeClear(rect.l, rect.r)) { + if (row !== undefined && !row.isRangeClear(rect.l, rect.r)) { return true } } @@ -432,7 +406,7 @@ export default class GranularRectLayout implements BaseLayout { /** * make a subarray if it does not exist */ - private autovivifyRow(bitmap: LayoutRow[], y: number): LayoutRow { + private autovivifyRow(bitmap: LayoutRow[], y: number) { let row = bitmap[y] if (!row) { if (y > this.hardRowLimit) { @@ -448,7 +422,7 @@ export default class GranularRectLayout implements BaseLayout { return row } - addRectToBitmap(rect: Rectangle): void { + addRectToBitmap(rect: Rectangle) { if (rect.top === null) { return } @@ -475,7 +449,7 @@ export default class GranularRectLayout implements BaseLayout { * Given a range of X coordinates, deletes all data dealing with * the features. */ - discardRange(left: number, right: number): void { + discardRange(left: number, right: number) { // console.log( 'discard', left, right ); const pLeft = Math.floor(left / this.pitchX) const pRight = Math.floor(right / this.pitchX) @@ -488,11 +462,11 @@ export default class GranularRectLayout implements BaseLayout { } } - hasSeen(id: string): boolean { + hasSeen(id: string) { return this.rectangles.has(id) } - getByCoord(x: number, y: number): Record | string | undefined { + getByCoord(x: number, y: number) { const pY = Math.floor(y / this.pitchY) const row = this.bitmap[pY] if (!row) { @@ -502,23 +476,28 @@ export default class GranularRectLayout implements BaseLayout { return row.getItemAt(pX) } - getByID(id: string): RectTuple | undefined { + getByID(id: string) { const r = this.rectangles.get(id) if (r) { const t = (r.top as number) * this.pitchY - return [r.l * this.pitchX, t, r.r * this.pitchX, t + r.originalHeight] + return [ + r.l * this.pitchX, + t, + r.r * this.pitchX, + t + r.originalHeight, + ] as RectTuple } return undefined } - getDataByID(id: string): unknown { + getDataByID(id: string) { return this.rectangles.get(id)?.data } - cleanup(): void {} + cleanup() {} - getTotalHeight(): number { + getTotalHeight() { return this.pTotalHeight * this.pitchY } diff --git a/packages/core/util/layouts/MultiLayout.ts b/packages/core/util/layouts/MultiLayout.ts index 7c037871f1..f8c87066ff 100644 --- a/packages/core/util/layouts/MultiLayout.ts +++ b/packages/core/util/layouts/MultiLayout.ts @@ -4,8 +4,6 @@ import { BaseLayout, SerializedLayout } from './BaseLayout' export default class MultiLayout, T> { subLayouts: Map = new Map() - subLayoutConstructorArgs: Record = {} - /** * layout class that just keeps a number of named sub-layouts. * basically just a fancier @@ -13,11 +11,8 @@ export default class MultiLayout, T> { */ constructor( public SubLayoutClass: new (...args: any[]) => SUB_LAYOUT_CLASS, - layoutArgs: Record = {}, - ) { - this.subLayouts = new Map() - this.subLayoutConstructorArgs = layoutArgs - } + public subLayoutConstructorArgs: Record = {}, + ) {} getDataByID(id: string): unknown { for (const layout of this.subLayouts.values()) { @@ -53,8 +48,7 @@ export default class MultiLayout, T> { } discardRange(layoutName: string, left: number, right: number) { - const layout = this.subLayouts.get(layoutName) - return layout && layout.discardRange(left, right) + return this.subLayouts.get(layoutName)?.discardRange(left, right) } toJSON() { diff --git a/plugins/alignments/src/BamAdapter/BamAdapter.ts b/plugins/alignments/src/BamAdapter/BamAdapter.ts index 7e312345df..d35c2107d0 100644 --- a/plugins/alignments/src/BamAdapter/BamAdapter.ts +++ b/plugins/alignments/src/BamAdapter/BamAdapter.ts @@ -9,7 +9,6 @@ import { openLocation } from '@jbrowse/core/util/io' import { ObservableCreate } from '@jbrowse/core/util/rxjs' import { Feature } from '@jbrowse/core/util/simpleFeature' import { toArray } from 'rxjs/operators' -import { readConfObject } from '@jbrowse/core/configuration' import BamSlightlyLazyFeature from './BamSlightlyLazyFeature' interface Header { @@ -21,51 +20,52 @@ export default class BamAdapter extends BaseFeatureDataAdapter { private samHeader?: Header private setupP?: Promise
- - protected configured?: Promise<{ + private configureP?: Promise<{ bam: BamFile sequenceAdapter?: BaseFeatureDataAdapter }> // derived classes may not use the same configuration so a custom // configure method allows derived classes to override this behavior - protected async configure() { - if (!this.configured) { - const bamLocation = readConfObject(this.config, 'bamLocation') - const location = readConfObject(this.config, ['index', 'location']) - const indexType = readConfObject(this.config, ['index', 'indexType']) - const bam = new BamFile({ - bamFilehandle: openLocation(bamLocation, this.pluginManager), - csiFilehandle: - indexType === 'CSI' - ? openLocation(location, this.pluginManager) - : undefined, - baiFilehandle: - indexType !== 'CSI' - ? openLocation(location, this.pluginManager) - : undefined, - - // chunkSizeLimit and fetchSizeLimit are more troublesome than - // helpful, and have given overly large values on the ultra long - // nanopore reads even with 500MB limits, so disabled with infinity - chunkSizeLimit: Infinity, - fetchSizeLimit: Infinity, - yieldThreadTime: Infinity, - }) + protected async configurePre() { + const bamLocation = this.getConf('bamLocation') + const location = this.getConf(['index', 'location']) + const indexType = this.getConf(['index', 'indexType']) + const pm = this.pluginManager + const csi = indexType === 'CSI' + const bam = new BamFile({ + bamFilehandle: openLocation(bamLocation, pm), + csiFilehandle: csi ? openLocation(location, pm) : undefined, + baiFilehandle: !csi ? openLocation(location, pm) : undefined, + + // chunkSizeLimit and fetchSizeLimit are more troublesome than + // helpful, and have given overly large values on the ultra long + // nanopore reads even with 500MB limits, so disabled with infinity + chunkSizeLimit: Infinity, + fetchSizeLimit: Infinity, + yieldThreadTime: Infinity, + }) - const adapterConfig = readConfObject(this.config, 'sequenceAdapter') - if (adapterConfig && this.getSubAdapter) { - this.configured = this.getSubAdapter(adapterConfig).then( - ({ dataAdapter }) => ({ - bam, - sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, - }), - ) - } else { - this.configured = Promise.resolve({ bam }) + const adapterConfig = this.getConf('sequenceAdapter') + if (adapterConfig && this.getSubAdapter) { + const { dataAdapter } = await this.getSubAdapter(adapterConfig) + return { + bam, + sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, } + } else { + return { bam } + } + } + + protected async configure() { + if (!this.configureP) { + this.configureP = this.configurePre().catch(e => { + this.configureP = undefined + throw e + }) } - return this.configured + return this.configureP } async getHeader(opts?: BaseOptions) { @@ -231,7 +231,7 @@ export default class BamAdapter extends BaseFeatureDataAdapter { // @ts-ignore if (bam.index.filehandle !== '?') { const bytes = await bytesForRegions(regions, bam) - const fetchSizeLimit = readConfObject(this.config, 'fetchSizeLimit') + const fetchSizeLimit = this.getConf('fetchSizeLimit') return { bytes, fetchSizeLimit } } else { return super.estimateRegionsStats(regions, opts) @@ -241,7 +241,7 @@ export default class BamAdapter extends BaseFeatureDataAdapter { freeResources(/* { region } */): void {} // depends on setup being called before the BAM constructor - refIdToName(refId: number): string | undefined { + refIdToName(refId: number) { return this.samHeader?.idToName[refId] } } diff --git a/plugins/alignments/src/CramAdapter/CramAdapter.ts b/plugins/alignments/src/CramAdapter/CramAdapter.ts index 8f94becaeb..59d4a43154 100644 --- a/plugins/alignments/src/CramAdapter/CramAdapter.ts +++ b/plugins/alignments/src/CramAdapter/CramAdapter.ts @@ -2,6 +2,7 @@ import { CraiIndex, IndexedCramFile } from '@gmod/cram' import { BaseFeatureDataAdapter, BaseOptions, + BaseSequenceAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter' import { checkAbortSignal, Region, Feature } from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' @@ -33,7 +34,12 @@ export default class CramAdapter extends BaseFeatureDataAdapter { private setupP?: Promise<{ samHeader: Header cram: any // eslint-disable-line @typescript-eslint/no-explicit-any - sequenceAdapter: any // eslint-disable-line @typescript-eslint/no-explicit-any + sequenceAdapter: BaseSequenceAdapter + }> + + private configureP?: Promise<{ + cram: any // eslint-disable-line @typescript-eslint/no-explicit-any + sequenceAdapter: BaseSequenceAdapter }> // maps a refname to an id @@ -42,7 +48,7 @@ export default class CramAdapter extends BaseFeatureDataAdapter { // maps a seqId to original refname, passed specially to render args, to a seqid private seqIdToOriginalRefName: string[] = [] - public async configure() { + public async configurePre() { const cramLocation = this.getConf('cramLocation') const craiLocation = this.getConf('craiLocation') if (!cramLocation) { @@ -51,34 +57,38 @@ export default class CramAdapter extends BaseFeatureDataAdapter { if (!craiLocation) { throw new Error('missing craiLocation argument') } + const pm = this.pluginManager // eslint-disable-next-line @typescript-eslint/no-explicit-any const cram: any = new IndexedCramFile({ - cramFilehandle: openLocation(cramLocation, this.pluginManager), - index: new CraiIndex({ - filehandle: openLocation(craiLocation, this.pluginManager), - }), + cramFilehandle: openLocation(cramLocation, pm), + index: new CraiIndex({ filehandle: openLocation(craiLocation, pm) }), seqFetch: this.seqFetch.bind(this), checkSequenceMD5: false, fetchSizeLimit: 200_000_000, // just make this a large size to avoid hitting it }) - // instantiate the sequence adapter - const sequenceAdapterType = this.getConf(['sequenceAdapter', 'type']) if (!this.getSubAdapter) { throw new Error('Error getting subadapter') } const seqConf = this.getConf('sequenceAdapter') - const { dataAdapter: sequenceAdapter } = await this.getSubAdapter(seqConf) + const subadapter = await this.getSubAdapter(seqConf) - if (!(sequenceAdapter instanceof BaseFeatureDataAdapter)) { - throw new Error( - `CRAM feature adapters cannot use sequence adapters of type '${sequenceAdapterType}'`, - ) + return { + cram, + sequenceAdapter: subadapter.dataAdapter as BaseSequenceAdapter, } + } - return { cram, sequenceAdapter } + public async configure() { + if (!this.configureP) { + this.configureP = this.configurePre().catch(e => { + this.configureP = undefined + throw e + }) + } + return this.configureP } async getHeader(opts?: BaseOptions) { @@ -132,9 +142,9 @@ export default class CramAdapter extends BaseFeatureDataAdapter { private async setupPre(opts?: BaseOptions) { const { statusCallback = () => {} } = opts || {} - const configured = await this.configure() + const conf = await this.configure() statusCallback('Downloading index') - const { cram } = configured + const { cram } = conf const samHeader: HeaderLine[] = await cram.cram.getSamHeader(opts?.signal) // use the @SQ lines in the header to figure out the @@ -161,7 +171,7 @@ export default class CramAdapter extends BaseFeatureDataAdapter { const data = { idToName, nameToId, readGroups } statusCallback('') this.samHeader = data - return { samHeader: data, ...configured } + return { samHeader: data, ...conf } } private async setup(opts?: BaseOptions) { @@ -197,13 +207,7 @@ export default class CramAdapter extends BaseFeatureDataAdapter { // use info from the SAM header if possible, but fall back to using // the ref seq order from when the browser's refseqs were loaded refIdToName(refId: number) { - if (this.samHeader.idToName) { - return this.samHeader.idToName[refId] - } - if (this.seqIdToRefName) { - return this.seqIdToRefName[refId] - } - return undefined + return this.samHeader.idToName?.[refId] || this.seqIdToRefName?.[refId] } refIdToOriginalName(refId: number) { @@ -220,53 +224,53 @@ export default class CramAdapter extends BaseFeatureDataAdapter { const { refName, start, end, originalRefName } = region return ObservableCreate(async observer => { - const { cram, sequenceAdapter } = await this.setup(opts) - statusCallback('Downloading alignments') - if (!this.seqIdToRefName) { - this.seqIdToRefName = await sequenceAdapter.getRefNames(opts) - } + const { cram } = await this.setup(opts) + const refId = this.refNameToId(refName) - if (refId !== undefined) { - if (originalRefName) { - this.seqIdToOriginalRefName[refId] = originalRefName - } - const records = await cram.getRecordsForRange(refId, start, end, opts) - checkAbortSignal(signal) - const { - flagInclude = 0, - flagExclude = 0, - tagFilter, - readName, - } = filterBy || {} + if (refId === undefined) { + console.warn('Unknown refName', refName) + observer.complete() + return + } + + if (originalRefName) { + this.seqIdToOriginalRefName[refId] = originalRefName + } + statusCallback('Downloading alignments') + const records = await cram.getRecordsForRange(refId, start, end, opts) + checkAbortSignal(signal) + const { + flagInclude = 0, + flagExclude = 0, + tagFilter, + readName, + } = filterBy || {} + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let filtered = records.filter((record: any) => { + const flags = record.flags + return (flags & flagInclude) === flagInclude && !(flags & flagExclude) + }) + if (tagFilter) { // eslint-disable-next-line @typescript-eslint/no-explicit-any - let filtered = records.filter((record: any) => { - const flags = record.flags - return (flags & flagInclude) === flagInclude && !(flags & flagExclude) + filtered = filtered.filter((record: any) => { + const val = record[tagFilter.tag] + return val === '*' ? val !== undefined : val === tagFilter.value }) + } - if (tagFilter) { + if (readName) { + filtered = filtered.filter( // eslint-disable-next-line @typescript-eslint/no-explicit-any - filtered = filtered.filter((record: any) => { - const val = record[tagFilter.tag] - return val === '*' ? val !== undefined : val === tagFilter.value - }) - } - - if (readName) { - filtered = filtered.filter( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (record: any) => record.readName === readName, - ) - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - filtered.forEach((record: any) => { - observer.next(this.cramRecordToFeature(record)) - }) - } else { - console.warn('Unknown refName', refName) + (record: any) => record.readName === readName, + ) } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + filtered.forEach((record: any) => { + observer.next(this.cramRecordToFeature(record)) + }) statusCallback('') observer.complete() }, signal) diff --git a/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts b/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts index 5ae9382f06..7344b998fb 100644 --- a/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts +++ b/plugins/alignments/src/HtsgetBamAdapter/HtsgetBamAdapter.ts @@ -4,28 +4,23 @@ import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' import BamAdapter from '../BamAdapter/BamAdapter' export default class HtsgetBamAdapter extends BamAdapter { - protected async configure() { - if (!this.configured) { - const htsgetBase = readConfObject(this.config, 'htsgetBase') - const htsgetTrackId = readConfObject(this.config, 'htsgetTrackId') - const bam = new HtsgetFile({ - baseUrl: htsgetBase, - trackId: htsgetTrackId, - }) as unknown as BamFile + protected async configurePre() { + const htsgetBase = readConfObject(this.config, 'htsgetBase') + const htsgetTrackId = readConfObject(this.config, 'htsgetTrackId') + const bam = new HtsgetFile({ + baseUrl: htsgetBase, + trackId: htsgetTrackId, + }) as unknown as BamFile - const adapterConfig = readConfObject(this.config, 'sequenceAdapter') - if (adapterConfig && this.getSubAdapter) { - this.configured = this.getSubAdapter(adapterConfig).then( - ({ dataAdapter }) => { - return { - bam, - sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, - } - }, - ) - } - this.configured = Promise.resolve({ bam }) + const adapterConfig = readConfObject(this.config, 'sequenceAdapter') + if (adapterConfig && this.getSubAdapter) { + return this.getSubAdapter(adapterConfig).then(({ dataAdapter }) => { + return { + bam, + sequenceAdapter: dataAdapter as BaseFeatureDataAdapter, + } + }) } - return this.configured + return { bam } } } diff --git a/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx b/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx index a1cc8b9f9f..bf70107fd4 100644 --- a/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx +++ b/plugins/alignments/src/PileupRenderer/PileupRenderer.tsx @@ -150,7 +150,7 @@ export default class PileupRenderer extends BoxRendererType { // get width and height of chars the height is an approximation: width // letter M is approximately the height - getCharWidthHeight(ctx: CanvasRenderingContext2D) { + getCharWidthHeight() { const charWidth = measureText('A') const charHeight = measureText('M') - 2 return { charWidth, charHeight } @@ -237,11 +237,7 @@ export default class PileupRenderer extends BoxRendererType { const maxClippingSize = readConfObject(config, 'maxClippingSize') const { start, end } = region - const len = end - start - const bpExpansion = Math.max( - len, - showSoftClip ? Math.round(maxClippingSize) : 0, - ) + const bpExpansion = showSoftClip ? Math.round(maxClippingSize) : 0 return { // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit @@ -1058,7 +1054,7 @@ export default class PileupRenderer extends BoxRendererType { const minFeatWidth = readConfObject(config, 'minSubfeatureWidth') const mismatches: Mismatch[] = feature.get('mismatches') const seq = feature.get('seq') - const { charWidth, charHeight } = this.getCharWidthHeight(ctx) + const { charWidth, charHeight } = this.getCharWidthHeight() const { bases } = theme.palette const colorForBase: { [key: string]: string } = { A: bases.A.main, @@ -1161,7 +1157,7 @@ export default class PileupRenderer extends BoxRendererType { } ctx.font = 'bold 10px Courier New,monospace' - const { charWidth, charHeight } = this.getCharWidthHeight(ctx) + const { charWidth, charHeight } = this.getCharWidthHeight() const drawSNPsMuted = shouldDrawSNPsMuted(colorBy?.type) const drawIndels = shouldDrawIndels(colorBy?.type) for (let i = 0; i < layoutRecords.length; i++) { @@ -1271,13 +1267,13 @@ export default class PileupRenderer extends BoxRendererType { const features = await this.getFeatures(renderProps) const layout = this.createLayoutInWorker(renderProps) const { regions, bpPerPx } = renderProps + const [region] = regions const layoutRecords = this.layoutFeats({ ...renderProps, features, layout, }) - const [region] = regions // only need reference sequence if there are features and only for some // cases diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/alignments-features-test-tsx-color-by-tag-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/alignments-features-test-tsx-color-by-tag-1-snap.png index 27ad37fbebdb5d712c875401e7f64f4606e029ce..850d794f68da0c3251d299137aba8f8cc498fd24 100644 GIT binary patch literal 22133 zcma&O2Ut_t_C9=+QM@WJ84D`S2{R&sfP(ZkBZz{6f(X)ukzNEsuj(if1Vm{{RSYNy zi1ZSIN>PCzL3*ztgx(=QzIEc<-~X1m&+~2P3D3YjXSY?}^{%z^;Ig&`$L=G$5d`75 za9&LpL3XMl$hNUvJK;AX)4zAYkDZoU8fpj={g+D2c!D5Dkqc_SUG+|!>1H)GD|ms`%&MPd7b#`X~O@x6I?%-+ufl^h5j~*1c4&V!ao;etG)T zFZ*c|mBjdL)U+^qbN-FZ=Gb)+ef^lbc3$w(6hINB6|lJUiQT!tmP`XM=g< zu$O5;UD4Pbj(hfjWWnrf^gFk2-{v@b_H3?>aPNK_d7Wu5g}pY(e80`&++K}ppYU_TJSq(KzDWO3 zdjebPSz^w$ERJjX9)6m%+p}>T2;cF31vis#oMl38m8bWrz)^KwFjsTT&a|J}BO{&A zxIh$G`{EJD8O#}r9ePN?AaBLz??)|IVU;l$_88}F2r{64@*zGep>gc`@bGY)hlj`J zb@Eyw9l-q_W?I66~%#6JDW_o&B(w(f_Y$tv=7(p5^A%(iU z#pMSV+<1-3b|6Tw0eRM{{}B2ox7S$;X2l9M4#z6YK%Ok7C6H}Me2slwg|eCC+hb)M z=#=BFO#Z;)QekfMQgQ7{xe-ARes6J(HISQ+r6T{+xMBK&ah^g< z4$MCI=?!E%BB7zES3eiCBYU+tnwgE;15f0dXnuCuWK^*h(a9%QS(Liec;59lwT)Le zF8I6nNdm5Wb#>KPaLAotEFZpY*JL>_#!Ic5ODhDa>eI~fb;0L&JG|^LWUYvM$zRRH zD7U@ehjKwksl!&PFG;uTXobL9=;7e1N}rdl_Sw!-M{LFtb?|sUE%t5jhKxmJ-fV%S zBf{BX_+Ek^j2SP*i>W^nUc1ii{HC2Qow`Y%uJxA8*%JwzUA77 zo4@LgRSYx7A1k$WlYPt`XZVg^Z8<#cYk$Rr*_$TRUMI#IrV_O9aYxv=T7O`r(AKO& z-BjMxOq@zVKO^9ykn>-IX$>eSHc)!t?!sGsWSPt~vE94^4P5+y^G@{DzICYstpS zN~Jk`g}?ZUnH1MqiER#=*A>^2R7$r7KAdrFyR*;c4Mx7Xe@0exYkaPKGH+^-Ia~Pq z8Qdcq!J3JZ(BS(?E~k;_+}5f7PQ?n`UgYBKN_>Zrerp%yXO(*7hp~8L7ox{+`JEM~ zss0*jqQbo(UlKy2-a5E;{x4pUm07sm@XS4ot4Dt4#s}EOD+H^+FYw@_!NEa77`J$i z8#yi{B?u&p67kTeQm$Xp&1q{Wj!Tq}4Pl5-{o6ox+MYjup08D`=FPT$?9W8^%uIVH zvX8sk>SGRgY&i-$^uqA1!!JR0I3L;}B!0Wb%V=eD{Z@{^+6tzV7Vp?R^0z zDT2)*%ZVRHCs`G?-fBB)&Cgqkb<-wTAr`y+Q!_HC^{y+&Io{!NT*m$ZOwxiIvWyUt-E_)(3VTm8f4@T2eygo*xsJ z9_<-B&9WE)XY5}mUt2N52#-=uArd>Bd3kvJ9D;(FwYuAS37mTy5*MFvH_<~vLS`D| zf=**&W1L~Mqgbq)+J^pQBD23mp>N%UwJADdiQZav|1tqbW|ky}k8aH&!u&oIl39x4pTZFNtkClhD}hP7dP1 zXlcs8Bpc*}w}d^5#k4cpQ^bzM$pxv}W6^L3Y;u{msW)CM9TNQf}=YPaCiAHBs}DH&?l; zq8+4;yvBVLiJ3Y4S)6%1I8NGgGp5;hqxrMP%KQ_{_vL{OGoFugLh%XAfTVt2OuNnn z0ZAAC`q~bk`V67=!n9bmrhD{s%l4E9YvoMiBZoSa4=B+8NJ~o#iHM9062&TCF53~G z5W!5-S~mQr$GXg+H-&$YFx)XmiZ@Y-3;dNok!ipn_Q#c*&B2$*Qx!9mr@^qxM}dbxBseH`Q7s0jE7OX*c+Wb2t?yb^;Ti1MB6lSl zqAGOiU!)#}KQdA-I9mKtpC}V8_H_4>@1|s-k<)dxy|JhRG&{^%$%(0l(QP%EeUg;S zN)4^Li-gL`N)7tbdbi*ZC7ME}D1o|YNuuvf|8h3UT`=3oM_==`zPz>k%V;-111Y*j z7>u#j3T!bc9-ZS`lABuPv1AoTb)#Mxq5Ind0s^?4`YVZ1x@9M@)}wDhuH;R$u~WK2k&3R-!GoA@Fpv*G>x zKSdaN{B4ua*VWfAt-jqq`yf)Ssc7a>PBFlkjy{FU*d4(Em-|cYBbU6W*#YZ$vQ#BD zHZ~sXcY>(FQ!|lzQun8)%zuh-mIa0o?$UWk!DVf6q|Ec%8U% z*NfwSnR$Y$(eMeGC$VdM3AYuyO6O|z&ROW1Y2hv@<4HB z)+k%rP``COgx}XTkj9VL>V>F9I4sCJf5QzJ;NVhK--Vl?t`AfHqbL#OPEgp(+D=c-knT7gUk;7mm`>} zTKYvIX5-iGRXDk$1l&#VB}3_#5+a1rF;A#htLIs?pWmX4&x4ixddx&;yWR)nhhUng zZ}v66Tei02n}oASYWSvoftw^(gh`Z3+3PIuWd;9ee^M0)B5ZMtH&%E34}E=^UcVV) z7&_a8iHQ9{KWS8KRVtROg@b=cy~OH6+m$MbLL{`YK$PU*)5HZ7KKAHo%iYufTWhN~ z95t*n{COrZ@mlVxHTs)BN9HkX~+mMesH1^;4H$ z>3Q(a1uzKZU_|oUBHhUbQb)og)1!@8lNiOXW_8FhNf}-hOQrwp%v!B*oO_@IVG&-t z#jaV5sPgz>jcBCwmTP^w@;@M5_vjZaPQc71V%*gHCm)^VEOn$&2<5Dk(VWxCEBA1f zCvM^X{ba^9%Tt^Sjb;uXI@AH?5b5dw)BO%icNw_Aujlyf3XQl+l0j|$z6CEo&dmHm z5cIxTq)0mByjk3RtUdRs*B>UUnM{+n<1v2zD=WjfDeK)zMVsvgn;Ek9eGa=1oHFJ+ zcAY?y ziI=#F@WBdt@$Q3Hx>jSu^A=)tbaEUtPCiK9(|$nIQa7{_aMKr>q8i{Pe90+npKMay z?Z?ZbzH1$Gk+qn8%+sZTVnkv7#Gu}SGev3rJ@0UlODUwaL0Qj1!{^VIaT_`P5o`-2 z?Hp3?=5z0N^vOHwQ`Gg0tz(rW#)HpG^Y`j48=u=u%{a@*90|8mQaPt~Ro~-^nu$Vh z-L~|)rsVpRNqL1zcvgwOMXBWqBEg5+V!^sP!Jz^0re8UCLTJP#I}psJQ5_=qA`5jH z4N@Rw@3E`V2J5p8oh38z;!?x6LrV#i3+O7xU5f0dU8i=z|D~jKTMS73Zkm;Ds$o!_=0xKTn_5ezjE${ ze#gO+^>xHJKg7#Gz!U6wMZeW=NXUH1*BcFJY`J$HMR0%mw_GxH9dQ*1O=N1QHHZW5 zm`cseJc}Jl!?<2y^^>V&`z}!N9_U+l(R$p4D48(^>LX7Chv zm^mC+BE(h*eS0*{zW;nfe}EQpk?n9@%|8dCor1g3x)6P|k0$yF zT56%=9{-H|5F8QPSG2)S`_|{B5xNIE6vCS0;>t>phoj@0WcRHWd^`(s{tA(rgb3;# z)%aC@#`YVd8ufmnHLH%nVC3TQu)YLV{POqOgdpRh5UnWoveSGfo4r4p2jU`~`qz`{ zEhpoDZ3(bFo?hwR%1?Lk3Ob%VDPMk>Bfkc-Po^$!IOr4z>87TlEHiia!Kq?aOoJ2n zrC;*&6jeU{MAK#``--8sce{%^Ag5(}f&bEu^p}xjss9eRw|dDzYq*E~Bv&`3Zf4LX zgD<2;KxymQ=cPF%m53$*Mp8;Z$E}wS7ATpuGS*Vg&%z@j_~n(AxAO3-s&LlnO+!(a zTot!ge`ZEcsS&D`n!c6p9gVXoD^A=wFj4zQ$>hf}@JvP7+q6IBCXJ==V zHN|UXY#lP7rU)`cT|2)@#}l;9mWLax%9%yq^~8m-6OPj=7&j1OOp%!|FcS z!Ds#9Yyyn2k@W}b3d4iu=EiSreb<;vqkNqkzw@p%F}DJ`n)nuKy$2pgl1AJ&{C;&a z@j5p%6sBb}yO5a)AUBPmfD9aXc3yb1<~Me}#X7AxvEDPL?61E^8fD8W#+zfY1iv@p z{!>NXj4aRnnNNLtF_@M9Am)v7͛^4ezMCqe>Z(RQdJsP4w_zO`Y@T%e61?8;bb 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 diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-bam-404-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-bam-404-1-snap.png index 2ade875d3999219518ed7199eacdd04ddf5b7164..ea3817c5dc2f8739b944e942d677dac2f1345c6b 100644 GIT binary patch delta 53 zcmexpvQ&G57&pT!4mJh`hF{U0q7xNGm_(yCnum!>9N6&Jy6lbOPfO1iPk^!vp00i_ I>zopr0ONNOm;e9( delta 668 zcmZ3g{n2EC7&qev4mJh`hL4sj4JImzFiELxG!GM<9KggeibunM#%X|6{Pg$tPu42_ VbmF_S3z!HQJYD@<);T3K0RTrHpq>B# diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-crai-404-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/reload-test-tsx-reloads-alignments-track-crai-404-1-snap.png index 2ade875d3999219518ed7199eacdd04ddf5b7164..ea3817c5dc2f8739b944e942d677dac2f1345c6b 100644 GIT binary patch delta 53 zcmexpvQ&G57&pT!4mJh`hF{U0q7xNGm_(yCnum!>9N6&Jy6lbOPfO1iPk^!vp00i_ I>zopr0ONNOm;e9( delta 668 zcmZ3g{n2EC7&qev4mJh`hL4sj4JImzFiELxG!GM<9KggeibunM#%X|6{Pg$tPu42_ VbmF_S3z!HQJYD@<);T3K0RTrHpq>B# diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg b/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg index 735cd8c58b..04da9107e3 100644 --- a/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg +++ b/products/jbrowse-web/src/tests/__image_snapshots__/snapshot.svg @@ -1 +1 @@ -volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGCCATTGTCGGAAGT \ No newline at end of file +volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGC \ No newline at end of file diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-force-load-to-see-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-force-load-to-see-1-snap.png index 2741adbc2d885abc2c27251c00279c47375351ef..d9d7afcf907ab8fdfb55bf59ee07ff8f6cde2cd1 100644 GIT binary patch delta 5151 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 X4PEs_iccvu-$FW_M3f&r_uu~k{BFEU delta 5287 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 Tz!qQmN*zx+BPxD9|DXQ>VIUBW diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-zoom-in-to-see-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/stats-estimation-test-tsx-test-stats-estimation-pileup-zoom-in-to-see-1-snap.png index 164b55eeb2aab71cd819fc49630a5ef968037381..c89c51d64608cf9aff56fa7b0cb7f87abdec6342 100644 GIT binary patch delta 70 zcmV-M0J;Ci`vR=>0+1F90*D9(0000e_%>~^A-;$Kx3l1gix&uo(n|9H02(E;bD$v_ c81(S}14gj@Uk{rG+`RcgN4GdfGK=0W1_oJ&&BY58r6vn- z$Pt0X1pfSgd$18`8bgCZ{cAz76_Xh`bcxW2%Ww&?1eP@xf8$T;y_^U#)zj6_Wt~$( F699y%GLirQ diff --git a/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap b/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap index 4be5d104ac..14e2c9693b 100644 --- a/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap +++ b/products/jbrowse-web/src/tests/__snapshots__/ExportSvg.test.tsx.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`export svg 1`] = `"volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGCCATTGTCGGAAGT"`; +exports[`export svg 1`] = `"volvox80bpctgA020406080volvox-sorted.bam (ctgA, canvas)001111GTACAGAGTGACGCTCAAAGC"`;