icn3d 3.25.21 → 3.26.1

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
@@ -5924,6 +5924,10 @@ class ClickMenu {
5924
5924
  me.htmlCls.dialogCls.openDlg('dl_blast_rep_id', 'Align sequence to structure');
5925
5925
  });
5926
5926
 
5927
+ me.myEventCls.onIds("#" + me.pre + "mn1_esmfold", "click", function(e) { me.icn3d; //e.preventDefault();
5928
+ me.htmlCls.dialogCls.openDlg('dl_esmfold', 'Sequence to structure prediction with ESMFold');
5929
+ });
5930
+
5927
5931
  me.myEventCls.onIds("#" + me.pre + "mn1_gi", "click", function(e) { me.icn3d; //e.preventDefault();
5928
5932
  me.htmlCls.dialogCls.openDlg('dl_gi', 'Please input protein gi');
5929
5933
  });
@@ -5977,7 +5981,7 @@ class ClickMenu {
5977
5981
 
5978
5982
  me.myEventCls.onIds("#" + me.pre + "mn1_exportState", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
5979
5983
  thisClass.setLogCmd("export state file", false);
5980
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
5984
+ let file_pref = Object.keys(ic.structures).join(',');
5981
5985
 
5982
5986
  ic.saveFileCls.saveFile(file_pref + '_statefile.txt', 'command');
5983
5987
  });
@@ -5999,8 +6003,8 @@ class ClickMenu {
5999
6003
  let pdbStr = ic.saveFileCls.getSelectedResiduePDB();
6000
6004
 
6001
6005
  thisClass.setLogCmd("export PDB of selected residues", false);
6002
- //let file_pref =(ic.inputid) ? ic.inputid : "custom";
6003
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
6006
+ //let file_pref = Object.keys(ic.structures).join(',');
6007
+ let file_pref = Object.keys(ic.structures).join(',');
6004
6008
  ic.saveFileCls.saveFile(file_pref + '_icn3d_residues.pdb', 'text', [pdbStr]);
6005
6009
  });
6006
6010
 
@@ -6116,7 +6120,7 @@ class ClickMenu {
6116
6120
  text += '<tr><td>' + structure + '</td><td>' + chain + '</td><td>' + Object.keys(residueHash).length + '</td><td>' + Object.keys(ic.chains[chainid]).length + '</td></tr>';
6117
6121
  }
6118
6122
  text += '</table><br/></div></body></html>';
6119
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
6123
+ let file_pref = Object.keys(ic.structures).join(',');
6120
6124
  ic.saveFileCls.saveFile(file_pref + '_counts.html', 'html', text);
6121
6125
  });
6122
6126
 
@@ -6126,7 +6130,7 @@ class ClickMenu {
6126
6130
  thisClass.SetChainsAdvancedMenu();
6127
6131
 
6128
6132
  let text = ic.saveFileCls.exportCustomAtoms();
6129
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
6133
+ let file_pref = Object.keys(ic.structures).join(',');
6130
6134
  ic.saveFileCls.saveFile(file_pref + '_selections.txt', 'text', [text]);
6131
6135
  });
6132
6136
 
@@ -6137,7 +6141,7 @@ class ClickMenu {
6137
6141
 
6138
6142
  let bDetails = true;
6139
6143
  let text = ic.saveFileCls.exportCustomAtoms(bDetails);
6140
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
6144
+ let file_pref = Object.keys(ic.structures).join(',');
6141
6145
  ic.saveFileCls.saveFile(file_pref + '_sel_details.txt', 'text', [text]);
6142
6146
  });
6143
6147
 
@@ -6258,6 +6262,11 @@ class ClickMenu {
6258
6262
  window.open(url, urlTarget);
6259
6263
  });
6260
6264
 
6265
+ me.myEventCls.onIds("#" + me.pre + "mn1_alphafold", "click", function(e) { me.icn3d; //e.preventDefault();
6266
+ let url = 'https://github.com/sokrypton/ColabFold';
6267
+ window.open(url, '_blank');
6268
+ });
6269
+
6261
6270
  me.myEventCls.onIds("#" + me.pre + "mn1_link_bind", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
6262
6271
  let url = "https://www.ncbi.nlm.nih.gov/pccompound?LinkName=pccompound_structure&from_uid=" + ic.inputid;
6263
6272
  thisClass.setLogCmd("link to 3D protein structures bound to CID " + ic.inputid + ": " + url, false);
@@ -8496,6 +8505,14 @@ class SetMenu {
8496
8505
  html += "</ul>";
8497
8506
  html += "</li>";
8498
8507
 
8508
+ html += this.getMenuText('mn1_fold', 'AlphaFold/ESM', undefined, undefined, 1);
8509
+ html += "<ul>";
8510
+ html += this.getLink('mn1_alphafold', 'AlphaFold2 via ColabFold', undefined, 2);
8511
+ html += this.getLink('mn1_esmfold', 'ESMFold', undefined, 2);
8512
+ html += "</ul>";
8513
+
8514
+
8515
+
8499
8516
  html += this.getMenuText('mn1_alignwrap', 'Align', undefined, 1, 1);
8500
8517
  html += "<ul>";
8501
8518
 
@@ -10830,6 +10847,13 @@ class SetDialog {
10830
10847
  + me.htmlCls.buttonStr + "reload_alignswlocal' style='margin-left:30px'>Align with Local Smith-Waterman</button>";
10831
10848
  html += "</div>";
10832
10849
 
10850
+ html += me.htmlCls.divStr + "dl_esmfold' style='max-width:600px;' class='" + dialogClass + "'>";
10851
+ html += this.addNotebookTitle('dl_esmfold', 'Sequence to structure prediction with ESMFold');
10852
+ html += "The sequence to structure prediction is done via <a href='https://esmatlas.com/resources?action=fold' target='_blank'>ESM Metagenomic Atlas</a>. Generally the sequence should be less than 1024 characters. For any seqeunce longer than 1024, please see the discussion <a href='https://github.com/facebookresearch/esm/issues/21' target='_blank'>here</a>.<br><br> ";
10853
+ html += "FASTA sequence: <br><textarea id='" + me.pre + "esmfold_fasta' rows='5' style='width: 100%; height: " +(me.htmlCls.LOG_HEIGHT) + "px; padding: 0px; border: 0px;'></textarea><br><br>";
10854
+ html += me.htmlCls.buttonStr + "run_esmfold'>ESMFold</button> ";
10855
+ html += "</div>";
10856
+
10833
10857
  html += me.htmlCls.divStr + "dl_yournote' class='" + dialogClass + "'>";
10834
10858
  html += this.addNotebookTitle('dl_yournote', 'Your Note');
10835
10859
  html += "Your note will be saved in the HTML file when you click \"File > Save File > iCn3D PNG Image\".<br><br>";
@@ -12821,6 +12845,44 @@ class Events {
12821
12845
  + blast_rep_id + '; show selection', urlTarget);
12822
12846
  });
12823
12847
 
12848
+ me.myEventCls.onIds("#" + me.pre + "run_esmfold", "click", async function(e) { let ic = me.icn3d;
12849
+ e.preventDefault();
12850
+ if(!me.cfg.notebook) dialog.dialog( "close" );
12851
+
12852
+ if($('#' + me.pre + 'dl_mmdbafid').hasClass('ui-dialog-content')) {
12853
+ $('#' + me.pre + 'dl_mmdbafid').dialog( 'close' );
12854
+ }
12855
+
12856
+ let esmfold_fasta = $("#" + me.pre + "esmfold_fasta").val();
12857
+ let pdbid;
12858
+
12859
+ if(esmfold_fasta.indexOf('>') != -1) { //FASTA with header
12860
+ let pos = esmfold_fasta.indexOf('\n');
12861
+ ic.esmTitle = esmfold_fasta.substr(1, pos - 1).trim();
12862
+ pdbid = ic.esmTitle.substr(0, ic.esmTitle.indexOf(' '));
12863
+ if(pdbid.length < 6) pdbid = pdbid.padEnd(6, '-');
12864
+
12865
+ esmfold_fasta = esmfold_fasta.substr(pos + 1);
12866
+ }
12867
+
12868
+ // remove new lines
12869
+ esmfold_fasta = esmfold_fasta.replace(/\s/g, '');
12870
+
12871
+ if(esmfold_fasta.length > 1024) {
12872
+ var aaa = 1; //alert("Your seqeunce is larger than 1024 characters. Please consider to split it as described at https://github.com/facebookresearch/esm/issues/21.");
12873
+ return;
12874
+ }
12875
+
12876
+ let esmUrl = "https://api.esmatlas.com/foldSequence/v1/pdb/";
12877
+ let alertMess = 'Problem in returning PDB from ESMFold server...';
12878
+ thisClass.setLogCmd("Run ESMFold with the sequence " + esmfold_fasta, false);
12879
+
12880
+ let esmData = await me.getAjaxPostPromise(esmUrl, esmfold_fasta, true, alertMess, undefined, true, 'text');
12881
+ ic.bEsmfold = true;
12882
+ let bAppend = true;
12883
+ await ic.pdbParserCls.loadPdbData(esmData, pdbid, undefined, bAppend, undefined, undefined, undefined, ic.bEsmfold);
12884
+ });
12885
+
12824
12886
  me.myEventCls.onIds("#" + me.pre + "reload_alignsw", "click", function(e) { let ic = me.icn3d;
12825
12887
  e.preventDefault();
12826
12888
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -34872,7 +34934,7 @@ class SetColor {
34872
34934
  }
34873
34935
  else {
34874
34936
  let b = atom.b;
34875
-
34937
+
34876
34938
  // PDB
34877
34939
  b = (atom.structure.substr(0, 4) != ic.defaultPdbId && atom.structure.length < 6) ? 100 - b : b;
34878
34940
 
@@ -35402,7 +35464,7 @@ class SetOption {
35402
35464
 
35403
35465
  let colorLabel = colorType.substr(0, 1).toUpperCase() + colorType.substr(1);
35404
35466
  if(colorType == 'confidence') {
35405
- colorLabel = 'AlphaFold Confidence';
35467
+ colorLabel = 'AlphaFold Confidence (pLDDT)';
35406
35468
  }
35407
35469
  else if(colorType == 'normalized hydrophobic') {
35408
35470
  colorLabel = 'Normalized Hydrophobicity';
@@ -44671,7 +44733,8 @@ class LineGraph {
44671
44733
  for(let i = 0, il = ic.chainid2refpdbname[chainid].length; i < il; ++i) {
44672
44734
  chainList += ic.chainid2refpdbname[chainid][i] + " ";
44673
44735
  }
44674
- if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
44736
+ //if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
44737
+ console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
44675
44738
 
44676
44739
  let prevStrand;
44677
44740
  let bCd19 = ic.chainid2refpdbname[chainid].length == 1 && ic.chainid2refpdbname[chainid][0] == 'CD19_6al5A_human_C2orV-n1';
@@ -50403,14 +50466,14 @@ class PdbParser {
50403
50466
 
50404
50467
  //Atom "data" from PDB file was parsed to set up parameters for the 3D viewer. The deferred parameter
50405
50468
  //was resolved after the parsing so that other javascript code can be executed.
50406
- async loadPdbData(data, pdbid, bOpm, bAppend, type, bLastQuery, bNoDssp) { let ic = this.icn3d, me = ic.icn3dui;
50469
+ async loadPdbData(data, pdbid, bOpm, bAppend, type, bLastQuery, bNoDssp, bEsmfold) { let ic = this.icn3d, me = ic.icn3dui;
50407
50470
  if(!bAppend && (type === undefined || type === 'target')) {
50408
50471
  // if a command contains "load...", the commands should not be cleared with init()
50409
50472
  let bKeepCmd = (ic.bCommandLoad) ? true : false;
50410
50473
  if(!ic.bStatefile) ic.init(bKeepCmd);
50411
50474
  }
50412
50475
 
50413
- let hAtoms = ic.loadPDBCls.loadPDB(data, pdbid, bOpm, undefined, undefined, bAppend, type, bLastQuery); // defined in the core library
50476
+ let hAtoms = ic.loadPDBCls.loadPDB(data, pdbid, bOpm, undefined, undefined, bAppend, type, bEsmfold); // defined in the core library
50414
50477
 
50415
50478
  if(me.cfg.opmid === undefined) ic.ParserUtilsCls.transformToOpmOri(pdbid);
50416
50479
 
@@ -50480,7 +50543,7 @@ class PdbParser {
50480
50543
  }
50481
50544
 
50482
50545
  //if(me.cfg.afid && !ic.bAfMem && !me.cfg.blast_rep_id) {
50483
- if(me.cfg.afid && !ic.bAfMem) {
50546
+ if( (me.cfg.afid && !ic.bAfMem) || ic.bEsmfold) {
50484
50547
  ic.opts['color'] = 'confidence';
50485
50548
  }
50486
50549
 
@@ -53717,6 +53780,11 @@ class LoadAtomData {
53717
53780
  }
53718
53781
  }
53719
53782
  }
53783
+
53784
+ if(type === 'mmdbid') {
53785
+ if(!ic.molTitleHash) ic.molTitleHash = {};
53786
+ ic.molTitleHash[id] = ic.molTitle;
53787
+ }
53720
53788
 
53721
53789
  let atomid2serial = {};
53722
53790
  let prevStructureNum = '', prevChainNum = '', prevResidueNum = '';
@@ -55683,7 +55751,7 @@ class LoadPDB {
55683
55751
 
55684
55752
  // modified from iview (http://istar.cse.cuhk.edu.hk/iview/)
55685
55753
  //This PDB parser feeds the viewer with the content of a PDB file, pdbData.
55686
- loadPDB(src, pdbid, bOpm, bVector, bMutation, bAppend, type, bLastQuery) { let ic = this.icn3d, me = ic.icn3dui;
55754
+ loadPDB(src, pdbid, bOpm, bVector, bMutation, bAppend, type, bEsmfold) { let ic = this.icn3d, me = ic.icn3dui;
55687
55755
  let hAtoms = {};
55688
55756
 
55689
55757
  let bNMR = false;
@@ -55773,8 +55841,10 @@ class LoadPDB {
55773
55841
  } else if (record === 'TITLE ') {
55774
55842
  let name = line.substr(10).replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
55775
55843
  ic.molTitle += name.trim() + " ";
55844
+ if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
55845
+
55776
55846
  if(!ic.molTitleHash) ic.molTitleHash = {};
55777
- ic.molTitleHash[structure] = name.trim() + " ";
55847
+ ic.molTitleHash[structure] = ic.molTitle;
55778
55848
 
55779
55849
  } else if (record === 'HELIX ') {
55780
55850
  ic.bSecondaryStructure = true;
@@ -55951,6 +56021,9 @@ class LoadPDB {
55951
56021
  let z = parseFloat(line.substr(46, 8));
55952
56022
  let coord = new THREE.Vector3(x, y, z);
55953
56023
 
56024
+ let bFactor = parseFloat(line.substr(60, 8));
56025
+ if(bEsmfold) bFactor *= 100;
56026
+
55954
56027
  let atomDetails = {
55955
56028
  het: record[0] === 'H', // optional, used to determine chemicals, water, ions, etc
55956
56029
  serial: serial, // required, unique atom id
@@ -55962,7 +56035,7 @@ class LoadPDB {
55962
56035
  resi: resi, // optional, used to identify residue ID
55963
56036
  //insc: line.substr(26, 1),
55964
56037
  coord: coord, // required, used to draw 3D shape
55965
- b: parseFloat(line.substr(60, 8)), // optional, used to draw B-factor tube
56038
+ b: bFactor, // optional, used to draw B-factor tube
55966
56039
  elem: elem, // optional, used to determine hydrogen bond
55967
56040
  bonds: [], // required, used to connect atoms
55968
56041
  ss: 'coil', // optional, used to show secondary structures
@@ -67762,8 +67835,13 @@ class SaveFile {
67762
67835
  if(structureidArray.length > 1) {
67763
67836
  idName += 's';
67764
67837
  }
67765
- else if(ic.molTitleHash) {
67766
- title = ic.molTitleHash[inputid];
67838
+
67839
+ if(ic.molTitleHash) {
67840
+ title = '';
67841
+ for(let i = 0, il = structureidArray.length; i < il; ++i) {
67842
+ title += ic.molTitleHash[structureidArray[i]];
67843
+ if(i < il - 1) title += '; ';
67844
+ }
67767
67845
  }
67768
67846
  }
67769
67847
 
@@ -68168,7 +68246,7 @@ class ShareLink {
68168
68246
  outputCmd = tmpUrl;
68169
68247
 
68170
68248
  statefile = statefile.replace(/!/g, Object.keys(ic.structures)[0] + '_');
68171
- if((ic.bInputfile && !ic.bInputUrlfile) || (ic.bInputUrlfile && ic.bAppend) || url.length > 4000) url = statefile;
68249
+ if(ic.bEsmfold || (ic.bInputfile && !ic.bInputUrlfile) || (ic.bInputUrlfile && ic.bAppend) || url.length > 4000) url = statefile;
68172
68250
  let id;
68173
68251
  if(ic.structures !== undefined && Object.keys(ic.structures).length == 1 && ic.inputid !== undefined) {
68174
68252
  id = Object.keys(ic.structures)[0];
@@ -71003,7 +71081,7 @@ iCn3D.prototype.resetConfig = function () { let ic = this, me = ic.icn3dui;
71003
71081
  this.opts['chemicals'] = 'ball and stick';
71004
71082
  }
71005
71083
 
71006
- if(me.cfg.afid !== undefined) {
71084
+ if(me.cfg.afid !== undefined || ic.bEsmfold) {
71007
71085
  this.opts['color'] = 'confidence';
71008
71086
  }
71009
71087
 
@@ -71039,7 +71117,7 @@ class iCn3DUI {
71039
71117
  //even when multiple iCn3D viewers are shown together.
71040
71118
  this.pre = this.cfg.divid + "_";
71041
71119
 
71042
- this.REVISION = '3.25.4';
71120
+ this.REVISION = '3.26.0';
71043
71121
 
71044
71122
  // In nodejs, iCn3D defines "window = {navigator: {}}"
71045
71123
  this.bNode = (Object.keys(window).length < 2) ? true : false;