Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create stranded SNPCoverage view #2833

Closed
cmdcolin opened this issue Mar 21, 2022 · 11 comments
Closed

Create stranded SNPCoverage view #2833

cmdcolin opened this issue Mar 21, 2022 · 11 comments
Labels
applied enhancement New feature or request

Comments

@cmdcolin
Copy link
Collaborator

from thread here https://twitter.com/gringene_bio/status/1505780926734774275

would create separate coverage for positive and negative strand reads

@cmdcolin cmdcolin added the enhancement New feature or request label Mar 21, 2022
@cmdcolin
Copy link
Collaborator Author

could also think about multibigwig/strandedplot https://github.com/bhofmei/jbplugin-strandedplot style results but this request is more about automatically calculating from the reads themselves

@cmdcolin
Copy link
Collaborator Author

cmdcolin commented Mar 21, 2022

example image from twitter thread
image

@gringer
Copy link

gringer commented Mar 21, 2022

For showing the overall coverage, I expect this would involve adding an additional fwd/reverse feature filter:

const feats = [...features.values()]
const coverage = feats.filter(f => f.get('type') !== 'skip')
const skips = feats.filter(f => f.get('type') === 'skip')
// Use two pass rendering, which helps in visualizing the SNPs at higher
// bpPerPx First pass: draw the gray background
ctx.fillStyle = colorForBase.total
for (let i = 0; i < coverage.length; i++) {
const feature = coverage[i]
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
const w = rightPx - leftPx + 0.3
const score = feature.get('score') as number
ctx.fillRect(leftPx, toY(score), w, toHeight(score))
}

My guess:

const feats = [...features.values()]
const coverage_fwd = feats.filter( f => (f.get('type') !== 'skip') && (f.get('strand') == 1) )
const coverage_rev = feats.filter( f => (f.get('type') !== 'skip') && (f.get('strand') == -1) )
const skips_fwd = feats.filter( (f => f.get('type') === 'skip')  && (f.get('strand') == 1) )
const skips_rev = feats.filter( (f => f.get('type') === 'skip')  && (f.get('strand') == -1) )

// Use two pass rendering, which helps in visualizing the SNPs at higher
// bpPerPx First pass: draw the gray background
ctx.fillStyle = colorForBase.total
// forward reads (shown above the Y axis)
for (let i = 0; i < coverage_fwd.length; i++) {
  const feature = coverage_fwd[i]
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
  const w = rightPx - leftPx + 0.3
  const score = feature.get('score') as number
  ctx.fillRect(leftPx, toY(score), w, toHeight(score))
}
// reverse reads (shown below the Y axis)
for (let i = 0; i < coverage_rev.length; i++) {
  const feature = coverage_rev[i]
  const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
  const w = rightPx - leftPx + 0.3
  const score = feature.get('score') as number
  ctx.fillRect(leftPx, toY(score), w, toY - toHeight(score))
}

[if the filtered coverage tracks can be assumed to be the same length, then these rectangles could be done within the same loop]

@gringer
Copy link

gringer commented Mar 22, 2022

Here is a reference assembly and BAM file that can be used for testing (the same one that I used in the JBrowse2 picture). This BAM file is useful because it shows stranded long reads with a very high dynamic range in coverage, so the log representation is necessary to fully appreciate the expression pattern:

GRCm39.primary_assembly.chrM.fa.gz

mm2_GCFeb22_S14_called_BC07_vs_chrM.bam.gz

edit: updated BAM file

@gringer
Copy link

gringer commented Mar 25, 2022

Should look something like this:

Screen Shot 2022-03-25 at 19 04 33

I needed to dig down to the SNPCoverageAdapter bin function to create additional scores for forward and reverse strand, in order to get this working. It's also a bastardisation of the scale (as you may be able to tell by looking at the Y axis).

... although it does seem to work well on log scale as well:

Screen Shot 2022-03-25 at 19 10 05

@cmdcolin
Copy link
Collaborator Author

great initiative diving into the codebase:)! could possibly use negative values but those will not log transform well...will probably need a real notion of having multiple signals in a single track a la multibigwig and https://github.com/bhofmei/jbplugin-strandedplot

@gringer
Copy link

gringer commented Mar 26, 2022

I've attached a diff (based on commit 85973e5). This creates a new StrandedRelCoverage Display Type and associated adapters (based on LinearSNPCoverage), which has a stranded coverage track and stranded variant display.

I suppose this would be better designed as a modification of the existing LinearSNPCoverage track, but I didn't want to break existing functionality when creating something different.

patch-stranded-snp-coverage.diff.gz

Screen Shot 2022-03-26 at 16 51 33

Note that in the highlighted column, the 'C' variants are broken by an 'A' variant in the middle on the opposite strand. This could be improved (e.g. by sorting variants based on their frequency), but I think this is at least good enough for others to understand what I'd like to achieve.

@garrettjstevens
Copy link
Collaborator

Another +1 for this from @haessar today. He said, I believe, that he uses differences in coverage between strands to help with annotating UTRs. Here's a screenshot of this feature Artemis:

image

@cmdcolin
Copy link
Collaborator Author

definitely a good use case there. could possibly leverage multiwiggle display for this purpose (as they are conceptually two different signals)

@cmdcolin
Copy link
Collaborator Author

I made it so that you can now use "group by->strand" following #4178

this group by approach is a little more "round about" compared with making "displaying stranded read coverage" option in the single track, but hopefully it helps a bit

maybe can close :)

@cmdcolin
Copy link
Collaborator Author

(if you are able to try it out and have any feedback, let me know)

example session

image

https://jbrowse.org/code/jb2/main/?config=test_data%2Fvolvox%2Fconfig.json&session=share-EAlzHWoalP&password=h2gxM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
applied enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants