icn3d 3.21.2 → 3.22.0

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
@@ -5986,11 +5986,23 @@ class ClickMenu {
5986
5986
  thisClass.setLogCmd("export pqr", true);
5987
5987
  });
5988
5988
 
5989
- me.myEventCls.onIds(["#" + me.pre + "delphipdbh", "#" + me.pre + "phipqr", "#" + me.pre + "phiurlpqr"], "click", async function(e) { me.icn3d; //e.preventDefault();
5990
- let bPdb = true;
5991
- await me.htmlCls.setHtmlCls.exportPqr(bPdb);
5992
- thisClass.setLogCmd("export pdbh", false);
5993
- });
5989
+ // me.myEventCls.onIds("#" + me.pre + "delphipqbh", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
5990
+ // let bPdb = true;
5991
+ // await me.htmlCls.setHtmlCls.exportPqr(bPdb);
5992
+ // thisClass.setLogCmd("export pdbh", false);
5993
+ // });
5994
+
5995
+ me.myEventCls.onIds("#" + me.pre + "profixpdb", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
5996
+ let bHydrogen = false;
5997
+ await ic.scapCls.exportPdbProfix(bHydrogen);
5998
+ thisClass.setLogCmd("export pdb missing atoms", true);
5999
+ });
6000
+
6001
+ me.myEventCls.onIds("#" + me.pre + "profixpdbh", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
6002
+ let bHydrogen = true;
6003
+ await ic.scapCls.exportPdbProfix(bHydrogen);
6004
+ thisClass.setLogCmd("export pdb hydrogen", true);
6005
+ });
5994
6006
 
5995
6007
  me.myEventCls.onIds("#" + me.pre + "mn1_exportStl", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
5996
6008
  thisClass.setLogCmd("export stl file", false);
@@ -7778,7 +7790,7 @@ class ClickMenu {
7778
7790
  type: 'POST',
7779
7791
  data: {
7780
7792
  q : pdbstr,
7781
- database: ["afdb50", "afdb-swissprot", "gmgcl_id", "pdb100"],
7793
+ database: ["afdb50", "afdb-swissprot", "gmgcl_id", "pdb100", "afdb-proteome", "mgnify_esm30"],
7782
7794
  mode: "3diaa"
7783
7795
  },
7784
7796
  dataType: 'text',
@@ -8498,7 +8510,8 @@ class SetMenu {
8498
8510
  html += this.getLink('mn1_exportCounts', 'Residue Counts', undefined, 2);
8499
8511
 
8500
8512
  html += this.getLink('mn1_exportPdbRes', 'PDB', 1, 2);
8501
- html += this.getLink('delphipdbh', 'PDB with Hydrogens', undefined, 2);
8513
+ html += this.getLink('profixpdb', 'PDB with Missing Atoms', undefined, 2);
8514
+ html += this.getLink('profixpdbh', 'PDB with Hydrogens', undefined, 2);
8502
8515
 
8503
8516
  if(me.cfg.cid === undefined) {
8504
8517
  html += this.getLink('mn1_exportSecondary', 'Secondary Structure', undefined, 2);
@@ -9330,6 +9343,10 @@ class SetMenu {
9330
9343
  html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 2);
9331
9344
  html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', true, undefined, 2);
9332
9345
  }
9346
+ else {
9347
+ html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 2);
9348
+ html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', undefined, undefined, 2);
9349
+ }
9333
9350
 
9334
9351
  //if(me.cfg.afid) html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
9335
9352
  //if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) {
@@ -9404,6 +9421,15 @@ class SetMenu {
9404
9421
 
9405
9422
  html += this.getLink('mn6_hbondsYes', 'Interactions', 1, 1);
9406
9423
 
9424
+ html += this.getMenuText('mn1_window', 'Bring to Front', undefined, undefined, 1);
9425
+ html += "<ul>";
9426
+ html += this.getLink('mn1_window_table', 'Interaction Table', undefined, 2);
9427
+ html += this.getLink('mn1_window_linegraph', '2D Interaction Network', undefined, 2);
9428
+ html += this.getLink('mn1_window_scatterplot', '2D Interaction Map', undefined, 2);
9429
+ html += this.getLink('mn1_window_graph', '2D Graph(Force-Directed)', undefined, 2);
9430
+ html += "</ul>";
9431
+ html += "</li>";
9432
+
9407
9433
  html += this.getLink('mn6_contactmap', 'Contact Map', undefined, 1);
9408
9434
 
9409
9435
  if(!me.cfg.notebook) {
@@ -10514,10 +10540,11 @@ class SetDialog {
10514
10540
 
10515
10541
  html += me.htmlCls.divStr + "dl_customref' class='" + dialogClass + "'>";
10516
10542
  html += '<div style="width:550px;">You can define your own reference numbers in a custom file using Excel, and then export it as a CSV file. An example file is shown below with cells separated by commas.<br>';
10517
- html += '<pre>refnum,11,12,,21,22<br>';
10518
- html += '1TUP_A,100,101,,,132<br>';
10519
- html += '1TUP_B,110,111,,141,142</pre>';
10520
- html += 'The first row defines the reference residue numbers. The 1st cell could be anything. The rest cells are reference residue numbers (e.g., 11, 12, 21, 22) or empty cells. Each chain has a separate row. The first cell of the second row is the chain ID "1TUP_A". The rest cells are the corresponding real residue numbers for reference residue numbers in the first row. For example, the reference numbers for residues 100, 101, and 132 in the chain 1TUP_A are 11, 12, and 22, respectively. The thrid row shows the real residue numbers for the chain "1TUP_B".<br><br>';
10543
+ html += '<pre>refnum,11,12,,21,22,,10C,11C,20C<br>';
10544
+ html += '1TUP_A,100,101,,,132,,,,<br>';
10545
+ html += '1TUP_B,110,111,,141,142,,,,</pre>';
10546
+ html += '1TUP_C,,,,,,,200,201,230</pre>';
10547
+ html += 'The first row defines the reference residue numbers, which could be any strings. The 1st cell could be anything. The rest cells are reference residue numbers (e.g., 11, 21, 10C, etc.) or empty cells. Each chain has a separate row. The first cell of the second row is the chain ID "1TUP_A". The rest cells are the corresponding real residue numbers for reference residue numbers in the first row. For example, the reference numbers for residues 100, 101, and 132 in the chain 1TUP_A are 11, 12, and 22, respectively. The fourth row shows another set of reference numners for the chain "1TUP_C". It could be a chain from a different structure.<br><br>';
10521
10548
  html += 'To select all residues corresponding to the reference numbers, you can simplay replace ":" with "%" in the <a href="https://www.ncbi.nlm.nih.gov/Structure/icn3d/icn3d.html#selectb" target="_blank">Specification</a>. For example, "%12" selects the residue 101 in 1TUP_A and the residue 111 in 1TUP_B. ".A%12" has the chain "A" filter and selects the residue 101 in 1TUP_A.<br>';
10522
10549
  html += '</div><br>';
10523
10550
  html += "Custom File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "cstreffile' size=8> <br><br>";
@@ -10893,11 +10920,14 @@ class SetDialog {
10893
10920
 
10894
10921
  html += me.htmlCls.divStr + "dl_realignbystruct' class='" + dialogClass + "'>";
10895
10922
 
10896
- html += me.htmlCls.divNowrapStr + "1. Select sets in two chains below <br>or use your current selection:</div><br>";
10923
+ html += me.htmlCls.divNowrapStr + "<b>1</b>. Select sets in two chains below <br>or use your current selection:</div><br>";
10897
10924
  html += "<div style='text-indent:1.1em'><select id='" + me.pre + "atomsCustomRealignByStruct' multiple size='5' style='min-width:130px;'>";
10898
10925
  html += "</select></div><br>";
10899
10926
 
10900
- html += "<div>2. " + me.htmlCls.buttonStr + "applyRealignByStruct_tmalign'>Realign with TM-align</button>" + me.htmlCls.buttonStr + "applyRealignByStruct' style='margin-left:30px'>Realign with VAST</button></div><br>";
10927
+ html += "<div><b>2a</b>. <div style='display:inline-block; width:80px'>MSA:</div> " + me.htmlCls.buttonStr + "applyRealignByStructMsa_tmalign'>Realign with TM-align</button>" + me.htmlCls.buttonStr + "applyRealignByStructMsa' style='margin-left:30px'>Realign with VAST</button></div><br>";
10928
+
10929
+ html += "<div>or <b>2b</b>. <div style='display:inline-block; width:65px'>Pairwise:</div> " + me.htmlCls.buttonStr + "applyRealignByStruct_tmalign'>Realign with TM-align</button>" + me.htmlCls.buttonStr + "applyRealignByStruct' style='margin-left:30px'>Realign with VAST</button></div><br>";
10930
+
10901
10931
  html += "</div>";
10902
10932
 
10903
10933
  html += me.htmlCls.divStr + "dl_realigntwostru' class='" + dialogClass + "'>";
@@ -11570,6 +11600,32 @@ class Events {
11570
11600
  thisClass.setLogCmd('select ' + select + ' | name ' + commandname, true);
11571
11601
  }
11572
11602
 
11603
+ async setRealign(alignType, bMsa) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
11604
+ let nameArray = $("#" + me.pre + "atomsCustomRealignByStruct").val();
11605
+ if(nameArray.length > 0) {
11606
+ ic.hAtoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
11607
+ }
11608
+
11609
+ me.cfg.aligntool = alignType;
11610
+
11611
+ if(bMsa) {
11612
+ await ic.realignParserCls.realignOnStructAlignMsa(nameArray);
11613
+ }
11614
+ else {
11615
+ await ic.realignParserCls.realignOnStructAlign();
11616
+ }
11617
+
11618
+ let alignStr = (alignType == 'vast') ? 'structure align' : 'tmalign';
11619
+ alignStr += (bMsa) ? ' msa' : '';
11620
+
11621
+ if(nameArray.length > 0) {
11622
+ thisClass.setLogCmd("realign on " + alignStr + " | " + nameArray, true);
11623
+ }
11624
+ else {
11625
+ thisClass.setLogCmd("realign on " + alignStr, true);
11626
+ }
11627
+ }
11628
+
11573
11629
  readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
11574
11630
  let file = files[index];
11575
11631
  let commandName = (bAppend) ? 'append': 'load';
@@ -11880,42 +11936,32 @@ class Events {
11880
11936
  }
11881
11937
  });
11882
11938
 
11883
- me.myEventCls.onIds("#" + me.pre + "applyRealignByStruct", "click", async function(e) { let ic = me.icn3d;
11939
+ me.myEventCls.onIds("#" + me.pre + "applyRealignByStruct", "click", async function(e) { me.icn3d;
11884
11940
  e.preventDefault();
11885
11941
  if(!me.cfg.notebook) dialog.dialog( "close" );
11886
- let nameArray = $("#" + me.pre + "atomsCustomRealignByStruct").val();
11887
- if(nameArray.length > 0) {
11888
- ic.hAtoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
11889
- }
11890
-
11891
- me.cfg.aligntool = 'vast';
11892
-
11893
- await ic.realignParserCls.realignOnStructAlign();
11894
- if(nameArray.length > 0) {
11895
- thisClass.setLogCmd("realign on structure align | " + nameArray, true);
11896
- }
11897
- else {
11898
- thisClass.setLogCmd("realign on structure align", true);
11899
- }
11942
+
11943
+ await thisClass.setRealign('vast', false);
11900
11944
  });
11901
11945
 
11902
- me.myEventCls.onIds("#" + me.pre + "applyRealignByStruct_tmalign", "click", async function(e) { let ic = me.icn3d;
11946
+ me.myEventCls.onIds("#" + me.pre + "applyRealignByStruct_tmalign", "click", async function(e) { me.icn3d;
11903
11947
  e.preventDefault();
11904
11948
  if(!me.cfg.notebook) dialog.dialog( "close" );
11905
- let nameArray = $("#" + me.pre + "atomsCustomRealignByStruct").val();
11906
- if(nameArray.length > 0) {
11907
- ic.hAtoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
11908
- }
11909
11949
 
11910
- me.cfg.aligntool = 'tmalign';
11911
-
11912
- await ic.realignParserCls.realignOnStructAlign();
11913
- if(nameArray.length > 0) {
11914
- thisClass.setLogCmd("realign on tmalign | " + nameArray, true);
11915
- }
11916
- else {
11917
- thisClass.setLogCmd("realign on tmalign", true);
11918
- }
11950
+ await thisClass.setRealign('tmalign', false);
11951
+ });
11952
+
11953
+ me.myEventCls.onIds("#" + me.pre + "applyRealignByStructMsa", "click", async function(e) { me.icn3d;
11954
+ e.preventDefault();
11955
+ if(!me.cfg.notebook) dialog.dialog( "close" );
11956
+
11957
+ await thisClass.setRealign('vast', true);
11958
+ });
11959
+
11960
+ me.myEventCls.onIds("#" + me.pre + "applyRealignByStructMsa_tmalign", "click", async function(e) { me.icn3d;
11961
+ e.preventDefault();
11962
+ if(!me.cfg.notebook) dialog.dialog( "close" );
11963
+
11964
+ await thisClass.setRealign('tmalign', true);
11919
11965
  });
11920
11966
 
11921
11967
  me.myEventCls.onIds("#" + me.pre + "applyRealignByStruct_vastplus", "click", async function(e) { let ic = me.icn3d;
@@ -15002,7 +15048,7 @@ class SetHtml {
15002
15048
  else if(pos != -1) {
15003
15049
  let url = imageStr.substr(pos + matchedStr.length);
15004
15050
  me.htmlCls.clickMenuCls.setLogCmd('load iCn3D PNG image ' + $("#" + me.pre + "pngimage").val(), false);
15005
- window.open(url);
15051
+ window.open(url, '_self');
15006
15052
  }
15007
15053
  else if(posState != -1) {
15008
15054
  let matchedStrData = "Start of data file======\n";
@@ -33055,7 +33101,7 @@ class SetColor {
33055
33101
  let b = atom.b;
33056
33102
 
33057
33103
  // PDB
33058
- b = (atom.structure.length < 6) ? 100 - b : b;
33104
+ b = (atom.structure.substr(0, 4) != ic.defaultPdbId && atom.structure.length < 6) ? 100 - b : b;
33059
33105
 
33060
33106
  if(b >= 90) {
33061
33107
  atom.color = me.parasCls.thr().setRGB(0, 0.325, 0.839);
@@ -33093,7 +33139,7 @@ class SetColor {
33093
33139
  if(b > 100) b = 100;
33094
33140
 
33095
33141
  // AlphaFold
33096
- b = (atom.structure.length > 5) ? 100 - b : b;
33142
+ b = (atom.structure.substr(0, 4) != ic.defaultPdbId && atom.structure.length > 5) ? 100 - b : b;
33097
33143
 
33098
33144
  let s1 = (ic.middB - b) * ic.spanBinv1;
33099
33145
  let s2 = (b - ic.middB) * ic.spanBinv2;
@@ -34000,7 +34046,7 @@ class AnnoCddSite {
34000
34046
 
34001
34047
  let linkStr = (bCoordinates) ? 'icn3d-link icn3d-blue' : '';
34002
34048
 
34003
- let htmlTmp2 = '<div class="icn3d-seqTitle ' + linkStr + '" site="site" posarray="' + adjustedResPosArray.toString() + '" shorttitle="' + title + '" setname="' + chnid + '_site_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
34049
+ let htmlTmp2 = '<div class="icn3d-seqTitle ' + linkStr + '" site="site" posarray="' + resPosArray.toString() + '" shorttitle="' + title + '" setname="' + chnid + '_site_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
34004
34050
  let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
34005
34051
  let htmlTmp = '<span class="icn3d-seqLine">';
34006
34052
  html3 += htmlTmp2 + htmlTmp3 + '<br>';
@@ -34172,8 +34218,9 @@ class AnnoCddSite {
34172
34218
  let from = parseInt(fromArray[i]), to = parseInt(toArray[i]);
34173
34219
 
34174
34220
  for(let j = from; j <= to; ++j) {
34175
-
34176
- let resid = chnid + "_" + j;
34221
+ let resi = ic.ParserUtilsCls.getResi(chnid, j);
34222
+ //let resid = chnid + "_" + j;
34223
+ let resid = chnid + "_" + resi;
34177
34224
 
34178
34225
  if(ic.residues.hasOwnProperty(resid)) {
34179
34226
  bCoordinates = true;
@@ -39925,7 +39972,7 @@ class ShowSeq {
39925
39972
 
39926
39973
  //if(ic.resid2refnum.hasOwnProperty(residueid)) {
39927
39974
  let refnumLabel = ic.resid2refnum[residueid];
39928
- if(refnumLabel) {
39975
+ if(refnumLabel) {
39929
39976
  let refnumStr_ori = refnumLabel.replace(/'/g, '').substr(1);
39930
39977
  let refnumStr;
39931
39978
  if(bCustom) {
@@ -41100,7 +41147,9 @@ class LineGraph {
41100
41147
  nodeArray2 = nodeArrays.nodeArray2;
41101
41148
  ic.lineGraphStr = '{\n';
41102
41149
 
41103
- let structureArray = ic.resid2specCls.atoms2structureArray(ic.hAtoms);
41150
+ //let structureArray = ic.resid2specCls.atoms2structureArray(ic.hAtoms);
41151
+ let structureArray = Object.keys(ic.structures);
41152
+
41104
41153
  //if(Object.keys(ic.structures).length > 1) {
41105
41154
  if(structureArray.length > 1) {
41106
41155
 
@@ -41868,6 +41917,7 @@ class GetGraph {
41868
41917
 
41869
41918
  updateGraphColor() { let ic = this.icn3d, me = ic.icn3dui;
41870
41919
  // change graph color
41920
+
41871
41921
  if(ic.graphStr !== undefined) {
41872
41922
  let graphJson = JSON.parse(ic.graphStr);
41873
41923
  let resid2color = {};
@@ -43991,7 +44041,7 @@ class ContactMap {
43991
44041
 
43992
44042
  let graphStr = '{\n';
43993
44043
 
43994
- let struc1 = (ic.structures.length > 0) ? ic.structures[0] : 'stru';
44044
+ let struc1 = (ic.structures.length > 0) ? ic.structures[0] : ic.defaultPdbId;
43995
44045
  let len1 = nodeArray1.length,
43996
44046
  len2 = nodeArray2.length;
43997
44047
  let factor = 1;
@@ -44531,7 +44581,8 @@ class ChainalignParser {
44531
44581
  }
44532
44582
  }
44533
44583
 
44534
- async downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray, indexArray, mmdbid_t, struArray) { let ic = this.icn3d, me = ic.icn3dui;
44584
+ async downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray,
44585
+ indexArray, mmdbid_t, struArray) { let ic = this.icn3d, me = ic.icn3dui;
44535
44586
  //let bTargetTransformed = (ic.qt_start_end[0]) ? true : false;
44536
44587
 
44537
44588
  // modify the previous trans and rotation matrix
@@ -44876,7 +44927,7 @@ class ChainalignParser {
44876
44927
  let chainid = chainidArray[i];
44877
44928
  let pos = chainid.indexOf('_');
44878
44929
  let struct = chainid.substr(0, pos);
44879
- if(struct != 'stru') struct = struct.toUpperCase();
44930
+ if(struct != ic.defaultPdbId) struct = struct.toUpperCase();
44880
44931
 
44881
44932
  if(!struct2cnt.hasOwnProperty(struct)) {
44882
44933
  struct2cnt[struct] = 1;
@@ -45062,11 +45113,16 @@ class ChainalignParser {
45062
45113
  if(ic.afChainIndexHash.hasOwnProperty(index)) {
45063
45114
  ++missedChainCnt;
45064
45115
 
45065
- // need to pass C-alpha coords and get transformation matrix from backend
45066
- ic.t_trans_add[index-1] = {"x":0, "y":0, "z":0};
45067
- ic.q_trans_sub[index-1] = {"x":0, "y":0, "z":0};
45116
+
45068
45117
 
45069
- if(me.cfg.aligntool == 'tmalign') ic.q_trans_add[index-1] = {"x":0, "y":0, "z":0};
45118
+ if(me.cfg.aligntool == 'tmalign') {
45119
+ ic.q_trans_add[index-1] = {"x":0, "y":0, "z":0};
45120
+ }
45121
+ else {
45122
+ // need to pass C-alpha coords and get transformation matrix from backend
45123
+ ic.t_trans_add[index-1] = {"x":0, "y":0, "z":0};
45124
+ ic.q_trans_sub[index-1] = {"x":0, "y":0, "z":0};
45125
+ }
45070
45126
 
45071
45127
  ic.q_rotation[index-1] = {"x1":1, "y1":0, "z1":0, "x2":0, "y2":1, "z2":0, "x3":0, "y3":0, "z3":1};
45072
45128
  ic.qt_start_end[index-1] = undefined;
@@ -45123,10 +45179,14 @@ class ChainalignParser {
45123
45179
  ic.q_rotation.push(align[0].q_rotation);
45124
45180
  ic.qt_start_end.push(align[0].segs);
45125
45181
  */
45126
- ic.t_trans_add[index] = align[0].t_trans_add;
45127
- ic.q_trans_sub[index] = align[0].q_trans_sub;
45128
45182
 
45129
- if(me.cfg.aligntool == 'tmalign') ic.q_trans_add[index] = align[0].q_trans_add;
45183
+ if(me.cfg.aligntool == 'tmalign') {
45184
+ ic.q_trans_add[index] = align[0].q_trans_add;
45185
+ }
45186
+ else {
45187
+ ic.t_trans_add[index] = align[0].t_trans_add;
45188
+ ic.q_trans_sub[index] = align[0].q_trans_sub;
45189
+ }
45130
45190
 
45131
45191
  ic.q_rotation[index] = align[0].q_rotation;
45132
45192
  ic.qt_start_end[index] = align[0].segs;
@@ -45673,11 +45733,11 @@ class MmcifParser {
45673
45733
 
45674
45734
  //ic.bCid = undefined;
45675
45735
 
45676
- let data1 = await me.getAjaxPromise(url, 'text', false, 'The structure " + mmcifid + " was not found...');
45736
+ let data1 = await me.getAjaxPromise(url, 'text', false, "The structure " + mmcifid + " was not found...");
45677
45737
 
45678
45738
  url = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi";
45679
45739
  let dataObj = {'mmcifheader': data1};
45680
- let data = await me.getAjaxPostPromise(url, dataObj, false, 'The mmCIF data of " + mmcifid + " can not be parsed...');
45740
+ let data = await me.getAjaxPostPromise(url, dataObj, false, "The mmCIF data of " + mmcifid + " can not be parsed...");
45681
45741
 
45682
45742
  if(data.emd !== undefined) ic.emd = data.emd;
45683
45743
  if(data.organism !== undefined) ic.organism = data.organism;
@@ -45737,7 +45797,7 @@ class MmcifParser {
45737
45797
  //loadAtomDataIn. The deferred parameter was resolved after the parsing so that other javascript code can be executed.
45738
45798
  async loadMmcifData(data, mmcifid) { let ic = this.icn3d; ic.icn3dui;
45739
45799
  if(!mmcifid) mmcifid = data.mmcif;
45740
- if(!mmcifid) mmcifid = 'stru';
45800
+ if(!mmcifid) mmcifid = ic.defaultPdbId;
45741
45801
 
45742
45802
  if(data.atoms !== undefined) {
45743
45803
  ic.init();
@@ -46834,7 +46894,7 @@ class OpmParser {
46834
46894
 
46835
46895
  async loadOpmData(data, pdbid, bFull, type, pdbid2) { let ic = this.icn3d, me = ic.icn3dui;
46836
46896
  try {
46837
- if(!pdbid) pdbid = 'stru';
46897
+ if(!pdbid) pdbid = ic.defaultPdbId;
46838
46898
  let url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&opm&uid=" + pdbid.toLowerCase();
46839
46899
 
46840
46900
  let opmdata = await me.getAjaxPromise(url, 'jsonp', false);
@@ -47039,20 +47099,22 @@ class PdbParser {
47039
47099
  if(me.cfg.opmid === undefined) ic.ParserUtilsCls.transformToOpmOri(pdbid);
47040
47100
 
47041
47101
  if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
47042
- $("#" + ic.pre + "assemblyWrapper").show();
47102
+ if(!me.bNode) $("#" + ic.pre + "assemblyWrapper").show();
47043
47103
 
47044
47104
  ic.asuCnt = ic.biomtMatrices.length;
47045
47105
  }
47046
47106
 
47047
- if(ic.emd !== undefined) {
47048
- $("#" + ic.pre + "mapWrapper1").hide();
47049
- $("#" + ic.pre + "mapWrapper2").hide();
47050
- $("#" + ic.pre + "mapWrapper3").hide();
47051
- }
47052
- else {
47053
- $("#" + ic.pre + "emmapWrapper1").hide();
47054
- $("#" + ic.pre + "emmapWrapper2").hide();
47055
- $("#" + ic.pre + "emmapWrapper3").hide();
47107
+ if(!me.bNode) {
47108
+ if(ic.emd !== undefined) {
47109
+ $("#" + ic.pre + "mapWrapper1").hide();
47110
+ $("#" + ic.pre + "mapWrapper2").hide();
47111
+ $("#" + ic.pre + "mapWrapper3").hide();
47112
+ }
47113
+ else {
47114
+ $("#" + ic.pre + "emmapWrapper1").hide();
47115
+ $("#" + ic.pre + "emmapWrapper2").hide();
47116
+ $("#" + ic.pre + "emmapWrapper3").hide();
47117
+ }
47056
47118
  }
47057
47119
 
47058
47120
  // calculate secondary structures if not available
@@ -47073,7 +47135,7 @@ class PdbParser {
47073
47135
  else {
47074
47136
  await this.loadPdbDataRender(bAppend);
47075
47137
 
47076
- await ic.ParserUtilsCls.checkMemProteinAndRotate();
47138
+ if(!me.bNode) await ic.ParserUtilsCls.checkMemProteinAndRotate();
47077
47139
 
47078
47140
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
47079
47141
  }
@@ -47895,6 +47957,8 @@ class RealignParser {
47895
47957
  let ajaxArray = [], chainidPairArray = [];
47896
47958
  let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi";
47897
47959
  let urltmalign = me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
47960
+
47961
+ //let cnt = 0;
47898
47962
  let structArray = Object.keys(struct2domain);
47899
47963
  for(let s = 0, sl = structArray.length; s < sl; ++s) {
47900
47964
  let struct1 = structArray[s];
@@ -47907,13 +47971,13 @@ class RealignParser {
47907
47971
 
47908
47972
  for(let i = 0, il = chainidArray1.length; i < il; ++i) {
47909
47973
  let chainid1 = chainidArray1[i];
47974
+ let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
47910
47975
  for(let j = 0, jl = chainidArray2.length; j < jl; ++j) {
47911
47976
  let chainid2 = chainidArray2[j];
47912
47977
 
47913
47978
  let alignAjax;
47914
47979
 
47915
47980
  if(me.cfg.aligntool != 'tmalign') {
47916
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
47917
47981
  let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct2][chainid2]);
47918
47982
 
47919
47983
  let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
@@ -47931,7 +47995,8 @@ class RealignParser {
47931
47995
  }
47932
47996
 
47933
47997
  ajaxArray.push(alignAjax);
47934
- chainidPairArray.push(chainid1 + ',' + chainid2); // chainid2 is target
47998
+ chainidPairArray.push(chainid1 + ',' + chainid2);
47999
+ //++cnt;
47935
48000
  }
47936
48001
  }
47937
48002
  }
@@ -47948,6 +48013,87 @@ class RealignParser {
47948
48013
  }
47949
48014
  }
47950
48015
 
48016
+ async realignOnStructAlignMsa(nameArray) { let ic = this.icn3d, me = ic.icn3dui;
48017
+ // each 3D domain should have at least 3 secondary structures
48018
+ let minSseCnt = 3;
48019
+ let chainid2domain = {};
48020
+
48021
+ for(let i = 0, il = nameArray.length; i < il; ++i) {
48022
+ let chainid = nameArray[i];
48023
+ let atoms = me.hashUtilsCls.intHash(ic.hAtoms, ic.chains[chainid]);
48024
+ let sseCnt = 0;
48025
+ for(let serial in atoms) {
48026
+ if(ic.atoms[serial].ssbegin) ++sseCnt;
48027
+ if(sseCnt == minSseCnt) {
48028
+ chainid2domain[chainid] = atoms;
48029
+ break;
48030
+ }
48031
+ }
48032
+ }
48033
+
48034
+ let ajaxArray = [], indexArray = [], struArray = [];
48035
+ let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi";
48036
+ let urltmalign = me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
48037
+
48038
+ let chainid1 = nameArray[0];
48039
+ let struct1 = chainid1.substr(0, chainid1.indexOf('_'));
48040
+ let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(chainid2domain[chainid1]);
48041
+
48042
+ for(let i = 1, il = nameArray.length; i < il; ++i) {
48043
+ let chainid2 = nameArray[i];
48044
+ let struct2 = chainid2.substr(0, chainid2.indexOf('_'));
48045
+
48046
+ let alignAjax;
48047
+
48048
+ if(me.cfg.aligntool != 'tmalign') {
48049
+ let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(chainid2domain[chainid2]);
48050
+
48051
+ let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
48052
+ alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
48053
+ }
48054
+ else {
48055
+ // let pdb_target = ic.saveFileCls.getAtomPDB(chainid2domain[chainid1], undefined, undefined, undefined, undefined, struct1);
48056
+ // let pdb_query = ic.saveFileCls.getAtomPDB(chainid2domain[chainid2], undefined, undefined, undefined, undefined, struct2);
48057
+
48058
+ let pdb_target = ic.saveFileCls.getAtomPDB(ic.chains[chainid1], undefined, undefined, undefined, undefined, struct1);
48059
+ let pdb_query = ic.saveFileCls.getAtomPDB(ic.chains[chainid2], undefined, undefined, undefined, undefined, struct2);
48060
+
48061
+ let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target};
48062
+ alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
48063
+ }
48064
+
48065
+ ajaxArray.push(alignAjax);
48066
+ //chainidPairArray.push(chainid1 + ',' + chainid2);
48067
+
48068
+ indexArray.push(i - 1);
48069
+ struArray.push(struct2);
48070
+
48071
+ //++cnt;
48072
+ }
48073
+
48074
+ let allPromise = Promise.allSettled(ajaxArray);
48075
+ //try {
48076
+ let dataArray = await allPromise;
48077
+ //ic.qt_start_end = []; // reset the alignment
48078
+ //await ic.chainalignParserCls.downloadChainalignmentPart2bRealignMsa(dataArray, chainidPairArray);
48079
+
48080
+ // set trans and rotation matrix
48081
+ ic.t_trans_add = [];
48082
+ ic.q_trans_sub = [];
48083
+
48084
+ if(me.cfg.aligntool == 'tmalign') ic.q_trans_add = [];
48085
+
48086
+ ic.q_rotation = [];
48087
+ ic.qt_start_end = [];
48088
+
48089
+ await ic.chainalignParserCls.downloadChainalignmentPart2b(undefined, nameArray, undefined, dataArray,
48090
+ indexArray, struct1, struArray);
48091
+ // }
48092
+ // catch(err) {
48093
+ // if(ic.bRender) var aaa = 1; //alert("These structures can NOT be aligned to each other...");
48094
+ // }
48095
+ }
48096
+
47951
48097
  async realignChainOnSeqAlign(chainresiCalphaHash2, chainidArray, bRealign, bPredefined) { let ic = this.icn3d, me = ic.icn3dui;
47952
48098
  let thisClass = this;
47953
48099
 
@@ -49721,7 +49867,7 @@ class ParserUtils {
49721
49867
 
49722
49868
  //var dxymax = npoint / 2.0 * step;
49723
49869
 
49724
- pdbid =(pdbid) ? pdbid.toUpperCase() : 'stru';
49870
+ pdbid =(pdbid) ? pdbid.toUpperCase() : ic.defaultPdbId;
49725
49871
 
49726
49872
  ic.structures[pdbid].push(pdbid + '_MEM');
49727
49873
  ic.chains[pdbid + '_MEM'] = {};
@@ -49963,7 +50109,7 @@ class ParserUtils {
49963
50109
  let afMemdata = await me.getAjaxPromise(url2, 'text');
49964
50110
 
49965
50111
  ic.bAfMem = true;
49966
- $("#" + me.pre + "togglememli").show(); // show the menu "View > Toggle Membrane"
50112
+ if(!me.bNode) $("#" + me.pre + "togglememli").show(); // show the menu "View > Toggle Membrane"
49967
50113
 
49968
50114
  // append the PDB
49969
50115
  let pdbid = data.pdbid.substr(0, data.pdbid.indexOf('_'));
@@ -52144,7 +52290,7 @@ class LoadPDB {
52144
52290
 
52145
52291
  //let chainMissingResidueArray = {}
52146
52292
 
52147
- let id = (pdbid) ? pdbid : 'stru';
52293
+ let id = (pdbid) ? pdbid : ic.defaultPdbId;
52148
52294
  let structure = id;
52149
52295
 
52150
52296
  let prevMissingChain = '';
@@ -52164,18 +52310,18 @@ class LoadPDB {
52164
52310
 
52165
52311
  if(id == '') {
52166
52312
  if(bAppend) {
52167
- id = "stru";
52313
+ id = ic.defaultPdbId;
52168
52314
  }
52169
52315
  else {
52170
- //if(!ic.inputid) ic.inputid = 'stru';
52171
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : "stru"; //ic.filename.substr(0, 4);
52316
+ //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
52317
+ id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
52172
52318
  }
52173
52319
  }
52174
52320
 
52175
52321
  structure = id;
52176
52322
 
52177
- if(id == 'stru' || bMutation) { // bMutation: side chain prediction
52178
- //if(id == 'stru') {
52323
+ if(id == ic.defaultPdbId || bMutation) { // bMutation: side chain prediction
52324
+ //if(id == ic.defaultPdbId) {
52179
52325
  structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
52180
52326
  }
52181
52327
 
@@ -52290,12 +52436,12 @@ class LoadPDB {
52290
52436
  ic.organism = ic.organism.substr(0, ic.organism.length - 1);
52291
52437
  } else if (record === 'ENDMDL') {
52292
52438
  ++moleculeNum;
52293
- id = 'stru';
52439
+ id = ic.defaultPdbId;
52294
52440
 
52295
52441
  structure = id;
52296
52442
 
52297
- if(id == 'stru' || bMutation) { // bMutation: side chain prediction
52298
- //if(id == 'stru') {
52443
+ if(id == ic.defaultPdbId || bMutation) { // bMutation: side chain prediction
52444
+ //if(id == ic.defaultPdbId) {
52299
52445
  structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
52300
52446
  }
52301
52447
 
@@ -52318,8 +52464,8 @@ class LoadPDB {
52318
52464
  } else if (record === 'ATOM ' || record === 'HETATM') {
52319
52465
  structure = id;
52320
52466
 
52321
- if(id == 'stru' || bMutation) { // bMutation: side chain prediction
52322
- //if(id == 'stru') {
52467
+ if(id == ic.defaultPdbId || bMutation) { // bMutation: side chain prediction
52468
+ //if(id == ic.defaultPdbId) {
52323
52469
  structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
52324
52470
  }
52325
52471
 
@@ -53791,6 +53937,12 @@ class ApplyCommand {
53791
53937
  else if(command == 'export pdb') {
53792
53938
  me.htmlCls.setHtmlCls.exportPdb();
53793
53939
  }
53940
+ else if(command == 'export pdb missing atoms') {
53941
+ await ic.scapCls.exportPdbProfix(false);
53942
+ }
53943
+ else if(command == 'export pdb hydrogen') {
53944
+ await ic.scapCls.exportPdbProfix(true);
53945
+ }
53794
53946
  else if(command == 'export secondary structure') {
53795
53947
  me.htmlCls.setHtmlCls.exportSecondary();
53796
53948
  }
@@ -54964,21 +55116,23 @@ class ApplyCommand {
54964
55116
  else if(command.indexOf('window') == 0) {
54965
55117
  let secondPart = command.substr(command.indexOf(' ') + 1);
54966
55118
 
54967
- if(secondPart == "aligned sequences") {
55119
+ setTimeout(function(){
55120
+ if(secondPart == "aligned sequences") {
54968
55121
  me.htmlCls.dialogCls.openDlg('dl_alignment', 'Select residues in aligned sequences');
54969
- }
54970
- else if(secondPart == "interaction table") {
54971
- me.htmlCls.dialogCls.openDlg('dl_allinteraction', 'Show interactions');
54972
- }
54973
- else if(secondPart == "interaction graph") {
54974
- me.htmlCls.dialogCls.openDlg('dl_linegraph', 'Show interactions between two lines of residue nodes');
54975
- }
54976
- else if(secondPart == "interaction scatterplot") {
54977
- me.htmlCls.dialogCls.openDlg('dl_scatterplot', 'Show interactions as scatterplot');
54978
- }
54979
- else if(secondPart == "force-directed graph") {
54980
- me.htmlCls.dialogCls.openDlg('dl_graph', 'Force-directed graph');
54981
- }
55122
+ }
55123
+ else if(secondPart == "interaction table") {
55124
+ me.htmlCls.dialogCls.openDlg('dl_allinteraction', 'Show interactions');
55125
+ }
55126
+ else if(secondPart == "interaction graph") {
55127
+ me.htmlCls.dialogCls.openDlg('dl_linegraph', 'Show interactions between two lines of residue nodes');
55128
+ }
55129
+ else if(secondPart == "interaction scatterplot") {
55130
+ me.htmlCls.dialogCls.openDlg('dl_scatterplot', 'Show interactions as scatterplot');
55131
+ }
55132
+ else if(secondPart == "force-directed graph") {
55133
+ me.htmlCls.dialogCls.openDlg('dl_graph', 'Force-directed graph');
55134
+ }
55135
+ }, 1000);
54982
55136
  }
54983
55137
  else if(command.indexOf('set theme') == 0) {
54984
55138
  let color = command.substr(command.lastIndexOf(' ') + 1);
@@ -56179,6 +56333,17 @@ class LoadScript {
56179
56333
  await this.execCommandsBase(start, end, steps);
56180
56334
  }
56181
56335
 
56336
+ getNameArray(command) { let ic = this.icn3d; ic.icn3dui;
56337
+ let paraArray = command.split(' | ');
56338
+ let nameArray = [];
56339
+ if(paraArray.length == 2) {
56340
+ nameArray = paraArray[1].split(',');
56341
+ ic.hAtoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
56342
+ }
56343
+
56344
+ return nameArray;
56345
+ }
56346
+
56182
56347
  async execCommandsBase(start, end, steps, bFinalStep) { let ic = this.icn3d, me = ic.icn3dui;
56183
56348
  let thisClass = this;
56184
56349
  let i;
@@ -56320,31 +56485,37 @@ class LoadScript {
56320
56485
  await ic.scapCls.applyCommandScap(command);
56321
56486
  }
56322
56487
  else if(command.indexOf('realign on seq align') == 0) {
56323
- let paraArray = command.split(' | ');
56324
- if(paraArray.length == 2) {
56325
- let nameArray = paraArray[1].split(',');
56326
- ic.hAtoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
56327
- }
56488
+ this.getNameArray(command);
56328
56489
 
56329
56490
  await thisClass.applyCommandRealign(command);
56330
56491
  }
56492
+ else if(command.indexOf('realign on structure align msa') == 0) {
56493
+ let nameArray = this.getNameArray(command);
56494
+
56495
+ me.cfg.aligntool = 'vast';
56496
+
56497
+ await ic.realignParserCls.realignOnStructAlignMsa(nameArray);
56498
+ }
56331
56499
  else if(command.indexOf('realign on structure align') == 0) {
56332
- let paraArray = command.split(' | ');
56333
- if(paraArray.length == 2) {
56334
- let nameArray = paraArray[1].split(',');
56335
- ic.hAtoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
56336
- }
56500
+ this.getNameArray(command);
56337
56501
 
56338
56502
  me.cfg.aligntool = 'vast';
56339
56503
 
56340
- await thisClass.applyCommandRealignByStruct(command);
56504
+ await ic.realignParserCls.realignOnStructAlign();
56505
+ }
56506
+ else if(command.indexOf('realign on tmalign msa') == 0) {
56507
+ let nameArray = this.getNameArray(command);
56508
+
56509
+ me.cfg.aligntool = 'tmalign';
56510
+
56511
+ await ic.realignParserCls.realignOnStructAlignMsa(nameArray);
56341
56512
  }
56342
56513
  else if(command.indexOf('realign on tmalign') == 0) {
56343
- thisClass.getHAtoms(ic.commands[i]);
56514
+ this.getNameArray(command);
56344
56515
 
56345
56516
  me.cfg.aligntool = 'tmalign';
56346
56517
 
56347
- await thisClass.applyCommandRealignByStruct(ic.commands[i]);
56518
+ await ic.realignParserCls.realignOnStructAlign();
56348
56519
  }
56349
56520
  else if(command.indexOf('realign on vastplus') == 0) {
56350
56521
  thisClass.getHAtoms(ic.commands[i]);
@@ -59344,7 +59515,7 @@ class Dssp {
59344
59515
  async showIgRefNum() { let ic = this.icn3d, me = ic.icn3dui;
59345
59516
  let thisClass = this;
59346
59517
 
59347
- if(Object.keys(ic.resid2refnum).length > 0) {
59518
+ if(ic.resid2refnum && Object.keys(ic.resid2refnum).length > 0) {
59348
59519
  ic.bShowRefnum = true;
59349
59520
 
59350
59521
  // open sequence view
@@ -59391,16 +59562,17 @@ class Dssp {
59391
59562
  let ajaxArray = [];
59392
59563
  let domainidpairArray = [];
59393
59564
 
59394
- me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
59565
+ let urltmalign = me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
59395
59566
 
59396
59567
  ic.resid2domainid = {};
59397
59568
 
59398
59569
  for(let i = 0, il = struArray.length; i < il; ++i) {
59399
59570
  let struct = struArray[i];
59400
59571
  let chainidArray = ic.structures[struct];
59401
-
59572
+
59402
59573
  for(let j = 0, jl = chainidArray.length; j < jl; ++j) {
59403
59574
  let chainid = chainidArray[j];
59575
+
59404
59576
  if(!ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]).serial)) continue;
59405
59577
  if(ic.chainsSeq[chainid].length < 50) continue; // peptide
59406
59578
 
@@ -59435,20 +59607,19 @@ class Dssp {
59435
59607
  domainAtomsArray.push(domainAtoms);
59436
59608
  }
59437
59609
  }
59438
-
59610
+
59439
59611
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
59612
+
59440
59613
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
59441
59614
  let domainid = chainid + '-' + k;
59442
59615
  for(let index = 0, indexl = dataArray.length; index < indexl; ++index) {
59443
- let struct2 = "stru" + index;
59616
+ let struct2 = ic.defaultPdbId + index;
59444
59617
  let pdb_query = dataArray[index].value; //[0];
59445
-
59446
59618
  let header = 'HEADER ' + struct2 + '\n';
59447
59619
  pdb_query = header + pdb_query;
59448
59620
 
59449
59621
  let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbArray[index]};
59450
- let alignAjax = me.getAjaxPostPromise(url, dataObj);
59451
-
59622
+ let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
59452
59623
  ajaxArray.push(alignAjax);
59453
59624
 
59454
59625
  domainidpairArray.push(domainid + "," + index);
@@ -59459,18 +59630,19 @@ class Dssp {
59459
59630
 
59460
59631
  let allPromise = Promise.allSettled(ajaxArray);
59461
59632
  try {
59462
- let dataArray = await allPromise;
59463
- await thisClass.parseAlignData(dataArray, domainidpairArray);
59633
+ let dataArray2 = await allPromise;
59634
+
59635
+ await thisClass.parseAlignData(dataArray2, domainidpairArray);
59464
59636
 
59465
59637
  /// if(ic.deferredRefnum !== undefined) ic.deferredRefnum.resolve();
59466
59638
  }
59467
59639
  catch(err) {
59468
- console.log("Error in aligning with TM-align...");
59640
+ if(!me.bNode) console.log("Error in aligning with TM-align...");
59469
59641
  return;
59470
59642
  }
59471
59643
  }
59472
59644
 
59473
- async parseAlignData(dataArray, domainidpairArray) { let ic = this.icn3d; ic.icn3dui;
59645
+ async parseAlignData(dataArray, domainidpairArray) { let ic = this.icn3d, me = ic.icn3dui;
59474
59646
  let thisClass = this;
59475
59647
 
59476
59648
  let tmscoreThreshold = 0.4; //0.5;
@@ -59479,9 +59651,12 @@ class Dssp {
59479
59651
  let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
59480
59652
  ic.chainid2index = {};
59481
59653
  ic.domainid2ig2kabat = {};
59654
+
59482
59655
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
59483
59656
  let queryData = dataArray[i].value; //[0];
59657
+
59484
59658
  if(queryData.length == 0) continue;
59659
+
59485
59660
  if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < 50) continue;
59486
59661
 
59487
59662
  let domainid_index = domainidpairArray[i].split(',');
@@ -59493,6 +59668,7 @@ class Dssp {
59493
59668
  let bBstrand = false, bCstrand = false, bEstrand = false, bFstrand = false;
59494
59669
  for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
59495
59670
  let seg = queryData[0].segs[i];
59671
+
59496
59672
  if(seg.q_start.indexOf('2050') != -1) {
59497
59673
  bBstrand = true;
59498
59674
  }
@@ -59512,12 +59688,13 @@ class Dssp {
59512
59688
  //if(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand) break;
59513
59689
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
59514
59690
  }
59691
+
59515
59692
  //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
59516
59693
  if(!(bBstrand && bCstrand && bEstrand && bFstrand)) continue;
59517
59694
 
59518
59695
  if(!domainid2score.hasOwnProperty(domainid) || queryData[0].score > domainid2score[domainid]) {
59519
59696
  domainid2score[domainid] = queryData[0].score;
59520
- console.log(domainid + ' TM-score: ' + domainid2score[domainid] + ' matched ' + ic.refpdbArray[domainid_index[1]]);
59697
+ if(!me.bNode) console.log(domainid + ' TM-score: ' + domainid2score[domainid] + ' matched ' + ic.refpdbArray[domainid_index[1]]);
59521
59698
  ic.chainid2index[chainid] = domainid_index[1]; // could be several, just take the recent one for simplicity
59522
59699
  domainid2segs[domainid] = queryData[0].segs;
59523
59700
  ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
@@ -59537,7 +59714,7 @@ console.log(domainid + ' TM-score: ' + domainid2score[domainid] + ' matched ' +
59537
59714
  if(!ic.chainsMapping) ic.chainsMapping = {};
59538
59715
  for(let chainid in chainid2segs) {
59539
59716
  let segArray = chainid2segs[chainid];
59540
- console.log("One of the reference PDBs for chain chainid: " + ic.refpdbArray[ic.chainid2index[chainid]]);
59717
+ if(!me.bNode) console.log("One of the reference PDBs for chain chainid: " + ic.refpdbArray[ic.chainid2index[chainid]]);
59541
59718
 
59542
59719
  for(let i = 0, il = segArray.length; i < il; ++i) {
59543
59720
  let seg = segArray[i];
@@ -59807,11 +59984,12 @@ console.log("free energy: " + energy + " kcal/mol");
59807
59984
 
59808
59985
  // get the full mutatnt PDB
59809
59986
  let pdbDataMutant = ic.saveFileCls.getAtomPDB(ic.atoms, false, false, false, chainResi2pdb);
59987
+
59810
59988
  ic.hAtoms = {};
59811
59989
  let bMutation = true;
59812
59990
  ic.loadPDBCls.loadPDB(pdbDataMutant, pdbid, false, false, bMutation, bAddition);
59813
59991
  //let allAtoms2 = me.hashUtilsCls.cloneHash(ic.hAtoms);
59814
-
59992
+
59815
59993
  ic.setStyleCls.setAtomStyleByOptions(ic.opts);
59816
59994
  ic.setColorCls.setColorByOptions(ic.opts, ic.hAtoms);
59817
59995
 
@@ -59866,11 +60044,10 @@ console.log("free energy: " + energy + " kcal/mol");
59866
60044
  }
59867
60045
 
59868
60046
  if(bPdb) {
59869
- //let pdbStr = '';
59870
- //pdbStr += ic.saveFileCls.getAtomPDB(ic.hAtoms);
60047
+ // let file_pref =(ic.inputid) ? ic.inputid : "custom";
60048
+ // ic.saveFileCls.saveFile(file_pref + '_' + snpStr + '.pdb', 'text', [pdbDataMutant]);
59871
60049
 
59872
- let file_pref =(ic.inputid) ? ic.inputid : "custom";
59873
- ic.saveFileCls.saveFile(file_pref + '_' + snpStr + '.pdb', 'text', [pdbDataMutant]);
60050
+ await thisClass.exportPdbProfix(false, pdbDataMutant, snpStr);
59874
60051
 
59875
60052
  ic.drawCls.draw();
59876
60053
  }
@@ -59921,7 +60098,40 @@ console.log("free energy: " + energy + " kcal/mol");
59921
60098
 
59922
60099
  /// if(ic.deferredScap !== undefined) ic.deferredScap.resolve();
59923
60100
  return;
59924
- } }
60101
+ }
60102
+ }
60103
+
60104
+ async exportPdbProfix(bHydrogen, pdb, snpStr) { let ic = this.icn3d, me = ic.icn3dui;
60105
+ let pdbStr;
60106
+
60107
+ if(pdb) {
60108
+ pdbStr = pdb;
60109
+ }
60110
+ else {
60111
+ let atoms = me.hashUtilsCls.intHash(ic.dAtoms, ic.hAtoms);
60112
+ pdbStr += ic.saveFileCls.getAtomPDB(atoms);
60113
+ }
60114
+
60115
+ let url = me.htmlCls.baseUrl + "scap/scap.cgi";
60116
+ let hydrogenStr = (bHydrogen) ? '1' : '0';
60117
+ let dataObj = {'pdb': pdbStr, 'profix': '1', 'hydrogen': hydrogenStr};
60118
+
60119
+ let data;
60120
+
60121
+ try {
60122
+ data = await me.getAjaxPostPromise(url, dataObj, undefined, undefined, undefined, undefined, 'text');
60123
+ }
60124
+ catch(err) {
60125
+ var aaa = 1; //alert("There are some problems in adding missing atoms or hydrogens...");
60126
+ return;
60127
+ }
60128
+
60129
+ let file_pref =(ic.inputid) ? ic.inputid : "custom";
60130
+ let postfix = (bHydrogen) ? "add_hydrogen" : "add_missing_atoms";
60131
+ if(snpStr) postfix = snpStr;
60132
+
60133
+ ic.saveFileCls.saveFile(file_pref + '_icn3d_' + postfix + '.pdb', 'text', [data]);
60134
+ }
59925
60135
  }
59926
60136
 
59927
60137
  /**
@@ -63765,10 +63975,11 @@ class SaveFile {
63765
63975
  }
63766
63976
 
63767
63977
  // if(!bNoSs) {
63768
- let prevResi, stru;
63978
+ let prevResi, stru, chainid;
63769
63979
  for(let i in calphaHash) {
63770
63980
  let atom = ic.atoms[i];
63771
63981
  stru = atom.structure;
63982
+ chainid = atom.structure + '_' + atom.chain;
63772
63983
 
63773
63984
  if(atom.ssbegin) {
63774
63985
  if(atom.ss == 'helix') {
@@ -63789,7 +64000,9 @@ class SaveFile {
63789
64000
  if(atom.ssend) {
63790
64001
  if(atom.ss == 'helix') {
63791
64002
  bHelixEnd = true;
63792
- let helixLen = ic.resid2ncbi[atom.resi] - ic.resid2ncbi[prevResi];
64003
+ let residEnd = ic.resid2ncbi[chainid + '_' + atom.resi];
64004
+ let residStart = ic.resid2ncbi[chainid + '_' + prevResi];
64005
+ let helixLen = (residEnd && residStart) ? parseInt(residEnd.substr(residEnd.lastIndexOf('_') + 1)) - parseInt(residStart.substr(residStart.lastIndexOf('_') + 1)) : 0;
63793
64006
  let helixType = 1;
63794
64007
  if(bHelixBegin) stru2header[stru] += atom.resn.padStart(5, ' ') + atom.chain.replace(/_/gi, '').substr(0, 2).padStart(2, ' ')
63795
64008
  + atom.resi.toString().padStart(5, ' ') + ' ' + helixType + helixLen.toString().padStart(36, ' ') + '\n';
@@ -63870,7 +64083,7 @@ class SaveFile {
63870
64083
  }
63871
64084
 
63872
64085
  let chainResi = atom.chain + '_' + atom.resi;
63873
- if(chainResi2pdb && chainResi2pdb.hasOwnProperty(chainResi)) {
64086
+ if(chainResi2pdb && chainResi2pdb.hasOwnProperty(chainResi)) {
63874
64087
  if(!addedChainResiHash.hasOwnProperty(chainResi)) {
63875
64088
  pdbStr += chainResi2pdb[chainResi];
63876
64089
  addedChainResiHash[chainResi] = 1;
@@ -64035,7 +64248,7 @@ class SaveFile {
64035
64248
  }
64036
64249
 
64037
64250
  pdbStr += connStr;
64038
-
64251
+
64039
64252
  if(bMulStruc) pdbStr += '\nENDMDL\n';
64040
64253
 
64041
64254
  return pdbStr;
@@ -64189,13 +64402,23 @@ class SaveFile {
64189
64402
  setStructureTitle(url, title, titlelinkColor) {var ic = this.icn3d, me = ic.icn3dui;
64190
64403
  if(ic.molTitle.length > 40) title = ic.molTitle.substr(0, 40) + "...";
64191
64404
 
64192
- //var asymmetricStr =(ic.bAssemblyUseAsu) ? "(Asymmetric Unit)" : "";
64193
- let asymmetricStr = "";
64405
+ let text = ic.inputid.toUpperCase();
64194
64406
 
64195
64407
  let idName = (isNaN(ic.inputid) && ic.inputid.length > 5) ? "AlphaFold ID" : "PDB ID";
64408
+ if(ic.inputid.indexOf('http') != -1) {
64409
+ idName = "Data from";
64410
+ url = ic.inputid;
64411
+ text = ic.inputid;
64412
+ }
64413
+
64196
64414
  if(me.cfg.refseqid) idName = 'NCBI Protein Acc.';
64197
64415
 
64198
- $("#" + ic.pre + "title").html(idName + " <a id='" + ic.pre + "titlelink' href='" + url + "' style='color:" + titlelinkColor + "' target='_blank'>" + ic.inputid.toUpperCase() + "</a>" + asymmetricStr + ": " + title);
64416
+ if(!ic.inputid || ic.inputid.substr(0, 4) == ic.defaultPdbId) {
64417
+ $("#" + ic.pre + "title").html(title);
64418
+ }
64419
+ else {
64420
+ $("#" + ic.pre + "title").html(idName + " <a id='" + ic.pre + "titlelink' href='" + url + "' style='color:" + titlelinkColor + "' target='_blank'>" + text + "</a>: " + title);
64421
+ }
64199
64422
  }
64200
64423
 
64201
64424
  getLinkToStructureSummary(bLog) {var ic = this.icn3d, me = ic.icn3dui;
@@ -64281,7 +64504,7 @@ class ShareLink {
64281
64504
  if(bPngHtml) url += "&random=" + parseInt(Math.random() * 1000); // generate a new shorten URL and thus image name everytime
64282
64505
  //var inputid =(ic.inputid) ? ic.inputid : "custom";
64283
64506
  let inputid = Object.keys(ic.structures).join('_');
64284
- if(inputid == 'stru') {
64507
+ if(inputid == ic.defaultPdbId) {
64285
64508
  if(ic.filename) {
64286
64509
  inputid = ic.filename;
64287
64510
  }
@@ -66833,6 +67056,7 @@ class iCn3D {
66833
67056
  this.transparentRenderOrder = false; // false: regular transparency; true: expensive renderOrder for each face
66834
67057
 
66835
67058
  this.AFUniprotVersion = 'v4';
67059
+ this.defaultPdbId = 'stru';
66836
67060
 
66837
67061
  if(!this.icn3dui.bNode) {
66838
67062
  if ( bWebGL2 && bVR) {
@@ -67416,7 +67640,7 @@ class iCn3DUI {
67416
67640
  //even when multiple iCn3D viewers are shown together.
67417
67641
  this.pre = this.cfg.divid + "_";
67418
67642
 
67419
- this.REVISION = '3.21.1';
67643
+ this.REVISION = '3.22.0';
67420
67644
 
67421
67645
  // In nodejs, iCn3D defines "window = {navigator: {}}"
67422
67646
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -67887,7 +68111,7 @@ iCn3DUI.prototype.getAjaxPromise = function(url, dataType, beforeSend, alertMess
67887
68111
  if(beforeSend) me.icn3d.ParserUtilsCls.showLoading();
67888
68112
  },
67889
68113
  complete: function() {
67890
- if(complete) ic.ParserUtilsCls.hideLoading();
68114
+ if(complete) me.icn3d.ParserUtilsCls.hideLoading();
67891
68115
  },
67892
68116
  success: function(data) {
67893
68117
  resolve(data);
@@ -67916,7 +68140,7 @@ iCn3DUI.prototype.getAjaxPostPromise = function(url, data, beforeSend, alertMess
67916
68140
  if(beforeSend) me.icn3d.ParserUtilsCls.showLoading();
67917
68141
  },
67918
68142
  complete: function() {
67919
- if(complete) ic.ParserUtilsCls.hideLoading();
68143
+ if(complete) me.icn3d.ParserUtilsCls.hideLoading();
67920
68144
  },
67921
68145
  success: function(data) {
67922
68146
  resolve(data);