icn3d 3.46.1 → 3.47.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 +1359 -42
- package/icn3d.min.js +4 -4
- package/icn3d.module.js +1358 -43
- package/package.json +1 -1
package/icn3d.module.js
CHANGED
|
@@ -56271,6 +56271,8 @@ class RmsdSuprCls {
|
|
|
56271
56271
|
supr = undefined;
|
|
56272
56272
|
}
|
|
56273
56273
|
|
|
56274
|
+
if(me.bNode) console.log("RMSD: " + supr);
|
|
56275
|
+
|
|
56274
56276
|
return {'rot': rot, 'trans1': xc1, 'trans2': xc2, 'rmsd': supr};
|
|
56275
56277
|
|
|
56276
56278
|
}; // end rmsd_supr
|
|
@@ -57066,11 +57068,12 @@ class ClickMenu {
|
|
|
57066
57068
|
}
|
|
57067
57069
|
}
|
|
57068
57070
|
|
|
57069
|
-
setSetsMenus(id, bOneset) { let me = this.icn3dui, ic = me.icn3d;
|
|
57071
|
+
setSetsMenus(id, bOneset, bThreeset) { let me = this.icn3dui, ic = me.icn3d;
|
|
57070
57072
|
this.SetChainsAdvancedMenu();
|
|
57071
57073
|
|
|
57072
57074
|
let id1 = id;
|
|
57073
57075
|
let id2 = id + '2';
|
|
57076
|
+
let id3 = id + '3';
|
|
57074
57077
|
|
|
57075
57078
|
let definedAtomsHtml = ic.definedSetsCls.setAtomMenu(['protein']);
|
|
57076
57079
|
if($("#" + me.pre + id1).length) {
|
|
@@ -57079,9 +57082,13 @@ class ClickMenu {
|
|
|
57079
57082
|
if(!bOneset && $("#" + me.pre + id2).length) {
|
|
57080
57083
|
$("#" + me.pre + id2).html(" <option value='selected' selected>selected</option>" + definedAtomsHtml);
|
|
57081
57084
|
}
|
|
57085
|
+
if(bThreeset && $("#" + me.pre + id3).length) {
|
|
57086
|
+
$("#" + me.pre + id3).html(" <option value='selected' selected>selected</option>" + definedAtomsHtml);
|
|
57087
|
+
}
|
|
57082
57088
|
|
|
57083
57089
|
$("#" + me.pre + id1).resizable();
|
|
57084
57090
|
if(!bOneset) $("#" + me.pre + id2).resizable();
|
|
57091
|
+
if(bThreeset) $("#" + me.pre + id3).resizable();
|
|
57085
57092
|
}
|
|
57086
57093
|
|
|
57087
57094
|
applyShownMenus(bNoSave) { let me = this.icn3dui; me.icn3d;
|
|
@@ -57298,27 +57305,31 @@ class ClickMenu {
|
|
|
57298
57305
|
|
|
57299
57306
|
me.myEventCls.onIds("#" + me.pre + "mn1_pdbfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57300
57307
|
//me = me.setIcn3dui($(this).attr('id'));
|
|
57301
|
-
me.htmlCls.dialogCls.openDlg('dl_pdbfile', 'Please input PDB
|
|
57308
|
+
me.htmlCls.dialogCls.openDlg('dl_pdbfile', 'Please input PDB file');
|
|
57302
57309
|
});
|
|
57303
57310
|
me.myEventCls.onIds(["#" + me.pre + "mn1_pdbfile_app", "#" + me.pre + "tool_pdbfile"], "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57304
57311
|
//me = me.setIcn3dui($(this).attr('id'));
|
|
57305
|
-
me.htmlCls.dialogCls.openDlg('dl_pdbfile_app', 'Please append PDB
|
|
57312
|
+
me.htmlCls.dialogCls.openDlg('dl_pdbfile_app', 'Please append PDB files');
|
|
57306
57313
|
});
|
|
57307
57314
|
|
|
57308
57315
|
me.myEventCls.onIds("#" + me.pre + "mn1_mol2file", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57309
|
-
me.htmlCls.dialogCls.openDlg('dl_mol2file', 'Please input Mol2
|
|
57316
|
+
me.htmlCls.dialogCls.openDlg('dl_mol2file', 'Please input Mol2 file');
|
|
57310
57317
|
});
|
|
57311
57318
|
|
|
57312
57319
|
me.myEventCls.onIds("#" + me.pre + "mn1_sdffile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57313
|
-
me.htmlCls.dialogCls.openDlg('dl_sdffile', 'Please input SDF
|
|
57320
|
+
me.htmlCls.dialogCls.openDlg('dl_sdffile', 'Please input SDF file');
|
|
57314
57321
|
});
|
|
57315
57322
|
|
|
57316
57323
|
me.myEventCls.onIds("#" + me.pre + "mn1_xyzfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57317
|
-
me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ
|
|
57324
|
+
me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ file');
|
|
57325
|
+
});
|
|
57326
|
+
|
|
57327
|
+
me.myEventCls.onIds("#" + me.pre + "mn1_dcdfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57328
|
+
me.htmlCls.dialogCls.openDlg('dl_dcdfile', 'Please input MD trajectory file');
|
|
57318
57329
|
});
|
|
57319
57330
|
|
|
57320
57331
|
me.myEventCls.onIds("#" + me.pre + "mn1_afmapfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57321
|
-
me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold PAE
|
|
57332
|
+
me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold PAE file');
|
|
57322
57333
|
});
|
|
57323
57334
|
|
|
57324
57335
|
me.myEventCls.onIds("#" + me.pre + "mn1_urlfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
@@ -57326,11 +57337,11 @@ class ClickMenu {
|
|
|
57326
57337
|
});
|
|
57327
57338
|
|
|
57328
57339
|
me.myEventCls.onIds("#" + me.pre + "mn1_clustalwfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57329
|
-
me.htmlCls.dialogCls.openDlg('dl_clustalwfile', 'Please input CLUSTALW MSA
|
|
57340
|
+
me.htmlCls.dialogCls.openDlg('dl_clustalwfile', 'Please input CLUSTALW MSA file');
|
|
57330
57341
|
});
|
|
57331
57342
|
|
|
57332
57343
|
me.myEventCls.onIds("#" + me.pre + "mn1_fastafile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
57333
|
-
me.htmlCls.dialogCls.openDlg('dl_fastafile', 'Please input FASTA MSA
|
|
57344
|
+
me.htmlCls.dialogCls.openDlg('dl_fastafile', 'Please input FASTA MSA file');
|
|
57334
57345
|
});
|
|
57335
57346
|
|
|
57336
57347
|
me.myEventCls.onIds("#" + me.pre + "mn1_fixedversion", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
@@ -59204,6 +59215,13 @@ class ClickMenu {
|
|
|
59204
59215
|
ic.bLinebtwsets = true;
|
|
59205
59216
|
});
|
|
59206
59217
|
|
|
59218
|
+
me.myEventCls.onIds("#" + me.pre + "mn5_plane3sets", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
|
|
59219
|
+
me.htmlCls.dialogCls.openDlg('dl_plane3sets', 'Draw a plane among three sets');
|
|
59220
|
+
|
|
59221
|
+
thisClass.setSetsMenus('plane3sets', undefined, true);
|
|
59222
|
+
|
|
59223
|
+
ic.bPlane3sets = true;
|
|
59224
|
+
});
|
|
59207
59225
|
|
|
59208
59226
|
me.myEventCls.onIds(["#" + me.pre + "mn2_selectedcenter", "#" + me.pre + "zoomin_selection", "#" + me.pre + "tool_selectedcenter"], "click", function(e) { let ic = me.icn3d; //e.preventDefault();
|
|
59209
59227
|
//thisClass.setLogCmd('zoom selection', true);
|
|
@@ -60292,6 +60310,7 @@ class SetMenu {
|
|
|
60292
60310
|
html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
|
|
60293
60311
|
html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
|
|
60294
60312
|
html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
|
|
60313
|
+
html += this.getLink('mn1_dcdfile', 'MD Trajectory File', undefined, 2);
|
|
60295
60314
|
|
|
60296
60315
|
html += this.getMenuSep();
|
|
60297
60316
|
|
|
@@ -60925,6 +60944,7 @@ class SetMenu {
|
|
|
60925
60944
|
|
|
60926
60945
|
html += this.getLink('mn5_cartoonshape', 'Cartoon for a Set', undefined, 1);
|
|
60927
60946
|
html += this.getLink('mn5_linebtwsets', 'Line btw. Two Sets', undefined, 1);
|
|
60947
|
+
html += this.getLink('mn5_plane3sets', 'Plane among 3 Sets', undefined, 1);
|
|
60928
60948
|
|
|
60929
60949
|
if(me.cfg.cid === undefined && me.cfg.align === undefined && me.cfg.chainalign === undefined && me.cfg.mmdbaf === undefined) {
|
|
60930
60950
|
html += this.getMenuSep();
|
|
@@ -61795,6 +61815,7 @@ class Dialog {
|
|
|
61795
61815
|
let bGraph = $('#' + me.pre + 'dl_graph').hasClass('ui-dialog-content'); // initialized
|
|
61796
61816
|
let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
|
|
61797
61817
|
let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
|
|
61818
|
+
let bRmsdplot = $('#' + me.pre + 'dl_rmsdplot').hasClass('ui-dialog-content'); // initialized
|
|
61798
61819
|
let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
|
|
61799
61820
|
let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
|
|
61800
61821
|
let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
|
|
@@ -61812,6 +61833,7 @@ class Dialog {
|
|
|
61812
61833
|
id2flag.dl_graph = 'bGraph2';
|
|
61813
61834
|
id2flag.dl_linegraph = 'bLineGraph2';
|
|
61814
61835
|
id2flag.dl_scatterplot = 'bScatterplot2';
|
|
61836
|
+
id2flag.dl_rmsdplot = 'bRmsdplot2';
|
|
61815
61837
|
id2flag.dl_ligplot = 'bLigplot2';
|
|
61816
61838
|
id2flag.dl_contactmap = 'bContactmap2';
|
|
61817
61839
|
id2flag.dl_alignerrormap = 'bAlignerrormap2';
|
|
@@ -61825,6 +61847,7 @@ class Dialog {
|
|
|
61825
61847
|
if(bGraph) status.bGraph2 = $('#' + me.pre + 'dl_graph').dialog( 'isOpen' );
|
|
61826
61848
|
if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
|
|
61827
61849
|
if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
|
|
61850
|
+
if(bRmsdplot) status.bRmsdplot2 = $('#' + me.pre + 'dl_rmsdplot').dialog( 'isOpen' );
|
|
61828
61851
|
if(bLigplot) status.bLigplot2 = $('#' + me.pre + 'dl_ligplot').dialog( 'isOpen' );
|
|
61829
61852
|
if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
|
|
61830
61853
|
if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
|
|
@@ -62014,7 +62037,7 @@ class Dialog {
|
|
|
62014
62037
|
|
|
62015
62038
|
let status = this.getDialogStatus().status;
|
|
62016
62039
|
|
|
62017
|
-
if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
|
|
62040
|
+
if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_rmsdplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
|
|
62018
62041
|
//var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
|
|
62019
62042
|
let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
|
|
62020
62043
|
|
|
@@ -62240,7 +62263,7 @@ class Dialog {
|
|
|
62240
62263
|
let width = 400, height = 150;
|
|
62241
62264
|
let twoddgmWidth = me.htmlCls.width2d + 20;
|
|
62242
62265
|
|
|
62243
|
-
if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
|
|
62266
|
+
if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_rmsdplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
|
|
62244
62267
|
$( "#" + id ).show();
|
|
62245
62268
|
$( "#" + id + "_nb").show();
|
|
62246
62269
|
$( "#" + id + "_title").html(title);
|
|
@@ -62671,6 +62694,23 @@ class SetDialog {
|
|
|
62671
62694
|
html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
|
|
62672
62695
|
html += "</div>";
|
|
62673
62696
|
|
|
62697
|
+
html += me.htmlCls.divStr + "dl_dcdfile' class='" + dialogClass + "'>";
|
|
62698
|
+
html += this.addNotebookTitle('dl_dcdfile', 'Please input an MD trajectory file');
|
|
62699
|
+
html += "Step 1. <b>PDB File</b>: " + me.htmlCls.inputFileStr + "id='" + me.pre + "dcdpdbfile' size=8> ";
|
|
62700
|
+
html += me.htmlCls.buttonStr + "reload_dcdpdbfile'>Load PDB File</button><br><br>";
|
|
62701
|
+
|
|
62702
|
+
html += "Step 2. <b>DCD File</b>: " + me.htmlCls.inputFileStr + "id='" + me.pre + "dcdfile' size=8> ";
|
|
62703
|
+
html += me.htmlCls.buttonStr + "reload_dcdfile'>Load DCD File</button><br>";
|
|
62704
|
+
|
|
62705
|
+
html += "or <b>XTC File</b>: " + me.htmlCls.inputFileStr + "id='" + me.pre + "xtcfile' size=8> ";
|
|
62706
|
+
html += me.htmlCls.buttonStr + "reload_xtcfile' style='margin-left:28px'>Load XTC File</button><br><br>";
|
|
62707
|
+
|
|
62708
|
+
html += "<hr><br>";
|
|
62709
|
+
html += "<b>Analysis</b>: " + me.htmlCls.buttonStr + "rmsd_plot'>RMSD Plot</button><br><br>";
|
|
62710
|
+
html += "<b>Video from Frames</b>: " + me.htmlCls.buttonStr + "video_frame'>Make Video</button> with " + me.htmlCls.inputTextStr + "id='" + me.pre + "videofps' value='2' size=2> FPS (Frame per Sec)<br><br>";
|
|
62711
|
+
|
|
62712
|
+
html += "</div>";
|
|
62713
|
+
|
|
62674
62714
|
html += me.htmlCls.divStr + "dl_clustalwfile' class='" + dialogClass + "' style='max-width:500px'>";
|
|
62675
62715
|
html += this.addNotebookTitle('dl_clustalwfile', 'Please input a CLUSTALW MSA file');
|
|
62676
62716
|
html += "Note the sequence names are either UniProt ID (e.g., A4D1S0 or A4D1S0_A), RefSeq ID (e.g., NP_001743), or PDB chain ID (e.g., 1HHO_A).<br><br>";
|
|
@@ -63201,6 +63241,15 @@ class SetDialog {
|
|
|
63201
63241
|
|
|
63202
63242
|
html += "</div>";
|
|
63203
63243
|
|
|
63244
|
+
html += me.htmlCls.divStr + "dl_rmsdplot' style='background-color:white' class='" + dialogClass + "'>";
|
|
63245
|
+
html += this.addNotebookTitle('dl_rmsdplot', 'RMSD Plot');
|
|
63246
|
+
|
|
63247
|
+
me.rmsdplotid = me.pre + 'rmsdplot';
|
|
63248
|
+
html += me.htmlCls.divNowrapStr + buttonStrTmp + me.rmsdplotid + '_json">JSON</button>' + me.htmlCls.space2 + " The image below can be saved via right click.<br></div>";
|
|
63249
|
+
|
|
63250
|
+
html += '<canvas id="' + me.rmsdplotid + '"></canvas>';
|
|
63251
|
+
|
|
63252
|
+
html += "</div>";
|
|
63204
63253
|
|
|
63205
63254
|
html += me.htmlCls.divStr + "dl_ligplot' style='background-color:white' class='" + dialogClass + "'>";
|
|
63206
63255
|
|
|
@@ -63458,6 +63507,42 @@ class SetDialog {
|
|
|
63458
63507
|
html += "</div>";
|
|
63459
63508
|
|
|
63460
63509
|
|
|
63510
|
+
html += me.htmlCls.divStr + "dl_plane3sets' class='" + dialogClass + "'>";
|
|
63511
|
+
html += this.addNotebookTitle('dl_plane3sets', 'Add a plane among three sets');
|
|
63512
|
+
html += me.htmlCls.spanNowrapStr + "1. Select three sets</span><br/>";
|
|
63513
|
+
html += "<table border=0 width=400 cellspacing=10><tr><td>";
|
|
63514
|
+
|
|
63515
|
+
html += me.htmlCls.divNowrapStr + "First set:</div>";
|
|
63516
|
+
html += "<div style='text-indent:1.1em'><select style='max-width:200px' id='" + me.pre + "plane3sets' multiple size='5' style='min-width:130px;'>";
|
|
63517
|
+
html += "</select></div>";
|
|
63518
|
+
|
|
63519
|
+
html += "</td><td>";
|
|
63520
|
+
|
|
63521
|
+
html += me.htmlCls.divNowrapStr + "Second set:</div>";
|
|
63522
|
+
html += "<div style='text-indent:1.1em'><select style='max-width:200px' id='" + me.pre + "plane3sets2' multiple size='5' style='min-width:130px;'>";
|
|
63523
|
+
html += "</select></div>";
|
|
63524
|
+
|
|
63525
|
+
html += "</td><td>";
|
|
63526
|
+
|
|
63527
|
+
html += me.htmlCls.divNowrapStr + "Third set:</div>";
|
|
63528
|
+
html += "<div style='text-indent:1.1em'><select style='max-width:200px' id='" + me.pre + "plane3sets3' multiple size='5' style='min-width:130px;'>";
|
|
63529
|
+
html += "</select></div>";
|
|
63530
|
+
|
|
63531
|
+
html += "</td></tr></table>";
|
|
63532
|
+
|
|
63533
|
+
html += "2. Thickness (Å): " + me.htmlCls.inputTextStr + "id='" + me.pre + "plane3sets_thickness' value='2' size=4><br/><br/>";
|
|
63534
|
+
|
|
63535
|
+
html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "plane3sets_customcolor' value='" + defaultColor + "' size=4><br/><br/>";
|
|
63536
|
+
|
|
63537
|
+
html += me.htmlCls.divNowrapStr + "4. Opacity: <select id='" + me.pre + "plane3sets_opacity'>";
|
|
63538
|
+
html += me.htmlCls.setHtmlCls.getOptionHtml(['1.0', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1'], 7);
|
|
63539
|
+
html += "</select></div><br>";
|
|
63540
|
+
|
|
63541
|
+
html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applyplane3sets'>Display</button></span>";
|
|
63542
|
+
html += me.htmlCls.space3 + me.htmlCls.spanNowrapStr + me.htmlCls.buttonStr + "clearplane3sets'>Clear</button></span>";
|
|
63543
|
+
html += "</div>";
|
|
63544
|
+
|
|
63545
|
+
|
|
63461
63546
|
html += me.htmlCls.divStr + "dl_cartoonshape' class='" + dialogClass + "'>";
|
|
63462
63547
|
html += this.addNotebookTitle('dl_cartoonshape', 'Cartoon Shape');
|
|
63463
63548
|
html += me.htmlCls.spanNowrapStr + "1. Select a set:</span><br/>";
|
|
@@ -64174,10 +64259,10 @@ class Events {
|
|
|
64174
64259
|
}
|
|
64175
64260
|
}
|
|
64176
64261
|
|
|
64177
|
-
async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
|
|
64262
|
+
async loadPdbFile(bAppend, fileId, bmmCIF, bOpenDialog) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
|
|
64178
64263
|
//me = ic.setIcn3dui(this.id);
|
|
64179
64264
|
ic.bInitial = true;
|
|
64180
|
-
thisClass.iniFileLoad();
|
|
64265
|
+
if(!bOpenDialog) thisClass.iniFileLoad();
|
|
64181
64266
|
let files = $("#" + me.pre + fileId)[0].files;
|
|
64182
64267
|
if(!files[0]) {
|
|
64183
64268
|
var aaa = 1; //alert("Please select a file before clicking 'Load'");
|
|
@@ -64495,7 +64580,7 @@ class Events {
|
|
|
64495
64580
|
|
|
64496
64581
|
me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", async function(e) { let ic = me.icn3d;
|
|
64497
64582
|
ic.bAlternate = true;
|
|
64498
|
-
|
|
64583
|
+
ic.alternateCls.alternateStructures();
|
|
64499
64584
|
ic.bAlternate = false;
|
|
64500
64585
|
|
|
64501
64586
|
thisClass.setLogCmd("alternate structures", false);
|
|
@@ -65417,14 +65502,53 @@ class Events {
|
|
|
65417
65502
|
|
|
65418
65503
|
// Start recording
|
|
65419
65504
|
ic.videoRecorder.start();
|
|
65420
|
-
thisClass.setLogCmd('Video
|
|
65505
|
+
thisClass.setLogCmd('Video recording started', false);
|
|
65421
65506
|
});
|
|
65422
65507
|
|
|
65423
65508
|
me.myEventCls.onIds("#" + me.pre + "video_end", "click", function(e) { let ic = me.icn3d;
|
|
65424
65509
|
e.preventDefault();
|
|
65425
65510
|
|
|
65426
65511
|
ic.videoRecorder.stop();
|
|
65427
|
-
thisClass.setLogCmd('Video
|
|
65512
|
+
thisClass.setLogCmd('Video recording ended', false);
|
|
65513
|
+
});
|
|
65514
|
+
|
|
65515
|
+
me.myEventCls.onIds("#" + me.pre + "video_frame", "click", function(e) { let ic = me.icn3d;
|
|
65516
|
+
e.preventDefault();
|
|
65517
|
+
|
|
65518
|
+
let fps = $("#" + me.pre + "videofps").val();
|
|
65519
|
+
let interval = 1000 / fps; // ms
|
|
65520
|
+
let duratinon = (ic.frames + 3) * interval; // make the video a little longer than the number of frames
|
|
65521
|
+
|
|
65522
|
+
const canvas = document.getElementById(ic.pre + "canvas");
|
|
65523
|
+
// ic.videoFrameRecorder = new MediaRecorder(canvas.captureStream(fps));
|
|
65524
|
+
ic.videoFrameRecorder = new MediaRecorder(canvas.captureStream());
|
|
65525
|
+
const recordedChunks = [];
|
|
65526
|
+
|
|
65527
|
+
// Collect data chunks
|
|
65528
|
+
ic.videoFrameRecorder.ondataavailable = event => {
|
|
65529
|
+
recordedChunks.push(event.data);
|
|
65530
|
+
};
|
|
65531
|
+
|
|
65532
|
+
ic.videoFrameRecorder.onstop = event => {
|
|
65533
|
+
// Code to save the recordedChunks as a video file
|
|
65534
|
+
const blob = new Blob(recordedChunks, {type: ic.videoFrameRecorder.mimeType});
|
|
65535
|
+
let fileName = ic.inputid + '_video_frame';
|
|
65536
|
+
saveAs(blob, fileName);
|
|
65537
|
+
};
|
|
65538
|
+
|
|
65539
|
+
// Start recording
|
|
65540
|
+
ic.videoFrameRecorder.start();
|
|
65541
|
+
thisClass.setLogCmd('Video recording started', false);
|
|
65542
|
+
|
|
65543
|
+
const intervalId = setInterval(function() {
|
|
65544
|
+
ic.alternateCls.alternateStructures();
|
|
65545
|
+
}, interval);
|
|
65546
|
+
|
|
65547
|
+
setTimeout(() => {
|
|
65548
|
+
clearInterval(intervalId);
|
|
65549
|
+
ic.videoFrameRecorder.stop();
|
|
65550
|
+
thisClass.setLogCmd('Video recording ended', false);
|
|
65551
|
+
}, duratinon);
|
|
65428
65552
|
});
|
|
65429
65553
|
|
|
65430
65554
|
me.myEventCls.onIds("#" + me.pre + "reload_state", "click", function(e) { let ic = me.icn3d;
|
|
@@ -66046,6 +66170,22 @@ class Events {
|
|
|
66046
66170
|
await thisClass.loadPdbFile(ic.bAppend, 'pdbfile_app');
|
|
66047
66171
|
});
|
|
66048
66172
|
|
|
66173
|
+
me.myEventCls.onIds("#" + me.pre + "reload_dcdpdbfile", "click", async function(e) { me.icn3d;
|
|
66174
|
+
e.preventDefault();
|
|
66175
|
+
|
|
66176
|
+
let bAppend = false;
|
|
66177
|
+
// ic.bRender = false;
|
|
66178
|
+
await thisClass.loadPdbFile(bAppend, 'dcdpdbfile', undefined, true);
|
|
66179
|
+
});
|
|
66180
|
+
|
|
66181
|
+
me.myEventCls.onIds("#" + me.pre + "reload_xtcpdbfile", "click", async function(e) { me.icn3d;
|
|
66182
|
+
e.preventDefault();
|
|
66183
|
+
|
|
66184
|
+
let bAppend = false;
|
|
66185
|
+
// ic.bRender = false;
|
|
66186
|
+
await thisClass.loadPdbFile(bAppend, 'xtcpdbfile', undefined, true);
|
|
66187
|
+
});
|
|
66188
|
+
|
|
66049
66189
|
me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
|
|
66050
66190
|
e.preventDefault();
|
|
66051
66191
|
ic.bInitial = true;
|
|
@@ -66127,6 +66267,62 @@ class Events {
|
|
|
66127
66267
|
}
|
|
66128
66268
|
});
|
|
66129
66269
|
|
|
66270
|
+
me.myEventCls.onIds("#" + me.pre + "reload_dcdfile", "click", async function(e) { let ic = me.icn3d;
|
|
66271
|
+
e.preventDefault();
|
|
66272
|
+
ic.bInitial = true;
|
|
66273
|
+
|
|
66274
|
+
//thisClass.iniFileLoad();
|
|
66275
|
+
let file = $("#" + me.pre + "dcdfile")[0].files[0];
|
|
66276
|
+
if(!file) {
|
|
66277
|
+
var aaa = 1; //alert("Please select a file before clicking 'Load'");
|
|
66278
|
+
}
|
|
66279
|
+
else {
|
|
66280
|
+
me.htmlCls.setHtmlCls.fileSupport();
|
|
66281
|
+
let reader = new FileReader();
|
|
66282
|
+
reader.onload = async function(e) {
|
|
66283
|
+
let arrayBuffer = e.target.result;
|
|
66284
|
+
thisClass.setLogCmd('load dcd file ' + $("#" + me.pre + "dcdfile").val(), false);
|
|
66285
|
+
ic.molTitle = "";
|
|
66286
|
+
ic.inputid = undefined;
|
|
66287
|
+
|
|
66288
|
+
// ic.init();
|
|
66289
|
+
ic.bInputfile = true;
|
|
66290
|
+
ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + arrayBuffer : arrayBuffer;
|
|
66291
|
+
ic.InputfileType = 'dcd';
|
|
66292
|
+
await ic.dcdParserCls.loadDcdData(arrayBuffer);
|
|
66293
|
+
};
|
|
66294
|
+
reader.readAsArrayBuffer(file);
|
|
66295
|
+
}
|
|
66296
|
+
});
|
|
66297
|
+
|
|
66298
|
+
me.myEventCls.onIds("#" + me.pre + "reload_xtcfile", "click", async function(e) { let ic = me.icn3d;
|
|
66299
|
+
e.preventDefault();
|
|
66300
|
+
ic.bInitial = true;
|
|
66301
|
+
|
|
66302
|
+
//thisClass.iniFileLoad();
|
|
66303
|
+
let file = $("#" + me.pre + "xtcfile")[0].files[0];
|
|
66304
|
+
if(!file) {
|
|
66305
|
+
var aaa = 1; //alert("Please select a file before clicking 'Load'");
|
|
66306
|
+
}
|
|
66307
|
+
else {
|
|
66308
|
+
me.htmlCls.setHtmlCls.fileSupport();
|
|
66309
|
+
let reader = new FileReader();
|
|
66310
|
+
reader.onload = async function(e) {
|
|
66311
|
+
let arrayBuffer = e.target.result;
|
|
66312
|
+
thisClass.setLogCmd('load xtc file ' + $("#" + me.pre + "xtcfile").val(), false);
|
|
66313
|
+
ic.molTitle = "";
|
|
66314
|
+
ic.inputid = undefined;
|
|
66315
|
+
|
|
66316
|
+
// ic.init();
|
|
66317
|
+
ic.bInputfile = true;
|
|
66318
|
+
ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + arrayBuffer : arrayBuffer;
|
|
66319
|
+
ic.InputfileType = 'xtc';
|
|
66320
|
+
await ic.xtcParserCls.loadXtcData(arrayBuffer);
|
|
66321
|
+
};
|
|
66322
|
+
reader.readAsArrayBuffer(file);
|
|
66323
|
+
}
|
|
66324
|
+
});
|
|
66325
|
+
|
|
66130
66326
|
me.myEventCls.onIds("#" + me.pre + "reload_clustalwfile", "click", function(e) { let ic = me.icn3d;
|
|
66131
66327
|
e.preventDefault();
|
|
66132
66328
|
ic.bInitial = true;
|
|
@@ -66379,6 +66575,11 @@ class Events {
|
|
|
66379
66575
|
|
|
66380
66576
|
await ic.showInterCls.showInteractions('graph');
|
|
66381
66577
|
});
|
|
66578
|
+
me.myEventCls.onIds("#" + me.pre + "rmsd_plot", "click", async function(e) { let ic = me.icn3d;
|
|
66579
|
+
e.preventDefault();
|
|
66580
|
+
|
|
66581
|
+
await ic.dcdParserCls.showRmsdPlot();
|
|
66582
|
+
});
|
|
66382
66583
|
me.myEventCls.onIds("#" + me.pre + "hbondLineGraph", "click", async function(e) { let ic = me.icn3d;
|
|
66383
66584
|
e.preventDefault();
|
|
66384
66585
|
|
|
@@ -66524,6 +66725,12 @@ class Events {
|
|
|
66524
66725
|
thisClass.setLogCmd("scatterplot scale " + scale, true);
|
|
66525
66726
|
});
|
|
66526
66727
|
|
|
66728
|
+
me.myEventCls.onIds("#" + me.rmsdplotid + "_json", "click", function(e) { let ic = me.icn3d;
|
|
66729
|
+
e.preventDefault();
|
|
66730
|
+
|
|
66731
|
+
ic.saveFileCls.saveFile(ic.inputid + "_rmsdplot.json", "text", [JSON.stringify(ic.mdDataSet)]);
|
|
66732
|
+
});
|
|
66733
|
+
|
|
66527
66734
|
me.myEventCls.onIds("#" + me.ligplotid + "_svg", "click", function(e) { let ic = me.icn3d;
|
|
66528
66735
|
e.preventDefault();
|
|
66529
66736
|
|
|
@@ -66920,6 +67127,39 @@ class Events {
|
|
|
66920
67127
|
ic.drawCls.draw();
|
|
66921
67128
|
});
|
|
66922
67129
|
|
|
67130
|
+
me.myEventCls.onIds("#" + me.pre + "applyplane3sets", "click", function(e) { let ic = me.icn3d;
|
|
67131
|
+
e.preventDefault();
|
|
67132
|
+
|
|
67133
|
+
ic.bLinebtwsets = false;
|
|
67134
|
+
|
|
67135
|
+
let nameArray = $("#" + me.pre + "plane3sets").val();
|
|
67136
|
+
let nameArray2 = $("#" + me.pre + "plane3sets2").val();
|
|
67137
|
+
let nameArray3 = $("#" + me.pre + "plane3sets3").val();
|
|
67138
|
+
|
|
67139
|
+
let atomSet1 = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
|
|
67140
|
+
let atomSet2 = ic.definedSetsCls.getAtomsFromNameArray(nameArray2);
|
|
67141
|
+
let atomSet3 = ic.definedSetsCls.getAtomsFromNameArray(nameArray3);
|
|
67142
|
+
|
|
67143
|
+
let posArray1 = ic.contactCls.getExtent(atomSet1);
|
|
67144
|
+
let posArray2 = ic.contactCls.getExtent(atomSet2);
|
|
67145
|
+
let posArray3 = ic.contactCls.getExtent(atomSet3);
|
|
67146
|
+
|
|
67147
|
+
let pos1 = new Vector3$1(posArray1[2][0], posArray1[2][1], posArray1[2][2]);
|
|
67148
|
+
let pos2 = new Vector3$1(posArray2[2][0], posArray2[2][1], posArray2[2][2]);
|
|
67149
|
+
let pos3 = new Vector3$1(posArray3[2][0], posArray3[2][1], posArray3[2][2]);
|
|
67150
|
+
|
|
67151
|
+
let thickness = $("#" + me.pre + "plane3sets_thickness").val();
|
|
67152
|
+
let color = $("#" + me.pre + "plane3sets_customcolor").val();
|
|
67153
|
+
let opacity = $("#" + me.pre + "plane3sets_opacity").val();
|
|
67154
|
+
|
|
67155
|
+
let command = 'add plane | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | x2 ' + pos2.x.toPrecision(4) + ' y2 ' + pos2.y.toPrecision(4) + ' z2 ' + pos2.z.toPrecision(4) + ' | x3 ' + pos3.x.toPrecision(4) + ' y3 ' + pos3.y.toPrecision(4) + ' z3 ' + pos3.z.toPrecision(4) + ' | color ' + color + ' | thickness ' + thickness + ' | opacity ' + opacity;
|
|
67156
|
+
|
|
67157
|
+
thisClass.setLogCmd(command, true);
|
|
67158
|
+
|
|
67159
|
+
ic.analysisCls.addPlane(pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z, pos3.x, pos3.y, pos3.z, color, thickness, opacity);
|
|
67160
|
+
ic.drawCls.draw();
|
|
67161
|
+
});
|
|
67162
|
+
|
|
66923
67163
|
me.myEventCls.onIds("#" + me.pre + "applycartoonshape", "click", function(e) { let ic = me.icn3d;
|
|
66924
67164
|
e.preventDefault();
|
|
66925
67165
|
|
|
@@ -66967,6 +67207,16 @@ class Events {
|
|
|
66967
67207
|
ic.drawCls.draw();
|
|
66968
67208
|
});
|
|
66969
67209
|
|
|
67210
|
+
me.myEventCls.onIds("#" + me.pre + "clearplane3sets", "click", function(e) { let ic = me.icn3d;
|
|
67211
|
+
e.preventDefault();
|
|
67212
|
+
|
|
67213
|
+
|
|
67214
|
+
ic.planes = [];
|
|
67215
|
+
thisClass.setLogCmd('clear plane among sets', true);
|
|
67216
|
+
|
|
67217
|
+
ic.drawCls.draw();
|
|
67218
|
+
});
|
|
67219
|
+
|
|
66970
67220
|
me.myEventCls.onIds("#" + me.pre + "clearcartoonshape", "click", function(e) { let ic = me.icn3d;
|
|
66971
67221
|
e.preventDefault();
|
|
66972
67222
|
|
|
@@ -68463,6 +68713,12 @@ class SetHtml {
|
|
|
68463
68713
|
else if(type === 'xyz') {
|
|
68464
68714
|
await ic.xyzParserCls.loadXyzData(data);
|
|
68465
68715
|
}
|
|
68716
|
+
else if(type === 'dcd') {
|
|
68717
|
+
await ic.dcdParserCls.loadDcdData(data);
|
|
68718
|
+
}
|
|
68719
|
+
else if(type === 'xtc') {
|
|
68720
|
+
await ic.xtcParserCls.loadXtcData(data);
|
|
68721
|
+
}
|
|
68466
68722
|
else if(type === 'mmcif') {
|
|
68467
68723
|
await ic.mmcifParserCls.loadMmcifData(data);
|
|
68468
68724
|
}
|
|
@@ -78142,6 +78398,37 @@ class Cylinder {
|
|
|
78142
78398
|
}
|
|
78143
78399
|
}
|
|
78144
78400
|
|
|
78401
|
+
//Create planes for a list of "planes", each of which has the properties 'position1', 'position2', 'position2', 'color', 'thickness', 'opacity',
|
|
78402
|
+
createPlanes(planes) { let ic = this.icn3d, me = ic.icn3dui;
|
|
78403
|
+
if(me.bNode) return;
|
|
78404
|
+
|
|
78405
|
+
for(let i = 0, il = planes.length; i < il; ++i) {
|
|
78406
|
+
let plane = planes[i];
|
|
78407
|
+
|
|
78408
|
+
let p1 = plane.position1;
|
|
78409
|
+
let p2 = plane.position2;
|
|
78410
|
+
let p3 = plane.position3;
|
|
78411
|
+
|
|
78412
|
+
let thickness = (plane.thickness) ? plane.thickness : 2;
|
|
78413
|
+
let opacity = (plane.opacity) ? plane.opacity : 0.3;
|
|
78414
|
+
let colorStr = '#' + plane.color.replace(/\#/g, '');
|
|
78415
|
+
let color = me.parasCls.thr(colorStr);
|
|
78416
|
+
|
|
78417
|
+
let planeGeo = new Plane();
|
|
78418
|
+
planeGeo.setFromCoplanarPoints(p1, p2, p3);
|
|
78419
|
+
let planeNormal = planeGeo.normal;
|
|
78420
|
+
|
|
78421
|
+
const projectedPoint = new Vector3$1();
|
|
78422
|
+
// Project the center onto the plane
|
|
78423
|
+
planeGeo.projectPoint(ic.center, projectedPoint);
|
|
78424
|
+
|
|
78425
|
+
let c0 = projectedPoint.clone().sub(planeNormal.clone().multiplyScalar(thickness * 0.5));
|
|
78426
|
+
let c1 = projectedPoint.clone().add(planeNormal.clone().multiplyScalar(thickness * 0.5));
|
|
78427
|
+
let radius = ic.maxD / 2;
|
|
78428
|
+
ic.cylinderCls.createCylinder(c0, c1, radius, color, undefined, color, undefined, undefined, opacity);
|
|
78429
|
+
}
|
|
78430
|
+
}
|
|
78431
|
+
|
|
78145
78432
|
createCylinder_base(p0, p1, radius, color, bHighlight, color2, bPicking) { let ic = this.icn3d, me = ic.icn3dui;
|
|
78146
78433
|
if(me.bNode) return;
|
|
78147
78434
|
|
|
@@ -78553,7 +78840,7 @@ class Line$1 {
|
|
|
78553
78840
|
}
|
|
78554
78841
|
|
|
78555
78842
|
// do not add the artificial lines to raycasting objects
|
|
78556
|
-
}
|
|
78843
|
+
}
|
|
78557
78844
|
|
|
78558
78845
|
}
|
|
78559
78846
|
|
|
@@ -79031,7 +79318,7 @@ class FirstAtomObj {
|
|
|
79031
79318
|
let firstIndex;
|
|
79032
79319
|
|
|
79033
79320
|
for(let i in atomsHash) {
|
|
79034
|
-
if(ic.atoms[i].name == 'CA') {
|
|
79321
|
+
if(ic.atoms[i] && ic.atoms[i].name == 'CA') {
|
|
79035
79322
|
firstIndex = i;
|
|
79036
79323
|
break;
|
|
79037
79324
|
}
|
|
@@ -79039,7 +79326,7 @@ class FirstAtomObj {
|
|
|
79039
79326
|
|
|
79040
79327
|
if(!firstIndex) {
|
|
79041
79328
|
for(let i in atomsHash) {
|
|
79042
|
-
if(ic.atoms[i].name == "O3'" || ic.atoms[i].name == "O3*") {
|
|
79329
|
+
if(ic.atoms[i] && (ic.atoms[i].name == "O3'" || ic.atoms[i].name == "O3*")) {
|
|
79043
79330
|
firstIndex = i;
|
|
79044
79331
|
break;
|
|
79045
79332
|
}
|
|
@@ -79118,7 +79405,7 @@ class FirstAtomObj {
|
|
|
79118
79405
|
getAtomFromResi(resid, atomName) { let ic = this.icn3d; ic.icn3dui;
|
|
79119
79406
|
if(ic.residues.hasOwnProperty(resid)) {
|
|
79120
79407
|
for(let i in ic.residues[resid]) {
|
|
79121
|
-
if(ic.atoms[i].name === atomName && !ic.atoms[i].het) {
|
|
79408
|
+
if(ic.atoms[i] && ic.atoms[i].name === atomName && !ic.atoms[i].het) {
|
|
79122
79409
|
return ic.atoms[i];
|
|
79123
79410
|
}
|
|
79124
79411
|
}
|
|
@@ -84968,6 +85255,8 @@ class ApplyOther {
|
|
|
84968
85255
|
}
|
|
84969
85256
|
|
|
84970
85257
|
ic.lineCls.createLines(ic.lines);
|
|
85258
|
+
if(!ic.planes) ic.planes = [];
|
|
85259
|
+
ic.cylinderCls.createPlanes(ic.planes);
|
|
84971
85260
|
// }
|
|
84972
85261
|
|
|
84973
85262
|
// distance sets
|
|
@@ -87201,7 +87490,7 @@ class Alternate {
|
|
|
87201
87490
|
|
|
87202
87491
|
// change the display atom when alternating
|
|
87203
87492
|
//Show structures one by one.
|
|
87204
|
-
|
|
87493
|
+
alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
|
|
87205
87494
|
ic.bAlternate = true;
|
|
87206
87495
|
|
|
87207
87496
|
//ic.transformCls.zoominSelection();
|
|
@@ -87346,7 +87635,7 @@ class Alternate {
|
|
|
87346
87635
|
|
|
87347
87636
|
async alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
|
|
87348
87637
|
ic.bAlternate = true;
|
|
87349
|
-
|
|
87638
|
+
this.alternateStructures();
|
|
87350
87639
|
ic.bAlternate = false;
|
|
87351
87640
|
}
|
|
87352
87641
|
|
|
@@ -98035,6 +98324,8 @@ class ShowAnno {
|
|
|
98035
98324
|
ic.seqAnnWidth = dialogWidth - 120 - 30*2 - 50; // title: 120px, start and end resi: 30px, extra space on the left and right: 50px
|
|
98036
98325
|
|
|
98037
98326
|
for(let i = 0, il = chainArray.length; i < il; ++i) {
|
|
98327
|
+
if(!ic.chainsSeq[chainArray[i]]) continue; // skip empty chain
|
|
98328
|
+
|
|
98038
98329
|
Math.round(chainArray[i].indexOf('_'));
|
|
98039
98330
|
//if(pos > 4) continue; // NMR structures with structure id such as 2K042,2K043, ...
|
|
98040
98331
|
// let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chainArray[i]]);
|
|
@@ -100757,7 +101048,7 @@ class LineGraph {
|
|
|
100757
101048
|
}
|
|
100758
101049
|
|
|
100759
101050
|
for(let i = 0, il = structureArray.length; i < il; ++i) {
|
|
100760
|
-
let labelFinal = label;
|
|
101051
|
+
let labelFinal = (i+1).toString() + '. ' + label;
|
|
100761
101052
|
if(bMutation) {
|
|
100762
101053
|
if(i == 0) {
|
|
100763
101054
|
labelFinal += "Wild Type ";
|
|
@@ -108465,6 +108756,12 @@ class PdbParser {
|
|
|
108465
108756
|
else if(type === 'xyz') {
|
|
108466
108757
|
await ic.xyzParserCls.loadXyzData(data);
|
|
108467
108758
|
}
|
|
108759
|
+
else if(type === 'dcd') {
|
|
108760
|
+
await ic.dcdParserCls.loadDcdData(data);
|
|
108761
|
+
}
|
|
108762
|
+
else if(type === 'xtc') {
|
|
108763
|
+
await ic.xtcParserCls.loadXtcData(data);
|
|
108764
|
+
}
|
|
108468
108765
|
else if(type === 'mmcif') {
|
|
108469
108766
|
await ic.mmcifParserCls.loadMmcifData(data);
|
|
108470
108767
|
}
|
|
@@ -109019,6 +109316,995 @@ class XyzParser {
|
|
|
109019
109316
|
}
|
|
109020
109317
|
}
|
|
109021
109318
|
|
|
109319
|
+
/**
|
|
109320
|
+
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
109321
|
+
*/
|
|
109322
|
+
|
|
109323
|
+
class DcdParser {
|
|
109324
|
+
constructor(icn3d) {
|
|
109325
|
+
this.icn3d = icn3d;
|
|
109326
|
+
icn3d.DELTA = 1;
|
|
109327
|
+
icn3d.TIMEOFFSET = 0;
|
|
109328
|
+
}
|
|
109329
|
+
|
|
109330
|
+
async loadDcdData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
109331
|
+
let bResult = this.loadDcdAtomData(data);
|
|
109332
|
+
|
|
109333
|
+
if(me.cfg.align === undefined && Object.keys(ic.structures).length == 1) {
|
|
109334
|
+
$("#" + ic.pre + "alternateWrapper").hide();
|
|
109335
|
+
}
|
|
109336
|
+
|
|
109337
|
+
if(!bResult) {
|
|
109338
|
+
var aaa = 1; //alert('The DCD file has the wrong format...');
|
|
109339
|
+
}
|
|
109340
|
+
else {
|
|
109341
|
+
ic.setStyleCls.setAtomStyleByOptions(ic.opts);
|
|
109342
|
+
ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
|
|
109343
|
+
|
|
109344
|
+
// hide water, ions
|
|
109345
|
+
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
109346
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.nucleotides);
|
|
109347
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chemicals);
|
|
109348
|
+
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
109349
|
+
ic.transformCls.zoominSelection();
|
|
109350
|
+
|
|
109351
|
+
// ic.bRender = true;
|
|
109352
|
+
await ic.ParserUtilsCls.renderStructure();
|
|
109353
|
+
|
|
109354
|
+
if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
|
|
109355
|
+
|
|
109356
|
+
//if(me.deferred !== undefined) me.deferred.resolve(); /// if(ic.deferred2 !== undefined) ic.deferred2.resolve();
|
|
109357
|
+
}
|
|
109358
|
+
}
|
|
109359
|
+
|
|
109360
|
+
// modified from https://github.com/molstar/molstar/blob/master/src/mol-io/reader/dcd/parser.ts
|
|
109361
|
+
loadDcdAtomData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
109362
|
+
// http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/dcdplugin.html
|
|
109363
|
+
|
|
109364
|
+
// The DCD format is structured as follows
|
|
109365
|
+
// (FORTRAN UNFORMATTED, with Fortran data type descriptions):
|
|
109366
|
+
// HDR NSET ISTRT NSAVC 5-ZEROS NATOM-NFREAT DELTA 9-ZEROS
|
|
109367
|
+
// `CORD' #files step 1 step zeroes (zero) timestep (zeroes)
|
|
109368
|
+
// interval
|
|
109369
|
+
// C*4 INT INT INT 5INT INT DOUBLE 9INT
|
|
109370
|
+
// ==========================================================================
|
|
109371
|
+
// NTITLE TITLE
|
|
109372
|
+
// INT (=2) C*MAXTITL
|
|
109373
|
+
// (=32)
|
|
109374
|
+
// ==========================================================================
|
|
109375
|
+
// NATOM
|
|
109376
|
+
// #atoms
|
|
109377
|
+
// INT
|
|
109378
|
+
// ==========================================================================
|
|
109379
|
+
// X(I), I=1,NATOM (DOUBLE)
|
|
109380
|
+
// Y(I), I=1,NATOM
|
|
109381
|
+
// Z(I), I=1,NATOM
|
|
109382
|
+
// ==========================================================================
|
|
109383
|
+
|
|
109384
|
+
let bin =(data.buffer && data.buffer instanceof ArrayBuffer) ? data.buffer : data;
|
|
109385
|
+
const dv = new DataView(bin);
|
|
109386
|
+
|
|
109387
|
+
// const header: Mutable<DcdHeader> = Object.create(null);
|
|
109388
|
+
// const frames: DcdFrame[] = [];
|
|
109389
|
+
const header = {};
|
|
109390
|
+
|
|
109391
|
+
let nextPos = 0;
|
|
109392
|
+
|
|
109393
|
+
// header block
|
|
109394
|
+
|
|
109395
|
+
const intView = new Int32Array(bin, 0, 23);
|
|
109396
|
+
const ef = intView[0] !== dv.getInt32(0); // endianess flag
|
|
109397
|
+
// swap byte order when big endian (84 indicates little endian)
|
|
109398
|
+
if (intView[0] !== 84) {
|
|
109399
|
+
const n = data.byteLength;
|
|
109400
|
+
for (let i = 0; i < n; i += 4) {
|
|
109401
|
+
dv.setFloat32(i, dv.getFloat32(i), true);
|
|
109402
|
+
}
|
|
109403
|
+
}
|
|
109404
|
+
if (intView[0] !== 84) {
|
|
109405
|
+
console.error('dcd bad format, header block start');
|
|
109406
|
+
return false;
|
|
109407
|
+
}
|
|
109408
|
+
|
|
109409
|
+
// format indicator, should read 'CORD'
|
|
109410
|
+
const formatString = String.fromCharCode(
|
|
109411
|
+
dv.getUint8(4), dv.getUint8(5),
|
|
109412
|
+
dv.getUint8(6), dv.getUint8(7)
|
|
109413
|
+
);
|
|
109414
|
+
if (formatString !== 'CORD') {
|
|
109415
|
+
console.error('dcd bad format, format string');
|
|
109416
|
+
return false;
|
|
109417
|
+
}
|
|
109418
|
+
let isCharmm = false;
|
|
109419
|
+
let extraBlock = false;
|
|
109420
|
+
let fourDims = false;
|
|
109421
|
+
// version field in charmm, unused in X-PLOR
|
|
109422
|
+
if (intView[22] !== 0) {
|
|
109423
|
+
isCharmm = true;
|
|
109424
|
+
if (intView[12] !== 0) extraBlock = true;
|
|
109425
|
+
if (intView[13] === 1) fourDims = true;
|
|
109426
|
+
}
|
|
109427
|
+
header.NSET = intView[2];
|
|
109428
|
+
header.ISTART = intView[3];
|
|
109429
|
+
header.NSAVC = intView[4];
|
|
109430
|
+
header.NAMNF = intView[10];
|
|
109431
|
+
|
|
109432
|
+
ic.frames = header.NSET;
|
|
109433
|
+
|
|
109434
|
+
if (isCharmm) {
|
|
109435
|
+
header.DELTA = dv.getFloat32(44, ef);
|
|
109436
|
+
} else {
|
|
109437
|
+
header.DELTA = dv.getFloat64(44, ef);
|
|
109438
|
+
}
|
|
109439
|
+
this.DELTA = header.DELTA;
|
|
109440
|
+
|
|
109441
|
+
if (intView[22] !== 84) {
|
|
109442
|
+
console.error('dcd bad format, header block end');
|
|
109443
|
+
return false;
|
|
109444
|
+
}
|
|
109445
|
+
nextPos = nextPos + 21 * 4 + 8;
|
|
109446
|
+
|
|
109447
|
+
// title block
|
|
109448
|
+
|
|
109449
|
+
const titleEnd = dv.getInt32(nextPos, ef);
|
|
109450
|
+
const titleStart = nextPos + 1;
|
|
109451
|
+
if ((titleEnd - 4) % 80 !== 0) {
|
|
109452
|
+
console.error('dcd bad format, title block start');
|
|
109453
|
+
return false;
|
|
109454
|
+
}
|
|
109455
|
+
|
|
109456
|
+
let byteView = new Uint8Array(bin);
|
|
109457
|
+
header.TITLE = String.fromCharCode.apply(null, byteView.subarray(titleStart, titleEnd));
|
|
109458
|
+
if (dv.getInt32(titleStart + titleEnd + 4 - 1, ef) !== titleEnd) {
|
|
109459
|
+
console.error('dcd bad format, title block end');
|
|
109460
|
+
return false;
|
|
109461
|
+
}
|
|
109462
|
+
|
|
109463
|
+
nextPos = nextPos + titleEnd + 8;
|
|
109464
|
+
|
|
109465
|
+
// natom block
|
|
109466
|
+
|
|
109467
|
+
if (dv.getInt32(nextPos, ef) !== 4) {
|
|
109468
|
+
console.error('dcd bad format, natom block start');
|
|
109469
|
+
return false;
|
|
109470
|
+
}
|
|
109471
|
+
header.NATOM = dv.getInt32(nextPos + 4, ef);
|
|
109472
|
+
if (dv.getInt32(nextPos + 8, ef) !== 4) {
|
|
109473
|
+
console.error('dcd bad format, natom block end');
|
|
109474
|
+
return false;
|
|
109475
|
+
}
|
|
109476
|
+
nextPos = nextPos + 4 + 8;
|
|
109477
|
+
|
|
109478
|
+
// fixed atoms block
|
|
109479
|
+
|
|
109480
|
+
if (header.NAMNF > 0) {
|
|
109481
|
+
// TODO read coordinates and indices of fixed atoms
|
|
109482
|
+
console.error('dcd format with fixed atoms unsupported, aborting');
|
|
109483
|
+
return false;
|
|
109484
|
+
}
|
|
109485
|
+
|
|
109486
|
+
// frames
|
|
109487
|
+
const natom = header.NATOM;
|
|
109488
|
+
const natom4 = natom * 4;
|
|
109489
|
+
|
|
109490
|
+
if(natom != Object.keys(ic.atoms).length) {
|
|
109491
|
+
var aaa = 1; //alert('The number of atoms in the DCD file does not match the number of atoms in the PDB file: ' + natom + ' != ' + Object.keys(ic.atoms).length);
|
|
109492
|
+
return false;
|
|
109493
|
+
}
|
|
109494
|
+
|
|
109495
|
+
let structuresOri = me.hashUtilsCls.cloneHash(ic.structures);
|
|
109496
|
+
let residuesOri = me.hashUtilsCls.cloneHash(ic.residues);
|
|
109497
|
+
let chainsOri = me.hashUtilsCls.cloneHash(ic.chains);
|
|
109498
|
+
|
|
109499
|
+
let proteinsOri = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
109500
|
+
let nucleotidesOri = me.hashUtilsCls.cloneHash(ic.nucleotides);
|
|
109501
|
+
let waterOri = me.hashUtilsCls.cloneHash(ic.water);
|
|
109502
|
+
let ionsOri = me.hashUtilsCls.cloneHash(ic.ions);
|
|
109503
|
+
let chemicalsOri = me.hashUtilsCls.cloneHash(ic.chemicals);
|
|
109504
|
+
|
|
109505
|
+
let serial = natom + 1; // a preloaded PDB structure would have atom serial from 1 to natom
|
|
109506
|
+
for (let i = 0, n = header.NSET; i < n; ++i) {
|
|
109507
|
+
const frame = {};
|
|
109508
|
+
frame.elementCount = natom;
|
|
109509
|
+
|
|
109510
|
+
if (extraBlock) {
|
|
109511
|
+
nextPos += 4; // block start
|
|
109512
|
+
frame.cell = [
|
|
109513
|
+
dv.getFloat64(nextPos, ef),
|
|
109514
|
+
dv.getFloat64(nextPos + 1, ef),
|
|
109515
|
+
dv.getFloat64(nextPos + 2 * 8, ef),
|
|
109516
|
+
dv.getFloat64(nextPos + 3 * 8, ef),
|
|
109517
|
+
dv.getFloat64(nextPos + 4 * 8, ef),
|
|
109518
|
+
dv.getFloat64(nextPos + 5 * 8, ef)
|
|
109519
|
+
];
|
|
109520
|
+
nextPos += 48;
|
|
109521
|
+
nextPos += 4; // block end
|
|
109522
|
+
}
|
|
109523
|
+
|
|
109524
|
+
// xyz coordinates
|
|
109525
|
+
for (let j = 0; j < 3; ++j) {
|
|
109526
|
+
if (dv.getInt32(nextPos, ef) !== natom4) {
|
|
109527
|
+
console.error(`dcd bad format, coord block start: ${i}, ${j}`);
|
|
109528
|
+
return false;
|
|
109529
|
+
}
|
|
109530
|
+
nextPos += 4; // block start
|
|
109531
|
+
const c = new Float32Array(bin, nextPos, natom);
|
|
109532
|
+
if (j === 0) frame.x = c;
|
|
109533
|
+
else if (j === 1) frame.y = c;
|
|
109534
|
+
else frame.z = c;
|
|
109535
|
+
|
|
109536
|
+
nextPos += natom4;
|
|
109537
|
+
if (dv.getInt32(nextPos, ef) !== natom4) {
|
|
109538
|
+
console.error(`dcd bad format, coord block end: ${i}, ${j}`);
|
|
109539
|
+
return false;
|
|
109540
|
+
}
|
|
109541
|
+
nextPos += 4; // block end
|
|
109542
|
+
}
|
|
109543
|
+
|
|
109544
|
+
if (fourDims) {
|
|
109545
|
+
const bytes = dv.getInt32(nextPos, ef);
|
|
109546
|
+
nextPos += 4 + bytes + 4; // block start + skip + block end
|
|
109547
|
+
}
|
|
109548
|
+
|
|
109549
|
+
// skip the first structure since it was read from PDB already
|
|
109550
|
+
if(i == 0) continue;
|
|
109551
|
+
|
|
109552
|
+
let molNum = i + 1; // to avoid the same molNum as the PDB structure
|
|
109553
|
+
for(let j = 0; j < natom; ++j) {
|
|
109554
|
+
let coord = new Vector3$1(frame.x[j], frame.y[j], frame.z[j]);
|
|
109555
|
+
|
|
109556
|
+
let atom = me.hashUtilsCls.cloneHash(ic.atoms[j + 1]);
|
|
109557
|
+
|
|
109558
|
+
atom.serial = serial;
|
|
109559
|
+
atom.structure = atom.structure + molNum;
|
|
109560
|
+
atom.coord = coord;
|
|
109561
|
+
atom.bonds = [].concat(ic.atoms[j + 1].bonds);
|
|
109562
|
+
|
|
109563
|
+
// update bonds
|
|
109564
|
+
for(let k = 0, kl = atom.bonds.length; k < kl; ++k) {
|
|
109565
|
+
atom.bonds[k] = parseInt(atom.bonds[k]) + natom * i;
|
|
109566
|
+
}
|
|
109567
|
+
|
|
109568
|
+
ic.atoms[serial] = atom;
|
|
109569
|
+
|
|
109570
|
+
// assign extra info
|
|
109571
|
+
ic.dAtoms[serial] = 1;
|
|
109572
|
+
ic.hAtoms[serial] = 1;
|
|
109573
|
+
|
|
109574
|
+
let chainid = atom.structure + '_' + atom.chain;
|
|
109575
|
+
let residid = chainid + '_' + atom.resi;
|
|
109576
|
+
ic.secondaries[residid] = atom.ss;
|
|
109577
|
+
ic.residueId2Name[residid] = me.utilsCls.residueName2Abbr(atom.resn);
|
|
109578
|
+
|
|
109579
|
+
++serial;
|
|
109580
|
+
}
|
|
109581
|
+
|
|
109582
|
+
// update ic.structures, ic.residues and ic.chains
|
|
109583
|
+
for(let structure in structuresOri) {
|
|
109584
|
+
let structure2 = structure + molNum;
|
|
109585
|
+
ic.structures[structure2] = [];
|
|
109586
|
+
|
|
109587
|
+
for(let k = 0, kl = structuresOri[structure].length; k < kl; ++k) {
|
|
109588
|
+
let idArray = structuresOri[structure][k].split('_');
|
|
109589
|
+
ic.structures[structure2].push(structure2 + '_' + idArray[1]);
|
|
109590
|
+
}
|
|
109591
|
+
}
|
|
109592
|
+
|
|
109593
|
+
for(let j in residuesOri) {
|
|
109594
|
+
let idArray = j.split('_');
|
|
109595
|
+
let structure2 = idArray[0] + molNum;
|
|
109596
|
+
let residid2 = structure2 + '_' + idArray[1] + '_' + idArray[2];
|
|
109597
|
+
ic.residues[residid2] = {};
|
|
109598
|
+
|
|
109599
|
+
for(let k in residuesOri[j]) {
|
|
109600
|
+
ic.residues[residid2][parseInt(k) + natom * i] = 1;
|
|
109601
|
+
}
|
|
109602
|
+
}
|
|
109603
|
+
|
|
109604
|
+
for(let j in chainsOri) {
|
|
109605
|
+
let idArray = j.split('_');
|
|
109606
|
+
let structure2 = idArray[0] + molNum;
|
|
109607
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
109608
|
+
|
|
109609
|
+
// ic.chainsSeq[chainid2] = [].concat(ic.chainsSeq[j]);
|
|
109610
|
+
|
|
109611
|
+
ic.chains[chainid2] = {};
|
|
109612
|
+
for(let k in chainsOri[j]) {
|
|
109613
|
+
ic.chains[chainid2][parseInt(k)+ natom * i] = 1;
|
|
109614
|
+
}
|
|
109615
|
+
}
|
|
109616
|
+
|
|
109617
|
+
// update ic.proteins, etc
|
|
109618
|
+
for(let j in proteinsOri) {
|
|
109619
|
+
ic.proteins[parseInt(j) + natom * i] = 1;
|
|
109620
|
+
}
|
|
109621
|
+
for(let j in nucleotidesOri) {
|
|
109622
|
+
ic.nucleotides[parseInt(j) + natom * i] = 1;
|
|
109623
|
+
}
|
|
109624
|
+
for(let j in waterOri) {
|
|
109625
|
+
ic.water[parseInt(j) + natom * i] = 1;
|
|
109626
|
+
}
|
|
109627
|
+
for(let j in ionsOri) {
|
|
109628
|
+
ic.ions[parseInt(j) + natom * i] = 1;
|
|
109629
|
+
}
|
|
109630
|
+
for(let j in chemicalsOri) {
|
|
109631
|
+
ic.chemicals[parseInt(j) + natom * i] = 1;
|
|
109632
|
+
}
|
|
109633
|
+
|
|
109634
|
+
// set ic.ncbi2resid and ic.resid2ncbi
|
|
109635
|
+
for(let chainid in chainsOri) {
|
|
109636
|
+
let idArray = chainid.split('_');
|
|
109637
|
+
let structure2 = idArray[0] + molNum;
|
|
109638
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
109639
|
+
|
|
109640
|
+
for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
|
|
109641
|
+
// NCBI residue number starts from 1 and increases continuously
|
|
109642
|
+
let residNCBI = chainid2 + '_' + (j+1).toString();
|
|
109643
|
+
let resid = chainid2 + '_' + ic.chainsSeq[chainid][j].resi;
|
|
109644
|
+
ic.ncbi2resid[residNCBI] = resid;
|
|
109645
|
+
ic.resid2ncbi[resid] = residNCBI;
|
|
109646
|
+
}
|
|
109647
|
+
}
|
|
109648
|
+
}
|
|
109649
|
+
|
|
109650
|
+
ic.molTitle = header.TITLE;
|
|
109651
|
+
ic.inputid = 'stru';
|
|
109652
|
+
|
|
109653
|
+
// ic.ParserUtilsCls.setMaxD();
|
|
109654
|
+
|
|
109655
|
+
ic.saveFileCls.showTitle();
|
|
109656
|
+
|
|
109657
|
+
return true;
|
|
109658
|
+
}
|
|
109659
|
+
|
|
109660
|
+
async showRmsdPlot() { let ic = this.icn3d, me = ic.icn3dui;
|
|
109661
|
+
if(ic.bChartjs === undefined) {
|
|
109662
|
+
let url = "https://cdn.jsdelivr.net/npm/chart.js";
|
|
109663
|
+
await me.getAjaxPromise(url, 'script');
|
|
109664
|
+
|
|
109665
|
+
ic.bChartjs = true;
|
|
109666
|
+
}
|
|
109667
|
+
|
|
109668
|
+
$("#" + me.rmsdplotid).empty();
|
|
109669
|
+
me.htmlCls.dialogCls.openDlg('dl_rmsdplot', 'RMSD Plot');
|
|
109670
|
+
|
|
109671
|
+
let dataSet = [];
|
|
109672
|
+
let structureArray = Object.keys(ic.structures);
|
|
109673
|
+
let coord1 = [], coord2 = [];
|
|
109674
|
+
for(let i = 0, il = structureArray.length; i < il; ++i) {
|
|
109675
|
+
let chainArray = ic.structures[structureArray[i]];
|
|
109676
|
+
|
|
109677
|
+
let coord = [];
|
|
109678
|
+
let nAtoms = 0;
|
|
109679
|
+
for(let j = 0, jl = chainArray.length; j < jl; ++j) {
|
|
109680
|
+
let chainid = chainArray[j];
|
|
109681
|
+
for(let k in ic.chains[chainid]) {
|
|
109682
|
+
let atom = ic.atoms[k];
|
|
109683
|
+
// only align proteins
|
|
109684
|
+
if(ic.proteins.hasOwnProperty(atom.serial)) {
|
|
109685
|
+
coord.push(atom.coord);
|
|
109686
|
+
++nAtoms;
|
|
109687
|
+
}
|
|
109688
|
+
}
|
|
109689
|
+
}
|
|
109690
|
+
|
|
109691
|
+
if(i == 0) {
|
|
109692
|
+
coord1 = [].concat(coord);
|
|
109693
|
+
}
|
|
109694
|
+
else {
|
|
109695
|
+
coord2 = coord;
|
|
109696
|
+
}
|
|
109697
|
+
|
|
109698
|
+
if(i > 0) {
|
|
109699
|
+
let result = me.rmsdSuprCls.getRmsdSuprCls(coord1, coord2, nAtoms);
|
|
109700
|
+
let rmsd = (result.rmsd * 0.1).toPrecision(4); // convert from Å to nm
|
|
109701
|
+
|
|
109702
|
+
let time = ic.TIMEOFFSET + (i * ic.DELTA).toPrecision(4);
|
|
109703
|
+
dataSet.push({x: time, y: rmsd});
|
|
109704
|
+
}
|
|
109705
|
+
}
|
|
109706
|
+
|
|
109707
|
+
ic.mdDataSet = dataSet;
|
|
109708
|
+
if(me.bNode) console.log(dataSet);
|
|
109709
|
+
|
|
109710
|
+
let stepSize = (structureArray.length - 1) * ic.DELTA / 10; // 10 ticks
|
|
109711
|
+
|
|
109712
|
+
// https://www.chartjs.org/docs/latest/samples/line/line.html
|
|
109713
|
+
// const ctx = $("#" + me.rmsdplotid)[0].getContext('2d');
|
|
109714
|
+
const ctx = $("#" + me.rmsdplotid)[0];
|
|
109715
|
+
|
|
109716
|
+
new Chart(ctx, {
|
|
109717
|
+
type: 'line',
|
|
109718
|
+
data: {
|
|
109719
|
+
datasets: [{
|
|
109720
|
+
label: 'RMSD',
|
|
109721
|
+
data: dataSet
|
|
109722
|
+
}]
|
|
109723
|
+
},
|
|
109724
|
+
options: {
|
|
109725
|
+
responsive: true,
|
|
109726
|
+
scales: {
|
|
109727
|
+
x: { // X-axis configuration
|
|
109728
|
+
title: {
|
|
109729
|
+
display: true, // Show the X-axis label
|
|
109730
|
+
text: 'Time (ps)' // Text for the X-axis label
|
|
109731
|
+
},
|
|
109732
|
+
type: 'linear', // Required for numerical x-axis
|
|
109733
|
+
position: 'bottom',
|
|
109734
|
+
ticks: {
|
|
109735
|
+
stepSize: stepSize
|
|
109736
|
+
}
|
|
109737
|
+
},
|
|
109738
|
+
y: { // Y-axis configuration (defaults to numeric scale)
|
|
109739
|
+
title: {
|
|
109740
|
+
display: true, // Show the Y-axis label
|
|
109741
|
+
text: 'RMSD (nm)' // Text for the Y-axis label
|
|
109742
|
+
}
|
|
109743
|
+
}
|
|
109744
|
+
}
|
|
109745
|
+
}
|
|
109746
|
+
});
|
|
109747
|
+
}
|
|
109748
|
+
}
|
|
109749
|
+
|
|
109750
|
+
/**
|
|
109751
|
+
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
109752
|
+
*/
|
|
109753
|
+
|
|
109754
|
+
class XtcParser {
|
|
109755
|
+
constructor(icn3d) {
|
|
109756
|
+
this.icn3d = icn3d;
|
|
109757
|
+
|
|
109758
|
+
icn3d.DELTA = 1;
|
|
109759
|
+
icn3d.TIMEOFFSET = 0;
|
|
109760
|
+
|
|
109761
|
+
this.MagicInts = new Uint32Array([
|
|
109762
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
|
|
109763
|
+
80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
|
|
109764
|
+
1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003,
|
|
109765
|
+
16384, 20642, 26007, 32768, 41285, 52015, 65536, 82570, 104031,
|
|
109766
|
+
131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
|
|
109767
|
+
832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021,
|
|
109768
|
+
4194304, 5284491, 6658042, 8388607, 10568983, 13316085, 16777216
|
|
109769
|
+
]);
|
|
109770
|
+
this.FirstIdx = 9;
|
|
109771
|
+
|
|
109772
|
+
this._tmpBytes = new Uint8Array(32);
|
|
109773
|
+
let _buffer = new ArrayBuffer(8 * 3);
|
|
109774
|
+
this.buf = new Int32Array(_buffer);
|
|
109775
|
+
this.uint32view = new Uint32Array(_buffer);
|
|
109776
|
+
this.intBytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
109777
|
+
}
|
|
109778
|
+
|
|
109779
|
+
async loadXtcData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
109780
|
+
let bResult = this.loadXtcAtomData(data);
|
|
109781
|
+
|
|
109782
|
+
if(me.cfg.align === undefined && Object.keys(ic.structures).length == 1) {
|
|
109783
|
+
$("#" + ic.pre + "alternateWrapper").hide();
|
|
109784
|
+
}
|
|
109785
|
+
|
|
109786
|
+
if(!bResult) {
|
|
109787
|
+
var aaa = 1; //alert('The XTC file has the wrong format...');
|
|
109788
|
+
}
|
|
109789
|
+
else {
|
|
109790
|
+
ic.setStyleCls.setAtomStyleByOptions(ic.opts);
|
|
109791
|
+
ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
|
|
109792
|
+
|
|
109793
|
+
// hide water, ions
|
|
109794
|
+
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
109795
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.nucleotides);
|
|
109796
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chemicals);
|
|
109797
|
+
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
109798
|
+
ic.transformCls.zoominSelection();
|
|
109799
|
+
|
|
109800
|
+
// ic.bRender = true;
|
|
109801
|
+
await ic.ParserUtilsCls.renderStructure();
|
|
109802
|
+
|
|
109803
|
+
if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
|
|
109804
|
+
|
|
109805
|
+
//if(me.deferred !== undefined) me.deferred.resolve(); /// if(ic.deferred2 !== undefined) ic.deferred2.resolve();
|
|
109806
|
+
}
|
|
109807
|
+
}
|
|
109808
|
+
|
|
109809
|
+
|
|
109810
|
+
// modified from https://github.com/molstar/molstar/blob/master/src/mol-io/reader/xtc/parser.ts
|
|
109811
|
+
loadXtcAtomData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
109812
|
+
// https://github.com/gromacs/gromacs/blob/master/src/gromacs/fileio/xtcio.cpp
|
|
109813
|
+
// https://github.com/gromacs/gromacs/blob/master/src/gromacs/fileio/libxdrf.cpp
|
|
109814
|
+
|
|
109815
|
+
let bin =(data.buffer && data.buffer instanceof ArrayBuffer) ? data.buffer : data;
|
|
109816
|
+
|
|
109817
|
+
// const dv = new DataView(bin, data.byteOffset);
|
|
109818
|
+
const dv = new DataView(bin);
|
|
109819
|
+
|
|
109820
|
+
data = new Uint8Array(bin);
|
|
109821
|
+
|
|
109822
|
+
// const f = {
|
|
109823
|
+
// frames: [],
|
|
109824
|
+
// boxes: [],
|
|
109825
|
+
// times: [],
|
|
109826
|
+
// timeOffset: 0,
|
|
109827
|
+
// deltaTime: 0
|
|
109828
|
+
// };
|
|
109829
|
+
|
|
109830
|
+
const coordinates = []; //f.frames;
|
|
109831
|
+
const times = []; //f.times;
|
|
109832
|
+
|
|
109833
|
+
const minMaxInt = [0, 0, 0, 0, 0, 0];
|
|
109834
|
+
const sizeint = [0, 0, 0];
|
|
109835
|
+
const bitsizeint = [0, 0, 0];
|
|
109836
|
+
const sizesmall = [0, 0, 0];
|
|
109837
|
+
const thiscoord = [0.1, 0.1, 0.1];
|
|
109838
|
+
const prevcoord = [0.1, 0.1, 0.1];
|
|
109839
|
+
|
|
109840
|
+
let offset = 0, natom;
|
|
109841
|
+
|
|
109842
|
+
while (true) {
|
|
109843
|
+
let frameCoords;
|
|
109844
|
+
|
|
109845
|
+
// const magicnum = dv.getInt32(offset)
|
|
109846
|
+
natom = dv.getInt32(offset + 4);
|
|
109847
|
+
// const step = dv.getInt32(offset + 8)
|
|
109848
|
+
offset += 12;
|
|
109849
|
+
|
|
109850
|
+
if(natom != Object.keys(ic.atoms).length) {
|
|
109851
|
+
var aaa = 1; //alert('The number of atoms in the XTC file does not match the number of atoms in the PDB file: ' + natom + ' != ' + Object.keys(ic.atoms).length);
|
|
109852
|
+
return false;
|
|
109853
|
+
}
|
|
109854
|
+
|
|
109855
|
+
times.push(dv.getFloat32(offset));
|
|
109856
|
+
offset += 4;
|
|
109857
|
+
|
|
109858
|
+
const box = new Float32Array(9);
|
|
109859
|
+
for (let i = 0; i < 9; ++i) {
|
|
109860
|
+
box[i] = dv.getFloat32(offset) * 10;
|
|
109861
|
+
offset += 4;
|
|
109862
|
+
}
|
|
109863
|
+
|
|
109864
|
+
if (natom <= 9) { // no compression
|
|
109865
|
+
frameCoords = { count: natom, x: new Float32Array(natom), y: new Float32Array(natom), z: new Float32Array(natom) };
|
|
109866
|
+
offset += 4;
|
|
109867
|
+
for (let i = 0; i < natom; ++i) {
|
|
109868
|
+
frameCoords.x[i] = dv.getFloat32(offset);
|
|
109869
|
+
frameCoords.y[i] = dv.getFloat32(offset + 4);
|
|
109870
|
+
frameCoords.z[i] = dv.getFloat32(offset + 8);
|
|
109871
|
+
offset += 12;
|
|
109872
|
+
}
|
|
109873
|
+
} else {
|
|
109874
|
+
this.buf[0] = this.buf[1] = this.buf[2] = 0;
|
|
109875
|
+
sizeint[0] = sizeint[1] = sizeint[2] = 0;
|
|
109876
|
+
sizesmall[0] = sizesmall[1] = sizesmall[2] = 0;
|
|
109877
|
+
bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
|
|
109878
|
+
thiscoord[0] = thiscoord[1] = thiscoord[2] = 0;
|
|
109879
|
+
prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
|
|
109880
|
+
|
|
109881
|
+
frameCoords = { count: natom, x: new Float32Array(natom), y: new Float32Array(natom), z: new Float32Array(natom) };
|
|
109882
|
+
let lfp = 0;
|
|
109883
|
+
|
|
109884
|
+
const lsize = dv.getInt32(offset);
|
|
109885
|
+
offset += 4;
|
|
109886
|
+
const precision = dv.getFloat32(offset);
|
|
109887
|
+
offset += 4;
|
|
109888
|
+
|
|
109889
|
+
minMaxInt[0] = dv.getInt32(offset);
|
|
109890
|
+
minMaxInt[1] = dv.getInt32(offset + 4);
|
|
109891
|
+
minMaxInt[2] = dv.getInt32(offset + 8);
|
|
109892
|
+
minMaxInt[3] = dv.getInt32(offset + 12);
|
|
109893
|
+
minMaxInt[4] = dv.getInt32(offset + 16);
|
|
109894
|
+
minMaxInt[5] = dv.getInt32(offset + 20);
|
|
109895
|
+
sizeint[0] = minMaxInt[3] - minMaxInt[0] + 1;
|
|
109896
|
+
sizeint[1] = minMaxInt[4] - minMaxInt[1] + 1;
|
|
109897
|
+
sizeint[2] = minMaxInt[5] - minMaxInt[2] + 1;
|
|
109898
|
+
offset += 24;
|
|
109899
|
+
|
|
109900
|
+
let bitsize;
|
|
109901
|
+
if ((sizeint[0] | sizeint[1] | sizeint[2]) > 0xffffff) {
|
|
109902
|
+
bitsizeint[0] = this.sizeOfInt(sizeint[0]);
|
|
109903
|
+
bitsizeint[1] = this.sizeOfInt(sizeint[1]);
|
|
109904
|
+
bitsizeint[2] = this.sizeOfInt(sizeint[2]);
|
|
109905
|
+
bitsize = 0; // flag the use of large sizes
|
|
109906
|
+
} else {
|
|
109907
|
+
bitsize = this.sizeOfInts(3, sizeint);
|
|
109908
|
+
}
|
|
109909
|
+
|
|
109910
|
+
let smallidx = dv.getInt32(offset);
|
|
109911
|
+
offset += 4;
|
|
109912
|
+
|
|
109913
|
+
let tmpIdx = smallidx - 1;
|
|
109914
|
+
tmpIdx = (this.FirstIdx > tmpIdx) ? this.FirstIdx : tmpIdx;
|
|
109915
|
+
let smaller = (this.MagicInts[tmpIdx] / 2) | 0;
|
|
109916
|
+
let smallnum = (this.MagicInts[smallidx] / 2) | 0;
|
|
109917
|
+
|
|
109918
|
+
sizesmall[0] = sizesmall[1] = sizesmall[2] = this.MagicInts[smallidx];
|
|
109919
|
+
|
|
109920
|
+
const adz = Math.ceil(dv.getInt32(offset) / 4) * 4;
|
|
109921
|
+
offset += 4;
|
|
109922
|
+
|
|
109923
|
+
const invPrecision = 1.0 / precision;
|
|
109924
|
+
let run = 0;
|
|
109925
|
+
let i = 0;
|
|
109926
|
+
|
|
109927
|
+
// const this.buf8 = new Uint8Array(data.this.buffer, data.byteOffset + offset, 32 * 4); // 229...
|
|
109928
|
+
|
|
109929
|
+
thiscoord[0] = thiscoord[1] = thiscoord[2] = 0;
|
|
109930
|
+
|
|
109931
|
+
while (i < lsize) {
|
|
109932
|
+
if (bitsize === 0) {
|
|
109933
|
+
thiscoord[0] = this.decodeBits(data, offset, bitsizeint[0]);
|
|
109934
|
+
thiscoord[1] = this.decodeBits(data, offset, bitsizeint[1]);
|
|
109935
|
+
thiscoord[2] = this.decodeBits(data, offset, bitsizeint[2]);
|
|
109936
|
+
} else {
|
|
109937
|
+
this.decodeInts(data, offset, bitsize, sizeint, thiscoord);
|
|
109938
|
+
}
|
|
109939
|
+
|
|
109940
|
+
i++;
|
|
109941
|
+
|
|
109942
|
+
thiscoord[0] += minMaxInt[0];
|
|
109943
|
+
thiscoord[1] += minMaxInt[1];
|
|
109944
|
+
thiscoord[2] += minMaxInt[2];
|
|
109945
|
+
|
|
109946
|
+
prevcoord[0] = thiscoord[0];
|
|
109947
|
+
prevcoord[1] = thiscoord[1];
|
|
109948
|
+
prevcoord[2] = thiscoord[2];
|
|
109949
|
+
|
|
109950
|
+
const flag = this.decodeBits(data, offset, 1);
|
|
109951
|
+
let isSmaller = 0;
|
|
109952
|
+
|
|
109953
|
+
if (flag === 1) {
|
|
109954
|
+
run = this.decodeBits(data, offset, 5);
|
|
109955
|
+
isSmaller = run % 3;
|
|
109956
|
+
run -= isSmaller;
|
|
109957
|
+
isSmaller--;
|
|
109958
|
+
}
|
|
109959
|
+
|
|
109960
|
+
// if ((lfp-ptrstart)+run > size3){
|
|
109961
|
+
// fprintf(stderr, "(xdrfile error) Buffer overrun during decompression.\n");
|
|
109962
|
+
// return 0;
|
|
109963
|
+
// }
|
|
109964
|
+
|
|
109965
|
+
if (run > 0) {
|
|
109966
|
+
thiscoord[0] = thiscoord[1] = thiscoord[2] = 0;
|
|
109967
|
+
|
|
109968
|
+
for (let k = 0; k < run; k += 3) {
|
|
109969
|
+
this.decodeInts(data, offset, smallidx, sizesmall, thiscoord);
|
|
109970
|
+
i++;
|
|
109971
|
+
|
|
109972
|
+
thiscoord[0] += prevcoord[0] - smallnum;
|
|
109973
|
+
thiscoord[1] += prevcoord[1] - smallnum;
|
|
109974
|
+
thiscoord[2] += prevcoord[2] - smallnum;
|
|
109975
|
+
|
|
109976
|
+
if (k === 0) {
|
|
109977
|
+
// interchange first with second atom for
|
|
109978
|
+
// better compression of water molecules
|
|
109979
|
+
let tmpSwap = thiscoord[0];
|
|
109980
|
+
thiscoord[0] = prevcoord[0];
|
|
109981
|
+
prevcoord[0] = tmpSwap;
|
|
109982
|
+
|
|
109983
|
+
tmpSwap = thiscoord[1];
|
|
109984
|
+
thiscoord[1] = prevcoord[1];
|
|
109985
|
+
prevcoord[1] = tmpSwap;
|
|
109986
|
+
|
|
109987
|
+
tmpSwap = thiscoord[2];
|
|
109988
|
+
thiscoord[2] = prevcoord[2];
|
|
109989
|
+
prevcoord[2] = tmpSwap;
|
|
109990
|
+
|
|
109991
|
+
frameCoords.x[lfp] = prevcoord[0] * invPrecision;
|
|
109992
|
+
frameCoords.y[lfp] = prevcoord[1] * invPrecision;
|
|
109993
|
+
frameCoords.z[lfp] = prevcoord[2] * invPrecision;
|
|
109994
|
+
lfp++;
|
|
109995
|
+
} else {
|
|
109996
|
+
prevcoord[0] = thiscoord[0];
|
|
109997
|
+
prevcoord[1] = thiscoord[1];
|
|
109998
|
+
prevcoord[2] = thiscoord[2];
|
|
109999
|
+
}
|
|
110000
|
+
frameCoords.x[lfp] = thiscoord[0] * invPrecision;
|
|
110001
|
+
frameCoords.y[lfp] = thiscoord[1] * invPrecision;
|
|
110002
|
+
frameCoords.z[lfp] = thiscoord[2] * invPrecision;
|
|
110003
|
+
lfp++;
|
|
110004
|
+
}
|
|
110005
|
+
} else {
|
|
110006
|
+
frameCoords.x[lfp] = thiscoord[0] * invPrecision;
|
|
110007
|
+
frameCoords.y[lfp] = thiscoord[1] * invPrecision;
|
|
110008
|
+
frameCoords.z[lfp] = thiscoord[2] * invPrecision;
|
|
110009
|
+
lfp++;
|
|
110010
|
+
}
|
|
110011
|
+
|
|
110012
|
+
smallidx += isSmaller;
|
|
110013
|
+
|
|
110014
|
+
if (isSmaller < 0) {
|
|
110015
|
+
smallnum = smaller;
|
|
110016
|
+
if (smallidx > this.FirstIdx) {
|
|
110017
|
+
smaller = (this.MagicInts[smallidx - 1] / 2) | 0;
|
|
110018
|
+
} else {
|
|
110019
|
+
smaller = 0;
|
|
110020
|
+
}
|
|
110021
|
+
} else if (isSmaller > 0) {
|
|
110022
|
+
smaller = smallnum;
|
|
110023
|
+
smallnum = (this.MagicInts[smallidx] / 2) | 0;
|
|
110024
|
+
}
|
|
110025
|
+
sizesmall[0] = sizesmall[1] = sizesmall[2] = this.MagicInts[smallidx];
|
|
110026
|
+
|
|
110027
|
+
if (sizesmall[0] === 0 || sizesmall[1] === 0 || sizesmall[2] === 0) {
|
|
110028
|
+
undefinedError();
|
|
110029
|
+
}
|
|
110030
|
+
}
|
|
110031
|
+
offset += adz;
|
|
110032
|
+
}
|
|
110033
|
+
|
|
110034
|
+
let factor = 10;
|
|
110035
|
+
for (let c = 0; c < natom; c++) {
|
|
110036
|
+
frameCoords.x[c] *= factor;
|
|
110037
|
+
frameCoords.y[c] *= factor;
|
|
110038
|
+
frameCoords.z[c] *= factor;
|
|
110039
|
+
}
|
|
110040
|
+
|
|
110041
|
+
coordinates.push(frameCoords);
|
|
110042
|
+
|
|
110043
|
+
// if (ctx.shouldUpdate) {
|
|
110044
|
+
// await ctx.update({ current: offset, max: data.length });
|
|
110045
|
+
// }
|
|
110046
|
+
|
|
110047
|
+
// if (offset >= data.length) break;
|
|
110048
|
+
if (offset >= dv.byteLength) break;
|
|
110049
|
+
}
|
|
110050
|
+
|
|
110051
|
+
ic.frames = coordinates.length;
|
|
110052
|
+
|
|
110053
|
+
if (times.length >= 1) {
|
|
110054
|
+
ic.TIMEOFFSET = times[0];
|
|
110055
|
+
}
|
|
110056
|
+
if (times.length >= 2) {
|
|
110057
|
+
ic.DELTA = times[1] - times[0];
|
|
110058
|
+
}
|
|
110059
|
+
|
|
110060
|
+
// frames
|
|
110061
|
+
let structuresOri = me.hashUtilsCls.cloneHash(ic.structures);
|
|
110062
|
+
let residuesOri = me.hashUtilsCls.cloneHash(ic.residues);
|
|
110063
|
+
let chainsOri = me.hashUtilsCls.cloneHash(ic.chains);
|
|
110064
|
+
|
|
110065
|
+
let proteinsOri = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
110066
|
+
let nucleotidesOri = me.hashUtilsCls.cloneHash(ic.nucleotides);
|
|
110067
|
+
let waterOri = me.hashUtilsCls.cloneHash(ic.water);
|
|
110068
|
+
let ionsOri = me.hashUtilsCls.cloneHash(ic.ions);
|
|
110069
|
+
let chemicalsOri = me.hashUtilsCls.cloneHash(ic.chemicals);
|
|
110070
|
+
|
|
110071
|
+
// let serial = natom + 1; // a preloaded PDB structure would have atom serial from 1 to natom
|
|
110072
|
+
let serial = 1;
|
|
110073
|
+
|
|
110074
|
+
for (let i = 0, n = coordinates.length; i < n; ++i) {
|
|
110075
|
+
// skip the first structure since it was read from PDB already
|
|
110076
|
+
// if(i == 0) continue;
|
|
110077
|
+
|
|
110078
|
+
// rewrite the coordinates of the first structure
|
|
110079
|
+
let frame = coordinates[i];
|
|
110080
|
+
|
|
110081
|
+
// let molNum = i + 1; // to avoid the same molNum as the PDB structure
|
|
110082
|
+
let molNum = (i == 0) ? '' : i;
|
|
110083
|
+
for(let j = 0; j < natom; ++j) {
|
|
110084
|
+
let coord = new Vector3$1(frame.x[j], frame.y[j], frame.z[j]);
|
|
110085
|
+
let atom = me.hashUtilsCls.cloneHash(ic.atoms[j + 1]);
|
|
110086
|
+
|
|
110087
|
+
atom.serial = serial;
|
|
110088
|
+
atom.structure = atom.structure + molNum;
|
|
110089
|
+
atom.coord = coord;
|
|
110090
|
+
atom.bonds = [].concat(ic.atoms[j + 1].bonds);
|
|
110091
|
+
|
|
110092
|
+
// update bonds
|
|
110093
|
+
for(let k = 0, kl = atom.bonds.length; k < kl; ++k) {
|
|
110094
|
+
atom.bonds[k] = parseInt(atom.bonds[k]) + natom * i;
|
|
110095
|
+
}
|
|
110096
|
+
|
|
110097
|
+
ic.atoms[serial] = atom;
|
|
110098
|
+
|
|
110099
|
+
// assign extra info
|
|
110100
|
+
ic.dAtoms[serial] = 1;
|
|
110101
|
+
ic.hAtoms[serial] = 1;
|
|
110102
|
+
|
|
110103
|
+
let chainid = atom.structure + '_' + atom.chain;
|
|
110104
|
+
let residid = chainid + '_' + atom.resi;
|
|
110105
|
+
ic.secondaries[residid] = atom.ss;
|
|
110106
|
+
ic.residueId2Name[residid] = me.utilsCls.residueName2Abbr(atom.resn);
|
|
110107
|
+
|
|
110108
|
+
++serial;
|
|
110109
|
+
}
|
|
110110
|
+
|
|
110111
|
+
// update ic.structures, ic.residues and ic.chains
|
|
110112
|
+
for(let structure in structuresOri) {
|
|
110113
|
+
let structure2 = structure + molNum;
|
|
110114
|
+
ic.structures[structure2] = [];
|
|
110115
|
+
|
|
110116
|
+
for(let k = 0, kl = structuresOri[structure].length; k < kl; ++k) {
|
|
110117
|
+
let idArray = structuresOri[structure][k].split('_');
|
|
110118
|
+
ic.structures[structure2].push(structure2 + '_' + idArray[1]);
|
|
110119
|
+
}
|
|
110120
|
+
}
|
|
110121
|
+
|
|
110122
|
+
for(let j in residuesOri) {
|
|
110123
|
+
let idArray = j.split('_');
|
|
110124
|
+
let structure2 = idArray[0] + molNum;
|
|
110125
|
+
let residid2 = structure2 + '_' + idArray[1] + '_' + idArray[2];
|
|
110126
|
+
ic.residues[residid2] = {};
|
|
110127
|
+
|
|
110128
|
+
for(let k in residuesOri[j]) {
|
|
110129
|
+
ic.residues[residid2][parseInt(k) + natom * i] = 1;
|
|
110130
|
+
}
|
|
110131
|
+
}
|
|
110132
|
+
|
|
110133
|
+
for(let j in chainsOri) {
|
|
110134
|
+
let idArray = j.split('_');
|
|
110135
|
+
let structure2 = idArray[0] + molNum;
|
|
110136
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
110137
|
+
|
|
110138
|
+
// ic.chainsSeq[chainid2] = [].concat(ic.chainsSeq[j]);
|
|
110139
|
+
|
|
110140
|
+
ic.chains[chainid2] = {};
|
|
110141
|
+
for(let k in chainsOri[j]) {
|
|
110142
|
+
ic.chains[chainid2][parseInt(k)+ natom * i] = 1;
|
|
110143
|
+
}
|
|
110144
|
+
}
|
|
110145
|
+
|
|
110146
|
+
// update ic.proteins, etc
|
|
110147
|
+
for(let j in proteinsOri) {
|
|
110148
|
+
ic.proteins[parseInt(j) + natom * i] = 1;
|
|
110149
|
+
}
|
|
110150
|
+
for(let j in nucleotidesOri) {
|
|
110151
|
+
ic.nucleotides[parseInt(j) + natom * i] = 1;
|
|
110152
|
+
}
|
|
110153
|
+
for(let j in waterOri) {
|
|
110154
|
+
ic.water[parseInt(j) + natom * i] = 1;
|
|
110155
|
+
}
|
|
110156
|
+
for(let j in ionsOri) {
|
|
110157
|
+
ic.ions[parseInt(j) + natom * i] = 1;
|
|
110158
|
+
}
|
|
110159
|
+
for(let j in chemicalsOri) {
|
|
110160
|
+
ic.chemicals[parseInt(j) + natom * i] = 1;
|
|
110161
|
+
}
|
|
110162
|
+
|
|
110163
|
+
// set ic.ncbi2resid and ic.resid2ncbi
|
|
110164
|
+
for(let chainid in chainsOri) {
|
|
110165
|
+
let idArray = chainid.split('_');
|
|
110166
|
+
let structure2 = idArray[0] + molNum;
|
|
110167
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
110168
|
+
|
|
110169
|
+
for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
|
|
110170
|
+
// NCBI residue number starts from 1 and increases continuously
|
|
110171
|
+
let residNCBI = chainid2 + '_' + (j+1).toString();
|
|
110172
|
+
let resid = chainid2 + '_' + ic.chainsSeq[chainid][j].resi;
|
|
110173
|
+
ic.ncbi2resid[residNCBI] = resid;
|
|
110174
|
+
ic.resid2ncbi[resid] = residNCBI;
|
|
110175
|
+
}
|
|
110176
|
+
}
|
|
110177
|
+
}
|
|
110178
|
+
|
|
110179
|
+
// ic.molTitle = header.TITLE;
|
|
110180
|
+
ic.inputid = 'stru';
|
|
110181
|
+
|
|
110182
|
+
// ic.ParserUtilsCls.setMaxD();
|
|
110183
|
+
|
|
110184
|
+
ic.saveFileCls.showTitle();
|
|
110185
|
+
|
|
110186
|
+
return true;
|
|
110187
|
+
}
|
|
110188
|
+
|
|
110189
|
+
sizeOfInt(size) { let ic = this.icn3d; ic.icn3dui;
|
|
110190
|
+
let num = 1;
|
|
110191
|
+
let numOfBits = 0;
|
|
110192
|
+
while (size >= num && numOfBits < 32) {
|
|
110193
|
+
numOfBits++;
|
|
110194
|
+
num <<= 1;
|
|
110195
|
+
}
|
|
110196
|
+
return numOfBits;
|
|
110197
|
+
}
|
|
110198
|
+
|
|
110199
|
+
sizeOfInts(numOfInts, sizes) { let ic = this.icn3d; ic.icn3dui;
|
|
110200
|
+
let numOfBytes = 1;
|
|
110201
|
+
let numOfBits = 0;
|
|
110202
|
+
this._tmpBytes[0] = 1;
|
|
110203
|
+
for (let i = 0; i < numOfInts; i++) {
|
|
110204
|
+
let bytecnt;
|
|
110205
|
+
let tmp = 0;
|
|
110206
|
+
for (bytecnt = 0; bytecnt < numOfBytes; bytecnt++) {
|
|
110207
|
+
tmp += this._tmpBytes[bytecnt] * sizes[i];
|
|
110208
|
+
this._tmpBytes[bytecnt] = tmp & 0xff;
|
|
110209
|
+
tmp >>= 8;
|
|
110210
|
+
}
|
|
110211
|
+
while (tmp !== 0) {
|
|
110212
|
+
this._tmpBytes[bytecnt++] = tmp & 0xff;
|
|
110213
|
+
tmp >>= 8;
|
|
110214
|
+
}
|
|
110215
|
+
numOfBytes = bytecnt;
|
|
110216
|
+
}
|
|
110217
|
+
let num = 1;
|
|
110218
|
+
numOfBytes--;
|
|
110219
|
+
while (this._tmpBytes[numOfBytes] >= num) {
|
|
110220
|
+
numOfBits++;
|
|
110221
|
+
num *= 2;
|
|
110222
|
+
}
|
|
110223
|
+
return numOfBits + numOfBytes * 8;
|
|
110224
|
+
}
|
|
110225
|
+
|
|
110226
|
+
decodeBits(cbuf, offset, numOfBits1) { let ic = this.icn3d; ic.icn3dui;
|
|
110227
|
+
let numOfBits = numOfBits1;
|
|
110228
|
+
const mask = (1 << numOfBits) - 1;
|
|
110229
|
+
let lastBB0 = this.uint32view[1];
|
|
110230
|
+
let lastBB1 = this.uint32view[2];
|
|
110231
|
+
let cnt = this.buf[0];
|
|
110232
|
+
let num = 0;
|
|
110233
|
+
|
|
110234
|
+
while (numOfBits >= 8) {
|
|
110235
|
+
lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt++];
|
|
110236
|
+
num |= (lastBB1 >> lastBB0) << (numOfBits - 8);
|
|
110237
|
+
numOfBits -= 8;
|
|
110238
|
+
}
|
|
110239
|
+
|
|
110240
|
+
if (numOfBits > 0) {
|
|
110241
|
+
if (lastBB0 < numOfBits) {
|
|
110242
|
+
lastBB0 += 8;
|
|
110243
|
+
lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt++];
|
|
110244
|
+
}
|
|
110245
|
+
lastBB0 -= numOfBits;
|
|
110246
|
+
num |= (lastBB1 >> lastBB0) & ((1 << numOfBits) - 1);
|
|
110247
|
+
}
|
|
110248
|
+
|
|
110249
|
+
num &= mask;
|
|
110250
|
+
this.buf[0] = cnt;
|
|
110251
|
+
this.buf[1] = lastBB0;
|
|
110252
|
+
this.buf[2] = lastBB1;
|
|
110253
|
+
|
|
110254
|
+
return num;
|
|
110255
|
+
}
|
|
110256
|
+
|
|
110257
|
+
decodeByte(cbuf, offset) { let ic = this.icn3d; ic.icn3dui;
|
|
110258
|
+
// special version of decodeBits with numOfBits = 8
|
|
110259
|
+
|
|
110260
|
+
// const mask = 0xff; // (1 << 8) - 1;
|
|
110261
|
+
// let lastBB0 = uint32view[1];
|
|
110262
|
+
let lastBB1 = this.uint32view[2];
|
|
110263
|
+
const cnt = this.buf[0];
|
|
110264
|
+
|
|
110265
|
+
lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt];
|
|
110266
|
+
|
|
110267
|
+
this.buf[0] = cnt + 1;
|
|
110268
|
+
// this.buf[1] = lastBB0;
|
|
110269
|
+
this.buf[2] = lastBB1;
|
|
110270
|
+
|
|
110271
|
+
return (lastBB1 >> this.uint32view[1]) & 0xff;
|
|
110272
|
+
}
|
|
110273
|
+
|
|
110274
|
+
decodeInts(cbuf, offset, numOfBits1, sizes, nums) { let ic = this.icn3d; ic.icn3dui;
|
|
110275
|
+
let numOfBits = numOfBits1;
|
|
110276
|
+
let numOfBytes = 0;
|
|
110277
|
+
|
|
110278
|
+
this.intBytes[0] = 0;
|
|
110279
|
+
this.intBytes[1] = 0;
|
|
110280
|
+
this.intBytes[2] = 0;
|
|
110281
|
+
this.intBytes[3] = 0;
|
|
110282
|
+
|
|
110283
|
+
while (numOfBits > 8) {
|
|
110284
|
+
// this is inversed??? why??? because of the endiannness???
|
|
110285
|
+
this.intBytes[numOfBytes++] = this.decodeByte(cbuf, offset);
|
|
110286
|
+
numOfBits -= 8;
|
|
110287
|
+
}
|
|
110288
|
+
|
|
110289
|
+
if (numOfBits > 0) {
|
|
110290
|
+
this.intBytes[numOfBytes++] = this.decodeBits(cbuf, offset, numOfBits);
|
|
110291
|
+
}
|
|
110292
|
+
|
|
110293
|
+
for (let i = 2; i > 0; i--) {
|
|
110294
|
+
let num = 0;
|
|
110295
|
+
const s = sizes[i];
|
|
110296
|
+
for (let j = numOfBytes - 1; j >= 0; j--) {
|
|
110297
|
+
num = (num << 8) | this.intBytes[j];
|
|
110298
|
+
const t = (num / s) | 0;
|
|
110299
|
+
this.intBytes[j] = t;
|
|
110300
|
+
num = num - t * s;
|
|
110301
|
+
}
|
|
110302
|
+
nums[i] = num;
|
|
110303
|
+
}
|
|
110304
|
+
nums[0] = this.intBytes[0] | (this.intBytes[1] << 8) | (this.intBytes[2] << 16) | (this.intBytes[3] << 24);
|
|
110305
|
+
}
|
|
110306
|
+
}
|
|
110307
|
+
|
|
109022
110308
|
/**
|
|
109023
110309
|
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
109024
110310
|
*/
|
|
@@ -114913,7 +116199,15 @@ class LoadPDB {
|
|
|
114913
116199
|
prevCarbonArray.push(atom);
|
|
114914
116200
|
}
|
|
114915
116201
|
|
|
114916
|
-
if(
|
|
116202
|
+
if(atom.resn === 'HOH' || atom.resn === 'WAT' || atom.resn === 'SOL') {
|
|
116203
|
+
ic.water[atom.serial] = 1;
|
|
116204
|
+
atom.color = me.parasCls.atomColors[atom.elem];
|
|
116205
|
+
}
|
|
116206
|
+
else if($.inArray(atom.resn.trim(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
|
|
116207
|
+
ic.ions[atom.serial] = 1;
|
|
116208
|
+
atom.color = me.parasCls.atomColors[atom.elem];
|
|
116209
|
+
}
|
|
116210
|
+
else if(!atom.het) {
|
|
114917
116211
|
if($.inArray(atom.resn, me.parasCls.nucleotidesArray) !== -1) {
|
|
114918
116212
|
ic.nucleotides[atom.serial] = 1;
|
|
114919
116213
|
//if (atom.name === 'P') {
|
|
@@ -114938,19 +116232,7 @@ class LoadPDB {
|
|
|
114938
116232
|
}
|
|
114939
116233
|
}
|
|
114940
116234
|
else if(atom.het) {
|
|
114941
|
-
|
|
114942
|
-
ic.water[atom.serial] = 1;
|
|
114943
|
-
}
|
|
114944
|
-
//else if(bOpm && atom.resn === 'DUM') {
|
|
114945
|
-
// ic.mem[atom.serial] = 1;
|
|
114946
|
-
//}
|
|
114947
|
-
else if($.inArray(atom.resn, me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
|
|
114948
|
-
ic.ions[atom.serial] = 1;
|
|
114949
|
-
}
|
|
114950
|
-
else {
|
|
114951
|
-
ic.chemicals[atom.serial] = 1;
|
|
114952
|
-
}
|
|
114953
|
-
|
|
116235
|
+
ic.chemicals[atom.serial] = 1;
|
|
114954
116236
|
atom.color = me.parasCls.atomColors[atom.elem];
|
|
114955
116237
|
}
|
|
114956
116238
|
|
|
@@ -117748,6 +119030,18 @@ class ApplyCommand {
|
|
|
117748
119030
|
ic.analysisCls.addLine(parseFloat(p1Array[1]), parseFloat(p1Array[3]), parseFloat(p1Array[5]), parseFloat(p2Array[1]), parseFloat(p2Array[3]), parseFloat(p2Array[5]), color, dashed, type, parseFloat(radius), parseFloat(opacity));
|
|
117749
119031
|
ic.drawCls.draw();
|
|
117750
119032
|
}
|
|
119033
|
+
else if(command.indexOf('add plane') == 0) {
|
|
119034
|
+
let paraArray = command.split(' | ');
|
|
119035
|
+
let p1Array = paraArray[1].split(' ');
|
|
119036
|
+
let p2Array = paraArray[2].split(' ');
|
|
119037
|
+
let p3Array = paraArray[3].split(' ');
|
|
119038
|
+
let color = paraArray[4].substr(paraArray[4].lastIndexOf(' ') + 1);
|
|
119039
|
+
let thickness = (paraArray.length > 5) ? paraArray[5].substr(paraArray[5].lastIndexOf(' ') + 1) : 2;
|
|
119040
|
+
let opacity = (paraArray.length > 6) ? paraArray[6].substr(paraArray[6].lastIndexOf(' ') + 1) : 0.3;
|
|
119041
|
+
|
|
119042
|
+
ic.analysisCls.addPlane(parseFloat(p1Array[1]), parseFloat(p1Array[3]), parseFloat(p1Array[5]), parseFloat(p2Array[1]), parseFloat(p2Array[3]), parseFloat(p2Array[5]), parseFloat(p3Array[1]), parseFloat(p3Array[3]), parseFloat(p3Array[5]), color, parseFloat(thickness), parseFloat(opacity));
|
|
119043
|
+
ic.drawCls.draw();
|
|
119044
|
+
}
|
|
117751
119045
|
else if(command.indexOf('add sphere') == 0) {
|
|
117752
119046
|
this.addShape(commandOri, 'sphere');
|
|
117753
119047
|
ic.shapeCmdHash[commandOri] = 1;
|
|
@@ -117766,6 +119060,10 @@ class ApplyCommand {
|
|
|
117766
119060
|
ic.lines['cylinder'] = []; // reset
|
|
117767
119061
|
//ic.drawCls.draw();
|
|
117768
119062
|
}
|
|
119063
|
+
else if(command.indexOf('clear plane among sets') == 0) {
|
|
119064
|
+
ic.planes = []; // reset
|
|
119065
|
+
//ic.drawCls.draw();
|
|
119066
|
+
}
|
|
117769
119067
|
else if(commandOri.indexOf('add label') == 0) {
|
|
117770
119068
|
let paraArray = commandOri.split(' | ');
|
|
117771
119069
|
let text = paraArray[0].substr(('add label').length + 1);
|
|
@@ -126519,6 +127817,21 @@ class Analysis {
|
|
|
126519
127817
|
//ic.drawCls.draw();
|
|
126520
127818
|
}
|
|
126521
127819
|
|
|
127820
|
+
//Add a plane among the positions (x1, y1, z1), (x2, y2, z2) and (x3, y3, z3) with the input "color".
|
|
127821
|
+
addPlane(x1, y1, z1, x2, y2, z2, x3, y3, z3, color, thickness, opacity) {var ic = this.icn3d; ic.icn3dui;
|
|
127822
|
+
let plane = {}; // Each plane contains 'position1', 'position2', 'position3', 'color', and 'thickness'
|
|
127823
|
+
plane.position1 = new Vector3$1(x1, y1, z1);
|
|
127824
|
+
plane.position2 = new Vector3$1(x2, y2, z2);
|
|
127825
|
+
plane.position3 = new Vector3$1(x3, y3, z3);
|
|
127826
|
+
plane.color = color;
|
|
127827
|
+
plane.thickness = thickness;
|
|
127828
|
+
plane.opacity = opacity;
|
|
127829
|
+
if(ic.planes === undefined) ic.planes = [];
|
|
127830
|
+
ic.planes.push(plane);
|
|
127831
|
+
|
|
127832
|
+
ic.hlObjectsCls.removeHlObjects();
|
|
127833
|
+
}
|
|
127834
|
+
|
|
126522
127835
|
addLineFromPicking(type) {var ic = this.icn3d, me = ic.icn3dui;
|
|
126523
127836
|
let color = $("#" + ic.pre + type + "color" ).val();
|
|
126524
127837
|
(ic.pAtom.coord.x + ic.pAtom2.coord.x) / 2;
|
|
@@ -130305,12 +131618,13 @@ class SaveFile {
|
|
|
130305
131618
|
let structureArray = Object.keys(me.utilsCls.getStructures(ic.dAtoms));
|
|
130306
131619
|
|
|
130307
131620
|
if(structureArray.length > 1) {
|
|
130308
|
-
title = '
|
|
130309
|
-
for(let i = 0, il = structureArray.length; i < il; ++i) {
|
|
131621
|
+
title = structureArray.length + ' structures: ';
|
|
131622
|
+
for(let i = 0, il = structureArray.length; i < il && i < 5; ++i) {
|
|
130310
131623
|
let url = (isNaN(structureArray[i]) && structureArray[i].length > 5) ? 'https://alphafold.ebi.ac.uk/entry/' + structureArray[i] : 'https://www.ncbi.nlm.nih.gov/structure/?term=' + structureArray[i];
|
|
130311
131624
|
title += '<a href="' + url + '" style="color:' + titlelinkColor + '" target="_blank">' + structureArray[i] + '</a>';
|
|
130312
131625
|
if(i < il - 1) title += ', ';
|
|
130313
131626
|
}
|
|
131627
|
+
if(structureArray.length > 5) title += '...';
|
|
130314
131628
|
$("#" + ic.pre + "title").html(title);
|
|
130315
131629
|
}
|
|
130316
131630
|
else if(structureArray.length == 1) {
|
|
@@ -132101,12 +133415,11 @@ class Control {
|
|
|
132101
133415
|
ic.transformCls.setRotation(axis, angle);
|
|
132102
133416
|
}
|
|
132103
133417
|
|
|
132104
|
-
else if(e.keyCode === 65 ) { // A, alternate
|
|
133418
|
+
else if(e.keyCode === 65 ) { // A, alternate forward
|
|
132105
133419
|
if(Object.keys(ic.structures).length > 1) {
|
|
132106
133420
|
await ic.alternateCls.alternateWrapper();
|
|
132107
133421
|
}
|
|
132108
133422
|
}
|
|
132109
|
-
|
|
132110
133423
|
}
|
|
132111
133424
|
});
|
|
132112
133425
|
|
|
@@ -133556,6 +134869,8 @@ class iCn3D {
|
|
|
133556
134869
|
this.pdbParserCls = new PdbParser(this);
|
|
133557
134870
|
this.sdfParserCls = new SdfParser(this);
|
|
133558
134871
|
this.xyzParserCls = new XyzParser(this);
|
|
134872
|
+
this.dcdParserCls = new DcdParser(this);
|
|
134873
|
+
this.xtcParserCls = new XtcParser(this);
|
|
133559
134874
|
this.msaParserCls = new MsaParser(this);
|
|
133560
134875
|
this.realignParserCls = new RealignParser(this);
|
|
133561
134876
|
this.densityCifParserCls = new DensityCifParser(this);
|
|
@@ -133813,7 +135128,7 @@ class iCn3DUI {
|
|
|
133813
135128
|
//even when multiple iCn3D viewers are shown together.
|
|
133814
135129
|
this.pre = this.cfg.divid + "_";
|
|
133815
135130
|
|
|
133816
|
-
this.REVISION = '3.
|
|
135131
|
+
this.REVISION = '3.47.0';
|
|
133817
135132
|
|
|
133818
135133
|
// In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
|
|
133819
135134
|
this.bNode = (Object.keys(window).length < 3) ? true : false;
|
|
@@ -134574,4 +135889,4 @@ class printMsg {
|
|
|
134574
135889
|
}
|
|
134575
135890
|
}
|
|
134576
135891
|
|
|
134577
|
-
export { ARButton, AddTrack, AlignParser, AlignSW, AlignSeq, Alternate, Analysis, AnnoCddSite, AnnoContact, AnnoCrossLink, AnnoDomain, AnnoSnpClinVar, AnnoSsbond, AnnoTransMem, Annotation, ApplyCenter, ApplyClbonds, ApplyCommand, ApplyDisplay, ApplyMap, ApplyOther, ApplySsbonds, ApplySymd, Axes, Box, Brick, Camera, CartoonNucl, ChainalignParser, ClickMenu, Contact, Control, ConvertTypeCls, Curve, CurveStripArrow, Cylinder, DefinedSets, Delphi, DensityCifParser, Diagram2d, Dialog, Domain3d, Draw, DrawGraph, Dsn6Parser, Dssp, ElectronMap, Events, Export3D, FirstAtomObj, Fog, GetGraph, Glycan, HBond, HashUtilsCls, HlObjects, HlSeq, HlUpdate, Html, Impostor, Instancing, Label, Line$1 as Line, LineGraph, LoadAtomData, LoadCIF, LoadPDB, LoadScript, MarchingCube, MmcifParser, MmdbParser, Mol2Parser, MsaParser, MyEventCls, OpmParser, ParasCls, ParserUtils, PdbParser, PiHalogen, Picking, ProteinSurface, Ray, RealignParser, Refnum, ReprSub, Resid2spec, ResidueLabels, ResizeCanvas, RmsdSuprCls, Saltbridge, SaveFile, Scap, Scene, SdfParser, SelectByCommand, Selection, SetColor, SetDialog, SetHtml, SetMenu, SetOption, SetSeqAlign, SetStyle, ShareLink, ShowAnno, ShowInter, ShowSeq, Sphere$1 as Sphere, Stick, Strand, Strip, SubdivideCls, Surface, Symd, ThreeDPrint, Transform, Tube, UtilsCls, VRButton, Vastplus, ViewInterPairs, XyzParser, iCn3D, iCn3DUI, printMsg };
|
|
135892
|
+
export { ARButton, AddTrack, AlignParser, AlignSW, AlignSeq, Alternate, Analysis, AnnoCddSite, AnnoContact, AnnoCrossLink, AnnoDomain, AnnoSnpClinVar, AnnoSsbond, AnnoTransMem, Annotation, ApplyCenter, ApplyClbonds, ApplyCommand, ApplyDisplay, ApplyMap, ApplyOther, ApplySsbonds, ApplySymd, Axes, Box, Brick, Camera, CartoonNucl, ChainalignParser, ClickMenu, Contact, Control, ConvertTypeCls, Curve, CurveStripArrow, Cylinder, DcdParser, DefinedSets, Delphi, DensityCifParser, Diagram2d, Dialog, Domain3d, Draw, DrawGraph, Dsn6Parser, Dssp, ElectronMap, Events, Export3D, FirstAtomObj, Fog, GetGraph, Glycan, HBond, HashUtilsCls, HlObjects, HlSeq, HlUpdate, Html, Impostor, Instancing, Label, Line$1 as Line, LineGraph, LoadAtomData, LoadCIF, LoadPDB, LoadScript, MarchingCube, MmcifParser, MmdbParser, Mol2Parser, MsaParser, MyEventCls, OpmParser, ParasCls, ParserUtils, PdbParser, PiHalogen, Picking, ProteinSurface, Ray, RealignParser, Refnum, ReprSub, Resid2spec, ResidueLabels, ResizeCanvas, RmsdSuprCls, Saltbridge, SaveFile, Scap, Scene, SdfParser, SelectByCommand, Selection, SetColor, SetDialog, SetHtml, SetMenu, SetOption, SetSeqAlign, SetStyle, ShareLink, ShowAnno, ShowInter, ShowSeq, Sphere$1 as Sphere, Stick, Strand, Strip, SubdivideCls, Surface, Symd, ThreeDPrint, Transform, Tube, UtilsCls, VRButton, Vastplus, ViewInterPairs, XtcParser, XyzParser, iCn3D, iCn3DUI, printMsg };
|