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.js CHANGED
@@ -9062,9 +9062,9 @@ class ClickMenu {
9062
9062
  });
9063
9063
 
9064
9064
  me.myEventCls.onIds("#" + me.pre + "mn1_collection", "click", function (e) { me.icn3d; //e.preventDefault();
9065
- me.htmlCls.dialogCls.openDlg('dl_collection', 'Please input the collection file');
9066
- });
9067
-
9065
+ me.htmlCls.dialogCls.openDlg("dl_selectCollections", "Select Collections");
9066
+ });
9067
+
9068
9068
  me.myEventCls.onIds("#" + me.pre + "mn1_dsn6", "click", function(e) { me.icn3d; //e.preventDefault();
9069
9069
  me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the map file to display electron density map');
9070
9070
  });
@@ -14131,18 +14131,18 @@ class SetDialog {
14131
14131
  html += me.htmlCls.buttonStr + "reload_selectionfile' style='margin-top: 6px;'>Load</button>";
14132
14132
  html += "</div>";
14133
14133
 
14134
- html += me.htmlCls.divStr + "dl_collection' class='" + dialogClass + "'>";
14135
- html += this.addNotebookTitle('dl_collection', 'Please input the collection file');
14134
+ html += me.htmlCls.divStr + "dl_selectCollections' class='" + dialogClass + "'>";
14135
+ html += me.htmlCls.divStr + "dl_collectionsMenu'>";
14136
+ 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>';
14137
+ html += me.htmlCls.divStr + "dl_collection_file' style=''>";
14136
14138
  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>";
14137
14139
  html += "Collection file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "collectionfile'><br/>";
14138
14140
  html += me.htmlCls.buttonStr + "reload_collectionfile' style='margin-top: 6px;'>Load</button>";
14139
14141
  html += "</div>";
14140
-
14141
- html += me.htmlCls.divStr + "dl_selectCollections' class='" + dialogClass + "'>";
14142
- html += me.htmlCls.divStr + "dl_collectionsMenu'>";
14143
- html += "<b>Structures:</b> <br/>";
14144
- html += "<select id='" + me.pre + "collections_menu' multiple size='6' style='min-width:130px;'>";
14145
- html += "</select>";
14142
+ html += "</div>";
14143
+ 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>';
14144
+ html += me.htmlCls.divStr + "dl_collection_structures' style='display: none'>";
14145
+ html += "<select id='" + me.pre + "collections_menu'multiple size='6' style='min-width:300px;'></select>";
14146
14146
  html += "</div>";
14147
14147
  html += "</div>";
14148
14148
 
@@ -16505,17 +16505,13 @@ class Events {
16505
16505
  ic.resizeCanvasCls.closeDialogs();
16506
16506
  }
16507
16507
  me.htmlCls.setHtmlCls.fileSupport();
16508
- let reader = new FileReader();
16509
- reader.onload = async function (e) {
16508
+ let reader = new FileReader();
16509
+
16510
+ reader.onload = async function (e) {
16510
16511
  let dataStr = JSON.parse(e.target.result);
16511
16512
  let collection = [dataStr["structures"].map(({ id }) => id), dataStr["structures"].map(({ title }) => title)];
16512
16513
  let collectionHtml = ic.selectCollectionsCls.setAtomMenu(collection[0], collection[1]);
16513
- let bNoDuplicate = true;
16514
- await ic.chainalignParserCls.downloadMmdbAf(collection[0][0], undefined, undefined, bNoDuplicate);
16515
-
16516
- ic.opts["color"] = "structure";
16517
- ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
16518
-
16514
+
16519
16515
  $("#" + ic.pre + "collections_menu").html(collectionHtml);
16520
16516
  ic.selectCollectionsCls.clickStructure();
16521
16517
 
@@ -16526,8 +16522,27 @@ class Events {
16526
16522
  $("#" + me.pre + "collectionfile").val(),
16527
16523
  false
16528
16524
  );
16525
+
16529
16526
  };
16530
16527
  reader.readAsText(file);
16528
+
16529
+ if (Object.keys(me.utilsCls.getStructures(ic.dAtoms))){
16530
+ $("#" + me.pre + "dl_collection_file").hide();
16531
+ $("#" + me.pre + "dl_collection_structures").show();
16532
+ $("#" + me.pre + "dl_collection_file_expand").show();
16533
+ $("#" + me.pre + "dl_collection_file_shrink").hide();
16534
+ $("#" + me.pre + "dl_collection_structures_expand").hide();
16535
+ $("#" + me.pre + "dl_collection_structures_shrink").show();
16536
+
16537
+ } else {
16538
+ $("#" + me.pre + "dl_collection_file").show();
16539
+ $("#" + me.pre + "dl_collection_structures").hide();
16540
+ $("#" + me.pre + "dl_collection_file_expand").hide();
16541
+ $("#" + me.pre + "dl_collection_file_shrink").hide();
16542
+ $("#" + me.pre + "dl_collection_structures_expand").show();
16543
+ $("#" + me.pre + "dl_collection_structures_shrink").hide();
16544
+ }
16545
+
16531
16546
  me.htmlCls.dialogCls.openDlg("dl_selectCollections", "Select Collections");
16532
16547
  }
16533
16548
  });
@@ -40865,8 +40880,10 @@ class AnnoIg {
40865
40880
  }
40866
40881
 
40867
40882
  showRefNum(giSeq, chnid, kabat_or_imgt, bCustom) { let ic = this.icn3d; ic.icn3dui;
40868
- let bResult = ic.chainid2igtrack[chnid];
40869
- if(!bResult) return {html: '', html2: '', html3: ''};
40883
+ if(ic.chainid2igtrack) {
40884
+ let bResult = ic.chainid2igtrack[chnid];
40885
+ if(!bResult) return {html: '', html2: '', html3: ''};
40886
+ }
40870
40887
 
40871
40888
  let html = this.getIgAnnoHtml(chnid, giSeq, bCustom, kabat_or_imgt);
40872
40889
 
@@ -40933,12 +40950,13 @@ class AnnoIg {
40933
40950
  ic.chain2igArray[chnid] = [];
40934
40951
  this.setChain2igArray(chnid, giSeq, bCustom);
40935
40952
 
40936
-
40937
40953
  // remove Igs without BCEF strands one more time
40938
40954
  let igArray = ic.chain2igArray[chnid];
40939
40955
 
40940
40956
  for(let i = 0, il = igArray.length; i < il; ++i) {
40941
40957
  let domainid = igArray[i].domainid;
40958
+
40959
+ if(!ic.domainid2info) continue;
40942
40960
  let info = ic.domainid2info[domainid];
40943
40961
  if(!info) continue;
40944
40962
 
@@ -41006,7 +41024,6 @@ class AnnoIg {
41006
41024
  }
41007
41025
  }
41008
41026
 
41009
-
41010
41027
  // reset ic.chain2igArray
41011
41028
  ic.chain2igArray[chnid] = [];
41012
41029
  this.setChain2igArray(chnid, giSeq, bCustom);
@@ -41025,7 +41042,7 @@ class AnnoIg {
41025
41042
  // htmlIg += '<span></span>';
41026
41043
  //}
41027
41044
  //else {
41028
- refnumLabel = ic.resid2refnum[residueid];
41045
+ refnumLabel = (bCustom) ? ic.chainsMapping[chnid][residueid] : ic.resid2refnum[residueid];
41029
41046
  let bHidelabel = false;
41030
41047
 
41031
41048
  if(refnumLabel) {
@@ -41150,9 +41167,14 @@ class AnnoIg {
41150
41167
  html3 += htmlTmp + '<br>';
41151
41168
  html += htmlTmp + '<span class="icn3d-seqLine">';
41152
41169
 
41170
+ if(ic.seqStartLen && ic.seqStartLen[chnid]) html += ic.showSeqCls.insertMulGap(ic.seqStartLen[chnid], '-');
41171
+
41153
41172
  html += htmlIg;
41154
41173
 
41155
- html += htmlCnt;
41174
+ if(ic.seqStartLen && ic.seqStartLen[chnid]) html += ic.showSeqCls.insertMulGap(ic.seqEndLen[chnid], '-');
41175
+
41176
+ if(!bCustom) html += htmlCnt;
41177
+
41156
41178
  html += '</span>';
41157
41179
  html += '<br>';
41158
41180
  html += '</div>';
@@ -41166,6 +41188,8 @@ class AnnoIg {
41166
41188
 
41167
41189
  for(let i = 0, il = igArray.length; i < il; ++i) {
41168
41190
  let domainid = igArray[i].domainid;
41191
+ if(!ic.domainid2info) continue;
41192
+
41169
41193
  let info = ic.domainid2info[domainid];
41170
41194
  if(!info) continue;
41171
41195
 
@@ -41194,6 +41218,8 @@ class AnnoIg {
41194
41218
  html2 += htmlTitle;
41195
41219
  html2 += htmlCnt + '<span class="icn3d-seqLine">';
41196
41220
 
41221
+ if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
41222
+
41197
41223
  let prevDomainindex, color;
41198
41224
  for(let i = 0, il = fromArray.length; i < il; ++i) {
41199
41225
  let resi = ic.ParserUtilsCls.getResi(chnid, fromArray[i]);
@@ -41625,7 +41651,7 @@ class AnnoDomain {
41625
41651
 
41626
41652
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
41627
41653
 
41628
- if(me.cfg.blast_rep_id != chnid) { // regular
41654
+ if(me.cfg.blast_rep_id != chnid) { // regular
41629
41655
  for(let i = 0, il = posFromArray.length; i < il; ++i) {
41630
41656
  // 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);
41631
41657
  let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
@@ -41634,7 +41660,7 @@ class AnnoDomain {
41634
41660
  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>';
41635
41661
  }
41636
41662
  }
41637
- else { // with potential gaps
41663
+ else { // with potential gaps
41638
41664
  let fromArray2 = [], toArray2 = [];
41639
41665
  for(let i = 0, il = fromArray.length; i < il; ++i) {
41640
41666
  fromArray2.push(fromArray[i]);
@@ -44425,7 +44451,7 @@ class AddTrack {
44425
44451
 
44426
44452
  getExonHtml(exonIndex, colorGradient, from, to, genomeRange, chainid, simpTitle) { let ic = this.icn3d; ic.icn3dui;
44427
44453
  // 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>';
44428
- 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>';
44454
+ 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>';
44429
44455
  }
44430
44456
 
44431
44457
  getExonColor(start, end, pos) { let ic = this.icn3d; ic.icn3dui;
@@ -47557,6 +47583,7 @@ class ShowSeq {
47557
47583
  let bCustom = true;
47558
47584
  let result = ic.annoIgCls.showRefNum(giSeq, chnid, undefined, bCustom);
47559
47585
  html += result.html;
47586
+ // html2 += result.html2;
47560
47587
  html3 += result.html3;
47561
47588
  }
47562
47589
  }
@@ -60993,13 +61020,15 @@ class SetSeqAlign {
60993
61020
  ic.alnChains = {};
60994
61021
  ic.alnChains[chainid1] = {};
60995
61022
 
60996
- let resi2range_t = {}; // accumulative aligned residues in the template chain
61023
+ let resid2range_t = {}; // accumulative aligned residues in the template chain
60997
61024
  // start and end of MSA
60998
61025
  let start_t = 9999, end_t = -1;
60999
61026
 
61000
61027
  let baseResi = ic.chainsSeq[chainid1][0].resi - 1;
61028
+
61001
61029
  for(let index = 1, indexl = chainidArray.length; index < indexl; ++index) {
61002
61030
  let chainIndex = index - 1;
61031
+ chainidArray[index];
61003
61032
  if(!ic.qt_start_end[chainIndex]) continue;
61004
61033
 
61005
61034
  for(let i = 0, il = ic.qt_start_end[chainIndex].length; i < il; ++i) {
@@ -61010,11 +61039,12 @@ class SetSeqAlign {
61010
61039
  // end1 = ic.qt_start_end[chainIndex][i].t_end;
61011
61040
  // }
61012
61041
  // else {
61042
+ //ic.qt_start_end is zero-based
61013
61043
  start1 = parseInt(ic.qt_start_end[chainIndex][i].t_start) - 1;
61014
61044
  end1 = parseInt(ic.qt_start_end[chainIndex][i].t_end) - 1;
61015
61045
  // }
61016
61046
  for(let j = start1; j <= end1; ++j) {
61017
- let resi;
61047
+ let resi, resid;
61018
61048
 
61019
61049
  // if(me.cfg.aligntool == 'tmalign') { // tmalign: just one residue in this for loop
61020
61050
  // resi = ic.qt_start_end[chainIndex][i].t_start;
@@ -61026,53 +61056,56 @@ class SetSeqAlign {
61026
61056
  resiPos = j - baseResi;
61027
61057
  }
61028
61058
  else {
61029
- resiPos = (bRealign) ? j : j - baseResi;
61059
+ // resiPos = (bRealign) ? j : j - baseResi;
61060
+ resiPos = j;
61030
61061
  }
61031
61062
  resi = ic.ParserUtilsCls.getResi(chainidArray[0], resiPos);
61063
+ resid = chainidArray[0] + '_' + resi;
61032
61064
  // }
61033
61065
 
61034
- resi2range_t[resi] = 1;
61066
+ resid2range_t[resid] = 1;
61035
61067
  if(j < start_t) start_t = j;
61036
61068
  if(j > end_t) end_t = j;
61037
61069
  }
61038
61070
  }
61039
61071
  }
61040
-
61072
+
61041
61073
  // TM-align should use "start1 = ic.qt_start_end[chainIndex][i].t_start - 1", but the rest are the same as ""bRealign"
61042
61074
  if(me.cfg.aligntool == 'tmalign') bRealign = true; // real residue numbers are stored
61043
61075
 
61044
- let resi2rangeArray = Object.keys(resi2range_t);
61045
- resi2rangeArray.sort(function(a, b) {
61046
- return parseInt(a) - parseInt(b);
61076
+ let resid2rangeArray = Object.keys(resid2range_t);
61077
+ resid2rangeArray.sort(function(a, b) {
61078
+ return parseInt(a.split('_')[2]) - parseInt(b.split('_')[2]);
61047
61079
  });
61048
61080
 
61049
61081
  // assign range to each resi
61050
- let prevResi = -999, start = 0, end = 0, resiArray = [], prevEnd = 0;
61051
- for(let i = 0, il = resi2rangeArray.length; i < il; ++i) {
61052
- let resi = resi2rangeArray[i];
61082
+ let prevResi = -999, start = 0, end = 0, residArray = [], prevEnd = 0;
61083
+ for(let i = 0, il = resid2rangeArray.length; i < il; ++i) {
61084
+ let resid = resid2rangeArray[i];
61085
+ let resi = resid.split('_')[2];
61053
61086
 
61054
61087
  if(i == 0) {
61055
61088
  start = resi;
61056
61089
  }
61057
61090
  else if(i > 0 && ic.resid2ncbi[resi] != ic.resid2ncbi[prevResi] + 1 && ic.resid2ncbi[resi] != ic.resid2ncbi[prevResi]) { // new start
61058
61091
  end = prevResi;
61059
- for(let j = 0, jl = resiArray.length; j < jl; ++j) {
61060
- resi2range_t[resiArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61092
+ for(let j = 0, jl = residArray.length; j < jl; ++j) {
61093
+ resid2range_t[residArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61061
61094
  }
61062
61095
 
61063
- resiArray = [];
61096
+ residArray = [];
61064
61097
  start = resi;
61065
61098
  prevEnd = end;
61066
61099
  }
61067
61100
 
61068
- resiArray.push(resi);
61101
+ residArray.push(resid);
61069
61102
 
61070
61103
  prevResi = resi;
61071
61104
  }
61072
61105
 
61073
61106
  end = prevResi;
61074
- for(let j = 0, jl = resiArray.length; j < jl; ++j) {
61075
- resi2range_t[resiArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61107
+ for(let j = 0, jl = residArray.length; j < jl; ++j) {
61108
+ resid2range_t[residArray[j]] = {resiStart: start, resiEnd: end, prevResiEnd: prevEnd};
61076
61109
  }
61077
61110
 
61078
61111
  for(let i = 0, il = chainidArray.length; i < il; ++i) {
@@ -61086,6 +61119,7 @@ class SetSeqAlign {
61086
61119
  // fill the template ic.alnChainsSeq[chainid1]
61087
61120
  for(let j = 0, jl = ic.chainsSeq[chainid1].length; j < jl; ++j) {
61088
61121
  let resi = ic.chainsSeq[chainid1][j].resi;
61122
+ let resid = chainid1 + '_' + resi;
61089
61123
 
61090
61124
  let jAdjusted = (me.cfg.aligntool != 'tmalign') ? j : j + baseResi;
61091
61125
 
@@ -61099,15 +61133,15 @@ class SetSeqAlign {
61099
61133
  resObject.mmdbid = chainid1.substr(0, pos);
61100
61134
  resObject.chain = chainid1.substr(pos+1);
61101
61135
  resObject.resi = resi;
61102
- resObject.resn = (resi2range_t[resi]) ? ic.chainsSeq[chainid1][j].name.toUpperCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
61103
- resObject.aligned = (resi2range_t[resi]) ? true : false;
61104
- resObject.color = (resi2range_t[resi]) ? '#FF0000' : me.htmlCls.GREYC; // color by identity
61105
- resObject.color2 = (resi2range_t[resi]) ? '#FF0000' : me.htmlCls.GREYC; // color by conservation
61106
- resObject.class = (resi2range_t[resi]) ? 'icn3d-align' : 'icn3d-nalign';
61136
+ resObject.resn = (resid2range_t[resid]) ? ic.chainsSeq[chainid1][j].name.toUpperCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
61137
+ resObject.aligned = (resid2range_t[resid]) ? true : false;
61138
+ resObject.color = (resid2range_t[resid]) ? '#FF0000' : me.htmlCls.GREYC; // color by identity
61139
+ resObject.color2 = (resid2range_t[resid]) ? '#FF0000' : me.htmlCls.GREYC; // color by conservation
61140
+ resObject.class = (resid2range_t[resid]) ? 'icn3d-align' : 'icn3d-nalign';
61107
61141
 
61108
61142
  ic.alnChainsSeq[chainid1].push(resObject);
61109
61143
 
61110
- if(resi2range_t[resi]) {
61144
+ if(resid2range_t[resid]) {
61111
61145
  $.extend(ic.alnChains[chainid1], ic.residues[chainid1 + '_' + resObject.resi] );
61112
61146
  hAtoms = me.hashUtilsCls.unionHash(hAtoms, ic.residues[chainid1 + '_' + resObject.resi]);
61113
61147
  }
@@ -61119,7 +61153,7 @@ class SetSeqAlign {
61119
61153
  for(let arrayIndex = 0, arrayIndexl = index_alignLen.length; arrayIndex < arrayIndexl; ++arrayIndex) {
61120
61154
  let index = index_alignLen[arrayIndex].index;
61121
61155
  alignedChainIndice.push(index);
61122
- let hAtomsTmp = this.mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resi2range_t, start_t, end_t, bRealign);
61156
+ let hAtomsTmp = this.mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resid2range_t, start_t, end_t, bRealign);
61123
61157
 
61124
61158
  hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
61125
61159
  }
@@ -61292,7 +61326,7 @@ class SetSeqAlign {
61292
61326
  return {"pos1": result1.pos, "pos2": result2.pos};
61293
61327
  }
61294
61328
 
61295
- mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resi2range_t, start_t, end_t, bRealign) { let ic = this.icn3d, me = ic.icn3dui;
61329
+ mergeTwoSeqForAll(chainidArray, index, alignedChainIndice, resid2range_t, start_t, end_t, bRealign) { let ic = this.icn3d, me = ic.icn3dui;
61296
61330
  let hAtoms = {};
61297
61331
 
61298
61332
  let chainid = chainidArray[index];
@@ -61381,7 +61415,7 @@ class SetSeqAlign {
61381
61415
  start1Pos = start1;
61382
61416
  end1Pos = end1;
61383
61417
  }
61384
- //let range = resi2range_t[resiStart1];
61418
+ //let range = resid2range_t[chainid1 + '_' + resiStart1];
61385
61419
 
61386
61420
  // if the mapping does not start from start_t, add gaps to the query seq
61387
61421
  if(i == 0) {
@@ -66849,70 +66883,181 @@ class SelectCollections {
66849
66883
  return html;
66850
66884
  }
66851
66885
 
66886
+ reset() {
66887
+ let ic = this.icn3d;
66888
+
66889
+ ic.atoms = {};
66890
+
66891
+ ic.proteins = {};
66892
+ ic.nucleotides = {};
66893
+ ic.chemicals = {};
66894
+ ic.ions = {};
66895
+ ic.water = {};
66896
+
66897
+ ic.structures = {};
66898
+ ic.chains = {};
66899
+ ic.chainsSeq = {};
66900
+ ic.residues = {};
66901
+
66902
+ ic.defNames2Atoms = {};
66903
+ ic.defNames2Residues = {};
66904
+
66905
+ ic.ssbondpnts = {};
66906
+
66907
+ ic.bShowHighlight = false;
66908
+ ic.bResetSets = true;
66909
+ }
66910
+
66911
+ dictionaryDifference(dict1, dict2) {
66912
+ const difference = {};
66913
+
66914
+ for (let key in dict2) {
66915
+ if (!(key in dict1)) {
66916
+ difference[key] = dict2[key];
66917
+ }
66918
+ }
66919
+
66920
+ return difference;
66921
+ }
66922
+
66852
66923
  clickStructure() {
66853
66924
  let ic = this.icn3d,
66854
66925
  me = ic.icn3dui;
66855
66926
  let thisClass = this;
66856
66927
 
66928
+ if (ic.allData == undefined) {
66929
+ ic.allData = {};
66930
+ ic.allData['all'] = {
66931
+ 'atoms': {},
66932
+ 'proteins': {},
66933
+ 'nucleotides': {},
66934
+ 'chemicals': {},
66935
+ 'ions': {},
66936
+ 'water': {},
66937
+ 'structures': {}, // getSSExpandedAtoms
66938
+ 'ssbondpnts': {},
66939
+ 'residues': {}, // getSSExpandedAtoms
66940
+ 'chains': {},
66941
+ 'chainsSeq': {}, //Sequences and Annotation
66942
+ 'defNames2Atoms': {},
66943
+ 'defNames2Residues': {}
66944
+ };
66945
+ ic.allData['prev'] = {};
66946
+ }
66947
+
66857
66948
  //me.myEventCls.onIds("#" + ic.pre + "atomsCustom", "change", function(e) { let ic = thisClass.icn3d;
66858
66949
  $("#" + ic.pre + "collections_menu").change(async function (e) {
66859
66950
  let ic = thisClass.icn3d;
66860
- // ic.init()
66951
+
66861
66952
  let nameArray = $(this).val();
66862
66953
  let nameStructure = $(this).find("option:selected").text();
66863
66954
 
66864
66955
  ic.nameArray = nameArray;
66865
66956
  if (nameArray !== null) {
66866
- ic.bShowHighlight = false;
66957
+ // let chainIdHash = {};
66958
+
66867
66959
  let bNoDuplicate = true;
66868
- await ic.chainalignParserCls.downloadMmdbAf(nameArray.toString(), undefined, undefined, bNoDuplicate);
66960
+ thisClass.reset();
66961
+ for (const name of nameArray) {
66962
+ if (!(name in ic.allData)) {
66963
+ ic.allData['prev'] = JSON.parse(JSON.stringify(ic.allData['all']));//me.hashUtilsCls.cloneHash(ic.allData['all']);
66869
66964
 
66870
- ic.dAtoms = {};
66871
- ic.hAtoms = {};
66872
- // ic.ssbondpnts = {};
66873
- let chainIdHash = {};
66874
-
66875
- for (const name in nameArray) {
66876
- for (const key in ic.chains) {
66877
- if (key.includes(nameArray[name])) {
66878
- chainIdHash[key] = 1;
66879
- if (ic.chains.hasOwnProperty(key)) {
66880
- const innerDict = ic.chains[key];
66881
- for (const innerKey in innerDict) {
66882
- if (innerDict.hasOwnProperty(innerKey)) {
66883
- ic.dAtoms[innerKey] = innerDict[innerKey];
66884
- ic.hAtoms[innerKey] = innerDict[innerKey];
66885
- }
66886
- }
66887
- }
66888
- }
66965
+ ic.atoms = ic.allData['all']['atoms'];
66966
+
66967
+ ic.proteins = ic.allData['all']['proteins'];
66968
+ ic.nucleotides = ic.allData['all']['nucleotides'];
66969
+ ic.chemicals = ic.allData['all']['chemicals'];
66970
+ ic.ions = ic.allData['all']['ions'];
66971
+ ic.water = ic.allData['all']['water'];
66972
+
66973
+ ic.structures = ic.allData['all']['structures'];
66974
+ ic.ssbondpnts = ic.allData['all']['ssbondpnts'];
66975
+ ic.residues = ic.allData['all']['residues'];
66976
+ ic.chains = ic.allData['all']['chains'];
66977
+ ic.chainsSeq = ic.allData['all']['chainsSeq'];
66978
+ ic.defalls2Atoms = ic.allData['all']['defalls2Atoms'];
66979
+ ic.defalls2Residues = ic.allData['all']['defalls2Residues'];
66980
+ await ic.chainalignParserCls.downloadMmdbAf(name, undefined, undefined, bNoDuplicate).then(() => {
66981
+ ic.allData['all'] = {
66982
+ 'atoms': ic.atoms,
66983
+ 'proteins': ic.proteins,
66984
+ 'nucleotides': ic.nucleotides,
66985
+ 'chemicals': ic.chemicals,
66986
+ 'ions': ic.ions,
66987
+ 'water': ic.water,
66988
+ 'structures': ic.structures, // getSSExpandedAtoms
66989
+ 'ssbondpnts': ic.ssbondpnts,
66990
+ 'residues': ic.residues, // getSSExpandedAtoms
66991
+ 'chains': ic.chains,
66992
+ 'chainsSeq': ic.chainsSeq, //Sequences and Annotation
66993
+ 'defNames2Atoms': ic.defNames2Atoms,
66994
+ 'defNames2Residues': ic.defNames2Residues
66995
+ };
66996
+
66997
+ ic.allData[name] = {
66998
+ 'atoms': thisClass.dictionaryDifference(ic.allData['prev']['atoms'], ic.atoms),
66999
+ 'proteins': thisClass.dictionaryDifference(ic.allData['prev']['proteins'], ic.proteins),
67000
+ 'nucleotides': thisClass.dictionaryDifference(ic.allData['prev']['nucleotides'], ic.nucleotides),
67001
+ 'chemicals': thisClass.dictionaryDifference(ic.allData['prev']['chemicals'], ic.chemicals),
67002
+ 'ions': thisClass.dictionaryDifference(ic.allData['prev']['ions'], ic.ions),
67003
+ 'water': thisClass.dictionaryDifference(ic.allData['prev']['water'], ic.water),
67004
+ 'structures': thisClass.dictionaryDifference(ic.allData['prev']['structures'], ic.structures), // getSSExpandedAtoms
67005
+ 'ssbondpnts': thisClass.dictionaryDifference(ic.allData['prev']['ssbondpnts'], ic.ssbondpnts),
67006
+ 'residues': thisClass.dictionaryDifference(ic.allData['prev']['residues'], ic.residues), // getSSExpandedAtoms
67007
+ 'chains': thisClass.dictionaryDifference(ic.allData['prev']['chains'], ic.chains),
67008
+ 'chainsSeq': thisClass.dictionaryDifference(ic.allData['prev']['chainsSeq'], ic.chainsSeq), //Sequences and Annotation
67009
+ 'defNames2Atoms': thisClass.dictionaryDifference(ic.allData['prev']['defNames2Atoms'], ic.defNames2Atoms),
67010
+ 'defNames2Residues': thisClass.dictionaryDifference(ic.allData['prev']['defNames2Residues'], ic.defNames2Residues)
67011
+ };
67012
+
67013
+ // ic.atoms = Object.assign(ic.atoms, ic.atomsTemp);
67014
+ thisClass.reset();
67015
+ });
66889
67016
  }
66890
67017
  }
67018
+ for (const name of nameArray) {
67019
+ ic.atoms = Object.assign(ic.atoms, ic.allData[name]['atoms']);
67020
+
67021
+ ic.proteins = Object.assign(ic.proteins, ic.allData[name]['proteins']);
67022
+ ic.nucleotides = Object.assign(ic.nucleotides, ic.allData[name]['nucleotides']);
67023
+ ic.chemicals = Object.assign(ic.chemicals, ic.allData[name]['chemicals']);
67024
+ ic.ions = Object.assign(ic.ions, ic.allData[name]['ions']);
67025
+ ic.water = Object.assign(ic.water, ic.allData[name]['water']);
67026
+
67027
+ ic.structures = Object.assign(ic.structures, ic.allData[name]['structures']);
67028
+ ic.ssbondpnts = Object.assign(ic.ssbondpnts, ic.allData[name]['ssbondpnts']);
67029
+ ic.residues = Object.assign(ic.residues, ic.allData[name]['residues']);
67030
+ ic.chains = Object.assign(ic.chains, ic.allData[name]['chains']);
67031
+ ic.chainsSeq = Object.assign(ic.chainsSeq, ic.allData[name]['chainsSeq']);
67032
+ ic.defNames2Atoms = Object.assign(ic.defNames2Atoms, ic.allData[name]['defNames2Atoms']);
67033
+ ic.defNames2Residues = Object.assign(ic.defNames2Residues, ic.allData[name]['defNames2Residues']);
67034
+ ic.dAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
67035
+ ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
67036
+ }
67037
+
67038
+ ic.opts["color"] = "structure";
67039
+ ic.setStyleCls.setAtomStyleByOptions();
67040
+ ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
66891
67041
 
66892
67042
  ic.transformCls.zoominSelection();
66893
67043
  ic.definedSetsCls.showSets();
66894
67044
 
66895
- await ic.drawCls.draw();
66896
- ic.saveFileCls.showTitle();
66897
-
66898
67045
  ic.bResetAnno = true;
66899
67046
  if(ic.bAnnoShown) {
66900
- // show annotations just fo the displayed atoms
66901
- // await ic.showAnnoCls.showAnnotations(ic.dAtoms);
66902
67047
  await ic.showAnnoCls.showAnnotations();
66903
67048
 
66904
67049
  ic.hlUpdateCls.updateHlAll(nameArray);
66905
67050
  // show selected chains in annotation window
66906
67051
  ic.annotationCls.showAnnoSelectedChains();
66907
67052
  }
66908
-
67053
+
67054
+ await ic.drawCls.draw();
67055
+ ic.saveFileCls.showTitle();
67056
+
66909
67057
  me.htmlCls.clickMenuCls.setLogCmd(
66910
67058
  "select structure " + "[" + nameStructure + "]",
66911
67059
  true
66912
67060
  );
66913
- ic.bSelectResidue = false;
66914
-
66915
- ic.bShowHighlight = true; // reset
66916
67061
  }
66917
67062
  });
66918
67063
 
@@ -67467,7 +67612,10 @@ class LoadScript {
67467
67612
  let idArray = id.split(',');
67468
67613
  let idNew = '';
67469
67614
  for(let i = 0, il = idArray.length; i < il; ++i) {
67470
- if(!(ic.structures && ic.structures.hasOwnProperty(idArray[i]))) {
67615
+ if(!(ic.structures && (ic.structures.hasOwnProperty(idArray[i])
67616
+ || ic.structures.hasOwnProperty(idArray[i].toLowerCase())
67617
+ || ic.structures.hasOwnProperty(idArray[i].toUpperCase())
67618
+ ) )) {
67471
67619
  if(idNew) idNew += ',';
67472
67620
  idNew += idArray[i];
67473
67621
  }
@@ -70491,7 +70639,7 @@ class Dssp {
70491
70639
  ic.ref2igtype['LaminAC_1ifrA_human'] = 'Lamin';
70492
70640
  ic.ref2igtype['MHCIa_7phrH_human_C1'] = 'IgC1';
70493
70641
  ic.ref2igtype['MPT63_1lmiA_bacteria'] = 'IgE';
70494
- ic.ref2igtype['NaCaExchanger_2fwuA_dog_n2'] = 'IgE';
70642
+ ic.ref2igtype['NaCaExchanger_2fwuA_dog_n2'] = 'IgFN3-like';
70495
70643
  ic.ref2igtype['NaKATPaseTransporterBeta_2zxeB_spurdogshark'] = 'IgE';
70496
70644
  ic.ref2igtype['ORF7a_1xakA_virus'] = 'ORF';
70497
70645
  ic.ref2igtype['PD1_4zqkB_human_V'] = 'IgV';
@@ -71218,14 +71366,16 @@ class Dssp {
71218
71366
  let resiDistToC = (bCpstrand) ? parseInt(CpAtom.resi) - parseInt(CAtom.resi) : parseInt(DAtom.resi) - parseInt(CAtom.resi);
71219
71367
  let resiDistToE = (bCpstrand) ? parseInt(EAtom.resi) - parseInt(CpAtom.resi) : parseInt(EAtom.resi) - parseInt(DAtom.resi);
71220
71368
 
71369
+ let adjust = 1;
71370
+
71221
71371
  if(bCpstrand) {
71222
- if(distToC > distToE || (distToC == distToE && resiDistToC > resiDistToE)) { // rename C' to D
71372
+ if(distToC > distToE + adjust || (distToC == distToE + adjust && resiDistToC > resiDistToE + adjust)) { // rename C' to D
71223
71373
  CpToDResi.push(CpAtom.resi);
71224
71374
  if(!me.bNode) console.log("Rename strand C' to D: distToC " + distToC + " distToE " + distToE + " resiDistToC " + resiDistToC + " resiDistToE " + resiDistToE);
71225
71375
  }
71226
71376
  }
71227
71377
  else if(bDstrand) {
71228
- if(distToC < distToE || (distToC == distToE && resiDistToC < resiDistToE)) { // rename D to C'
71378
+ if(distToC + adjust < distToE || (distToC + adjust == distToE && resiDistToC + adjust < resiDistToE)) { // rename D to C'
71229
71379
  DToCpResi.push(DAtom.resi);
71230
71380
  if(!me.bNode) console.log("Rename strand D to C': distToC " + distToC + " distToE " + distToE + " resiDistToC " + resiDistToC + " resiDistToE " + resiDistToE);
71231
71381
  }
@@ -71245,7 +71395,8 @@ class Dssp {
71245
71395
 
71246
71396
  seg.q_start;
71247
71397
  let qStartInt = parseInt(seg.q_start);
71248
- if(isNaN(seg.q_start)) seg.q_start.substr(seg.q_start.length - 1, 1);
71398
+ let postfix = '';
71399
+ if(isNaN(seg.q_start)) postfix = seg.q_start.substr(seg.q_start.length - 1, 1);
71249
71400
 
71250
71401
  // one item in "seq"
71251
71402
  // q_start and q_end are numbers, but saved in string
@@ -71260,7 +71411,7 @@ class Dssp {
71260
71411
  //let refnum = qStart;
71261
71412
  let refnum = qStartInt;
71262
71413
 
71263
- let refnumLabel = this.getLabelFromRefnum(refnum);
71414
+ let refnumLabel = this.getLabelFromRefnum(refnum, postfix);
71264
71415
  currStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
71265
71416
 
71266
71417
  let currStrandFinal = currStrand;
@@ -71282,7 +71433,7 @@ class Dssp {
71282
71433
  }
71283
71434
 
71284
71435
  if(currStrand != currStrandFinal) {
71285
- refnumLabel = this.getLabelFromRefnum(refnum, currStrandFinal);
71436
+ refnumLabel = this.getLabelFromRefnum(refnum, postfix, currStrandFinal);
71286
71437
  }
71287
71438
 
71288
71439
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
@@ -71318,7 +71469,7 @@ class Dssp {
71318
71469
  }
71319
71470
  }
71320
71471
 
71321
- getStrandFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
71472
+ getStrandFromRefnum(oriRefnum, finalStrand) { let ic = this.icn3d; ic.icn3dui;
71322
71473
  let refnum = parseInt(oriRefnum);
71323
71474
 
71324
71475
  //N-terminus = 0999-0001
@@ -71397,16 +71548,25 @@ class Dssp {
71397
71548
  else if(refnum > 9900) strand = undefined;
71398
71549
  else strand = " ";
71399
71550
 
71400
- if(prevStrand) strand = prevStrand;
71551
+ if(finalStrand) strand = finalStrand;
71401
71552
 
71402
71553
  return strand
71403
71554
  }
71404
71555
 
71405
- getLabelFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
71406
- let strand = this.getStrandFromRefnum(oriRefnum, prevStrand);
71556
+ getLabelFromRefnum(oriRefnum, postfix, finalStrand) { let ic = this.icn3d; ic.icn3dui;
71557
+ let strand = this.getStrandFromRefnum(oriRefnum, finalStrand);
71558
+
71559
+ // rename C' to D or D to C'
71560
+ let refnum = oriRefnum.toString();
71561
+ if(finalStrand == "C'" && refnum.substr(0, 1) == '6') { // previous D
71562
+ refnum = '4' + refnum.substr(1);
71563
+ }
71564
+ else if(finalStrand == "D" && refnum.substr(0, 1) == '4') { // previous C'
71565
+ refnum = '6' + refnum.substr(1);
71566
+ }
71407
71567
 
71408
71568
  if(strand) {
71409
- return strand + oriRefnum;
71569
+ return strand + refnum + postfix;
71410
71570
  }
71411
71571
  else {
71412
71572
  return undefined;
@@ -71480,7 +71640,12 @@ class Dssp {
71480
71640
  }
71481
71641
 
71482
71642
  rmStrandFromRefnumlabel(refnumLabel) { let ic = this.icn3d; ic.icn3dui;
71483
- return (!refnumLabel) ? refnumLabel : refnumLabel.replace(/'/g, '').replace(/\*/g, '').replace(/\^/g, '').replace(/\+/g, '').replace(/\-/g, '').substr(1); // C', C''
71643
+ if(isNaN(refnumLabel.substr(0,1))) {
71644
+ return (!refnumLabel) ? refnumLabel : refnumLabel.replace(/'/g, '').replace(/\*/g, '').replace(/\^/g, '').replace(/\+/g, '').replace(/\-/g, '').substr(1); // C', C''
71645
+ }
71646
+ else { // custom ref numbers
71647
+ return refnumLabel;
71648
+ }
71484
71649
  }
71485
71650
 
71486
71651
  exportRefnum(type, bNoArraySymbol) { let ic = this.icn3d, me = ic.icn3dui;
@@ -80325,7 +80490,7 @@ class iCn3DUI {
80325
80490
  //even when multiple iCn3D viewers are shown together.
80326
80491
  this.pre = this.cfg.divid + "_";
80327
80492
 
80328
- this.REVISION = '3.31.2';
80493
+ this.REVISION = '3.31.3';
80329
80494
 
80330
80495
  // In nodejs, iCn3D defines "window = {navigator: {}}"
80331
80496
  this.bNode = (Object.keys(window).length < 2) ? true : false;