diff --git a/plugins/alignments/src/BamAdapter/BamAdapter.ts b/plugins/alignments/src/BamAdapter/BamAdapter.ts index 33788a5c3f..8fad3a00ce 100644 --- a/plugins/alignments/src/BamAdapter/BamAdapter.ts +++ b/plugins/alignments/src/BamAdapter/BamAdapter.ts @@ -189,6 +189,8 @@ export default class BamAdapter extends BaseFeatureDataAdapter { readName, } = filterBy || {} + let hits = 0 + let nohits = 0 for (const record of records) { let ref: string | undefined if (!record.tags.MD) { @@ -224,14 +226,18 @@ export default class BamAdapter extends BaseFeatureDataAdapter { // features in the cache have pre-computed mismatches objects that // can be re-used across blocks const ret = this.featureCache.get(`${record.id}`) + if (!ret) { + nohits++ const elt = new BamSlightlyLazyFeature(record, this, ref) this.featureCache.set(`${record.id}`, elt) observer.next(elt) } else { + hits++ observer.next(ret) } } + console.log({ hits, nohits }) observer.complete() }) }, signal) diff --git a/plugins/alignments/src/BamAdapter/BamSlightlyLazyFeature.ts b/plugins/alignments/src/BamAdapter/BamSlightlyLazyFeature.ts index c85a6ccaa2..012a8760e4 100644 --- a/plugins/alignments/src/BamAdapter/BamSlightlyLazyFeature.ts +++ b/plugins/alignments/src/BamAdapter/BamSlightlyLazyFeature.ts @@ -5,9 +5,12 @@ import { import { BamRecord } from '@gmod/bam' // locals -import { getMismatches } from '../MismatchParser' +import { getMismatches, parseCigar } from '../MismatchParser' import BamAdapter from './BamAdapter' import { cacheGetter } from '../shared/util' +import { getTagAlt } from '../util' +import { getModPositions, getModProbabilities } from '../ModificationParser' +import { getMaxProbModAtEachPosition } from '../shared/getMaximumModificationAtEachPosition' export default class BamSlightlyLazyFeature implements Feature { // uses parameter properties to automatically create fields on the class @@ -31,6 +34,10 @@ export default class BamSlightlyLazyFeature implements Feature { ) } + get modifications() { + return getMaxProbModAtEachPosition(this) + } + get qual() { return this.record.qual?.join(' ') } @@ -40,7 +47,9 @@ export default class BamSlightlyLazyFeature implements Feature { ? this.mismatches : field === 'qual' ? this.qual - : this.fields[field] + : field === 'modifications' + ? this.modifications + : this.fields[field] } parent() { @@ -88,3 +97,4 @@ export default class BamSlightlyLazyFeature implements Feature { cacheGetter(BamSlightlyLazyFeature, 'fields') cacheGetter(BamSlightlyLazyFeature, 'mismatches') +cacheGetter(BamSlightlyLazyFeature, 'modifications') diff --git a/plugins/alignments/src/CramAdapter/CramAdapter.ts b/plugins/alignments/src/CramAdapter/CramAdapter.ts index 97a3eeec56..ca00a592ff 100644 --- a/plugins/alignments/src/CramAdapter/CramAdapter.ts +++ b/plugins/alignments/src/CramAdapter/CramAdapter.ts @@ -245,7 +245,8 @@ export default class CramAdapter extends BaseFeatureDataAdapter { tagFilter, readName, } = filterBy || {} - + let hits = 0 + let nohits = 0 for (const record of records) { const flags = record.flags if ((flags & flagInclude) !== flagInclude && !(flags & flagExclude)) { @@ -275,13 +276,16 @@ export default class CramAdapter extends BaseFeatureDataAdapter { // can be re-used across blocks const ret = this.featureCache.get(`${record.uniqueId}`) if (!ret) { + nohits++ const elt = this.cramRecordToFeature(record) this.featureCache.set(`${record.uniqueId}`, elt) observer.next(elt) } else { + hits++ observer.next(ret) } } + console.log({ nohits, hits }) observer.complete() }) diff --git a/plugins/alignments/src/CramAdapter/CramSlightlyLazyFeature.ts b/plugins/alignments/src/CramAdapter/CramSlightlyLazyFeature.ts index 354ff92b3f..8efbd46871 100644 --- a/plugins/alignments/src/CramAdapter/CramSlightlyLazyFeature.ts +++ b/plugins/alignments/src/CramAdapter/CramSlightlyLazyFeature.ts @@ -7,6 +7,7 @@ import { readFeaturesToCIGAR, readFeaturesToMismatches } from './util' import { parseCigar } from '../MismatchParser' import { mdToMismatches } from '../MismatchParser/mdToMismatches' import { cacheGetter } from '../shared/util' +import { getMaxProbModAtEachPosition } from '../shared/getMaximumModificationAtEachPosition' export default class CramSlightlyLazyFeature implements Feature { // uses parameter properties to automatically create fields on the class @@ -112,7 +113,9 @@ export default class CramSlightlyLazyFeature implements Feature { ? this.qual : field === 'CIGAR' ? this.CIGAR - : this.fields[field] + : field === 'modifications' + ? this.modifications + : this.fields[field] } parent() { @@ -142,6 +145,11 @@ export default class CramSlightlyLazyFeature implements Feature { : mismatches } + get modifications() { + console.log('here') + return getMaxProbModAtEachPosition(this) + } + get fields(): SimpleFeatureSerialized { return { start: this.start, @@ -177,3 +185,4 @@ export default class CramSlightlyLazyFeature implements Feature { cacheGetter(CramSlightlyLazyFeature, 'fields') cacheGetter(CramSlightlyLazyFeature, 'CIGAR') cacheGetter(CramSlightlyLazyFeature, 'mismatches') +cacheGetter(CramSlightlyLazyFeature, 'modifications') diff --git a/plugins/alignments/src/PileupRenderer/renderAlignment.ts b/plugins/alignments/src/PileupRenderer/renderAlignment.ts index 0795f10a11..682d176772 100644 --- a/plugins/alignments/src/PileupRenderer/renderAlignment.ts +++ b/plugins/alignments/src/PileupRenderer/renderAlignment.ts @@ -88,7 +88,6 @@ export function renderAlignment({ bpPerPx, renderArgs, canvasWidth, - cigarOps, }) break } diff --git a/plugins/alignments/src/PileupRenderer/renderModifications.ts b/plugins/alignments/src/PileupRenderer/renderModifications.ts index 8214180a57..43a7708976 100644 --- a/plugins/alignments/src/PileupRenderer/renderModifications.ts +++ b/plugins/alignments/src/PileupRenderer/renderModifications.ts @@ -5,7 +5,7 @@ import { bpSpanPx, max, sum } from '@jbrowse/core/util' import { fillRect, LayoutFeature } from './util' import { RenderArgsWithColor } from './makeImageData' import { alphaColor } from '../shared/util' -import { getMaxProbModAtEachPosition } from '../shared/getMaximumModificationAtEachPosition' +import { MaximumProbabilityMod } from '../shared/getMaximumModificationAtEachPosition' // render modifications stored in MM tag in BAM export function renderModifications({ @@ -15,7 +15,6 @@ export function renderModifications({ bpPerPx, renderArgs, canvasWidth, - cigarOps, }: { ctx: CanvasRenderingContext2D feat: LayoutFeature @@ -23,7 +22,6 @@ export function renderModifications({ bpPerPx: number renderArgs: RenderArgsWithColor canvasWidth: number - cigarOps: string[] }) { const { feature, topPx, heightPx } = feat const { colorBy, visibleModifications = {} } = renderArgs @@ -37,7 +35,7 @@ export function renderModifications({ const isolatedModification = colorBy?.modifications?.isolatedModification const twoColor = colorBy?.modifications?.twoColor - getMaxProbModAtEachPosition(feature, cigarOps)?.forEach( + ;(feature.get('modifications') as MaximumProbabilityMod[])?.forEach( ({ allProbs, prob, type }, pos) => { const r = start + pos const [leftPx, rightPx] = bpSpanPx(r, r + 1, region, bpPerPx) diff --git a/plugins/alignments/src/SNPCoverageAdapter/generateCoverageBins.ts b/plugins/alignments/src/SNPCoverageAdapter/generateCoverageBins.ts index 95e6cfe0b7..a16da77592 100644 --- a/plugins/alignments/src/SNPCoverageAdapter/generateCoverageBins.ts +++ b/plugins/alignments/src/SNPCoverageAdapter/generateCoverageBins.ts @@ -11,7 +11,7 @@ import { PreBaseCoverageBinSubtypes, SkipMap, } from '../shared/types' -import { getMaxProbModAtEachPosition } from '../shared/getMaximumModificationAtEachPosition' +import { MaximumProbabilityMod } from '../shared/getMaxProbModAtEachPosition' function mismatchLen(mismatch: Mismatch) { return !isInterbase(mismatch.type) ? mismatch.length : 1 @@ -282,7 +282,8 @@ function processModification({ const fend = feature.get('end') const twoColor = colorBy?.modifications?.twoColor const isolatedModification = colorBy?.modifications?.isolatedModification - getMaxProbModAtEachPosition(feature)?.forEach( + + ;(feature.get('modifications') as MaximumProbabilityMod[])?.forEach( ({ type, prob, allProbs }, pos) => { if (isolatedModification && type !== isolatedModification) { return diff --git a/plugins/alignments/src/shared/getMaximumModificationAtEachPosition.ts b/plugins/alignments/src/shared/getMaximumModificationAtEachPosition.ts index 14603e94fd..3be4adbe54 100644 --- a/plugins/alignments/src/shared/getMaximumModificationAtEachPosition.ts +++ b/plugins/alignments/src/shared/getMaximumModificationAtEachPosition.ts @@ -4,7 +4,7 @@ import { getModPositions, getModProbabilities } from '../ModificationParser' import { getNextRefPos, parseCigar } from '../MismatchParser' import { getTagAlt } from '../util' -interface MaximumProbabilityMod { +export interface MaximumProbabilityMod { type: string prob: number allProbs: number[]