icn3d 3.25.21 → 3.26.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.module.js CHANGED
@@ -6825,6 +6825,10 @@ class ClickMenu {
6825
6825
  me.htmlCls.dialogCls.openDlg('dl_blast_rep_id', 'Align sequence to structure');
6826
6826
  });
6827
6827
 
6828
+ me.myEventCls.onIds("#" + me.pre + "mn1_esmfold", "click", function(e) { me.icn3d; //e.preventDefault();
6829
+ me.htmlCls.dialogCls.openDlg('dl_esmfold', 'Sequence to structure prediction with ESMFold');
6830
+ });
6831
+
6828
6832
  me.myEventCls.onIds("#" + me.pre + "mn1_gi", "click", function(e) { me.icn3d; //e.preventDefault();
6829
6833
  me.htmlCls.dialogCls.openDlg('dl_gi', 'Please input protein gi');
6830
6834
  });
@@ -6878,7 +6882,7 @@ class ClickMenu {
6878
6882
 
6879
6883
  me.myEventCls.onIds("#" + me.pre + "mn1_exportState", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
6880
6884
  thisClass.setLogCmd("export state file", false);
6881
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
6885
+ let file_pref = Object.keys(ic.structures).join(',');
6882
6886
 
6883
6887
  ic.saveFileCls.saveFile(file_pref + '_statefile.txt', 'command');
6884
6888
  });
@@ -6900,8 +6904,8 @@ class ClickMenu {
6900
6904
  let pdbStr = ic.saveFileCls.getSelectedResiduePDB();
6901
6905
 
6902
6906
  thisClass.setLogCmd("export PDB of selected residues", false);
6903
- //let file_pref =(ic.inputid) ? ic.inputid : "custom";
6904
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
6907
+ //let file_pref = Object.keys(ic.structures).join(',');
6908
+ let file_pref = Object.keys(ic.structures).join(',');
6905
6909
  ic.saveFileCls.saveFile(file_pref + '_icn3d_residues.pdb', 'text', [pdbStr]);
6906
6910
  });
6907
6911
 
@@ -7017,7 +7021,7 @@ class ClickMenu {
7017
7021
  text += '<tr><td>' + structure + '</td><td>' + chain + '</td><td>' + Object.keys(residueHash).length + '</td><td>' + Object.keys(ic.chains[chainid]).length + '</td></tr>';
7018
7022
  }
7019
7023
  text += '</table><br/></div></body></html>';
7020
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
7024
+ let file_pref = Object.keys(ic.structures).join(',');
7021
7025
  ic.saveFileCls.saveFile(file_pref + '_counts.html', 'html', text);
7022
7026
  });
7023
7027
 
@@ -7027,7 +7031,7 @@ class ClickMenu {
7027
7031
  thisClass.SetChainsAdvancedMenu();
7028
7032
 
7029
7033
  let text = ic.saveFileCls.exportCustomAtoms();
7030
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
7034
+ let file_pref = Object.keys(ic.structures).join(',');
7031
7035
  ic.saveFileCls.saveFile(file_pref + '_selections.txt', 'text', [text]);
7032
7036
  });
7033
7037
 
@@ -7038,7 +7042,7 @@ class ClickMenu {
7038
7042
 
7039
7043
  let bDetails = true;
7040
7044
  let text = ic.saveFileCls.exportCustomAtoms(bDetails);
7041
- let file_pref = Object.keys(me.utilsCls.getHlStructures()).join(',');
7045
+ let file_pref = Object.keys(ic.structures).join(',');
7042
7046
  ic.saveFileCls.saveFile(file_pref + '_sel_details.txt', 'text', [text]);
7043
7047
  });
7044
7048
 
@@ -7159,6 +7163,11 @@ class ClickMenu {
7159
7163
  window.open(url, urlTarget);
7160
7164
  });
7161
7165
 
7166
+ me.myEventCls.onIds("#" + me.pre + "mn1_alphafold", "click", function(e) { me.icn3d; //e.preventDefault();
7167
+ let url = 'https://github.com/sokrypton/ColabFold';
7168
+ window.open(url, '_blank');
7169
+ });
7170
+
7162
7171
  me.myEventCls.onIds("#" + me.pre + "mn1_link_bind", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
7163
7172
  let url = "https://www.ncbi.nlm.nih.gov/pccompound?LinkName=pccompound_structure&from_uid=" + ic.inputid;
7164
7173
  thisClass.setLogCmd("link to 3D protein structures bound to CID " + ic.inputid + ": " + url, false);
@@ -9397,6 +9406,14 @@ class SetMenu {
9397
9406
  html += "</ul>";
9398
9407
  html += "</li>";
9399
9408
 
9409
+ html += this.getMenuText('mn1_fold', 'AlphaFold/ESM', undefined, undefined, 1);
9410
+ html += "<ul>";
9411
+ html += this.getLink('mn1_alphafold', 'AlphaFold2 via ColabFold', undefined, 2);
9412
+ html += this.getLink('mn1_esmfold', 'ESMFold', undefined, 2);
9413
+ html += "</ul>";
9414
+
9415
+
9416
+
9400
9417
  html += this.getMenuText('mn1_alignwrap', 'Align', undefined, 1, 1);
9401
9418
  html += "<ul>";
9402
9419
 
@@ -11731,6 +11748,13 @@ class SetDialog {
11731
11748
  + me.htmlCls.buttonStr + "reload_alignswlocal' style='margin-left:30px'>Align with Local Smith-Waterman</button>";
11732
11749
  html += "</div>";
11733
11750
 
11751
+ html += me.htmlCls.divStr + "dl_esmfold' style='max-width:600px;' class='" + dialogClass + "'>";
11752
+ html += this.addNotebookTitle('dl_esmfold', 'Sequence to structure prediction with ESMFold');
11753
+ 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> ";
11754
+ 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>";
11755
+ html += me.htmlCls.buttonStr + "run_esmfold'>ESMFold</button> ";
11756
+ html += "</div>";
11757
+
11734
11758
  html += me.htmlCls.divStr + "dl_yournote' class='" + dialogClass + "'>";
11735
11759
  html += this.addNotebookTitle('dl_yournote', 'Your Note');
11736
11760
  html += "Your note will be saved in the HTML file when you click \"File > Save File > iCn3D PNG Image\".<br><br>";
@@ -13722,6 +13746,44 @@ class Events {
13722
13746
  + blast_rep_id + '; show selection', urlTarget);
13723
13747
  });
13724
13748
 
13749
+ me.myEventCls.onIds("#" + me.pre + "run_esmfold", "click", async function(e) { let ic = me.icn3d;
13750
+ e.preventDefault();
13751
+ if(!me.cfg.notebook) dialog.dialog( "close" );
13752
+
13753
+ if($('#' + me.pre + 'dl_mmdbafid').hasClass('ui-dialog-content')) {
13754
+ $('#' + me.pre + 'dl_mmdbafid').dialog( 'close' );
13755
+ }
13756
+
13757
+ let esmfold_fasta = $("#" + me.pre + "esmfold_fasta").val();
13758
+ let pdbid;
13759
+
13760
+ if(esmfold_fasta.indexOf('>') != -1) { //FASTA with header
13761
+ let pos = esmfold_fasta.indexOf('\n');
13762
+ ic.esmTitle = esmfold_fasta.substr(1, pos - 1);
13763
+ pdbid = ic.esmTitle.substr(0, ic.esmTitle.indexOf(' '));
13764
+ if(pdbid.length < 6) pdbid = pdbid.padEnd(6, '-');
13765
+
13766
+ esmfold_fasta = esmfold_fasta.substr(pos + 1);
13767
+ }
13768
+
13769
+ // remove new lines
13770
+ esmfold_fasta = esmfold_fasta.replace(/\s/g, '');
13771
+
13772
+ if(esmfold_fasta.length > 1024) {
13773
+ alert("Your seqeunce is larger than 1024 characters. Please consider to split it as described at https://github.com/facebookresearch/esm/issues/21.");
13774
+ return;
13775
+ }
13776
+
13777
+ let esmUrl = "https://api.esmatlas.com/foldSequence/v1/pdb/";
13778
+ let alertMess = 'Problem in returning PDB from ESMFold server...';
13779
+ thisClass.setLogCmd("Run ESMFold with the sequence " + esmfold_fasta, false);
13780
+
13781
+ let esmData = await me.getAjaxPostPromise(esmUrl, esmfold_fasta, true, alertMess, undefined, true, 'text');
13782
+ ic.bEsmfold = true;
13783
+ let bAppend = true;
13784
+ await ic.pdbParserCls.loadPdbData(esmData, pdbid, undefined, bAppend, undefined, undefined, undefined, ic.bEsmfold);
13785
+ });
13786
+
13725
13787
  me.myEventCls.onIds("#" + me.pre + "reload_alignsw", "click", function(e) { let ic = me.icn3d;
13726
13788
  e.preventDefault();
13727
13789
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -35773,7 +35835,7 @@ class SetColor {
35773
35835
  }
35774
35836
  else {
35775
35837
  let b = atom.b;
35776
-
35838
+
35777
35839
  // PDB
35778
35840
  b = (atom.structure.substr(0, 4) != ic.defaultPdbId && atom.structure.length < 6) ? 100 - b : b;
35779
35841
 
@@ -36303,7 +36365,7 @@ class SetOption {
36303
36365
 
36304
36366
  let colorLabel = colorType.substr(0, 1).toUpperCase() + colorType.substr(1);
36305
36367
  if(colorType == 'confidence') {
36306
- colorLabel = 'AlphaFold Confidence';
36368
+ colorLabel = 'AlphaFold Confidence (pLDDT)';
36307
36369
  }
36308
36370
  else if(colorType == 'normalized hydrophobic') {
36309
36371
  colorLabel = 'Normalized Hydrophobicity';
@@ -45572,7 +45634,8 @@ class LineGraph {
45572
45634
  for(let i = 0, il = ic.chainid2refpdbname[chainid].length; i < il; ++i) {
45573
45635
  chainList += ic.chainid2refpdbname[chainid][i] + " ";
45574
45636
  }
45575
- if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
45637
+ //if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
45638
+ console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
45576
45639
 
45577
45640
  let prevStrand;
45578
45641
  let bCd19 = ic.chainid2refpdbname[chainid].length == 1 && ic.chainid2refpdbname[chainid][0] == 'CD19_6al5A_human_C2orV-n1';
@@ -51304,14 +51367,14 @@ class PdbParser {
51304
51367
 
51305
51368
  //Atom "data" from PDB file was parsed to set up parameters for the 3D viewer. The deferred parameter
51306
51369
  //was resolved after the parsing so that other javascript code can be executed.
51307
- async loadPdbData(data, pdbid, bOpm, bAppend, type, bLastQuery, bNoDssp) { let ic = this.icn3d, me = ic.icn3dui;
51370
+ async loadPdbData(data, pdbid, bOpm, bAppend, type, bLastQuery, bNoDssp, bEsmfold) { let ic = this.icn3d, me = ic.icn3dui;
51308
51371
  if(!bAppend && (type === undefined || type === 'target')) {
51309
51372
  // if a command contains "load...", the commands should not be cleared with init()
51310
51373
  let bKeepCmd = (ic.bCommandLoad) ? true : false;
51311
51374
  if(!ic.bStatefile) ic.init(bKeepCmd);
51312
51375
  }
51313
51376
 
51314
- let hAtoms = ic.loadPDBCls.loadPDB(data, pdbid, bOpm, undefined, undefined, bAppend, type, bLastQuery); // defined in the core library
51377
+ let hAtoms = ic.loadPDBCls.loadPDB(data, pdbid, bOpm, undefined, undefined, bAppend, type, bEsmfold); // defined in the core library
51315
51378
 
51316
51379
  if(me.cfg.opmid === undefined) ic.ParserUtilsCls.transformToOpmOri(pdbid);
51317
51380
 
@@ -51381,7 +51444,7 @@ class PdbParser {
51381
51444
  }
51382
51445
 
51383
51446
  //if(me.cfg.afid && !ic.bAfMem && !me.cfg.blast_rep_id) {
51384
- if(me.cfg.afid && !ic.bAfMem) {
51447
+ if( (me.cfg.afid && !ic.bAfMem) || ic.bEsmfold) {
51385
51448
  ic.opts['color'] = 'confidence';
51386
51449
  }
51387
51450
 
@@ -54618,6 +54681,11 @@ class LoadAtomData {
54618
54681
  }
54619
54682
  }
54620
54683
  }
54684
+
54685
+ if(type === 'mmdbid') {
54686
+ if(!ic.molTitleHash) ic.molTitleHash = {};
54687
+ ic.molTitleHash[id] = ic.molTitle;
54688
+ }
54621
54689
 
54622
54690
  let atomid2serial = {};
54623
54691
  let prevStructureNum = '', prevChainNum = '', prevResidueNum = '';
@@ -56584,7 +56652,7 @@ class LoadPDB {
56584
56652
 
56585
56653
  // modified from iview (http://istar.cse.cuhk.edu.hk/iview/)
56586
56654
  //This PDB parser feeds the viewer with the content of a PDB file, pdbData.
56587
- loadPDB(src, pdbid, bOpm, bVector, bMutation, bAppend, type, bLastQuery) { let ic = this.icn3d, me = ic.icn3dui;
56655
+ loadPDB(src, pdbid, bOpm, bVector, bMutation, bAppend, type, bEsmfold) { let ic = this.icn3d, me = ic.icn3dui;
56588
56656
  let hAtoms = {};
56589
56657
 
56590
56658
  let bNMR = false;
@@ -56674,8 +56742,10 @@ class LoadPDB {
56674
56742
  } else if (record === 'TITLE ') {
56675
56743
  let name = line.substr(10).replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
56676
56744
  ic.molTitle += name.trim() + " ";
56745
+ if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
56746
+
56677
56747
  if(!ic.molTitleHash) ic.molTitleHash = {};
56678
- ic.molTitleHash[structure] = name.trim() + " ";
56748
+ ic.molTitleHash[structure] = ic.molTitle;
56679
56749
 
56680
56750
  } else if (record === 'HELIX ') {
56681
56751
  ic.bSecondaryStructure = true;
@@ -56852,6 +56922,9 @@ class LoadPDB {
56852
56922
  let z = parseFloat(line.substr(46, 8));
56853
56923
  let coord = new THREE.Vector3(x, y, z);
56854
56924
 
56925
+ let bFactor = parseFloat(line.substr(60, 8));
56926
+ if(bEsmfold) bFactor *= 100;
56927
+
56855
56928
  let atomDetails = {
56856
56929
  het: record[0] === 'H', // optional, used to determine chemicals, water, ions, etc
56857
56930
  serial: serial, // required, unique atom id
@@ -56863,7 +56936,7 @@ class LoadPDB {
56863
56936
  resi: resi, // optional, used to identify residue ID
56864
56937
  //insc: line.substr(26, 1),
56865
56938
  coord: coord, // required, used to draw 3D shape
56866
- b: parseFloat(line.substr(60, 8)), // optional, used to draw B-factor tube
56939
+ b: bFactor, // optional, used to draw B-factor tube
56867
56940
  elem: elem, // optional, used to determine hydrogen bond
56868
56941
  bonds: [], // required, used to connect atoms
56869
56942
  ss: 'coil', // optional, used to show secondary structures
@@ -68663,8 +68736,13 @@ class SaveFile {
68663
68736
  if(structureidArray.length > 1) {
68664
68737
  idName += 's';
68665
68738
  }
68666
- else if(ic.molTitleHash) {
68667
- title = ic.molTitleHash[inputid];
68739
+
68740
+ if(ic.molTitleHash) {
68741
+ title = '';
68742
+ for(let i = 0, il = structureidArray.length; i < il; ++i) {
68743
+ title += ic.molTitleHash[structureidArray[i]];
68744
+ if(i < il - 1) title += '; ';
68745
+ }
68668
68746
  }
68669
68747
  }
68670
68748
 
@@ -69069,7 +69147,7 @@ class ShareLink {
69069
69147
  outputCmd = tmpUrl;
69070
69148
 
69071
69149
  statefile = statefile.replace(/!/g, Object.keys(ic.structures)[0] + '_');
69072
- if((ic.bInputfile && !ic.bInputUrlfile) || (ic.bInputUrlfile && ic.bAppend) || url.length > 4000) url = statefile;
69150
+ if(ic.bEmsfold || (ic.bInputfile && !ic.bInputUrlfile) || (ic.bInputUrlfile && ic.bAppend) || url.length > 4000) url = statefile;
69073
69151
  let id;
69074
69152
  if(ic.structures !== undefined && Object.keys(ic.structures).length == 1 && ic.inputid !== undefined) {
69075
69153
  id = Object.keys(ic.structures)[0];
@@ -71904,7 +71982,7 @@ iCn3D.prototype.resetConfig = function () { let ic = this, me = ic.icn3dui;
71904
71982
  this.opts['chemicals'] = 'ball and stick';
71905
71983
  }
71906
71984
 
71907
- if(me.cfg.afid !== undefined) {
71985
+ if(me.cfg.afid !== undefined || ic.bEsmfold) {
71908
71986
  this.opts['color'] = 'confidence';
71909
71987
  }
71910
71988
 
@@ -71940,7 +72018,7 @@ class iCn3DUI {
71940
72018
  //even when multiple iCn3D viewers are shown together.
71941
72019
  this.pre = this.cfg.divid + "_";
71942
72020
 
71943
- this.REVISION = '3.25.4';
72021
+ this.REVISION = '3.26.0';
71944
72022
 
71945
72023
  // In nodejs, iCn3D defines "window = {navigator: {}}"
71946
72024
  this.bNode = (Object.keys(window).length < 2) ? true : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icn3d",
3
- "version": "3.25.21",
3
+ "version": "3.26.0",
4
4
  "main": "./icn3d.js",
5
5
  "exports": {
6
6
  ".": {