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.js
CHANGED
|
@@ -55370,6 +55370,8 @@ class RmsdSuprCls {
|
|
|
55370
55370
|
supr = undefined;
|
|
55371
55371
|
}
|
|
55372
55372
|
|
|
55373
|
+
if(me.bNode) console.log("RMSD: " + supr);
|
|
55374
|
+
|
|
55373
55375
|
return {'rot': rot, 'trans1': xc1, 'trans2': xc2, 'rmsd': supr};
|
|
55374
55376
|
|
|
55375
55377
|
}; // end rmsd_supr
|
|
@@ -56165,11 +56167,12 @@ class ClickMenu {
|
|
|
56165
56167
|
}
|
|
56166
56168
|
}
|
|
56167
56169
|
|
|
56168
|
-
setSetsMenus(id, bOneset) { let me = this.icn3dui, ic = me.icn3d;
|
|
56170
|
+
setSetsMenus(id, bOneset, bThreeset) { let me = this.icn3dui, ic = me.icn3d;
|
|
56169
56171
|
this.SetChainsAdvancedMenu();
|
|
56170
56172
|
|
|
56171
56173
|
let id1 = id;
|
|
56172
56174
|
let id2 = id + '2';
|
|
56175
|
+
let id3 = id + '3';
|
|
56173
56176
|
|
|
56174
56177
|
let definedAtomsHtml = ic.definedSetsCls.setAtomMenu(['protein']);
|
|
56175
56178
|
if($("#" + me.pre + id1).length) {
|
|
@@ -56178,9 +56181,13 @@ class ClickMenu {
|
|
|
56178
56181
|
if(!bOneset && $("#" + me.pre + id2).length) {
|
|
56179
56182
|
$("#" + me.pre + id2).html(" <option value='selected' selected>selected</option>" + definedAtomsHtml);
|
|
56180
56183
|
}
|
|
56184
|
+
if(bThreeset && $("#" + me.pre + id3).length) {
|
|
56185
|
+
$("#" + me.pre + id3).html(" <option value='selected' selected>selected</option>" + definedAtomsHtml);
|
|
56186
|
+
}
|
|
56181
56187
|
|
|
56182
56188
|
$("#" + me.pre + id1).resizable();
|
|
56183
56189
|
if(!bOneset) $("#" + me.pre + id2).resizable();
|
|
56190
|
+
if(bThreeset) $("#" + me.pre + id3).resizable();
|
|
56184
56191
|
}
|
|
56185
56192
|
|
|
56186
56193
|
applyShownMenus(bNoSave) { let me = this.icn3dui; me.icn3d;
|
|
@@ -56397,27 +56404,31 @@ class ClickMenu {
|
|
|
56397
56404
|
|
|
56398
56405
|
me.myEventCls.onIds("#" + me.pre + "mn1_pdbfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56399
56406
|
//me = me.setIcn3dui($(this).attr('id'));
|
|
56400
|
-
me.htmlCls.dialogCls.openDlg('dl_pdbfile', 'Please input PDB
|
|
56407
|
+
me.htmlCls.dialogCls.openDlg('dl_pdbfile', 'Please input PDB file');
|
|
56401
56408
|
});
|
|
56402
56409
|
me.myEventCls.onIds(["#" + me.pre + "mn1_pdbfile_app", "#" + me.pre + "tool_pdbfile"], "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56403
56410
|
//me = me.setIcn3dui($(this).attr('id'));
|
|
56404
|
-
me.htmlCls.dialogCls.openDlg('dl_pdbfile_app', 'Please append PDB
|
|
56411
|
+
me.htmlCls.dialogCls.openDlg('dl_pdbfile_app', 'Please append PDB files');
|
|
56405
56412
|
});
|
|
56406
56413
|
|
|
56407
56414
|
me.myEventCls.onIds("#" + me.pre + "mn1_mol2file", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56408
|
-
me.htmlCls.dialogCls.openDlg('dl_mol2file', 'Please input Mol2
|
|
56415
|
+
me.htmlCls.dialogCls.openDlg('dl_mol2file', 'Please input Mol2 file');
|
|
56409
56416
|
});
|
|
56410
56417
|
|
|
56411
56418
|
me.myEventCls.onIds("#" + me.pre + "mn1_sdffile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56412
|
-
me.htmlCls.dialogCls.openDlg('dl_sdffile', 'Please input SDF
|
|
56419
|
+
me.htmlCls.dialogCls.openDlg('dl_sdffile', 'Please input SDF file');
|
|
56413
56420
|
});
|
|
56414
56421
|
|
|
56415
56422
|
me.myEventCls.onIds("#" + me.pre + "mn1_xyzfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56416
|
-
me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ
|
|
56423
|
+
me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ file');
|
|
56424
|
+
});
|
|
56425
|
+
|
|
56426
|
+
me.myEventCls.onIds("#" + me.pre + "mn1_dcdfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56427
|
+
me.htmlCls.dialogCls.openDlg('dl_dcdfile', 'Please input MD trajectory file');
|
|
56417
56428
|
});
|
|
56418
56429
|
|
|
56419
56430
|
me.myEventCls.onIds("#" + me.pre + "mn1_afmapfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56420
|
-
me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold PAE
|
|
56431
|
+
me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold PAE file');
|
|
56421
56432
|
});
|
|
56422
56433
|
|
|
56423
56434
|
me.myEventCls.onIds("#" + me.pre + "mn1_urlfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
@@ -56425,11 +56436,11 @@ class ClickMenu {
|
|
|
56425
56436
|
});
|
|
56426
56437
|
|
|
56427
56438
|
me.myEventCls.onIds("#" + me.pre + "mn1_clustalwfile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56428
|
-
me.htmlCls.dialogCls.openDlg('dl_clustalwfile', 'Please input CLUSTALW MSA
|
|
56439
|
+
me.htmlCls.dialogCls.openDlg('dl_clustalwfile', 'Please input CLUSTALW MSA file');
|
|
56429
56440
|
});
|
|
56430
56441
|
|
|
56431
56442
|
me.myEventCls.onIds("#" + me.pre + "mn1_fastafile", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
56432
|
-
me.htmlCls.dialogCls.openDlg('dl_fastafile', 'Please input FASTA MSA
|
|
56443
|
+
me.htmlCls.dialogCls.openDlg('dl_fastafile', 'Please input FASTA MSA file');
|
|
56433
56444
|
});
|
|
56434
56445
|
|
|
56435
56446
|
me.myEventCls.onIds("#" + me.pre + "mn1_fixedversion", "click", function(e) { me.icn3d; //e.preventDefault();
|
|
@@ -58303,6 +58314,13 @@ class ClickMenu {
|
|
|
58303
58314
|
ic.bLinebtwsets = true;
|
|
58304
58315
|
});
|
|
58305
58316
|
|
|
58317
|
+
me.myEventCls.onIds("#" + me.pre + "mn5_plane3sets", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
|
|
58318
|
+
me.htmlCls.dialogCls.openDlg('dl_plane3sets', 'Draw a plane among three sets');
|
|
58319
|
+
|
|
58320
|
+
thisClass.setSetsMenus('plane3sets', undefined, true);
|
|
58321
|
+
|
|
58322
|
+
ic.bPlane3sets = true;
|
|
58323
|
+
});
|
|
58306
58324
|
|
|
58307
58325
|
me.myEventCls.onIds(["#" + me.pre + "mn2_selectedcenter", "#" + me.pre + "zoomin_selection", "#" + me.pre + "tool_selectedcenter"], "click", function(e) { let ic = me.icn3d; //e.preventDefault();
|
|
58308
58326
|
//thisClass.setLogCmd('zoom selection', true);
|
|
@@ -59391,6 +59409,7 @@ class SetMenu {
|
|
|
59391
59409
|
html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
|
|
59392
59410
|
html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
|
|
59393
59411
|
html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
|
|
59412
|
+
html += this.getLink('mn1_dcdfile', 'MD Trajectory File', undefined, 2);
|
|
59394
59413
|
|
|
59395
59414
|
html += this.getMenuSep();
|
|
59396
59415
|
|
|
@@ -60024,6 +60043,7 @@ class SetMenu {
|
|
|
60024
60043
|
|
|
60025
60044
|
html += this.getLink('mn5_cartoonshape', 'Cartoon for a Set', undefined, 1);
|
|
60026
60045
|
html += this.getLink('mn5_linebtwsets', 'Line btw. Two Sets', undefined, 1);
|
|
60046
|
+
html += this.getLink('mn5_plane3sets', 'Plane among 3 Sets', undefined, 1);
|
|
60027
60047
|
|
|
60028
60048
|
if(me.cfg.cid === undefined && me.cfg.align === undefined && me.cfg.chainalign === undefined && me.cfg.mmdbaf === undefined) {
|
|
60029
60049
|
html += this.getMenuSep();
|
|
@@ -60894,6 +60914,7 @@ class Dialog {
|
|
|
60894
60914
|
let bGraph = $('#' + me.pre + 'dl_graph').hasClass('ui-dialog-content'); // initialized
|
|
60895
60915
|
let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
|
|
60896
60916
|
let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
|
|
60917
|
+
let bRmsdplot = $('#' + me.pre + 'dl_rmsdplot').hasClass('ui-dialog-content'); // initialized
|
|
60897
60918
|
let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
|
|
60898
60919
|
let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
|
|
60899
60920
|
let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
|
|
@@ -60911,6 +60932,7 @@ class Dialog {
|
|
|
60911
60932
|
id2flag.dl_graph = 'bGraph2';
|
|
60912
60933
|
id2flag.dl_linegraph = 'bLineGraph2';
|
|
60913
60934
|
id2flag.dl_scatterplot = 'bScatterplot2';
|
|
60935
|
+
id2flag.dl_rmsdplot = 'bRmsdplot2';
|
|
60914
60936
|
id2flag.dl_ligplot = 'bLigplot2';
|
|
60915
60937
|
id2flag.dl_contactmap = 'bContactmap2';
|
|
60916
60938
|
id2flag.dl_alignerrormap = 'bAlignerrormap2';
|
|
@@ -60924,6 +60946,7 @@ class Dialog {
|
|
|
60924
60946
|
if(bGraph) status.bGraph2 = $('#' + me.pre + 'dl_graph').dialog( 'isOpen' );
|
|
60925
60947
|
if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
|
|
60926
60948
|
if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
|
|
60949
|
+
if(bRmsdplot) status.bRmsdplot2 = $('#' + me.pre + 'dl_rmsdplot').dialog( 'isOpen' );
|
|
60927
60950
|
if(bLigplot) status.bLigplot2 = $('#' + me.pre + 'dl_ligplot').dialog( 'isOpen' );
|
|
60928
60951
|
if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
|
|
60929
60952
|
if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
|
|
@@ -61113,7 +61136,7 @@ class Dialog {
|
|
|
61113
61136
|
|
|
61114
61137
|
let status = this.getDialogStatus().status;
|
|
61115
61138
|
|
|
61116
|
-
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') {
|
|
61139
|
+
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') {
|
|
61117
61140
|
//var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
|
|
61118
61141
|
let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
|
|
61119
61142
|
|
|
@@ -61339,7 +61362,7 @@ class Dialog {
|
|
|
61339
61362
|
let width = 400, height = 150;
|
|
61340
61363
|
let twoddgmWidth = me.htmlCls.width2d + 20;
|
|
61341
61364
|
|
|
61342
|
-
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') {
|
|
61365
|
+
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') {
|
|
61343
61366
|
$( "#" + id ).show();
|
|
61344
61367
|
$( "#" + id + "_nb").show();
|
|
61345
61368
|
$( "#" + id + "_title").html(title);
|
|
@@ -61770,6 +61793,23 @@ class SetDialog {
|
|
|
61770
61793
|
html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
|
|
61771
61794
|
html += "</div>";
|
|
61772
61795
|
|
|
61796
|
+
html += me.htmlCls.divStr + "dl_dcdfile' class='" + dialogClass + "'>";
|
|
61797
|
+
html += this.addNotebookTitle('dl_dcdfile', 'Please input an MD trajectory file');
|
|
61798
|
+
html += "Step 1. <b>PDB File</b>: " + me.htmlCls.inputFileStr + "id='" + me.pre + "dcdpdbfile' size=8> ";
|
|
61799
|
+
html += me.htmlCls.buttonStr + "reload_dcdpdbfile'>Load PDB File</button><br><br>";
|
|
61800
|
+
|
|
61801
|
+
html += "Step 2. <b>DCD File</b>: " + me.htmlCls.inputFileStr + "id='" + me.pre + "dcdfile' size=8> ";
|
|
61802
|
+
html += me.htmlCls.buttonStr + "reload_dcdfile'>Load DCD File</button><br>";
|
|
61803
|
+
|
|
61804
|
+
html += "or <b>XTC File</b>: " + me.htmlCls.inputFileStr + "id='" + me.pre + "xtcfile' size=8> ";
|
|
61805
|
+
html += me.htmlCls.buttonStr + "reload_xtcfile' style='margin-left:28px'>Load XTC File</button><br><br>";
|
|
61806
|
+
|
|
61807
|
+
html += "<hr><br>";
|
|
61808
|
+
html += "<b>Analysis</b>: " + me.htmlCls.buttonStr + "rmsd_plot'>RMSD Plot</button><br><br>";
|
|
61809
|
+
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>";
|
|
61810
|
+
|
|
61811
|
+
html += "</div>";
|
|
61812
|
+
|
|
61773
61813
|
html += me.htmlCls.divStr + "dl_clustalwfile' class='" + dialogClass + "' style='max-width:500px'>";
|
|
61774
61814
|
html += this.addNotebookTitle('dl_clustalwfile', 'Please input a CLUSTALW MSA file');
|
|
61775
61815
|
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>";
|
|
@@ -62300,6 +62340,15 @@ class SetDialog {
|
|
|
62300
62340
|
|
|
62301
62341
|
html += "</div>";
|
|
62302
62342
|
|
|
62343
|
+
html += me.htmlCls.divStr + "dl_rmsdplot' style='background-color:white' class='" + dialogClass + "'>";
|
|
62344
|
+
html += this.addNotebookTitle('dl_rmsdplot', 'RMSD Plot');
|
|
62345
|
+
|
|
62346
|
+
me.rmsdplotid = me.pre + 'rmsdplot';
|
|
62347
|
+
html += me.htmlCls.divNowrapStr + buttonStrTmp + me.rmsdplotid + '_json">JSON</button>' + me.htmlCls.space2 + " The image below can be saved via right click.<br></div>";
|
|
62348
|
+
|
|
62349
|
+
html += '<canvas id="' + me.rmsdplotid + '"></canvas>';
|
|
62350
|
+
|
|
62351
|
+
html += "</div>";
|
|
62303
62352
|
|
|
62304
62353
|
html += me.htmlCls.divStr + "dl_ligplot' style='background-color:white' class='" + dialogClass + "'>";
|
|
62305
62354
|
|
|
@@ -62557,6 +62606,42 @@ class SetDialog {
|
|
|
62557
62606
|
html += "</div>";
|
|
62558
62607
|
|
|
62559
62608
|
|
|
62609
|
+
html += me.htmlCls.divStr + "dl_plane3sets' class='" + dialogClass + "'>";
|
|
62610
|
+
html += this.addNotebookTitle('dl_plane3sets', 'Add a plane among three sets');
|
|
62611
|
+
html += me.htmlCls.spanNowrapStr + "1. Select three sets</span><br/>";
|
|
62612
|
+
html += "<table border=0 width=400 cellspacing=10><tr><td>";
|
|
62613
|
+
|
|
62614
|
+
html += me.htmlCls.divNowrapStr + "First set:</div>";
|
|
62615
|
+
html += "<div style='text-indent:1.1em'><select style='max-width:200px' id='" + me.pre + "plane3sets' multiple size='5' style='min-width:130px;'>";
|
|
62616
|
+
html += "</select></div>";
|
|
62617
|
+
|
|
62618
|
+
html += "</td><td>";
|
|
62619
|
+
|
|
62620
|
+
html += me.htmlCls.divNowrapStr + "Second set:</div>";
|
|
62621
|
+
html += "<div style='text-indent:1.1em'><select style='max-width:200px' id='" + me.pre + "plane3sets2' multiple size='5' style='min-width:130px;'>";
|
|
62622
|
+
html += "</select></div>";
|
|
62623
|
+
|
|
62624
|
+
html += "</td><td>";
|
|
62625
|
+
|
|
62626
|
+
html += me.htmlCls.divNowrapStr + "Third set:</div>";
|
|
62627
|
+
html += "<div style='text-indent:1.1em'><select style='max-width:200px' id='" + me.pre + "plane3sets3' multiple size='5' style='min-width:130px;'>";
|
|
62628
|
+
html += "</select></div>";
|
|
62629
|
+
|
|
62630
|
+
html += "</td></tr></table>";
|
|
62631
|
+
|
|
62632
|
+
html += "2. Thickness (Å): " + me.htmlCls.inputTextStr + "id='" + me.pre + "plane3sets_thickness' value='2' size=4><br/><br/>";
|
|
62633
|
+
|
|
62634
|
+
html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "plane3sets_customcolor' value='" + defaultColor + "' size=4><br/><br/>";
|
|
62635
|
+
|
|
62636
|
+
html += me.htmlCls.divNowrapStr + "4. Opacity: <select id='" + me.pre + "plane3sets_opacity'>";
|
|
62637
|
+
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);
|
|
62638
|
+
html += "</select></div><br>";
|
|
62639
|
+
|
|
62640
|
+
html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applyplane3sets'>Display</button></span>";
|
|
62641
|
+
html += me.htmlCls.space3 + me.htmlCls.spanNowrapStr + me.htmlCls.buttonStr + "clearplane3sets'>Clear</button></span>";
|
|
62642
|
+
html += "</div>";
|
|
62643
|
+
|
|
62644
|
+
|
|
62560
62645
|
html += me.htmlCls.divStr + "dl_cartoonshape' class='" + dialogClass + "'>";
|
|
62561
62646
|
html += this.addNotebookTitle('dl_cartoonshape', 'Cartoon Shape');
|
|
62562
62647
|
html += me.htmlCls.spanNowrapStr + "1. Select a set:</span><br/>";
|
|
@@ -63273,10 +63358,10 @@ class Events {
|
|
|
63273
63358
|
}
|
|
63274
63359
|
}
|
|
63275
63360
|
|
|
63276
|
-
async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
|
|
63361
|
+
async loadPdbFile(bAppend, fileId, bmmCIF, bOpenDialog) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
|
|
63277
63362
|
//me = ic.setIcn3dui(this.id);
|
|
63278
63363
|
ic.bInitial = true;
|
|
63279
|
-
thisClass.iniFileLoad();
|
|
63364
|
+
if(!bOpenDialog) thisClass.iniFileLoad();
|
|
63280
63365
|
let files = $("#" + me.pre + fileId)[0].files;
|
|
63281
63366
|
if(!files[0]) {
|
|
63282
63367
|
var aaa = 1; //alert("Please select a file before clicking 'Load'");
|
|
@@ -63594,7 +63679,7 @@ class Events {
|
|
|
63594
63679
|
|
|
63595
63680
|
me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", async function(e) { let ic = me.icn3d;
|
|
63596
63681
|
ic.bAlternate = true;
|
|
63597
|
-
|
|
63682
|
+
ic.alternateCls.alternateStructures();
|
|
63598
63683
|
ic.bAlternate = false;
|
|
63599
63684
|
|
|
63600
63685
|
thisClass.setLogCmd("alternate structures", false);
|
|
@@ -64516,14 +64601,53 @@ class Events {
|
|
|
64516
64601
|
|
|
64517
64602
|
// Start recording
|
|
64518
64603
|
ic.videoRecorder.start();
|
|
64519
|
-
thisClass.setLogCmd('Video
|
|
64604
|
+
thisClass.setLogCmd('Video recording started', false);
|
|
64520
64605
|
});
|
|
64521
64606
|
|
|
64522
64607
|
me.myEventCls.onIds("#" + me.pre + "video_end", "click", function(e) { let ic = me.icn3d;
|
|
64523
64608
|
e.preventDefault();
|
|
64524
64609
|
|
|
64525
64610
|
ic.videoRecorder.stop();
|
|
64526
|
-
thisClass.setLogCmd('Video
|
|
64611
|
+
thisClass.setLogCmd('Video recording ended', false);
|
|
64612
|
+
});
|
|
64613
|
+
|
|
64614
|
+
me.myEventCls.onIds("#" + me.pre + "video_frame", "click", function(e) { let ic = me.icn3d;
|
|
64615
|
+
e.preventDefault();
|
|
64616
|
+
|
|
64617
|
+
let fps = $("#" + me.pre + "videofps").val();
|
|
64618
|
+
let interval = 1000 / fps; // ms
|
|
64619
|
+
let duratinon = (ic.frames + 3) * interval; // make the video a little longer than the number of frames
|
|
64620
|
+
|
|
64621
|
+
const canvas = document.getElementById(ic.pre + "canvas");
|
|
64622
|
+
// ic.videoFrameRecorder = new MediaRecorder(canvas.captureStream(fps));
|
|
64623
|
+
ic.videoFrameRecorder = new MediaRecorder(canvas.captureStream());
|
|
64624
|
+
const recordedChunks = [];
|
|
64625
|
+
|
|
64626
|
+
// Collect data chunks
|
|
64627
|
+
ic.videoFrameRecorder.ondataavailable = event => {
|
|
64628
|
+
recordedChunks.push(event.data);
|
|
64629
|
+
};
|
|
64630
|
+
|
|
64631
|
+
ic.videoFrameRecorder.onstop = event => {
|
|
64632
|
+
// Code to save the recordedChunks as a video file
|
|
64633
|
+
const blob = new Blob(recordedChunks, {type: ic.videoFrameRecorder.mimeType});
|
|
64634
|
+
let fileName = ic.inputid + '_video_frame';
|
|
64635
|
+
saveAs(blob, fileName);
|
|
64636
|
+
};
|
|
64637
|
+
|
|
64638
|
+
// Start recording
|
|
64639
|
+
ic.videoFrameRecorder.start();
|
|
64640
|
+
thisClass.setLogCmd('Video recording started', false);
|
|
64641
|
+
|
|
64642
|
+
const intervalId = setInterval(function() {
|
|
64643
|
+
ic.alternateCls.alternateStructures();
|
|
64644
|
+
}, interval);
|
|
64645
|
+
|
|
64646
|
+
setTimeout(() => {
|
|
64647
|
+
clearInterval(intervalId);
|
|
64648
|
+
ic.videoFrameRecorder.stop();
|
|
64649
|
+
thisClass.setLogCmd('Video recording ended', false);
|
|
64650
|
+
}, duratinon);
|
|
64527
64651
|
});
|
|
64528
64652
|
|
|
64529
64653
|
me.myEventCls.onIds("#" + me.pre + "reload_state", "click", function(e) { let ic = me.icn3d;
|
|
@@ -65145,6 +65269,22 @@ class Events {
|
|
|
65145
65269
|
await thisClass.loadPdbFile(ic.bAppend, 'pdbfile_app');
|
|
65146
65270
|
});
|
|
65147
65271
|
|
|
65272
|
+
me.myEventCls.onIds("#" + me.pre + "reload_dcdpdbfile", "click", async function(e) { me.icn3d;
|
|
65273
|
+
e.preventDefault();
|
|
65274
|
+
|
|
65275
|
+
let bAppend = false;
|
|
65276
|
+
// ic.bRender = false;
|
|
65277
|
+
await thisClass.loadPdbFile(bAppend, 'dcdpdbfile', undefined, true);
|
|
65278
|
+
});
|
|
65279
|
+
|
|
65280
|
+
me.myEventCls.onIds("#" + me.pre + "reload_xtcpdbfile", "click", async function(e) { me.icn3d;
|
|
65281
|
+
e.preventDefault();
|
|
65282
|
+
|
|
65283
|
+
let bAppend = false;
|
|
65284
|
+
// ic.bRender = false;
|
|
65285
|
+
await thisClass.loadPdbFile(bAppend, 'xtcpdbfile', undefined, true);
|
|
65286
|
+
});
|
|
65287
|
+
|
|
65148
65288
|
me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
|
|
65149
65289
|
e.preventDefault();
|
|
65150
65290
|
ic.bInitial = true;
|
|
@@ -65226,6 +65366,62 @@ class Events {
|
|
|
65226
65366
|
}
|
|
65227
65367
|
});
|
|
65228
65368
|
|
|
65369
|
+
me.myEventCls.onIds("#" + me.pre + "reload_dcdfile", "click", async function(e) { let ic = me.icn3d;
|
|
65370
|
+
e.preventDefault();
|
|
65371
|
+
ic.bInitial = true;
|
|
65372
|
+
|
|
65373
|
+
//thisClass.iniFileLoad();
|
|
65374
|
+
let file = $("#" + me.pre + "dcdfile")[0].files[0];
|
|
65375
|
+
if(!file) {
|
|
65376
|
+
var aaa = 1; //alert("Please select a file before clicking 'Load'");
|
|
65377
|
+
}
|
|
65378
|
+
else {
|
|
65379
|
+
me.htmlCls.setHtmlCls.fileSupport();
|
|
65380
|
+
let reader = new FileReader();
|
|
65381
|
+
reader.onload = async function(e) {
|
|
65382
|
+
let arrayBuffer = e.target.result;
|
|
65383
|
+
thisClass.setLogCmd('load dcd file ' + $("#" + me.pre + "dcdfile").val(), false);
|
|
65384
|
+
ic.molTitle = "";
|
|
65385
|
+
ic.inputid = undefined;
|
|
65386
|
+
|
|
65387
|
+
// ic.init();
|
|
65388
|
+
ic.bInputfile = true;
|
|
65389
|
+
ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + arrayBuffer : arrayBuffer;
|
|
65390
|
+
ic.InputfileType = 'dcd';
|
|
65391
|
+
await ic.dcdParserCls.loadDcdData(arrayBuffer);
|
|
65392
|
+
};
|
|
65393
|
+
reader.readAsArrayBuffer(file);
|
|
65394
|
+
}
|
|
65395
|
+
});
|
|
65396
|
+
|
|
65397
|
+
me.myEventCls.onIds("#" + me.pre + "reload_xtcfile", "click", async function(e) { let ic = me.icn3d;
|
|
65398
|
+
e.preventDefault();
|
|
65399
|
+
ic.bInitial = true;
|
|
65400
|
+
|
|
65401
|
+
//thisClass.iniFileLoad();
|
|
65402
|
+
let file = $("#" + me.pre + "xtcfile")[0].files[0];
|
|
65403
|
+
if(!file) {
|
|
65404
|
+
var aaa = 1; //alert("Please select a file before clicking 'Load'");
|
|
65405
|
+
}
|
|
65406
|
+
else {
|
|
65407
|
+
me.htmlCls.setHtmlCls.fileSupport();
|
|
65408
|
+
let reader = new FileReader();
|
|
65409
|
+
reader.onload = async function(e) {
|
|
65410
|
+
let arrayBuffer = e.target.result;
|
|
65411
|
+
thisClass.setLogCmd('load xtc file ' + $("#" + me.pre + "xtcfile").val(), false);
|
|
65412
|
+
ic.molTitle = "";
|
|
65413
|
+
ic.inputid = undefined;
|
|
65414
|
+
|
|
65415
|
+
// ic.init();
|
|
65416
|
+
ic.bInputfile = true;
|
|
65417
|
+
ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + arrayBuffer : arrayBuffer;
|
|
65418
|
+
ic.InputfileType = 'xtc';
|
|
65419
|
+
await ic.xtcParserCls.loadXtcData(arrayBuffer);
|
|
65420
|
+
};
|
|
65421
|
+
reader.readAsArrayBuffer(file);
|
|
65422
|
+
}
|
|
65423
|
+
});
|
|
65424
|
+
|
|
65229
65425
|
me.myEventCls.onIds("#" + me.pre + "reload_clustalwfile", "click", function(e) { let ic = me.icn3d;
|
|
65230
65426
|
e.preventDefault();
|
|
65231
65427
|
ic.bInitial = true;
|
|
@@ -65478,6 +65674,11 @@ class Events {
|
|
|
65478
65674
|
|
|
65479
65675
|
await ic.showInterCls.showInteractions('graph');
|
|
65480
65676
|
});
|
|
65677
|
+
me.myEventCls.onIds("#" + me.pre + "rmsd_plot", "click", async function(e) { let ic = me.icn3d;
|
|
65678
|
+
e.preventDefault();
|
|
65679
|
+
|
|
65680
|
+
await ic.dcdParserCls.showRmsdPlot();
|
|
65681
|
+
});
|
|
65481
65682
|
me.myEventCls.onIds("#" + me.pre + "hbondLineGraph", "click", async function(e) { let ic = me.icn3d;
|
|
65482
65683
|
e.preventDefault();
|
|
65483
65684
|
|
|
@@ -65623,6 +65824,12 @@ class Events {
|
|
|
65623
65824
|
thisClass.setLogCmd("scatterplot scale " + scale, true);
|
|
65624
65825
|
});
|
|
65625
65826
|
|
|
65827
|
+
me.myEventCls.onIds("#" + me.rmsdplotid + "_json", "click", function(e) { let ic = me.icn3d;
|
|
65828
|
+
e.preventDefault();
|
|
65829
|
+
|
|
65830
|
+
ic.saveFileCls.saveFile(ic.inputid + "_rmsdplot.json", "text", [JSON.stringify(ic.mdDataSet)]);
|
|
65831
|
+
});
|
|
65832
|
+
|
|
65626
65833
|
me.myEventCls.onIds("#" + me.ligplotid + "_svg", "click", function(e) { let ic = me.icn3d;
|
|
65627
65834
|
e.preventDefault();
|
|
65628
65835
|
|
|
@@ -66019,6 +66226,39 @@ class Events {
|
|
|
66019
66226
|
ic.drawCls.draw();
|
|
66020
66227
|
});
|
|
66021
66228
|
|
|
66229
|
+
me.myEventCls.onIds("#" + me.pre + "applyplane3sets", "click", function(e) { let ic = me.icn3d;
|
|
66230
|
+
e.preventDefault();
|
|
66231
|
+
|
|
66232
|
+
ic.bLinebtwsets = false;
|
|
66233
|
+
|
|
66234
|
+
let nameArray = $("#" + me.pre + "plane3sets").val();
|
|
66235
|
+
let nameArray2 = $("#" + me.pre + "plane3sets2").val();
|
|
66236
|
+
let nameArray3 = $("#" + me.pre + "plane3sets3").val();
|
|
66237
|
+
|
|
66238
|
+
let atomSet1 = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
|
|
66239
|
+
let atomSet2 = ic.definedSetsCls.getAtomsFromNameArray(nameArray2);
|
|
66240
|
+
let atomSet3 = ic.definedSetsCls.getAtomsFromNameArray(nameArray3);
|
|
66241
|
+
|
|
66242
|
+
let posArray1 = ic.contactCls.getExtent(atomSet1);
|
|
66243
|
+
let posArray2 = ic.contactCls.getExtent(atomSet2);
|
|
66244
|
+
let posArray3 = ic.contactCls.getExtent(atomSet3);
|
|
66245
|
+
|
|
66246
|
+
let pos1 = new Vector3$1(posArray1[2][0], posArray1[2][1], posArray1[2][2]);
|
|
66247
|
+
let pos2 = new Vector3$1(posArray2[2][0], posArray2[2][1], posArray2[2][2]);
|
|
66248
|
+
let pos3 = new Vector3$1(posArray3[2][0], posArray3[2][1], posArray3[2][2]);
|
|
66249
|
+
|
|
66250
|
+
let thickness = $("#" + me.pre + "plane3sets_thickness").val();
|
|
66251
|
+
let color = $("#" + me.pre + "plane3sets_customcolor").val();
|
|
66252
|
+
let opacity = $("#" + me.pre + "plane3sets_opacity").val();
|
|
66253
|
+
|
|
66254
|
+
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;
|
|
66255
|
+
|
|
66256
|
+
thisClass.setLogCmd(command, true);
|
|
66257
|
+
|
|
66258
|
+
ic.analysisCls.addPlane(pos1.x, pos1.y, pos1.z, pos2.x, pos2.y, pos2.z, pos3.x, pos3.y, pos3.z, color, thickness, opacity);
|
|
66259
|
+
ic.drawCls.draw();
|
|
66260
|
+
});
|
|
66261
|
+
|
|
66022
66262
|
me.myEventCls.onIds("#" + me.pre + "applycartoonshape", "click", function(e) { let ic = me.icn3d;
|
|
66023
66263
|
e.preventDefault();
|
|
66024
66264
|
|
|
@@ -66066,6 +66306,16 @@ class Events {
|
|
|
66066
66306
|
ic.drawCls.draw();
|
|
66067
66307
|
});
|
|
66068
66308
|
|
|
66309
|
+
me.myEventCls.onIds("#" + me.pre + "clearplane3sets", "click", function(e) { let ic = me.icn3d;
|
|
66310
|
+
e.preventDefault();
|
|
66311
|
+
|
|
66312
|
+
|
|
66313
|
+
ic.planes = [];
|
|
66314
|
+
thisClass.setLogCmd('clear plane among sets', true);
|
|
66315
|
+
|
|
66316
|
+
ic.drawCls.draw();
|
|
66317
|
+
});
|
|
66318
|
+
|
|
66069
66319
|
me.myEventCls.onIds("#" + me.pre + "clearcartoonshape", "click", function(e) { let ic = me.icn3d;
|
|
66070
66320
|
e.preventDefault();
|
|
66071
66321
|
|
|
@@ -67562,6 +67812,12 @@ class SetHtml {
|
|
|
67562
67812
|
else if(type === 'xyz') {
|
|
67563
67813
|
await ic.xyzParserCls.loadXyzData(data);
|
|
67564
67814
|
}
|
|
67815
|
+
else if(type === 'dcd') {
|
|
67816
|
+
await ic.dcdParserCls.loadDcdData(data);
|
|
67817
|
+
}
|
|
67818
|
+
else if(type === 'xtc') {
|
|
67819
|
+
await ic.xtcParserCls.loadXtcData(data);
|
|
67820
|
+
}
|
|
67565
67821
|
else if(type === 'mmcif') {
|
|
67566
67822
|
await ic.mmcifParserCls.loadMmcifData(data);
|
|
67567
67823
|
}
|
|
@@ -77241,6 +77497,37 @@ class Cylinder {
|
|
|
77241
77497
|
}
|
|
77242
77498
|
}
|
|
77243
77499
|
|
|
77500
|
+
//Create planes for a list of "planes", each of which has the properties 'position1', 'position2', 'position2', 'color', 'thickness', 'opacity',
|
|
77501
|
+
createPlanes(planes) { let ic = this.icn3d, me = ic.icn3dui;
|
|
77502
|
+
if(me.bNode) return;
|
|
77503
|
+
|
|
77504
|
+
for(let i = 0, il = planes.length; i < il; ++i) {
|
|
77505
|
+
let plane = planes[i];
|
|
77506
|
+
|
|
77507
|
+
let p1 = plane.position1;
|
|
77508
|
+
let p2 = plane.position2;
|
|
77509
|
+
let p3 = plane.position3;
|
|
77510
|
+
|
|
77511
|
+
let thickness = (plane.thickness) ? plane.thickness : 2;
|
|
77512
|
+
let opacity = (plane.opacity) ? plane.opacity : 0.3;
|
|
77513
|
+
let colorStr = '#' + plane.color.replace(/\#/g, '');
|
|
77514
|
+
let color = me.parasCls.thr(colorStr);
|
|
77515
|
+
|
|
77516
|
+
let planeGeo = new Plane();
|
|
77517
|
+
planeGeo.setFromCoplanarPoints(p1, p2, p3);
|
|
77518
|
+
let planeNormal = planeGeo.normal;
|
|
77519
|
+
|
|
77520
|
+
const projectedPoint = new Vector3$1();
|
|
77521
|
+
// Project the center onto the plane
|
|
77522
|
+
planeGeo.projectPoint(ic.center, projectedPoint);
|
|
77523
|
+
|
|
77524
|
+
let c0 = projectedPoint.clone().sub(planeNormal.clone().multiplyScalar(thickness * 0.5));
|
|
77525
|
+
let c1 = projectedPoint.clone().add(planeNormal.clone().multiplyScalar(thickness * 0.5));
|
|
77526
|
+
let radius = ic.maxD / 2;
|
|
77527
|
+
ic.cylinderCls.createCylinder(c0, c1, radius, color, undefined, color, undefined, undefined, opacity);
|
|
77528
|
+
}
|
|
77529
|
+
}
|
|
77530
|
+
|
|
77244
77531
|
createCylinder_base(p0, p1, radius, color, bHighlight, color2, bPicking) { let ic = this.icn3d, me = ic.icn3dui;
|
|
77245
77532
|
if(me.bNode) return;
|
|
77246
77533
|
|
|
@@ -77652,7 +77939,7 @@ class Line$1 {
|
|
|
77652
77939
|
}
|
|
77653
77940
|
|
|
77654
77941
|
// do not add the artificial lines to raycasting objects
|
|
77655
|
-
}
|
|
77942
|
+
}
|
|
77656
77943
|
|
|
77657
77944
|
}
|
|
77658
77945
|
|
|
@@ -78130,7 +78417,7 @@ class FirstAtomObj {
|
|
|
78130
78417
|
let firstIndex;
|
|
78131
78418
|
|
|
78132
78419
|
for(let i in atomsHash) {
|
|
78133
|
-
if(ic.atoms[i].name == 'CA') {
|
|
78420
|
+
if(ic.atoms[i] && ic.atoms[i].name == 'CA') {
|
|
78134
78421
|
firstIndex = i;
|
|
78135
78422
|
break;
|
|
78136
78423
|
}
|
|
@@ -78138,7 +78425,7 @@ class FirstAtomObj {
|
|
|
78138
78425
|
|
|
78139
78426
|
if(!firstIndex) {
|
|
78140
78427
|
for(let i in atomsHash) {
|
|
78141
|
-
if(ic.atoms[i].name == "O3'" || ic.atoms[i].name == "O3*") {
|
|
78428
|
+
if(ic.atoms[i] && (ic.atoms[i].name == "O3'" || ic.atoms[i].name == "O3*")) {
|
|
78142
78429
|
firstIndex = i;
|
|
78143
78430
|
break;
|
|
78144
78431
|
}
|
|
@@ -78217,7 +78504,7 @@ class FirstAtomObj {
|
|
|
78217
78504
|
getAtomFromResi(resid, atomName) { let ic = this.icn3d; ic.icn3dui;
|
|
78218
78505
|
if(ic.residues.hasOwnProperty(resid)) {
|
|
78219
78506
|
for(let i in ic.residues[resid]) {
|
|
78220
|
-
if(ic.atoms[i].name === atomName && !ic.atoms[i].het) {
|
|
78507
|
+
if(ic.atoms[i] && ic.atoms[i].name === atomName && !ic.atoms[i].het) {
|
|
78221
78508
|
return ic.atoms[i];
|
|
78222
78509
|
}
|
|
78223
78510
|
}
|
|
@@ -84067,6 +84354,8 @@ class ApplyOther {
|
|
|
84067
84354
|
}
|
|
84068
84355
|
|
|
84069
84356
|
ic.lineCls.createLines(ic.lines);
|
|
84357
|
+
if(!ic.planes) ic.planes = [];
|
|
84358
|
+
ic.cylinderCls.createPlanes(ic.planes);
|
|
84070
84359
|
// }
|
|
84071
84360
|
|
|
84072
84361
|
// distance sets
|
|
@@ -86300,7 +86589,7 @@ class Alternate {
|
|
|
86300
86589
|
|
|
86301
86590
|
// change the display atom when alternating
|
|
86302
86591
|
//Show structures one by one.
|
|
86303
|
-
|
|
86592
|
+
alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
|
|
86304
86593
|
ic.bAlternate = true;
|
|
86305
86594
|
|
|
86306
86595
|
//ic.transformCls.zoominSelection();
|
|
@@ -86445,7 +86734,7 @@ class Alternate {
|
|
|
86445
86734
|
|
|
86446
86735
|
async alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
|
|
86447
86736
|
ic.bAlternate = true;
|
|
86448
|
-
|
|
86737
|
+
this.alternateStructures();
|
|
86449
86738
|
ic.bAlternate = false;
|
|
86450
86739
|
}
|
|
86451
86740
|
|
|
@@ -97134,6 +97423,8 @@ class ShowAnno {
|
|
|
97134
97423
|
ic.seqAnnWidth = dialogWidth - 120 - 30*2 - 50; // title: 120px, start and end resi: 30px, extra space on the left and right: 50px
|
|
97135
97424
|
|
|
97136
97425
|
for(let i = 0, il = chainArray.length; i < il; ++i) {
|
|
97426
|
+
if(!ic.chainsSeq[chainArray[i]]) continue; // skip empty chain
|
|
97427
|
+
|
|
97137
97428
|
Math.round(chainArray[i].indexOf('_'));
|
|
97138
97429
|
//if(pos > 4) continue; // NMR structures with structure id such as 2K042,2K043, ...
|
|
97139
97430
|
// let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chainArray[i]]);
|
|
@@ -99856,7 +100147,7 @@ class LineGraph {
|
|
|
99856
100147
|
}
|
|
99857
100148
|
|
|
99858
100149
|
for(let i = 0, il = structureArray.length; i < il; ++i) {
|
|
99859
|
-
let labelFinal = label;
|
|
100150
|
+
let labelFinal = (i+1).toString() + '. ' + label;
|
|
99860
100151
|
if(bMutation) {
|
|
99861
100152
|
if(i == 0) {
|
|
99862
100153
|
labelFinal += "Wild Type ";
|
|
@@ -107564,6 +107855,12 @@ class PdbParser {
|
|
|
107564
107855
|
else if(type === 'xyz') {
|
|
107565
107856
|
await ic.xyzParserCls.loadXyzData(data);
|
|
107566
107857
|
}
|
|
107858
|
+
else if(type === 'dcd') {
|
|
107859
|
+
await ic.dcdParserCls.loadDcdData(data);
|
|
107860
|
+
}
|
|
107861
|
+
else if(type === 'xtc') {
|
|
107862
|
+
await ic.xtcParserCls.loadXtcData(data);
|
|
107863
|
+
}
|
|
107567
107864
|
else if(type === 'mmcif') {
|
|
107568
107865
|
await ic.mmcifParserCls.loadMmcifData(data);
|
|
107569
107866
|
}
|
|
@@ -108118,6 +108415,995 @@ class XyzParser {
|
|
|
108118
108415
|
}
|
|
108119
108416
|
}
|
|
108120
108417
|
|
|
108418
|
+
/**
|
|
108419
|
+
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
108420
|
+
*/
|
|
108421
|
+
|
|
108422
|
+
class DcdParser {
|
|
108423
|
+
constructor(icn3d) {
|
|
108424
|
+
this.icn3d = icn3d;
|
|
108425
|
+
icn3d.DELTA = 1;
|
|
108426
|
+
icn3d.TIMEOFFSET = 0;
|
|
108427
|
+
}
|
|
108428
|
+
|
|
108429
|
+
async loadDcdData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
108430
|
+
let bResult = this.loadDcdAtomData(data);
|
|
108431
|
+
|
|
108432
|
+
if(me.cfg.align === undefined && Object.keys(ic.structures).length == 1) {
|
|
108433
|
+
$("#" + ic.pre + "alternateWrapper").hide();
|
|
108434
|
+
}
|
|
108435
|
+
|
|
108436
|
+
if(!bResult) {
|
|
108437
|
+
var aaa = 1; //alert('The DCD file has the wrong format...');
|
|
108438
|
+
}
|
|
108439
|
+
else {
|
|
108440
|
+
ic.setStyleCls.setAtomStyleByOptions(ic.opts);
|
|
108441
|
+
ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
|
|
108442
|
+
|
|
108443
|
+
// hide water, ions
|
|
108444
|
+
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
108445
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.nucleotides);
|
|
108446
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chemicals);
|
|
108447
|
+
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
108448
|
+
ic.transformCls.zoominSelection();
|
|
108449
|
+
|
|
108450
|
+
// ic.bRender = true;
|
|
108451
|
+
await ic.ParserUtilsCls.renderStructure();
|
|
108452
|
+
|
|
108453
|
+
if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
|
|
108454
|
+
|
|
108455
|
+
//if(me.deferred !== undefined) me.deferred.resolve(); /// if(ic.deferred2 !== undefined) ic.deferred2.resolve();
|
|
108456
|
+
}
|
|
108457
|
+
}
|
|
108458
|
+
|
|
108459
|
+
// modified from https://github.com/molstar/molstar/blob/master/src/mol-io/reader/dcd/parser.ts
|
|
108460
|
+
loadDcdAtomData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
108461
|
+
// http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/dcdplugin.html
|
|
108462
|
+
|
|
108463
|
+
// The DCD format is structured as follows
|
|
108464
|
+
// (FORTRAN UNFORMATTED, with Fortran data type descriptions):
|
|
108465
|
+
// HDR NSET ISTRT NSAVC 5-ZEROS NATOM-NFREAT DELTA 9-ZEROS
|
|
108466
|
+
// `CORD' #files step 1 step zeroes (zero) timestep (zeroes)
|
|
108467
|
+
// interval
|
|
108468
|
+
// C*4 INT INT INT 5INT INT DOUBLE 9INT
|
|
108469
|
+
// ==========================================================================
|
|
108470
|
+
// NTITLE TITLE
|
|
108471
|
+
// INT (=2) C*MAXTITL
|
|
108472
|
+
// (=32)
|
|
108473
|
+
// ==========================================================================
|
|
108474
|
+
// NATOM
|
|
108475
|
+
// #atoms
|
|
108476
|
+
// INT
|
|
108477
|
+
// ==========================================================================
|
|
108478
|
+
// X(I), I=1,NATOM (DOUBLE)
|
|
108479
|
+
// Y(I), I=1,NATOM
|
|
108480
|
+
// Z(I), I=1,NATOM
|
|
108481
|
+
// ==========================================================================
|
|
108482
|
+
|
|
108483
|
+
let bin =(data.buffer && data.buffer instanceof ArrayBuffer) ? data.buffer : data;
|
|
108484
|
+
const dv = new DataView(bin);
|
|
108485
|
+
|
|
108486
|
+
// const header: Mutable<DcdHeader> = Object.create(null);
|
|
108487
|
+
// const frames: DcdFrame[] = [];
|
|
108488
|
+
const header = {};
|
|
108489
|
+
|
|
108490
|
+
let nextPos = 0;
|
|
108491
|
+
|
|
108492
|
+
// header block
|
|
108493
|
+
|
|
108494
|
+
const intView = new Int32Array(bin, 0, 23);
|
|
108495
|
+
const ef = intView[0] !== dv.getInt32(0); // endianess flag
|
|
108496
|
+
// swap byte order when big endian (84 indicates little endian)
|
|
108497
|
+
if (intView[0] !== 84) {
|
|
108498
|
+
const n = data.byteLength;
|
|
108499
|
+
for (let i = 0; i < n; i += 4) {
|
|
108500
|
+
dv.setFloat32(i, dv.getFloat32(i), true);
|
|
108501
|
+
}
|
|
108502
|
+
}
|
|
108503
|
+
if (intView[0] !== 84) {
|
|
108504
|
+
console.error('dcd bad format, header block start');
|
|
108505
|
+
return false;
|
|
108506
|
+
}
|
|
108507
|
+
|
|
108508
|
+
// format indicator, should read 'CORD'
|
|
108509
|
+
const formatString = String.fromCharCode(
|
|
108510
|
+
dv.getUint8(4), dv.getUint8(5),
|
|
108511
|
+
dv.getUint8(6), dv.getUint8(7)
|
|
108512
|
+
);
|
|
108513
|
+
if (formatString !== 'CORD') {
|
|
108514
|
+
console.error('dcd bad format, format string');
|
|
108515
|
+
return false;
|
|
108516
|
+
}
|
|
108517
|
+
let isCharmm = false;
|
|
108518
|
+
let extraBlock = false;
|
|
108519
|
+
let fourDims = false;
|
|
108520
|
+
// version field in charmm, unused in X-PLOR
|
|
108521
|
+
if (intView[22] !== 0) {
|
|
108522
|
+
isCharmm = true;
|
|
108523
|
+
if (intView[12] !== 0) extraBlock = true;
|
|
108524
|
+
if (intView[13] === 1) fourDims = true;
|
|
108525
|
+
}
|
|
108526
|
+
header.NSET = intView[2];
|
|
108527
|
+
header.ISTART = intView[3];
|
|
108528
|
+
header.NSAVC = intView[4];
|
|
108529
|
+
header.NAMNF = intView[10];
|
|
108530
|
+
|
|
108531
|
+
ic.frames = header.NSET;
|
|
108532
|
+
|
|
108533
|
+
if (isCharmm) {
|
|
108534
|
+
header.DELTA = dv.getFloat32(44, ef);
|
|
108535
|
+
} else {
|
|
108536
|
+
header.DELTA = dv.getFloat64(44, ef);
|
|
108537
|
+
}
|
|
108538
|
+
this.DELTA = header.DELTA;
|
|
108539
|
+
|
|
108540
|
+
if (intView[22] !== 84) {
|
|
108541
|
+
console.error('dcd bad format, header block end');
|
|
108542
|
+
return false;
|
|
108543
|
+
}
|
|
108544
|
+
nextPos = nextPos + 21 * 4 + 8;
|
|
108545
|
+
|
|
108546
|
+
// title block
|
|
108547
|
+
|
|
108548
|
+
const titleEnd = dv.getInt32(nextPos, ef);
|
|
108549
|
+
const titleStart = nextPos + 1;
|
|
108550
|
+
if ((titleEnd - 4) % 80 !== 0) {
|
|
108551
|
+
console.error('dcd bad format, title block start');
|
|
108552
|
+
return false;
|
|
108553
|
+
}
|
|
108554
|
+
|
|
108555
|
+
let byteView = new Uint8Array(bin);
|
|
108556
|
+
header.TITLE = String.fromCharCode.apply(null, byteView.subarray(titleStart, titleEnd));
|
|
108557
|
+
if (dv.getInt32(titleStart + titleEnd + 4 - 1, ef) !== titleEnd) {
|
|
108558
|
+
console.error('dcd bad format, title block end');
|
|
108559
|
+
return false;
|
|
108560
|
+
}
|
|
108561
|
+
|
|
108562
|
+
nextPos = nextPos + titleEnd + 8;
|
|
108563
|
+
|
|
108564
|
+
// natom block
|
|
108565
|
+
|
|
108566
|
+
if (dv.getInt32(nextPos, ef) !== 4) {
|
|
108567
|
+
console.error('dcd bad format, natom block start');
|
|
108568
|
+
return false;
|
|
108569
|
+
}
|
|
108570
|
+
header.NATOM = dv.getInt32(nextPos + 4, ef);
|
|
108571
|
+
if (dv.getInt32(nextPos + 8, ef) !== 4) {
|
|
108572
|
+
console.error('dcd bad format, natom block end');
|
|
108573
|
+
return false;
|
|
108574
|
+
}
|
|
108575
|
+
nextPos = nextPos + 4 + 8;
|
|
108576
|
+
|
|
108577
|
+
// fixed atoms block
|
|
108578
|
+
|
|
108579
|
+
if (header.NAMNF > 0) {
|
|
108580
|
+
// TODO read coordinates and indices of fixed atoms
|
|
108581
|
+
console.error('dcd format with fixed atoms unsupported, aborting');
|
|
108582
|
+
return false;
|
|
108583
|
+
}
|
|
108584
|
+
|
|
108585
|
+
// frames
|
|
108586
|
+
const natom = header.NATOM;
|
|
108587
|
+
const natom4 = natom * 4;
|
|
108588
|
+
|
|
108589
|
+
if(natom != Object.keys(ic.atoms).length) {
|
|
108590
|
+
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);
|
|
108591
|
+
return false;
|
|
108592
|
+
}
|
|
108593
|
+
|
|
108594
|
+
let structuresOri = me.hashUtilsCls.cloneHash(ic.structures);
|
|
108595
|
+
let residuesOri = me.hashUtilsCls.cloneHash(ic.residues);
|
|
108596
|
+
let chainsOri = me.hashUtilsCls.cloneHash(ic.chains);
|
|
108597
|
+
|
|
108598
|
+
let proteinsOri = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
108599
|
+
let nucleotidesOri = me.hashUtilsCls.cloneHash(ic.nucleotides);
|
|
108600
|
+
let waterOri = me.hashUtilsCls.cloneHash(ic.water);
|
|
108601
|
+
let ionsOri = me.hashUtilsCls.cloneHash(ic.ions);
|
|
108602
|
+
let chemicalsOri = me.hashUtilsCls.cloneHash(ic.chemicals);
|
|
108603
|
+
|
|
108604
|
+
let serial = natom + 1; // a preloaded PDB structure would have atom serial from 1 to natom
|
|
108605
|
+
for (let i = 0, n = header.NSET; i < n; ++i) {
|
|
108606
|
+
const frame = {};
|
|
108607
|
+
frame.elementCount = natom;
|
|
108608
|
+
|
|
108609
|
+
if (extraBlock) {
|
|
108610
|
+
nextPos += 4; // block start
|
|
108611
|
+
frame.cell = [
|
|
108612
|
+
dv.getFloat64(nextPos, ef),
|
|
108613
|
+
dv.getFloat64(nextPos + 1, ef),
|
|
108614
|
+
dv.getFloat64(nextPos + 2 * 8, ef),
|
|
108615
|
+
dv.getFloat64(nextPos + 3 * 8, ef),
|
|
108616
|
+
dv.getFloat64(nextPos + 4 * 8, ef),
|
|
108617
|
+
dv.getFloat64(nextPos + 5 * 8, ef)
|
|
108618
|
+
];
|
|
108619
|
+
nextPos += 48;
|
|
108620
|
+
nextPos += 4; // block end
|
|
108621
|
+
}
|
|
108622
|
+
|
|
108623
|
+
// xyz coordinates
|
|
108624
|
+
for (let j = 0; j < 3; ++j) {
|
|
108625
|
+
if (dv.getInt32(nextPos, ef) !== natom4) {
|
|
108626
|
+
console.error(`dcd bad format, coord block start: ${i}, ${j}`);
|
|
108627
|
+
return false;
|
|
108628
|
+
}
|
|
108629
|
+
nextPos += 4; // block start
|
|
108630
|
+
const c = new Float32Array(bin, nextPos, natom);
|
|
108631
|
+
if (j === 0) frame.x = c;
|
|
108632
|
+
else if (j === 1) frame.y = c;
|
|
108633
|
+
else frame.z = c;
|
|
108634
|
+
|
|
108635
|
+
nextPos += natom4;
|
|
108636
|
+
if (dv.getInt32(nextPos, ef) !== natom4) {
|
|
108637
|
+
console.error(`dcd bad format, coord block end: ${i}, ${j}`);
|
|
108638
|
+
return false;
|
|
108639
|
+
}
|
|
108640
|
+
nextPos += 4; // block end
|
|
108641
|
+
}
|
|
108642
|
+
|
|
108643
|
+
if (fourDims) {
|
|
108644
|
+
const bytes = dv.getInt32(nextPos, ef);
|
|
108645
|
+
nextPos += 4 + bytes + 4; // block start + skip + block end
|
|
108646
|
+
}
|
|
108647
|
+
|
|
108648
|
+
// skip the first structure since it was read from PDB already
|
|
108649
|
+
if(i == 0) continue;
|
|
108650
|
+
|
|
108651
|
+
let molNum = i + 1; // to avoid the same molNum as the PDB structure
|
|
108652
|
+
for(let j = 0; j < natom; ++j) {
|
|
108653
|
+
let coord = new Vector3$1(frame.x[j], frame.y[j], frame.z[j]);
|
|
108654
|
+
|
|
108655
|
+
let atom = me.hashUtilsCls.cloneHash(ic.atoms[j + 1]);
|
|
108656
|
+
|
|
108657
|
+
atom.serial = serial;
|
|
108658
|
+
atom.structure = atom.structure + molNum;
|
|
108659
|
+
atom.coord = coord;
|
|
108660
|
+
atom.bonds = [].concat(ic.atoms[j + 1].bonds);
|
|
108661
|
+
|
|
108662
|
+
// update bonds
|
|
108663
|
+
for(let k = 0, kl = atom.bonds.length; k < kl; ++k) {
|
|
108664
|
+
atom.bonds[k] = parseInt(atom.bonds[k]) + natom * i;
|
|
108665
|
+
}
|
|
108666
|
+
|
|
108667
|
+
ic.atoms[serial] = atom;
|
|
108668
|
+
|
|
108669
|
+
// assign extra info
|
|
108670
|
+
ic.dAtoms[serial] = 1;
|
|
108671
|
+
ic.hAtoms[serial] = 1;
|
|
108672
|
+
|
|
108673
|
+
let chainid = atom.structure + '_' + atom.chain;
|
|
108674
|
+
let residid = chainid + '_' + atom.resi;
|
|
108675
|
+
ic.secondaries[residid] = atom.ss;
|
|
108676
|
+
ic.residueId2Name[residid] = me.utilsCls.residueName2Abbr(atom.resn);
|
|
108677
|
+
|
|
108678
|
+
++serial;
|
|
108679
|
+
}
|
|
108680
|
+
|
|
108681
|
+
// update ic.structures, ic.residues and ic.chains
|
|
108682
|
+
for(let structure in structuresOri) {
|
|
108683
|
+
let structure2 = structure + molNum;
|
|
108684
|
+
ic.structures[structure2] = [];
|
|
108685
|
+
|
|
108686
|
+
for(let k = 0, kl = structuresOri[structure].length; k < kl; ++k) {
|
|
108687
|
+
let idArray = structuresOri[structure][k].split('_');
|
|
108688
|
+
ic.structures[structure2].push(structure2 + '_' + idArray[1]);
|
|
108689
|
+
}
|
|
108690
|
+
}
|
|
108691
|
+
|
|
108692
|
+
for(let j in residuesOri) {
|
|
108693
|
+
let idArray = j.split('_');
|
|
108694
|
+
let structure2 = idArray[0] + molNum;
|
|
108695
|
+
let residid2 = structure2 + '_' + idArray[1] + '_' + idArray[2];
|
|
108696
|
+
ic.residues[residid2] = {};
|
|
108697
|
+
|
|
108698
|
+
for(let k in residuesOri[j]) {
|
|
108699
|
+
ic.residues[residid2][parseInt(k) + natom * i] = 1;
|
|
108700
|
+
}
|
|
108701
|
+
}
|
|
108702
|
+
|
|
108703
|
+
for(let j in chainsOri) {
|
|
108704
|
+
let idArray = j.split('_');
|
|
108705
|
+
let structure2 = idArray[0] + molNum;
|
|
108706
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
108707
|
+
|
|
108708
|
+
// ic.chainsSeq[chainid2] = [].concat(ic.chainsSeq[j]);
|
|
108709
|
+
|
|
108710
|
+
ic.chains[chainid2] = {};
|
|
108711
|
+
for(let k in chainsOri[j]) {
|
|
108712
|
+
ic.chains[chainid2][parseInt(k)+ natom * i] = 1;
|
|
108713
|
+
}
|
|
108714
|
+
}
|
|
108715
|
+
|
|
108716
|
+
// update ic.proteins, etc
|
|
108717
|
+
for(let j in proteinsOri) {
|
|
108718
|
+
ic.proteins[parseInt(j) + natom * i] = 1;
|
|
108719
|
+
}
|
|
108720
|
+
for(let j in nucleotidesOri) {
|
|
108721
|
+
ic.nucleotides[parseInt(j) + natom * i] = 1;
|
|
108722
|
+
}
|
|
108723
|
+
for(let j in waterOri) {
|
|
108724
|
+
ic.water[parseInt(j) + natom * i] = 1;
|
|
108725
|
+
}
|
|
108726
|
+
for(let j in ionsOri) {
|
|
108727
|
+
ic.ions[parseInt(j) + natom * i] = 1;
|
|
108728
|
+
}
|
|
108729
|
+
for(let j in chemicalsOri) {
|
|
108730
|
+
ic.chemicals[parseInt(j) + natom * i] = 1;
|
|
108731
|
+
}
|
|
108732
|
+
|
|
108733
|
+
// set ic.ncbi2resid and ic.resid2ncbi
|
|
108734
|
+
for(let chainid in chainsOri) {
|
|
108735
|
+
let idArray = chainid.split('_');
|
|
108736
|
+
let structure2 = idArray[0] + molNum;
|
|
108737
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
108738
|
+
|
|
108739
|
+
for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
|
|
108740
|
+
// NCBI residue number starts from 1 and increases continuously
|
|
108741
|
+
let residNCBI = chainid2 + '_' + (j+1).toString();
|
|
108742
|
+
let resid = chainid2 + '_' + ic.chainsSeq[chainid][j].resi;
|
|
108743
|
+
ic.ncbi2resid[residNCBI] = resid;
|
|
108744
|
+
ic.resid2ncbi[resid] = residNCBI;
|
|
108745
|
+
}
|
|
108746
|
+
}
|
|
108747
|
+
}
|
|
108748
|
+
|
|
108749
|
+
ic.molTitle = header.TITLE;
|
|
108750
|
+
ic.inputid = 'stru';
|
|
108751
|
+
|
|
108752
|
+
// ic.ParserUtilsCls.setMaxD();
|
|
108753
|
+
|
|
108754
|
+
ic.saveFileCls.showTitle();
|
|
108755
|
+
|
|
108756
|
+
return true;
|
|
108757
|
+
}
|
|
108758
|
+
|
|
108759
|
+
async showRmsdPlot() { let ic = this.icn3d, me = ic.icn3dui;
|
|
108760
|
+
if(ic.bChartjs === undefined) {
|
|
108761
|
+
let url = "https://cdn.jsdelivr.net/npm/chart.js";
|
|
108762
|
+
await me.getAjaxPromise(url, 'script');
|
|
108763
|
+
|
|
108764
|
+
ic.bChartjs = true;
|
|
108765
|
+
}
|
|
108766
|
+
|
|
108767
|
+
$("#" + me.rmsdplotid).empty();
|
|
108768
|
+
me.htmlCls.dialogCls.openDlg('dl_rmsdplot', 'RMSD Plot');
|
|
108769
|
+
|
|
108770
|
+
let dataSet = [];
|
|
108771
|
+
let structureArray = Object.keys(ic.structures);
|
|
108772
|
+
let coord1 = [], coord2 = [];
|
|
108773
|
+
for(let i = 0, il = structureArray.length; i < il; ++i) {
|
|
108774
|
+
let chainArray = ic.structures[structureArray[i]];
|
|
108775
|
+
|
|
108776
|
+
let coord = [];
|
|
108777
|
+
let nAtoms = 0;
|
|
108778
|
+
for(let j = 0, jl = chainArray.length; j < jl; ++j) {
|
|
108779
|
+
let chainid = chainArray[j];
|
|
108780
|
+
for(let k in ic.chains[chainid]) {
|
|
108781
|
+
let atom = ic.atoms[k];
|
|
108782
|
+
// only align proteins
|
|
108783
|
+
if(ic.proteins.hasOwnProperty(atom.serial)) {
|
|
108784
|
+
coord.push(atom.coord);
|
|
108785
|
+
++nAtoms;
|
|
108786
|
+
}
|
|
108787
|
+
}
|
|
108788
|
+
}
|
|
108789
|
+
|
|
108790
|
+
if(i == 0) {
|
|
108791
|
+
coord1 = [].concat(coord);
|
|
108792
|
+
}
|
|
108793
|
+
else {
|
|
108794
|
+
coord2 = coord;
|
|
108795
|
+
}
|
|
108796
|
+
|
|
108797
|
+
if(i > 0) {
|
|
108798
|
+
let result = me.rmsdSuprCls.getRmsdSuprCls(coord1, coord2, nAtoms);
|
|
108799
|
+
let rmsd = (result.rmsd * 0.1).toPrecision(4); // convert from Å to nm
|
|
108800
|
+
|
|
108801
|
+
let time = ic.TIMEOFFSET + (i * ic.DELTA).toPrecision(4);
|
|
108802
|
+
dataSet.push({x: time, y: rmsd});
|
|
108803
|
+
}
|
|
108804
|
+
}
|
|
108805
|
+
|
|
108806
|
+
ic.mdDataSet = dataSet;
|
|
108807
|
+
if(me.bNode) console.log(dataSet);
|
|
108808
|
+
|
|
108809
|
+
let stepSize = (structureArray.length - 1) * ic.DELTA / 10; // 10 ticks
|
|
108810
|
+
|
|
108811
|
+
// https://www.chartjs.org/docs/latest/samples/line/line.html
|
|
108812
|
+
// const ctx = $("#" + me.rmsdplotid)[0].getContext('2d');
|
|
108813
|
+
const ctx = $("#" + me.rmsdplotid)[0];
|
|
108814
|
+
|
|
108815
|
+
new Chart(ctx, {
|
|
108816
|
+
type: 'line',
|
|
108817
|
+
data: {
|
|
108818
|
+
datasets: [{
|
|
108819
|
+
label: 'RMSD',
|
|
108820
|
+
data: dataSet
|
|
108821
|
+
}]
|
|
108822
|
+
},
|
|
108823
|
+
options: {
|
|
108824
|
+
responsive: true,
|
|
108825
|
+
scales: {
|
|
108826
|
+
x: { // X-axis configuration
|
|
108827
|
+
title: {
|
|
108828
|
+
display: true, // Show the X-axis label
|
|
108829
|
+
text: 'Time (ps)' // Text for the X-axis label
|
|
108830
|
+
},
|
|
108831
|
+
type: 'linear', // Required for numerical x-axis
|
|
108832
|
+
position: 'bottom',
|
|
108833
|
+
ticks: {
|
|
108834
|
+
stepSize: stepSize
|
|
108835
|
+
}
|
|
108836
|
+
},
|
|
108837
|
+
y: { // Y-axis configuration (defaults to numeric scale)
|
|
108838
|
+
title: {
|
|
108839
|
+
display: true, // Show the Y-axis label
|
|
108840
|
+
text: 'RMSD (nm)' // Text for the Y-axis label
|
|
108841
|
+
}
|
|
108842
|
+
}
|
|
108843
|
+
}
|
|
108844
|
+
}
|
|
108845
|
+
});
|
|
108846
|
+
}
|
|
108847
|
+
}
|
|
108848
|
+
|
|
108849
|
+
/**
|
|
108850
|
+
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
108851
|
+
*/
|
|
108852
|
+
|
|
108853
|
+
class XtcParser {
|
|
108854
|
+
constructor(icn3d) {
|
|
108855
|
+
this.icn3d = icn3d;
|
|
108856
|
+
|
|
108857
|
+
icn3d.DELTA = 1;
|
|
108858
|
+
icn3d.TIMEOFFSET = 0;
|
|
108859
|
+
|
|
108860
|
+
this.MagicInts = new Uint32Array([
|
|
108861
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
|
|
108862
|
+
80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
|
|
108863
|
+
1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003,
|
|
108864
|
+
16384, 20642, 26007, 32768, 41285, 52015, 65536, 82570, 104031,
|
|
108865
|
+
131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561,
|
|
108866
|
+
832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021,
|
|
108867
|
+
4194304, 5284491, 6658042, 8388607, 10568983, 13316085, 16777216
|
|
108868
|
+
]);
|
|
108869
|
+
this.FirstIdx = 9;
|
|
108870
|
+
|
|
108871
|
+
this._tmpBytes = new Uint8Array(32);
|
|
108872
|
+
let _buffer = new ArrayBuffer(8 * 3);
|
|
108873
|
+
this.buf = new Int32Array(_buffer);
|
|
108874
|
+
this.uint32view = new Uint32Array(_buffer);
|
|
108875
|
+
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];
|
|
108876
|
+
}
|
|
108877
|
+
|
|
108878
|
+
async loadXtcData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
108879
|
+
let bResult = this.loadXtcAtomData(data);
|
|
108880
|
+
|
|
108881
|
+
if(me.cfg.align === undefined && Object.keys(ic.structures).length == 1) {
|
|
108882
|
+
$("#" + ic.pre + "alternateWrapper").hide();
|
|
108883
|
+
}
|
|
108884
|
+
|
|
108885
|
+
if(!bResult) {
|
|
108886
|
+
var aaa = 1; //alert('The XTC file has the wrong format...');
|
|
108887
|
+
}
|
|
108888
|
+
else {
|
|
108889
|
+
ic.setStyleCls.setAtomStyleByOptions(ic.opts);
|
|
108890
|
+
ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
|
|
108891
|
+
|
|
108892
|
+
// hide water, ions
|
|
108893
|
+
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
108894
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.nucleotides);
|
|
108895
|
+
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chemicals);
|
|
108896
|
+
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
108897
|
+
ic.transformCls.zoominSelection();
|
|
108898
|
+
|
|
108899
|
+
// ic.bRender = true;
|
|
108900
|
+
await ic.ParserUtilsCls.renderStructure();
|
|
108901
|
+
|
|
108902
|
+
if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
|
|
108903
|
+
|
|
108904
|
+
//if(me.deferred !== undefined) me.deferred.resolve(); /// if(ic.deferred2 !== undefined) ic.deferred2.resolve();
|
|
108905
|
+
}
|
|
108906
|
+
}
|
|
108907
|
+
|
|
108908
|
+
|
|
108909
|
+
// modified from https://github.com/molstar/molstar/blob/master/src/mol-io/reader/xtc/parser.ts
|
|
108910
|
+
loadXtcAtomData(data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
108911
|
+
// https://github.com/gromacs/gromacs/blob/master/src/gromacs/fileio/xtcio.cpp
|
|
108912
|
+
// https://github.com/gromacs/gromacs/blob/master/src/gromacs/fileio/libxdrf.cpp
|
|
108913
|
+
|
|
108914
|
+
let bin =(data.buffer && data.buffer instanceof ArrayBuffer) ? data.buffer : data;
|
|
108915
|
+
|
|
108916
|
+
// const dv = new DataView(bin, data.byteOffset);
|
|
108917
|
+
const dv = new DataView(bin);
|
|
108918
|
+
|
|
108919
|
+
data = new Uint8Array(bin);
|
|
108920
|
+
|
|
108921
|
+
// const f = {
|
|
108922
|
+
// frames: [],
|
|
108923
|
+
// boxes: [],
|
|
108924
|
+
// times: [],
|
|
108925
|
+
// timeOffset: 0,
|
|
108926
|
+
// deltaTime: 0
|
|
108927
|
+
// };
|
|
108928
|
+
|
|
108929
|
+
const coordinates = []; //f.frames;
|
|
108930
|
+
const times = []; //f.times;
|
|
108931
|
+
|
|
108932
|
+
const minMaxInt = [0, 0, 0, 0, 0, 0];
|
|
108933
|
+
const sizeint = [0, 0, 0];
|
|
108934
|
+
const bitsizeint = [0, 0, 0];
|
|
108935
|
+
const sizesmall = [0, 0, 0];
|
|
108936
|
+
const thiscoord = [0.1, 0.1, 0.1];
|
|
108937
|
+
const prevcoord = [0.1, 0.1, 0.1];
|
|
108938
|
+
|
|
108939
|
+
let offset = 0, natom;
|
|
108940
|
+
|
|
108941
|
+
while (true) {
|
|
108942
|
+
let frameCoords;
|
|
108943
|
+
|
|
108944
|
+
// const magicnum = dv.getInt32(offset)
|
|
108945
|
+
natom = dv.getInt32(offset + 4);
|
|
108946
|
+
// const step = dv.getInt32(offset + 8)
|
|
108947
|
+
offset += 12;
|
|
108948
|
+
|
|
108949
|
+
if(natom != Object.keys(ic.atoms).length) {
|
|
108950
|
+
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);
|
|
108951
|
+
return false;
|
|
108952
|
+
}
|
|
108953
|
+
|
|
108954
|
+
times.push(dv.getFloat32(offset));
|
|
108955
|
+
offset += 4;
|
|
108956
|
+
|
|
108957
|
+
const box = new Float32Array(9);
|
|
108958
|
+
for (let i = 0; i < 9; ++i) {
|
|
108959
|
+
box[i] = dv.getFloat32(offset) * 10;
|
|
108960
|
+
offset += 4;
|
|
108961
|
+
}
|
|
108962
|
+
|
|
108963
|
+
if (natom <= 9) { // no compression
|
|
108964
|
+
frameCoords = { count: natom, x: new Float32Array(natom), y: new Float32Array(natom), z: new Float32Array(natom) };
|
|
108965
|
+
offset += 4;
|
|
108966
|
+
for (let i = 0; i < natom; ++i) {
|
|
108967
|
+
frameCoords.x[i] = dv.getFloat32(offset);
|
|
108968
|
+
frameCoords.y[i] = dv.getFloat32(offset + 4);
|
|
108969
|
+
frameCoords.z[i] = dv.getFloat32(offset + 8);
|
|
108970
|
+
offset += 12;
|
|
108971
|
+
}
|
|
108972
|
+
} else {
|
|
108973
|
+
this.buf[0] = this.buf[1] = this.buf[2] = 0;
|
|
108974
|
+
sizeint[0] = sizeint[1] = sizeint[2] = 0;
|
|
108975
|
+
sizesmall[0] = sizesmall[1] = sizesmall[2] = 0;
|
|
108976
|
+
bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0;
|
|
108977
|
+
thiscoord[0] = thiscoord[1] = thiscoord[2] = 0;
|
|
108978
|
+
prevcoord[0] = prevcoord[1] = prevcoord[2] = 0;
|
|
108979
|
+
|
|
108980
|
+
frameCoords = { count: natom, x: new Float32Array(natom), y: new Float32Array(natom), z: new Float32Array(natom) };
|
|
108981
|
+
let lfp = 0;
|
|
108982
|
+
|
|
108983
|
+
const lsize = dv.getInt32(offset);
|
|
108984
|
+
offset += 4;
|
|
108985
|
+
const precision = dv.getFloat32(offset);
|
|
108986
|
+
offset += 4;
|
|
108987
|
+
|
|
108988
|
+
minMaxInt[0] = dv.getInt32(offset);
|
|
108989
|
+
minMaxInt[1] = dv.getInt32(offset + 4);
|
|
108990
|
+
minMaxInt[2] = dv.getInt32(offset + 8);
|
|
108991
|
+
minMaxInt[3] = dv.getInt32(offset + 12);
|
|
108992
|
+
minMaxInt[4] = dv.getInt32(offset + 16);
|
|
108993
|
+
minMaxInt[5] = dv.getInt32(offset + 20);
|
|
108994
|
+
sizeint[0] = minMaxInt[3] - minMaxInt[0] + 1;
|
|
108995
|
+
sizeint[1] = minMaxInt[4] - minMaxInt[1] + 1;
|
|
108996
|
+
sizeint[2] = minMaxInt[5] - minMaxInt[2] + 1;
|
|
108997
|
+
offset += 24;
|
|
108998
|
+
|
|
108999
|
+
let bitsize;
|
|
109000
|
+
if ((sizeint[0] | sizeint[1] | sizeint[2]) > 0xffffff) {
|
|
109001
|
+
bitsizeint[0] = this.sizeOfInt(sizeint[0]);
|
|
109002
|
+
bitsizeint[1] = this.sizeOfInt(sizeint[1]);
|
|
109003
|
+
bitsizeint[2] = this.sizeOfInt(sizeint[2]);
|
|
109004
|
+
bitsize = 0; // flag the use of large sizes
|
|
109005
|
+
} else {
|
|
109006
|
+
bitsize = this.sizeOfInts(3, sizeint);
|
|
109007
|
+
}
|
|
109008
|
+
|
|
109009
|
+
let smallidx = dv.getInt32(offset);
|
|
109010
|
+
offset += 4;
|
|
109011
|
+
|
|
109012
|
+
let tmpIdx = smallidx - 1;
|
|
109013
|
+
tmpIdx = (this.FirstIdx > tmpIdx) ? this.FirstIdx : tmpIdx;
|
|
109014
|
+
let smaller = (this.MagicInts[tmpIdx] / 2) | 0;
|
|
109015
|
+
let smallnum = (this.MagicInts[smallidx] / 2) | 0;
|
|
109016
|
+
|
|
109017
|
+
sizesmall[0] = sizesmall[1] = sizesmall[2] = this.MagicInts[smallidx];
|
|
109018
|
+
|
|
109019
|
+
const adz = Math.ceil(dv.getInt32(offset) / 4) * 4;
|
|
109020
|
+
offset += 4;
|
|
109021
|
+
|
|
109022
|
+
const invPrecision = 1.0 / precision;
|
|
109023
|
+
let run = 0;
|
|
109024
|
+
let i = 0;
|
|
109025
|
+
|
|
109026
|
+
// const this.buf8 = new Uint8Array(data.this.buffer, data.byteOffset + offset, 32 * 4); // 229...
|
|
109027
|
+
|
|
109028
|
+
thiscoord[0] = thiscoord[1] = thiscoord[2] = 0;
|
|
109029
|
+
|
|
109030
|
+
while (i < lsize) {
|
|
109031
|
+
if (bitsize === 0) {
|
|
109032
|
+
thiscoord[0] = this.decodeBits(data, offset, bitsizeint[0]);
|
|
109033
|
+
thiscoord[1] = this.decodeBits(data, offset, bitsizeint[1]);
|
|
109034
|
+
thiscoord[2] = this.decodeBits(data, offset, bitsizeint[2]);
|
|
109035
|
+
} else {
|
|
109036
|
+
this.decodeInts(data, offset, bitsize, sizeint, thiscoord);
|
|
109037
|
+
}
|
|
109038
|
+
|
|
109039
|
+
i++;
|
|
109040
|
+
|
|
109041
|
+
thiscoord[0] += minMaxInt[0];
|
|
109042
|
+
thiscoord[1] += minMaxInt[1];
|
|
109043
|
+
thiscoord[2] += minMaxInt[2];
|
|
109044
|
+
|
|
109045
|
+
prevcoord[0] = thiscoord[0];
|
|
109046
|
+
prevcoord[1] = thiscoord[1];
|
|
109047
|
+
prevcoord[2] = thiscoord[2];
|
|
109048
|
+
|
|
109049
|
+
const flag = this.decodeBits(data, offset, 1);
|
|
109050
|
+
let isSmaller = 0;
|
|
109051
|
+
|
|
109052
|
+
if (flag === 1) {
|
|
109053
|
+
run = this.decodeBits(data, offset, 5);
|
|
109054
|
+
isSmaller = run % 3;
|
|
109055
|
+
run -= isSmaller;
|
|
109056
|
+
isSmaller--;
|
|
109057
|
+
}
|
|
109058
|
+
|
|
109059
|
+
// if ((lfp-ptrstart)+run > size3){
|
|
109060
|
+
// fprintf(stderr, "(xdrfile error) Buffer overrun during decompression.\n");
|
|
109061
|
+
// return 0;
|
|
109062
|
+
// }
|
|
109063
|
+
|
|
109064
|
+
if (run > 0) {
|
|
109065
|
+
thiscoord[0] = thiscoord[1] = thiscoord[2] = 0;
|
|
109066
|
+
|
|
109067
|
+
for (let k = 0; k < run; k += 3) {
|
|
109068
|
+
this.decodeInts(data, offset, smallidx, sizesmall, thiscoord);
|
|
109069
|
+
i++;
|
|
109070
|
+
|
|
109071
|
+
thiscoord[0] += prevcoord[0] - smallnum;
|
|
109072
|
+
thiscoord[1] += prevcoord[1] - smallnum;
|
|
109073
|
+
thiscoord[2] += prevcoord[2] - smallnum;
|
|
109074
|
+
|
|
109075
|
+
if (k === 0) {
|
|
109076
|
+
// interchange first with second atom for
|
|
109077
|
+
// better compression of water molecules
|
|
109078
|
+
let tmpSwap = thiscoord[0];
|
|
109079
|
+
thiscoord[0] = prevcoord[0];
|
|
109080
|
+
prevcoord[0] = tmpSwap;
|
|
109081
|
+
|
|
109082
|
+
tmpSwap = thiscoord[1];
|
|
109083
|
+
thiscoord[1] = prevcoord[1];
|
|
109084
|
+
prevcoord[1] = tmpSwap;
|
|
109085
|
+
|
|
109086
|
+
tmpSwap = thiscoord[2];
|
|
109087
|
+
thiscoord[2] = prevcoord[2];
|
|
109088
|
+
prevcoord[2] = tmpSwap;
|
|
109089
|
+
|
|
109090
|
+
frameCoords.x[lfp] = prevcoord[0] * invPrecision;
|
|
109091
|
+
frameCoords.y[lfp] = prevcoord[1] * invPrecision;
|
|
109092
|
+
frameCoords.z[lfp] = prevcoord[2] * invPrecision;
|
|
109093
|
+
lfp++;
|
|
109094
|
+
} else {
|
|
109095
|
+
prevcoord[0] = thiscoord[0];
|
|
109096
|
+
prevcoord[1] = thiscoord[1];
|
|
109097
|
+
prevcoord[2] = thiscoord[2];
|
|
109098
|
+
}
|
|
109099
|
+
frameCoords.x[lfp] = thiscoord[0] * invPrecision;
|
|
109100
|
+
frameCoords.y[lfp] = thiscoord[1] * invPrecision;
|
|
109101
|
+
frameCoords.z[lfp] = thiscoord[2] * invPrecision;
|
|
109102
|
+
lfp++;
|
|
109103
|
+
}
|
|
109104
|
+
} else {
|
|
109105
|
+
frameCoords.x[lfp] = thiscoord[0] * invPrecision;
|
|
109106
|
+
frameCoords.y[lfp] = thiscoord[1] * invPrecision;
|
|
109107
|
+
frameCoords.z[lfp] = thiscoord[2] * invPrecision;
|
|
109108
|
+
lfp++;
|
|
109109
|
+
}
|
|
109110
|
+
|
|
109111
|
+
smallidx += isSmaller;
|
|
109112
|
+
|
|
109113
|
+
if (isSmaller < 0) {
|
|
109114
|
+
smallnum = smaller;
|
|
109115
|
+
if (smallidx > this.FirstIdx) {
|
|
109116
|
+
smaller = (this.MagicInts[smallidx - 1] / 2) | 0;
|
|
109117
|
+
} else {
|
|
109118
|
+
smaller = 0;
|
|
109119
|
+
}
|
|
109120
|
+
} else if (isSmaller > 0) {
|
|
109121
|
+
smaller = smallnum;
|
|
109122
|
+
smallnum = (this.MagicInts[smallidx] / 2) | 0;
|
|
109123
|
+
}
|
|
109124
|
+
sizesmall[0] = sizesmall[1] = sizesmall[2] = this.MagicInts[smallidx];
|
|
109125
|
+
|
|
109126
|
+
if (sizesmall[0] === 0 || sizesmall[1] === 0 || sizesmall[2] === 0) {
|
|
109127
|
+
undefinedError();
|
|
109128
|
+
}
|
|
109129
|
+
}
|
|
109130
|
+
offset += adz;
|
|
109131
|
+
}
|
|
109132
|
+
|
|
109133
|
+
let factor = 10;
|
|
109134
|
+
for (let c = 0; c < natom; c++) {
|
|
109135
|
+
frameCoords.x[c] *= factor;
|
|
109136
|
+
frameCoords.y[c] *= factor;
|
|
109137
|
+
frameCoords.z[c] *= factor;
|
|
109138
|
+
}
|
|
109139
|
+
|
|
109140
|
+
coordinates.push(frameCoords);
|
|
109141
|
+
|
|
109142
|
+
// if (ctx.shouldUpdate) {
|
|
109143
|
+
// await ctx.update({ current: offset, max: data.length });
|
|
109144
|
+
// }
|
|
109145
|
+
|
|
109146
|
+
// if (offset >= data.length) break;
|
|
109147
|
+
if (offset >= dv.byteLength) break;
|
|
109148
|
+
}
|
|
109149
|
+
|
|
109150
|
+
ic.frames = coordinates.length;
|
|
109151
|
+
|
|
109152
|
+
if (times.length >= 1) {
|
|
109153
|
+
ic.TIMEOFFSET = times[0];
|
|
109154
|
+
}
|
|
109155
|
+
if (times.length >= 2) {
|
|
109156
|
+
ic.DELTA = times[1] - times[0];
|
|
109157
|
+
}
|
|
109158
|
+
|
|
109159
|
+
// frames
|
|
109160
|
+
let structuresOri = me.hashUtilsCls.cloneHash(ic.structures);
|
|
109161
|
+
let residuesOri = me.hashUtilsCls.cloneHash(ic.residues);
|
|
109162
|
+
let chainsOri = me.hashUtilsCls.cloneHash(ic.chains);
|
|
109163
|
+
|
|
109164
|
+
let proteinsOri = me.hashUtilsCls.cloneHash(ic.proteins);
|
|
109165
|
+
let nucleotidesOri = me.hashUtilsCls.cloneHash(ic.nucleotides);
|
|
109166
|
+
let waterOri = me.hashUtilsCls.cloneHash(ic.water);
|
|
109167
|
+
let ionsOri = me.hashUtilsCls.cloneHash(ic.ions);
|
|
109168
|
+
let chemicalsOri = me.hashUtilsCls.cloneHash(ic.chemicals);
|
|
109169
|
+
|
|
109170
|
+
// let serial = natom + 1; // a preloaded PDB structure would have atom serial from 1 to natom
|
|
109171
|
+
let serial = 1;
|
|
109172
|
+
|
|
109173
|
+
for (let i = 0, n = coordinates.length; i < n; ++i) {
|
|
109174
|
+
// skip the first structure since it was read from PDB already
|
|
109175
|
+
// if(i == 0) continue;
|
|
109176
|
+
|
|
109177
|
+
// rewrite the coordinates of the first structure
|
|
109178
|
+
let frame = coordinates[i];
|
|
109179
|
+
|
|
109180
|
+
// let molNum = i + 1; // to avoid the same molNum as the PDB structure
|
|
109181
|
+
let molNum = (i == 0) ? '' : i;
|
|
109182
|
+
for(let j = 0; j < natom; ++j) {
|
|
109183
|
+
let coord = new Vector3$1(frame.x[j], frame.y[j], frame.z[j]);
|
|
109184
|
+
let atom = me.hashUtilsCls.cloneHash(ic.atoms[j + 1]);
|
|
109185
|
+
|
|
109186
|
+
atom.serial = serial;
|
|
109187
|
+
atom.structure = atom.structure + molNum;
|
|
109188
|
+
atom.coord = coord;
|
|
109189
|
+
atom.bonds = [].concat(ic.atoms[j + 1].bonds);
|
|
109190
|
+
|
|
109191
|
+
// update bonds
|
|
109192
|
+
for(let k = 0, kl = atom.bonds.length; k < kl; ++k) {
|
|
109193
|
+
atom.bonds[k] = parseInt(atom.bonds[k]) + natom * i;
|
|
109194
|
+
}
|
|
109195
|
+
|
|
109196
|
+
ic.atoms[serial] = atom;
|
|
109197
|
+
|
|
109198
|
+
// assign extra info
|
|
109199
|
+
ic.dAtoms[serial] = 1;
|
|
109200
|
+
ic.hAtoms[serial] = 1;
|
|
109201
|
+
|
|
109202
|
+
let chainid = atom.structure + '_' + atom.chain;
|
|
109203
|
+
let residid = chainid + '_' + atom.resi;
|
|
109204
|
+
ic.secondaries[residid] = atom.ss;
|
|
109205
|
+
ic.residueId2Name[residid] = me.utilsCls.residueName2Abbr(atom.resn);
|
|
109206
|
+
|
|
109207
|
+
++serial;
|
|
109208
|
+
}
|
|
109209
|
+
|
|
109210
|
+
// update ic.structures, ic.residues and ic.chains
|
|
109211
|
+
for(let structure in structuresOri) {
|
|
109212
|
+
let structure2 = structure + molNum;
|
|
109213
|
+
ic.structures[structure2] = [];
|
|
109214
|
+
|
|
109215
|
+
for(let k = 0, kl = structuresOri[structure].length; k < kl; ++k) {
|
|
109216
|
+
let idArray = structuresOri[structure][k].split('_');
|
|
109217
|
+
ic.structures[structure2].push(structure2 + '_' + idArray[1]);
|
|
109218
|
+
}
|
|
109219
|
+
}
|
|
109220
|
+
|
|
109221
|
+
for(let j in residuesOri) {
|
|
109222
|
+
let idArray = j.split('_');
|
|
109223
|
+
let structure2 = idArray[0] + molNum;
|
|
109224
|
+
let residid2 = structure2 + '_' + idArray[1] + '_' + idArray[2];
|
|
109225
|
+
ic.residues[residid2] = {};
|
|
109226
|
+
|
|
109227
|
+
for(let k in residuesOri[j]) {
|
|
109228
|
+
ic.residues[residid2][parseInt(k) + natom * i] = 1;
|
|
109229
|
+
}
|
|
109230
|
+
}
|
|
109231
|
+
|
|
109232
|
+
for(let j in chainsOri) {
|
|
109233
|
+
let idArray = j.split('_');
|
|
109234
|
+
let structure2 = idArray[0] + molNum;
|
|
109235
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
109236
|
+
|
|
109237
|
+
// ic.chainsSeq[chainid2] = [].concat(ic.chainsSeq[j]);
|
|
109238
|
+
|
|
109239
|
+
ic.chains[chainid2] = {};
|
|
109240
|
+
for(let k in chainsOri[j]) {
|
|
109241
|
+
ic.chains[chainid2][parseInt(k)+ natom * i] = 1;
|
|
109242
|
+
}
|
|
109243
|
+
}
|
|
109244
|
+
|
|
109245
|
+
// update ic.proteins, etc
|
|
109246
|
+
for(let j in proteinsOri) {
|
|
109247
|
+
ic.proteins[parseInt(j) + natom * i] = 1;
|
|
109248
|
+
}
|
|
109249
|
+
for(let j in nucleotidesOri) {
|
|
109250
|
+
ic.nucleotides[parseInt(j) + natom * i] = 1;
|
|
109251
|
+
}
|
|
109252
|
+
for(let j in waterOri) {
|
|
109253
|
+
ic.water[parseInt(j) + natom * i] = 1;
|
|
109254
|
+
}
|
|
109255
|
+
for(let j in ionsOri) {
|
|
109256
|
+
ic.ions[parseInt(j) + natom * i] = 1;
|
|
109257
|
+
}
|
|
109258
|
+
for(let j in chemicalsOri) {
|
|
109259
|
+
ic.chemicals[parseInt(j) + natom * i] = 1;
|
|
109260
|
+
}
|
|
109261
|
+
|
|
109262
|
+
// set ic.ncbi2resid and ic.resid2ncbi
|
|
109263
|
+
for(let chainid in chainsOri) {
|
|
109264
|
+
let idArray = chainid.split('_');
|
|
109265
|
+
let structure2 = idArray[0] + molNum;
|
|
109266
|
+
let chainid2 = structure2 + '_' + idArray[1];
|
|
109267
|
+
|
|
109268
|
+
for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
|
|
109269
|
+
// NCBI residue number starts from 1 and increases continuously
|
|
109270
|
+
let residNCBI = chainid2 + '_' + (j+1).toString();
|
|
109271
|
+
let resid = chainid2 + '_' + ic.chainsSeq[chainid][j].resi;
|
|
109272
|
+
ic.ncbi2resid[residNCBI] = resid;
|
|
109273
|
+
ic.resid2ncbi[resid] = residNCBI;
|
|
109274
|
+
}
|
|
109275
|
+
}
|
|
109276
|
+
}
|
|
109277
|
+
|
|
109278
|
+
// ic.molTitle = header.TITLE;
|
|
109279
|
+
ic.inputid = 'stru';
|
|
109280
|
+
|
|
109281
|
+
// ic.ParserUtilsCls.setMaxD();
|
|
109282
|
+
|
|
109283
|
+
ic.saveFileCls.showTitle();
|
|
109284
|
+
|
|
109285
|
+
return true;
|
|
109286
|
+
}
|
|
109287
|
+
|
|
109288
|
+
sizeOfInt(size) { let ic = this.icn3d; ic.icn3dui;
|
|
109289
|
+
let num = 1;
|
|
109290
|
+
let numOfBits = 0;
|
|
109291
|
+
while (size >= num && numOfBits < 32) {
|
|
109292
|
+
numOfBits++;
|
|
109293
|
+
num <<= 1;
|
|
109294
|
+
}
|
|
109295
|
+
return numOfBits;
|
|
109296
|
+
}
|
|
109297
|
+
|
|
109298
|
+
sizeOfInts(numOfInts, sizes) { let ic = this.icn3d; ic.icn3dui;
|
|
109299
|
+
let numOfBytes = 1;
|
|
109300
|
+
let numOfBits = 0;
|
|
109301
|
+
this._tmpBytes[0] = 1;
|
|
109302
|
+
for (let i = 0; i < numOfInts; i++) {
|
|
109303
|
+
let bytecnt;
|
|
109304
|
+
let tmp = 0;
|
|
109305
|
+
for (bytecnt = 0; bytecnt < numOfBytes; bytecnt++) {
|
|
109306
|
+
tmp += this._tmpBytes[bytecnt] * sizes[i];
|
|
109307
|
+
this._tmpBytes[bytecnt] = tmp & 0xff;
|
|
109308
|
+
tmp >>= 8;
|
|
109309
|
+
}
|
|
109310
|
+
while (tmp !== 0) {
|
|
109311
|
+
this._tmpBytes[bytecnt++] = tmp & 0xff;
|
|
109312
|
+
tmp >>= 8;
|
|
109313
|
+
}
|
|
109314
|
+
numOfBytes = bytecnt;
|
|
109315
|
+
}
|
|
109316
|
+
let num = 1;
|
|
109317
|
+
numOfBytes--;
|
|
109318
|
+
while (this._tmpBytes[numOfBytes] >= num) {
|
|
109319
|
+
numOfBits++;
|
|
109320
|
+
num *= 2;
|
|
109321
|
+
}
|
|
109322
|
+
return numOfBits + numOfBytes * 8;
|
|
109323
|
+
}
|
|
109324
|
+
|
|
109325
|
+
decodeBits(cbuf, offset, numOfBits1) { let ic = this.icn3d; ic.icn3dui;
|
|
109326
|
+
let numOfBits = numOfBits1;
|
|
109327
|
+
const mask = (1 << numOfBits) - 1;
|
|
109328
|
+
let lastBB0 = this.uint32view[1];
|
|
109329
|
+
let lastBB1 = this.uint32view[2];
|
|
109330
|
+
let cnt = this.buf[0];
|
|
109331
|
+
let num = 0;
|
|
109332
|
+
|
|
109333
|
+
while (numOfBits >= 8) {
|
|
109334
|
+
lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt++];
|
|
109335
|
+
num |= (lastBB1 >> lastBB0) << (numOfBits - 8);
|
|
109336
|
+
numOfBits -= 8;
|
|
109337
|
+
}
|
|
109338
|
+
|
|
109339
|
+
if (numOfBits > 0) {
|
|
109340
|
+
if (lastBB0 < numOfBits) {
|
|
109341
|
+
lastBB0 += 8;
|
|
109342
|
+
lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt++];
|
|
109343
|
+
}
|
|
109344
|
+
lastBB0 -= numOfBits;
|
|
109345
|
+
num |= (lastBB1 >> lastBB0) & ((1 << numOfBits) - 1);
|
|
109346
|
+
}
|
|
109347
|
+
|
|
109348
|
+
num &= mask;
|
|
109349
|
+
this.buf[0] = cnt;
|
|
109350
|
+
this.buf[1] = lastBB0;
|
|
109351
|
+
this.buf[2] = lastBB1;
|
|
109352
|
+
|
|
109353
|
+
return num;
|
|
109354
|
+
}
|
|
109355
|
+
|
|
109356
|
+
decodeByte(cbuf, offset) { let ic = this.icn3d; ic.icn3dui;
|
|
109357
|
+
// special version of decodeBits with numOfBits = 8
|
|
109358
|
+
|
|
109359
|
+
// const mask = 0xff; // (1 << 8) - 1;
|
|
109360
|
+
// let lastBB0 = uint32view[1];
|
|
109361
|
+
let lastBB1 = this.uint32view[2];
|
|
109362
|
+
const cnt = this.buf[0];
|
|
109363
|
+
|
|
109364
|
+
lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt];
|
|
109365
|
+
|
|
109366
|
+
this.buf[0] = cnt + 1;
|
|
109367
|
+
// this.buf[1] = lastBB0;
|
|
109368
|
+
this.buf[2] = lastBB1;
|
|
109369
|
+
|
|
109370
|
+
return (lastBB1 >> this.uint32view[1]) & 0xff;
|
|
109371
|
+
}
|
|
109372
|
+
|
|
109373
|
+
decodeInts(cbuf, offset, numOfBits1, sizes, nums) { let ic = this.icn3d; ic.icn3dui;
|
|
109374
|
+
let numOfBits = numOfBits1;
|
|
109375
|
+
let numOfBytes = 0;
|
|
109376
|
+
|
|
109377
|
+
this.intBytes[0] = 0;
|
|
109378
|
+
this.intBytes[1] = 0;
|
|
109379
|
+
this.intBytes[2] = 0;
|
|
109380
|
+
this.intBytes[3] = 0;
|
|
109381
|
+
|
|
109382
|
+
while (numOfBits > 8) {
|
|
109383
|
+
// this is inversed??? why??? because of the endiannness???
|
|
109384
|
+
this.intBytes[numOfBytes++] = this.decodeByte(cbuf, offset);
|
|
109385
|
+
numOfBits -= 8;
|
|
109386
|
+
}
|
|
109387
|
+
|
|
109388
|
+
if (numOfBits > 0) {
|
|
109389
|
+
this.intBytes[numOfBytes++] = this.decodeBits(cbuf, offset, numOfBits);
|
|
109390
|
+
}
|
|
109391
|
+
|
|
109392
|
+
for (let i = 2; i > 0; i--) {
|
|
109393
|
+
let num = 0;
|
|
109394
|
+
const s = sizes[i];
|
|
109395
|
+
for (let j = numOfBytes - 1; j >= 0; j--) {
|
|
109396
|
+
num = (num << 8) | this.intBytes[j];
|
|
109397
|
+
const t = (num / s) | 0;
|
|
109398
|
+
this.intBytes[j] = t;
|
|
109399
|
+
num = num - t * s;
|
|
109400
|
+
}
|
|
109401
|
+
nums[i] = num;
|
|
109402
|
+
}
|
|
109403
|
+
nums[0] = this.intBytes[0] | (this.intBytes[1] << 8) | (this.intBytes[2] << 16) | (this.intBytes[3] << 24);
|
|
109404
|
+
}
|
|
109405
|
+
}
|
|
109406
|
+
|
|
108121
109407
|
/**
|
|
108122
109408
|
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
108123
109409
|
*/
|
|
@@ -114012,7 +115298,15 @@ class LoadPDB {
|
|
|
114012
115298
|
prevCarbonArray.push(atom);
|
|
114013
115299
|
}
|
|
114014
115300
|
|
|
114015
|
-
if(
|
|
115301
|
+
if(atom.resn === 'HOH' || atom.resn === 'WAT' || atom.resn === 'SOL') {
|
|
115302
|
+
ic.water[atom.serial] = 1;
|
|
115303
|
+
atom.color = me.parasCls.atomColors[atom.elem];
|
|
115304
|
+
}
|
|
115305
|
+
else if($.inArray(atom.resn.trim(), me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
|
|
115306
|
+
ic.ions[atom.serial] = 1;
|
|
115307
|
+
atom.color = me.parasCls.atomColors[atom.elem];
|
|
115308
|
+
}
|
|
115309
|
+
else if(!atom.het) {
|
|
114016
115310
|
if($.inArray(atom.resn, me.parasCls.nucleotidesArray) !== -1) {
|
|
114017
115311
|
ic.nucleotides[atom.serial] = 1;
|
|
114018
115312
|
//if (atom.name === 'P') {
|
|
@@ -114037,19 +115331,7 @@ class LoadPDB {
|
|
|
114037
115331
|
}
|
|
114038
115332
|
}
|
|
114039
115333
|
else if(atom.het) {
|
|
114040
|
-
|
|
114041
|
-
ic.water[atom.serial] = 1;
|
|
114042
|
-
}
|
|
114043
|
-
//else if(bOpm && atom.resn === 'DUM') {
|
|
114044
|
-
// ic.mem[atom.serial] = 1;
|
|
114045
|
-
//}
|
|
114046
|
-
else if($.inArray(atom.resn, me.parasCls.ionsArray) !== -1 || atom.elem.trim() === atom.resn.trim()) {
|
|
114047
|
-
ic.ions[atom.serial] = 1;
|
|
114048
|
-
}
|
|
114049
|
-
else {
|
|
114050
|
-
ic.chemicals[atom.serial] = 1;
|
|
114051
|
-
}
|
|
114052
|
-
|
|
115334
|
+
ic.chemicals[atom.serial] = 1;
|
|
114053
115335
|
atom.color = me.parasCls.atomColors[atom.elem];
|
|
114054
115336
|
}
|
|
114055
115337
|
|
|
@@ -116847,6 +118129,18 @@ class ApplyCommand {
|
|
|
116847
118129
|
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));
|
|
116848
118130
|
ic.drawCls.draw();
|
|
116849
118131
|
}
|
|
118132
|
+
else if(command.indexOf('add plane') == 0) {
|
|
118133
|
+
let paraArray = command.split(' | ');
|
|
118134
|
+
let p1Array = paraArray[1].split(' ');
|
|
118135
|
+
let p2Array = paraArray[2].split(' ');
|
|
118136
|
+
let p3Array = paraArray[3].split(' ');
|
|
118137
|
+
let color = paraArray[4].substr(paraArray[4].lastIndexOf(' ') + 1);
|
|
118138
|
+
let thickness = (paraArray.length > 5) ? paraArray[5].substr(paraArray[5].lastIndexOf(' ') + 1) : 2;
|
|
118139
|
+
let opacity = (paraArray.length > 6) ? paraArray[6].substr(paraArray[6].lastIndexOf(' ') + 1) : 0.3;
|
|
118140
|
+
|
|
118141
|
+
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));
|
|
118142
|
+
ic.drawCls.draw();
|
|
118143
|
+
}
|
|
116850
118144
|
else if(command.indexOf('add sphere') == 0) {
|
|
116851
118145
|
this.addShape(commandOri, 'sphere');
|
|
116852
118146
|
ic.shapeCmdHash[commandOri] = 1;
|
|
@@ -116865,6 +118159,10 @@ class ApplyCommand {
|
|
|
116865
118159
|
ic.lines['cylinder'] = []; // reset
|
|
116866
118160
|
//ic.drawCls.draw();
|
|
116867
118161
|
}
|
|
118162
|
+
else if(command.indexOf('clear plane among sets') == 0) {
|
|
118163
|
+
ic.planes = []; // reset
|
|
118164
|
+
//ic.drawCls.draw();
|
|
118165
|
+
}
|
|
116868
118166
|
else if(commandOri.indexOf('add label') == 0) {
|
|
116869
118167
|
let paraArray = commandOri.split(' | ');
|
|
116870
118168
|
let text = paraArray[0].substr(('add label').length + 1);
|
|
@@ -125618,6 +126916,21 @@ class Analysis {
|
|
|
125618
126916
|
//ic.drawCls.draw();
|
|
125619
126917
|
}
|
|
125620
126918
|
|
|
126919
|
+
//Add a plane among the positions (x1, y1, z1), (x2, y2, z2) and (x3, y3, z3) with the input "color".
|
|
126920
|
+
addPlane(x1, y1, z1, x2, y2, z2, x3, y3, z3, color, thickness, opacity) {var ic = this.icn3d; ic.icn3dui;
|
|
126921
|
+
let plane = {}; // Each plane contains 'position1', 'position2', 'position3', 'color', and 'thickness'
|
|
126922
|
+
plane.position1 = new Vector3$1(x1, y1, z1);
|
|
126923
|
+
plane.position2 = new Vector3$1(x2, y2, z2);
|
|
126924
|
+
plane.position3 = new Vector3$1(x3, y3, z3);
|
|
126925
|
+
plane.color = color;
|
|
126926
|
+
plane.thickness = thickness;
|
|
126927
|
+
plane.opacity = opacity;
|
|
126928
|
+
if(ic.planes === undefined) ic.planes = [];
|
|
126929
|
+
ic.planes.push(plane);
|
|
126930
|
+
|
|
126931
|
+
ic.hlObjectsCls.removeHlObjects();
|
|
126932
|
+
}
|
|
126933
|
+
|
|
125621
126934
|
addLineFromPicking(type) {var ic = this.icn3d, me = ic.icn3dui;
|
|
125622
126935
|
let color = $("#" + ic.pre + type + "color" ).val();
|
|
125623
126936
|
(ic.pAtom.coord.x + ic.pAtom2.coord.x) / 2;
|
|
@@ -129404,12 +130717,13 @@ class SaveFile {
|
|
|
129404
130717
|
let structureArray = Object.keys(me.utilsCls.getStructures(ic.dAtoms));
|
|
129405
130718
|
|
|
129406
130719
|
if(structureArray.length > 1) {
|
|
129407
|
-
title = '
|
|
129408
|
-
for(let i = 0, il = structureArray.length; i < il; ++i) {
|
|
130720
|
+
title = structureArray.length + ' structures: ';
|
|
130721
|
+
for(let i = 0, il = structureArray.length; i < il && i < 5; ++i) {
|
|
129409
130722
|
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];
|
|
129410
130723
|
title += '<a href="' + url + '" style="color:' + titlelinkColor + '" target="_blank">' + structureArray[i] + '</a>';
|
|
129411
130724
|
if(i < il - 1) title += ', ';
|
|
129412
130725
|
}
|
|
130726
|
+
if(structureArray.length > 5) title += '...';
|
|
129413
130727
|
$("#" + ic.pre + "title").html(title);
|
|
129414
130728
|
}
|
|
129415
130729
|
else if(structureArray.length == 1) {
|
|
@@ -131200,12 +132514,11 @@ class Control {
|
|
|
131200
132514
|
ic.transformCls.setRotation(axis, angle);
|
|
131201
132515
|
}
|
|
131202
132516
|
|
|
131203
|
-
else if(e.keyCode === 65 ) { // A, alternate
|
|
132517
|
+
else if(e.keyCode === 65 ) { // A, alternate forward
|
|
131204
132518
|
if(Object.keys(ic.structures).length > 1) {
|
|
131205
132519
|
await ic.alternateCls.alternateWrapper();
|
|
131206
132520
|
}
|
|
131207
132521
|
}
|
|
131208
|
-
|
|
131209
132522
|
}
|
|
131210
132523
|
});
|
|
131211
132524
|
|
|
@@ -132655,6 +133968,8 @@ class iCn3D {
|
|
|
132655
133968
|
this.pdbParserCls = new PdbParser(this);
|
|
132656
133969
|
this.sdfParserCls = new SdfParser(this);
|
|
132657
133970
|
this.xyzParserCls = new XyzParser(this);
|
|
133971
|
+
this.dcdParserCls = new DcdParser(this);
|
|
133972
|
+
this.xtcParserCls = new XtcParser(this);
|
|
132658
133973
|
this.msaParserCls = new MsaParser(this);
|
|
132659
133974
|
this.realignParserCls = new RealignParser(this);
|
|
132660
133975
|
this.densityCifParserCls = new DensityCifParser(this);
|
|
@@ -132912,7 +134227,7 @@ class iCn3DUI {
|
|
|
132912
134227
|
//even when multiple iCn3D viewers are shown together.
|
|
132913
134228
|
this.pre = this.cfg.divid + "_";
|
|
132914
134229
|
|
|
132915
|
-
this.REVISION = '3.
|
|
134230
|
+
this.REVISION = '3.47.0';
|
|
132916
134231
|
|
|
132917
134232
|
// In nodejs, iCn3D defines "window = {navigator: {}}", and added window = {navigator: {}, "__THREE__":"177"}
|
|
132918
134233
|
this.bNode = (Object.keys(window).length < 3) ? true : false;
|
|
@@ -133709,6 +135024,7 @@ exports.ConvertTypeCls = ConvertTypeCls;
|
|
|
133709
135024
|
exports.Curve = Curve;
|
|
133710
135025
|
exports.CurveStripArrow = CurveStripArrow;
|
|
133711
135026
|
exports.Cylinder = Cylinder;
|
|
135027
|
+
exports.DcdParser = DcdParser;
|
|
133712
135028
|
exports.DefinedSets = DefinedSets;
|
|
133713
135029
|
exports.Delphi = Delphi;
|
|
133714
135030
|
exports.DensityCifParser = DensityCifParser;
|
|
@@ -133794,6 +135110,7 @@ exports.UtilsCls = UtilsCls;
|
|
|
133794
135110
|
exports.VRButton = VRButton;
|
|
133795
135111
|
exports.Vastplus = Vastplus;
|
|
133796
135112
|
exports.ViewInterPairs = ViewInterPairs;
|
|
135113
|
+
exports.XtcParser = XtcParser;
|
|
133797
135114
|
exports.XyzParser = XyzParser;
|
|
133798
135115
|
exports.iCn3D = iCn3D;
|
|
133799
135116
|
exports.iCn3DUI = iCn3DUI;
|