Skip to content

Commit

Permalink
Reduce self-pairing for some paired-end read data in breakpoint split…
Browse files Browse the repository at this point in the history
… view (#4667)
  • Loading branch information
cmdcolin authored Nov 19, 2024
1 parent 1cccc87 commit 9a83551
Show file tree
Hide file tree
Showing 4 changed files with 1,012 additions and 952 deletions.
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export default tseslint.config(
'unicorn/prefer-at': 'off',
'unicorn/prefer-string-replace-all': 'off',
'unicorn/no-array-reduce': 'off',
'unicorn/expiring-todo-comments': 'off',

'@typescript-eslint/no-deprecated': 'off',
'@typescript-eslint/no-explicit-any': 'off',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export default function LaunchBreakpointSplitViewPanel({
feature: SimpleFeatureSerialized
viewType: ViewType
}) {
const session = getSession(model)
const { view } = model
const [res, setRes] = useState<ReducedFeature[]>()
const [error, setError] = useState<unknown>()
Expand Down Expand Up @@ -67,50 +66,92 @@ export default function LaunchBreakpointSplitViewPanel({
<li key={`${JSON.stringify(arg)}-${index}`}>
{f1.refName}:{toLocale(f1.strand === 1 ? f1.end : f1.start)} -&gt;{' '}
{f2.refName}:{toLocale(f2.strand === 1 ? f2.start : f2.end)}{' '}
<Link
href="#"
onClick={event => {
event.preventDefault()
session.queueDialog(handleClose => [
BreakendMultiLevelOptionDialog,
{
handleClose,
model,
feature: new SimpleFeature({ ...f1, mate: f2 }),
// @ts-expect-error
viewType,
view: model.view,
assemblyName: model.view.displayedRegions[0].assemblyName,
},
])
}}
>
(top/bottom)
</Link>{' '}
<Link
href="#"
onClick={event => {
event.preventDefault()
session.queueDialog(handleClose => [
BreakendSingleLevelOptionDialog,
{
handleClose,
model,
feature: new SimpleFeature({ ...f1, mate: f2 }),
// @ts-expect-error
viewType,
view: model.view,
assemblyName: model.view.displayedRegions[0].assemblyName,
},
])
}}
>
(single row)
</Link>
<TopBottomSplitViewLink
model={model}
f1={f1}
f2={f2}
viewType={viewType}
/>{' '}
<SideBySideViewLink
model={model}
f1={f1}
f2={f2}
viewType={viewType}
/>
</li>
)
})}
</ul>
</div>
) : null
}

function TopBottomSplitViewLink({
model,
f1,
f2,
viewType,
}: {
model: AlignmentFeatureWidgetModel
f1: ReducedFeature
f2: ReducedFeature
viewType: ViewType
}) {
return (
<Link
href="#"
onClick={event => {
event.preventDefault()
getSession(model).queueDialog(handleClose => [
BreakendMultiLevelOptionDialog,
{
handleClose,
model,
feature: new SimpleFeature({ ...f1, mate: f2 }),
// @ts-expect-error
viewType,
view: model.view,
assemblyName: model.view.displayedRegions[0].assemblyName,
},
])
}}
>
(top/bottom)
</Link>
)
}

function SideBySideViewLink({
model,
f1,
f2,
viewType,
}: {
model: AlignmentFeatureWidgetModel
f1: ReducedFeature
f2: ReducedFeature
viewType: ViewType
}) {
return (
<Link
href="#"
onClick={event => {
event.preventDefault()
getSession(model).queueDialog(handleClose => [
BreakendSingleLevelOptionDialog,
{
handleClose,
model,
feature: new SimpleFeature({ ...f1, mate: f2 }),
// @ts-expect-error
viewType,
view: model.view,
assemblyName: model.view.displayedRegions[0].assemblyName,
},
])
}}
>
(single row)
</Link>
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Feature, notEmpty } from '@jbrowse/core/util'
import { assembleLocStringFast, Feature, notEmpty } from '@jbrowse/core/util'

import { parseBreakend } from '@gmod/vcf'

Expand All @@ -7,15 +7,26 @@ import { parseBreakend } from '@gmod/vcf'
export function getBadlyPairedAlignments(features: Map<string, Feature>) {
const candidates = new Map<string, Feature[]>()
const alreadySeen = new Set<string>()
const alreadyPairedWithSamePosition = new Set<string>()

// this finds candidate features that share the same name
for (const feature of features.values()) {
const flags = feature.get('flags')
const id = feature.id()
const supp = assembleLocStringFast({
refName: feature.get('refName'),
start: feature.get('start'),
end: feature.get('end'),
})
const unmapped = flags & 4
const correctlyPaired = flags & 2

if (!alreadySeen.has(id) && !correctlyPaired && !unmapped) {
if (
!alreadySeen.has(id) &&
!alreadyPairedWithSamePosition.has(supp) &&
!correctlyPaired &&
!unmapped
) {
const n = feature.get('name')
let val = candidates.get(n)
if (!val) {
Expand All @@ -25,6 +36,7 @@ export function getBadlyPairedAlignments(features: Map<string, Feature>) {
val.push(feature)
}
alreadySeen.add(feature.id())
alreadyPairedWithSamePosition.add(supp)
}

return [...candidates.values()].filter(v => v.length > 1)
Expand Down
Loading

0 comments on commit 9a83551

Please sign in to comment.