Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Nov 18, 2024
1 parent ea97091 commit 510af3d
Show file tree
Hide file tree
Showing 9 changed files with 443 additions and 452 deletions.
29 changes: 18 additions & 11 deletions plugins/bed/src/BedAdapter/BedAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
} from '@jbrowse/core/data_adapters/BaseAdapter'
import { openLocation } from '@jbrowse/core/util/io'
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
import { Region, Feature, fetchAndMaybeUnzip } from '@jbrowse/core/util'
import {
Region,
Feature,
fetchAndMaybeUnzip,
SimpleFeature,
} from '@jbrowse/core/util'
import IntervalTree from '@flatten-js/interval-tree'

// locals
Expand Down Expand Up @@ -123,17 +128,19 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
const names = await this.getNames()

const intervalTree = new IntervalTree()
const ret = lines.map((f, i) => {
const ret = lines.map((line, i) => {
const uniqueId = `${this.id}-${refName}-${i}`
return featureData(
f,
colRef,
colStart,
colEnd,
scoreColumn,
parser,
uniqueId,
names,
return new SimpleFeature(
featureData({
line,
colRef,
colStart,
colEnd,
scoreColumn,
parser,
uniqueId,
names,
}),
)
})

Expand Down
30 changes: 17 additions & 13 deletions plugins/bed/src/BedTabixAdapter/BedTabixAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
} from '@jbrowse/core/data_adapters/BaseAdapter'
import { openLocation } from '@jbrowse/core/util/io'
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
import { FileLocation, Region, Feature } from '@jbrowse/core/util'
import {
FileLocation,
Region,
Feature,
SimpleFeature,
} from '@jbrowse/core/util'
import { TabixIndexedFile } from '@gmod/tabix'
import PluginManager from '@jbrowse/core/PluginManager'
import { AnyConfigurationModel } from '@jbrowse/core/configuration'
Expand Down Expand Up @@ -78,22 +83,21 @@ export default class BedTabixAdapter extends BaseFeatureDataAdapter {
const colRef = columnNumbers.ref - 1
const colStart = columnNumbers.start - 1
const colEnd = columnNumbers.end - 1
// colSame handles special case for tabix where a single column is both
// the start and end, this is assumed to be covering the base at this
// position (e.g. tabix -s 1 -b 2 -e 2) begin and end are same
const names = await this.getNames()
await this.bed.getLines(query.refName, query.start, query.end, {
lineCallback: (line, fileOffset) => {
observer.next(
featureData(
line,
colRef,
colStart,
colEnd,
this.scoreColumn,
this.parser,
`${this.id}-${fileOffset}`,
names,
new SimpleFeature(
featureData({
line,
colRef,
colStart,
colEnd,
scoreColumn: this.scoreColumn,
parser: this.parser,
uniqueId: `${this.id}-${fileOffset}`,
names,
}),
),
)
},
Expand Down
105 changes: 16 additions & 89 deletions plugins/bed/src/BigBedAdapter/BigBedAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,12 @@ import {
min,
Feature,
SimpleFeature,
SimpleFeatureSerializedNoId,
SimpleFeatureSerialized,
} from '@jbrowse/core/util'
import { firstValueFrom, Observer, toArray } from 'rxjs'

// locals
import {
isUcscTranscript,
generateUcscTranscript,
makeRepeatTrackDescription,
makeBlocks,
arrayify,
} from '../util'
import { featureData2 } from '../util'

export default class BigBedAdapter extends BaseFeatureDataAdapter {
private cachedP?: Promise<{
Expand Down Expand Up @@ -148,19 +142,14 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
}
}

const parentAggregation = {} as Record<
string,
SimpleFeatureSerializedNoId[]
>
const parentAggregation = {} as Record<string, SimpleFeatureSerialized[]>

if (feats.some(f => f.uniqueId === undefined)) {
throw new Error('found uniqueId undefined')
}
for (const feat of feats) {
const data = parser.parseLine(
`${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`,
{ uniqueId: feat.uniqueId! },
)
const line = `${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`
const data = parser.parseLine(line, { uniqueId: feat.uniqueId! })

const aggr = data[aggregateField]
if (!parentAggregation[aggr]) {
Expand All @@ -183,89 +172,27 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
strand,
...rest
} = data
const chromStarts = arrayify(chromStarts2)
const blockStarts = arrayify(blockStarts2)
const blockSizes = arrayify(blockSizes2)
const score = scoreColumn ? +data[scoreColumn] : +score2

const subfeatures = makeBlocks({
chromStarts,
blockStarts,
blockSizes,
blockCount,
const f = featureData2({
...rest,
scoreColumn,
line,
parser,
uniqueId,
refName: query.refName,
start: feat.start,
end: feat.end,
refName: query.refName,
})

if (
isUcscTranscript({
strand,
blockCount,
thickStart,
description,
})
) {
const f = generateUcscTranscript({
...rest,
strand,
uniqueId,
type,
start: feat.start,
end: feat.end,
refName: query.refName,
score,
description,
chromStarts: chromStarts!,
blockSizes: blockSizes!,
blockCount,
thickStart,
thickEnd,
subfeatures,
})
if (aggr) {
parentAggregation[aggr].push(f)
} else {
if (
doesIntersect2(
f.start,
f.end,
originalQuery.start,
originalQuery.end,
)
) {
observer.next(
new SimpleFeature({
id: `${this.id}-${uniqueId}`,
data: f,
}),
)
}
}
if (aggr) {
parentAggregation[aggr].push(f)
} else {
if (
doesIntersect2(
feat.start,
feat.end,
originalQuery.start,
originalQuery.end,
)
doesIntersect2(f.start, f.end, originalQuery.start, originalQuery.end)
) {
observer.next(
new SimpleFeature({
id: `${this.id}-${uniqueId}`,
data: {
...rest,
...makeRepeatTrackDescription(description),
start: feat.start,
end: feat.end,
strand,
uniqueId,
type,
score,
refName: query.refName,
subfeatures,
},
data: f,
}),
)
}
Expand Down
69 changes: 69 additions & 0 deletions plugins/bed/src/generateBedMethylFature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { SimpleFeature } from '@jbrowse/core/util'

Check warning on line 1 in plugins/bed/src/generateBedMethylFature.ts

View workflow job for this annotation

GitHub Actions / Lint, typecheck, test

"Fature" should be "Feature".

export function isBedMethylFeature({
splitLine,
start,
end,
}: {
splitLine: string[]
start: number
end: number
}) {
return +(splitLine[6] || 0) === start && +(splitLine[7] || 0) === end
}
export function generateBedMethylFeature({
line,
uniqueId,
refName,
start,
end,
}: {
line: string
uniqueId: string
refName: string
start: number
end: number
}) {
// see
// https://github.com/nanoporetech/modkit?tab=readme-ov-file#description-of-bedmethyl-output
const [
,
,
,
code,
,
strand,
,
,
color,
n_valid_cov,
fraction_modified,
n_mod,
n_canonical,
n_other_mod,
n_delete,
n_fail,
n_diff,
n_nocall,
] = line.split('\t')
return {
uniqueId,
refName,
start,
end,
code,
score: fraction_modified,
strand,
color,
source: code,
n_valid_cov,
fraction_modified,
n_mod,
n_canonical,
n_other_mod,
n_delete,
n_fail,
n_diff,
n_nocall,
}
}
73 changes: 73 additions & 0 deletions plugins/bed/src/generateRepeatMaskerFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { SimpleFeature } from '@jbrowse/core/util'

export function isRepeatMaskerDescriptionField(desc?: string): desc is string {
const ret = desc?.trim().split(' ')
return [0, 1, 2, 3, 5, 6].every(s =>
ret?.[s] !== undefined ? !Number.isNaN(+ret[s]) : false,
)
}

function makeRepeatTrackDescription(description?: string) {
if (isRepeatMaskerDescriptionField(description)) {
const [
bitsw_score,
percent_div,
percent_del,
percent_ins,
query_chr,
query_begin,
query_end,
query_remaining,
orientation,
matching_repeat_name,
matching_repeat_class,
matching_repeat_begin,
matching_repeat_end,
matching_repeat_remaining,
repeat_id,
] = description.trim().split(' ')
return {
bitsw_score,
percent_div,
percent_del,
percent_ins,
query_chr,
query_begin,
query_end,
query_remaining,
orientation,
matching_repeat_name,
matching_repeat_class,
matching_repeat_begin,
matching_repeat_end,
matching_repeat_remaining,
repeat_id,
}
}
return { description }
}

export function generateRepeatMaskerFeature({
uniqueId,
refName,
start,
end,
description,
...rest
}: {
uniqueId: string
refName: string
start: number
end: number
description: string
[key: string]: unknown
}) {
return {
...rest,
...makeRepeatTrackDescription(description),
uniqueId,
refName,
start,
end,
}
}
Loading

0 comments on commit 510af3d

Please sign in to comment.