Skip to content

Commit

Permalink
Fetch entire bigBed blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
danvk committed Mar 18, 2015
1 parent ecd58f5 commit 0346319
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 17 deletions.
1 change: 1 addition & 0 deletions lib/underscore.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ declare module "underscore" {
declare function flatten<S>(a: S[][]): S[];

declare function chain<S>(obj: S): any;
declare function any<T>(list: Array<T>, pred: (el: T)=>boolean): boolean;
}

4 changes: 2 additions & 2 deletions src/BigBed.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ type BedRow = {

// All features found in range.
type BedBlock = {
range: ContigRange<string>;
range: ContigInterval<string>;
rows: BedRow[];
}

Expand Down Expand Up @@ -235,7 +235,7 @@ class BigBed {
* Because these features must all be fetched, decompressed and parsed
* anyway, this can be helpful for upstream caching.
*/
getFeatureBlocksOverlapping(range: ContigRange): Q.Promise<Array<BedBlock>> {
getFeatureBlocksOverlapping(range: ContigInterval<string>): Q.Promise<Array<BedBlock>> {
return Q.spread([this.header, this.cirTree, this.contigMap],
(header, cirTree, contigMap) => {
var contigIx = getContigId(contigMap, range.contig);
Expand Down
28 changes: 22 additions & 6 deletions src/BigBedDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@ type BedRow = {
// Remaining fields in the BED row (typically tab-delimited)
rest: string;
}
type BedBlock = {
range: ContigInterval<string>;
rows: BedRow[];
}

declare class BigBed {
getFeaturesInRange: (contig: string, start: number, stop: number) => Q.Promise<Array<BedRow>>;
getFeatureBlocksOverlapping(range: ContigInterval): Q.Promise<Array<BedBlock>>;
}


Expand Down Expand Up @@ -73,6 +78,9 @@ function createBigBedDataSource(remoteSource: BigBed): BigBedSource {
var genes: Array<Gene> = [];
window.genes = genes;

// Ranges for which we have complete information -- no need to hit network.
var coveredRanges: Array<ContigInterval<string>> = []

function addGene(newGene) {
if (!_.findWhere(genes, {id: newGene.id})) {
genes.push(newGene);
Expand All @@ -85,12 +93,20 @@ function createBigBedDataSource(remoteSource: BigBed): BigBedSource {
}

function fetch(range: GenomeRange) {
// TODO: add an API for requesting the entire block of genes.
return remoteSource.getFeaturesInRange(range.contig, range.start, range.stop)
.then(features => {
var genes = features.map(parseBedFeature);
genes.forEach(gene => addGene(gene));
});
var interval = new ContigInterval(range.contig, range.start, range.stop);

// Check if this interval is already in the cache.
if (_.any(coveredRanges, r => r.intersects(interval))) {
return Q.when();
}

return remoteSource.getFeatureBlocksOverlapping(interval).then(featureBlocks => {
featureBlocks.forEach(fb => {
coveredRanges.push(fb.range);
var genes = fb.rows.map(parseBedFeature);
genes.forEach(gene => addGene(gene));
});
});
}

var o = {
Expand Down
1 change: 0 additions & 1 deletion src/RemoteFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class RemoteFile {
// TODO: handle partial overlap of request w/ cache.

// Need to fetch from the network.
console.log('fetching from network: ', start, '+', length);
return this.getFromNetwork(start, stop);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ var Root = React.createClass({
// this is here to facilitate faster iteration
this.handleRangeChange({
contig: 'chr17',
start: 100,
stop: 150
start: 7512444,
stop: 7512484
});
});

Expand Down
1 change: 0 additions & 1 deletion src/TwoBitDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ var createTwoBitDataSource = function(remoteSource: TwoBit): TwoBitSource {
return Q.when(); // empty promise
}
if (isEntirelyKnown(range)) {
console.log('skipping TwoBit.js');
return Q.when();
}

Expand Down
7 changes: 2 additions & 5 deletions test/TwoBitDataSource-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('TwoBitDataSource', function() {
source = createTwoBitDataSource(tb);

source.on('newdata', () => {
expect(source.getRange({contig: 'chr22', start: 1, stop: 18}))
expect(source.getRange({contig: 'chr22', start: 1, stop: 15}))
.to.deep.equal({
'chr22:1': 'N',
'chr22:2': 'T',
Expand All @@ -68,10 +68,7 @@ describe('TwoBitDataSource', function() {
'chr22:12': 'C',
'chr22:13': 'C',
'chr22:14': 'A',
'chr22:15': 'T', // 5 past end of request
'chr22:16': null,
'chr22:17': null,
'chr22:18': null
'chr22:15': 'T',
});
done();
});
Expand Down

0 comments on commit 0346319

Please sign in to comment.