Skip to content
GMODPublic

About

Read CRAM v3 and v2 in node or in the browser

Topics

Resources

Contributing

Stars

18 stars

Watchers

10 watching

Forks

Latest commit

 

History

962 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@gmod/cram

NPM version Build Status

Read CRAM files in node or the browser. Handles CRAM 2.x and 3.x, .crai indexes, and every v3 and v3.1 codec, including fqzcomp and tok3. The codecs are the htscodecs C library that samtools uses, compiled to WebAssembly and inlined in the bundle, so there is no .wasm file to serve.

npm install @gmod/cram

Quick start

import { IndexedCramFile, CraiIndex } from '@gmod/cram'
import { IndexedFasta } from '@gmod/indexedfasta'
import { RemoteFile } from 'generic-filehandle2'

const fasta = new IndexedFasta({
  fasta: new RemoteFile('https://example.com/reference.fa'),
  fai: new RemoteFile('https://example.com/reference.fa.fai'),
})

const indexedFile = new IndexedCramFile({
  cramUrl: 'https://example.com/file.cram',
  index: new CraiIndex({ url: 'https://example.com/file.cram.crai' }),
  fetchReferenceSequence: (seqId, start, end, refName) =>
    fasta.getSequence(refName, start, end),
})

const records = await indexedFile.getRecordsForRange('chr1', 10000, 20000)

for (const record of records) {
  console.log(record.readName, record.start, record.getCigarString())
}

URLs work in node and the browser. For local files, pass cramPath and CraiIndex({ path }), and IndexedFasta({ path }).

fetchReferenceSequence supplies the reference bases that CRAM stores reads against. Without it, records still have positions and CIGAR strings, but not read bases. docs/api.md has the details.

Range caching

For each query, the library reads one byte range per slice and two small ones per container. With cramUrl, it sends a separate HTTP request for each range. @gmod/range-cache-filehandle keeps the bytes it fetched and answers each range from them, so it fetches neighboring ranges in one request:

import { RemoteFileWithRangeCache } from '@gmod/range-cache-filehandle'

const indexedFile = new IndexedCramFile({
  cramFilehandle: new RemoteFileWithRangeCache(url),
  index: new CraiIndex({
    filehandle: new RemoteFileWithRangeCache(`${url}.crai`),
  }),
})

Reference names

Query a reference by its name in the file's header, such as chr1, 1 or CHROMOSOME_I. A query for a name the file lacks returns no records, so the same query can run across files that cover different references:

await indexedFile.getRecordsForRange('chrY', 0, 50000) // [] if the file has no chrY
await indexedFile.hasDataForReferenceSequence('chrY') // false, likewise
await indexedFile.cram.getReferenceInfo() // [{ name, length, md5 }, ...]

Coordinates

Coordinates are 0-based half-open, as in @gmod/bam. Add 1 to convert to a 1-based format such as SAM's POS.

Records

record.getReadBases() // 'ACGT…', the read sequence
record.getCigarString() // '50M2I48M'
record.getMismatches() // every difference from the reference
record.getTag('NM') // one auxiliary tag
record.qualityScoreAt(0) // one base quality
record.isReverseComplemented() // the usual SAM flags

docs/api.md lists every property and method.

Script tag

The package ships a standalone browser build that puts the same exports on window.gmodCRAM. The example directory has a working page.

<script src="https://unpkg.com/@gmod/cram/dist/cram-bundle.js"></script>

Docs

Academic use

Written with NHGRI funding as part of JBrowse. If you use this in a publication, please cite the most recent JBrowse paper at jbrowse.org.

License

MIT

About

Read CRAM v3 and v2 in node or in the browser

Topics

Resources

Contributing

Stars

18 stars

Watchers

10 watching

Forks

Releases

Packages

Used by

Contributors

Languages