Skip to content

Commit

Permalink
Add status callback while parsing .delta (MUMmer), .chain (liftover) …
Browse files Browse the repository at this point in the history
…and PIF files (#4856)
  • Loading branch information
cmdcolin authored Feb 20, 2025
1 parent ecef89d commit 836122e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 41 deletions.
11 changes: 10 additions & 1 deletion plugins/comparative-adapters/src/ChainAdapter/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* SOFTWARE.
*/

import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter'

function generate_record(
qname: string,
qstart: number,
Expand Down Expand Up @@ -51,7 +53,8 @@ function generate_record(
}
}

export function paf_chain2paf(buffer: Uint8Array) {
export function paf_chain2paf(buffer: Uint8Array, opts?: BaseOptions) {
const { statusCallback = () => {} } = opts || {}
let t_name = ''
let t_start = 0
let t_end = 0
Expand All @@ -64,9 +67,15 @@ export function paf_chain2paf(buffer: Uint8Array) {
let cigar = ''
const records = []

let i = 0
let blockStart = 0
const decoder = new TextDecoder('utf8')
while (blockStart < buffer.length) {
if (i++ % 10_000 === 0) {
statusCallback(
`Loading ${Math.floor(blockStart / 1_000_000).toLocaleString('en-US')}/${Math.floor(buffer.length / 1_000_000).toLocaleString('en-US')} MB`,
)
}
const n = buffer.indexOf(10, blockStart)
if (n === -1) {
break
Expand Down
11 changes: 10 additions & 1 deletion plugins/comparative-adapters/src/DeltaAdapter/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter/BaseOptions'

/* paf2delta from paftools.js in the minimap2 repository, license reproduced below
*
* The MIT License
Expand Down Expand Up @@ -26,7 +28,8 @@
* SOFTWARE.
*/

export function paf_delta2paf(buffer: Uint8Array) {
export function paf_delta2paf(buffer: Uint8Array, opts?: BaseOptions) {
const { statusCallback = () => {} } = opts || {}
let rname = ''
let qname = ''
let qs = 0
Expand All @@ -45,8 +48,14 @@ export function paf_delta2paf(buffer: Uint8Array) {

let blockStart = 0
let i = 0
let j = 0
const decoder = new TextDecoder('utf8')
while (blockStart < buffer.length) {
if (j++ % 10_000 === 0) {
statusCallback(
`Loading ${Math.floor(blockStart / 1_000_000).toLocaleString('en-US')}/${Math.floor(buffer.length / 1_000_000).toLocaleString('en-US')} MB`,
)
}
const n = buffer.indexOf(10, blockStart)
if (n === -1) {
break
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TabixIndexedFile } from '@gmod/tabix'
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
import { updateStatus } from '@jbrowse/core/util'
import { openLocation } from '@jbrowse/core/util/io'
import { ObservableCreate } from '@jbrowse/core/util/rxjs'

Expand Down Expand Up @@ -77,6 +78,7 @@ export default class PAFAdapter extends BaseFeatureDataAdapter {
}

getFeatures(query: Region, opts: PAFOptions = {}) {
const { statusCallback = () => {} } = opts
return ObservableCreate<Feature>(async observer => {
const { assemblyName } = query

Expand All @@ -85,45 +87,47 @@ export default class PAFAdapter extends BaseFeatureDataAdapter {
const flip = index === 0
const letter = flip ? 'q' : 't'

await this.pif.getLines(letter + query.refName, query.start, query.end, {
lineCallback: (line, fileOffset) => {
const r = parsePAFLine(line)
const refName = r.qname.slice(1)
const start = r.qstart
const end = r.qend
const mateName = r.tname
const mateStart = r.tstart
const mateEnd = r.tend

const { extra, strand } = r
const { numMatches = 0, blockLen = 1, cg, ...rest } = extra

observer.next(
new SyntenyFeature({
uniqueId: fileOffset + assemblyName,
assemblyName,
start,
end,
type: 'match',
refName,
strand,
...rest,
CIGAR: extra.cg,
syntenyId: fileOffset,
identity: numMatches / blockLen,
numMatches,
blockLen,
mate: {
start: mateStart,
end: mateEnd,
refName: mateName,
assemblyName: assemblyNames[+flip],
},
}),
)
},
stopToken: opts.stopToken,
})
await updateStatus('Downloading features', statusCallback, () =>
this.pif.getLines(letter + query.refName, query.start, query.end, {
lineCallback: (line, fileOffset) => {
const r = parsePAFLine(line)
const refName = r.qname.slice(1)
const start = r.qstart
const end = r.qend
const mateName = r.tname
const mateStart = r.tstart
const mateEnd = r.tend

const { extra, strand } = r
const { numMatches = 0, blockLen = 1, cg, ...rest } = extra

observer.next(
new SyntenyFeature({
uniqueId: fileOffset + assemblyName,
assemblyName,
start,
end,
type: 'match',
refName,
strand,
...rest,
CIGAR: extra.cg,
syntenyId: fileOffset,
identity: numMatches / blockLen,
numMatches,
blockLen,
mate: {
start: mateStart,
end: mateEnd,
refName: mateName,
assemblyName: assemblyNames[+flip],
},
}),
)
},
stopToken: opts.stopToken,
}),
)

observer.complete()
})
Expand Down

0 comments on commit 836122e

Please sign in to comment.