icn3d 3.31.8 → 3.31.10

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/icn3d.module.js CHANGED
@@ -9963,9 +9963,9 @@ class ClickMenu {
9963
9963
  });
9964
9964
 
9965
9965
  me.myEventCls.onIds("#" + me.pre + "mn1_collection", "click", function (e) { me.icn3d; //e.preventDefault();
9966
- me.htmlCls.dialogCls.openDlg('dl_collection', 'Please input the collection file');
9967
- });
9968
-
9966
+ me.htmlCls.dialogCls.openDlg("dl_selectCollections", "Select Collections");
9967
+ });
9968
+
9969
9969
  me.myEventCls.onIds("#" + me.pre + "mn1_dsn6", "click", function(e) { me.icn3d; //e.preventDefault();
9970
9970
  me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the map file to display electron density map');
9971
9971
  });
@@ -15032,18 +15032,18 @@ class SetDialog {
15032
15032
  html += me.htmlCls.buttonStr + "reload_selectionfile' style='margin-top: 6px;'>Load</button>";
15033
15033
  html += "</div>";
15034
15034
 
15035
- html += me.htmlCls.divStr + "dl_collection' class='" + dialogClass + "'>";
15036
- html += this.addNotebookTitle('dl_collection', 'Please input the collection file');
15035
+ html += me.htmlCls.divStr + "dl_selectCollections' class='" + dialogClass + "'>";
15036
+ html += me.htmlCls.divStr + "dl_collectionsMenu'>";
15037
+ html += '<b>Collection File</b>: <div style="width:20px; margin-top:6px; display:inline-block;"><span id="' + me.pre + 'dl_collection_file_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="display:none; width:15px;" title="Expand"></span><span id="' + me.pre + 'dl_collection_file_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="width:15px;" title="Shrink"></span></div><br>';
15038
+ html += me.htmlCls.divStr + "dl_collection_file' style=''>";
15037
15039
  html += "You can load a collection of structures via a file. Here is <a href='https://github.com/ncbi/icn3d/blob/master/example/collection.json' target='_blank'>one example file</a><br><br>";
15038
15040
  html += "Collection file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "collectionfile'><br/>";
15039
15041
  html += me.htmlCls.buttonStr + "reload_collectionfile' style='margin-top: 6px;'>Load</button>";
15040
15042
  html += "</div>";
15041
-
15042
- html += me.htmlCls.divStr + "dl_selectCollections' class='" + dialogClass + "'>";
15043
- html += me.htmlCls.divStr + "dl_collectionsMenu'>";
15044
- html += "<b>Structures:</b> <br/>";
15045
- html += "<select id='" + me.pre + "collections_menu' multiple size='6' style='min-width:130px;'>";
15046
- html += "</select>";
15043
+ html += "</div>";
15044
+ html += '<br/><b>Structures</b>: <div style="width:20px; margin-top:6px; display:inline-block;"><span id="' + me.pre + 'dl_collection_structures_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="width:15px;" title="Expand"></span><span id="' + me.pre + 'dl_collection_structures_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="display:none; width:15px;" title="Shrink"></span></div><br>';
15045
+ html += me.htmlCls.divStr + "dl_collection_structures' style='display: none'>";
15046
+ html += "<select id='" + me.pre + "collections_menu'multiple size='6' style='min-width:300px;'></select>";
15047
15047
  html += "</div>";
15048
15048
  html += "</div>";
15049
15049
 
@@ -17406,17 +17406,13 @@ class Events {
17406
17406
  ic.resizeCanvasCls.closeDialogs();
17407
17407
  }
17408
17408
  me.htmlCls.setHtmlCls.fileSupport();
17409
- let reader = new FileReader();
17410
- reader.onload = async function (e) {
17409
+ let reader = new FileReader();
17410
+
17411
+ reader.onload = async function (e) {
17411
17412
  let dataStr = JSON.parse(e.target.result);
17412
17413
  let collection = [dataStr["structures"].map(({ id }) => id), dataStr["structures"].map(({ title }) => title)];
17413
17414
  let collectionHtml = ic.selectCollectionsCls.setAtomMenu(collection[0], collection[1]);
17414
- let bNoDuplicate = true;
17415
- await ic.chainalignParserCls.downloadMmdbAf(collection[0][0], undefined, undefined, bNoDuplicate);
17416
-
17417
- ic.opts["color"] = "structure";
17418
- ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
17419
-
17415
+
17420
17416
  $("#" + ic.pre + "collections_menu").html(collectionHtml);
17421
17417
  ic.selectCollectionsCls.clickStructure();
17422
17418
 
@@ -17427,8 +17423,27 @@ class Events {
17427
17423
  $("#" + me.pre + "collectionfile").val(),
17428
17424
  false
17429
17425
  );
17426
+
17430
17427
  };
17431
17428
  reader.readAsText(file);
17429
+
17430
+ if (Object.keys(me.utilsCls.getStructures(ic.dAtoms))){
17431
+ $("#" + me.pre + "dl_collection_file").hide();
17432
+ $("#" + me.pre + "dl_collection_structures").show();
17433
+ $("#" + me.pre + "dl_collection_file_expand").show();
17434
+ $("#" + me.pre + "dl_collection_file_shrink").hide();
17435
+ $("#" + me.pre + "dl_collection_structures_expand").hide();
17436
+ $("#" + me.pre + "dl_collection_structures_shrink").show();
17437
+
17438
+ } else {
17439
+ $("#" + me.pre + "dl_collection_file").show();
17440
+ $("#" + me.pre + "dl_collection_structures").hide();
17441
+ $("#" + me.pre + "dl_collection_file_expand").hide();
17442
+ $("#" + me.pre + "dl_collection_file_shrink").hide();
17443
+ $("#" + me.pre + "dl_collection_structures_expand").show();
17444
+ $("#" + me.pre + "dl_collection_structures_shrink").hide();
17445
+ }
17446
+
17432
17447
  me.htmlCls.dialogCls.openDlg("dl_selectCollections", "Select Collections");
17433
17448
  }
17434
17449
  });
@@ -41766,8 +41781,10 @@ class AnnoIg {
41766
41781
  }
41767
41782
 
41768
41783
  showRefNum(giSeq, chnid, kabat_or_imgt, bCustom) { let ic = this.icn3d; ic.icn3dui;
41769
- let bResult = ic.chainid2igtrack[chnid];
41770
- if(!bResult) return {html: '', html2: '', html3: ''};
41784
+ if(ic.chainid2igtrack) {
41785
+ let bResult = ic.chainid2igtrack[chnid];
41786
+ if(!bResult) return {html: '', html2: '', html3: ''};
41787
+ }
41771
41788
 
41772
41789
  let html = this.getIgAnnoHtml(chnid, giSeq, bCustom, kabat_or_imgt);
41773
41790
 
@@ -41834,12 +41851,13 @@ class AnnoIg {
41834
41851
  ic.chain2igArray[chnid] = [];
41835
41852
  this.setChain2igArray(chnid, giSeq, bCustom);
41836
41853
 
41837
-
41838
41854
  // remove Igs without BCEF strands one more time
41839
41855
  let igArray = ic.chain2igArray[chnid];
41840
41856
 
41841
41857
  for(let i = 0, il = igArray.length; i < il; ++i) {
41842
41858
  let domainid = igArray[i].domainid;
41859
+
41860
+ if(!ic.domainid2info) continue;
41843
41861
  let info = ic.domainid2info[domainid];
41844
41862
  if(!info) continue;
41845
41863
 
@@ -41907,7 +41925,6 @@ class AnnoIg {
41907
41925
  }
41908
41926
  }
41909
41927
 
41910
-
41911
41928
  // reset ic.chain2igArray
41912
41929
  ic.chain2igArray[chnid] = [];
41913
41930
  this.setChain2igArray(chnid, giSeq, bCustom);
@@ -41926,7 +41943,7 @@ class AnnoIg {
41926
41943
  // htmlIg += '<span></span>';
41927
41944
  //}
41928
41945
  //else {
41929
- refnumLabel = ic.resid2refnum[residueid];
41946
+ refnumLabel = (bCustom) ? ic.chainsMapping[chnid][residueid] : ic.resid2refnum[residueid];
41930
41947
  let bHidelabel = false;
41931
41948
 
41932
41949
  if(refnumLabel) {
@@ -42051,9 +42068,14 @@ class AnnoIg {
42051
42068
  html3 += htmlTmp + '<br>';
42052
42069
  html += htmlTmp + '<span class="icn3d-seqLine">';
42053
42070
 
42071
+ if(ic.seqStartLen && ic.seqStartLen[chnid]) html += ic.showSeqCls.insertMulGap(ic.seqStartLen[chnid], '-');
42072
+
42054
42073
  html += htmlIg;
42055
42074
 
42056
- html += htmlCnt;
42075
+ if(ic.seqStartLen && ic.seqStartLen[chnid]) html += ic.showSeqCls.insertMulGap(ic.seqEndLen[chnid], '-');
42076
+
42077
+ if(!bCustom) html += htmlCnt;
42078
+
42057
42079
  html += '</span>';
42058
42080
  html += '<br>';
42059
42081
  html += '</div>';
@@ -42067,6 +42089,8 @@ class AnnoIg {
42067
42089
 
42068
42090
  for(let i = 0, il = igArray.length; i < il; ++i) {
42069
42091
  let domainid = igArray[i].domainid;
42092
+ if(!ic.domainid2info) continue;
42093
+
42070
42094
  let info = ic.domainid2info[domainid];
42071
42095
  if(!info) continue;
42072
42096
 
@@ -42095,6 +42119,8 @@ class AnnoIg {
42095
42119
  html2 += htmlTitle;
42096
42120
  html2 += htmlCnt + '<span class="icn3d-seqLine">';
42097
42121
 
42122
+ if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
42123
+
42098
42124
  let prevDomainindex, color;
42099
42125
  for(let i = 0, il = fromArray.length; i < il; ++i) {
42100
42126
  let resi = ic.ParserUtilsCls.getResi(chnid, fromArray[i]);
@@ -42526,7 +42552,7 @@ class AnnoDomain {
42526
42552
 
42527
42553
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
42528
42554
 
42529
- if(me.cfg.blast_rep_id != chnid) { // regular
42555
+ if(me.cfg.blast_rep_id != chnid) { // regular
42530
42556
  for(let i = 0, il = posFromArray.length; i < il; ++i) {
42531
42557
  // let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i] - ic.baseResi[chnid] - 1) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
42532
42558
  let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
@@ -42535,7 +42561,7 @@ class AnnoDomain {
42535
42561
  html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(posToArray[i] - posFromArray[i] + 1) / ic.maxAnnoLength) + 'px;" class="icn3d-seqTitle icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + posFromArray + '" to="' + posToArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" id="' + chnid + '_3d_domain_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">3D domain ' +(index+1).toString() + '</div>';
42536
42562
  }
42537
42563
  }
42538
- else { // with potential gaps
42564
+ else { // with potential gaps
42539
42565
  let fromArray2 = [], toArray2 = [];
42540
42566
  for(let i = 0, il = fromArray.length; i < il; ++i) {
42541
42567
  fromArray2.push(fromArray[i]);
@@ -45326,7 +45352,7 @@ class AddTrack {
45326
45352
 
45327
45353
  getExonHtml(exonIndex, colorGradient, from, to, genomeRange, chainid, simpTitle) { let ic = this.icn3d; ic.icn3dui;
45328
45354
  // return '<div style="display:inline-block; color:white!important; width:' + Math.round(ic.seqAnnWidth *(to - from + 1) /(ic.maxAnnoLength + ic.nTotalGap)) + 'px;" class="icn3d-seqTitle icn3d-link icn3d-blue" domain="' + (exonIndex + 1) + '" from="' + from + '" to="' + to + '" setname="' + simpTitle + ', Exon ' + (exonIndex + 1) + '" title="Exon ' + (exonIndex + 1) + ': ' + genomeRange + ' genomic interval" anno="sequence" chain="' + chainid + '"><div style="height: 12px; border: 1px solid #000; background: linear-gradient(to right, ' + colorGradient + ');"></div></div>';
45329
- return '<div style="display:inline-block; color:white!important; width:' + Math.round(ic.seqAnnWidth *(to - from + 1) /(ic.maxAnnoLength + ic.nTotalGap)) + 'px;" class="icn3d-seqTitle icn3d-link icn3d-blue" domain="' + (exonIndex + 1) + '" from="' + from + '" to="' + to + '" setname="' + simpTitle + ', #' + (exonIndex + 1) + '" title="Exon: ' + genomeRange + ' genomic interval" anno="sequence" chain="' + chainid + '"><div style="height: 12px; border: 1px solid #000; background: linear-gradient(to right, ' + colorGradient + ');"></div></div>';
45355
+ return '<div style="display:inline-block; color:white!important; width:' + Math.round(ic.seqAnnWidth *(to - from + 1) /(ic.maxAnnoLength + ic.nTotalGap)) + 'px;" class="icn3d-seqTitle icn3d-link icn3d-blue" domain="' + (exonIndex + 1) + '" from="' + from + '" to="' + to + '" setname="' + simpTitle + ', ' + (exonIndex + 1) + '" title="Exon: ' + genomeRange + ' genomic interval" anno="sequence" chain="' + chainid + '"><div style="height: 12px; border: 1px solid #000; background: linear-gradient(to right, ' + colorGradient + ');"></div></div>';
45330
45356
  }
45331
45357
 
45332
45358
  getExonColor(start, end, pos) { let ic = this.icn3d; ic.icn3dui;
@@ -48458,6 +48484,7 @@ class ShowSeq {
48458
48484
  let bCustom = true;
48459
48485
  let result = ic.annoIgCls.showRefNum(giSeq, chnid, undefined, bCustom);
48460
48486
  html += result.html;
48487
+ // html2 += result.html2;
48461
48488
  html3 += result.html3;
48462
48489
  }
48463
48490
  }
@@ -61894,13 +61921,15 @@ class SetSeqAlign {
61894
61921
  ic.alnChains = {};
61895
61922
  ic.alnChains[chainid1] = {};
61896
61923
 
61897
- let resi2range_t = {}; // accumulative aligned residues in the template chain
61924
+ let resid2range_t = {}; // accumulative aligned residues in the template chain
61898
61925
  // start and end of MSA
61899
61926
  let start_t = 9999, end_t = -1;
61900
61927
 
61901
61928
  let baseResi = ic.chainsSeq[chainid1][0].resi - 1;
61929
+
61902
61930
  for(let index = 1, indexl = chainidArray.length; index < indexl; ++index) {
61903
61931
  let chainIndex = index - 1;
61932
+ chainidArray[index];
61904
61933
  if(!ic.qt_start_end[chainIndex]) continue;
61905
61934
 
61906
61935
  for(let i = 0, il = ic.qt_start_end[chainIndex].length; i < il; ++i) {
@@ -61911,11 +61940,12 @@ class SetSeqAlign {
61911
61940
  // end1 = ic.qt_start_end[chainIndex][i].t_end;
61912
61941
  // }
61913
61942
  // else {
61943
+ //ic.qt_start_end is zero-based
61914
61944
  start1 = parseInt(ic.qt_start_end[chainIndex][i].t_start) - 1;
61915
61945
  end1 = parseInt(ic.qt_start_end[chainIndex][i].t_end) - 1;
61916
61946
  // }
61917
61947
  for(let j = start1; j <= end1; ++j) {
61918
- let resi;
61948
+ let resi, resid;
61919
61949
 
61920
61950
  // if(me.cfg.aligntool == 'tmalign') { // tmalign: just one residue in this for loop
61921
61951
  // resi = ic.qt_start_end[chainIndex][i].t_start;
@@ -61927,53 +61957,56 @@ class SetSeqAlign {
61927
61957
  resiPos = j - baseResi;
61928
61958
  }
61929
61959
  else {
61930
- resiPos = (bRealign) ? j : j - baseResi;
61960
+ // resiPos = (bRealign) ? j : j - baseResi;
61961
+ resiPos = j;
61931
61962
  }
61932
61963
  resi = ic.ParserUtilsCls.getResi(chainidArray[0], resiPos);
61964
+ resid = chainidArray[0] + '_' + resi;
61933
61965
  // }
61934
61966
 
61935
- resi2range_t[resi] = 1;
61967
+ resid2range_t[resid] = 1;
61936
61968
  if(j < start_t) start_t = j;
61937
61969
  if(j > end_t) end_t = j;
61938
61970
  }
61939
61971
  }
61940
61972
  }
61941
-
61973
+
61942
61974
  // TM-align should use "start1 = ic.qt_start_end[chainIndex][i].t_start - 1", but the rest are the same as ""bRealign"
61943
61975
  if(me.cfg.aligntool == 'tmalign') bRealign = true; // real residue numbers are stored
61944
61976
 
61945
- let resi2rangeArray = Object.keys(resi2range_t);
61946
- resi2rangeArray.sort(function(a, b) {
61947
- return parseInt(a) - parseInt(b);
61977
+ let resid2rangeArray = Object.keys(resid2range_t);
61978
+ resid2rangeArray.sort(function(a, b) {
61979
+ return parseInt(a.split('_')[2]) - parseInt(b.split('_')[2]);
61948
61980
  });
61949
61981
 
61950
61982
  // assign range to each resi
61951
- let prevResi = -999, start = 0, end = 0, resiArray = [], prevEnd = 0;
61952
- for(let i = 0, il = resi2rangeArray.length; i < il; ++i) {
61953
- let resi = resi2rangeArray[i];
61983
+ let prevResi = -999, start = 0, end = 0, residArray = [], prevEnd = 0;
61984
+ for(let i = 0, il = resid2rangeArray.length; i < il; ++i) {
61985
+ let resid = resid2rangeArray[i];
61986
+ let resi = resid.split('_')[2];
61954
61987
 
61955
61988
  if(i == 0) {
61956
61989
  start = resi;
61957
61990
  }
61958
61991
  else if(i > 0 && ic.resid2ncbi[resi] != ic.resid2ncbi[prevResi] + 1 && ic.resid2ncbi[resi] != ic.resid2ncbi[prevResi]) { // new start
61959
61992
  end = prevResi;
61960
- for(let j = 0, jl = resiArray.length; j < jl; ++j) {
61961
- resi2range_t[resiArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61993
+ for(let j = 0, jl = residArray.length; j < jl; ++j) {
61994
+ resid2range_t[residArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61962
61995
  }
61963
61996
 
61964
- resiArray = [];
61997
+ residArray = [];
61965
61998
  start = resi;
61966
61999
  prevEnd = end;
61967
62000
  }
61968
62001
 
61969
- resiArray.push(resi);
62002
+ residArray.push(resid);
61970
62003
 
61971
62004
  prevResi = resi;
61972
62005
  }
61973
62006
 
61974
62007
  end = prevResi;
61975
- for(let j = 0, jl = resiArray.length; j < jl; ++j) {
61976
- resi2range_t[resiArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
62008
+ for(let j = 0, jl = residArray.length; j < jl; ++j) {
62009
+ resid2range_t[residArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61977
62010
  }
61978
62011
 
61979
62012
  for(let i = 0, il = chainidArray.length; i < il; ++i) {
@@ -61987,6 +62020,7 @@ class SetSeqAlign {
61987
62020
  // fill the template ic.alnChainsSeq[chainid1]
61988
62021
  for(let j = 0, jl = ic.chainsSeq[chainid1].length; j < jl; ++j) {
61989
62022
  let resi = ic.chainsSeq[chainid1][j].resi;
62023
+ let resid = chainid1 + '_' + resi;
61990
62024
 
61991
62025
  let jAdjusted = (me.cfg.aligntool != 'tmalign') ? j : j + baseResi;
61992
62026
 
@@ -62000,15 +62034,15 @@ class SetSeqAlign {
62000
62034
  resObject.mmdbid = chainid1.substr(0, pos);
62001
62035
  resObject.chain = chainid1.substr(pos+1);
62002
62036
  resObject.resi = resi;
62003
- resObject.resn = (resi2range_t[resi]) ? ic.chainsSeq[chainid1][j].name.toUpperCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
62004
- resObject.aligned = (resi2range_t[resi]) ? true : false;
62005
- resObject.color = (resi2range_t[resi]) ? '#FF0000' : me.htmlCls.GREYC; // color by identity
62006
- resObject.color2 = (resi2range_t[resi]) ? '#FF0000' : me.htmlCls.GREYC; // color by conservation
62007
- resObject.class = (resi2range_t[resi]) ? 'icn3d-align' : 'icn3d-nalign';
62037
+ resObject.resn = (resid2range_t[resid]) ? ic.chainsSeq[chainid1][j].name.toUpperCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
62038
+ resObject.aligned = (resid2range_t[resid]) ? true : false;
62039
+ resObject.color = (resid2range_t[resid]) ? '#FF0000' : me.htmlCls.GREYC; // color by identity
62040
+ resObject.color2 = (resid2range_t[resid]) ? '#FF0000' : me.htmlCls.GREYC; // color by conservation
62041
+ resObject.class = (resid2range_t[resid]) ? 'icn3d-align' : 'icn3d-nalign';
62008
62042
 
62009
62043
  ic.alnChainsSeq[chainid1].push(resObject);
62010
62044
 
62011
- if(resi2range_t[resi]) {
62045
+ if(resid2range_t[resid]) {
62012
62046
  $.extend(ic.alnChains[chainid1], ic.residues[chainid1 + '_' + resObject.resi] );
62013
62047
  hAtoms = me.hashUtilsCls.unionHash(hAtoms, ic.residues[chainid1 + '_' + resObject.resi]);
62014
62048
  }
@@ -62020,7 +62054,7 @@ class SetSeqAlign {
62020
62054
  for(let arrayIndex = 0, arrayIndexl = index_alignLen.length; arrayIndex < arrayIndexl; ++arrayIndex) {
62021
62055
  let index = index_alignLen[arrayIndex].index;
62022
62056
  alignedChainIndice.push(index);
62023
- let hAtomsTmp = this.mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resi2range_t, start_t, end_t, bRealign);
62057
+ let hAtomsTmp = this.mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resid2range_t, start_t, end_t, bRealign);
62024
62058
 
62025
62059
  hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
62026
62060
  }
@@ -62193,7 +62227,7 @@ class SetSeqAlign {
62193
62227
  return {"pos1": result1.pos, "pos2": result2.pos};
62194
62228
  }
62195
62229
 
62196
- mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resi2range_t, start_t, end_t, bRealign) { let ic = this.icn3d, me = ic.icn3dui;
62230
+ mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resid2range_t, start_t, end_t, bRealign) { let ic = this.icn3d, me = ic.icn3dui;
62197
62231
  let hAtoms = {};
62198
62232
 
62199
62233
  let chainid = chainidArray[index];
@@ -62282,7 +62316,7 @@ class SetSeqAlign {
62282
62316
  start1Pos = start1;
62283
62317
  end1Pos = end1;
62284
62318
  }
62285
- //let range = resi2range_t[resiStart1];
62319
+ //let range = resid2range_t[chainid1 + '_' + resiStart1];
62286
62320
 
62287
62321
  // if the mapping does not start from start_t, add gaps to the query seq
62288
62322
  if(i == 0) {
@@ -67750,70 +67784,181 @@ class SelectCollections {
67750
67784
  return html;
67751
67785
  }
67752
67786
 
67787
+ reset() {
67788
+ let ic = this.icn3d;
67789
+
67790
+ ic.atoms = {};
67791
+
67792
+ ic.proteins = {};
67793
+ ic.nucleotides = {};
67794
+ ic.chemicals = {};
67795
+ ic.ions = {};
67796
+ ic.water = {};
67797
+
67798
+ ic.structures = {};
67799
+ ic.chains = {};
67800
+ ic.chainsSeq = {};
67801
+ ic.residues = {};
67802
+
67803
+ ic.defNames2Atoms = {};
67804
+ ic.defNames2Residues = {};
67805
+
67806
+ ic.ssbondpnts = {};
67807
+
67808
+ ic.bShowHighlight = false;
67809
+ ic.bResetSets = true;
67810
+ }
67811
+
67812
+ dictionaryDifference(dict1, dict2) {
67813
+ const difference = {};
67814
+
67815
+ for (let key in dict2) {
67816
+ if (!(key in dict1)) {
67817
+ difference[key] = dict2[key];
67818
+ }
67819
+ }
67820
+
67821
+ return difference;
67822
+ }
67823
+
67753
67824
  clickStructure() {
67754
67825
  let ic = this.icn3d,
67755
67826
  me = ic.icn3dui;
67756
67827
  let thisClass = this;
67757
67828
 
67829
+ if (ic.allData == undefined) {
67830
+ ic.allData = {};
67831
+ ic.allData['all'] = {
67832
+ 'atoms': {},
67833
+ 'proteins': {},
67834
+ 'nucleotides': {},
67835
+ 'chemicals': {},
67836
+ 'ions': {},
67837
+ 'water': {},
67838
+ 'structures': {}, // getSSExpandedAtoms
67839
+ 'ssbondpnts': {},
67840
+ 'residues': {}, // getSSExpandedAtoms
67841
+ 'chains': {},
67842
+ 'chainsSeq': {}, //Sequences and Annotation
67843
+ 'defNames2Atoms': {},
67844
+ 'defNames2Residues': {}
67845
+ };
67846
+ ic.allData['prev'] = {};
67847
+ }
67848
+
67758
67849
  //me.myEventCls.onIds("#" + ic.pre + "atomsCustom", "change", function(e) { let ic = thisClass.icn3d;
67759
67850
  $("#" + ic.pre + "collections_menu").change(async function (e) {
67760
67851
  let ic = thisClass.icn3d;
67761
- // ic.init()
67852
+
67762
67853
  let nameArray = $(this).val();
67763
67854
  let nameStructure = $(this).find("option:selected").text();
67764
67855
 
67765
67856
  ic.nameArray = nameArray;
67766
67857
  if (nameArray !== null) {
67767
- ic.bShowHighlight = false;
67858
+ // let chainIdHash = {};
67859
+
67768
67860
  let bNoDuplicate = true;
67769
- await ic.chainalignParserCls.downloadMmdbAf(nameArray.toString(), undefined, undefined, bNoDuplicate);
67861
+ thisClass.reset();
67862
+ for (const name of nameArray) {
67863
+ if (!(name in ic.allData)) {
67864
+ ic.allData['prev'] = JSON.parse(JSON.stringify(ic.allData['all']));//me.hashUtilsCls.cloneHash(ic.allData['all']);
67770
67865
 
67771
- ic.dAtoms = {};
67772
- ic.hAtoms = {};
67773
- // ic.ssbondpnts = {};
67774
- let chainIdHash = {};
67775
-
67776
- for (const name in nameArray) {
67777
- for (const key in ic.chains) {
67778
- if (key.includes(nameArray[name])) {
67779
- chainIdHash[key] = 1;
67780
- if (ic.chains.hasOwnProperty(key)) {
67781
- const innerDict = ic.chains[key];
67782
- for (const innerKey in innerDict) {
67783
- if (innerDict.hasOwnProperty(innerKey)) {
67784
- ic.dAtoms[innerKey] = innerDict[innerKey];
67785
- ic.hAtoms[innerKey] = innerDict[innerKey];
67786
- }
67787
- }
67788
- }
67789
- }
67866
+ ic.atoms = ic.allData['all']['atoms'];
67867
+
67868
+ ic.proteins = ic.allData['all']['proteins'];
67869
+ ic.nucleotides = ic.allData['all']['nucleotides'];
67870
+ ic.chemicals = ic.allData['all']['chemicals'];
67871
+ ic.ions = ic.allData['all']['ions'];
67872
+ ic.water = ic.allData['all']['water'];
67873
+
67874
+ ic.structures = ic.allData['all']['structures'];
67875
+ ic.ssbondpnts = ic.allData['all']['ssbondpnts'];
67876
+ ic.residues = ic.allData['all']['residues'];
67877
+ ic.chains = ic.allData['all']['chains'];
67878
+ ic.chainsSeq = ic.allData['all']['chainsSeq'];
67879
+ ic.defalls2Atoms = ic.allData['all']['defalls2Atoms'];
67880
+ ic.defalls2Residues = ic.allData['all']['defalls2Residues'];
67881
+ await ic.chainalignParserCls.downloadMmdbAf(name, undefined, undefined, bNoDuplicate).then(() => {
67882
+ ic.allData['all'] = {
67883
+ 'atoms': ic.atoms,
67884
+ 'proteins': ic.proteins,
67885
+ 'nucleotides': ic.nucleotides,
67886
+ 'chemicals': ic.chemicals,
67887
+ 'ions': ic.ions,
67888
+ 'water': ic.water,
67889
+ 'structures': ic.structures, // getSSExpandedAtoms
67890
+ 'ssbondpnts': ic.ssbondpnts,
67891
+ 'residues': ic.residues, // getSSExpandedAtoms
67892
+ 'chains': ic.chains,
67893
+ 'chainsSeq': ic.chainsSeq, //Sequences and Annotation
67894
+ 'defNames2Atoms': ic.defNames2Atoms,
67895
+ 'defNames2Residues': ic.defNames2Residues
67896
+ };
67897
+
67898
+ ic.allData[name] = {
67899
+ 'atoms': thisClass.dictionaryDifference(ic.allData['prev']['atoms'], ic.atoms),
67900
+ 'proteins': thisClass.dictionaryDifference(ic.allData['prev']['proteins'], ic.proteins),
67901
+ 'nucleotides': thisClass.dictionaryDifference(ic.allData['prev']['nucleotides'], ic.nucleotides),
67902
+ 'chemicals': thisClass.dictionaryDifference(ic.allData['prev']['chemicals'], ic.chemicals),
67903
+ 'ions': thisClass.dictionaryDifference(ic.allData['prev']['ions'], ic.ions),
67904
+ 'water': thisClass.dictionaryDifference(ic.allData['prev']['water'], ic.water),
67905
+ 'structures': thisClass.dictionaryDifference(ic.allData['prev']['structures'], ic.structures), // getSSExpandedAtoms
67906
+ 'ssbondpnts': thisClass.dictionaryDifference(ic.allData['prev']['ssbondpnts'], ic.ssbondpnts),
67907
+ 'residues': thisClass.dictionaryDifference(ic.allData['prev']['residues'], ic.residues), // getSSExpandedAtoms
67908
+ 'chains': thisClass.dictionaryDifference(ic.allData['prev']['chains'], ic.chains),
67909
+ 'chainsSeq': thisClass.dictionaryDifference(ic.allData['prev']['chainsSeq'], ic.chainsSeq), //Sequences and Annotation
67910
+ 'defNames2Atoms': thisClass.dictionaryDifference(ic.allData['prev']['defNames2Atoms'], ic.defNames2Atoms),
67911
+ 'defNames2Residues': thisClass.dictionaryDifference(ic.allData['prev']['defNames2Residues'], ic.defNames2Residues)
67912
+ };
67913
+
67914
+ // ic.atoms = Object.assign(ic.atoms, ic.atomsTemp);
67915
+ thisClass.reset();
67916
+ });
67790
67917
  }
67791
67918
  }
67919
+ for (const name of nameArray) {
67920
+ ic.atoms = Object.assign(ic.atoms, ic.allData[name]['atoms']);
67921
+
67922
+ ic.proteins = Object.assign(ic.proteins, ic.allData[name]['proteins']);
67923
+ ic.nucleotides = Object.assign(ic.nucleotides, ic.allData[name]['nucleotides']);
67924
+ ic.chemicals = Object.assign(ic.chemicals, ic.allData[name]['chemicals']);
67925
+ ic.ions = Object.assign(ic.ions, ic.allData[name]['ions']);
67926
+ ic.water = Object.assign(ic.water, ic.allData[name]['water']);
67927
+
67928
+ ic.structures = Object.assign(ic.structures, ic.allData[name]['structures']);
67929
+ ic.ssbondpnts = Object.assign(ic.ssbondpnts, ic.allData[name]['ssbondpnts']);
67930
+ ic.residues = Object.assign(ic.residues, ic.allData[name]['residues']);
67931
+ ic.chains = Object.assign(ic.chains, ic.allData[name]['chains']);
67932
+ ic.chainsSeq = Object.assign(ic.chainsSeq, ic.allData[name]['chainsSeq']);
67933
+ ic.defNames2Atoms = Object.assign(ic.defNames2Atoms, ic.allData[name]['defNames2Atoms']);
67934
+ ic.defNames2Residues = Object.assign(ic.defNames2Residues, ic.allData[name]['defNames2Residues']);
67935
+ ic.dAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
67936
+ ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
67937
+ }
67938
+
67939
+ ic.opts["color"] = "structure";
67940
+ ic.setStyleCls.setAtomStyleByOptions();
67941
+ ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
67792
67942
 
67793
67943
  ic.transformCls.zoominSelection();
67794
67944
  ic.definedSetsCls.showSets();
67795
67945
 
67796
- await ic.drawCls.draw();
67797
- ic.saveFileCls.showTitle();
67798
-
67799
67946
  ic.bResetAnno = true;
67800
67947
  if(ic.bAnnoShown) {
67801
- // show annotations just fo the displayed atoms
67802
- // await ic.showAnnoCls.showAnnotations(ic.dAtoms);
67803
67948
  await ic.showAnnoCls.showAnnotations();
67804
67949
 
67805
67950
  ic.hlUpdateCls.updateHlAll(nameArray);
67806
67951
  // show selected chains in annotation window
67807
67952
  ic.annotationCls.showAnnoSelectedChains();
67808
67953
  }
67809
-
67954
+
67955
+ await ic.drawCls.draw();
67956
+ ic.saveFileCls.showTitle();
67957
+
67810
67958
  me.htmlCls.clickMenuCls.setLogCmd(
67811
67959
  "select structure " + "[" + nameStructure + "]",
67812
67960
  true
67813
67961
  );
67814
- ic.bSelectResidue = false;
67815
-
67816
- ic.bShowHighlight = true; // reset
67817
67962
  }
67818
67963
  });
67819
67964
 
@@ -68368,7 +68513,10 @@ class LoadScript {
68368
68513
  let idArray = id.split(',');
68369
68514
  let idNew = '';
68370
68515
  for(let i = 0, il = idArray.length; i < il; ++i) {
68371
- if(!(ic.structures && ic.structures.hasOwnProperty(idArray[i]))) {
68516
+ if(!(ic.structures && (ic.structures.hasOwnProperty(idArray[i])
68517
+ || ic.structures.hasOwnProperty(idArray[i].toLowerCase())
68518
+ || ic.structures.hasOwnProperty(idArray[i].toUpperCase())
68519
+ ) )) {
68372
68520
  if(idNew) idNew += ',';
68373
68521
  idNew += idArray[i];
68374
68522
  }
@@ -71392,7 +71540,7 @@ class Dssp {
71392
71540
  ic.ref2igtype['LaminAC_1ifrA_human'] = 'Lamin';
71393
71541
  ic.ref2igtype['MHCIa_7phrH_human_C1'] = 'IgC1';
71394
71542
  ic.ref2igtype['MPT63_1lmiA_bacteria'] = 'IgE';
71395
- ic.ref2igtype['NaCaExchanger_2fwuA_dog_n2'] = 'IgE';
71543
+ ic.ref2igtype['NaCaExchanger_2fwuA_dog_n2'] = 'IgFN3-like';
71396
71544
  ic.ref2igtype['NaKATPaseTransporterBeta_2zxeB_spurdogshark'] = 'IgE';
71397
71545
  ic.ref2igtype['ORF7a_1xakA_virus'] = 'ORF';
71398
71546
  ic.ref2igtype['PD1_4zqkB_human_V'] = 'IgV';
@@ -72119,14 +72267,16 @@ class Dssp {
72119
72267
  let resiDistToC = (bCpstrand) ? parseInt(CpAtom.resi) - parseInt(CAtom.resi) : parseInt(DAtom.resi) - parseInt(CAtom.resi);
72120
72268
  let resiDistToE = (bCpstrand) ? parseInt(EAtom.resi) - parseInt(CpAtom.resi) : parseInt(EAtom.resi) - parseInt(DAtom.resi);
72121
72269
 
72270
+ let adjust = 1;
72271
+
72122
72272
  if(bCpstrand) {
72123
- if(distToC > distToE || (distToC == distToE && resiDistToC > resiDistToE)) { // rename C' to D
72273
+ if(distToC > distToE + adjust || (distToC == distToE + adjust && resiDistToC > resiDistToE + adjust)) { // rename C' to D
72124
72274
  CpToDResi.push(CpAtom.resi);
72125
72275
  if(!me.bNode) console.log("Rename strand C' to D: distToC " + distToC + " distToE " + distToE + " resiDistToC " + resiDistToC + " resiDistToE " + resiDistToE);
72126
72276
  }
72127
72277
  }
72128
72278
  else if(bDstrand) {
72129
- if(distToC < distToE || (distToC == distToE && resiDistToC < resiDistToE)) { // rename D to C'
72279
+ if(distToC + adjust < distToE || (distToC + adjust == distToE && resiDistToC + adjust < resiDistToE)) { // rename D to C'
72130
72280
  DToCpResi.push(DAtom.resi);
72131
72281
  if(!me.bNode) console.log("Rename strand D to C': distToC " + distToC + " distToE " + distToE + " resiDistToC " + resiDistToC + " resiDistToE " + resiDistToE);
72132
72282
  }
@@ -72146,7 +72296,8 @@ class Dssp {
72146
72296
 
72147
72297
  seg.q_start;
72148
72298
  let qStartInt = parseInt(seg.q_start);
72149
- if(isNaN(seg.q_start)) seg.q_start.substr(seg.q_start.length - 1, 1);
72299
+ let postfix = '';
72300
+ if(isNaN(seg.q_start)) postfix = seg.q_start.substr(seg.q_start.length - 1, 1);
72150
72301
 
72151
72302
  // one item in "seq"
72152
72303
  // q_start and q_end are numbers, but saved in string
@@ -72161,7 +72312,7 @@ class Dssp {
72161
72312
  //let refnum = qStart;
72162
72313
  let refnum = qStartInt;
72163
72314
 
72164
- let refnumLabel = this.getLabelFromRefnum(refnum);
72315
+ let refnumLabel = this.getLabelFromRefnum(refnum, postfix);
72165
72316
  currStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
72166
72317
 
72167
72318
  let currStrandFinal = currStrand;
@@ -72183,7 +72334,7 @@ class Dssp {
72183
72334
  }
72184
72335
 
72185
72336
  if(currStrand != currStrandFinal) {
72186
- refnumLabel = this.getLabelFromRefnum(refnum, currStrandFinal);
72337
+ refnumLabel = this.getLabelFromRefnum(refnum, postfix, currStrandFinal);
72187
72338
  }
72188
72339
 
72189
72340
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
@@ -72219,7 +72370,7 @@ class Dssp {
72219
72370
  }
72220
72371
  }
72221
72372
 
72222
- getStrandFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
72373
+ getStrandFromRefnum(oriRefnum, finalStrand) { let ic = this.icn3d; ic.icn3dui;
72223
72374
  let refnum = parseInt(oriRefnum);
72224
72375
 
72225
72376
  //N-terminus = 0999-0001
@@ -72298,16 +72449,25 @@ class Dssp {
72298
72449
  else if(refnum > 9900) strand = undefined;
72299
72450
  else strand = " ";
72300
72451
 
72301
- if(prevStrand) strand = prevStrand;
72452
+ if(finalStrand) strand = finalStrand;
72302
72453
 
72303
72454
  return strand
72304
72455
  }
72305
72456
 
72306
- getLabelFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
72307
- let strand = this.getStrandFromRefnum(oriRefnum, prevStrand);
72457
+ getLabelFromRefnum(oriRefnum, postfix, finalStrand) { let ic = this.icn3d; ic.icn3dui;
72458
+ let strand = this.getStrandFromRefnum(oriRefnum, finalStrand);
72459
+
72460
+ // rename C' to D or D to C'
72461
+ let refnum = oriRefnum.toString();
72462
+ if(finalStrand == "C'" && refnum.substr(0, 1) == '6') { // previous D
72463
+ refnum = '4' + refnum.substr(1);
72464
+ }
72465
+ else if(finalStrand == "D" && refnum.substr(0, 1) == '4') { // previous C'
72466
+ refnum = '6' + refnum.substr(1);
72467
+ }
72308
72468
 
72309
72469
  if(strand) {
72310
- return strand + oriRefnum;
72470
+ return strand + refnum + postfix;
72311
72471
  }
72312
72472
  else {
72313
72473
  return undefined;
@@ -72381,7 +72541,12 @@ class Dssp {
72381
72541
  }
72382
72542
 
72383
72543
  rmStrandFromRefnumlabel(refnumLabel) { let ic = this.icn3d; ic.icn3dui;
72384
- return (!refnumLabel) ? refnumLabel : refnumLabel.replace(/'/g, '').replace(/\*/g, '').replace(/\^/g, '').replace(/\+/g, '').replace(/\-/g, '').substr(1); // C', C''
72544
+ if(isNaN(refnumLabel.substr(0,1))) {
72545
+ return (!refnumLabel) ? refnumLabel : refnumLabel.replace(/'/g, '').replace(/\*/g, '').replace(/\^/g, '').replace(/\+/g, '').replace(/\-/g, '').substr(1); // C', C''
72546
+ }
72547
+ else { // custom ref numbers
72548
+ return refnumLabel;
72549
+ }
72385
72550
  }
72386
72551
 
72387
72552
  exportRefnum(type, bNoArraySymbol) { let ic = this.icn3d, me = ic.icn3dui;
@@ -81226,7 +81391,7 @@ class iCn3DUI {
81226
81391
  //even when multiple iCn3D viewers are shown together.
81227
81392
  this.pre = this.cfg.divid + "_";
81228
81393
 
81229
- this.REVISION = '3.31.2';
81394
+ this.REVISION = '3.31.3';
81230
81395
 
81231
81396
  // In nodejs, iCn3D defines "window = {navigator: {}}"
81232
81397
  this.bNode = (Object.keys(window).length < 2) ? true : false;