UNPKG

@gmod/jbrowse

Version:

JBrowse - client-side genome browser

139 lines (125 loc) 4.69 kB
const { TribbleIndexedFile } = cjsRequire('@gmod/tribble-index') const VCF = cjsRequire('@gmod/vcf') define([ 'dojo/_base/declare', 'JBrowse/Errors', 'dojo/_base/lang', 'JBrowse/Store/SeqFeature', 'JBrowse/Store/DeferredStatsMixin', 'JBrowse/Store/DeferredFeaturesMixin', 'JBrowse/Store/SeqFeature/GlobalStatsEstimationMixin', 'JBrowse/Model/XHRBlob', 'JBrowse/Model/BlobFilehandleWrapper', 'JBrowse/Model/VCFFeature', ], function( declare, Errors, lang, SeqFeatureStore, DeferredStatsMixin, DeferredFeaturesMixin, GlobalStatsEstimationMixin, XHRBlob, BlobFilehandleWrapper, VCFFeature ) { return declare( [ SeqFeatureStore, DeferredStatsMixin, DeferredFeaturesMixin, GlobalStatsEstimationMixin ], { constructor( args ) { var thisB = this; var idxBlob = args.idx || new BlobFilehandleWrapper( new XHRBlob( this.resolveUrl( this.getConf('idxUrlTemplate',[]) || this.getConf('urlTemplate',[])+'.idx' ) ) ); var fileBlob = args.file || new BlobFilehandleWrapper( new XHRBlob( this.resolveUrl( this.getConf('urlTemplate',[]) ), { expectRanges: true } ) ); this.indexedData = new TribbleIndexedFile({ filehandle: fileBlob, tribbleFilehandle: idxBlob, oneBasedClosed: true, chunkSizeLimit: args.chunkSizeLimit || 2000000, renameRefSeqs: n => this.browser.regularizeReferenceName(n) }); this.getParser() .then( function( parser ) { thisB._deferred.features.resolve({success:true}); thisB._estimateGlobalStats() .then( function( stats ) { thisB.globalStats = stats; thisB._deferred.stats.resolve( stats ); }, lang.hitch( thisB, '_failAllDeferred' ) ); }, lang.hitch( thisB, '_failAllDeferred' ) ); }, getParser() { if (!this._parser) { this._parser = this.indexedData.getHeader() .then(header => new VCF({header: header})) } return this._parser }, _getFeatures( query, featureCallback, finishedCallback, errorCallback ) { var thisB = this; thisB.getParser().then(parser => { const regularizedReferenceName = this.browser.regularizeReferenceName(query.ref) thisB.indexedData.getLines( regularizedReferenceName, query.start, query.end, line => { const variant = parser.parseLine(line) const feature = new VCFFeature({ variant: variant, parser: parser, id: variant.ID.length ? variant.ID[0] : `chr${variant.CHROM}_pos${variant.POS}_ref${variant.REF}_alt${variant.ALT}` }) featureCallback(feature) } ) .then(finishedCallback, error => { if (errorCallback) { if (error.message && error.message.indexOf('Too much data') >= 0) { error = new Errors.DataOverflow(error.message) } errorCallback(error) } else console.error(error) }) }) .catch(errorCallback) }, /** * Interrogate whether a store has data for a given reference * sequence. Calls the given callback with either true or false. * * Implemented as a binary interrogation because some stores are * smart enough to regularize reference sequence names, while * others are not. */ hasRefSeq: function( seqName, callback, errorCallback ) { return this.indexedData.index.hasRefSeq( seqName, callback, errorCallback ); }, saveStore: function() { return { urlTemplate: this.config.file.url, idxUrlTemplate: this.config.idx.url }; } }); });