icn3d 3.21.1 → 3.21.3

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
@@ -7778,7 +7778,7 @@ class ClickMenu {
7778
7778
  type: 'POST',
7779
7779
  data: {
7780
7780
  q : pdbstr,
7781
- database: ["afdb50", "afdb-swissprot", "gmgcl_id", "pdb100"],
7781
+ database: ["afdb50", "afdb-swissprot", "gmgcl_id", "pdb100", "afdb-proteome", "mgnify_esm30"],
7782
7782
  mode: "3diaa"
7783
7783
  },
7784
7784
  dataType: 'text',
@@ -9330,6 +9330,10 @@ class SetMenu {
9330
9330
  html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 2);
9331
9331
  html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', true, undefined, 2);
9332
9332
  }
9333
+ else {
9334
+ html += this.getRadio('mn4_clr', 'mn4_clrIdentity', 'Identity', undefined, undefined, 2);
9335
+ html += this.getRadio('mn4_clr', 'mn4_clrConserved', 'Conservation', undefined, undefined, 2);
9336
+ }
9333
9337
 
9334
9338
  //if(me.cfg.afid) html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
9335
9339
  //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 +9408,15 @@ class SetMenu {
9404
9408
 
9405
9409
  html += this.getLink('mn6_hbondsYes', 'Interactions', 1, 1);
9406
9410
 
9411
+ html += this.getMenuText('mn1_window', 'Bring to Front', undefined, undefined, 1);
9412
+ html += "<ul>";
9413
+ html += this.getLink('mn1_window_table', 'Interaction Table', undefined, 2);
9414
+ html += this.getLink('mn1_window_linegraph', '2D Interaction Network', undefined, 2);
9415
+ html += this.getLink('mn1_window_scatterplot', '2D Interaction Map', undefined, 2);
9416
+ html += this.getLink('mn1_window_graph', '2D Graph(Force-Directed)', undefined, 2);
9417
+ html += "</ul>";
9418
+ html += "</li>";
9419
+
9407
9420
  html += this.getLink('mn6_contactmap', 'Contact Map', undefined, 1);
9408
9421
 
9409
9422
  if(!me.cfg.notebook) {
@@ -10514,10 +10527,11 @@ class SetDialog {
10514
10527
 
10515
10528
  html += me.htmlCls.divStr + "dl_customref' class='" + dialogClass + "'>";
10516
10529
  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>';
10530
+ html += '<pre>refnum,11,12,,21,22,,10C,11C,20C<br>';
10531
+ html += '1TUP_A,100,101,,,132,,,,<br>';
10532
+ html += '1TUP_B,110,111,,141,142,,,,</pre>';
10533
+ html += '1TUP_C,,,,,,,200,201,230</pre>';
10534
+ 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
10535
  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
10536
  html += '</div><br>';
10523
10537
  html += "Custom File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "cstreffile' size=8> <br><br>";
@@ -15002,7 +15016,7 @@ class SetHtml {
15002
15016
  else if(pos != -1) {
15003
15017
  let url = imageStr.substr(pos + matchedStr.length);
15004
15018
  me.htmlCls.clickMenuCls.setLogCmd('load iCn3D PNG image ' + $("#" + me.pre + "pngimage").val(), false);
15005
- window.open(url);
15019
+ window.open(url, '_self');
15006
15020
  }
15007
15021
  else if(posState != -1) {
15008
15022
  let matchedStrData = "Start of data file======\n";
@@ -33055,7 +33069,7 @@ class SetColor {
33055
33069
  let b = atom.b;
33056
33070
 
33057
33071
  // PDB
33058
- b = (atom.structure.length < 6) ? 100 - b : b;
33072
+ b = (atom.structure.substr(0, 4) != ic.defaultPdbId && atom.structure.length < 6) ? 100 - b : b;
33059
33073
 
33060
33074
  if(b >= 90) {
33061
33075
  atom.color = me.parasCls.thr().setRGB(0, 0.325, 0.839);
@@ -33093,7 +33107,7 @@ class SetColor {
33093
33107
  if(b > 100) b = 100;
33094
33108
 
33095
33109
  // AlphaFold
33096
- b = (atom.structure.length > 5) ? 100 - b : b;
33110
+ b = (atom.structure.substr(0, 4) != ic.defaultPdbId && atom.structure.length > 5) ? 100 - b : b;
33097
33111
 
33098
33112
  let s1 = (ic.middB - b) * ic.spanBinv1;
33099
33113
  let s2 = (b - ic.middB) * ic.spanBinv2;
@@ -34138,7 +34152,7 @@ class AnnoCddSite {
34138
34152
  for(let s = 0, sl = segArray.length; s < sl; ++s) {
34139
34153
  let domainFrom = Math.round(segArray[s].from);
34140
34154
  let domainTo = Math.round(segArray[s].to);
34141
-
34155
+
34142
34156
  // if(ic.bNCBI) {
34143
34157
  // fromArray.push(domainFrom);
34144
34158
  // toArray.push(domainTo);
@@ -34148,8 +34162,11 @@ class AnnoCddSite {
34148
34162
  // toArray.push(thisClass.getAdjustedResi(domainTo, chnid, ic.matchedPos, ic.chainsSeq, ic.baseResi) - 1);
34149
34163
  // }
34150
34164
 
34151
- fromArray.push(ic.ParserUtilsCls.getResi(chnid, domainFrom));
34152
- toArray.push(ic.ParserUtilsCls.getResi(chnid, domainTo));
34165
+ // fromArray.push(ic.ParserUtilsCls.getResi(chnid, domainFrom));
34166
+ // toArray.push(ic.ParserUtilsCls.getResi(chnid, domainTo));
34167
+
34168
+ fromArray.push(domainFrom);
34169
+ toArray.push(domainTo);
34153
34170
 
34154
34171
  for(let i = domainFrom; i <= domainTo; ++i) {
34155
34172
  resiHash[i] = 1;
@@ -38859,7 +38876,8 @@ class ShowAnno {
38859
38876
  if(me.cfg.blast_rep_id === undefined) {
38860
38877
  if(ic.bFullUi) {
38861
38878
  if(me.cfg.mmtfid !== undefined) { // mmtf data do NOT have the missing residues
38862
- let id = chainArray[0].substr(0, chainArray[0].indexOf('_'));
38879
+ //let id = chainArray[0].substr(0, chainArray[0].indexOf('_'));
38880
+ let id = Object.keys(ic.structures)[0];
38863
38881
 
38864
38882
  await ic.mmcifParserCls.downloadMmcifSymmetry(id, 'mmtfid');
38865
38883
  }
@@ -39921,7 +39939,7 @@ class ShowSeq {
39921
39939
 
39922
39940
  //if(ic.resid2refnum.hasOwnProperty(residueid)) {
39923
39941
  let refnumLabel = ic.resid2refnum[residueid];
39924
- if(refnumLabel) {
39942
+ if(refnumLabel) {
39925
39943
  let refnumStr_ori = refnumLabel.replace(/'/g, '').substr(1);
39926
39944
  let refnumStr;
39927
39945
  if(bCustom) {
@@ -40408,7 +40426,7 @@ class HlSeq {
40408
40426
  to = parseInt(toArray[i]);
40409
40427
 
40410
40428
  for(let j = from; j <= to; ++j) {
40411
- // if(ic.bNCBI && ($(that).attr('domain') !== undefined || $(that).attr('feat') !== undefined || $(that).attr('3ddomain') !== undefined) ) {
40429
+ /*
40412
40430
  if( ($(that).attr('domain') !== undefined || $(that).attr('feat') !== undefined || $(that).attr('3ddomain') !== undefined) ) {
40413
40431
  let residNCBI = chainid + '_' + (j+1).toString();
40414
40432
  // AlphaFold domains calculated on-the-fly have no conversion
@@ -40424,6 +40442,12 @@ class HlSeq {
40424
40442
 
40425
40443
  residueid = ic.ncbi2resid[residNCBI];
40426
40444
  }
40445
+ */
40446
+
40447
+ if(($(that).attr('domain') !== undefined || $(that).attr('feat') !== undefined) || $(that).attr('3ddomain') !== undefined) {
40448
+ let residNCBI = chainid + '_' + (j+1).toString();
40449
+ residueid = ic.ncbi2resid[residNCBI];
40450
+ }
40427
40451
  else {
40428
40452
  residueid = chainid + '_' + (j+1).toString();
40429
40453
  }
@@ -40861,7 +40885,7 @@ class HlUpdate {
40861
40885
  // update annotation windows and alignment sequences
40862
40886
  let chainHash = {};
40863
40887
  for(let i = 0, il = residueArray.length; i < il; ++i) {
40864
- let pickedResidue = residueArray[i];
40888
+ let pickedResidue = residueArray[i].trim();
40865
40889
  //[id$= is expensive to search id ending with
40866
40890
  //var resElem = $("[id$=" + ic.pre + pickedResidue + "]");
40867
40891
  let resElem = $("[id=giseq_" + ic.pre + pickedResidue + "]");
@@ -43981,7 +44005,7 @@ class ContactMap {
43981
44005
 
43982
44006
  let graphStr = '{\n';
43983
44007
 
43984
- let struc1 = (ic.structures.length > 0) ? ic.structures[0] : 'stru';
44008
+ let struc1 = (ic.structures.length > 0) ? ic.structures[0] : ic.defaultPdbId;
43985
44009
  let len1 = nodeArray1.length,
43986
44010
  len2 = nodeArray2.length;
43987
44011
  let factor = 1;
@@ -44866,7 +44890,7 @@ class ChainalignParser {
44866
44890
  let chainid = chainidArray[i];
44867
44891
  let pos = chainid.indexOf('_');
44868
44892
  let struct = chainid.substr(0, pos);
44869
- if(struct != 'stru') struct = struct.toUpperCase();
44893
+ if(struct != ic.defaultPdbId) struct = struct.toUpperCase();
44870
44894
 
44871
44895
  if(!struct2cnt.hasOwnProperty(struct)) {
44872
44896
  struct2cnt[struct] = 1;
@@ -45663,11 +45687,11 @@ class MmcifParser {
45663
45687
 
45664
45688
  //ic.bCid = undefined;
45665
45689
 
45666
- let data1 = await me.getAjaxPromise(url, 'text', false, 'The structure " + mmcifid + " was not found...');
45690
+ let data1 = await me.getAjaxPromise(url, 'text', false, "The structure " + mmcifid + " was not found...");
45667
45691
 
45668
45692
  url = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi";
45669
45693
  let dataObj = {'mmcifheader': data1};
45670
- let data = await me.getAjaxPostPromise(url, dataObj, false, 'The mmCIF data of " + mmcifid + " can not be parsed...');
45694
+ let data = await me.getAjaxPostPromise(url, dataObj, false, "The mmCIF data of " + mmcifid + " can not be parsed...");
45671
45695
 
45672
45696
  if(data.emd !== undefined) ic.emd = data.emd;
45673
45697
  if(data.organism !== undefined) ic.organism = data.organism;
@@ -45727,7 +45751,7 @@ class MmcifParser {
45727
45751
  //loadAtomDataIn. The deferred parameter was resolved after the parsing so that other javascript code can be executed.
45728
45752
  async loadMmcifData(data, mmcifid) { let ic = this.icn3d; ic.icn3dui;
45729
45753
  if(!mmcifid) mmcifid = data.mmcif;
45730
- if(!mmcifid) mmcifid = 'stru';
45754
+ if(!mmcifid) mmcifid = ic.defaultPdbId;
45731
45755
 
45732
45756
  if(data.atoms !== undefined) {
45733
45757
  ic.init();
@@ -45814,6 +45838,16 @@ class MmdbParser {
45814
45838
  }
45815
45839
  }
45816
45840
 
45841
+ //Ajax call was used to get the atom data from the NCBI "gi". This function was deferred so that
45842
+ //it can be chained together with other deferred functions for sequential execution. Note that
45843
+ //only one structure corresponding to the gi will be shown. If there is no structures available
45844
+ //for the gi, a warning message will be shown.
45845
+ async downloadGi(gi) { let ic = this.icn3d; ic.icn3dui;
45846
+ ic.bCid = undefined;
45847
+ let bGi = true;
45848
+ await this.downloadMmdb(gi, bGi);
45849
+ }
45850
+
45817
45851
  //Ajax call was used to get the atom data from "sequence_id_comma_structure_id", comma-separated
45818
45852
  //NCBI protein accessions of a protein sequence and a chain of a 3D structure (e.g., 23491729,1TUP_A).
45819
45853
  //This function was deferred so that it can be chained together with other deferred functions for
@@ -46814,7 +46848,7 @@ class OpmParser {
46814
46848
 
46815
46849
  async loadOpmData(data, pdbid, bFull, type, pdbid2) { let ic = this.icn3d, me = ic.icn3dui;
46816
46850
  try {
46817
- if(!pdbid) pdbid = 'stru';
46851
+ if(!pdbid) pdbid = ic.defaultPdbId;
46818
46852
  let url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&opm&uid=" + pdbid.toLowerCase();
46819
46853
 
46820
46854
  let opmdata = await me.getAjaxPromise(url, 'jsonp', false);
@@ -47019,20 +47053,22 @@ class PdbParser {
47019
47053
  if(me.cfg.opmid === undefined) ic.ParserUtilsCls.transformToOpmOri(pdbid);
47020
47054
 
47021
47055
  if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
47022
- $("#" + ic.pre + "assemblyWrapper").show();
47056
+ if(!me.bNode) $("#" + ic.pre + "assemblyWrapper").show();
47023
47057
 
47024
47058
  ic.asuCnt = ic.biomtMatrices.length;
47025
47059
  }
47026
47060
 
47027
- if(ic.emd !== undefined) {
47028
- $("#" + ic.pre + "mapWrapper1").hide();
47029
- $("#" + ic.pre + "mapWrapper2").hide();
47030
- $("#" + ic.pre + "mapWrapper3").hide();
47031
- }
47032
- else {
47033
- $("#" + ic.pre + "emmapWrapper1").hide();
47034
- $("#" + ic.pre + "emmapWrapper2").hide();
47035
- $("#" + ic.pre + "emmapWrapper3").hide();
47061
+ if(!me.bNode) {
47062
+ if(ic.emd !== undefined) {
47063
+ $("#" + ic.pre + "mapWrapper1").hide();
47064
+ $("#" + ic.pre + "mapWrapper2").hide();
47065
+ $("#" + ic.pre + "mapWrapper3").hide();
47066
+ }
47067
+ else {
47068
+ $("#" + ic.pre + "emmapWrapper1").hide();
47069
+ $("#" + ic.pre + "emmapWrapper2").hide();
47070
+ $("#" + ic.pre + "emmapWrapper3").hide();
47071
+ }
47036
47072
  }
47037
47073
 
47038
47074
  // calculate secondary structures if not available
@@ -47053,7 +47089,7 @@ class PdbParser {
47053
47089
  else {
47054
47090
  await this.loadPdbDataRender(bAppend);
47055
47091
 
47056
- await ic.ParserUtilsCls.checkMemProteinAndRotate();
47092
+ if(!me.bNode) await ic.ParserUtilsCls.checkMemProteinAndRotate();
47057
47093
 
47058
47094
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
47059
47095
  }
@@ -49701,7 +49737,7 @@ class ParserUtils {
49701
49737
 
49702
49738
  //var dxymax = npoint / 2.0 * step;
49703
49739
 
49704
- pdbid =(pdbid) ? pdbid.toUpperCase() : 'stru';
49740
+ pdbid =(pdbid) ? pdbid.toUpperCase() : ic.defaultPdbId;
49705
49741
 
49706
49742
  ic.structures[pdbid].push(pdbid + '_MEM');
49707
49743
  ic.chains[pdbid + '_MEM'] = {};
@@ -49943,7 +49979,7 @@ class ParserUtils {
49943
49979
  let afMemdata = await me.getAjaxPromise(url2, 'text');
49944
49980
 
49945
49981
  ic.bAfMem = true;
49946
- $("#" + me.pre + "togglememli").show(); // show the menu "View > Toggle Membrane"
49982
+ if(!me.bNode) $("#" + me.pre + "togglememli").show(); // show the menu "View > Toggle Membrane"
49947
49983
 
49948
49984
  // append the PDB
49949
49985
  let pdbid = data.pdbid.substr(0, data.pdbid.indexOf('_'));
@@ -52124,13 +52160,12 @@ class LoadPDB {
52124
52160
 
52125
52161
  //let chainMissingResidueArray = {}
52126
52162
 
52127
- let id = (pdbid) ? pdbid : 'stru';
52163
+ let id = (pdbid) ? pdbid : ic.defaultPdbId;
52164
+ let structure = id;
52128
52165
 
52129
52166
  let prevMissingChain = '';
52130
52167
  let CSerial, prevCSerial, OSerial, prevOSerial;
52131
-
52132
- let structure = "stru";
52133
-
52168
+
52134
52169
  let bHeader = false;
52135
52170
 
52136
52171
  for (let i in lines) {
@@ -52145,18 +52180,18 @@ class LoadPDB {
52145
52180
 
52146
52181
  if(id == '') {
52147
52182
  if(bAppend) {
52148
- id = "stru";
52183
+ id = ic.defaultPdbId;
52149
52184
  }
52150
52185
  else {
52151
- //if(!ic.inputid) ic.inputid = 'stru';
52152
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : "stru"; //ic.filename.substr(0, 4);
52186
+ //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
52187
+ id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
52153
52188
  }
52154
52189
  }
52155
52190
 
52156
52191
  structure = id;
52157
52192
 
52158
- if(id == 'stru' || bMutation) { // bMutation: side chain prediction
52159
- //if(id == 'stru') {
52193
+ if(id == ic.defaultPdbId || bMutation) { // bMutation: side chain prediction
52194
+ //if(id == ic.defaultPdbId) {
52160
52195
  structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
52161
52196
  }
52162
52197
 
@@ -52181,7 +52216,7 @@ class LoadPDB {
52181
52216
 
52182
52217
  if(j === startResi) helixStart.push(resid);
52183
52218
  if(j === endResi) helixEnd.push(resid);
52184
- }
52219
+ }
52185
52220
  } else if (record === 'SHEET ') {
52186
52221
  //ic.bSecondaryStructure = true;
52187
52222
  if(bOpm === undefined || !bOpm) ic.bSecondaryStructure = true;
@@ -52243,10 +52278,7 @@ class LoadPDB {
52243
52278
  //let chain = line.substr(19, 1);
52244
52279
  let chain = line.substr(18, 2).trim();
52245
52280
  //let resi = parseInt(line.substr(21, 5));
52246
- let resi = line.substr(21, 5);
52247
-
52248
- //var structure = parseInt(line.substr(13, 1));
52249
- //if(line.substr(13, 1) == ' ') structure = 1;
52281
+ let resi = line.substr(21, 5).trim();
52250
52282
 
52251
52283
  //var chainNum = structure + '_' + chain;
52252
52284
  let chainNum = id + '_' + chain;
@@ -52274,12 +52306,12 @@ class LoadPDB {
52274
52306
  ic.organism = ic.organism.substr(0, ic.organism.length - 1);
52275
52307
  } else if (record === 'ENDMDL') {
52276
52308
  ++moleculeNum;
52277
- id = 'stru';
52309
+ id = ic.defaultPdbId;
52278
52310
 
52279
52311
  structure = id;
52280
52312
 
52281
- if(id == 'stru' || bMutation) { // bMutation: side chain prediction
52282
- //if(id == 'stru') {
52313
+ if(id == ic.defaultPdbId || bMutation) { // bMutation: side chain prediction
52314
+ //if(id == ic.defaultPdbId) {
52283
52315
  structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
52284
52316
  }
52285
52317
 
@@ -52302,8 +52334,8 @@ class LoadPDB {
52302
52334
  } else if (record === 'ATOM ' || record === 'HETATM') {
52303
52335
  structure = id;
52304
52336
 
52305
- if(id == 'stru' || bMutation) { // bMutation: side chain prediction
52306
- //if(id == 'stru') {
52337
+ if(id == ic.defaultPdbId || bMutation) { // bMutation: side chain prediction
52338
+ //if(id == ic.defaultPdbId) {
52307
52339
  structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
52308
52340
  }
52309
52341
 
@@ -52718,73 +52750,81 @@ class LoadPDB {
52718
52750
  for(let chainNum in ic.chainsSeq) {
52719
52751
  if(chainMissingResidueArray[chainNum] === undefined) continue;
52720
52752
 
52721
- //let A = ic.chainsSeq[chainNum];
52722
- //let B = chainMissingResidueArray[chainNum];
52723
-
52724
- let A = chainMissingResidueArray[chainNum];
52725
- let B = ic.chainsSeq[chainNum];
52726
-
52727
- let m = A.length;
52728
- let n = B.length;
52729
-
52730
- let C = new Array(m + n);
52731
- //var C2 = new Array(m + n);
52732
- //var C3 = new Array(m + n);
52733
-
52734
- // http://www.algolist.net/Algorithms/Merge/Sorted_arrays
52735
- // m - size of A
52736
- // n - size of B
52737
- // size of C array must be equal or greater than m + n
52738
- let i, j, k;
52739
- i = 0;
52740
- j = 0;
52741
- k = 0;
52742
- while (i < m && j < n) {
52743
- if (parseInt(A[i].resi) <= parseInt(B[j].resi)) {
52744
- C[k] = A[i];
52745
- //C2[k] = A2[i];
52746
- //C3[k] = A3[i];
52747
- i++;
52748
- } else {
52749
- C[k] = B[j];
52750
- //if(B[j].resi % 10 === 0) {
52751
- // C2[k] = B[j].resi.toString();
52752
- //}
52753
- //else {
52754
- // C2[k] = '';
52755
- //}
52756
- //C3[k] = '-';
52757
- j++;
52753
+ ic.chainsSeq[chainNum] = this.mergeTwoSequences(chainMissingResidueArray[chainNum], ic.chainsSeq[chainNum]);
52754
+ }
52755
+
52756
+ this.setResidMapping();
52757
+ }
52758
+
52759
+ mergeTwoSequences(A, B) {
52760
+ let m = A.length; // missing residues
52761
+ let n = B.length; // residues with coord
52762
+
52763
+ // inserted domain such as PRK150 in the R chain of PDB 6WW2
52764
+ let lastResiA = parseInt(A[m - 1].resi);
52765
+ let lastResiB = parseInt(B[n - 1].resi);
52766
+ let lastResi = (lastResiA >= lastResiB) ? lastResiA : lastResiB;
52767
+
52768
+ let C = new Array(m + n);
52769
+ // http://www.algolist.net/Algorithms/Merge/Sorted_arrays
52770
+ // m - size of A
52771
+ // n - size of B
52772
+ // size of C array must be equal or greater than m + n
52773
+ let i = 0, j = 0, k = 0;
52774
+ let bInsertion = false;
52775
+
52776
+ while (i < m && j < n) {
52777
+ let aResi = parseInt(A[i].resi), bResi = parseInt(B[j].resi);
52778
+ if(aResi > lastResi && bResi > lastResi) bInsertion = true;
52779
+
52780
+ if(aResi <= lastResi && bResi > lastResi) {
52781
+ if (aResi > bResi || bInsertion) {
52782
+ C[k] = B[j];
52783
+ j++;
52758
52784
  }
52759
- k++;
52760
- }
52761
- if (i < m) {
52762
- for (let p = i; p < m; p++) {
52763
- C[k] = A[p];
52764
- //C2[k] = A2[p];
52765
- //C3[k] = A3[p];
52766
- k++;
52785
+ else {
52786
+ C[k] = A[i];
52787
+ i++;
52767
52788
  }
52768
- } else {
52769
- for (let p = j; p < n; p++) {
52770
- C[k] = B[p];
52771
- //if(B[p].resi % 10 === 0) {
52772
- // C2[k] = B[p].resi.toString();
52773
- //}
52774
- //else {
52775
- // C2[k] = '';
52776
- //}
52777
- //C3[k] = '-';
52778
- k++;
52789
+ }
52790
+ else if(aResi > lastResi && bResi <= lastResi) {
52791
+ if (aResi <= bResi || bInsertion) {
52792
+ C[k] = A[i];
52793
+ i++;
52779
52794
  }
52780
- }
52795
+ else {
52796
+ C[k] = B[j];
52797
+ j++;
52798
+ }
52799
+ }
52800
+ else {
52801
+ if (aResi <= bResi) {
52802
+ C[k] = A[i];
52803
+ i++;
52804
+ }
52805
+ else {
52806
+ C[k] = B[j];
52807
+ j++;
52808
+ }
52809
+ }
52781
52810
 
52782
- ic.chainsSeq[chainNum] = C;
52783
- //ic.chainsAn[chainNum][0] = C2;
52784
- //ic.chainsAn[chainNum][1] = C3;
52785
- }
52811
+ k++;
52812
+ }
52786
52813
 
52787
- this.setResidMapping();
52814
+ if (i < m) {
52815
+ for (let p = i; p < m; p++) {
52816
+ C[k] = A[p];
52817
+ k++;
52818
+ }
52819
+ }
52820
+ else {
52821
+ for (let p = j; p < n; p++) {
52822
+ C[k] = B[p];
52823
+ k++;
52824
+ }
52825
+ }
52826
+
52827
+ return C;
52788
52828
  }
52789
52829
 
52790
52830
  setResidMapping() { let ic = this.icn3d; ic.icn3dui;
@@ -54940,21 +54980,23 @@ class ApplyCommand {
54940
54980
  else if(command.indexOf('window') == 0) {
54941
54981
  let secondPart = command.substr(command.indexOf(' ') + 1);
54942
54982
 
54943
- if(secondPart == "aligned sequences") {
54983
+ setTimeout(function(){
54984
+ if(secondPart == "aligned sequences") {
54944
54985
  me.htmlCls.dialogCls.openDlg('dl_alignment', 'Select residues in aligned sequences');
54945
- }
54946
- else if(secondPart == "interaction table") {
54947
- me.htmlCls.dialogCls.openDlg('dl_allinteraction', 'Show interactions');
54948
- }
54949
- else if(secondPart == "interaction graph") {
54950
- me.htmlCls.dialogCls.openDlg('dl_linegraph', 'Show interactions between two lines of residue nodes');
54951
- }
54952
- else if(secondPart == "interaction scatterplot") {
54953
- me.htmlCls.dialogCls.openDlg('dl_scatterplot', 'Show interactions as scatterplot');
54954
- }
54955
- else if(secondPart == "force-directed graph") {
54956
- me.htmlCls.dialogCls.openDlg('dl_graph', 'Force-directed graph');
54957
- }
54986
+ }
54987
+ else if(secondPart == "interaction table") {
54988
+ me.htmlCls.dialogCls.openDlg('dl_allinteraction', 'Show interactions');
54989
+ }
54990
+ else if(secondPart == "interaction graph") {
54991
+ me.htmlCls.dialogCls.openDlg('dl_linegraph', 'Show interactions between two lines of residue nodes');
54992
+ }
54993
+ else if(secondPart == "interaction scatterplot") {
54994
+ me.htmlCls.dialogCls.openDlg('dl_scatterplot', 'Show interactions as scatterplot');
54995
+ }
54996
+ else if(secondPart == "force-directed graph") {
54997
+ me.htmlCls.dialogCls.openDlg('dl_graph', 'Force-directed graph');
54998
+ }
54999
+ }, 1000);
54958
55000
  }
54959
55001
  else if(command.indexOf('set theme') == 0) {
54960
55002
  let color = command.substr(command.lastIndexOf(' ') + 1);
@@ -56582,6 +56624,10 @@ class LoadScript {
56582
56624
 
56583
56625
  await ic.chainalignParserCls.downloadMmdbAf(id);
56584
56626
  }
56627
+ else if(command.indexOf('load gi') !== -1) {
56628
+ me.cfg.gi = id;
56629
+ await ic.mmdbParserCls.downloadGi(id);
56630
+ }
56585
56631
  else if(command.indexOf('load refseq') !== -1) {
56586
56632
  me.cfg.refseqid = id;
56587
56633
  await ic.mmdbParserCls.downloadRefseq(id);
@@ -59316,7 +59362,7 @@ class Dssp {
59316
59362
  async showIgRefNum() { let ic = this.icn3d, me = ic.icn3dui;
59317
59363
  let thisClass = this;
59318
59364
 
59319
- if(Object.keys(ic.resid2refnum).length > 0) {
59365
+ if(ic.resid2refnum && Object.keys(ic.resid2refnum).length > 0) {
59320
59366
  ic.bShowRefnum = true;
59321
59367
 
59322
59368
  // open sequence view
@@ -59363,16 +59409,17 @@ class Dssp {
59363
59409
  let ajaxArray = [];
59364
59410
  let domainidpairArray = [];
59365
59411
 
59366
- me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
59412
+ let urltmalign = me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
59367
59413
 
59368
59414
  ic.resid2domainid = {};
59369
59415
 
59370
59416
  for(let i = 0, il = struArray.length; i < il; ++i) {
59371
59417
  let struct = struArray[i];
59372
59418
  let chainidArray = ic.structures[struct];
59373
-
59419
+
59374
59420
  for(let j = 0, jl = chainidArray.length; j < jl; ++j) {
59375
59421
  let chainid = chainidArray[j];
59422
+
59376
59423
  if(!ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]).serial)) continue;
59377
59424
  if(ic.chainsSeq[chainid].length < 50) continue; // peptide
59378
59425
 
@@ -59407,20 +59454,19 @@ class Dssp {
59407
59454
  domainAtomsArray.push(domainAtoms);
59408
59455
  }
59409
59456
  }
59410
-
59457
+
59411
59458
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
59459
+
59412
59460
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
59413
59461
  let domainid = chainid + '-' + k;
59414
59462
  for(let index = 0, indexl = dataArray.length; index < indexl; ++index) {
59415
- let struct2 = "stru" + index;
59463
+ let struct2 = ic.defaultPdbId + index;
59416
59464
  let pdb_query = dataArray[index].value; //[0];
59417
-
59418
59465
  let header = 'HEADER ' + struct2 + '\n';
59419
59466
  pdb_query = header + pdb_query;
59420
59467
 
59421
59468
  let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbArray[index]};
59422
- let alignAjax = me.getAjaxPostPromise(url, dataObj);
59423
-
59469
+ let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
59424
59470
  ajaxArray.push(alignAjax);
59425
59471
 
59426
59472
  domainidpairArray.push(domainid + "," + index);
@@ -59431,18 +59477,19 @@ class Dssp {
59431
59477
 
59432
59478
  let allPromise = Promise.allSettled(ajaxArray);
59433
59479
  try {
59434
- let dataArray = await allPromise;
59435
- await thisClass.parseAlignData(dataArray, domainidpairArray);
59480
+ let dataArray2 = await allPromise;
59481
+
59482
+ await thisClass.parseAlignData(dataArray2, domainidpairArray);
59436
59483
 
59437
59484
  /// if(ic.deferredRefnum !== undefined) ic.deferredRefnum.resolve();
59438
59485
  }
59439
59486
  catch(err) {
59440
- console.log("Error in aligning with TM-align...");
59487
+ if(!me.bNode) console.log("Error in aligning with TM-align...");
59441
59488
  return;
59442
59489
  }
59443
59490
  }
59444
59491
 
59445
- async parseAlignData(dataArray, domainidpairArray) { let ic = this.icn3d; ic.icn3dui;
59492
+ async parseAlignData(dataArray, domainidpairArray) { let ic = this.icn3d, me = ic.icn3dui;
59446
59493
  let thisClass = this;
59447
59494
 
59448
59495
  let tmscoreThreshold = 0.4; //0.5;
@@ -59451,9 +59498,12 @@ class Dssp {
59451
59498
  let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
59452
59499
  ic.chainid2index = {};
59453
59500
  ic.domainid2ig2kabat = {};
59501
+
59454
59502
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
59455
59503
  let queryData = dataArray[i].value; //[0];
59504
+
59456
59505
  if(queryData.length == 0) continue;
59506
+
59457
59507
  if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < 50) continue;
59458
59508
 
59459
59509
  let domainid_index = domainidpairArray[i].split(',');
@@ -59465,6 +59515,7 @@ class Dssp {
59465
59515
  let bBstrand = false, bCstrand = false, bEstrand = false, bFstrand = false;
59466
59516
  for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
59467
59517
  let seg = queryData[0].segs[i];
59518
+
59468
59519
  if(seg.q_start.indexOf('2050') != -1) {
59469
59520
  bBstrand = true;
59470
59521
  }
@@ -59484,12 +59535,13 @@ class Dssp {
59484
59535
  //if(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand) break;
59485
59536
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
59486
59537
  }
59538
+
59487
59539
  //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
59488
59540
  if(!(bBstrand && bCstrand && bEstrand && bFstrand)) continue;
59489
59541
 
59490
59542
  if(!domainid2score.hasOwnProperty(domainid) || queryData[0].score > domainid2score[domainid]) {
59491
59543
  domainid2score[domainid] = queryData[0].score;
59492
- console.log(domainid + ' TM-score: ' + domainid2score[domainid] + ' matched ' + ic.refpdbArray[domainid_index[1]]);
59544
+ if(!me.bNode) console.log(domainid + ' TM-score: ' + domainid2score[domainid] + ' matched ' + ic.refpdbArray[domainid_index[1]]);
59493
59545
  ic.chainid2index[chainid] = domainid_index[1]; // could be several, just take the recent one for simplicity
59494
59546
  domainid2segs[domainid] = queryData[0].segs;
59495
59547
  ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
@@ -59509,7 +59561,7 @@ console.log(domainid + ' TM-score: ' + domainid2score[domainid] + ' matched ' +
59509
59561
  if(!ic.chainsMapping) ic.chainsMapping = {};
59510
59562
  for(let chainid in chainid2segs) {
59511
59563
  let segArray = chainid2segs[chainid];
59512
- console.log("One of the reference PDBs for chain chainid: " + ic.refpdbArray[ic.chainid2index[chainid]]);
59564
+ if(!me.bNode) console.log("One of the reference PDBs for chain chainid: " + ic.refpdbArray[ic.chainid2index[chainid]]);
59513
59565
 
59514
59566
  for(let i = 0, il = segArray.length; i < il; ++i) {
59515
59567
  let seg = segArray[i];
@@ -64161,13 +64213,23 @@ class SaveFile {
64161
64213
  setStructureTitle(url, title, titlelinkColor) {var ic = this.icn3d, me = ic.icn3dui;
64162
64214
  if(ic.molTitle.length > 40) title = ic.molTitle.substr(0, 40) + "...";
64163
64215
 
64164
- //var asymmetricStr =(ic.bAssemblyUseAsu) ? "(Asymmetric Unit)" : "";
64165
- let asymmetricStr = "";
64216
+ let text = ic.inputid.toUpperCase();
64166
64217
 
64167
64218
  let idName = (isNaN(ic.inputid) && ic.inputid.length > 5) ? "AlphaFold ID" : "PDB ID";
64219
+ if(ic.inputid.indexOf('http') != -1) {
64220
+ idName = "Data from";
64221
+ url = ic.inputid;
64222
+ text = ic.inputid;
64223
+ }
64224
+
64168
64225
  if(me.cfg.refseqid) idName = 'NCBI Protein Acc.';
64169
64226
 
64170
- $("#" + ic.pre + "title").html(idName + " <a id='" + ic.pre + "titlelink' href='" + url + "' style='color:" + titlelinkColor + "' target='_blank'>" + ic.inputid.toUpperCase() + "</a>" + asymmetricStr + ": " + title);
64227
+ if(!ic.inputid || ic.inputid.substr(0, 4) == ic.defaultPdbId) {
64228
+ $("#" + ic.pre + "title").html(title);
64229
+ }
64230
+ else {
64231
+ $("#" + ic.pre + "title").html(idName + " <a id='" + ic.pre + "titlelink' href='" + url + "' style='color:" + titlelinkColor + "' target='_blank'>" + text + "</a>: " + title);
64232
+ }
64171
64233
  }
64172
64234
 
64173
64235
  getLinkToStructureSummary(bLog) {var ic = this.icn3d, me = ic.icn3dui;
@@ -64253,7 +64315,7 @@ class ShareLink {
64253
64315
  if(bPngHtml) url += "&random=" + parseInt(Math.random() * 1000); // generate a new shorten URL and thus image name everytime
64254
64316
  //var inputid =(ic.inputid) ? ic.inputid : "custom";
64255
64317
  let inputid = Object.keys(ic.structures).join('_');
64256
- if(inputid == 'stru') {
64318
+ if(inputid == ic.defaultPdbId) {
64257
64319
  if(ic.filename) {
64258
64320
  inputid = ic.filename;
64259
64321
  }
@@ -66805,6 +66867,7 @@ class iCn3D {
66805
66867
  this.transparentRenderOrder = false; // false: regular transparency; true: expensive renderOrder for each face
66806
66868
 
66807
66869
  this.AFUniprotVersion = 'v4';
66870
+ this.defaultPdbId = 'stru';
66808
66871
 
66809
66872
  if(!this.icn3dui.bNode) {
66810
66873
  if ( bWebGL2 && bVR) {
@@ -67388,7 +67451,7 @@ class iCn3DUI {
67388
67451
  //even when multiple iCn3D viewers are shown together.
67389
67452
  this.pre = this.cfg.divid + "_";
67390
67453
 
67391
- this.REVISION = '3.21.0';
67454
+ this.REVISION = '3.21.3';
67392
67455
 
67393
67456
  // In nodejs, iCn3D defines "window = {navigator: {}}"
67394
67457
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -67665,6 +67728,12 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
67665
67728
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
67666
67729
  await ic.mmdbParserCls.downloadMmdb(me.cfg.mmdbid);
67667
67730
  }
67731
+ else if(me.cfg.gi !== undefined) {
67732
+ // ic.bNCBI = true;
67733
+ ic.loadCmd = 'load gi ' + me.cfg.gi;
67734
+ me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
67735
+ await ic.mmdbParserCls.downloadGi(me.cfg.gi);
67736
+ }
67668
67737
  else if(me.cfg.refseqid !== undefined) {
67669
67738
  ic.inputid = me.cfg.refseqid;
67670
67739
 
@@ -67853,7 +67922,7 @@ iCn3DUI.prototype.getAjaxPromise = function(url, dataType, beforeSend, alertMess
67853
67922
  if(beforeSend) me.icn3d.ParserUtilsCls.showLoading();
67854
67923
  },
67855
67924
  complete: function() {
67856
- if(complete) ic.ParserUtilsCls.hideLoading();
67925
+ if(complete) me.icn3d.ParserUtilsCls.hideLoading();
67857
67926
  },
67858
67927
  success: function(data) {
67859
67928
  resolve(data);
@@ -67882,7 +67951,7 @@ iCn3DUI.prototype.getAjaxPostPromise = function(url, data, beforeSend, alertMess
67882
67951
  if(beforeSend) me.icn3d.ParserUtilsCls.showLoading();
67883
67952
  },
67884
67953
  complete: function() {
67885
- if(complete) ic.ParserUtilsCls.hideLoading();
67954
+ if(complete) me.icn3d.ParserUtilsCls.hideLoading();
67886
67955
  },
67887
67956
  success: function(data) {
67888
67957
  resolve(data);