icn3d 3.31.9 → 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]);
@@ -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
  }
@@ -71492,7 +71640,12 @@ class Dssp {
71492
71640
  }
71493
71641
 
71494
71642
  rmStrandFromRefnumlabel(refnumLabel) { let ic = this.icn3d; ic.icn3dui;
71495
- 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
+ }
71496
71649
  }
71497
71650
 
71498
71651
  exportRefnum(type, bNoArraySymbol) { let ic = this.icn3d, me = ic.icn3dui;
@@ -80337,7 +80490,7 @@ class iCn3DUI {
80337
80490
  //even when multiple iCn3D viewers are shown together.
80338
80491
  this.pre = this.cfg.divid + "_";
80339
80492
 
80340
- this.REVISION = '3.31.2';
80493
+ this.REVISION = '3.31.3';
80341
80494
 
80342
80495
  // In nodejs, iCn3D defines "window = {navigator: {}}"
80343
80496
  this.bNode = (Object.keys(window).length < 2) ? true : false;