igv 2.15.0 → 2.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/igv.esm.js CHANGED
@@ -18656,6 +18656,8 @@ class IGVXhr {
18656
18656
 
18657
18657
  async _loadURL(url, options) {
18658
18658
 
18659
+ const self = this;
18660
+
18659
18661
  //console.log(`${Date.now()} ${url}`)
18660
18662
  url = mapUrl$1(url);
18661
18663
 
@@ -18745,7 +18747,7 @@ class IGVXhr {
18745
18747
  // For small files a range starting at 0 can return the whole file => 200
18746
18748
  // Provide just the slice we asked for, throw out the rest quietly
18747
18749
  // If file is large warn user
18748
- if (xhr.response.length > 100000 && !this.RANGE_WARNING_GIVEN) {
18750
+ if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) {
18749
18751
  alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`);
18750
18752
  }
18751
18753
  resolve(xhr.response.slice(range.start, range.start + range.size));
@@ -18774,8 +18776,9 @@ class IGVXhr {
18774
18776
  xhr.onerror = function (event) {
18775
18777
  if (isGoogleURL(url) && !options.retries) {
18776
18778
  tryGoogleAuth();
18779
+ } else {
18780
+ handleError("Error accessing resource: " + url + " Status: " + xhr.status);
18777
18781
  }
18778
- handleError("Error accessing resource: " + url + " Status: " + xhr.status);
18779
18782
  };
18780
18783
 
18781
18784
  xhr.ontimeout = function (event) {
@@ -18790,7 +18793,11 @@ class IGVXhr {
18790
18793
  try {
18791
18794
  xhr.send(sendData);
18792
18795
  } catch (e) {
18793
- reject(e);
18796
+ if (isGoogleURL(url) && !options.retries) {
18797
+ tryGoogleAuth();
18798
+ } else {
18799
+ handleError(e);
18800
+ }
18794
18801
  }
18795
18802
 
18796
18803
 
@@ -18807,7 +18814,7 @@ class IGVXhr {
18807
18814
  const accessToken = await fetchGoogleAccessToken(url);
18808
18815
  options.retries = 1;
18809
18816
  options.oauthToken = accessToken;
18810
- const response = await this._load(url, options);
18817
+ const response = await self.load(url, options);
18811
18818
  resolve(response);
18812
18819
  } catch (e) {
18813
18820
  if (e.error) {
@@ -18953,14 +18960,16 @@ function addTeamDrive(url) {
18953
18960
  */
18954
18961
  function mapUrl$1(url) {
18955
18962
 
18956
- if (url.includes("//www.dropbox.com")) {
18963
+ if (url.startsWith("https://www.dropbox.com")) {
18957
18964
  return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com")
18958
- } else if (url.includes("//drive.google.com")) {
18965
+ } else if (url.startsWith("https://drive.google.com")) {
18959
18966
  return getDriveDownloadURL(url)
18960
18967
  } else if (url.includes("//www.broadinstitute.org/igvdata")) {
18961
18968
  return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata")
18962
18969
  } else if (url.includes("//igvdata.broadinstitute.org")) {
18963
- return url.replace("//igvdata.broadinstitute.org", "https://dn7ywbm9isq8j.cloudfront.net")
18970
+ return url.replace("//igvdata.broadinstitute.org", "//s3.amazonaws.com/igv.broadinstitute.org")
18971
+ } else if (url.includes("//igv.genepattern.org")) {
18972
+ return url.replace("//igv.genepattern.org", "//igv-genepattern-org.s3.amazonaws.com")
18964
18973
  } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) {
18965
18974
  return url.replace("ftp://", "https://")
18966
18975
  } else {
@@ -23922,7 +23931,7 @@ const Cytoband = function (start, end, name, typestain) {
23922
23931
  }
23923
23932
  };
23924
23933
 
23925
- const _version = "2.15.0";
23934
+ const _version = "2.15.2";
23926
23935
  function version() {
23927
23936
  return _version
23928
23937
  }
@@ -25759,15 +25768,15 @@ function decodeGTF(tokens, header) {
25759
25768
  * @param keyValueDelim
25760
25769
  * @returns {[]}
25761
25770
  */
25762
- function parseAttributeString(attributeString, keyValueDelim) {
25771
+ function parseAttributeString(attributeString, keyValueDelim, relaxed = false) {
25763
25772
  // parse 'attributes' string (see column 9 docs in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md)
25764
25773
  var attributes = [];
25765
25774
  for (let kv of attributeString.split(';')) {
25766
25775
  kv = kv.trim();
25767
25776
  const idx = kv.indexOf(keyValueDelim);
25768
25777
  if (idx > 0 && idx < kv.length - 1) {
25769
- const key = kv.substring(0, idx);
25770
- let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim()));
25778
+ const key = stripQuotes(decodeGFFAttribute(kv.substring(0, idx).trim(), relaxed));
25779
+ let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim(), relaxed));
25771
25780
  attributes.push([key, value]);
25772
25781
  }
25773
25782
  }
@@ -25806,11 +25815,14 @@ const encodings = new Map([
25806
25815
  ["%2C", ","]
25807
25816
  ]);
25808
25817
 
25809
- function decodeGFFAttribute(str) {
25818
+ function decodeGFFAttribute(str, relaxed = false) {
25810
25819
 
25811
25820
  if (!str.includes("%")) {
25812
25821
  return str
25813
25822
  }
25823
+ if (relaxed) {
25824
+ return decodeURIComponent(str);
25825
+ }
25814
25826
  let decoded = "";
25815
25827
  for (let i = 0; i < str.length; i++) {
25816
25828
 
@@ -25868,7 +25880,7 @@ function decodeBed(tokens, header) {
25868
25880
 
25869
25881
  // Potentially parse name field as GFF column 9 style streng.
25870
25882
  if (tokens[3].indexOf(';') > 0 && tokens[3].indexOf('=') > 0) {
25871
- const attributeKVs = parseAttributeString(tokens[3], '=');
25883
+ const attributeKVs = parseAttributeString(tokens[3], '=', true);
25872
25884
  feature.attributes = {};
25873
25885
  for (let kv of attributeKVs) {
25874
25886
  feature.attributes[kv[0]] = kv[1];
@@ -25916,7 +25928,25 @@ function decodeBed(tokens, header) {
25916
25928
  }
25917
25929
 
25918
25930
  if (tokens.length > 11) {
25919
- const exons = decodeExons(tokens[9], tokens[10], tokens[11]);
25931
+ const exonCount = parseInt(tokens[9]);
25932
+ // Some basic validation
25933
+ if (exonCount > 1000) {
25934
+ // unlikely
25935
+ return feature
25936
+ }
25937
+
25938
+ const exonSizes = tokens[10].replace(/,$/, '').split(',');
25939
+ const exonStarts = tokens[11].replace(/,$/, '').split(',');
25940
+ if (!(exonSizes.length === exonStarts.length && exonCount === exonSizes.length)) {
25941
+ return feature
25942
+ }
25943
+
25944
+ const exons = [];
25945
+ for (let i = 0; i < exonCount; i++) {
25946
+ const eStart = start + parseInt(exonStarts[i]);
25947
+ const eEnd = eStart + parseInt(exonSizes[i]);
25948
+ exons.push({start: eStart, end: eEnd});
25949
+ }
25920
25950
  if (exons.length > 0) {
25921
25951
  findUTRs$1(exons, feature.cdStart, feature.cdEnd);
25922
25952
  feature.exons = exons;
@@ -25940,7 +25970,6 @@ function decodeBed(tokens, header) {
25940
25970
  }
25941
25971
 
25942
25972
  return feature
25943
-
25944
25973
  }
25945
25974
 
25946
25975
  /**
@@ -27252,6 +27281,8 @@ class TrackBase {
27252
27281
  }
27253
27282
  tracklineConfg.autoscale = false;
27254
27283
  tracklineConfg.dataRange = {min, max};
27284
+ this.viewLimitMin = min;
27285
+ this.viewLimitMax = max;
27255
27286
  }
27256
27287
  case "name":
27257
27288
  tracklineConfg[key] = properties[key];
@@ -29150,9 +29181,9 @@ function optimizeChunks(chunks, lowest) {
29150
29181
  * @returns {boolean|boolean}
29151
29182
  */
29152
29183
  function canMerge(chunk1, chunk2) {
29153
- const gap = chunk2.minv.block - chunk1.maxv.block;
29184
+ chunk2.minv.block - chunk1.maxv.block;
29154
29185
  const sizeEstimate = chunk1.maxv.block - chunk1.minv.block;
29155
- return gap < 65000 && sizeEstimate < 5000000
29186
+ return sizeEstimate < 5000000
29156
29187
  }
29157
29188
 
29158
29189
  // Represents a CSI Bam or Tabix index
@@ -40775,8 +40806,8 @@ class FeatureTrack extends TrackBase {
40775
40806
  color = IGVColor.addAlpha(color, feature.alpha);
40776
40807
  } else if (this.useScore && feature.score && !Number.isNaN(feature.score)) {
40777
40808
  // UCSC useScore option, for scores between 0-1000. See https://genome.ucsc.edu/goldenPath/help/customTrack.html#TRACK
40778
- const min = this.config.min ? this.config.min : 0; //getViewLimitMin(track);
40779
- const max = this.config.max ? this.config.max : 1000; //getViewLimitMax(track);
40809
+ const min = this.config.min ? this.config.min : this.viewLimitMin ? this.viewLimitMin : 0;
40810
+ const max = this.config.max ? this.config.max : this.viewLimitMax ? this.viewLimitMax : 1000;
40780
40811
  const alpha = getAlpha(min, max, feature.score);
40781
40812
  feature.alpha = alpha; // Avoid computing again
40782
40813
  color = IGVColor.addAlpha(color, alpha);
@@ -54145,11 +54176,13 @@ class HDF5Reader {
54145
54176
 
54146
54177
  // console.log(h5_obj_keys)
54147
54178
  let signal_bin = new ParseSignals(h5_obj_keys);
54148
- this.rd_bins = signal_bin.get_rd_bins();
54179
+ let rd_bins = signal_bin.get_rd_bins();
54180
+ let snp_bins = signal_bin.get_snp_bins();
54181
+ this.available_bins = [...new Set(rd_bins, snp_bins)];
54149
54182
 
54150
54183
  // let bin_size = this.bin_size
54151
- if(! this.rd_bins.includes(bin_size)){
54152
- bin_size = this.rd_bins[rd_bins.length-1];
54184
+ if(! this.available_bins.includes(bin_size)){
54185
+ bin_size = this.available_bins.at(-1);
54153
54186
  }
54154
54187
 
54155
54188
  const chr_ds = await h5_obj.get("rd_chromosomes");
@@ -54193,6 +54226,9 @@ class HDF5Reader {
54193
54226
  let signal_baf_1 = `snp_likelihood_${chrom}_${bin_size}_mask`;
54194
54227
  let chr_wig_bafs = await this.get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1);
54195
54228
 
54229
+ // let signal_baf_1 = `snp_i1_${chrom}_${bin_size}_mask`
54230
+ // let chr_wig_bafs = await this.get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1)
54231
+
54196
54232
  wigFeatures_baf1 = wigFeatures_baf1.concat(chr_wig_bafs[0]);
54197
54233
  wigFeatures_baf2 = wigFeatures_baf2.concat(chr_wig_bafs[1]);
54198
54234
  // this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat)
@@ -54317,6 +54353,28 @@ class HDF5Reader {
54317
54353
  }
54318
54354
  return [chr_wig_1, chr_wig_2]
54319
54355
  }
54356
+
54357
+ async get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){
54358
+
54359
+ /* return two list of dictionary*/
54360
+ let chr_wig_1 = [];
54361
+ let chr_wig_2 = [];
54362
+ if (h5_obj_keys.includes(signal_name)){
54363
+ let chrom_dataset = await h5_obj.get(signal_name);
54364
+ let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape)
54365
+ chrom_data.forEach((lh, bin_idx) => {
54366
+ if (!isNaN(lh)){
54367
+ chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 - lh )});
54368
+ if(lh != 0.5){
54369
+ chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 + lh )});
54370
+ }
54371
+ }
54372
+ });
54373
+ }
54374
+ console.log(chrom, chr_wig_1, chr_wig_2);
54375
+ return [chr_wig_1, chr_wig_2]
54376
+
54377
+ }
54320
54378
  }
54321
54379
 
54322
54380
  class ParseSignals{
@@ -54357,6 +54415,53 @@ class ParseSignals{
54357
54415
  }
54358
54416
  }
54359
54417
 
54418
+ class GetFit {
54419
+ constructor(allBins) {
54420
+ this.allBins = allBins;
54421
+ }
54422
+ getValues() {
54423
+ const bins = Object.values(this.allBins).reduce(
54424
+ (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []);
54425
+ return bins
54426
+ }
54427
+ getMean(data) {
54428
+ return (data.reduce(function (a, b) { return a + b; }) / data.length);
54429
+ }
54430
+ fit_data() {
54431
+ let rd_list = this.getValues();
54432
+ let distParmas = getDistParams(rd_list);
54433
+ return distParmas
54434
+ }
54435
+
54436
+ histogram(data, bins) {
54437
+ const step = bins[1] - bins[0];
54438
+ const hist_bins = [];
54439
+
54440
+ data.forEach((value, index) => {
54441
+ bins.forEach((bin_value, bin_index) => {
54442
+ if (!hist_bins[bin_value]) {
54443
+ hist_bins[bin_value] = { count: 0 };
54444
+ }
54445
+ if (bin_value <= value && value < bin_value + step) {
54446
+ hist_bins[bin_value].count++;
54447
+ return false;
54448
+ }
54449
+ });
54450
+ });
54451
+ const dist_p = [];
54452
+ hist_bins.forEach((bin, index) => { dist_p.push(bin.count); });
54453
+ return dist_p
54454
+ }
54455
+
54456
+ }
54457
+
54458
+ function range_function(start, stop, step) {
54459
+ const data_array = Array(Math.ceil((stop - start) / step))
54460
+ .fill(start)
54461
+ .map((x, y) => x + y * step);
54462
+ return data_array;
54463
+ }
54464
+
54360
54465
  function filterOutliers(someArray) {
54361
54466
 
54362
54467
  if (someArray.length < 4)
@@ -54389,6 +54494,21 @@ function getDistParams(bins) {
54389
54494
  return [mean, std]
54390
54495
  }
54391
54496
 
54497
+ function linspace(a, b, n) {
54498
+ if (typeof n === "undefined") n = Math.max(Math.round(b - a) + 1, 1);
54499
+ if (n < 2) {
54500
+ return n === 1 ? [a] : [];
54501
+ }
54502
+ var ret = Array(n);
54503
+ n--;
54504
+ for (let i = n; i >= 0; i--) {
54505
+ ret[i] = (i * b + (n - i) * a) / n;
54506
+ }
54507
+ return ret;
54508
+ }
54509
+
54510
+ var g_utils = { range_function, getDistParams, linspace, GetFit};
54511
+
54392
54512
  /**
54393
54513
  * Evaluates the cumulative distribution function (CDF) for a Student's t distribution with degrees of freedom `v` at a value `t`.
54394
54514
  *
@@ -54533,48 +54653,507 @@ function lgamma(xg){
54533
54653
  return Math.log(gamma(xg))
54534
54654
  }
54535
54655
 
54536
- var t_dist = {TdistributionCDF, gamma};
54656
+ function t_test_1_sample$1(mean, m, s, n) {
54657
+ if (s == 0) s = 1;
54658
+ var t = ((mean - m) / s) * Math.sqrt(n);
54659
+ var p = 1.0 - TdistributionCDF(Math.abs(t), (n - 1));
54660
+ return p
54661
+ }
54537
54662
 
54538
- class GetFit {
54539
- constructor(allBins) {
54540
- this.allBins = allBins;
54541
- }
54542
- getValues() {
54543
- const bins = Object.values(this.allBins).reduce(
54544
- (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []);
54545
- return bins
54663
+ function t_test_2_samples$1(m1, s1, n1, m2, s2, n2) {
54664
+ if (s1 == 0) s1 = 1;
54665
+ if (s2 == 0) s2 = 1;
54666
+ var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2);
54667
+ var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) /
54668
+ ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2);
54669
+
54670
+ var p = 1.0 - TdistributionCDF(Math.abs(t), parseInt(df + 0.5));
54671
+
54672
+ return p
54673
+ }
54674
+
54675
+ var t_dist = {TdistributionCDF, gamma, t_test_1_sample: t_test_1_sample$1, t_test_2_samples: t_test_2_samples$1};
54676
+
54677
+ class CombinedCaller{
54678
+ constructor(wigFeatures, binSize) {
54679
+ this.wigFeatures = wigFeatures;
54680
+ this.binSize = binSize;
54681
+ // let fit_obj = this.get_fit()
54682
+ // this.globalMean = fit_obj.globalMean
54683
+ // this.globalStd = fit_obj.globalStd
54546
54684
  }
54547
- getMean(data) {
54548
- return (data.reduce(function (a, b) { return a + b; }) / data.length);
54685
+ get_fit(){
54686
+ var fit_info = new g_utils.GetFit(this.wigFeatures);
54687
+ var [globalMean, globalStd] = fit_info.fit_data();
54688
+
54689
+ return {globalMean:globalMean, globalStd:globalStd}
54690
+
54549
54691
  }
54550
- fit_data() {
54551
- let rd_list = this.getValues();
54552
- let distParmas = getDistParams(rd_list);
54553
- return distParmas
54692
+ async call_2d(omin=null, mcount=null, event_type="both", max_distance=0.1, baf_threshold=0, max_copy_number=10, min_cell_fraction=0.0){
54693
+
54694
+ let fit_obj = this.get_fit();
54695
+ this.globalMean = fit_obj.globalMean;
54696
+ this.globalStd = fit_obj.globalStd;
54697
+
54698
+ let overlap_min = omin==null ? 0.05 * this.binSize / 3e9: omin ;
54699
+ let min_count = mcount == null ? parseInt(this.binSize / 10000) : mcount ;
54700
+
54701
+ let gstat_rd0 = [];
54702
+ let gstat_rd_all = [];
54703
+ let gstat_rd = [];
54704
+ let gstat_error = [];
54705
+ let gstat_lh = [];
54706
+ let gstat_n = [];
54707
+
54708
+ for (const [chr, wig] of Object.entries(this.wigFeatures)) {
54709
+ let segments = [];
54710
+ let levels = [];
54711
+ let likelihoods = [];
54712
+
54713
+ wig.forEach((bin, bin_idx) => {
54714
+ if (bin.hets_count > 4 ){
54715
+
54716
+ if( bin.dp_count > min_count ){
54717
+ segments.push([bin_idx]);
54718
+ levels.push(bin.binScore);
54719
+ likelihoods.push(bin.likelihood_score);
54720
+ delete bin.likelihood_score;
54721
+
54722
+ }
54723
+ }
54724
+ });
54725
+
54726
+ let diff_level = [];
54727
+ for(let i=1; i<levels.length; i++){
54728
+ diff_level.push(Math.abs(levels[i] - levels[i-1]));
54729
+ }
54730
+ let min_flank = [0];
54731
+ for(let i=1; i<diff_level.length; i++){
54732
+ min_flank.push(Math.min(diff_level[i-1], diff_level[i]));
54733
+ }
54734
+ min_flank.push(0);
54735
+
54736
+ let error = levels.map((x, x_idx) => {return Math.sqrt(Math.sqrt(x) ** 2 + this.globalStd ** 2 + Math.pow(min_flank[x_idx]/2, 2));});
54737
+
54738
+ let overlaps = [];
54739
+
54740
+ for(let i=0; i< segments.length-1; i++){
54741
+
54742
+ let lh_overlap = 0;
54743
+ try{
54744
+ lh_overlap = likelihood_overlap(likelihoods[i], likelihoods[i+1]);
54745
+ }catch{
54746
+ console.log("Overlap failed: ", i, likelihoods[i], segments[i+1], likelihoods[i+1]);
54747
+ }
54748
+
54749
+ let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]);
54750
+ overlaps.push(rd_overlap * lh_overlap);
54751
+
54752
+ }
54753
+
54754
+ while(overlaps.length >0) {
54755
+ overlaps = overlaps.filter(num => typeof num === "number");
54756
+
54757
+ let max_overlap = arrayMax(overlaps);
54758
+ if(isNaN(max_overlap)){
54759
+ console.log('NaN value', overlaps);
54760
+ }
54761
+ if(max_overlap < overlap_min){
54762
+ // console.log("maxoverlap ",max_overlap, "is smaller than overlap min")
54763
+ break
54764
+ }
54765
+ let i = overlaps.indexOf(max_overlap);
54766
+
54767
+ let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]);
54768
+
54769
+ let nlh;
54770
+ let nlh_sum;
54771
+ try{
54772
+ nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]});
54773
+
54774
+ nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});
54775
+
54776
+ }catch{
54777
+ console.log(likelihoods);
54778
+ console.log('max_overlap:', max_overlap, i, overlaps.length);
54779
+ console.log('likelihood: ', i ,likelihoods[i], likelihoods[i+1]);
54780
+ console.log('nlh: ', nlh_sum);
54781
+ }
54782
+ // nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});
54783
+
54784
+ levels[i] = merge_level.nl;
54785
+ error[i] = merge_level.ne;
54786
+
54787
+ likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } );
54788
+
54789
+ segments[i].push(...segments[i+1]);
54790
+
54791
+ levels.splice(i + 1, 1);
54792
+ error.splice(i + 1, 1);
54793
+ segments.splice(i + 1, 1);
54794
+ likelihoods.splice(i + 1, 1);
54795
+ overlaps.splice(i, 1);
54796
+
54797
+ if(i < overlaps.length){
54798
+
54799
+ let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]);
54800
+ let new_overlap = rd_overlap * likelihood_overlap(likelihoods[i], likelihoods[i + 1]);
54801
+
54802
+ overlaps[i] = new_overlap;
54803
+ }
54804
+ if(i > 0){
54805
+ let new_overlap = normal_overlap_approx(levels[i - 1], error[i - 1], levels[i], error[i])
54806
+ * likelihood_overlap(likelihoods[i - 1], likelihoods[i]);
54807
+ overlaps[i - 1] = new_overlap;
54808
+ }
54809
+
54810
+ }
54811
+ let ons = -1;
54812
+ while(true){
54813
+ overlaps = [];
54814
+ for(let i=0; i< levels.length; i++){
54815
+ for(let j=i; j<levels.length; j++){
54816
+ if(segments[j][0] - segments[i].at(-1) < max_distance * (segments[i].length + segments[j].length)){
54817
+ overlaps.push(normal_overlap_approx(levels[i], error[i], levels[j], error[j]) * likelihood_overlap(likelihoods[i], likelihoods[j]));
54818
+ }
54819
+ }
54820
+ }
54821
+
54822
+ if(overlaps.length == 0){
54823
+ break
54824
+ }
54825
+ let max_overlap = arrayMax(overlaps);
54826
+ if(max_overlap < overlap_min){
54827
+ break
54828
+ }
54829
+ let i = 0;
54830
+ let j = 1;
54831
+ while (i < segments.length - 1){
54832
+ let overlap_value = normal_overlap_approx(levels[i], error[i], levels[j], error[j]) * likelihood_overlap(likelihoods[i], likelihoods[j]);
54833
+
54834
+ if((segments[j][0] - segments[i].at(-1)) < max_distance * (segments[i].length + segments[j].length) && overlap_value == max_overlap){
54835
+ let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]);
54836
+
54837
+ levels[i] = merge_level.nl;
54838
+ error[i] = merge_level.ne;
54839
+ let nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]});
54840
+ let nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});
54841
+ likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } );
54842
+
54843
+
54844
+ segments[i].push(...segments[i+1]);
54845
+ segments[i] = segments[i].sort((a,b) => a-b);
54846
+
54847
+ levels.splice(j, 1);
54848
+ error.splice(j, 1);
54849
+ segments.splice(j, 1);
54850
+ likelihoods.splice(j, 1);
54851
+
54852
+ if(j >= segments.length){
54853
+ i += 1;
54854
+ j = i + 1;
54855
+ }
54856
+
54857
+ }else {
54858
+ j += 1;
54859
+ if(j >= segments.length){
54860
+ i += 1;
54861
+ j = i + 1;
54862
+ }
54863
+ }
54864
+ }
54865
+ if(ons == segments.length){
54866
+ break
54867
+ }
54868
+ ons = segments.length;
54869
+ }
54870
+ // console.log('final segments', segments)
54871
+
54872
+ segments.forEach((seg_value, seg_idx) => {
54873
+ let baf_info = likelihood_baf_pval(likelihoods[seg_idx]);
54874
+ if(seg_value.length > 1){
54875
+
54876
+ seg_value.forEach((bin, bin_idx) =>{
54877
+ gstat_rd_all.push(wig[bin]);
54878
+ if(baf_info.mean <= baf_threshold){
54879
+ gstat_rd0.push(wig[bin]);
54880
+ }
54881
+ wig[bin].segment_score = levels[seg_idx];
54882
+ });
54883
+ gstat_rd.push(levels[seg_idx]);
54884
+ gstat_error.push(error[seg_idx]);
54885
+ gstat_lh.push(likelihoods[seg_idx]);
54886
+
54887
+ }
54888
+
54889
+ });
54890
+
54891
+ continue
54892
+ }
54893
+
54894
+ // Third stage for call
54895
+
54896
+ // let data = gstat_rd0.lengthn == 0 ? gstat_rd_all: gstat_rd0 ;
54897
+
54898
+ let points = parseInt(1000 * (1 - min_cell_fraction));
54899
+ if(points == 0){
54900
+ points = 1;
54901
+ }
54902
+ let x = g_utils.linspace(min_cell_fraction, 1, points);
54903
+ let master_lh = {};
54904
+ let germline_lh = {};
54905
+ for(let cn=10; cn > -1; cn--){
54906
+ for(let h1=0; h1 < (cn/2+1); h1++){
54907
+ let h2 = cn - h1;
54908
+ let mrd = x.map((v, idx) => {return 1-v +v*cn/2});
54909
+ let g_mrd = cn / 2;
54910
+ let g_mbaf;
54911
+ let mbaf;
54912
+ if(cn > 0){
54913
+ g_mbaf = 0.5 - (h1 / (h1 + h2));
54914
+ mbaf = x.map((v, idx) => {return 0.5 - (1 - v + v * h1) / (2 - 2 * v + (h1 + h2) * v)});
54915
+
54916
+ }else {
54917
+ g_mbaf = 0;
54918
+ mbaf = x.map((v, idx) => {return 0*v});
54919
+ }
54920
+
54921
+ for( let ei=0; ei < gstat_rd.length; ei++){
54922
+
54923
+ let g_lh = normal(g_mrd * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + g_mbaf);
54924
+ if(ei in germline_lh){
54925
+ germline_lh[ei].push([cn, h1, h2, g_lh, 1.0]);
54926
+ }else {
54927
+ germline_lh[ei] = [cn, h1, h2, g_lh, 1.0];
54928
+ }
54929
+ let slh = 0;
54930
+ let max_lh = 0;
54931
+ let max_x = 0;
54932
+ mrd.forEach((mi, idx) => {
54933
+ if(!isNaN(mbaf[idx])){
54934
+ let tmpl = normal(mi * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + mbaf[idx]);
54935
+ slh += tmpl;
54936
+ if(tmpl > max_lh){
54937
+ max_lh = tmpl;
54938
+ max_x = x[idx];
54939
+ }
54940
+ }
54941
+ });
54942
+ if(ei in master_lh){
54943
+ master_lh[ei].push([cn, h1, h2, slh / x.length, max_x]);
54944
+ }else {
54945
+ master_lh[ei] = [cn, h1, h2, slh / x.length, max_x];
54946
+ }
54947
+ }
54948
+
54949
+ for( let ei=0; ei < gstat_rd.length; ei++){
54950
+ if(event_type == "germline"){
54951
+ master_lh[ei].sort((a, b) => a[3] - b[3]);
54952
+ }
54953
+ else {
54954
+ master_lh[ei].sort((a, b) => a[3] - b[3]);
54955
+ if(event_type == "both"){
54956
+
54957
+ germline_lh[ei].sort((a, b) => a[3] - b[3]);
54958
+ if(germline_lh[ei][0][3] > master_lh[ei][0][3]){
54959
+ //let tmp_list = list(filter( lambda x: x[0] != germline_lh[ei][0][0] and x[1] != germline_lh[ei][0][1], master_lh[ei]))
54960
+ let tmp_list = master_lh[ei].filter((x) => (x[0] != germline_lh[ei][0][0]) && (x[1] <= germline_lh[ei][0][1]));
54961
+ // console.log('tmp_list', tmp_list)
54962
+ // master_lh[ei] = [germline_lh[ei][0]] + tmp_list
54963
+ master_lh[ei] = [germline_lh[ei][0]].push(...tmp_list);
54964
+ }
54965
+ }
54966
+ }
54967
+ }
54968
+ for( let ei=0; ei < gstat_rd.length; ei++){
54969
+ if(master_lh[ei][0][0] > 2);
54970
+ if(master_lh[ei][0][0] < 2);
54971
+ gstat_rd[ei] / this.globalMean;
54972
+ t_dist.t_test_1_sample(this.globalMean, gstat_rd[ei], gstat_error[ei], gstat_n[ei]);
54973
+ // console.log(etype)
54974
+
54975
+ }
54976
+
54977
+
54978
+ // break
54979
+ }
54980
+
54981
+ }
54982
+
54983
+ var rawbinScore = this.formatDataStructure(this.wigFeatures, 'binScore', this.globalMean);
54984
+ var callScore = this.formatDataStructure(this.wigFeatures, 'segment_score', this.globalMean);
54985
+
54986
+ return {binScore: rawbinScore, segment_score: callScore}
54987
+
54554
54988
  }
54555
54989
 
54556
- histogram(data, bins) {
54557
- const step = bins[1] - bins[0];
54558
- const hist_bins = [];
54990
+ formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) {
54991
+ const results = [];
54992
+ for (const [chr, wig] of Object.entries(wigFeatures)) {
54559
54993
 
54560
- data.forEach((value, index) => {
54561
- bins.forEach((bin_value, bin_index) => {
54562
- if (!hist_bins[bin_value]) {
54563
- hist_bins[bin_value] = { count: 0 };
54994
+ wig.forEach(sample => {
54995
+ var new_sample = { ...sample };
54996
+ if (scaling_factor != 1) {
54997
+ new_sample.value = sample[feature_column] / scaling_factor * 2;
54564
54998
  }
54565
- if (bin_value <= value && value < bin_value + step) {
54566
- hist_bins[bin_value].count++;
54567
- return false;
54999
+ results.push(new_sample);
55000
+ });
55001
+ }
55002
+
55003
+ return results
55004
+ }
55005
+
55006
+ formatDataStructure_BAF(feature_column, scaling_factor = 2) {
55007
+ const baf1 = [];
55008
+ const baf2 = [];
55009
+ for (const [chr, wig] of Object.entries(this.wigFeatures)) {
55010
+
55011
+ wig.forEach(sample => {
55012
+
55013
+ var baf1_value = { ...sample };
55014
+ var baf2_value = { ...sample };
55015
+
55016
+ let value = sample[feature_column];
55017
+ if (value != 0.5){
55018
+ baf2_value.value = -2 * (1 - value);
55019
+ baf2.push(baf2_value);
54568
55020
  }
55021
+ baf1_value.value = -2 * value;
55022
+ baf1.push(baf1_value);
55023
+
54569
55024
  });
54570
- });
54571
- const dist_p = [];
54572
- hist_bins.forEach((bin, index) => { dist_p.push(bin.count); });
54573
- return dist_p
55025
+ }
55026
+
55027
+
55028
+ return [baf1, baf2]
54574
55029
  }
55030
+ }
54575
55031
 
55032
+ function arrayMax(arr) {
55033
+ return arr.reduce(function (p, v) {
55034
+ return ( p > v ? p : v );
55035
+ });
55036
+ }
55037
+
55038
+ /**
55039
+ * Normal distribution.
55040
+ *
55041
+ * @param {float} x - Variable.
55042
+ * @param {float} a - area
55043
+ * @param {float} x0 - Mean value
55044
+ * @param {float} sigma - Sigma
55045
+ * @returns {float} - Value of distribution in x.
55046
+ */
55047
+ function normal(x, a, x0, sigma){
55048
+
55049
+ return a * Math.exp(-1* (x - x0) ** 2 / (2 * sigma ** 2)) / Math.sqrt(2 * Math.PI) / sigma
55050
+
55051
+ }
55052
+
55053
+ /**
55054
+ * Calculates two normal distributions overlap area.
55055
+ *
55056
+ * @param {float} m1 - Mean value of the first distribution
55057
+ * @param {float} s1 - Sigma of the first distribution
55058
+ * @param {float} m2 - Mean value for second distribution
55059
+ * @param {float} s2 - Sigma of the second distribution
55060
+ *
55061
+ * @returns {float} area - Area of overlap
55062
+ */
55063
+ function normal_overlap_approx(m1, s1, m2, s2){
55064
+
55065
+ return Math.exp(-1* (m1-m2)**2/ (s1**2+s2**2))
55066
+ }
55067
+
55068
+
55069
+ /**
55070
+ * Returns overlap area of two likelihood functions.
55071
+ *
55072
+ * @param {*} lk1 - First likelihood function.
55073
+ * @param {*} lk2 - Second likelihood function.
55074
+ *
55075
+ * @returns {float} - Overlap area.
55076
+ */
55077
+ function likelihood_overlap(likelihood_1, likelihood_2){
55078
+ let sum;
55079
+ try{
55080
+ sum = likelihood_1.reduce((accumulator, currentValue, currentIndex) => {return accumulator + Math.min(currentValue, likelihood_2[currentIndex])});
55081
+ }catch{
55082
+ console.log("Failed to find likelihood overlap: ", likelihood_1, likelihood_2);
55083
+ return 0
55084
+ }
55085
+
55086
+ return sum
54576
55087
  }
54577
55088
 
55089
+ /**
55090
+ * Calculates normal distribution that is product of two given normal distributions.
55091
+ *
55092
+ * @param {float} m1 - Mean value of the first distribution
55093
+ * @param {float} s1 - Sigma of the first distribution
55094
+ * @param {float} m2 - Mean value for second distribution
55095
+ * @param {float} s2 - Sigma of the second distribution
55096
+ * @returns {Object} An object representing the first distribution
55097
+ * @property {float} nl - Mean value of the first distribution
55098
+ * @property {float} ne - Sigma of the first distribution
55099
+ */
55100
+ function normal_merge(m1, s1, m2, s2){
55101
+
55102
+ if((s1 == 0) && (s2 == 0)){
55103
+ return {nl: 0.5 * (m1 + m2), ne: 0}
55104
+ }
55105
+ else {
55106
+ return {nl: (m1 * s2 * s2 + m2 * s1 * s1) / (s1 * s1 + s2 * s2), ne: Math.sqrt(s1 * s1 * s2 * s2 / (s1 * s1 + s2 * s2))}
55107
+ }
55108
+ }
55109
+
55110
+ /**
55111
+ * Calculates likelihood for given baf
55112
+ * @param {*} likelihood
55113
+ * @param {*} baf
55114
+ * @returns {float} likelihood value
55115
+ */
55116
+ function likelihood_of_baf(likelihood, baf){
55117
+
55118
+ let bin = parseInt(baf * (likelihood.length - 1));
55119
+ let fr = baf * (likelihood.length - 1) - bin;
55120
+ if(bin < likelihood.length - 1){
55121
+ return likelihood[bin] * (1 - fr) + likelihood[bin + 1] * fr
55122
+ }
55123
+ else {
55124
+ return likelihood[bin]
55125
+ }
55126
+ }
55127
+
55128
+ /**
55129
+ *
55130
+ * Calculates baf level and p-value for given likelihood function.
55131
+ *
55132
+ * @param {*} likelihood
55133
+ * @returns {Object} An object representing BAF
55134
+ * @property {float} mean BAF level (difference from 1/2)
55135
+ * @property {float} p p-value for event different than 1/2
55136
+ */
55137
+ function likelihood_baf_pval(likelihood) {
55138
+ const res = likelihood.length;
55139
+ const max_lh = Math.max(...likelihood);
55140
+ let ix = likelihood.indexOf(max_lh);
55141
+ if (ix > Math.floor(res / 2)) {
55142
+ ix = res - 1 - ix;
55143
+ }
55144
+ const b = (res / 2 - ix) / (res + 1);
55145
+
55146
+ const ix1 = Math.floor((res / 2 + ix) / 2);
55147
+ const ix2 = res - 1 - ix1;
55148
+ let p = likelihood.slice(ix1, ix2 + 1).reduce((acc, val) => acc + val, 0) / likelihood.reduce((acc, val) => acc + val, 0);
55149
+ if (ix === Math.floor(res / 2)) {
55150
+ p = 1.0;
55151
+ }
55152
+ return {mean:b, p:p};
55153
+ }
55154
+
55155
+ var combined_caller = {CombinedCaller};
55156
+
54578
55157
  function erf(x) {
54579
55158
  var m = 1.0, s = 1.0, sum = x * 1.0;
54580
55159
  for (var i = 1; i < 50; i++) {
@@ -55222,6 +55801,10 @@ class Partition {
55222
55801
  }
55223
55802
  }
55224
55803
 
55804
+
55805
+
55806
+ var read_depth_caller = { Partition };
55807
+
55225
55808
  class CNVpytorVCF {
55226
55809
  constructor(allVariants, binSize) {
55227
55810
  this.allVariants = allVariants;
@@ -55349,13 +55932,11 @@ class CNVpytorVCF {
55349
55932
  readDepthMeanshift(wigFeatures) {
55350
55933
 
55351
55934
  // Get global mean and standrad deviation
55352
- var fit_info = new GetFit(wigFeatures);
55935
+ var fit_info = new g_utils.GetFit(wigFeatures);
55353
55936
  var [globamMean, globalStd] = fit_info.fit_data();
55354
- // console.log('Fitter', globamMean, globalStd)
55355
-
55356
55937
 
55357
55938
  // Apply partition method
55358
- var partition = new Partition(wigFeatures, globamMean, globalStd);
55939
+ var partition = new read_depth_caller.Partition(wigFeatures, globamMean, globalStd);
55359
55940
  var partition_array = partition.meanShiftCaller();
55360
55941
  var caller_array = partition.cnv_calling();
55361
55942
 
@@ -55386,86 +55967,10 @@ class CNVpytorVCF {
55386
55967
  results.push(new_sample);
55387
55968
  });
55388
55969
  }
55389
- // console.log(feature_column, results)
55390
55970
 
55391
55971
  return results
55392
55972
  }
55393
55973
 
55394
- // function for baf likelihood calculations
55395
- async computeBAF() {
55396
- const chromosomes = Object.keys(this.allVariants);
55397
- const wigFeatures = {};
55398
- const results = [];
55399
-
55400
- for (let chr of chromosomes) {
55401
- const variants = this.allVariants[chr];
55402
- if (variants.length === 0) continue
55403
- var featureBin;
55404
- for (let snp of variants) {
55405
- featureBin = Math.max(Math.floor(snp.start / this.binSize), 0);
55406
-
55407
- if (!wigFeatures[chr]) {
55408
- wigFeatures[chr] = [];
55409
- }
55410
- if (!wigFeatures[chr][featureBin]) {
55411
- if (featureBin > 0) {
55412
- // calculating the BAF likelihood for previous bin
55413
- let previous_featureBin = featureBin - 1;
55414
- if (wigFeatures[chr][previous_featureBin]) {
55415
-
55416
- const updated_bin = this.get_max_min_score(wigFeatures[chr][previous_featureBin]);
55417
- wigFeatures[chr][previous_featureBin] = updated_bin;
55418
- results.push(wigFeatures[chr][previous_featureBin]);
55419
- }
55420
- }
55421
- wigFeatures[chr][featureBin] = {
55422
- chr,
55423
- start: featureBin * this.binSize,
55424
- end: (featureBin + 1) * this.binSize,
55425
- value: 0,
55426
- count: 0,
55427
- likelihood_score: [],
55428
- min_score: 0,
55429
- };
55430
- }
55431
- const calls = snp.calls[9];
55432
- let genotype = calls.genotype;
55433
- let ad_score = calls.info["AD"].split(',');
55434
- let ad_a = ad_score[0], ad_b = ad_score[1];
55435
-
55436
- if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) {
55437
- //apply the beta function
55438
- if (wigFeatures[chr][featureBin].likelihood_score.length == 0) {
55439
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 200).map((value, index) => {
55440
- return beta(ad_a, ad_b, value);
55441
- });
55442
- } else {
55443
- var sum = 0;
55444
-
55445
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 200).map((value, index) => {
55446
- var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value);
55447
- sum = sum + likelihood_value;
55448
- return likelihood_value;
55449
- });
55450
-
55451
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 200).map((value, index) => {
55452
- return wigFeatures[chr][featureBin].likelihood_score[index] / sum;
55453
- });
55454
- }
55455
- wigFeatures[chr][featureBin].count++;
55456
- }
55457
- }
55458
-
55459
- // last feature bin
55460
- const updated_bin = this.get_max_min_score(wigFeatures[chr][featureBin]);
55461
- wigFeatures[chr][featureBin] = updated_bin;
55462
- results.push(wigFeatures[chr][featureBin]);
55463
- }
55464
-
55465
- const baf2_result = this.format_BAF_likelihood(wigFeatures);
55466
- return [results, baf2_result]
55467
-
55468
- }
55469
55974
  async computeBAF_v2() {
55470
55975
 
55471
55976
  const chromosomes = Object.keys(this.allVariants);
@@ -55520,19 +56025,19 @@ class CNVpytorVCF {
55520
56025
  if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) {
55521
56026
  //apply the beta function
55522
56027
  if (wigFeatures[chr][featureBin].likelihood_score.length == 0) {
55523
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56028
+ wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55524
56029
  return beta(ad_a, ad_b, value);
55525
56030
  });
55526
56031
  } else {
55527
56032
  var sum = 0;
55528
56033
 
55529
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56034
+ wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55530
56035
  var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value);
55531
56036
  sum = sum + likelihood_value;
55532
56037
  return likelihood_value;
55533
56038
  });
55534
56039
 
55535
- wigFeatures[chr][featureBin].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56040
+ wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55536
56041
  return wigFeatures[chr][featureBin].likelihood_score[index] / sum;
55537
56042
  });
55538
56043
  }
@@ -55578,7 +56083,6 @@ class CNVpytorVCF {
55578
56083
  if (sample.likelihood_score.length > 0) {
55579
56084
  const max = Math.max(...sample.likelihood_score);
55580
56085
  const res = sample.likelihood_score.indexOf(max);
55581
- sample.likelihood_score = [];
55582
56086
  sample.value = Math.max(res / 100, 1 - res / 100);
55583
56087
  sample.min_score = Math.min(res / 100, 1 - res / 100);
55584
56088
 
@@ -55594,7 +56098,7 @@ class CNVpytorVCF {
55594
56098
 
55595
56099
  //console.log('getAllbins', bins["value"])
55596
56100
 
55597
- const fitter = new GetFit(bins);
56101
+ const fitter = new g_utils.GetFit(bins);
55598
56102
 
55599
56103
  fitter.fit_data();
55600
56104
  // dconsole.log('rd list', distParams)
@@ -55602,7 +56106,7 @@ class CNVpytorVCF {
55602
56106
  return bins
55603
56107
  }
55604
56108
 
55605
- async read_rd_baf(){
56109
+ async read_rd_baf(caller='ReadDepth'){
55606
56110
 
55607
56111
  const chromosomes = Object.keys(this.allVariants);
55608
56112
  var wigFeatures = {};
@@ -55648,13 +56152,22 @@ class CNVpytorVCF {
55648
56152
  }
55649
56153
 
55650
56154
  }
55651
-
56155
+
55652
56156
  var avgbin = this.adjust_bin_size(wigFeatures);
56157
+ var finalFeatureSet;
56158
+ if(caller == 'ReadDepth'){
56159
+ finalFeatureSet = this.readDepthMeanshift(avgbin);
56160
+ var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood');
56161
+ }else if(caller=='2D'){
56162
+
56163
+ let caller_obj = new combined_caller.CombinedCaller(avgbin, this.binSize);
56164
+ let processed_bins = await caller_obj.call_2d();
56165
+
56166
+ finalFeatureSet = [processed_bins.binScore, [], processed_bins.segment_score];
56167
+
56168
+ var baf = caller_obj.formatDataStructure_BAF('max_likelihood');
56169
+ }
55653
56170
 
55654
- let finalFeatureSet = this.readDepthMeanshift(avgbin);
55655
-
55656
- //var rawbinScore = this.formatDataStructure(avgbin, 'binScore', globamMean)
55657
- var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood');
55658
56171
 
55659
56172
  return [finalFeatureSet, baf]
55660
56173
  }
@@ -55717,19 +56230,19 @@ class CNVpytorVCF {
55717
56230
 
55718
56231
  wigFeatures[chr][j].hets.forEach((hets, hets_idx) => {
55719
56232
  if(avgbin[chr][k].likelihood_score.length == 0){
55720
- avgbin[chr][k].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56233
+ avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55721
56234
  return beta(hets.ref, hets.alt, value);
55722
56235
  });
55723
56236
  }
55724
56237
  else {
55725
56238
  var likelihood_sum = 0;
55726
- avgbin[chr][k].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56239
+ avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55727
56240
  var likelihood_value = avgbin[chr][k].likelihood_score[index] * beta(hets.ref, hets.alt, value);
55728
56241
  likelihood_sum += likelihood_value;
55729
56242
  return likelihood_value;
55730
56243
  });
55731
56244
 
55732
- avgbin[chr][k].likelihood_score = linspace(0, 1, 100).map((value, index) => {
56245
+ avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {
55733
56246
  return avgbin[chr][k].likelihood_score[index] / likelihood_sum;
55734
56247
  });
55735
56248
 
@@ -55754,19 +56267,6 @@ function beta(a, b, p, phased = true) {
55754
56267
  return p ** a * (1 - p) ** b + p ** b * (1 - p) ** a;
55755
56268
  }
55756
56269
 
55757
- function linspace(a, b, n) {
55758
- if (typeof n === "undefined") n = Math.max(Math.round(b - a) + 1, 1);
55759
- if (n < 2) {
55760
- return n === 1 ? [a] : [];
55761
- }
55762
- var ret = Array(n);
55763
- n--;
55764
- for (let i = n; i >= 0; i--) {
55765
- ret[i] = (i * b + (n - i) * a) / n;
55766
- }
55767
- return ret;
55768
- }
55769
-
55770
56270
  /*
55771
56271
  * The MIT License (MIT)
55772
56272
  *
@@ -55877,29 +56377,43 @@ class CNVPytorTrack extends TrackBase {
55877
56377
  }, Object.create(null));
55878
56378
 
55879
56379
  const cnvpytor_obj = new CNVpytorVCF(allVariants, this.bin_size);
55880
- //const wigFeatures = await cnvpytor_obj.computeReadDepth()
55881
- //const bafFeatures = await cnvpytor_obj.computeBAF_v2()
55882
- const dataWigs = await cnvpytor_obj.read_rd_baf();
55883
- const wigFeatures = dataWigs[0];
55884
- const bafFeatures = dataWigs[1];
55885
56380
 
56381
+ let wigFeatures;
56382
+ let bafFeatures;
55886
56383
  this.wigFeatures_obj = {};
55887
- this.wigFeatures_obj[this.bin_size] = {
55888
- "RD_Raw": wigFeatures[0],
55889
- "RD_Raw_gc_coor": wigFeatures[1],
55890
- "ReadDepth": wigFeatures[2],
55891
- "2D": [],
55892
- "BAF1": bafFeatures[0],
55893
- "BAF2": bafFeatures[1]
55894
- };
55895
- this.rd_bins = [this.bin_size];
55896
- this.available_callers = ["ReadDepth"];
56384
+ this.wigFeatures_obj[this.bin_size] = {};
56385
+
56386
+ let dataWigs;
56387
+ if(this.config.cnv_caller == '2D'){
56388
+
56389
+ dataWigs = await cnvpytor_obj.read_rd_baf('2D');
56390
+
56391
+ wigFeatures = dataWigs[0];
56392
+ bafFeatures = dataWigs[1];
56393
+ this.wigFeatures_obj[this.bin_size]['2D'] = wigFeatures[2];
56394
+
56395
+ this.available_callers = ['2D'];
56396
+ }else {
56397
+ dataWigs = await cnvpytor_obj.read_rd_baf();
56398
+ wigFeatures = dataWigs[0];
56399
+ bafFeatures = dataWigs[1];
56400
+ this.wigFeatures_obj[this.bin_size]['ReadDepth'] = wigFeatures[2];
56401
+ this.available_callers = ['ReadDepth'];
56402
+ }
56403
+
56404
+ this.wigFeatures_obj[this.bin_size]['RD_Raw'] = wigFeatures[0];
56405
+ this.wigFeatures_obj[this.bin_size]['RD_Raw_gc_coor'] = wigFeatures[1];
56406
+ this.wigFeatures_obj[this.bin_size]['BAF1'] = bafFeatures[0];
56407
+ this.wigFeatures_obj[this.bin_size]['BAF2'] = bafFeatures[1];
56408
+
56409
+ this.available_bins = [this.bin_size];
56410
+
55897
56411
  this.set_available_callers();
55898
56412
 
55899
56413
  } else {
55900
56414
  this.cnvpytor_obj = new HDF5Reader(this.config.url, this.bin_size);
55901
56415
  this.wigFeatures_obj = await this.cnvpytor_obj.get_rd_signal(this.bin_size);
55902
- this.rd_bins = this.cnvpytor_obj.rd_bins;
56416
+ this.available_bins = this.cnvpytor_obj.available_bins;
55903
56417
  this.available_callers = this.cnvpytor_obj.callers;
55904
56418
  this.set_available_callers();
55905
56419
  }
@@ -56012,7 +56526,7 @@ class CNVPytorTrack extends TrackBase {
56012
56526
 
56013
56527
  items.push('<hr/>');
56014
56528
  items.push("Bin Sizes");
56015
- for (let rd_bin of this.rd_bins) {
56529
+ for (let rd_bin of this.available_bins) {
56016
56530
  const checkBox = createCheckbox(rd_bin, rd_bin === this.bin_size);
56017
56531
  items.push({
56018
56532
  object: $$1(checkBox),