igv-rails 1.0.9.5 → 1.0.9.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 636c5f3a8ee2df878385395bd9a3e5251c81d2f8
4
- data.tar.gz: 4aa150d49e6483b5b41bc1cb6b4596bfd337aa5a
3
+ metadata.gz: 13bd75480e38855d195faab0a32943d8e3208554
4
+ data.tar.gz: bdd708cf6cf4adb74b233596ba132f65e4e2bceb
5
5
  SHA512:
6
- metadata.gz: af9347c8bbaedf1bd4eb8b3ad45c268da4e379cf9d0978fca74acf02fb920213a6010965881b9838f8db3285324e719b630b991209a2f84d8152c21211c81433
7
- data.tar.gz: c388d06b3c80d69a4718c53b6ec04b1d8f4d5635e6ece859133735478888a99b696fb6967daae34fe133ab9eb6169e9e0d4c1450c80db0bed5c39c9a713a23d3
6
+ metadata.gz: aca0fc1568a097ef11416ccbd76f7ef15a3814942bf71e94e74e246862a3ec53a70e5c484bd1ab932e7e2557ee0ede79a1c43b3a501d1b465b3ae1be912d1426
7
+ data.tar.gz: f9780e347f50f757da29a3ab944e341cd2ce50d907c7022b4c8ccc48269f9a4da4c702f9e09ab5e06f5870cd2f754a351758c09ed72aa54b6663d26962adfb4c
@@ -1,5 +1,5 @@
1
1
  module Igv
2
2
  module Rails
3
- VERSION = "1.0.9.5"
3
+ VERSION = "1.0.9.6"
4
4
  end
5
5
  end
@@ -24966,18 +24966,6 @@ var igv = (function (igv) {
24966
24966
  }
24967
24967
  };
24968
24968
 
24969
- // Alt - Click to Sort alignment rows
24970
- igv.BAMTrack.prototype.altClick = function (genomicLocation, referenceFrame, event) {
24971
-
24972
- this.alignmentTrack.sortAlignmentRows(genomicLocation, this.sortOption);
24973
-
24974
- // TODO - dat. Temporary hack to stand up mult-locus implementation.
24975
- // TODO - dat. MUST identify viewport that was clicked in.
24976
- this.trackView.viewports[0].redrawTile(this.featureSource.alignmentContainer);
24977
- this.trackView.viewports[0].$viewport.scrollTop(0);
24978
-
24979
- this.sortDirection = !this.sortDirection;
24980
- };
24981
24969
 
24982
24970
  /**
24983
24971
  * Optional method to compute pixel height to accomodate the list of features. The implementation below
@@ -25022,10 +25010,8 @@ var igv = (function (igv) {
25022
25010
 
25023
25011
  self.alignmentTrack.sortAlignmentRows(config.genomicLocation, self.sortOption);
25024
25012
 
25025
- config.viewport.redrawTile(self.featureSource.alignmentContainer);
25026
-
25027
- config.viewport.$viewport.scrollTop(0);
25028
-
25013
+ self.trackView.update();
25014
+
25029
25015
  self.sortDirection = !(self.sortDirection);
25030
25016
 
25031
25017
  config.popover.hide();
@@ -28785,6 +28771,8 @@ var igv = (function (igv) {
28785
28771
  chromosomeField: options.search.chromosomeField || "chromosome",
28786
28772
  startField: options.search.startField || "start",
28787
28773
  endField: options.search.endField || "end",
28774
+ geneField: options.search.geneField || "geneSymbol",
28775
+ snpField: options.search.snpField || "snp",
28788
28776
  resultsField: options.search.resultsField
28789
28777
  }
28790
28778
  }
@@ -28803,7 +28791,7 @@ var igv = (function (igv) {
28803
28791
  this.searchConfig = {
28804
28792
  // Legacy support -- deprecated
28805
28793
  type: "plain",
28806
- url:'https://portals.broadinstitute.org/webservices/igv/locus?genome=$GENOME$&name=$FEATURE$',
28794
+ url: 'https://portals.broadinstitute.org/webservices/igv/locus?genome=$GENOME$&name=$FEATURE$',
28807
28795
  coords: 0,
28808
28796
  chromosomeField: "chromosome",
28809
28797
  startField: "start",
@@ -28865,7 +28853,7 @@ var igv = (function (igv) {
28865
28853
  var self = this,
28866
28854
  loadedTracks = [];
28867
28855
 
28868
- configList.forEach( function (config) {
28856
+ configList.forEach(function (config) {
28869
28857
  var track = self.loadTrack(config);
28870
28858
  if (track) {
28871
28859
  loadedTracks.push(track);
@@ -28873,7 +28861,7 @@ var igv = (function (igv) {
28873
28861
  });
28874
28862
 
28875
28863
  // Really we should just resize the new trackViews, but currently there is no way to get a handle on those
28876
- this.trackViews.forEach( function (trackView) {
28864
+ this.trackViews.forEach(function (trackView) {
28877
28865
  trackView.resize();
28878
28866
  });
28879
28867
 
@@ -29177,7 +29165,7 @@ var igv = (function (igv) {
29177
29165
 
29178
29166
  igv.Browser.prototype.update = function () {
29179
29167
 
29180
- this.updateLocusSearchWithGenomicState(_.first(this.genomicStateList));
29168
+ this.updateLocusSearchWidget(_.first(this.genomicStateList));
29181
29169
 
29182
29170
  this.windowSizePanel.updateWithGenomicState(_.first(this.genomicStateList));
29183
29171
 
@@ -29195,7 +29183,7 @@ var igv = (function (igv) {
29195
29183
 
29196
29184
  igv.Browser.prototype.updateWithLocusIndex = function (locusIndex) {
29197
29185
 
29198
- igv.browser.updateLocusSearchWithGenomicState(_.first(this.genomicStateList));
29186
+ igv.browser.updateLocusSearchWidget(_.first(this.genomicStateList));
29199
29187
 
29200
29188
  if (0 === locusIndex) {
29201
29189
  this.windowSizePanel.updateWithGenomicState(this.genomicStateList[locusIndex]);
@@ -29233,7 +29221,7 @@ var igv = (function (igv) {
29233
29221
  return anyTrackViewIsLoading;
29234
29222
  };
29235
29223
 
29236
- igv.Browser.prototype.updateLocusSearchWithGenomicState = function (genomicState) {
29224
+ igv.Browser.prototype.updateLocusSearchWidget = function (genomicState) {
29237
29225
 
29238
29226
  var self = this,
29239
29227
  referenceFrame,
@@ -29587,48 +29575,58 @@ var igv = (function (igv) {
29587
29575
  igv.Browser.prototype.search = function (string) {
29588
29576
 
29589
29577
  var self = this,
29590
- loci = string.split(' ');
29578
+ loci;
29591
29579
 
29580
+ loci = string.split(' ');
29592
29581
  this.getGenomicStateList(loci, this.viewportContainerWidth())
29593
29582
  .then(function (genomicStateList) {
29583
+ var $content_header;
29594
29584
 
29595
- var found,
29596
- errorString,
29597
- $content_header = $('#igv-content-header');
29585
+ if (genomicStateList.length > 0) {
29598
29586
 
29599
- if (_.size(genomicStateList) > 0) {
29587
+ genomicStateList.forEach(function (genomicState, index) {
29600
29588
 
29601
- _.each(genomicStateList, function (genomicState, index) {
29602
- genomicState.locusIndex = index;
29603
- genomicState.locusCount = _.size(genomicStateList);
29604
- genomicState.referenceFrame = new igv.ReferenceFrame(genomicState.chromosome.name, genomicState.start, (genomicState.end - genomicState.start) / (self.viewportContainerWidth() / genomicState.locusCount));
29605
- });
29589
+ genomicState.locusIndex = index;
29590
+ genomicState.locusCount = _.size(genomicStateList);
29591
+ genomicState.referenceFrame =
29592
+ new igv.ReferenceFrame(
29593
+ genomicState.chromosome.name,
29594
+ genomicState.start,
29595
+ (genomicState.end - genomicState.start) / (self.viewportContainerWidth() / genomicState.locusCount));
29596
+ });
29606
29597
 
29607
- self.genomicStateList = genomicStateList;
29598
+ self.genomicStateList = genomicStateList;
29608
29599
 
29609
- self.emptyViewportContainers();
29600
+ self.emptyViewportContainers();
29610
29601
 
29611
- self.updateLocusSearchWithGenomicState(_.first(self.genomicStateList));
29602
+ self.updateLocusSearchWidget(_.first(self.genomicStateList));
29612
29603
 
29613
- self.zoomWidgetLayout();
29604
+ self.zoomWidgetLayout();
29614
29605
 
29615
- self.toggleCenterGuide(self.genomicStateList);
29616
- self.toggleCursorGuide(self.genomicStateList);
29606
+ self.toggleCenterGuide(self.genomicStateList);
29607
+ self.toggleCursorGuide(self.genomicStateList);
29617
29608
 
29618
- if (true === self.config.showIdeogram) {
29619
- igv.IdeoPanel.$empty($content_header);
29620
- self.ideoPanel.buildPanels($content_header);
29621
- }
29609
+ if (true === self.config.showIdeogram) {
29610
+ $content_header = $('#igv-content-header');
29611
+ igv.IdeoPanel.$empty($content_header);
29612
+ self.ideoPanel.buildPanels($content_header);
29613
+ }
29622
29614
 
29623
- self.buildViewportsWithGenomicStateList(genomicStateList);
29615
+ self.buildViewportsWithGenomicStateList(genomicStateList);
29624
29616
 
29625
- self.update();
29626
- } else {
29627
- errorString = 'Unrecognized locus ' + string;
29628
- igv.presentAlert(errorString, undefined);
29629
- }
29617
+ console.log('then(browser.update)');
29618
+ self.update();
29630
29619
 
29631
- });
29620
+ return genomicStateList
29621
+
29622
+ } else {
29623
+ throw new Error('Unrecognized locus ' + string);
29624
+ }
29625
+
29626
+ })
29627
+ .catch(function (error) {
29628
+ igv.presentAlert(error);
29629
+ });
29632
29630
  };
29633
29631
 
29634
29632
  igv.Browser.prototype.zoomWidgetLayout = function () {
@@ -29659,143 +29657,120 @@ var igv = (function (igv) {
29659
29657
 
29660
29658
  var self = this,
29661
29659
  searchConfig = igv.browser.searchConfig,
29662
- chrStartEndLoci,
29663
29660
  geneNameLoci,
29664
- locusGenomicState,
29661
+ genomicState,
29665
29662
  locusGenomicStates = [],
29666
- featureDBGenomicStates,
29667
- survivors,
29668
- paths,
29669
29663
  promises;
29670
29664
 
29671
- chrStartEndLoci = [];
29665
+ geneNameLoci = [];
29672
29666
 
29667
+ // Try locus string first (e.g. chr1:100-200)
29673
29668
  loci.forEach(function (locus) {
29674
-
29675
- locusGenomicState = {};
29676
- if (igv.Browser.isLocusChrNameStartEnd(locus, self.genome, locusGenomicState)) {
29677
- locusGenomicState.selection = undefined;
29678
- locusGenomicState.locusSearchString = locus;
29679
- locusGenomicStates.push(locusGenomicState);
29680
-
29681
- // accumulate successfully parsed loci
29682
- chrStartEndLoci.push(locus);
29669
+ genomicState = isLocusChrNameStartEnd(locus, self.genome);
29670
+ if (genomicState) {
29671
+ genomicState.locusSearchString = locus;
29672
+ locusGenomicStates.push(genomicState);
29673
+ }
29674
+ else {
29675
+ geneNameLoci.push(locus);
29683
29676
  }
29684
29677
  });
29685
29678
 
29686
- // isolate gene name loci
29687
- geneNameLoci = _.difference(loci, chrStartEndLoci);
29679
+ if (geneNameLoci.length == 0)
29680
+ return Promise.resolve(locusGenomicStates);
29688
29681
 
29689
- // parse gene names
29690
- if (geneNameLoci.length > 0) {
29682
+ else {
29683
+ // Search based on feature symbol
29691
29684
 
29692
- survivors = [];
29693
- featureDBGenomicStates = [];
29685
+ // Try local feature cache first. This is created from feature tracks tagged "searchable"
29686
+ promises = [];
29694
29687
  geneNameLoci.forEach(function (locus) {
29695
29688
  var result,
29696
29689
  genomicState;
29697
29690
 
29698
29691
  result = self.featureDB[locus.toUpperCase()];
29699
29692
  if (result) {
29700
- genomicState = createFeatureDBGenomicState(result);
29693
+ genomicState = processSearchResult(result, locus);
29701
29694
  if (genomicState) {
29702
- genomicState.locusSearchString = locus;
29703
- featureDBGenomicStates.push(genomicState);
29704
- } else {
29705
- survivors.push(locus);
29695
+ locusGenomicStates.push(genomicState);
29706
29696
  }
29707
29697
  } else {
29708
- survivors.push(locus);
29698
+ promises.push(searchPromise(locus)); // Not found, create promise to search via webservice
29709
29699
  }
29710
29700
  });
29711
29701
 
29712
- if (survivors.length > 0) {
29713
-
29714
- promises = survivors.map(function (locus) {
29715
-
29716
- var path = searchConfig.url.replace("$FEATURE$", locus);
29702
+ // Finally try search webservice
29703
+ if (promises.length > 0) {
29717
29704
 
29718
- if (path.indexOf("$GENOME$") > -1) {
29719
- path = path.replace("$GENOME$", (self.genome.id ? self.genome.id : "hg19"));
29720
- }
29721
-
29722
- return igv.xhr.loadString(path);
29723
- });
29724
-
29725
- return Promise .all(promises)
29705
+ return Promise
29706
+ .all(promises)
29726
29707
 
29727
- .then(function (response) {
29728
- var filtered,
29729
- geneNameGenomicStates;
29708
+ .then(function (searchResponses) {
29730
29709
 
29731
- filtered = _.filter(response, function (geneNameLookupResult) {
29732
- return geneNameLookupResult !== "";
29733
- });
29734
-
29735
- geneNameGenomicStates = _.filter(_.map(filtered, createGeneNameGenomicState), function (genomicState) {
29736
- return undefined !== genomicState;
29737
- });
29710
+ searchResponses.forEach(function (response) {
29711
+ var genomicState = processSearchResult(response.result, response.locusSearchString);
29712
+ if (genomicState) {
29713
+ locusGenomicStates.push(genomicState);
29714
+ }
29715
+ })
29738
29716
 
29739
- return _.union(locusGenomicStates, featureDBGenomicStates, geneNameGenomicStates);
29717
+ return locusGenomicStates;
29740
29718
  });
29741
-
29742
- } else {
29743
- return Promise.resolve(_.union(locusGenomicStates, featureDBGenomicStates));
29744
29719
  }
29745
-
29746
- } else {
29747
- return Promise.resolve(locusGenomicStates);
29748
29720
  }
29749
29721
 
29722
+ /* End of function */
29750
29723
 
29751
- function createFeatureDBGenomicState(featureDBLookupResult) {
29724
+ function searchPromise(locus) {
29752
29725
 
29753
- var start,
29754
- end,
29755
- locusString,
29756
- geneNameLocusObject;
29757
-
29758
- end = (undefined === featureDBLookupResult.end) ? 1 + featureDBLookupResult.start : featureDBLookupResult.end;
29726
+ var path = searchConfig.url.replace("$FEATURE$", locus);
29759
29727
 
29760
- if (igv.browser.flanking) {
29761
- start = Math.max(0, featureDBLookupResult.start - igv.browser.flanking);
29762
- end += igv.browser.flanking;
29728
+ if (path.indexOf("$GENOME$") > -1) {
29729
+ path = path.replace("$GENOME$", (self.genome.id ? self.genome.id : "hg19"));
29763
29730
  }
29764
29731
 
29765
- locusString = featureDBLookupResult.chr + ':' + start.toString() + '-' + end.toString();
29766
-
29767
- geneNameLocusObject = {};
29768
- if (igv.Browser.isLocusChrNameStartEnd(locusString, self.genome, geneNameLocusObject)) {
29769
- geneNameLocusObject.selection = new igv.GtexSelection({gene: featureDBLookupResult.name});
29770
- return geneNameLocusObject;
29771
- } else {
29772
- return undefined;
29773
- }
29732
+ return igv.xhr.loadString(path)
29733
+ .then(function (result) {
29734
+ return {
29735
+ result: result,
29736
+ locusSearchString: locus
29737
+ }
29738
+ });
29774
29739
 
29775
29740
  }
29776
29741
 
29777
- function createGeneNameGenomicState(geneNameLookupResponse) {
29742
+ function processSearchResult(searchServiceResponse, locusSearchString) {
29778
29743
 
29779
29744
  var results,
29780
29745
  result,
29781
29746
  chr,
29782
29747
  start,
29783
29748
  end,
29784
- type,
29785
- string,
29786
29749
  geneNameLocusObject;
29787
29750
 
29788
- results = ("plain" === searchConfig.type) ? parseSearchResults(geneNameLookupResponse) : JSON.parse(geneNameLookupResponse);
29751
+ if ('plain' === searchConfig.type) {
29752
+ results = parseSearchResults(searchServiceResponse);
29753
+ } else {
29754
+ results = JSON.parse(searchServiceResponse);
29755
+ }
29789
29756
 
29790
29757
  if (searchConfig.resultsField) {
29791
29758
  results = results[searchConfig.resultsField];
29792
29759
  }
29793
29760
 
29794
- if (0 === _.size(results)) {
29761
+ if (!results || 0 === results.length) {
29795
29762
  return undefined;
29796
- } else if (1 === _.size(results)) {
29763
+ } else {
29797
29764
 
29798
- result = _.first(results);
29765
+ // Ingoring all but first result for now
29766
+ // TODO -- present all and let user select if results.length > 1
29767
+ result = results[0];
29768
+
29769
+ //
29770
+ if (!(result.hasOwnProperty(searchConfig.chromosomeField) && (result.hasOwnProperty(searchConfig.startField)))) {
29771
+ console.log("Search service results must includ chromosome and start fields: " + result);
29772
+ return undefined;
29773
+ }
29799
29774
 
29800
29775
  chr = result[searchConfig.chromosomeField];
29801
29776
  start = result[searchConfig.startField] - searchConfig.coords;
@@ -29810,145 +29785,89 @@ var igv = (function (igv) {
29810
29785
  end += igv.browser.flanking;
29811
29786
  }
29812
29787
 
29813
- string = chr + ':' + start.toString() + '-' + end.toString();
29788
+ geneNameLocusObject = Object.assign({}, result);
29814
29789
 
29815
- geneNameLocusObject = {};
29816
- if (igv.Browser.isLocusChrNameStartEnd(string, self.genome, geneNameLocusObject)) {
29790
+ geneNameLocusObject.chromosome = self.genome.getChromosome(chr);
29791
+ geneNameLocusObject.start = start;
29792
+ geneNameLocusObject.end = end;
29793
+ geneNameLocusObject.locusSearchString = locusSearchString;
29817
29794
 
29818
- type = result["featureType"] || result["type"];
29795
+ geneNameLocusObject.selection = new igv.GtexSelection(result[searchConfig.geneField], result[searchConfig.snpField]);
29819
29796
 
29820
- geneNameLocusObject.locusSearchString = _.first(geneNameLookupResponse.split('\t'));
29821
- geneNameLocusObject.selection = new igv.GtexSelection('gtex' === type || 'snp' === type ? {snp: result.gene} : {gene: result.gene});
29822
- return geneNameLocusObject;
29823
- } else {
29824
- return undefined;
29825
- }
29826
29797
 
29827
- } else {
29828
- return undefined;
29829
- }
29798
+ // geneName = result.geneSymbol || result.gene;
29799
+ // geneNameLocusObject.locusSearchString = ('gtex' === geneNameLocusObject.type || 'snp' === geneNameLocusObject.type) ? result.snpId : geneName;
29800
+ //
29801
+ // obj = ('gtex' === geneNameLocusObject.type || 'snp' === geneNameLocusObject.type) ? {snp: result.snpId} : {gene: geneName};
29802
+ // geneNameLocusObject.selection = new igv.GtexSelection(obj);
29830
29803
 
29831
- }
29832
- };
29804
+ return geneNameLocusObject;
29833
29805
 
29834
- igv.Browser.prototype.on = function (eventName, fn) {
29835
- if (!this.eventHandlers[eventName]) {
29836
- this.eventHandlers[eventName] = [];
29837
- }
29838
- this.eventHandlers[eventName].push(fn);
29839
- };
29840
29806
 
29841
- igv.Browser.prototype.un = function (eventName, fn) {
29842
- if (!this.eventHandlers[eventName]) {
29843
- return;
29844
- }
29807
+ }
29845
29808
 
29846
- var callbackIndex = this.eventHandlers[eventName].indexOf(fn);
29847
- if (callbackIndex !== -1) {
29848
- this.eventHandlers[eventName].splice(callbackIndex, 1);
29849
29809
  }
29850
- };
29851
29810
 
29852
- igv.Browser.prototype.fireEvent = function (eventName, args, thisObj) {
29853
- var scope,
29854
- results;
29811
+ function isLocusChrNameStartEnd(locus, genome) {
29855
29812
 
29856
- if (undefined === this.eventHandlers[eventName]) {
29857
- return undefined;
29858
- }
29813
+ var a,
29814
+ b,
29815
+ numeric,
29816
+ chr,
29817
+ chromosome,
29818
+ locusObject;
29859
29819
 
29860
- scope = thisObj || window;
29861
- results = _.map(this.eventHandlers[eventName], function (event) {
29862
- return event.apply(scope, args);
29863
- });
29820
+ locusObject = {};
29821
+ a = locus.split(':');
29864
29822
 
29865
- return _.first(results);
29823
+ chr = a[0];
29866
29824
 
29867
- };
29868
29825
 
29869
- igv.Browser.prototype.loadSampleInformation = function (url) {
29870
- var name = url;
29871
- if (url instanceof File) {
29872
- name = url.name;
29873
- }
29874
- var ext = name.substr(name.lastIndexOf('.') + 1);
29875
- if (ext === 'fam') {
29876
- igv.sampleInformation.loadPlinkFile(url);
29877
- }
29878
- };
29879
-
29880
- igv.Browser.isLocusChrNameStartEnd = function (locus, genome, locusObject) {
29826
+ if (chr.toLowerCase() === 'all') {
29827
+ locusObject.chr = 'all';
29828
+ } else {
29829
+ chromosome = genome.getChromosome(chr); // Map chr to official name from (possible) alias
29830
+ if (!chromosome) {
29831
+ return false; // Unknown chromosome
29832
+ }
29833
+ locusObject.chromosome = chromosome; // Map chr to offical name from possible alias
29834
+ }
29881
29835
 
29882
- var a,
29883
- b,
29884
- numeric,
29885
- success,
29886
- chr;
29836
+ // if just a chromosome name we are done
29837
+ if (1 === a.length) {
29838
+ return locusObject;
29839
+ } else {
29887
29840
 
29888
- a = locus.split(':');
29841
+ b = _.last(a).split('-');
29889
29842
 
29890
- chr = a[0];
29891
- if(chr.toLowerCase() === 'all') chr = 'all';
29843
+ if (b.length > 2) {
29844
+ return false; // Not a locus string
29845
+ } else {
29892
29846
 
29893
- if (undefined === genome.getChromosome(chr)) {
29894
- return false;
29895
- } else if (locusObject) {
29847
+ numeric = b[0].replace(/\,/g, '');
29848
+ if (isNaN(numeric)) return false;
29896
29849
 
29897
- // start and end will get overridden if explicit start AND end exits
29898
- locusObject.chromosome = genome.getChromosome(chr);
29899
- locusObject.start = 0;
29900
- locusObject.end = locusObject.chromosome.bpLength;
29901
- }
29850
+ locusObject.start = parseInt(numeric, 10) - 1;
29902
29851
 
29903
- // if just a chromosome name we are done
29904
- if (1 === a.length) {
29905
- return true;
29906
- } else {
29852
+ if (2 === b.length) {
29907
29853
 
29908
- b = _.last(a).split('-');
29909
- if (_.size(b) > 2) {
29910
- return false;
29911
- } else if (1 === _.size(b)) {
29854
+ numeric = b[1].replace(/\,/g, '');
29855
+ if (isNaN(numeric)) return false;
29912
29856
 
29913
- numeric = _.first(b).replace(/\,/g, '');
29914
- success = !isNaN(numeric);
29915
- if (true === success && locusObject) {
29916
- locusObject.start = parseInt(numeric, 10);
29917
- locusObject.start -= 1;
29857
+ locusObject.end = parseInt(numeric, 10);
29858
+ }
29918
29859
 
29919
- locusObject.end = undefined;
29920
29860
  }
29921
29861
 
29922
- } else if (2 === _.size(b)) {
29923
-
29924
- success = true;
29925
- _.each(b, function (bb, index) {
29926
-
29927
- if (true === success) {
29928
- numeric = bb.replace(/\,/g, '');
29929
- success = !isNaN(numeric);
29930
- if (true === success && locusObject) {
29931
- if (0 === index) {
29932
- locusObject.start = parseInt(numeric, 10) - 1;
29933
- } else {
29934
- locusObject.end = parseInt(numeric, 10);
29935
- }
29936
-
29937
- }
29938
- }
29939
- });
29862
+ igv.Browser.validateLocusExtent(locusObject.chromosome, locusObject);
29940
29863
 
29941
- }
29864
+ return locusObject;
29942
29865
 
29943
- if (true === success && locusObject) {
29944
- igv.Browser.validateLocusExtent(locusObject.chromosome, locusObject);
29945
29866
  }
29946
29867
 
29947
- return success;
29948
29868
  }
29949
29869
 
29950
-
29951
- };
29870
+ }
29952
29871
 
29953
29872
  igv.Browser.validateLocusExtent = function (chromosome, extent) {
29954
29873
 
@@ -29997,10 +29916,12 @@ var igv = (function (igv) {
29997
29916
  */
29998
29917
  function parseSearchResults(data) {
29999
29918
 
30000
- var lines = data.splitLines(),
29919
+ var lines,
30001
29920
  linesTrimmed = [],
30002
29921
  results = [];
30003
29922
 
29923
+ lines = data.splitLines();
29924
+
30004
29925
  lines.forEach(function (item) {
30005
29926
  if ("" === item) {
30006
29927
  // do nothing
@@ -30014,7 +29935,8 @@ var igv = (function (igv) {
30014
29935
  var tokens = line.split("\t"),
30015
29936
  source,
30016
29937
  locusTokens,
30017
- rangeTokens;
29938
+ rangeTokens,
29939
+ obj;
30018
29940
 
30019
29941
  if (tokens.length >= 3) {
30020
29942
 
@@ -30022,13 +29944,16 @@ var igv = (function (igv) {
30022
29944
  rangeTokens = locusTokens[1].split("-");
30023
29945
  source = tokens[2].trim();
30024
29946
 
30025
- results.push({
29947
+ obj =
29948
+ {
30026
29949
  gene: tokens[0],
30027
29950
  chromosome: igv.browser.genome.getChromosomeName(locusTokens[0].trim()),
30028
29951
  start: parseInt(rangeTokens[0].replace(/,/g, '')),
30029
29952
  end: parseInt(rangeTokens[1].replace(/,/g, '')),
30030
29953
  type: ("gtex" === source ? "snp" : "gene")
30031
- });
29954
+ };
29955
+
29956
+ results.push(obj);
30032
29957
 
30033
29958
  }
30034
29959
 
@@ -30038,6 +29963,53 @@ var igv = (function (igv) {
30038
29963
 
30039
29964
  }
30040
29965
 
29966
+
29967
+ igv.Browser.prototype.on = function (eventName, fn) {
29968
+ if (!this.eventHandlers[eventName]) {
29969
+ this.eventHandlers[eventName] = [];
29970
+ }
29971
+ this.eventHandlers[eventName].push(fn);
29972
+ };
29973
+
29974
+ igv.Browser.prototype.un = function (eventName, fn) {
29975
+ if (!this.eventHandlers[eventName]) {
29976
+ return;
29977
+ }
29978
+
29979
+ var callbackIndex = this.eventHandlers[eventName].indexOf(fn);
29980
+ if (callbackIndex !== -1) {
29981
+ this.eventHandlers[eventName].splice(callbackIndex, 1);
29982
+ }
29983
+ };
29984
+
29985
+ igv.Browser.prototype.fireEvent = function (eventName, args, thisObj) {
29986
+ var scope,
29987
+ results;
29988
+
29989
+ if (undefined === this.eventHandlers[eventName]) {
29990
+ return undefined;
29991
+ }
29992
+
29993
+ scope = thisObj || window;
29994
+ results = _.map(this.eventHandlers[eventName], function (event) {
29995
+ return event.apply(scope, args);
29996
+ });
29997
+
29998
+ return _.first(results);
29999
+
30000
+ };
30001
+
30002
+ igv.Browser.prototype.loadSampleInformation = function (url) {
30003
+ var name = url;
30004
+ if (url instanceof File) {
30005
+ name = url.name;
30006
+ }
30007
+ var ext = name.substr(name.lastIndexOf('.') + 1);
30008
+ if (ext === 'fam') {
30009
+ igv.sampleInformation.loadPlinkFile(url);
30010
+ }
30011
+ };
30012
+
30041
30013
  function attachTrackContainerMouseHandlers(trackContainerDiv) {
30042
30014
 
30043
30015
  var $viewport,
@@ -30142,7 +30114,7 @@ var igv = (function (igv) {
30142
30114
  referenceFrame.start = maxStart;
30143
30115
  }
30144
30116
 
30145
- igv.browser.updateLocusSearchWithGenomicState(_.first(igv.browser.genomicStateList));
30117
+ igv.browser.updateLocusSearchWidget(_.first(igv.browser.genomicStateList));
30146
30118
 
30147
30119
  // igv.browser.repaint();
30148
30120
  igv.browser.repaintWithLocusIndex(viewport.genomicState.locusIndex);
@@ -30185,212 +30157,6 @@ var igv = (function (igv) {
30185
30157
 
30186
30158
  }
30187
30159
 
30188
-
30189
-
30190
-
30191
-
30192
- /**
30193
- * Public API search function
30194
- *
30195
- * @param feature
30196
- * @param callback - function to call
30197
- * @param force - force callback
30198
- */
30199
- igv.Browser.prototype.__depricated_search = function (feature, callback, force) {
30200
- var type,
30201
- chr,
30202
- start,
30203
- end,
30204
- searchConfig,
30205
- url,
30206
- result,
30207
- genomeID;
30208
-
30209
- // See if we're ready to respond to a search, if not just queue it up and return
30210
- if (igv.browser === undefined || igv.browser.genome === undefined) {
30211
- igv.browser.initialLocus = feature;
30212
- if (callback) {
30213
- callback();
30214
- }
30215
- return;
30216
- }
30217
-
30218
- if (igv.Browser.isLocusChrNameStartEnd(feature, this.genome, undefined)) {
30219
-
30220
- var success = igv.gotoLocusFeature(feature, this.genome, this);
30221
-
30222
- if ((force || true === success) && callback) {
30223
- callback();
30224
- }
30225
-
30226
- } else {
30227
-
30228
- // Try local feature cache first
30229
- result = this.featureDB[feature.toUpperCase()];
30230
- if (result) {
30231
-
30232
- handleSearchResult(result.name, result.chrName, result.start, result.end, "");
30233
-
30234
- } else if (this.searchConfig) {
30235
-
30236
- url = this.searchConfig.url.replace("$FEATURE$", feature);
30237
- searchConfig = this.searchConfig;
30238
-
30239
- if (url.indexOf("$GENOME$") > -1) {
30240
- var genomeId = this.genome.id ? this.genome.id : "hg19";
30241
- url = url.replace("$GENOME$", genomeId);
30242
- }
30243
-
30244
- igv.xhr.loadString(url).then(function (data) {
30245
-
30246
- var results = ("plain" === searchConfig.type) ? parseSearchResults(data) : JSON.parse(data),
30247
- r;
30248
-
30249
- if (searchConfig.resultsField) {
30250
- results = results[searchConfig.resultsField];
30251
- }
30252
-
30253
- if (results.length == 0) {
30254
- //alert('No feature found with name "' + feature + '"');
30255
- igv.presentAlert('No feature found with name "' + feature + '"', undefined);
30256
- }
30257
- else if (results.length == 1) {
30258
- // Just take the first result for now
30259
- // TODO - merge results, or ask user to choose
30260
-
30261
- r = results[0];
30262
- chr = r[searchConfig.chromosomeField];
30263
- start = r[searchConfig.startField] - searchConfig.coords;
30264
- end = r[searchConfig.endField];
30265
- type = r["featureType"] || r["type"];
30266
- handleSearchResult(feature, chr, start, end, type);
30267
- }
30268
- else {
30269
- presentSearchResults(results, searchConfig, feature);
30270
- }
30271
-
30272
- if (callback) callback();
30273
- });
30274
- }
30275
- }
30276
-
30277
- };
30278
-
30279
- igv.gotoLocusFeature = function (locusFeature, genome, browser) {
30280
-
30281
- var type,
30282
- tokens,
30283
- chr,
30284
- start,
30285
- end,
30286
- chrName,
30287
- startEnd,
30288
- center,
30289
- obj;
30290
-
30291
-
30292
- type = 'locus';
30293
- tokens = locusFeature.split(":");
30294
- chrName = genome.getChromosomeName(tokens[0]);
30295
- if (chrName) {
30296
- chr = genome.getChromosome(chrName);
30297
- }
30298
-
30299
- if (chr) {
30300
-
30301
- // returning undefined indicates locus is a chromosome name.
30302
- start = end = undefined;
30303
- if (1 === tokens.length) {
30304
- start = 0;
30305
- end = chr.bpLength;
30306
- } else {
30307
- startEnd = tokens[1].split("-");
30308
- start = Math.max(0, parseInt(startEnd[0].replace(/,/g, "")) - 1);
30309
- if (2 === startEnd.length) {
30310
- end = Math.min(chr.bpLength, parseInt(startEnd[1].replace(/,/g, "")));
30311
- if (end < 0) {
30312
- // This can happen from integer overflow
30313
- end = chr.bpLength;
30314
- }
30315
- }
30316
- }
30317
-
30318
- obj = {start: start, end: end};
30319
- igv.Browser.validateLocusExtent(chr, obj);
30320
-
30321
- start = obj.start;
30322
- end = obj.end;
30323
-
30324
- }
30325
-
30326
- if (undefined === chr || isNaN(start) || (start > end)) {
30327
- igv.presentAlert("Unrecognized feature or locus: " + locusFeature, undefined);
30328
- return false;
30329
- }
30330
-
30331
- browser.goto(chrName, start, end);
30332
- fireOnsearch.call(igv.browser, locusFeature, type);
30333
-
30334
- return true;
30335
- };
30336
-
30337
- function presentSearchResults(loci, config, feature) {
30338
-
30339
- igv.browser.$searchResultsTable.empty();
30340
- igv.browser.$searchResults.show();
30341
-
30342
- loci.forEach(function (locus) {
30343
-
30344
- var row = $('<tr>');
30345
- row.text(locus.locusString);
30346
-
30347
- row.click(function () {
30348
-
30349
- igv.browser.$searchResults.hide();
30350
-
30351
- handleSearchResult(
30352
- feature,
30353
- locus[config.chromosomeField],
30354
- locus[config.startField] - config.coords,
30355
- locus[config.endField],
30356
- (locus["featureType"] || locus["type"]));
30357
-
30358
- });
30359
-
30360
- igv.browser.$searchResultsTable.append(row);
30361
-
30362
- });
30363
-
30364
- }
30365
-
30366
- function handleSearchResult(name, chr, start, end, type) {
30367
-
30368
- igv.browser.selection = new igv.GtexSelection('gtex' === type || 'snp' === type ? {snp: name} : {gene: name});
30369
-
30370
- if (end === undefined) {
30371
- end = start + 1;
30372
- }
30373
- if (igv.browser.flanking) {
30374
- start = Math.max(0, start - igv.browser.flanking);
30375
- end += igv.browser.flanking; // TODO -- set max to chromosome length
30376
- }
30377
-
30378
- igv.browser.goto(chr, start, end);
30379
-
30380
- // Notify tracks (important for gtex). TODO -- replace this with some sort of event model ?
30381
- fireOnsearch.call(igv.browser, name, type);
30382
- }
30383
-
30384
- function fireOnsearch(feature, type) {
30385
- // Notify tracks (important for gtex). TODO -- replace this with some sort of event model ?
30386
- this.trackViews.forEach(function (tp) {
30387
- var track = tp.track;
30388
- if (track.onsearch) {
30389
- track.onsearch(feature, type);
30390
- }
30391
- });
30392
- }
30393
-
30394
30160
  return igv;
30395
30161
  })
30396
30162
  (igv || {});
@@ -31867,6 +31633,96 @@ var igv = (function (igv) {
31867
31633
 
31868
31634
  })(igv || {});
31869
31635
 
31636
+ /*
31637
+ * The MIT License (MIT)
31638
+ *
31639
+ * Copyright (c) 2016-2017 The Regents of the University of California
31640
+ * Author: Jim Robinson
31641
+ *
31642
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31643
+ * of this software and associated documentation files (the "Software"), to deal
31644
+ * in the Software without restriction, including without limitation the rights
31645
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31646
+ * copies of the Software, and to permit persons to whom the Software is
31647
+ * furnished to do so, subject to the following conditions:
31648
+ *
31649
+ * The above copyright notice and this permission notice shall be included in
31650
+ * all copies or substantial portions of the Software.
31651
+ *
31652
+ *
31653
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31654
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31655
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31656
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31657
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31658
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31659
+ * THE SOFTWARE.
31660
+ */
31661
+
31662
+ var igv = (function (igv) {
31663
+
31664
+
31665
+ igv.getDataWrapper = function(data) {
31666
+
31667
+ if (typeof(data) == 'string' || data instanceof String) {
31668
+ return new StringDataWrapper(data);
31669
+ } else {
31670
+ return new ByteArrayDataWrapper(data);
31671
+ }
31672
+ }
31673
+
31674
+
31675
+ // Data might be a string, or an UInt8Array
31676
+ var StringDataWrapper = function (string) {
31677
+ this.data = string;
31678
+ this.ptr = 0;
31679
+ }
31680
+
31681
+ StringDataWrapper.prototype.nextLine = function () {
31682
+ //return this.split(/\r\n|\n|\r/gm);
31683
+ var start = this.ptr,
31684
+ idx = this.data.indexOf('\n', start);
31685
+
31686
+ if (idx > 0) {
31687
+ this.ptr = idx + 1; // Advance pointer for next line
31688
+ return idx === start ? undefined : this.data.substring(start, idx).trim();
31689
+ }
31690
+ else {
31691
+ // Last line
31692
+ this.ptr = this.data.length;
31693
+ return (start >= this.data.length) ? undefined : this.data.substring(start).trim();
31694
+ }
31695
+ }
31696
+
31697
+
31698
+ var ByteArrayDataWrapper = function (array) {
31699
+ this.data = array;
31700
+ this.length = this.data.length;
31701
+ this.ptr = 0;
31702
+ }
31703
+
31704
+ ByteArrayDataWrapper.prototype.nextLine = function () {
31705
+
31706
+ var c, result;
31707
+ result = "";
31708
+
31709
+ if (this.ptr >= this.length) return undefined;
31710
+
31711
+ for (var i = this.ptr; i < this.length; i++) {
31712
+ c = String.fromCharCode(this.data[i]);
31713
+ if (c === '\r') continue;
31714
+ if (c === '\n') break;
31715
+ result = result + c;
31716
+ }
31717
+
31718
+ this.ptr = i + 1;
31719
+ return result;
31720
+ }
31721
+
31722
+
31723
+ return igv;
31724
+ })
31725
+ (igv || {});
31870
31726
  /*
31871
31727
  * The MIT License (MIT)
31872
31728
  *
@@ -32528,7 +32384,7 @@ var igv = (function (igv) {
32528
32384
  header,
32529
32385
  dataWrapper;
32530
32386
 
32531
- dataWrapper = getDataWrapper(data);
32387
+ dataWrapper = igv.getDataWrapper(data);
32532
32388
 
32533
32389
  while (line = dataWrapper.nextLine()) {
32534
32390
  if (line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) {
@@ -32565,7 +32421,7 @@ var igv = (function (igv) {
32565
32421
  format = this.format,
32566
32422
  delimiter = this.delimiter || "\t";
32567
32423
 
32568
- dataWrapper = getDataWrapper(data);
32424
+ dataWrapper = igv.getDataWrapper(data);
32569
32425
  i = 0;
32570
32426
 
32571
32427
  while (line = dataWrapper.nextLine()) {
@@ -33206,75 +33062,20 @@ var igv = (function (igv) {
33206
33062
  feature = {chr: chr, start: start, end: end};
33207
33063
 
33208
33064
  if (format.fields) {
33209
- format.fields.forEach(function (field, index) {
33210
- if (index != format.chr && index != format.start && index != format.end) {
33211
- feature[field] = tokens[index];
33212
- }
33213
- });
33214
- }
33215
-
33216
- return feature;
33217
-
33218
- }
33219
-
33220
- function getDataWrapper(data) {
33221
-
33222
- if (typeof(data) == 'string' || data instanceof String) {
33223
- return new StringDataWrapper(data);
33224
- } else {
33225
- return new ByteArrayDataWrapper(data);
33226
- }
33227
- }
33228
-
33229
-
33230
- // Data might be a string, or an UInt8Array
33231
- var StringDataWrapper = function (string) {
33232
- this.data = string;
33233
- this.ptr = 0;
33234
- }
33235
-
33236
- StringDataWrapper.prototype.nextLine = function () {
33237
- //return this.split(/\r\n|\n|\r/gm);
33238
- var start = this.ptr,
33239
- idx = this.data.indexOf('\n', start);
33240
-
33241
- if (idx > 0) {
33242
- this.ptr = idx + 1; // Advance pointer for next line
33243
- return idx === start ? undefined : this.data.substring(start, idx).trim();
33244
- }
33245
- else {
33246
- // Last line
33247
- this.ptr = this.data.length;
33248
- return (start >= this.data.length) ? undefined : this.data.substring(start).trim();
33249
- }
33250
- }
33251
-
33252
-
33253
- var ByteArrayDataWrapper = function (array) {
33254
- this.data = array;
33255
- this.length = this.data.length;
33256
- this.ptr = 0;
33257
- }
33258
-
33259
- ByteArrayDataWrapper.prototype.nextLine = function () {
33260
-
33261
- var c, result;
33262
- result = "";
33263
-
33264
- if (this.ptr >= this.length) return undefined;
33265
-
33266
- for (var i = this.ptr; i < this.length; i++) {
33267
- c = String.fromCharCode(this.data[i]);
33268
- if (c === '\r') continue;
33269
- if (c === '\n') break;
33270
- result = result + c;
33065
+ format.fields.forEach(function (field, index) {
33066
+ if (index != format.chr && index != format.start && index != format.end) {
33067
+ feature[field] = tokens[index];
33068
+ }
33069
+ });
33271
33070
  }
33272
33071
 
33273
- this.ptr = i + 1;
33274
- return result;
33072
+ return feature;
33073
+
33275
33074
  }
33276
33075
 
33277
33076
 
33077
+
33078
+
33278
33079
  return igv;
33279
33080
  })
33280
33081
  (igv || {});
@@ -34196,7 +33997,8 @@ var igv = (function (igv) {
34196
33997
  boxX, boxX1, // label should be centered between these two x-coordinates
34197
33998
  labelX, labelY,
34198
33999
  textFitsInBox,
34199
- selectedFeatureName = igv.FeatureTrack.selectedGene ? igv.FeatureTrack.selectedGene.toUpperCase() : undefined;
34000
+ selectedFeatureName = igv.FeatureTrack.selectedGene ? igv.FeatureTrack.selectedGene.toUpperCase() : undefined, // <= for juicebox
34001
+ selection = options.selection;
34200
34002
 
34201
34003
  // feature outside of viewable window
34202
34004
  if (featureX1 < windowX || featureX > windowX1) {
@@ -35524,22 +35326,6 @@ var igv = (function (igv) {
35524
35326
  })
35525
35327
  };
35526
35328
 
35527
- /**
35528
- * Handle an alt-click. TODO perhaps generalize this for all tracks (optional).
35529
- *
35530
- * @param genomicLocation
35531
- * @param referenceFrame
35532
- * @param event
35533
- */
35534
- igv.SegTrack.prototype.altClick = function (genomicLocation, referenceFrame, event) {
35535
-
35536
- // Define a region 5 "pixels" wide in genomic coordinates
35537
- var bpWidth = referenceFrame.toBP(2.5);
35538
-
35539
- this.sortSamples(referenceFrame.chrName, genomicLocation - bpWidth, genomicLocation + bpWidth, sortDirection);
35540
-
35541
- sortDirection = (sortDirection === "ASC" ? "DESC" : "ASC");
35542
- };
35543
35329
 
35544
35330
  igv.SegTrack.prototype.popupData = function (config) {
35545
35331
 
@@ -35591,7 +35377,15 @@ var igv = (function (igv) {
35591
35377
 
35592
35378
  clickHandler = function () {
35593
35379
 
35594
- self.altClick(config.genomicLocation, config.viewport.genomicState.referenceFrame);
35380
+ var genomicLocation = config.genomicLocation,
35381
+ referenceFrame = config.viewport.genomicState.referenceFrame;
35382
+
35383
+ // Define a region 5 "pixels" wide in genomic coordinates
35384
+ var bpWidth = referenceFrame.toBP(2.5);
35385
+
35386
+ self.sortSamples(referenceFrame.chrName, genomicLocation - bpWidth, genomicLocation + bpWidth, sortDirection);
35387
+
35388
+ sortDirection = (sortDirection === "ASC" ? "DESC" : "ASC");
35595
35389
 
35596
35390
  config.popover.hide();
35597
35391
 
@@ -37365,7 +37159,7 @@ var igv = (function (igv) {
37365
37159
  },
37366
37160
  decode: function (json) {
37367
37161
  // If specific callSetIds are specified filter to those
37368
- if (self.callSetIds) {
37162
+ if (self.callSetIds) {
37369
37163
  var filteredCallSets = [],
37370
37164
  csIdSet = new Set();
37371
37165
 
@@ -37399,39 +37193,40 @@ var igv = (function (igv) {
37399
37193
 
37400
37194
  var self = this;
37401
37195
 
37402
- return new Promise(function (fulfill, reject) {
37403
37196
 
37404
- self.readHeader().then(function (header) {
37197
+ return self.readHeader()
37198
+
37199
+ .then(function (header) {
37200
+ return getChrAliasTable()
37201
+ })
37405
37202
 
37406
- getChrAliasTable().then(function (chrAliasTable) {
37203
+ .then(function (chrAliasTable) {
37407
37204
 
37408
- var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr,
37409
- readURL = self.url + "/variants/search";
37205
+ var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr,
37206
+ readURL = self.url + "/variants/search";
37410
37207
 
37411
- igv.ga4ghSearch({
37412
- url: readURL,
37413
- fields: (self.includeCalls ? undefined : "nextPageToken,variants(id,variantSetId,names,referenceName,start,end,referenceBases,alternateBases,quality, filter, info)"),
37414
- body: {
37415
- "variantSetIds": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]),
37416
- "callSetIds": (self.callSetIds ? self.callSetIds : undefined),
37417
- "referenceName": queryChr,
37418
- "start": bpStart.toString(),
37419
- "end": bpEnd.toString(),
37420
- "pageSize": "10000"
37421
- },
37422
- decode: function (json) {
37423
- var variants = [];
37208
+ return igv.ga4ghSearch({
37209
+ url: readURL,
37210
+ fields: (self.includeCalls ? undefined : "nextPageToken,variants(id,variantSetId,names,referenceName,start,end,referenceBases,alternateBases,quality, filter, info)"),
37211
+ body: {
37212
+ "variantSetIds": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]),
37213
+ "callSetIds": (self.callSetIds ? self.callSetIds : undefined),
37214
+ "referenceName": queryChr,
37215
+ "start": bpStart.toString(),
37216
+ "end": bpEnd.toString(),
37217
+ "pageSize": "10000"
37218
+ },
37219
+ decode: function (json) {
37220
+ var variants = [];
37424
37221
 
37425
- json.variants.forEach(function (json) {
37426
- variants.push(igv.createGAVariant(json));
37427
- });
37222
+ json.variants.forEach(function (json) {
37223
+ variants.push(igv.createGAVariant(json));
37224
+ });
37428
37225
 
37429
- return variants;
37430
- }
37431
- }).then(fulfill).catch(reject);
37432
- }).catch(reject); // chr name map
37433
- }).catch(reject); // callsets
37434
- });
37226
+ return variants;
37227
+ }
37228
+ })
37229
+ })
37435
37230
 
37436
37231
 
37437
37232
  function getChrAliasTable() {
@@ -37649,14 +37444,14 @@ var igv = (function (igv) {
37649
37444
  igv.genomeIdLUT = function (string) {
37650
37445
 
37651
37446
  var lut =
37652
- {
37653
- dm3:'dm3',
37654
- mm10:'mm10',
37655
- hg19:'hg19',
37656
- hg38:'GRCh38'
37657
- };
37447
+ {
37448
+ dm3: 'dm3',
37449
+ mm10: 'mm10',
37450
+ hg19: 'hg19',
37451
+ hg38: 'GRCh38'
37452
+ };
37658
37453
 
37659
- return lut[ string ];
37454
+ return lut[string];
37660
37455
  };
37661
37456
 
37662
37457
  igv.loadGenome = function (reference) {
@@ -38044,39 +37839,29 @@ var igv = (function (igv) {
38044
37839
 
38045
37840
  }
38046
37841
 
38047
- // Static definition of known genome identifiers
38048
- igv.Genome.KnownGenomes = {
38049
- "hg18": {
38050
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg18/hg18.fasta",
38051
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg18/cytoBand.txt.gz"
38052
- },
38053
- "GRCh38": {
38054
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa",
38055
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/hg38/cytoBandIdeo.txt"
38056
- },
38057
- "hg38": {
38058
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa",
38059
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/hg38/cytoBandIdeo.txt"
38060
- },
38061
- "hg19": {
38062
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta",
38063
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/cytoBand.txt"
38064
- },
38065
- "GRCh37": {
38066
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta",
38067
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/cytoBand.txt"
38068
- },
38069
37842
 
38070
- "mm10": {
38071
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/mm10/mm10.fa",
38072
- indexURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/mm10/mm10.fa.fai",
38073
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/mm10/cytoBandIdeo.txt.gz"
38074
- },
38075
- "GRCm38": {
38076
- fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/mm10/mm10.fa",
38077
- indexURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/mm10/mm10.fa.fai",
38078
- cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/mm10/cytoBandIdeo.txt.gz"
37843
+ igv.Genome.getKnownGenomes = function () {
37844
+
37845
+ if (igv.Genome.KnownGenomes) {
37846
+ return Promise.resolve(igv.Genome.KnownGenomes)
37847
+ }
37848
+ else {
37849
+ return igv.xhr.loadJson("https://s3.amazonaws.com/igv.org.genomes/genomes.json", {})
37850
+ .then(function (jsonArray) {
37851
+
37852
+ var table = {};
37853
+
37854
+ jsonArray.forEach(function (json) {
37855
+ table[json.id] = json;
37856
+ });
37857
+
37858
+ igv.Genome.KnownGenomes = table;
37859
+
37860
+ return table;
37861
+ })
37862
+
38079
37863
  }
37864
+
38080
37865
  }
38081
37866
 
38082
37867
  return igv;
@@ -38123,7 +37908,8 @@ var igv = (function (igv) {
38123
37908
  this.url = url;
38124
37909
  this.name = label;
38125
37910
  this.pValueField = config.pValueField || "pValue";
38126
- this.geneField = config.geneField || "geneName";
37911
+ this.geneField = config.geneField || "geneSymbol";
37912
+ this.snpField = config.snpField || "snp";
38127
37913
 
38128
37914
  this.autoscale = (config.autoScale === undefined ? true : config.autoScale);
38129
37915
  this.percentile = (config.percentile === undefined ? 98 : config.percentile);
@@ -38140,11 +37926,7 @@ var igv = (function (igv) {
38140
37926
 
38141
37927
  this.featureSource = new igv.FeatureSource(config);
38142
37928
 
38143
-
38144
- this.onsearch = function (feature, source) {
38145
- selectedFeature.call(this, feature, source);
38146
- }
38147
- }
37929
+ };
38148
37930
 
38149
37931
  igv.EqtlTrack.prototype.paintAxis = function (ctx, pixelWidth, pixelHeight) {
38150
37932
 
@@ -38195,7 +37977,7 @@ var igv = (function (igv) {
38195
37977
 
38196
37978
  igv.EqtlTrack.prototype.getFeatures = function (chr, bpStart, bpEnd) {
38197
37979
  return this.featureSource.getFeatures(chr, bpStart, bpEnd);
38198
- }
37980
+ };
38199
37981
 
38200
37982
  igv.EqtlTrack.prototype.draw = function (options) {
38201
37983
 
@@ -38207,7 +37989,8 @@ var igv = (function (igv) {
38207
37989
  pixelWidth = options.pixelWidth,
38208
37990
  pixelHeight = options.pixelHeight,
38209
37991
  bpEnd = bpStart + pixelWidth * bpPerPixel + 1,
38210
- yScale = (self.maxLogP - self.minLogP) / pixelHeight;
37992
+ yScale = (self.maxLogP - self.minLogP) / pixelHeight,
37993
+ selection = options.genomicState.selection;
38211
37994
 
38212
37995
  // Background
38213
37996
  if (this.background) igv.graphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background});
@@ -38254,7 +38037,6 @@ var igv = (function (igv) {
38254
38037
  isSelected,
38255
38038
  snp,
38256
38039
  geneName,
38257
- selection,
38258
38040
  capped;
38259
38041
 
38260
38042
  for (i = 0; i < len; i++) {
@@ -38267,7 +38049,7 @@ var igv = (function (igv) {
38267
38049
 
38268
38050
  snp = eqtl.snp.toUpperCase();
38269
38051
  geneName = eqtl[self.geneField].toUpperCase();
38270
- selection = options.genomicState.selection;
38052
+
38271
38053
  isSelected = selection &&
38272
38054
  (selection.snp === snp || selection.gene === geneName);
38273
38055
 
@@ -38309,17 +38091,7 @@ var igv = (function (igv) {
38309
38091
  }
38310
38092
  }
38311
38093
 
38312
- }
38313
-
38314
- function selectedFeature(feature, source) {
38315
- console.log(feature + " " + source);
38316
-
38317
- // TODO -- temporary hack, determine type from the source
38318
- var type = source === "gtex" ? "snp" : "gene";
38319
-
38320
- this.selection = new GtexSelection(type == 'gene' ? {gene: feature} : {snp: feature});
38321
- igv.browser.update();
38322
- }
38094
+ };
38323
38095
 
38324
38096
  /**
38325
38097
  * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs
@@ -38367,70 +38139,7 @@ var igv = (function (igv) {
38367
38139
  }
38368
38140
  }
38369
38141
  }
38370
-
38371
- GtexSelection = function (selection) {
38372
-
38373
- this.geneColors = {};
38374
- this.gene = null;
38375
- this.snp = null;
38376
- this.genesCount = 0;
38377
-
38378
- if (selection.gene) {
38379
- this.gene = selection.gene.toUpperCase();
38380
- this.geneColors[this.gene] = brewer[this.genesCount++];
38381
-
38382
- }
38383
- if (selection.snp) {
38384
- this.snp = selection.snp.toUpperCase();
38385
- }
38386
-
38387
- }
38388
-
38389
- GtexSelection.prototype.addGene = function (geneName) {
38390
- if (!this.geneColors[geneName.toUpperCase()]) {
38391
- this.geneColors[geneName.toUpperCase()] = brewer[this.genesCount++];
38392
- }
38393
- }
38394
-
38395
- GtexSelection.prototype.colorForGene = function (geneName) {
38396
- return this.geneColors[geneName.toUpperCase()];
38397
- }
38398
-
38399
- var brewer = new Array();
38400
- // Set +!
38401
- brewer.push("rgb(228,26,28)");
38402
- brewer.push("rgb(55,126,184)");
38403
- brewer.push("rgb(77,175,74)");
38404
- brewer.push("rgb(166,86,40)");
38405
- brewer.push("rgb(152,78,163)");
38406
- brewer.push("rgb(255,127,0)");
38407
- brewer.push("rgb(247,129,191)");
38408
- brewer.push("rgb(153,153,153)");
38409
- brewer.push("rgb(255,255,51)");
38410
-
38411
- // #Set 2
38412
- brewer.push("rgb(102, 194, 165");
38413
- brewer.push("rgb(252, 141, 98");
38414
- brewer.push("rgb(141, 160, 203");
38415
- brewer.push("rgb(231, 138, 195");
38416
- brewer.push("rgb(166, 216, 84");
38417
- brewer.push("rgb(255, 217, 47");
38418
- brewer.push("rgb(229, 196, 148");
38419
- brewer.push("rgb(179, 179, 179");
38420
-
38421
- //#Set 3
38422
- brewer.push("rgb( 141, 211, 199");
38423
- brewer.push("rgb(255, 255, 179");
38424
- brewer.push("rgb(190, 186, 218");
38425
- brewer.push("rgb(251, 128, 114");
38426
- brewer.push("rgb(128, 177, 211");
38427
- brewer.push("rgb(253, 180, 98");
38428
- brewer.push("rgb(179, 222, 105");
38429
- brewer.push("rgb(252, 205, 229");
38430
- brewer.push("rgb(217, 217, 217");
38431
- brewer.push("rgb(188, 128, 189");
38432
- brewer.push("rgb(204, 235, 197");
38433
- brewer.push("rgb(255, 237, 111");
38142
+
38434
38143
 
38435
38144
  return igv;
38436
38145
 
@@ -38464,20 +38173,20 @@ var igv = (function (igv) {
38464
38173
  var igv = (function (igv) {
38465
38174
 
38466
38175
 
38467
- igv.GtexSelection = function (selection) {
38176
+ igv.GtexSelection = function (gene, snp) {
38468
38177
 
38469
38178
  this.geneColors = {};
38470
38179
  this.gene = null;
38471
38180
  this.snp = null;
38472
38181
  this.genesCount = 0;
38473
38182
 
38474
- if (selection.gene) {
38475
- this.gene = selection.gene.toUpperCase();
38183
+ if (gene) {
38184
+ this.gene = gene.toUpperCase();
38476
38185
  this.geneColors[this.gene] = brewer[this.genesCount++];
38477
38186
 
38478
38187
  }
38479
- if (selection.snp) {
38480
- this.snp = selection.snp.toUpperCase();
38188
+ if (snp) {
38189
+ this.snp = snp.toUpperCase();
38481
38190
  }
38482
38191
 
38483
38192
  }
@@ -40389,7 +40098,7 @@ var igv = (function (igv) {
40389
40098
  referenceFrame.start = Math.round((xPercentage - (chrCoveragePercentage/2.0)) * chr.bpLength);
40390
40099
  referenceFrame.bpPerPixel = (ee - ss)/ panel.$ideogram.width();
40391
40100
 
40392
- igv.browser.updateLocusSearchWithGenomicState(genomicState);
40101
+ igv.browser.updateLocusSearchWidget(genomicState);
40393
40102
 
40394
40103
  igv.browser.repaintWithLocusIndex( panel.genomicState.locusIndex )
40395
40104
 
@@ -41262,23 +40971,28 @@ var igv = (function (igv) {
41262
40971
 
41263
40972
  var width;
41264
40973
 
41265
- // Potentially load a session file
41266
- loadSessionFile()
40974
+ // Load known genome table (make this optional)
40975
+
40976
+ igv.Genome.getKnownGenomes()
40977
+ .then(function (genomeTable) {
40978
+ // Potentially load a session file
40979
+ return loadSessionFile();
40980
+ })
41267
40981
 
41268
40982
  .then(function (session) {
41269
40983
 
41270
40984
  if (session) {
41271
40985
  config = Object.assign(config, session);
41272
- if(undefined === config.tracks) config.tracks = [];
40986
+ if (undefined === config.tracks) config.tracks = [];
41273
40987
  config.tracks.push({type: "sequence", order: -Number.MAX_VALUE});
41274
40988
  }
41275
40989
 
41276
- // Deal with legacy genome definition options
40990
+ // Expand genome IDs and deal with legacy genome definition options
41277
40991
  setReferenceConfiguration(config);
41278
40992
 
41279
40993
  // Query parameter locus has precendence
41280
40994
  var initialLocus = extractLocus();
41281
- if(initialLocus) config.locus = initialLocus;
40995
+ if (initialLocus) config.locus = initialLocus;
41282
40996
 
41283
40997
  return config;
41284
40998
  })
@@ -41295,7 +41009,7 @@ var igv = (function (igv) {
41295
41009
  igv.browser.genome.id = config.reference.id;
41296
41010
 
41297
41011
  if (true === config.encodeEnabled) {
41298
- igv.browser.encodeTable.loadData();
41012
+ igv.browser.encodeTable.loadData(config.reference.id, undefined, undefined, undefined);
41299
41013
  }
41300
41014
 
41301
41015
  igv.browser.chromosomeSelectWidget.update(igv.browser.genome);
@@ -41318,7 +41032,7 @@ var igv = (function (igv) {
41318
41032
  return genomicState;
41319
41033
  });
41320
41034
 
41321
- igv.browser.updateLocusSearchWithGenomicState(_.first(igv.browser.genomicStateList));
41035
+ igv.browser.updateLocusSearchWidget(_.first(igv.browser.genomicStateList));
41322
41036
 
41323
41037
  igv.browser.zoomWidgetLayout();
41324
41038
 
@@ -42425,6 +42139,8 @@ var igv = (function (igv) {
42425
42139
 
42426
42140
  igv.presentAlert = function (alert, $parent) {
42427
42141
 
42142
+ console.error(alert);
42143
+
42428
42144
  var string;
42429
42145
 
42430
42146
  string = alert.message || alert;
@@ -45046,7 +44762,7 @@ var igv = (function (igv) {
45046
44762
  tickDivisor = tickDivisors[tickKeys[index]];
45047
44763
 
45048
44764
  number = Math.round(tickLabelNumber / tickDivisor);
45049
- string = igv.numberFormatter(number) + tickUnit;
44765
+ string = igv.numberFormatter(number) + ' ' + tickUnit;
45050
44766
 
45051
44767
  return string;
45052
44768
  }
@@ -45099,10 +44815,10 @@ var igv = (function (igv) {
45099
44815
  tickUnits[5e3.toString()] = 'kb';
45100
44816
  tickUnits[1e3.toString()] = 'kb';
45101
44817
 
45102
- tickUnits[5e2.toString()] = 'b';
45103
- tickUnits[1e2.toString()] = 'b';
45104
- tickUnits[5e1.toString()] = 'b';
45105
- tickUnits[1e1.toString()] = 'b';
44818
+ tickUnits[5e2.toString()] = '';
44819
+ tickUnits[1e2.toString()] = '';
44820
+ tickUnits[5e1.toString()] = '';
44821
+ tickUnits[1e1.toString()] = '';
45106
44822
 
45107
44823
  return tickUnits;
45108
44824
  }
@@ -50215,7 +49931,7 @@ var igv = (function (igv) {
50215
49931
  variant.type = 'str';
50216
49932
  }
50217
49933
 
50218
- initAlleles(variant);
49934
+ initAlleles(variant, true);
50219
49935
 
50220
49936
 
50221
49937
  return variant;
@@ -50240,7 +49956,9 @@ var igv = (function (igv) {
50240
49956
  var variant = new igv.Variant();
50241
49957
 
50242
49958
  variant.chr = json.referenceName;
50243
- variant.pos = parseInt(json.start);
49959
+ variant.start = parseInt(json.start);
49960
+ variant.end = parseInt(json.end);
49961
+ variant.pos = variant.start + 1; // GA4GH is not 0 based.
50244
49962
  variant.names = arrayToCommaString(json.names);
50245
49963
  variant.referenceBases = json.referenceBases + '';
50246
49964
  variant.alternateBases = json.alternateBases + '';
@@ -50248,6 +49966,10 @@ var igv = (function (igv) {
50248
49966
  variant.filter = arrayToCommaString(json.filter);
50249
49967
  variant.info = json.info;
50250
49968
 
49969
+ if(variant.pos === 155158842) {
49970
+ console.log('');
49971
+ }
49972
+
50251
49973
  if (variant.info["PERIOD"]) {
50252
49974
  variant.type = 'str';
50253
49975
  }
@@ -50270,14 +49992,14 @@ var igv = (function (igv) {
50270
49992
  })
50271
49993
  }
50272
49994
 
50273
- initAlleles(variant);
49995
+ initAlleles(variant, false);
50274
49996
 
50275
49997
  return variant;
50276
49998
 
50277
49999
  }
50278
50000
 
50279
50001
 
50280
- function initAlleles(variant) {
50002
+ function initAlleles(variant, computeStartEnd) {
50281
50003
 
50282
50004
  //Alleles
50283
50005
  var altTokens = variant.alternateBases.split(","),
@@ -50305,7 +50027,7 @@ var igv = (function (igv) {
50305
50027
 
50306
50028
  // Adjust for padding, used for insertions and deletions, unless variant is a short tandem repeat.
50307
50029
 
50308
- if (!('str' === variant.type) && alt.length > 0) {
50030
+ if (!('str' === variant.type) && alt.length > 0 && computeStartEnd) {
50309
50031
 
50310
50032
  diff = variant.referenceBases.length - alt.length;
50311
50033
 
@@ -50459,8 +50181,8 @@ var igv = (function (igv) {
50459
50181
  this.variantHeight = config.variantHeight || 10;
50460
50182
  this.squishedCallHeight = config.squishedCallHeight || 1;
50461
50183
  this.expandedCallHeight = config.expandedCallHeight || 10;
50462
- this.expandedVGap = config.expandedVGap !== undefined ? config.expandedVGap : 2;
50463
- this.squishedVGap = config.squishedVGap !== undefined ? config.squishedVGap : 1;
50184
+ this.expandedVGap = config.expandedVGap !== undefined ? config.expandedVGap : 2;
50185
+ this.squishedVGap = config.squishedVGap !== undefined ? config.squishedVGap : 1;
50464
50186
 
50465
50187
  this.expandedGroupGap = config.expandedGroupGap || 10;
50466
50188
  this.squishedGroupGap = config.squishedGroupGap || 5;
@@ -50481,10 +50203,14 @@ var igv = (function (igv) {
50481
50203
  igv.VariantTrack.prototype.getFileHeader = function () {
50482
50204
  var self = this;
50483
50205
 
50484
- return new Promise(function (fulfill, reject) {
50485
- if (typeof self.featureSource.getFileHeader === "function") {
50486
- self.featureSource.getFileHeader().then(function (header) {
50206
+ if (typeof self.featureSource.getFileHeader === "function") {
50207
+
50208
+ return self.featureSource.getFileHeader()
50209
+
50210
+ .then(function (header) {
50211
+
50487
50212
  if (header) {
50213
+
50488
50214
  // Header (from track line). Set properties,unless set in the config (config takes precedence)
50489
50215
  if (header.name && !self.config.name) {
50490
50216
  self.name = header.name;
@@ -50501,20 +50227,21 @@ var igv = (function (igv) {
50501
50227
  computeVisibilityWindow.call(self);
50502
50228
  }
50503
50229
  }
50504
- fulfill(header);
50230
+ return header;
50231
+
50232
+ })
50233
+ }
50234
+ else {
50235
+ return Promise.resolve(null);
50236
+ }
50505
50237
 
50506
- }).catch(reject);
50507
- }
50508
- else {
50509
- fulfill(null);
50510
- }
50511
- });
50512
50238
  }
50513
50239
 
50514
50240
  function getCallsetsLength() {
50515
- var length = 0, callSets = this.callSets;
50516
- Object.keys(callSets).forEach(function(key) {
50517
- length += callSets[key].length;
50241
+ var length = 0,
50242
+ callSets = this.callSets;
50243
+ Object.keys(callSets).forEach(function (key) {
50244
+ if (callSets[key]) length += callSets[key].length;
50518
50245
  });
50519
50246
  return length;
50520
50247
  }
@@ -50541,16 +50268,7 @@ var igv = (function (igv) {
50541
50268
  }
50542
50269
 
50543
50270
  igv.VariantTrack.prototype.getFeatures = function (chr, bpStart, bpEnd) {
50544
-
50545
- var self = this;
50546
-
50547
- return new Promise(function (fulfill, reject) {
50548
-
50549
- self.featureSource.getFeatures(chr, bpStart, bpEnd).then(function (features) {
50550
- fulfill(features);
50551
- }).catch(reject);
50552
-
50553
- });
50271
+ return this.featureSource.getFeatures(chr, bpStart, bpEnd);
50554
50272
  }
50555
50273
 
50556
50274
 
@@ -50591,7 +50309,6 @@ var igv = (function (igv) {
50591
50309
  this.nRows = nRows; // Needed in draw function
50592
50310
 
50593
50311
 
50594
-
50595
50312
  // if ((nCalls * nRows * this.expandedCallHeight) > 2000) {
50596
50313
  // this.expandedCallHeight = Math.max(1, 2000 / (nCalls * nRows));
50597
50314
  // }
@@ -50660,7 +50377,7 @@ var igv = (function (igv) {
50660
50377
  } else if (period > 6) {
50661
50378
  period = 6;
50662
50379
  }
50663
- ctx.fillStyle = variantColors[period-1];
50380
+ ctx.fillStyle = variantColors[period - 1];
50664
50381
  } else {
50665
50382
  ctx.fillStyle = this.color;
50666
50383
  }
@@ -50671,7 +50388,7 @@ var igv = (function (igv) {
50671
50388
 
50672
50389
  h = callHeight;
50673
50390
 
50674
- if('str' === variant.type) {
50391
+ if ('str' === variant.type) {
50675
50392
  lowColorScale = new igv.GradientColorScale(
50676
50393
  {
50677
50394
  low: variant.minAltLength,
@@ -50706,7 +50423,7 @@ var igv = (function (igv) {
50706
50423
  call = variant.calls[callSet.id];
50707
50424
  if (call) {
50708
50425
 
50709
- py = self.variantBandHeight + vGap + (callsDrawn + variant.row) * (h + vGap) + (j*groupGap);
50426
+ py = self.variantBandHeight + vGap + (callsDrawn + variant.row) * (h + vGap) + (j * groupGap);
50710
50427
 
50711
50428
  if (!('str' === variant.type)) {
50712
50429
 
@@ -50791,7 +50508,7 @@ var igv = (function (igv) {
50791
50508
  function sortCallSets(callSets, variant, direction) {
50792
50509
  var d = (direction === "DESC") ? 1 : -1;
50793
50510
  Object.keys(callSets).forEach(function (property) {
50794
- callSets[property].sort(function(a,b) {
50511
+ callSets[property].sort(function (a, b) {
50795
50512
  var aNan = isNaN(variant.calls[a.id].genotype[0]);
50796
50513
  var bNan = isNaN(variant.calls[b.id].genotype[0]);
50797
50514
  if (aNan && bNan) {
@@ -50816,6 +50533,7 @@ var igv = (function (igv) {
50816
50533
  }
50817
50534
 
50818
50535
  igv.VariantTrack.prototype.altClick = function (genomicLocation, referenceFrame, event) {
50536
+
50819
50537
  var chr = referenceFrame.chrName,
50820
50538
  tolerance = Math.floor(2 * referenceFrame.bpPerPixel), // We need some tolerance around genomicLocation, start with +/- 2 pixels
50821
50539
  featureList = this.featureSource.featureCache.queryFeatures(chr, genomicLocation - tolerance, genomicLocation + tolerance),
@@ -50841,7 +50559,7 @@ var igv = (function (igv) {
50841
50559
 
50842
50560
  /**
50843
50561
  * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs
50844
- */
50562
+ */
50845
50563
  igv.VariantTrack.prototype.popupData = function (config) {
50846
50564
 
50847
50565
  var genomicLocation = config.genomicLocation,
@@ -50896,8 +50614,8 @@ var igv = (function (igv) {
50896
50614
  for (group = 0; group < self.callSetGroups.length; group++) {
50897
50615
  var groupName = self.callSetGroups[group];
50898
50616
  var groupCalls = callSets[groupName].length;
50899
- if (yOffset <= self.variantBandHeight + vGap + (totalCalls+groupCalls) *
50900
- (callHeight + vGap) + (group * groupGap)) {
50617
+ if (yOffset <= self.variantBandHeight + vGap + (totalCalls + groupCalls) *
50618
+ (callHeight + vGap) + (group * groupGap)) {
50901
50619
  row = Math.floor((yOffset - (self.variantBandHeight + vGap + totalCalls * (callHeight + vGap)
50902
50620
  + (group * groupGap))) / (callHeight + vGap));
50903
50621
  break;
@@ -50937,7 +50655,7 @@ var igv = (function (igv) {
50937
50655
  allele = getAlleleString(call, variant, i);
50938
50656
  gt += allele;
50939
50657
  numRepeats += (allele.length / info.PERIOD).toString();
50940
- var ac = (call.genotype[i] === 0) ? info.REFAC : alt_ac[call.genotype[i]-1];
50658
+ var ac = (call.genotype[i] === 0) ? info.REFAC : alt_ac[call.genotype[i] - 1];
50941
50659
  alleleFrac += (parseInt(ac) / parseInt(info.AN)).toFixed(3);
50942
50660
  if (i < call.genotype.length - 1) {
50943
50661
  gt += " | ";
@@ -50978,8 +50696,8 @@ var igv = (function (igv) {
50978
50696
 
50979
50697
  var attr = igv.sampleInformation.getAttributes(call.callSetName);
50980
50698
  if (attr) {
50981
- Object.keys(attr).forEach(function(attrName) {
50982
- var displayText = attrName.replace( /([A-Z])/g, " $1" );
50699
+ Object.keys(attr).forEach(function (attrName) {
50700
+ var displayText = attrName.replace(/([A-Z])/g, " $1");
50983
50701
  displayText = displayText.charAt(0).toUpperCase() + displayText.slice(1);
50984
50702
  popupData.push({name: displayText, value: attr[attrName]});
50985
50703
  });
@@ -50996,19 +50714,19 @@ var igv = (function (igv) {
50996
50714
  return popupData;
50997
50715
  }
50998
50716
 
50999
- igv.VariantTrack.prototype.popupMenuItemList = function(config) {
50717
+ igv.VariantTrack.prototype.popupMenuItemList = function (config) {
51000
50718
  var menuItems = [];
51001
50719
  var self = this;
51002
50720
 
51003
50721
  if (this.groupBy !== 'NONE' && igv.sampleInformation.hasAttributes()) {
51004
50722
  menuItems.push({
51005
50723
  name: 'Sort groups',
51006
- click: function() {
50724
+ click: function () {
51007
50725
  try {
51008
- self.callSetGroups.sort(function(a,b) {
51009
- return a-b;
50726
+ self.callSetGroups.sort(function (a, b) {
50727
+ return a - b;
51010
50728
  });
51011
- } catch(err) {
50729
+ } catch (err) {
51012
50730
  self.callSetGroups.sort();
51013
50731
  }
51014
50732
  self.trackView.update();
@@ -51018,7 +50736,6 @@ var igv = (function (igv) {
51018
50736
  }
51019
50737
 
51020
50738
 
51021
-
51022
50739
  var referenceFrame = config.viewport.genomicState.referenceFrame,
51023
50740
  genomicLocation = config.genomicLocation,
51024
50741
  chr = referenceFrame.chrName,
@@ -51054,11 +50771,11 @@ var igv = (function (igv) {
51054
50771
 
51055
50772
  };
51056
50773
 
51057
- igv.VariantTrack.prototype.groupCallSets = function(attribute) {
50774
+ igv.VariantTrack.prototype.groupCallSets = function (attribute) {
51058
50775
  var groupedCallSets = {}, callSetGroups = [], group, attr, key, self = this;
51059
- Object.keys(this.callSets).forEach(function(i) {
50776
+ Object.keys(this.callSets).forEach(function (i) {
51060
50777
  group = self.callSets[i];
51061
- group.forEach(function(callSet) {
50778
+ group.forEach(function (callSet) {
51062
50779
  key = 'NONE';
51063
50780
  if (attribute !== 'NONE') {
51064
50781
  attr = igv.sampleInformation.getAttributes(callSet.name);
@@ -51106,8 +50823,8 @@ var igv = (function (igv) {
51106
50823
 
51107
50824
  var attrs = {};
51108
50825
  var attributes = igv.sampleInformation.getAttributeNames();
51109
- attributes.forEach(function(attribute) {
51110
- var result = attribute.replace( /([A-Z])/g, " $1" );
50826
+ attributes.forEach(function (attribute) {
50827
+ var result = attribute.replace(/([A-Z])/g, " $1");
51111
50828
  result = result.charAt(0).toUpperCase() + result.slice(1);
51112
50829
  attrs[attribute] = result;
51113
50830
  });
@@ -51205,12 +50922,10 @@ var igv = (function (igv) {
51205
50922
 
51206
50923
  igv.VcfParser.prototype.parseHeader = function (data) {
51207
50924
 
51208
- var lines = data.splitLines(),
51209
- len = lines.length,
50925
+ var dataWrapper,
50926
+ tokens,
51210
50927
  line,
51211
- i,
51212
50928
  j,
51213
- tokens,
51214
50929
  header = {},
51215
50930
  id,
51216
50931
  values,
@@ -51218,16 +50933,19 @@ var igv = (function (igv) {
51218
50933
  gtIdx,
51219
50934
  type;
51220
50935
 
50936
+ dataWrapper = igv.getDataWrapper(data);
50937
+
51221
50938
  // First line must be file format
51222
- if (lines[0].startsWith("##fileformat")) {
51223
- header.version = lines[0].substr(13);
50939
+ line = dataWrapper.nextLine();
50940
+ if (line.startsWith("##fileformat")) {
50941
+ header.version = line.substr(13);
51224
50942
  }
51225
50943
  else {
51226
50944
  throw new Error("Invalid VCF file: missing fileformat line");
51227
50945
  }
51228
50946
 
51229
- for (i = 1; i < len; i++) {
51230
- line = lines[i].trim();
50947
+ while (line = dataWrapper.nextLine()) {
50948
+
51231
50949
  if (line.startsWith("#")) {
51232
50950
 
51233
50951
  id = null;
@@ -51325,17 +51043,20 @@ var igv = (function (igv) {
51325
51043
  */
51326
51044
  igv.VcfParser.prototype.parseFeatures = function (data) {
51327
51045
 
51328
- var lines = data.split("\n"),
51046
+ var dataWrapper,
51047
+ line,
51329
51048
  allFeatures = [],
51330
- callSets = this.header.callSets;
51049
+ callSets = this.header.callSets,
51050
+ variant,
51051
+ tokens,
51052
+ callFields,
51053
+ index,
51054
+ token;
51331
51055
 
51332
- lines.forEach(function (line) {
51333
51056
 
51334
- var variant,
51335
- tokens,
51336
- callFields,
51337
- index,
51338
- token;
51057
+ dataWrapper = igv.getDataWrapper(data);
51058
+
51059
+ while (line = dataWrapper.nextLine()) {
51339
51060
 
51340
51061
  if (!line.startsWith("#")) {
51341
51062
 
@@ -51385,127 +51106,11 @@ var igv = (function (igv) {
51385
51106
 
51386
51107
  }
51387
51108
  }
51388
- });
51109
+ }
51389
51110
 
51390
51111
  return allFeatures;
51391
-
51392
51112
  }
51393
51113
 
51394
- // Variant class moved to variant.js
51395
- //
51396
- // function Variant(tokens) {
51397
- //
51398
- // var self = this,
51399
- // altTokens;
51400
- //
51401
- // this.chr = tokens[0]; // TODO -- use genome aliases
51402
- // this.pos = parseInt(tokens[1]);
51403
- // this.names = tokens[2]; // id in VCF
51404
- // this.referenceBases = tokens[3];
51405
- // this.alternateBases = tokens[4];
51406
- // this.quality = parseInt(tokens[5]);
51407
- // this.filter = tokens[6];
51408
- // this.info = tokens[7];
51409
- //
51410
- // // "ids" ("names" in ga4gh)
51411
- //
51412
- // //Alleles
51413
- // altTokens = this.alternateBases.split(",");
51414
- //
51415
- // if (altTokens.length > 0) {
51416
- //
51417
- // this.alleles = [];
51418
- //
51419
- // this.start = Number.MAX_VALUE;
51420
- // this.end = 0;
51421
- //
51422
- // altTokens.forEach(function (alt) {
51423
- // var a, s, e, diff;
51424
- // if (alt.length > 0) {
51425
- //
51426
- // diff = self.referenceBases.length - alt.length;
51427
- //
51428
- // if (diff > 0) {
51429
- // // deletion, assume left padded
51430
- // s = self.pos - 1 + alt.length;
51431
- // e = s + diff;
51432
- // } else if (diff < 0) {
51433
- // // Insertion, assume left padded, insertion begins to "right" of last ref base
51434
- // s = self.pos - 1 + self.referenceBases.length;
51435
- // e = s + 1; // Insertion between s & 3
51436
- // }
51437
- // else {
51438
- // // Substitution, SNP if seq.length == 1
51439
- // s = self.pos - 1;
51440
- // e = s + alt.length;
51441
- // }
51442
- // self.alleles.push({allele: alt, start: s, end: e});
51443
- // self.start = Math.min(self.start, s);
51444
- // self.end = Math.max(self.end, e);
51445
- // }
51446
- //
51447
- // });
51448
- // }
51449
- // else {
51450
- // // Is this even legal VCF? (NO alt alleles)
51451
- // this.start = this.pos - 1;
51452
- // this.end = this.pos;
51453
- // }
51454
- //
51455
- // // TODO -- genotype fields
51456
- // }
51457
- //
51458
- // Variant.prototype.popupData = function (genomicLocation, type) {
51459
- //
51460
- // var fields, infoFields, nameString;
51461
- //
51462
- // //infoFields = this.info.split(";");
51463
- // var info = this.getInfoObj(this.info);
51464
- //
51465
- // fields = [
51466
- // {name: "Names", value: this.names},
51467
- // {name: "Ref", value: this.referenceBases},
51468
- // {name: "Alt", value: this.alternateBases},
51469
- // {name: "Qual", value: this.quality},
51470
- // {name: "Filter", value: this.filter},
51471
- // ];
51472
- //
51473
- // if ('str' === type) {
51474
- // fields.push({
51475
- // name: "Heterozygosity",
51476
- // value: (info.AC && info.AN) ? this.calcHeterozygosity(info.AC, info.AN).toFixed(3) : 1
51477
- // });
51478
- // }
51479
- //
51480
- // Object.keys(info).forEach(function (key) {
51481
- // fields.push({name: key, value: info[key]});
51482
- // })
51483
- //
51484
- //
51485
- // return fields;
51486
- //
51487
- // }
51488
- //
51489
- // Variant.prototype.getInfoObj = function (infoStr) {
51490
- // var info = {};
51491
- // infoStr.split(';').forEach(function (elem) {
51492
- // var element = elem.split('=');
51493
- // info[element[0]] = element[1];
51494
- // });
51495
- // return info;
51496
- // };
51497
- //
51498
- // Variant.prototype.calcHeterozygosity = function (ac, an) {
51499
- // var sum = 0;
51500
- // an = parseInt(an);
51501
- // var altFreqs = ac.split(',');
51502
- // altFreqs.forEach(function (altFreq) {
51503
- // var altFrac = parseInt(altFreq) / an;
51504
- // sum += altFrac * altFrac;
51505
- // });
51506
- // return 1 - sum;
51507
- // };
51508
-
51509
51114
 
51510
51115
  return igv;
51511
51116
  })(igv || {});
@@ -51683,16 +51288,6 @@ var igv = (function (igv) {
51683
51288
 
51684
51289
  doubleClickDelay = igv.browser.constants.doubleClickDelay;
51685
51290
 
51686
- // right-click
51687
- $(self.canvas).contextmenu(function (e) {
51688
-
51689
- e.preventDefault();
51690
- e = $.event.fix(e);
51691
- e.stopPropagation();
51692
-
51693
- igv.popover.presentTrackPopupMenu(e, self);
51694
-
51695
- });
51696
51291
 
51697
51292
  $(self.canvas).mousedown(function (e) {
51698
51293
  var canvasCoords;
@@ -51781,9 +51376,16 @@ var igv = (function (igv) {
51781
51376
 
51782
51377
  } else if (e.altKey) {
51783
51378
 
51784
- if (self.trackView.track.altClick && self.tile) {
51785
- self.trackView.track.altClick(genomicLocation, referenceFrame, e);
51786
- }
51379
+ e.preventDefault();
51380
+ e = $.event.fix(e);
51381
+ e.stopPropagation();
51382
+
51383
+ igv.popover.presentTrackPopupMenu(e, self);
51384
+
51385
+ //
51386
+ // if (self.trackView.track.altClick && self.tile) {
51387
+ // self.trackView.track.altClick(genomicLocation, referenceFrame, e);
51388
+ // }
51787
51389
 
51788
51390
  } else if (Math.abs(canvasCoords.x - mouseDownX) <= igv.browser.constants.dragThreshold && self.trackView.track.popupData) {
51789
51391
 
@@ -51925,7 +51527,9 @@ var igv = (function (igv) {
51925
51527
  self.startSpinner();
51926
51528
 
51927
51529
  // console.log('get features');
51928
- this.trackView.track.getFeatures(referenceFrame.chrName, bpStart, bpEnd, referenceFrame.bpPerPixel)
51530
+ this.trackView.track
51531
+
51532
+ .getFeatures(referenceFrame.chrName, bpStart, bpEnd, referenceFrame.bpPerPixel)
51929
51533
 
51930
51534
  .then(function (features) {
51931
51535
 
@@ -51951,6 +51555,7 @@ var igv = (function (igv) {
51951
51555
  bpPerPixel: referenceFrame.bpPerPixel,
51952
51556
  referenceFrame: referenceFrame,
51953
51557
  genomicState: genomicState,
51558
+ selection: self.selection,
51954
51559
  viewport: self,
51955
51560
  viewportWidth: self.$viewport.width(),
51956
51561
  viewportContainerX: genomicState.referenceFrame.toPixels(genomicState.referenceFrame.start - bpStart),
@@ -52010,12 +51615,14 @@ var igv = (function (igv) {
52010
51615
 
52011
51616
  .catch(function (error) {
52012
51617
 
51618
+ console.error(error);
51619
+
52013
51620
  self.stopSpinner();
52014
51621
 
52015
51622
  self.loading = false;
52016
51623
 
52017
51624
  igv.presentAlert(error, undefined);
52018
-
51625
+
52019
51626
  });
52020
51627
 
52021
51628
  }
@@ -52043,6 +51650,7 @@ var igv = (function (igv) {
52043
51650
 
52044
51651
  };
52045
51652
 
51653
+
52046
51654
  igv.Viewport.prototype.setContentHeight = function (newHeight) {
52047
51655
 
52048
51656
  // Maximum height of a canvas is ~32,000 pixels on Chrome, possibly smaller on other platforms