icn3d 3.28.12 → 3.29.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.
Files changed (4) hide show
  1. package/icn3d.js +1764 -339
  2. package/icn3d.min.js +7 -5
  3. package/icn3d.module.js +1764 -339
  4. package/package.json +1 -1
package/icn3d.js CHANGED
@@ -5957,9 +5957,13 @@ class ClickMenu {
5957
5957
  me.myEventCls.onIds("#" + me.pre + "mn1_selection", "click", function(e) { me.icn3d; //e.preventDefault();
5958
5958
  me.htmlCls.dialogCls.openDlg('dl_selection', 'Please input the selection file');
5959
5959
  });
5960
+
5961
+ me.myEventCls.onIds("#" + me.pre + "mn1_collection", "click", function (e) { me.icn3d; //e.preventDefault();
5962
+ me.htmlCls.dialogCls.openDlg('dl_collection', 'Please input the collection file');
5963
+ });
5960
5964
 
5961
5965
  me.myEventCls.onIds("#" + me.pre + "mn1_dsn6", "click", function(e) { me.icn3d; //e.preventDefault();
5962
- me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the DSN6 file to display electron density map');
5966
+ me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the map file to display electron density map');
5963
5967
  });
5964
5968
 
5965
5969
 
@@ -5986,7 +5990,7 @@ class ClickMenu {
5986
5990
 
5987
5991
 
5988
5992
  me.myEventCls.onIds("#" + me.pre + "mn1_dsn6url", "click", function(e) { me.icn3d; //e.preventDefault();
5989
- me.htmlCls.dialogCls.openDlg('dl_dsn6url', 'Please input the DSN6 file to display electron density map');
5993
+ me.htmlCls.dialogCls.openDlg('dl_dsn6url', 'Please input the map file to display electron density map');
5990
5994
  });
5991
5995
 
5992
5996
  me.myEventCls.onIds("#" + me.pre + "mn1_exportState", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
@@ -7291,6 +7295,8 @@ class ClickMenu {
7291
7295
  let sigma2fofc = parseFloat($("#" + me.pre + "sigma2fofc" ).val());
7292
7296
  let type = '2fofc';
7293
7297
  await ic.dsn6ParserCls.dsn6Parser(ic.inputid, type, sigma2fofc);
7298
+ //ic.densityCifParserCls.densityCifParser(ic.inputid, type, sigma2fofc);
7299
+
7294
7300
  //ic.setOptionCls.setOption('map', '2fofc');
7295
7301
  thisClass.setLogCmd('set map 2fofc sigma ' + sigma2fofc, true);
7296
7302
  });
@@ -8544,15 +8550,18 @@ class SetMenu {
8544
8550
  html += this.getLink('mn1_state', 'State/Script File', undefined, 2);
8545
8551
  html += this.getLink('mn1_fixedversion', 'Share Link in Archived Ver. ' + me.htmlCls.wifiStr, undefined, 2);
8546
8552
  html += this.getLink('mn1_selection', 'Selection File', undefined, 2);
8553
+ html += this.getLink("mn1_collection", "Collection File", undefined, 2);
8547
8554
 
8548
8555
  html += this.getMenuSep();
8549
8556
 
8550
- html += this.getMenuText('mn1_dsn6wrap', 'Electron Density(DSN6)', undefined, undefined, 2);
8557
+ html += this.getMenuText('mn1_dsn6wrap', 'Electron Density', undefined, undefined, 2);
8551
8558
  html += "<ul>";
8552
8559
  html += this.getLink('mn1_dsn6', 'Local File', undefined, 3);
8553
8560
  html += this.getLink('mn1_dsn6url', 'URL(CORS) ' + me.htmlCls.wifiStr, undefined, 3);
8554
8561
  html += "</ul>";
8555
8562
 
8563
+ html += "<li><br/></li>";
8564
+
8556
8565
  html += "</ul>";
8557
8566
  html += "</li>";
8558
8567
 
@@ -8658,14 +8667,14 @@ class SetMenu {
8658
8667
  }
8659
8668
 
8660
8669
  //!!!
8661
- /*
8670
+
8662
8671
  html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
8663
8672
  html += "<ul>";
8664
8673
  html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
8665
8674
  html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
8666
8675
  html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
8667
8676
  html += "</ul>";
8668
- */
8677
+
8669
8678
 
8670
8679
  html += "<li><br/></li>";
8671
8680
 
@@ -9506,8 +9515,8 @@ class SetMenu {
9506
9515
  //}
9507
9516
 
9508
9517
  //!!!
9509
- //html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
9510
- //html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
9518
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
9519
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
9511
9520
  }
9512
9521
  else {
9513
9522
  //if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
@@ -9638,7 +9647,7 @@ class SetMenu {
9638
9647
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
9639
9648
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
9640
9649
  //!!!
9641
- //html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
9650
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
9642
9651
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
9643
9652
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
9644
9653
  }
@@ -9730,11 +9739,11 @@ class SetMenu {
9730
9739
 
9731
9740
  html += "<ul>";
9732
9741
  //!!!
9733
- /*
9742
+
9734
9743
  html += this.getLink('mn6_igrefYes', 'Show Ig Ref. Number', undefined, 2);
9735
9744
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
9736
9745
  html += this.getLink('mn6_igrefNo', 'Hide Ig Ref. Number', undefined, 2);
9737
- */
9746
+
9738
9747
  html += this.getMenuSep();
9739
9748
 
9740
9749
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
@@ -10967,6 +10976,19 @@ class SetDialog {
10967
10976
  html += me.htmlCls.buttonStr + "reload_selectionfile' style='margin-top: 6px;'>Load</button>";
10968
10977
  html += "</div>";
10969
10978
 
10979
+ html += me.htmlCls.divStr + "dl_collection' class='" + dialogClass + "'>";
10980
+ html += "Collection file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "collectionfile'><br/>";
10981
+ html += me.htmlCls.buttonStr + "reload_collectionfile' style='margin-top: 6px;'>Load</button>";
10982
+ html += "</div>";
10983
+
10984
+ html += me.htmlCls.divStr + "dl_selectCollections' class='" + dialogClass + "'>";
10985
+ html += me.htmlCls.divStr + "dl_collectionsMenu'>";
10986
+ html += "<b>Structures:</b> <br/>";
10987
+ html += "<select id='" + me.pre + "collections_menu' multiple size='6' style='min-width:130px;'>";
10988
+ html += "</select>";
10989
+ html += "</div>";
10990
+ html += "</div>";
10991
+
10970
10992
  html += me.htmlCls.divStr + "dl_menuloadpref' class='" + dialogClass + "'>";
10971
10993
  html += this.addNotebookTitle('dl_menuloadpref', 'Load a preference file');
10972
10994
  html += "Preference file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "menupreffile'><br/>";
@@ -10974,23 +10996,19 @@ class SetDialog {
10974
10996
  html += "</div>";
10975
10997
 
10976
10998
  html += me.htmlCls.divStr + "dl_dsn6' class='" + dialogClass + "'>";
10977
- html += this.addNotebookTitle('dl_dsn6', 'Load a DSN6 file');
10978
- html += "<b>Note</b>: Always load a PDB file before loading DSN6 files. <br/><br/><br/>";
10979
-
10980
- html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at: <select id='" + me.pre + "dsn6sigma2fofc'>";
10999
+ html += this.addNotebookTitle('dl_dsn6', 'Load a map file');
11000
+ html += "<b>Note</b>: Always load a PDB file before loading map files. If you don't specify the threshold <br>below, a default one will be chosen.<br/><br/><br/>";
10981
11001
 
10982
- let optArray1 = ['0', '0.5', '1', '1.5', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
10983
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
11002
+ html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at default threshold or at: "
11003
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigma2fofc' value='' size=8> &sigma;</span><br/>";
11004
+ //html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6file2fofc'> " + me.htmlCls.buttonStr + "reload_dsn6file2fofc' style='margin: 6px 20px 0 0;'>Load DSN6</button><br><br><br/>";
11005
+ html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6file2fofc'> " + me.htmlCls.buttonStr + "reload_dsn6file2fofc' style='margin: 6px 20px 0 0;'>Load DSN6</button>" + me.htmlCls.buttonStr + "reload_ccp4file2fofc' style='margin: 6px 20px 0 0;'>Load CCP4</button>" + me.htmlCls.buttonStr + "reload_mtzfile2fofc' style='margin-top: 6px;'>Load MTZ</button><br><br><br/>";
10984
11006
 
10985
- html += "</select> &sigma;</span><br/>";
10986
- html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6file2fofc'> " + me.htmlCls.buttonStr + "reload_dsn6file2fofc' style='margin-top: 6px;'>Load</button><br><br><br/>";
11007
+ html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at default threshold or at: "
11008
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmafofc' value='' size=8> &sigma;</span><br/>";
10987
11009
 
10988
- html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at: <select id='" + me.pre + "dsn6sigmafofc'>";
10989
-
10990
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 5);
10991
-
10992
- html += "</select> &sigma;</span><br/>";
10993
- html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6filefofc'> " + me.htmlCls.buttonStr + "reload_dsn6filefofc' style='margin-top: 6px;'>Load</button><br><br><br>";
11010
+ //html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6filefofc'> " + me.htmlCls.buttonStr + "reload_dsn6filefofc' style='margin: 6px 20px 0 0;'>Load DSN6</button><br><br><br>";
11011
+ html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6filefofc'> " + me.htmlCls.buttonStr + "reload_dsn6filefofc' style='margin: 6px 20px 0 0;'>Load DSN6</button>" + me.htmlCls.buttonStr + "reload_ccp4filefofc' style='margin: 6px 20px 0 0;'>Load CCP4</button>" + me.htmlCls.buttonStr + "reload_mtzfilefofc' style='margin-top: 6px;'>Load MTZ</button><br><br><br>";
10994
11012
 
10995
11013
  html += me.htmlCls.buttonStr + "elecmapNo4'>Remove Map</button><br>";
10996
11014
 
@@ -10998,21 +11016,17 @@ class SetDialog {
10998
11016
 
10999
11017
  html += me.htmlCls.divStr + "dl_dsn6url' class='" + dialogClass + "'>";
11000
11018
  html += this.addNotebookTitle('dl_dsn6url', 'Load a selection file via a URL');
11001
- html += "<b>Note</b>: Always load a PDB file before loading DSN6 files. <br/><br/><br/>";
11019
+ html += "<b>Note</b>: Always load a PDB file before loading map files. If you don't specify the threshold <br>below, a default one will be chosen.<br/><br/><br/>";
11002
11020
 
11003
- html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at: <select id='" + me.pre + "dsn6sigmaurl2fofc'>";
11021
+ html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at default threshold or at: "
11022
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmaurl2fofc' value='' size=8> &sigma;</span><br/>";
11004
11023
 
11005
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
11024
+ html += "URL in the same host: " + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6fileurl2fofc' size=20>" + me.htmlCls.space3 + me.htmlCls.buttonStr + "reload_dsn6fileurl2fofc' style='margin: 6px 20px 0 0;'>Load DSN6</button>" + me.htmlCls.buttonStr + "reload_ccp4fileurl2fofc' style='margin: 6px 20px 0 0;'>Load CCP4</button>" + me.htmlCls.buttonStr + "reload_mtzfileurl2fofc' style='margin-top: 6px;'>Load MTZ</button><br><br><br/>";
11006
11025
 
11007
- html += "</select> &sigma;</span><br/>";
11008
- html += "URL in the same host: " + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6fileurl2fofc' size=20>" + me.htmlCls.space3 + me.htmlCls.buttonStr + "reload_dsn6fileurl2fofc' style='margin-top: 6px;'>Load</button><br><br><br/>";
11026
+ html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at default threshold or at: "
11027
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmaurlfofc' value='' size=8> &sigma;</span><br/>";
11009
11028
 
11010
- html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at: <select id='" + me.pre + "dsn6sigmaurlfofc'>";
11011
-
11012
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 5);
11013
-
11014
- html += "</select> &sigma;</span><br/>";
11015
- html += "URL in the same host: " + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6fileurlfofc' size=20>" + me.htmlCls.space3 + me.htmlCls.buttonStr + "reload_dsn6fileurlfofc' style='margin-top: 6px;'>Load</button><br><br><br/>";
11029
+ html += "URL in the same host: " + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6fileurlfofc' size=20>" + me.htmlCls.space3 + me.htmlCls.buttonStr + "reload_dsn6fileurlfofc' style='margin: 6px 20px 0 0;'>Load DSN6</button>" + me.htmlCls.buttonStr + "reload_ccp4fileurlfofc' style='margin: 6px 20px 0 0;'>Load CCP4</button>" + me.htmlCls.buttonStr + "reload_mtzfileurlfofc' style='margin-top: 6px;'>Load MTZ</button><br><br><br>";
11016
11030
 
11017
11031
  html += me.htmlCls.buttonStr + "elecmapNo5'>Remove Map</button><br>";
11018
11032
 
@@ -11352,6 +11366,7 @@ class SetDialog {
11352
11366
  html += this.addNotebookTitle('dl_elecmap2fofc', 'Electron Density 2F0-Fc Map');
11353
11367
  html += "<span style='white-space:nowrap;font-weight:bold;'>Contour at: <select id='" + me.pre + "sigma2fofc'>";
11354
11368
 
11369
+ let optArray1 = ['0', '0.5', '1', '1.5', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
11355
11370
  html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
11356
11371
 
11357
11372
  html += "</select> &sigma;</span> <span style='white-space:nowrap; margin-left:30px;'>" + me.htmlCls.buttonStr + "applymap2fofc'>Display</button></span> <span style='white-space:nowrap; margin-left:30px;'>" + me.htmlCls.buttonStr + "elecmapNo2'>Remove Map</button></span>";
@@ -11998,7 +12013,7 @@ class Events {
11998
12013
  }
11999
12014
  }
12000
12015
 
12001
- readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
12016
+ async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
12002
12017
  let file = files[index];
12003
12018
  let commandName = (bAppend) ? 'append': 'load';
12004
12019
 
@@ -12035,7 +12050,20 @@ class Events {
12035
12050
  await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
12036
12051
  }
12037
12052
  else {
12038
- thisClass.readFile(bAppend, files, index + 1, dataStrAll);
12053
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
12054
+ }
12055
+
12056
+ if(bAppend) {
12057
+ if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
12058
+ //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
12059
+
12060
+ ic.bResetAnno = true;
12061
+
12062
+ if(ic.bAnnoShown) {
12063
+ await ic.showAnnoCls.showAnnotations();
12064
+
12065
+ ic.annotationCls.resetAnnoTabAll();
12066
+ }
12039
12067
  }
12040
12068
  };
12041
12069
 
@@ -12070,13 +12098,7 @@ class Events {
12070
12098
 
12071
12099
  ic.dataStrAll = '';
12072
12100
 
12073
- this.readFile(bAppend, files, 0, '');
12074
-
12075
- if(bAppend) {
12076
- if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
12077
- //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
12078
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
12079
- }
12101
+ await this.readFile(bAppend, files, 0, '');
12080
12102
  }
12081
12103
  }
12082
12104
 
@@ -12160,7 +12182,10 @@ class Events {
12160
12182
 
12161
12183
  if(bStructures) {
12162
12184
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
12163
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
12185
+ if(ic.bAnnoShown) {
12186
+ await ic.showAnnoCls.showAnnotations();
12187
+ ic.annotationCls.resetAnnoTabAll();
12188
+ }
12164
12189
  }
12165
12190
  }
12166
12191
  }
@@ -13168,17 +13193,78 @@ class Events {
13168
13193
  }
13169
13194
  });
13170
13195
 
13196
+ me.myEventCls.onIds("#" + me.pre + "reload_collectionfile", "click", function (e) { let ic = me.icn3d;
13197
+ e.preventDefault();
13198
+ let file = $("#" + me.pre + "collectionfile")[0].files[0];
13199
+ if (!file) {
13200
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
13201
+ } else {
13202
+ if (!me.cfg.notebook) dialog.dialog("close");
13203
+ if (!me.cfg.notebook) {
13204
+ $(".ui-dialog-content").dialog("close");
13205
+ } else {
13206
+ ic.resizeCanvasCls.closeDialogs();
13207
+ }
13208
+ me.htmlCls.setHtmlCls.fileSupport();
13209
+ let reader = new FileReader();
13210
+ reader.onload = async function (e) {
13211
+ let dataStr = JSON.parse(e.target.result);
13212
+ let collection = [dataStr["structures"].map(({ id }) => id), dataStr["structures"].map(({ title }) => title)];
13213
+ let collectionHtml = ic.selectCollectionsCls.setAtomMenu(collection[0], collection[1]);
13214
+ await ic.chainalignParserCls.downloadMmdbAf(collection[0][0]);
13215
+
13216
+ ic.opts["color"] = "structure";
13217
+ ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
13218
+
13219
+ $("#" + ic.pre + "collections_menu").html(collectionHtml);
13220
+ ic.selectCollectionsCls.clickStructure();
13221
+
13222
+ $("#" + ic.pre + "collections_menu").trigger("change");
13223
+
13224
+ me.htmlCls.clickMenuCls.setLogCmd(
13225
+ "load collection file " +
13226
+ $("#" + me.pre + "collectionfile").val(),
13227
+ false
13228
+ );
13229
+ };
13230
+ reader.readAsText(file);
13231
+ me.htmlCls.dialogCls.openDlg("dl_selectCollections", "Select Collections");
13232
+ }
13233
+ });
13234
+
13171
13235
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6file2fofc", "click", function(e) { let ic = me.icn3d;
13172
13236
  e.preventDefault();
13173
- if(!me.cfg.notebook) dialog.dialog( "close" );
13237
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13174
13238
  ic.dsn6ParserCls.loadDsn6File('2fofc');
13175
13239
  });
13176
13240
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6filefofc", "click", function(e) { let ic = me.icn3d;
13177
13241
  e.preventDefault();
13178
- if(!me.cfg.notebook) dialog.dialog( "close" );
13242
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13179
13243
  ic.dsn6ParserCls.loadDsn6File('fofc');
13180
13244
  });
13181
13245
 
13246
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4file2fofc", "click", function(e) { let ic = me.icn3d;
13247
+ e.preventDefault();
13248
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13249
+ ic.ccp4ParserCls.loadCcp4File('2fofc');
13250
+ });
13251
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4filefofc", "click", function(e) { let ic = me.icn3d;
13252
+ e.preventDefault();
13253
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13254
+ ic.ccp4ParserCls.loadCcp4File('fofc');
13255
+ });
13256
+
13257
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfile2fofc", "click", function(e) { let ic = me.icn3d;
13258
+ e.preventDefault();
13259
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13260
+ ic.mtzParserCls.loadMtzFile('2fofc');
13261
+ });
13262
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfilefofc", "click", function(e) { let ic = me.icn3d;
13263
+ e.preventDefault();
13264
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13265
+ ic.mtzParserCls.loadMtzFile('fofc');
13266
+ });
13267
+
13182
13268
  me.myEventCls.onIds("#" + me.pre + "reload_delphifile", "click", async function(e) { let ic = me.icn3d;
13183
13269
  e.preventDefault();
13184
13270
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -13268,15 +13354,37 @@ class Events {
13268
13354
 
13269
13355
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6fileurl2fofc", "click", function(e) { let ic = me.icn3d;
13270
13356
  e.preventDefault();
13271
- if(!me.cfg.notebook) dialog.dialog( "close" );
13357
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13272
13358
  ic.dsn6ParserCls.loadDsn6FileUrl('2fofc');
13273
13359
  });
13274
13360
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6fileurlfofc", "click", function(e) { let ic = me.icn3d;
13275
13361
  e.preventDefault();
13276
- if(!me.cfg.notebook) dialog.dialog( "close" );
13362
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13277
13363
  ic.dsn6ParserCls.loadDsn6FileUrl('fofc');
13278
13364
  });
13279
13365
 
13366
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4fileurl2fofc", "click", function(e) { let ic = me.icn3d;
13367
+ e.preventDefault();
13368
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13369
+ ic.ccp4ParserCls.loadCcp4FileUrl('2fofc');
13370
+ });
13371
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4fileurlfofc", "click", function(e) { let ic = me.icn3d;
13372
+ e.preventDefault();
13373
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13374
+ ic.ccp4ParserCls.loadCcp4FileUrl('fofc');
13375
+ });
13376
+
13377
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfileurl2fofc", "click", function(e) { let ic = me.icn3d;
13378
+ e.preventDefault();
13379
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13380
+ ic.mtzParserCls.loadMtzFileUrl('2fofc');
13381
+ });
13382
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfileurlfofc", "click", function(e) { let ic = me.icn3d;
13383
+ e.preventDefault();
13384
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
13385
+ ic.mtzParserCls.loadMtzFileUrl('fofc');
13386
+ });
13387
+
13280
13388
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile", "click", async function(e) { me.icn3d;
13281
13389
  e.preventDefault();
13282
13390
 
@@ -14664,7 +14772,7 @@ class AlignSeq {
14664
14772
  // for(let i in ic.alnChains) {
14665
14773
  for (let m = 0, ml = alignChainArray.length; m < ml; ++m) {
14666
14774
  let i = alignChainArray[m];
14667
-
14775
+
14668
14776
  if (index == 0) firstChainid = i;
14669
14777
 
14670
14778
  if (bOnechain && index > 0) {
@@ -28439,8 +28547,8 @@ class ElectronMap {
28439
28547
  this.pLength = 0;
28440
28548
  this.cutRadius = 0;
28441
28549
  this.vpBits = null; // uint8 array of bitmasks
28442
- this.vpDistance = null; // floatarray of _squared_ distances
28443
- this.vpAtomID = null; // intarray
28550
+ this.vpGridTrans = null; // array of translated number of grids
28551
+ this.vpAtomID = null; // uint8 array
28444
28552
  this.vertnumber = 0;
28445
28553
  this.facenumber = 0;
28446
28554
  this.pminx = 0;
@@ -28490,12 +28598,27 @@ ElectronMap.prototype.getFacesAndVertices = function(allatoms, atomlist) {
28490
28598
  atomsToShow[atomlist[i]] = 1;
28491
28599
  let vertices = this.verts;
28492
28600
 
28601
+ let vertTrans = {};
28493
28602
  for(i = 0, il = vertices.length; i < il; i++) {
28494
28603
  let r;
28495
28604
  if(this.type == 'phi') {
28496
28605
  r = new THREE.Vector3(vertices[i].x, vertices[i].y, vertices[i].z).multiplyScalar(1.0/this.header.scale).applyMatrix4(this.matrix);
28497
28606
  }
28498
28607
  else {
28608
+ // ccp4 has no translation vector. Only translated vertices are used.
28609
+ if(this.header.ccp4) {
28610
+ let index = vertices[i].index;
28611
+ let finalIndex;
28612
+ if(this.vpGridTrans[index]) {
28613
+ finalIndex = index;
28614
+
28615
+ vertices[i].x += this.vpGridTrans[finalIndex][0] * this.header.xExtent * this.scaleFactor;
28616
+ vertices[i].y += this.vpGridTrans[finalIndex][1] * this.header.xExtent * this.scaleFactor;
28617
+ vertices[i].z += this.vpGridTrans[finalIndex][2] * this.header.xExtent * this.scaleFactor;
28618
+
28619
+ vertTrans[finalIndex] = 1;
28620
+ }
28621
+ }
28499
28622
  r = new THREE.Vector3(vertices[i].x, vertices[i].y, vertices[i].z).applyMatrix4(this.matrix);
28500
28623
  }
28501
28624
  // vertices[i].x = r.x / this.scaleFactor - this.ptranx;
@@ -28514,13 +28637,22 @@ ElectronMap.prototype.getFacesAndVertices = function(allatoms, atomlist) {
28514
28637
  let fa = this.faces[i], fb = this.faces[i+1], fc = this.faces[i+2];
28515
28638
 
28516
28639
  if(fa !== fb && fb !== fc && fa !== fc){
28517
- finalfaces.push({"a":fa, "b":fb, "c":fc});
28640
+ if(this.header.ccp4) {
28641
+ // only transfered vertices will be used
28642
+ if(vertTrans.hasOwnProperty(vertices[fa].index) && vertTrans.hasOwnProperty(vertices[fb].index)
28643
+ && vertTrans.hasOwnProperty(vertices[fc].index)) {
28644
+ finalfaces.push({"a":fa, "b":fb, "c":fc});
28645
+ }
28646
+ }
28647
+ else {
28648
+ finalfaces.push({"a":fa, "b":fb, "c":fc});
28649
+ }
28518
28650
  }
28519
28651
  }
28520
28652
 
28521
28653
  //try to help the garbage collector
28522
28654
  this.vpBits = null; // uint8 array of bitmasks
28523
- this.vpDistance = null; // floatarray
28655
+ this.vpGridTrans = null; // uint8 array
28524
28656
  this.vpAtomID = null; // intarray
28525
28657
 
28526
28658
  return {
@@ -28579,6 +28711,8 @@ ElectronMap.prototype.initparm = function(inHeader, inData, inMatrix, inIsovalue
28579
28711
  this.cutRadius = this.probeRadius * this.scaleFactor;
28580
28712
 
28581
28713
  this.vpBits = new Uint8Array(this.pLength * this.pWidth * this.pHeight);
28714
+ if(this.header.ccp4) this.vpGridTrans = new Array(this.pLength * this.pWidth * this.pHeight);
28715
+
28582
28716
  this.vpAtomID = new Uint8Array(this.pLength * this.pWidth * this.pHeight);
28583
28717
  };
28584
28718
 
@@ -28604,7 +28738,6 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
28604
28738
  let i, j, k, il, jl, kl;
28605
28739
  for(i = 0, il = this.vpBits.length; i < il; i++) {
28606
28740
  this.vpBits[i] = 0;
28607
- //this.vpDistance[i] = -1.0;
28608
28741
  this.vpAtomID[i] = 0;
28609
28742
  }
28610
28743
 
@@ -28766,6 +28899,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
28766
28899
  }
28767
28900
  }
28768
28901
  else {
28902
+ // let index2ori = {};
28769
28903
  for(let serial in atomlist) {
28770
28904
  let atom = atoms[atomlist[serial]];
28771
28905
 
@@ -28796,6 +28930,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
28796
28930
 
28797
28931
  for(i = 0, il = indexArray.length; i < il; ++i) {
28798
28932
  let index = indexArray[i];
28933
+
28799
28934
  if(this.type == '2fofc') {
28800
28935
  this.vpBits[index] =(this.dataArray[index] >= this.isovalue) ? 1 : 0;
28801
28936
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
@@ -28809,6 +28944,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
28809
28944
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
28810
28945
  }
28811
28946
  }
28947
+
28812
28948
  }
28813
28949
  }
28814
28950
 
@@ -29032,7 +29168,18 @@ class Surface {
29032
29168
  cfg.isovalue = ic.mapData.sigma2;
29033
29169
  cfg.type = '2fofc';
29034
29170
 
29035
- ps = this.SetupMap(cfg);
29171
+ //ccp4
29172
+ cfg.ccp4 = ic.mapData.ccp4;
29173
+ cfg.grid = ic.mapData.grid2;
29174
+ cfg.unit_cell = ic.mapData.unit_cell2;
29175
+
29176
+ if(cfg.header || cfg.ccp4) ps = this.SetupMap(cfg);
29177
+ else return;
29178
+
29179
+ if(cfg.ccp4) {
29180
+ ic.mapData = {};
29181
+ return;
29182
+ }
29036
29183
  }
29037
29184
  else if(type == 12) { // fofc
29038
29185
  cfg.header = ic.mapData.header;
@@ -29041,7 +29188,18 @@ class Surface {
29041
29188
  cfg.isovalue = ic.mapData.sigma;
29042
29189
  cfg.type = 'fofc';
29043
29190
 
29044
- ps = this.SetupMap(cfg);
29191
+ //ccp4
29192
+ cfg.ccp4 = ic.mapData.ccp4;
29193
+ cfg.grid = ic.mapData.grid;
29194
+ cfg.unit_cell = ic.mapData.unit_cell;
29195
+
29196
+ if(cfg.header || cfg.ccp4) ps = this.SetupMap(cfg);
29197
+ else return;
29198
+
29199
+ if(cfg.ccp4) {
29200
+ ic.mapData = {};
29201
+ return;
29202
+ }
29045
29203
  }
29046
29204
  else if(type == 13) { // em
29047
29205
  cfg.maxdist = 3; // EM map has no unit cell. It could include more gird space.
@@ -29529,29 +29687,60 @@ class Surface {
29529
29687
  }
29530
29688
 
29531
29689
  SetupMap(data) { let ic = this.icn3d; ic.icn3dui;
29532
- let ps = new ElectronMap(ic);
29533
-
29534
- ps.initparm(data.header, data.data, data.matrix, data.isovalue, data.center, data.maxdist,
29535
- data.pmin, data.pmax, data.water, data.type, data.rmsd_supr, data.loadPhiFrom, data.icn3d);
29690
+ if(data.ccp4) {
29691
+ let radius = 10;
29692
+ let center = (ic.center) ? [ic.center.x, ic.center.y, ic.center.z] : [0,0,0];
29693
+
29694
+ let typeDetail;
29695
+ if(data.type == '2fofc') {
29696
+ typeDetail = '2fofc';
29697
+ let result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
29698
+ let iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
29699
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
29700
+
29701
+ result = null;
29702
+ iso = null;
29703
+ }
29704
+ else if(data.type == 'fofc') {
29705
+ typeDetail = 'fofc_neg';
29706
+ let result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
29707
+ let iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
29708
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
29709
+
29710
+ typeDetail = 'fofc_pos';
29711
+ result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
29712
+ iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
29713
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
29536
29714
 
29537
- ps.fillvoxels(data.allatoms, data.extendedAtoms);
29715
+ result = null;
29716
+ iso = null;
29717
+ }
29718
+ }
29719
+ else {
29720
+ let ps = new ElectronMap(ic);
29721
+
29722
+ ps.initparm(data.header, data.data, data.matrix, data.isovalue, data.center, data.maxdist,
29723
+ data.pmin, data.pmax, data.water, data.type, data.rmsd_supr, data.loadPhiFrom, data.icn3d);
29538
29724
 
29539
- if(!data.header.bSurface) ps.buildboundary();
29725
+ ps.fillvoxels(data.allatoms, data.extendedAtoms);
29540
29726
 
29541
- if(!data.header.bSurface) ps.marchingcube();
29542
-
29543
- ps.vpBits = null; // uint8 array of bitmasks
29544
- //ps.vpDistance = null; // floatarray of _squared_ distances
29545
- ps.vpAtomID = null; // intarray
29727
+ if(!data.header.bSurface) ps.buildboundary();
29546
29728
 
29547
- let result;
29729
+ if(!data.header.bSurface) ps.marchingcube();
29730
+
29731
+ ps.vpBits = null; // uint8 array of bitmasks
29732
+ //ps.vpDistance = null; // floatarray of _squared_ distances
29733
+ ps.vpAtomID = null; // intarray
29548
29734
 
29549
- if(!data.header.bSurface) result = ps.getFacesAndVertices(data.allatoms, data.atomsToShow);
29735
+ let result;
29550
29736
 
29551
- ps.faces = null;
29552
- ps.verts = null;
29737
+ if(!data.header.bSurface) result = ps.getFacesAndVertices(data.allatoms, data.atomsToShow);
29553
29738
 
29554
- return result;
29739
+ ps.faces = null;
29740
+ ps.verts = null;
29741
+
29742
+ return result;
29743
+ }
29555
29744
  }
29556
29745
  }
29557
29746
 
@@ -35038,7 +35227,7 @@ class SetColor {
35038
35227
 
35039
35228
  for(let resid in residueHash) {
35040
35229
  if(!ic.resid2refnum[resid]) {
35041
- color = me.parasCls.thr('#FFFFFF');
35230
+ color = me.parasCls.thr('#00FFFF'); //('#FFFFFF');
35042
35231
  }
35043
35232
  else {
35044
35233
  let refnumLabel = ic.resid2refnum[resid];
@@ -35073,7 +35262,7 @@ class SetColor {
35073
35262
  let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
35074
35263
  for(let resid in residueHash) {
35075
35264
  if(!ic.resid2refnum[resid]) {
35076
- color = me.parasCls.thr('#FFFFFF');
35265
+ color = me.parasCls.thr('#00FFFF'); //('#FFFFFF');
35077
35266
  }
35078
35267
  else {
35079
35268
  let refnumLabel = ic.resid2refnum[resid];
@@ -36043,15 +36232,13 @@ class SetOption {
36043
36232
  const name2color = {
36044
36233
  //"A- Strand": "FF00FF",
36045
36234
  "A Strand": "9400D3", //"663399",
36046
- //"A+ Strand": "9400D3", //"663399",
36047
- "A' Strand": "9400D3", //"663399",
36048
36235
  "B Strand": "ba55d3",
36049
36236
  "C Strand": "0000FF",
36050
36237
  "C' Strand": "6495ED",
36051
36238
  "C'' Strand": "006400",
36052
36239
  "D Strand": "00FF00",
36053
- "E Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36054
- "F Strand": "FFA500",
36240
+ "E Strand": "FFD700", //"FFFF00", //"F0E68C",
36241
+ "F Strand": "FF8C00",
36055
36242
  "G Strand": "FF0000",
36056
36243
  //"G+ Strand": "8B0000",
36057
36244
  "Loop": "CCCCCC"
@@ -36078,15 +36265,15 @@ class SetOption {
36078
36265
  "<b>Protodomain 1</b>": "",
36079
36266
  "A Strand": "0000FF",
36080
36267
  "B Strand": "006400",
36081
- "C Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36082
- "C' Strand": "FFA500",
36268
+ "C Strand": "FFD700", //"FFFF00", //"F0E68C",
36269
+ "C' Strand": "FF8C00",
36083
36270
  "<br><b>Linker</b>": "",
36084
36271
  "C'' Strand": "FF0000",
36085
36272
  "<br><b>Protodomain 2</b>": "",
36086
36273
  "D Strand": "0000FF",
36087
36274
  "E Strand": "006400",
36088
- "F Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36089
- "G Strand": "FFA500",
36275
+ "F Strand": "FFD700", //"FFFF00", //"F0E68C",
36276
+ "G Strand": "FF8C00",
36090
36277
  "": "",
36091
36278
  "Loop": "CCCCCC"
36092
36279
  };
@@ -37288,14 +37475,14 @@ class AnnoDomain {
37288
37475
  let pdbid = pdbArray[index];
37289
37476
  //let url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=" + pdbid;
37290
37477
 
37291
- if(index == 0 && ic.mmdb_data !== undefined) {
37478
+ if(!ic.bResetAnno && index == 0 && ic.mmdb_data !== undefined) {
37292
37479
  for(let chnid in ic.protein_chainid) {
37293
37480
  if(chnid.indexOf(pdbid) !== -1) {
37294
37481
  this.showDomainWithData(chnid, ic.mmdb_data);
37295
37482
  }
37296
37483
  }
37297
37484
  }
37298
- else if(ic.mmdb_dataArray[index] !== undefined) {
37485
+ else if(!ic.bResetAnno && ic.mmdb_dataArray[index] !== undefined) {
37299
37486
  for(let chnid in ic.protein_chainid) {
37300
37487
  if(chnid.indexOf(pdbid) !== -1) {
37301
37488
  this.showDomainWithData(chnid, ic.mmdb_dataArray[index]);
@@ -37370,6 +37557,10 @@ class AnnoDomain {
37370
37557
  let domainArray, proteinname;
37371
37558
  let pos = chnid.indexOf('_');
37372
37559
  let chain = chnid.substr(pos + 1);
37560
+ // MMDB symmetry chain has the form of 'A1'
37561
+ if(chain.length > 1 && chain.substr(chain.length - 1) == '1') {
37562
+ chain = chain.substr(0, chain.length - 1);
37563
+ }
37373
37564
 
37374
37565
  if(bCalcDirect) {
37375
37566
  proteinname = chnid;
@@ -38375,7 +38566,11 @@ class Domain3d {
38375
38566
  //this.dcut = 8; // threshold for C-alpha interactions
38376
38567
 
38377
38568
  // It seemed the threshold 7 angstrom works better
38378
- this.dcut = 7; // threshold for C-alpha interactions
38569
+ //this.dcut = 7; // threshold for C-alpha interactions
38570
+ this.dcut = 8; // threshold for C-alpha interactions
38571
+
38572
+ // added by Jiyao
38573
+ this.min_contacts = 5; //3; // minimum number of contacts to be considered as neighbors
38379
38574
 
38380
38575
  this.MAX_SSE = 512;
38381
38576
 
@@ -38409,9 +38604,6 @@ class Domain3d {
38409
38604
  this.c_delta = 3; // cut set parameter
38410
38605
  this.nc_fact = 0.0; // size factor for internal contacts
38411
38606
 
38412
- // added by Jiyao
38413
- this.min_contacts = 3; // minimum number of contacts to be considered as neighbors
38414
-
38415
38607
  //let this.elements[2*this.MAX_SSE]; // sets of this.elements to be split
38416
38608
  this.elements = [];
38417
38609
  this.elements.length = 2*this.MAX_SSE;
@@ -41989,6 +42181,10 @@ class ShowAnno {
41989
42181
  chainLetter = chainLetter.substr(0, chainLetter.indexOf('_'));
41990
42182
  chainidBase = chainArray[i].substr(0, chainArray[i].indexOf('_')) + '_' + chainLetter;
41991
42183
  }
42184
+ else if(chainLetter.length > 1 && chainLetter.substr(chainLetter.length - 1) == '1') { // NCBI modified chainid, e.g., A1
42185
+ chainLetter = chainLetter.substr(0, chainLetter.length - 1);
42186
+ chainidBase = chainArray[i].substr(0, chainArray[i].indexOf('_')) + '_' + chainLetter;
42187
+ }
41992
42188
  else {
41993
42189
  chainidBase = chainArray[i];
41994
42190
  }
@@ -43189,7 +43385,7 @@ class ShowSeq {
43189
43385
  html += '</div>';
43190
43386
  html3 += '</div></div>';
43191
43387
  }
43192
-
43388
+
43193
43389
  if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
43194
43390
  let result = this.showAllRefNum(giSeq, chnid);
43195
43391
 
@@ -43258,9 +43454,13 @@ class ShowSeq {
43258
43454
 
43259
43455
  if(!ic.chainid2refpdbname[chnid]) return {html: html, html3: html3};
43260
43456
 
43261
- let chainList = ic.refnumCls.getTemplateList(chnid);
43457
+ let result = ic.refnumCls.getTemplateList(chnid);
43458
+ let refpdbnameList = result.refpdbnameList;
43459
+ let scoreList = result.scoreList;
43460
+ let seqidList = result.seqidList;
43461
+ let nresAlignList = result.nresAlignList;
43262
43462
 
43263
- let refStruTitle = (chainList) ? "based on " + chainList : "";
43463
+ let refStruTitle = (refpdbnameList) ? "based on " + refpdbnameList + ". The TM-score(s) is(are) " + scoreList + ". The sequence identitie(s) is(are) " + seqidList + ". The number of aligned residue(s) is(are) " + nresAlignList + "." : "";
43264
43464
 
43265
43465
  let htmlTmp = '<div class="icn3d-dl_sequence">';
43266
43466
  htmlTmp += '<div class="icn3d-residueLine" style="white-space:nowrap;">';
@@ -43316,7 +43516,8 @@ class ShowSeq {
43316
43516
 
43317
43517
  // auto-generate ref numbers for loops
43318
43518
  let bLoop = false, currStrand = '', prevStrand = '';
43319
- let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c;
43519
+ let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c, refnum2c;
43520
+ let bExtendedStrand = false, bSecThird9 = false;
43320
43521
 
43321
43522
  // sometimes one chain may have several Ig domains,set an index for each IgDomain
43322
43523
  let index = 1, bStart = false;
@@ -43342,8 +43543,8 @@ class ShowSeq {
43342
43543
 
43343
43544
  refnumLabel = ic.resid2refnum[residueid];
43344
43545
 
43345
- let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : ' ';
43346
- if(!bStart && refnumLabel && (firstChar == ' ' || firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
43546
+ let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : '';
43547
+ if(!bStart && refnumLabel && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
43347
43548
  bStart = true;
43348
43549
  resCnt = 1; // the first oen is included
43349
43550
  }
@@ -43360,14 +43561,21 @@ class ShowSeq {
43360
43561
  refnumStr = refnumStr_ori;
43361
43562
  refnum = parseInt(refnumStr);
43362
43563
  refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
43564
+ refnum2c = (refnum - parseInt(refnum/100) * 100).toString();
43565
+
43566
+ // for extended strands, since A is 1550 and A+ is 1650, then the AA+ loop will be 1591, 1592, ... 1610, 1611, etc
43567
+ bSecThird9 = refnum3c.substr(0,1) == '9' || refnum2c.substr(0,1) == '9' || refnum2c.substr(0,1) == '0' || refnum2c.substr(0,1) == '1';
43568
+ if(bSecThird9) ic.residIgLoop[residueid] = 1;
43569
+
43363
43570
  strandPostfix = refnumStr.replace(refnum.toString(), '');
43364
43571
 
43365
43572
  postfix = strandPostfix + '_' + index;
43366
43573
 
43367
- let firstTwo = parseInt(refnum.toString().substr(0, 2)); // A- strand
43574
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
43575
+ bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
43368
43576
 
43369
43577
  if(currStrand && currStrand != ' ') {
43370
- if(refnum3c.substr(0,1) != '9' || firstTwo == 10) {
43578
+ if(!bSecThird9 || (bExtendedStrand && !bSecThird9)) {
43371
43579
  let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
43372
43580
 
43373
43581
  if(currStrand != prevStrand) { // reset currCnt
@@ -43394,7 +43602,7 @@ class ShowSeq {
43394
43602
  resCntAtAnchor = 0;
43395
43603
  }
43396
43604
 
43397
- if(firstTwo == 10) {
43605
+ if(bExtendedStrand) {
43398
43606
  strandArray[strandCnt].anchorRefnum = 0;
43399
43607
  }
43400
43608
 
@@ -43420,7 +43628,7 @@ class ShowSeq {
43420
43628
  resCntAtAnchor = 0;
43421
43629
  }
43422
43630
 
43423
- if(firstTwo == 10) {
43631
+ if(bExtendedStrand) {
43424
43632
  strandArray[strandCnt - 1].anchorRefnum = 0;
43425
43633
  }
43426
43634
 
@@ -43476,7 +43684,7 @@ class ShowSeq {
43476
43684
  currStrand = refnumLabel.replace(new RegExp(refnumStr,'g'), '');
43477
43685
 
43478
43686
  let firstChar = refnumLabel.substr(0,1);
43479
- if(!bStart && (firstChar == ' ' || firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
43687
+ if(!bStart && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
43480
43688
  bStart = true;
43481
43689
  bBeforeAstrand = true;
43482
43690
  loopCnt = 0;
@@ -43749,6 +43957,11 @@ class ShowSeq {
43749
43957
 
43750
43958
  getRefnumHtml(residueid, refnumStr, refnumStr_ori, refnumLabel, currStrand, bLoop, bHidelabel) { let ic = this.icn3d, me = ic.icn3dui;
43751
43959
  let refnum = parseInt(refnumStr).toString();
43960
+
43961
+ let refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
43962
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
43963
+ let bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
43964
+
43752
43965
  let color = this.getRefnumColor(currStrand, true);
43753
43966
  let colorStr = (!bLoop) ? 'style="color:' + color + '; text-decoration: underline overline;"' : 'style="color:' + color + '"';
43754
43967
 
@@ -43758,13 +43971,13 @@ class ShowSeq {
43758
43971
 
43759
43972
  let html = '';
43760
43973
 
43761
- if(refnumLabel && (lastTwo == 50 || refnum == 1094) && !bLoop) {
43974
+ if(refnumLabel && lastTwo == 50 && !bExtendedStrand && !bLoop) {
43762
43975
  // highlight the anchor residues
43763
43976
  ic.hAtomsRefnum = me.hashUtilsCls.unionHash(ic.hAtomsRefnum, ic.residues[residueid]);
43764
43977
 
43765
43978
  html += '<span ' + colorStr + ' title="' + refnumLabel + '"><b>' + refnumLabel.substr(0, 1) + '</b>' + refnumLabel.substr(1) + '</span>';
43766
43979
  }
43767
- else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && refnum != 1096 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
43980
+ else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
43768
43981
  // e.g., 2152a
43769
43982
  lastTwoStr = isNaN(refnumStr) ? lastTwoStr + refnumStr.substr(refnumStr.length - 1, 1) : lastTwoStr;
43770
43983
  html += '<span ' + colorStr + ' title="' + refnumLabel + '">' + lastTwoStr + '</span>';
@@ -43777,23 +43990,9 @@ class ShowSeq {
43777
43990
  }
43778
43991
 
43779
43992
  getRefnumColor(currStrand, bText) { let ic = this.icn3d, me = ic.icn3dui;
43780
- if(currStrand == "A-") {
43781
- return '#9400D3'; //'#663399';
43782
- }
43783
- else if(currStrand == "A") {
43784
- return '#9400D3'; //'#663399';
43785
- }
43786
- //else if(currStrand == "A*") {
43787
- else if(currStrand == "A+") {
43788
- return '#9400D3'; //'#663399';
43789
- }
43790
- else if(currStrand == "A'") {
43791
- return '#9400D3'; //'#663399';
43792
- }
43793
- else if(currStrand == "B") {
43794
- return '#ba55d3';
43795
- }
43796
- else if(currStrand == "C") {
43993
+ let strand = (currStrand) ? currStrand.substr(0,1) : '';
43994
+
43995
+ if(currStrand == "C") {
43797
43996
  return '#0000FF';
43798
43997
  }
43799
43998
  else if(currStrand == "C'") {
@@ -43802,39 +44001,44 @@ class ShowSeq {
43802
44001
  else if(currStrand == "C''") {
43803
44002
  return '#006400';
43804
44003
  }
43805
- else if(currStrand == "D") {
44004
+
44005
+ else if(strand == "A") {
44006
+ return '#9400D3'; //'#663399';
44007
+ }
44008
+ else if(strand == "B") {
44009
+ return '#ba55d3';
44010
+ }
44011
+ else if(strand == "D") {
43806
44012
  return '#00FF00';
43807
44013
  }
43808
- else if(currStrand == "E") {
43809
- //return (bText) ? "#F7DC6F" : "#FFFF00";
43810
- return "#F7DC6F";
44014
+ else if(strand == "E") {
44015
+ return "#FFD700";
43811
44016
  }
43812
- else if(currStrand == "F") {
43813
- return '#FFA500';
44017
+ else if(strand == "F") {
44018
+ return '#FF8C00';
43814
44019
  }
43815
- else if(currStrand == "G") {
44020
+ else if(strand == "G") {
43816
44021
  return '#FF0000';
43817
44022
  }
43818
- else if(currStrand == "G+") {
43819
- return '#8B0000';
43820
- }
43821
44023
  else {
43822
44024
  return me.htmlCls.GREYB;
43823
44025
  }
43824
44026
  }
43825
44027
 
43826
44028
  getProtodomainColor(currStrand) { let ic = this.icn3d, me = ic.icn3dui;
43827
- if((currStrand && currStrand.substr(0,1) == "A") || currStrand == "D") {
44029
+ let strand = (currStrand) ? currStrand.substr(0,1) : '';
44030
+
44031
+ if(strand == "A" || strand == "D") {
43828
44032
  return '#0000FF';
43829
44033
  }
43830
- else if(currStrand == "B" || currStrand == "E") {
44034
+ else if(strand == "B" || strand == "E") {
43831
44035
  return '#006400';
43832
44036
  }
43833
- else if(currStrand == "C" || currStrand == "F") {
43834
- return "#F7DC6F"; //"#FFFF00"; //'#F0E68C';
44037
+ else if(currStrand == "C" || strand == "F") {
44038
+ return "#FFD700"; //"#FFFF00"; //'#F0E68C';
43835
44039
  }
43836
- else if(currStrand == "C'" || (currStrand && currStrand.substr(0, 1) == "G")) {
43837
- return '#FFA500';
44040
+ else if(currStrand == "C'" || strand == "G") {
44041
+ return '#FF8C00';
43838
44042
  }
43839
44043
  else if(currStrand == "C''") { //linker
43840
44044
  return '#FF0000';
@@ -44537,8 +44741,8 @@ class HlUpdate {
44537
44741
  updateHlObjects(bForceHighlight) { let ic = this.icn3d; ic.icn3dui;
44538
44742
  ic.hlObjectsCls.removeHlObjects();
44539
44743
 
44540
- if((ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length < Object.keys(ic.atoms).length) || bForceHighlight) {
44541
- ic.hlObjectsCls.addHlObjects();
44744
+ if((ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length < Object.keys(ic.dAtoms).length) || bForceHighlight) {
44745
+ if(ic.bShowHighlight === undefined || ic.bShowHighlight) ic.hlObjectsCls.addHlObjects();
44542
44746
  ic.definedSetsCls.setMode('selection');
44543
44747
  }
44544
44748
  }
@@ -45618,8 +45822,11 @@ class LineGraph {
45618
45822
 
45619
45823
  // try {
45620
45824
  if(!template) {
45621
- let allPromise = Promise.allSettled(pdbAjaxArray);
45622
- ic.pdbDataArray = await allPromise;
45825
+ //let allPromise = Promise.allSettled(pdbAjaxArray);
45826
+ //ic.pdbDataArray = await allPromise;
45827
+
45828
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
45829
+
45623
45830
  await thisClass.parseRefPdbData(ic.pdbDataArray, template);
45624
45831
  }
45625
45832
  else {
@@ -45730,6 +45937,7 @@ class LineGraph {
45730
45937
  }
45731
45938
 
45732
45939
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
45940
+ if(!ic.domainid2score) ic.domainid2score = {};
45733
45941
 
45734
45942
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
45735
45943
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
@@ -45741,7 +45949,7 @@ class LineGraph {
45741
45949
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtomsArray[k]);
45742
45950
  let resiSum = atomFirst.resi + ':' + atomLast.resi;
45743
45951
  //let domainid = chainid + '-' + k + '_' + Object.keys(domainAtomsArray[k]).length;
45744
- let domainid = chainid + '-' + k + '_' + resiSum;
45952
+ let domainid = chainid + ',' + k + '_' + resiSum;
45745
45953
  ic.domainid2pdb[domainid] = pdb_target;
45746
45954
 
45747
45955
  if(!template) {
@@ -45771,30 +45979,14 @@ class LineGraph {
45771
45979
  }
45772
45980
  }
45773
45981
 
45774
- try {
45982
+ //try {
45775
45983
  if(!template) {
45776
45984
  let dataArray2 = [];
45777
45985
 
45778
45986
  // let allPromise = Promise.allSettled(ajaxArray);
45779
45987
  // dataArray2 = await allPromise;
45780
45988
 
45781
- //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
45782
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
45783
-
45784
- for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
45785
- let currAjaxArray = [];
45786
- if(i == il - 1) { // last one
45787
- currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
45788
- }
45789
- else {
45790
- currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
45791
- }
45792
-
45793
- let currPromise = Promise.allSettled(currAjaxArray);
45794
- let currDataArray = await currPromise;
45795
-
45796
- dataArray2 = dataArray2.concat(currDataArray);
45797
- }
45989
+ dataArray2 = await this.promiseWithFixedJobs(ajaxArray);
45798
45990
 
45799
45991
  let bRound1 = true;
45800
45992
  await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1);
@@ -45814,12 +46006,14 @@ class LineGraph {
45814
46006
  let pdbAjaxArray = [];
45815
46007
  pdbAjaxArray.push(pdbAjax);
45816
46008
 
45817
- let allPromise2 = Promise.allSettled(pdbAjaxArray);
45818
- ic.pdbDataArray = await allPromise2;
46009
+ //let allPromise2 = Promise.allSettled(pdbAjaxArray);
46010
+ //ic.pdbDataArray = await allPromise2;
46011
+
46012
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
45819
46013
 
45820
46014
  for(let domainid in ic.domainid2refpdbname) {
45821
- let refpdbname = ic.domainid2refpdbname[domainid];
45822
- let chainid = domainid.substr(0, domainid.indexOf('-'));
46015
+ ic.domainid2refpdbname[domainid];
46016
+ domainid.substr(0, domainid.indexOf(','));
45823
46017
 
45824
46018
  let pdb_target = ic.domainid2pdb[domainid];
45825
46019
  for(let index = 0, indexl = ic.pdbDataArray.length; index < indexl; ++index) {
@@ -45839,11 +46033,14 @@ class LineGraph {
45839
46033
  }
45840
46034
 
45841
46035
  let dataArray3 = [];
45842
- let allPromise = Promise.allSettled(ajaxArray);
45843
- dataArray3 = await allPromise;
46036
+ //let allPromise = Promise.allSettled(ajaxArray);
46037
+ //dataArray3 = await allPromise;
46038
+
46039
+ dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
45844
46040
 
45845
46041
  await thisClass.parseAlignData(dataArray3, domainidpairArray3);
45846
46042
  }
46043
+ /*
45847
46044
  }
45848
46045
  catch(err) {
45849
46046
  let mess = "Some of " + ajaxArray.length + " TM-align alignments failed. Please select a chain or a subset to assing reference numbers to avoid overloading the server...";
@@ -45855,17 +46052,23 @@ class LineGraph {
45855
46052
  }
45856
46053
  //console.log("Error in aligning with TM-align...");
45857
46054
  return;
45858
- }
46055
+ }
46056
+ */
45859
46057
  }
45860
46058
 
45861
46059
  getTemplateList(chainid) { let ic = this.icn3d; ic.icn3dui;
45862
- let domainid2refpdbname = {};
46060
+ let domainid2refpdbname = {}, domainid2score = {};
45863
46061
 
45864
46062
  for(let i = 0, il = ic.chainid2refpdbname[chainid].length; i < il; ++i) {
45865
46063
  let refpdbname_domainid = ic.chainid2refpdbname[chainid][i].split('|');
45866
46064
  domainid2refpdbname[refpdbname_domainid[1]] = refpdbname_domainid[0];
45867
46065
  }
45868
46066
 
46067
+ for(let i = 0, il = ic.chainid2score[chainid].length; i < il; ++i) {
46068
+ let score_domainid = ic.chainid2score[chainid][i].split('|');
46069
+ domainid2score[score_domainid[1]] = score_domainid[0];
46070
+ }
46071
+
45869
46072
  let domainidArray = Object.keys(domainid2refpdbname);
45870
46073
  domainidArray.sort(function(id1, id2) {
45871
46074
  let resi1 = parseInt(id1.substr(id1.lastIndexOf('_') + 1));
@@ -45873,13 +46076,28 @@ class LineGraph {
45873
46076
  return resi1 - resi2;
45874
46077
  });
45875
46078
 
45876
- let chainList = '';
46079
+ let refpdbnameList = '';
45877
46080
  for(let i = 0, il = domainidArray.length; i < il; ++i) {
45878
- chainList += domainid2refpdbname[domainidArray[i]];
45879
- if(i < il - 1) chainList += ", ";
46081
+ refpdbnameList += domainid2refpdbname[domainidArray[i]];
46082
+ if(i < il - 1) refpdbnameList += ", ";
45880
46083
  }
45881
46084
 
45882
- return chainList;
46085
+ let scoreList = '', seqidList = '', nresAlignList = '';
46086
+ for(let i = 0, il = domainidArray.length; i < il; ++i) {
46087
+ let itemArray = domainid2score[domainidArray[i]].split('_');
46088
+
46089
+ scoreList += itemArray[0];
46090
+ seqidList += itemArray[1];
46091
+ nresAlignList += itemArray[2];
46092
+
46093
+ if(i < il - 1) {
46094
+ scoreList += ", ";
46095
+ seqidList += ", ";
46096
+ nresAlignList += ", ";
46097
+ }
46098
+ }
46099
+
46100
+ return {'refpdbnameList': refpdbnameList, 'scoreList': scoreList, 'seqidList': seqidList, 'nresAlignList': nresAlignList};
45883
46101
  }
45884
46102
 
45885
46103
  async parseAlignData(dataArray, domainidpairArray, bRound1) { let ic = this.icn3d, me = ic.icn3dui;
@@ -45888,33 +46106,35 @@ class LineGraph {
45888
46106
  let tmscoreThreshold = 0.4; // 0.4; //0.5;
45889
46107
 
45890
46108
  // find the best alignment for each chain
45891
- let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
46109
+ let domainid2segs = {}, chainid2segs = {};
45892
46110
 
45893
46111
  if(!ic.chainid2refpdbname) ic.chainid2refpdbname = {};
46112
+ if(!ic.chainid2score) ic.chainid2score = {};
45894
46113
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
46114
+ if(!ic.domainid2score) ic.domainid2score = {};
45895
46115
  if(!ic.domainid2ig2kabat) ic.domainid2ig2kabat = {};
45896
46116
  if(!ic.domainid2ig2imgt) ic.domainid2ig2imgt = {};
45897
46117
 
45898
- // ic.chainid2refpdbname = {};
45899
- // ic.domainid2refpdbname = {};
45900
- // ic.domainid2ig2kabat = {};
45901
- // ic.domainid2ig2imgt = {};
45902
-
45903
46118
  let minResidues = 20;
45904
46119
 
45905
46120
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
45906
46121
  //let queryData = (me.bNode) ? dataArray[i] : dataArray[i].value; //[0];
45907
46122
  let queryData = dataArray[i].value; //[0];
45908
46123
 
45909
- if(!queryData) {
46124
+ if(!queryData || queryData.length == 0) {
45910
46125
  if(!me.bNode) console.log("The alignment data for " + domainidpairArray[i] + " is unavailable...");
45911
46126
  continue;
45912
46127
  }
45913
-
45914
- if(queryData.length == 0) continue;
45915
46128
 
46129
+ //let domainid_index = domainidpairArray[i].split(',');
46130
+ //let domainid = domainid_index[0];
46131
+ let domainid = domainidpairArray[i].substr(0, domainidpairArray[i].indexOf('|'));
46132
+ let refpdbname = domainidpairArray[i].substr(domainidpairArray[i].indexOf('|') + 1);
46133
+ //let chainid = domainid.split('-')[0];
46134
+
45916
46135
  if(!bRound1) {
45917
46136
  if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < minResidues) {
46137
+ if(!me.bNode) console.log("domainid " + domainid + " and refpdbname " + refpdbname + " were skipped due to a TM-score less than " + tmscoreThreshold);
45918
46138
  continue;
45919
46139
  }
45920
46140
  }
@@ -45926,12 +46146,6 @@ class LineGraph {
45926
46146
  continue;
45927
46147
  }
45928
46148
  }
45929
-
45930
- //let domainid_index = domainidpairArray[i].split(',');
45931
- //let domainid = domainid_index[0];
45932
- let domainid = domainidpairArray[i].substr(0, domainidpairArray[i].indexOf('|'));
45933
- let refpdbname = domainidpairArray[i].substr(domainidpairArray[i].indexOf('|') + 1);
45934
- //let chainid = domainid.split('-')[0];
45935
46149
 
45936
46150
  if(!bRound1) {
45937
46151
  if(!me.bNode) console.log("refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
@@ -45948,16 +46162,16 @@ class LineGraph {
45948
46162
  for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
45949
46163
  let seg = queryData[0].segs[i];
45950
46164
 
45951
- if(seg.q_start.indexOf('2150') != -1 || seg.q_start.indexOf('2250') != -1) {
46165
+ if(seg.q_start.indexOf('2550') != -1) {
45952
46166
  bBstrand = true;
45953
46167
  }
45954
- else if(seg.q_start.indexOf('3150') != -1 || seg.q_start.indexOf('3250') != -1) {
46168
+ else if(seg.q_start.indexOf('3550') != -1) {
45955
46169
  bCstrand = true;
45956
46170
  }
45957
- else if(seg.q_start.indexOf('7150') != -1 || seg.q_start.indexOf('7250') != -1) {
46171
+ else if(seg.q_start.indexOf('7550') != -1) {
45958
46172
  bEstrand = true;
45959
46173
  }
45960
- else if(seg.q_start.indexOf('8150') != -1 || seg.q_start.indexOf('8250') != -1) {
46174
+ else if(seg.q_start.indexOf('8550') != -1) {
45961
46175
  bFstrand = true;
45962
46176
  }
45963
46177
 
@@ -45968,35 +46182,25 @@ class LineGraph {
45968
46182
  //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
45969
46183
  if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
45970
46184
  if(!me.bNode) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
45971
- if(ic.domainid2refpdbname[domainid] == refpdbname) delete ic.domainid2refpdbname[domainid];
46185
+ if(ic.domainid2refpdbname[domainid] == refpdbname) {
46186
+ delete ic.domainid2refpdbname[domainid];
46187
+ delete ic.domainid2score[domainid];
46188
+ }
45972
46189
  continue;
45973
46190
  }
45974
46191
  }
45975
46192
 
45976
46193
  if(!bRound1) {
45977
46194
  console.log("domainid: " + domainid);
45978
-
45979
- if(!domainid2score.hasOwnProperty(domainid) || queryData[0].score > domainid2score[domainid]) {
45980
- domainid2score[domainid] = queryData[0].score;
45981
-
45982
- ic.domainid2refpdbname[domainid] = refpdbname;
45983
- domainid2segs[domainid] = queryData[0].segs;
45984
- ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
45985
- ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
45986
- }
45987
46195
  }
45988
- else {
45989
- //let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
45990
- let mixScore = queryData[0].score;
45991
46196
 
45992
- if(!domainid2score.hasOwnProperty(domainid) || mixScore > domainid2score[domainid]) {
45993
- domainid2score[domainid] = mixScore;
45994
-
45995
- ic.domainid2refpdbname[domainid] = refpdbname;
45996
- domainid2segs[domainid] = queryData[0].segs;
45997
- ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
45998
- ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
45999
- }
46197
+ if(!ic.domainid2score.hasOwnProperty(domainid) || queryData[0].score >= ic.domainid2score[domainid].split('_')[0]) {
46198
+ ic.domainid2score[domainid] = queryData[0].score + '_' + queryData[0].frac_identical + '_' + queryData[0].num_res ;
46199
+
46200
+ ic.domainid2refpdbname[domainid] = refpdbname;
46201
+ domainid2segs[domainid] = queryData[0].segs;
46202
+ ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
46203
+ ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46000
46204
  }
46001
46205
  }
46002
46206
 
@@ -46011,7 +46215,7 @@ class LineGraph {
46011
46215
  let pdbAjaxArray = [];
46012
46216
  let refpdbname = ic.domainid2refpdbname[domainid];
46013
46217
  //let pdbid = domainid.substr(0, domainid.indexOf('_'));
46014
- let chainid = domainid.substr(0, domainid.indexOf('-'));
46218
+ let chainid = domainid.substr(0, domainid.indexOf(','));
46015
46219
 
46016
46220
  //if(ic.refpdbHash.hasOwnProperty(pdbid)) {
46017
46221
  if(ic.refpdbHash.hasOwnProperty(chainid)) {
@@ -46034,8 +46238,10 @@ class LineGraph {
46034
46238
  pdbAjaxArray.push(pdbAjax);
46035
46239
  }
46036
46240
 
46037
- let allPromise2 = Promise.allSettled(pdbAjaxArray);
46038
- ic.pdbDataArray = await allPromise2;
46241
+ //let allPromise2 = Promise.allSettled(pdbAjaxArray);
46242
+ //ic.pdbDataArray = await allPromise2;
46243
+
46244
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46039
46245
 
46040
46246
  let pdb_target = ic.domainid2pdb[domainid];
46041
46247
  for(let index = 0, indexl = ic.pdbDataArray.length; index < indexl; ++index) {
@@ -46058,49 +46264,46 @@ class LineGraph {
46058
46264
  //let allPromise = Promise.allSettled(ajaxArray);
46059
46265
  //dataArray3 = await allPromise;
46060
46266
 
46061
- //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46062
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46063
-
46064
- for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46065
- let currAjaxArray = [];
46066
- if(i == il - 1) { // last one
46067
- currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
46068
- }
46069
- else {
46070
- currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
46071
- }
46072
-
46073
- let currPromise = Promise.allSettled(currAjaxArray);
46074
- let currDataArray = await currPromise;
46075
-
46076
- dataArray3 = dataArray3.concat(currDataArray);
46077
- }
46267
+ dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
46078
46268
 
46079
46269
  await thisClass.parseAlignData(dataArray3, domainidpairArray3, false);
46080
46270
 
46081
46271
  // end of round 2
46082
46272
  return;
46083
46273
  }
46084
-
46274
+
46085
46275
  // combine domainid into chainid
46086
46276
  let processedChainid = {};
46087
46277
  for(let domainid in ic.domainid2refpdbname) {
46088
- let chainid = domainid.split('-')[0];
46278
+ // remove the first round template
46279
+ if(ic.domainid2refpdbname[domainid].substr(0,1) == '1') {
46280
+ delete ic.domainid2refpdbname[domainid];
46281
+ delete ic.domainid2score[domainid];
46282
+ continue;
46283
+ }
46284
+
46285
+ let chainid = domainid.split(',')[0];
46089
46286
 
46090
- if(!processedChainid.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
46287
+ if(!processedChainid.hasOwnProperty(chainid)) {
46288
+ ic.chainid2refpdbname[chainid] = [];
46289
+ ic.chainid2score[chainid] = [];
46290
+ }
46091
46291
  processedChainid[chainid] = 1;
46092
46292
 
46093
46293
  if(!ic.chainid2refpdbname.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
46094
46294
  ic.chainid2refpdbname[chainid].push(ic.domainid2refpdbname[domainid] + '|' + domainid);
46295
+
46296
+ if(!ic.chainid2score.hasOwnProperty(chainid)) ic.chainid2score[chainid] = [];
46297
+ ic.chainid2score[chainid].push(ic.domainid2score[domainid] + '|' + domainid);
46095
46298
  }
46096
-
46299
+
46097
46300
  // combine domainid into chainid
46098
46301
  for(let domainid in domainid2segs) {
46099
- let chainid = domainid.split('-')[0];
46302
+ let chainid = domainid.split(',')[0];
46100
46303
  if(!chainid2segs[chainid]) chainid2segs[chainid] = [];
46101
46304
  chainid2segs[chainid] = chainid2segs[chainid].concat(domainid2segs[domainid]);
46102
46305
  }
46103
-
46306
+
46104
46307
  // assign ic.resid2refnum, ic.refnum2residArray, ic.chainsMapping
46105
46308
  if(!ic.resid2refnum) ic.resid2refnum = {};
46106
46309
  if(!ic.refnum2residArray) ic.refnum2residArray = {};
@@ -46113,11 +46316,18 @@ class LineGraph {
46113
46316
 
46114
46317
  let refpdbnameArray = ic.chainid2refpdbname[chainid];
46115
46318
 
46116
- let chainList = this.getTemplateList(chainid);
46319
+ let result = this.getTemplateList(chainid);
46320
+ let refpdbnameList = result.refpdbnameList;
46321
+ let scoreList = result.scoreList;
46322
+ let seqidList = result.seqidList;
46323
+ let nresAlignList = result.nresAlignList;
46117
46324
 
46118
- //if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
46119
- if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
46120
- ic.refPdbList.push("The reference PDB(s) for chain " + chainid + " are " + chainList);
46325
+ let message = "The reference PDB(s) for chain " + chainid + " is(are) " + refpdbnameList + ". The TM-score(s) is(are) " + scoreList + ". The sequence identitie(s) is(are) " + seqidList + ". The number of aligned residue(s) is(are) " + nresAlignList + ".";
46326
+ if(!me.bNode) {
46327
+ console.log(message);
46328
+ me.htmlCls.clickMenuCls.setLogCmd(message, true);
46329
+ }
46330
+ ic.refPdbList.push(message);
46121
46331
 
46122
46332
  let prevStrand;
46123
46333
  let bCd19 = refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
@@ -46187,51 +46397,52 @@ class LineGraph {
46187
46397
  getLabelFromRefnum(oriRefnum, prevStrand, bCd19) { let ic = this.icn3d; ic.icn3dui;
46188
46398
  let refnum = parseInt(oriRefnum);
46189
46399
 
46190
- // A-: 10xx
46191
- // A: 11xx
46192
- // A+ continue A
46193
- // A': 12xx
46194
- // B: 21xx
46195
- // C: 32xx
46196
- // C': 42xx
46197
- // C'': 51xx, 52xx
46198
- // D: 61xx
46199
- // E: 71xx
46200
- // E+: continue E
46201
- // F: 82xx
46202
- // G: 91xx, 92xx
46203
- // G+: continue G
46204
-
46205
- // if(refnum < 100) return " " + oriRefnum;
46206
- // else if(refnum >= 100 && refnum < 1000) {
46207
- // if(bCd19) return " " + oriRefnum;
46208
- // else return "A^" + oriRefnum;
46209
- // }
46210
- if(refnum < 900) return undefined;
46211
- else if(refnum >= 900 && refnum < 1000) return " " + oriRefnum;
46212
- else if(refnum >= 1000 && refnum < 1100) return "A-" + oriRefnum;
46213
- else if(refnum >= 1100 && refnum < 1200) return "A" + oriRefnum; // could be A+
46214
- else if(refnum >= 1200 && refnum < 1300) return "A'" + oriRefnum;
46215
- //else if(refnum >= 1300 && refnum < 1400) return "A+" + oriRefnum;
46216
- else if(refnum >= 1300 && refnum < 2000) {
46217
- if(prevStrand && prevStrand.substr(0, 1) == 'A') {
46218
- return prevStrand + oriRefnum;
46219
- }
46220
- else {
46221
- return "A" + oriRefnum;
46222
- }
46223
- }
46224
- else if(refnum >= 2000 && refnum < 3000) return "B" + oriRefnum;
46225
- else if(refnum >= 3000 && refnum < 4000) return "C" + oriRefnum;
46226
- else if(refnum >= 4000 && refnum < 5000) return "C'" + oriRefnum;
46227
- else if(refnum >= 5000 && refnum < 6000) return "C''" + oriRefnum;
46228
- else if(refnum >= 6000 && refnum < 7000) return "D" + oriRefnum;
46229
- else if(refnum >= 7000 && refnum < 8000) return "E" + oriRefnum; // could be E+
46230
- else if(refnum >= 8000 && refnum < 9000) return "F" + oriRefnum;
46231
- else if(refnum >= 9000 && refnum < 9300) return "G" + oriRefnum; // could be G+
46232
- //else if(refnum >= 9400 && refnum < 9500) return "G+" + oriRefnum;
46233
- else if(refnum >= 9300) return "G" + oriRefnum;
46234
- }
46400
+ //N-terminus = 0999-0001
46401
+ //A--- = 12xx
46402
+ //A-- = 13xx
46403
+ //A- = 14xx
46404
+ //A = 15xx (anchor 1550)
46405
+ //A+ = 16xx
46406
+ //A' = 18xx (anchor 1850)
46407
+ //B = 25xx (anchor 2550)
46408
+ //C-- = 33xx
46409
+ //C- = 34xx
46410
+ //C = 35xx (anchor 3550)
46411
+ //C' = 45xx (anchor 4550)
46412
+ //C'' = 55xx (anchor 5550)
46413
+ //D = 65xx (anchor 3550)
46414
+ //E = 75xx (anchor 7550)
46415
+ //E+ = 76xx
46416
+ //F = 85xx (anchor 8550)
46417
+ //G = 95xx (anchor 9550)
46418
+ //G+ = 96xx
46419
+ //G++ = 97xx
46420
+ //C-terminus = 9901-9999 (no anchor, numbering going forward)
46421
+
46422
+ // loops may have numbers such as 1310, 1410
46423
+
46424
+ if(refnum < 1000) return undefined;
46425
+ else if(refnum >= 1200 && refnum < 1290) return "A---" + oriRefnum;
46426
+ else if(refnum >= 1320 && refnum < 1390) return "A--" + oriRefnum;
46427
+ else if(refnum >= 1420 && refnum < 1490) return "A-" + oriRefnum;
46428
+ else if(refnum >= 1520 && refnum < 1590) return "A" + oriRefnum;
46429
+ else if(refnum >= 1620 && refnum < 1690) return "A+" + oriRefnum;
46430
+ else if(refnum >= 1820 && refnum < 1890) return "A'" + oriRefnum;
46431
+ else if(refnum >= 2000 && refnum < 2900) return "B" + oriRefnum;
46432
+ else if(refnum >= 3300 && refnum < 3390) return "C--" + oriRefnum;
46433
+ else if(refnum >= 3420 && refnum < 3490) return "C-" + oriRefnum;
46434
+ else if(refnum >= 3520 && refnum < 3590) return "C" + oriRefnum;
46435
+ else if(refnum >= 4000 && refnum < 4900) return "C'" + oriRefnum;
46436
+ else if(refnum >= 5000 && refnum < 5900) return "C''" + oriRefnum;
46437
+ else if(refnum >= 6000 && refnum < 6900) return "D" + oriRefnum;
46438
+ else if(refnum >= 7500 && refnum < 7590) return "E" + oriRefnum;
46439
+ else if(refnum >= 7620 && refnum < 7900) return "E+" + oriRefnum;
46440
+ else if(refnum >= 8000 && refnum < 8900) return "F" + oriRefnum;
46441
+ else if(refnum >= 9500 && refnum < 9590) return "G" + oriRefnum;
46442
+ else if(refnum >= 9620 && refnum < 9690) return "G+" + oriRefnum;
46443
+ else if(refnum >= 9720 && refnum < 9790) return "G++" + oriRefnum;
46444
+ else if(refnum > 9900) return undefined;
46445
+ else return " " + oriRefnum; }
46235
46446
 
46236
46447
  async parseCustomRefFile(data) { let ic = this.icn3d; ic.icn3dui;
46237
46448
  ic.bShowCustomRefnum = true;
@@ -46413,6 +46624,32 @@ class LineGraph {
46413
46624
  return refData;
46414
46625
  }
46415
46626
  }
46627
+
46628
+ async promiseWithFixedJobs(ajaxArray) { let ic = this.icn3d, me = ic.icn3dui;
46629
+ let dataArray3 = [];
46630
+ //let allPromise = Promise.allSettled(ajaxArray);
46631
+ //dataArray3 = await allPromise;
46632
+
46633
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46634
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46635
+
46636
+ for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46637
+ let currAjaxArray = [];
46638
+ if(i == il - 1) { // last one
46639
+ currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
46640
+ }
46641
+ else {
46642
+ currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
46643
+ }
46644
+
46645
+ let currPromise = Promise.allSettled(currAjaxArray);
46646
+ let currDataArray = await currPromise;
46647
+
46648
+ dataArray3 = dataArray3.concat(currDataArray);
46649
+ }
46650
+
46651
+ return dataArray3;
46652
+ }
46416
46653
  }
46417
46654
 
46418
46655
  /**
@@ -47721,7 +47958,7 @@ class ViewInterPairs {
47721
47958
 
47722
47959
  if(ic.bD3 === undefined) {
47723
47960
  //let url = "https://d3js.org/d3.v4.min.js";
47724
- let url = "https://www.ncbi.nlm.nih.gov/Structure/icn3d/script/d3v4-force-all.min.js";
47961
+ let url = "./script/d3v4-force-all.min.js";
47725
47962
  await me.getAjaxPromise(url, 'script');
47726
47963
 
47727
47964
  ic.bD3 = true;
@@ -48996,7 +49233,7 @@ class AlignParser {
48996
49233
  for(let j = 0, jl = mmdbTmp.molecules.length; j < jl; ++j) {
48997
49234
  let molecule = mmdbTmp.molecules[j];
48998
49235
  let molid = molecule.moleculeId;
48999
- let chainName = molecule.chain.trim();
49236
+ let chainName = molecule.chain.trim().replace(/_/g, ''); // change "A_1" to "A1"
49000
49237
  if(chainNameHash[chainName] === undefined) {
49001
49238
  chainNameHash[chainName] = 1;
49002
49239
  }
@@ -49407,6 +49644,8 @@ class ChainalignParser {
49407
49644
 
49408
49645
  let queryData = {}; // check whether undefined
49409
49646
 
49647
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
49648
+
49410
49649
  this.processAlign(align, index, queryData, bEqualMmdbid, bEqualChain);
49411
49650
  }
49412
49651
 
@@ -49504,6 +49743,8 @@ class ChainalignParser {
49504
49743
  continue;
49505
49744
  }
49506
49745
 
49746
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid1 + " with " + mmdbid2, false);
49747
+
49507
49748
  let bNoAlert = true;
49508
49749
  let bAligned = this.processAlign(align, i, queryData, bEqualMmdbid, bEqualChain, bNoAlert);
49509
49750
 
@@ -49954,6 +50195,8 @@ class ChainalignParser {
49954
50195
  let bEqualMmdbid = (mmdbid_q == mmdbid_t);
49955
50196
  let bEqualChain = (chain_q == chain_t);
49956
50197
 
50198
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
50199
+
49957
50200
  this.processAlign(align, index-1, queryData, bEqualMmdbid, bEqualChain);
49958
50201
  }
49959
50202
  }
@@ -50014,6 +50257,7 @@ class ChainalignParser {
50014
50257
  ic.qt_start_end[index] = align[0].segs;
50015
50258
 
50016
50259
  let rmsd = align[0].super_rmsd;
50260
+ console.log();
50017
50261
 
50018
50262
  let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
50019
50263
  if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
@@ -50283,10 +50527,10 @@ class Dsn6Parser {
50283
50527
  // https://edmaps.rcsb.org/maps/1kq2_fofc.dsn6
50284
50528
 
50285
50529
  let url = "https://edmaps.rcsb.org/maps/" + pdbid.toLowerCase() + "_" + type + ".dsn6";
50286
- await this.dsn6ParserBase(url, type, sigma);
50530
+ await this.dsn6ParserBase(url, type, sigma, 'url', true);
50287
50531
  }
50288
50532
 
50289
- async dsn6ParserBase(url, type, sigma) { let ic = this.icn3d, me = ic.icn3dui;
50533
+ async dsn6ParserBase(url, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
50290
50534
  let thisClass = this;
50291
50535
 
50292
50536
  //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
@@ -50300,7 +50544,7 @@ class Dsn6Parser {
50300
50544
  }
50301
50545
  else {
50302
50546
  let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'rcsbEdmaps');
50303
- thisClass.loadDsn6Data(arrayBuffer, type, sigma);
50547
+ sigma = thisClass.loadDsn6Data(arrayBuffer, type, sigma, location, bInputSigma);
50304
50548
 
50305
50549
  if(type == '2fofc') {
50306
50550
  ic.bAjax2fofc = true;
@@ -50311,9 +50555,11 @@ class Dsn6Parser {
50311
50555
 
50312
50556
  ic.setOptionCls.setOption('map', type);
50313
50557
  }
50558
+
50559
+ return sigma;
50314
50560
  }
50315
50561
 
50316
- loadDsn6Data(dsn6data, type, sigma) { let ic = this.icn3d; ic.icn3dui;
50562
+ loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
50317
50563
  // DSN6 http://www.uoxray.uoregon.edu/tnt/manual/node104.html
50318
50564
  // BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
50319
50565
 
@@ -50362,9 +50608,9 @@ class Dsn6Parser {
50362
50608
  }
50363
50609
  }
50364
50610
 
50365
- header.zStart = intView[ 2 ];
50366
50611
  header.xStart = intView[ 0 ]; // NXSTART
50367
50612
  header.yStart = intView[ 1 ];
50613
+ header.zStart = intView[ 2 ];
50368
50614
 
50369
50615
  header.xExtent = intView[ 3 ]; // NX
50370
50616
  header.yExtent = intView[ 4 ];
@@ -50400,6 +50646,7 @@ class Dsn6Parser {
50400
50646
  let zBlocks = Math.ceil(header.zExtent / 8);
50401
50647
 
50402
50648
  // loop over blocks
50649
+ let maxValue = -999;
50403
50650
  for(let zz = 0; zz < zBlocks; ++zz) {
50404
50651
  for(let yy = 0; yy < yBlocks; ++yy) {
50405
50652
  for(let xx = 0; xx < xBlocks; ++xx) {
@@ -50415,6 +50662,7 @@ class Dsn6Parser {
50415
50662
  if(x < header.xExtent && y < header.yExtent && z < header.zExtent) {
50416
50663
  let idx =((((x * header.yExtent) + y) * header.zExtent) + z);
50417
50664
  data[ idx ] =(byteView[ offset ] - summand) / divisor;
50665
+ if(data[ idx ] > maxValue) maxValue = data[ idx ];
50418
50666
  ++offset;
50419
50667
  } else {
50420
50668
  offset += 8 - i;
@@ -50427,6 +50675,10 @@ class Dsn6Parser {
50427
50675
  }
50428
50676
  }
50429
50677
 
50678
+ if(!bInputSigma) {
50679
+ sigma = this.setSigma(maxValue, location, type, sigma);
50680
+ }
50681
+
50430
50682
  if(type == '2fofc') {
50431
50683
  ic.mapData.header2 = header;
50432
50684
  ic.mapData.data2 = data;
@@ -50441,6 +50693,32 @@ class Dsn6Parser {
50441
50693
  ic.mapData.type = type;
50442
50694
  ic.mapData.sigma = sigma;
50443
50695
  }
50696
+
50697
+ return sigma;
50698
+ }
50699
+
50700
+ setSigma(maxValue, location, type, sigma) { let ic = this.icn3d, me = ic.icn3dui;
50701
+ let inputId;
50702
+ if(location == 'file') {
50703
+ inputId = 'dsn6sigma' + type;
50704
+ }
50705
+ else if(location == 'url') {
50706
+ inputId = 'dsn6sigmaurl' + type;
50707
+ }
50708
+
50709
+ let factor = (type == '2fofc') ? 0.5 : 0.3;
50710
+
50711
+ if(inputId) {
50712
+ if(!($("#" + me.pre + inputId).val())) {
50713
+ sigma = (factor * maxValue).toFixed(2);
50714
+ $("#" + me.pre + inputId).val(sigma);
50715
+ }
50716
+ else {
50717
+ sigma = $("#" + me.pre + inputId).val();
50718
+ }
50719
+ }
50720
+
50721
+ return sigma;
50444
50722
  }
50445
50723
 
50446
50724
  getMatrix(header) { let ic = this.icn3d; ic.icn3dui;
@@ -50514,7 +50792,9 @@ class Dsn6Parser {
50514
50792
  let reader = new FileReader();
50515
50793
  reader.onload = function(e) { let ic = thisClass.icn3d;
50516
50794
  let arrayBuffer = e.target.result; // or = reader.result;
50517
- thisClass.loadDsn6Data(arrayBuffer, type, sigma);
50795
+
50796
+ sigma = thisClass.loadDsn6Data(arrayBuffer, type, sigma, 'file');
50797
+
50518
50798
  if(type == '2fofc') {
50519
50799
  ic.bAjax2fofc = true;
50520
50800
  }
@@ -50522,21 +50802,1005 @@ class Dsn6Parser {
50522
50802
  ic.bAjaxfofc = true;
50523
50803
  }
50524
50804
  ic.setOptionCls.setOption('map', type);
50525
- me.htmlCls.clickMenuCls.setLogCmd('load dsn6 file ' + $("#" + ic.pre + "dsn6file" + type).val(), false);
50805
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
50526
50806
  };
50527
50807
  reader.readAsArrayBuffer(file);
50528
50808
  }
50529
50809
  }
50530
50810
 
50531
50811
  loadDsn6FileUrl(type) {var ic = this.icn3d, me = ic.icn3dui;
50812
+ let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
50813
+ let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
50814
+ if(!url) {
50815
+ var aaa = 1; //alert("Please input the file URL before clicking 'Load'");
50816
+ }
50817
+ else {
50818
+ sigma = this.dsn6ParserBase(url, type, sigma, 'url');
50819
+ me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file dsn6 | ' + encodeURIComponent(url), true);
50820
+ }
50821
+ }
50822
+
50823
+ }
50824
+
50825
+ /**
50826
+ * @file Ccp4 Parser
50827
+ * @author Marcin Wojdyr <wojdyr@gmail.com>
50828
+ * @private
50829
+ * Modified by Jiyao Wang / https://github.com/ncbi/icn3d
50830
+ */
50831
+
50832
+ class Ccp4Parser {
50833
+ constructor(icn3d) {
50834
+ this.icn3d = icn3d;
50835
+ }
50836
+
50837
+ async ccp4ParserBase(url, type, sigma, location) { let ic = this.icn3d, me = ic.icn3dui;
50838
+ let thisClass = this;
50839
+
50840
+ //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
50841
+ // if(type == '2fofc' && ic.bAjax2fofcccp4) {
50842
+ // ic.mapData.sigma2 = sigma;
50843
+ // ic.setOptionCls.setOption('map', type);
50844
+ // }
50845
+ // else if(type == 'fofc' && ic.bAjaxfofcccp4) {
50846
+ // ic.mapData.sigma = sigma;
50847
+ // ic.setOptionCls.setOption('map', type);
50848
+ // }
50849
+ // else {
50850
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', '');
50851
+ let bInputSigma = true;
50852
+ sigma = thisClass.load_map_from_buffer(arrayBuffer, type, sigma, location, bInputSigma);
50853
+
50854
+ // if(type == '2fofc') {
50855
+ // ic.bAjax2fofcccp4 = true;
50856
+ // }
50857
+ // else if(type == 'fofc') {
50858
+ // ic.bAjaxfofcccp4 = true;
50859
+ // }
50860
+
50861
+ ic.setOptionCls.setOption('map', type);
50862
+
50863
+ return sigma;
50864
+ // }
50865
+ }
50866
+
50867
+ // modified from_ccp4() at https://github.com/uglymol/uglymol.github.io/blob/master/src/elmap.js
50868
+ load_map_from_buffer(buf, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
50869
+ if (buf.byteLength < 1024) throw Error('File shorter than 1024 bytes.');
50870
+
50871
+ //console.log('buf type: ' + Object.prototype.toString.call(buf));
50872
+ // for now we assume both file and host are little endian
50873
+ const iview = new Int32Array(buf, 0, 256);
50874
+ // word 53 - character string 'MAP ' to identify file type
50875
+ if (iview[52] !== 0x2050414d) throw Error('not a CCP4 map');
50876
+
50877
+ // map has 3 dimensions referred to as columns (fastest changing), rows
50878
+ // and sections (c-r-s)
50879
+ const n_crs = [iview[0], iview[1], iview[2]]; // 108, 108, 108
50880
+ const mode = iview[3]; //2
50881
+ let nb;
50882
+ if (mode === 2) nb = 4;
50883
+ else if (mode === 0) nb = 1;
50884
+ else throw Error('Only Mode 2 and Mode 0 of CCP4 map is supported.');
50885
+
50886
+ const start = [iview[4], iview[5], iview[6]]; // 0,0,0
50887
+ const n_grid = [iview[7], iview[8], iview[9]]; // 108,108,108
50888
+ const nsymbt = iview[23]; // size of extended header in bytes
50889
+ // nsymbt = 1920
50890
+
50891
+ if (1024 + nsymbt + nb*n_crs[0]*n_crs[1]*n_crs[2] !== buf.byteLength) {
50892
+ throw Error('ccp4 file too short or too long');
50893
+ }
50894
+
50895
+ const fview = new Float32Array(buf, 0, buf.byteLength / 4);
50896
+ const grid = new GridArray(n_grid);
50897
+ const unit_cell = new UnitCell(fview[10], fview[11], fview[12], fview[13], fview[14], fview[15]); // 79.1, 79.1, 79.1, 90, 90, 90
50898
+
50899
+ // MAPC, MAPR, MAPS - axis corresp to cols, rows, sections (1,2,3 for X,Y,Z)
50900
+ const map_crs = [iview[16], iview[17], iview[18]]; // 2,1,3
50901
+ const ax = map_crs.indexOf(1);
50902
+ const ay = map_crs.indexOf(2);
50903
+ const az = map_crs.indexOf(3);
50904
+
50905
+ const min = fview[19]; // -0.49
50906
+ const max = fview[20]; // 0.94
50907
+ //const sg_number = iview[22];
50908
+ //const lskflg = iview[24];
50909
+
50910
+ if (nsymbt % 4 !== 0) {
50911
+ throw Error('CCP4 map with NSYMBT not divisible by 4 is not supported.');
50912
+ }
50913
+ let data_view;
50914
+ if (mode === 2) data_view = fview;
50915
+ else /* mode === 0 */ data_view = new Int8Array(buf);
50916
+ let idx = (1024 + nsymbt) / nb | 0; //736
50917
+
50918
+ // We assume that if DMEAN and RMS from the header are not clearly wrong
50919
+ // they are what the user wants. Because the map can cover a small part
50920
+ // of the asu and its rmsd may be different than the total rmsd.
50921
+ // let stats = { mean: 0.0, rms: 1.0 };
50922
+ // stats.mean = fview[21]; //0
50923
+ // stats.rms = fview[54]; //0.15
50924
+ // if (stats.mean < min || stats.mean > max || stats.rms <= 0) {
50925
+ // stats = this.calculate_stddev(data_view, idx);
50926
+ // }
50927
+
50928
+ let b1 = 1;
50929
+ let b0 = 0;
50930
+ // if the file was converted by mapmode2to0 - scale the data
50931
+ if (mode === 0 && iview[39] === -128 && iview[40] === 127) { //39:0, 40:0
50932
+ // scaling f(x)=b1*x+b0 such that f(-128)=min and f(127)=max
50933
+ b1 = (max - min) / 255.0;
50934
+ b0 = 0.5 * (min + max + b1);
50935
+ }
50936
+
50937
+ const end = [start[0] + n_crs[0], start[1] + n_crs[1], start[2] + n_crs[2]];
50938
+ let it = [0, 0, 0];
50939
+ let maxValue = -999;
50940
+ for (it[2] = start[2]; it[2] < end[2]; it[2]++) { // sections
50941
+ for (it[1] = start[1]; it[1] < end[1]; it[1]++) { // rows
50942
+ for (it[0] = start[0]; it[0] < end[0]; it[0]++) { // cols
50943
+ let value = b1 * data_view[idx] + b0;
50944
+ grid.set_grid_value(it[ax], it[ay], it[az], value);
50945
+
50946
+ if(value > maxValue) maxValue = value;
50947
+ idx++;
50948
+ }
50949
+ }
50950
+ }
50951
+
50952
+ /*
50953
+ if (expand_symmetry && nsymbt > 0) {
50954
+ const u8view = new Uint8Array(buf);
50955
+ for (let i = 0; i+80 <= nsymbt; i += 80) {
50956
+ let j;
50957
+ let symop = '';
50958
+ for (j = 0; j < 80; ++j) {
50959
+ symop += String.fromCharCode(u8view[1024 + i + j]);
50960
+ }
50961
+ if (/^\s*x\s*,\s*y\s*,\s*z\s*$/i.test(symop)) continue; // skip x,y,z
50962
+ //console.log('sym ops', symop.trim());
50963
+ let mat = this.parse_symop(symop);
50964
+ // Note: we apply here symops to grid points instead of coordinates.
50965
+ // In the cases we came across it is equivalent, but in general not.
50966
+ for (j = 0; j < 3; ++j) {
50967
+ mat[j][3] = Math.round(mat[j][3] * n_grid[j]) | 0;
50968
+ }
50969
+ idx = (1024 + nsymbt) / nb | 0;
50970
+ let xyz = [0, 0, 0];
50971
+ for (it[2] = start[2]; it[2] < end[2]; it[2]++) { // sections
50972
+ for (it[1] = start[1]; it[1] < end[1]; it[1]++) { // rows
50973
+ for (it[0] = start[0]; it[0] < end[0]; it[0]++) { // cols
50974
+ for (j = 0; j < 3; ++j) {
50975
+ xyz[j] = it[ax] * mat[j][0] + it[ay] * mat[j][1] +
50976
+ it[az] * mat[j][2] + mat[j][3];
50977
+ }
50978
+ let value = b1 * data_view[idx] + b0;
50979
+ grid.set_grid_value(xyz[0], xyz[1], xyz[2], value);
50980
+
50981
+ if(value > maxValue) maxValue = value;
50982
+ idx++;
50983
+ }
50984
+ }
50985
+ }
50986
+ }
50987
+ }
50988
+ */
50989
+
50990
+ if(!bInputSigma) {
50991
+ sigma = ic.dsn6ParserCls.setSigma(maxValue, location, type, sigma);
50992
+ }
50993
+
50994
+ if(type == '2fofc') {
50995
+ ic.mapData.ccp4 = 1;
50996
+ ic.mapData.grid2 = grid;
50997
+ ic.mapData.unit_cell2 = unit_cell;
50998
+ ic.mapData.type2 = type;
50999
+ ic.mapData.sigma2 = sigma;
51000
+ }
51001
+ else {
51002
+ ic.mapData.ccp4 = 1;
51003
+ ic.mapData.grid = grid;
51004
+ ic.mapData.unit_cell = unit_cell;
51005
+ ic.mapData.type = type;
51006
+ ic.mapData.sigma = sigma;
51007
+ }
51008
+
51009
+ return sigma;
51010
+ }
51011
+
51012
+ load_maps_from_mtz_buffer(mtz, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51013
+ let is_diff = (type == 'fofc'); // diff: fofc, non-diff: 2fofc
51014
+ let dataArray = mtz.calculate_map(is_diff);
51015
+
51016
+ let mc = mtz.cell;
51017
+ const unit_cell = new UnitCell(mc.a, mc.b, mc.c, mc.alpha, mc.beta, mc.gamma);
51018
+
51019
+ let maxValue = -999;
51020
+ for(let i = 0, il = dataArray.length; i < il; ++i) {
51021
+ if(dataArray[i] > maxValue) maxValue = dataArray[i];
51022
+ }
51023
+
51024
+ if(!bInputSigma) {
51025
+ sigma = ic.dsn6ParserCls.setSigma(maxValue, location, type, sigma);
51026
+ }
51027
+
51028
+ const grid = new GridArray([mtz.nx, mtz.ny, mtz.nz]);
51029
+ grid.values.set(dataArray);
51030
+
51031
+ if(type == '2fofc') {
51032
+ ic.mapData.ccp4 = 1;
51033
+ ic.mapData.grid2 = grid;
51034
+ ic.mapData.unit_cell2 = unit_cell;
51035
+ ic.mapData.type2 = type;
51036
+ ic.mapData.sigma2 = sigma;
51037
+ }
51038
+ else {
51039
+ ic.mapData.ccp4 = 1;
51040
+ ic.mapData.grid = grid;
51041
+ ic.mapData.unit_cell = unit_cell;
51042
+ ic.mapData.type = type;
51043
+ ic.mapData.sigma = sigma;
51044
+ }
51045
+
51046
+ mtz.delete();
51047
+
51048
+ return sigma;
51049
+ }
51050
+
51051
+ // calculate_stddev(a, offset) {
51052
+ // let sum = 0;
51053
+ // let sq_sum = 0;
51054
+ // const alen = a.length;
51055
+ // for (let i = offset; i < alen; i++) {
51056
+ // sum += a[i];
51057
+ // sq_sum += a[i] * a[i];
51058
+ // }
51059
+ // const mean = sum / (alen - offset);
51060
+ // const variance = sq_sum / (alen - offset) - mean * mean;
51061
+ // return {mean: mean, rms: Math.sqrt(variance)};
51062
+ // }
51063
+
51064
+ parse_symop(symop) {
51065
+ const ops = symop.toLowerCase().replace(/\s+/g, '').split(',');
51066
+ if (ops.length !== 3) throw Error('Unexpected symop: ' + symop);
51067
+ let mat = [];
51068
+ for (let i = 0; i < 3; i++) {
51069
+ const terms = ops[i].split(/(?=[+-])/);
51070
+ let row = [0, 0, 0, 0];
51071
+ for (let j = 0; j < terms.length; j++) {
51072
+ const term = terms[j];
51073
+ const sign = (term[0] === '-' ? -1 : 1);
51074
+ let m = terms[j].match(/^[+-]?([xyz])$/);
51075
+ if (m) {
51076
+ const pos = {x: 0, y: 1, z: 2}[m[1]];
51077
+ row[pos] = sign;
51078
+ } else {
51079
+ m = terms[j].match(/^[+-]?(\d)\/(\d)$/);
51080
+ if (!m) throw Error('What is ' + terms[j] + ' in ' + symop);
51081
+ row[3] = sign * Number(m[1]) / Number(m[2]);
51082
+ }
51083
+ }
51084
+ mat.push(row);
51085
+ }
51086
+ return mat;
51087
+ }
51088
+
51089
+ loadCcp4File(type) {let ic = this.icn3d, me = ic.icn3dui;
51090
+ let thisClass = this;
51091
+
51092
+ let file = $("#" + ic.pre + "dsn6file" + type)[0].files[0];
51093
+ let sigma = $("#" + ic.pre + "dsn6sigma" + type).val();
51094
+ if(!file) {
51095
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
51096
+ }
51097
+ else {
51098
+ me.utilsCls.checkFileAPI();
51099
+ let reader = new FileReader();
51100
+ reader.onload = function(e) { let ic = thisClass.icn3d;
51101
+ let arrayBuffer = e.target.result; // or = reader.result;
51102
+ sigma = thisClass.load_map_from_buffer(arrayBuffer, type, sigma, 'file');
51103
+
51104
+ // if(type == '2fofc') {
51105
+ // ic.bAjax2fofcCcp4 = true;
51106
+ // }
51107
+ // else if(type == 'fofc') {
51108
+ // ic.bAjaxfofcCcp4 = true;
51109
+ // }
51110
+ ic.setOptionCls.setOption('map', type);
51111
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
51112
+ };
51113
+ reader.readAsArrayBuffer(file);
51114
+ }
51115
+ }
51116
+
51117
+ async loadCcp4FileUrl(type) { let ic = this.icn3d, me = ic.icn3dui;
50532
51118
  let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
50533
51119
  let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
50534
51120
  if(!url) {
50535
51121
  var aaa = 1; //alert("Please input the file URL before clicking 'Load'");
50536
51122
  }
50537
51123
  else {
50538
- this.dsn6ParserBase(url, type, sigma);
50539
- me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' | ' + encodeURIComponent(url), true);
51124
+ sigma = await this.ccp4ParserBase(url, type, sigma, 'file');
51125
+
51126
+ me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file ccp4 | ' + encodeURIComponent(url), true);
51127
+ }
51128
+ }
51129
+
51130
+ // Extract a block of density for calculating an isosurface using the
51131
+ // separate marching cubes implementation.
51132
+ extract_block(grid, unit_cell, radius, center, typeDetail) { let ic = this.icn3d; ic.icn3dui;
51133
+ // let grid = this.grid;
51134
+ // let unit_cell = this.unit_cell;
51135
+ if (grid == null || unit_cell == null) { return; }
51136
+ let fc = unit_cell.fractionalize(center);
51137
+
51138
+ let r = [radius / unit_cell.parameters[0],
51139
+ radius / unit_cell.parameters[1],
51140
+ radius / unit_cell.parameters[2]];
51141
+ let grid_min = grid.frac2grid([fc[0] - r[0], fc[1] - r[1], fc[2] - r[2]]);
51142
+ let grid_max = grid.frac2grid([fc[0] + r[0], fc[1] + r[1], fc[2] + r[2]]);
51143
+
51144
+ let size = [grid_max[0] - grid_min[0] + 1,
51145
+ grid_max[1] - grid_min[1] + 1,
51146
+ grid_max[2] - grid_min[2] + 1];
51147
+ let points = [];
51148
+ let values = [];
51149
+ let threshold = 1;
51150
+ let bAtoms = ic.hAtoms && Object.keys(ic.hAtoms).length > 0;
51151
+ for (let i = grid_min[0]; i <= grid_max[0]; i++) {
51152
+ for (let j = grid_min[1]; j <= grid_max[1]; j++) {
51153
+ for (let k = grid_min[2]; k <= grid_max[2]; k++) {
51154
+ let frac = grid.grid2frac(i, j, k);
51155
+ let orth = unit_cell.orthogonalize(frac);
51156
+ points.push(orth);
51157
+
51158
+ // get overlap between map and atoms
51159
+ let positoin = new THREE.Vector3(orth[0], orth[1], orth[2]);
51160
+ let atomsNear = ic.rayCls.getAtomsFromPosition(positoin, threshold, ic.hAtoms);
51161
+
51162
+ let map_value = (atomsNear || !bAtoms) ? grid.get_grid_value(i, j, k) : 0;
51163
+
51164
+ if(typeDetail == 'fofc_pos' && map_value < 0) map_value = 0;
51165
+ if(typeDetail == 'fofc_neg') map_value = (map_value > 0) ? 0 : -map_value;
51166
+
51167
+ values.push(map_value);
51168
+ }
51169
+ }
51170
+ }
51171
+
51172
+ return {size: size, values: values, points: points};
51173
+ // this.block.set(points, values, size);
51174
+ };
51175
+
51176
+ marchingCubes(dims, values, points, isolevel, method) { let ic = this.icn3d; ic.icn3dui;
51177
+ const edgeTable = new Int32Array([
51178
+ 0x0 , 0x0 , 0x202, 0x302, 0x406, 0x406, 0x604, 0x704,
51179
+ 0x804, 0x805, 0xa06, 0xa06, 0xc0a, 0xd03, 0xe08, 0xf00,
51180
+ 0x90 , 0x98 , 0x292, 0x292, 0x496, 0x49e, 0x694, 0x694,
51181
+ 0x894, 0x894, 0xa96, 0xa96, 0xc9a, 0xc92, 0xe91, 0xe90,
51182
+ 0x230, 0x230, 0x33 , 0x13a, 0x636, 0x636, 0x434, 0x43c,
51183
+ 0xa34, 0xa35, 0x837, 0x936, 0xe3a, 0xf32, 0xc31, 0xd30,
51184
+ 0x2a0, 0x2a8, 0xa3 , 0xaa , 0x6a6, 0x6af, 0x5a4, 0x4ac,
51185
+ 0xaa4, 0xaa4, 0x9a6, 0x8a6, 0xfaa, 0xea3, 0xca1, 0xca0,
51186
+ 0x460, 0x460, 0x662, 0x762, 0x66 , 0x66 , 0x265, 0x364,
51187
+ 0xc64, 0xc65, 0xe66, 0xe66, 0x86a, 0x863, 0xa69, 0xa60,
51188
+ 0x4f0, 0x4f8, 0x6f2, 0x6f2, 0xf6 , 0xfe , 0x2f5, 0x2fc,
51189
+ 0xcf4, 0xcf4, 0xef6, 0xef6, 0x8fa, 0x8f3, 0xaf9, 0xaf0,
51190
+ 0x650, 0x650, 0x453, 0x552, 0x256, 0x256, 0x54 , 0x154,
51191
+ 0xe54, 0xf54, 0xc57, 0xd56, 0xa5a, 0xb52, 0x859, 0x950,
51192
+ 0x7c0, 0x6c1, 0x5c2, 0x4c2, 0x3c6, 0x2ce, 0xc5 , 0xc4 ,
51193
+ 0xfc4, 0xec5, 0xdc6, 0xcc6, 0xbca, 0xac2, 0x8c1, 0x8c0,
51194
+ 0x8c0, 0x8c0, 0xac2, 0xbc2, 0xcc6, 0xcc6, 0xec4, 0xfcc,
51195
+ 0xc4 , 0xc5 , 0x2c6, 0x3c6, 0x4c2, 0x5c2, 0x6c1, 0x7c0,
51196
+ 0x950, 0x859, 0xb52, 0xa5a, 0xd56, 0xc57, 0xe54, 0xe5c,
51197
+ 0x154, 0x54 , 0x25e, 0x256, 0x552, 0x453, 0x658, 0x650,
51198
+ 0xaf0, 0xaf0, 0x8f3, 0x8fa, 0xef6, 0xef6, 0xcf4, 0xcfc,
51199
+ 0x2f4, 0x3f5, 0xff , 0x1f6, 0x6f2, 0x6f3, 0x4f9, 0x5f0,
51200
+ 0xa60, 0xa69, 0x863, 0x86a, 0xe66, 0xe67, 0xd65, 0xc6c,
51201
+ 0x364, 0x265, 0x166, 0x66 , 0x76a, 0x663, 0x460, 0x460,
51202
+ 0xca0, 0xca0, 0xea2, 0xfa2, 0x8a6, 0x8a6, 0xaa4, 0xba4,
51203
+ 0x4ac, 0x5a4, 0x6ae, 0x7a6, 0xaa , 0xa3 , 0x2a8, 0x2a0,
51204
+ 0xd30, 0xc31, 0xf32, 0xe3a, 0x936, 0x837, 0xb35, 0xa34,
51205
+ 0x43c, 0x434, 0x73e, 0x636, 0x13a, 0x33 , 0x339, 0x230,
51206
+ 0xe90, 0xe90, 0xc92, 0xc9a, 0xa96, 0xa96, 0x894, 0x89c,
51207
+ 0x694, 0x695, 0x49f, 0x496, 0x292, 0x392, 0x98 , 0x90 ,
51208
+ 0xf00, 0xe08, 0xd03, 0xc0a, 0xa06, 0xa0e, 0x805, 0x804,
51209
+ 0x704, 0x604, 0x506, 0x406, 0x302, 0x202, 0x0 , 0x0]);
51210
+
51211
+ const segTable = [
51212
+ [],
51213
+ [],
51214
+ [1, 9],
51215
+ [1, 8, 1, 9],
51216
+ [2, 10, 10, 1],
51217
+ [2, 10, 10, 1],
51218
+ [9, 2, 2, 10, 10, 9],
51219
+ [2, 8, 2, 10, 10, 8, 10, 9],
51220
+ [11, 2],
51221
+ [0, 11, 11, 2],
51222
+ [1, 9, 11, 2],
51223
+ [1, 11, 11, 2, 1, 9, 9, 11],
51224
+ [3, 10, 10, 1, 11, 10],
51225
+ [0, 10, 10, 1, 8, 10, 11, 10],
51226
+ [3, 9, 11, 9, 11, 10, 10, 9],
51227
+ [8, 10, 10, 9, 11, 10],
51228
+ [4, 7],
51229
+ [4, 3, 4, 7],
51230
+ [1, 9, 4, 7],
51231
+ [4, 1, 1, 9, 4, 7, 7, 1],
51232
+ [2, 10, 10, 1, 4, 7],
51233
+ [3, 4, 4, 7, 2, 10, 10, 1],
51234
+ [9, 2, 2, 10, 10, 9, 4, 7],
51235
+ [2, 10, 10, 9, 9, 2, 9, 7, 7, 2, 4, 7],
51236
+ [4, 7, 11, 2],
51237
+ [11, 4, 4, 7, 11, 2, 2, 4],
51238
+ [1, 9, 4, 7, 11, 2],
51239
+ [4, 7, 11, 4, 11, 9, 11, 2, 2, 9, 1, 9],
51240
+ [3, 10, 10, 1, 11, 10, 4, 7],
51241
+ [1, 11, 11, 10, 10, 1, 1, 4, 4, 11, 4, 7],
51242
+ [4, 7, 0, 11, 11, 9, 11, 10, 10, 9],
51243
+ [4, 7, 11, 4, 11, 9, 11, 10, 10, 9],
51244
+ [9, 5, 5, 4],
51245
+ [9, 5, 5, 4],
51246
+ [0, 5, 5, 4, 1, 5],
51247
+ [8, 5, 5, 4, 3, 5, 1, 5],
51248
+ [2, 10, 10, 1, 9, 5, 5, 4],
51249
+ [2, 10, 10, 1, 9, 5, 5, 4],
51250
+ [5, 2, 2, 10, 10, 5, 5, 4, 4, 2],
51251
+ [2, 10, 10, 5, 5, 2, 5, 3, 5, 4, 4, 3],
51252
+ [9, 5, 5, 4, 11, 2],
51253
+ [0, 11, 11, 2, 9, 5, 5, 4],
51254
+ [0, 5, 5, 4, 1, 5, 11, 2],
51255
+ [1, 5, 5, 2, 5, 8, 8, 2, 11, 2, 5, 4],
51256
+ [10, 3, 11, 10, 10, 1, 9, 5, 5, 4],
51257
+ [9, 5, 5, 4, 8, 1, 8, 10, 10, 1, 11, 10],
51258
+ [5, 4, 0, 5, 0, 11, 11, 5, 11, 10, 10, 5],
51259
+ [5, 4, 8, 5, 8, 10, 10, 5, 11, 10],
51260
+ [9, 7, 5, 7, 9, 5],
51261
+ [9, 3, 9, 5, 5, 3, 5, 7],
51262
+ [0, 7, 1, 7, 1, 5, 5, 7],
51263
+ [1, 5, 5, 3, 5, 7],
51264
+ [9, 7, 9, 5, 5, 7, 10, 1, 2, 10],
51265
+ [10, 1, 2, 10, 9, 5, 5, 0, 5, 3, 5, 7],
51266
+ [2, 8, 2, 5, 5, 8, 5, 7, 10, 5, 2, 10],
51267
+ [2, 10, 10, 5, 5, 2, 5, 3, 5, 7],
51268
+ [7, 9, 9, 5, 5, 7, 11, 2],
51269
+ [9, 5, 5, 7, 7, 9, 7, 2, 2, 9, 11, 2],
51270
+ [11, 2, 1, 8, 1, 7, 1, 5, 5, 7],
51271
+ [11, 2, 1, 11, 1, 7, 1, 5, 5, 7],
51272
+ [9, 5, 5, 8, 5, 7, 10, 1, 3, 10, 11, 10],
51273
+ [5, 7, 7, 0, 0, 5, 9, 5, 11, 0, 0, 10, 10, 1, 11, 10],
51274
+ [11, 10, 10, 0, 0, 11, 10, 5, 5, 0, 0, 7, 5, 7],
51275
+ [11, 10, 10, 5, 5, 11, 5, 7],
51276
+ [10, 6, 6, 5, 5, 10],
51277
+ [5, 10, 10, 6, 6, 5],
51278
+ [1, 9, 5, 10, 10, 6, 6, 5],
51279
+ [1, 8, 1, 9, 5, 10, 10, 6, 6, 5],
51280
+ [1, 6, 6, 5, 5, 1, 2, 6],
51281
+ [1, 6, 6, 5, 5, 1, 2, 6],
51282
+ [9, 6, 6, 5, 5, 9, 0, 6, 2, 6],
51283
+ [5, 9, 8, 5, 8, 2, 2, 5, 2, 6, 6, 5],
51284
+ [11, 2, 10, 6, 6, 5, 5, 10],
51285
+ [11, 0, 11, 2, 10, 6, 6, 5, 5, 10],
51286
+ [1, 9, 11, 2, 5, 10, 10, 6, 6, 5],
51287
+ [5, 10, 10, 6, 6, 5, 1, 9, 9, 2, 9, 11, 11, 2],
51288
+ [6, 3, 11, 6, 6, 5, 5, 3, 5, 1],
51289
+ [11, 0, 11, 5, 5, 0, 5, 1, 11, 6, 6, 5],
51290
+ [11, 6, 6, 3, 6, 0, 6, 5, 5, 0, 5, 9],
51291
+ [6, 5, 5, 9, 9, 6, 9, 11, 11, 6],
51292
+ [5, 10, 10, 6, 6, 5, 4, 7],
51293
+ [4, 3, 4, 7, 6, 5, 5, 10, 10, 6],
51294
+ [1, 9, 5, 10, 10, 6, 6, 5, 4, 7],
51295
+ [10, 6, 6, 5, 5, 10, 1, 9, 9, 7, 7, 1, 4, 7],
51296
+ [6, 1, 2, 6, 6, 5, 5, 1, 4, 7],
51297
+ [2, 5, 5, 1, 2, 6, 6, 5, 4, 3, 4, 7],
51298
+ [4, 7, 0, 5, 5, 9, 0, 6, 6, 5, 2, 6],
51299
+ [3, 9, 9, 7, 4, 7, 2, 9, 5, 9, 9, 6, 6, 5, 2, 6],
51300
+ [11, 2, 4, 7, 10, 6, 6, 5, 5, 10],
51301
+ [5, 10, 10, 6, 6, 5, 4, 7, 7, 2, 2, 4, 11, 2],
51302
+ [1, 9, 4, 7, 11, 2, 5, 10, 10, 6, 6, 5],
51303
+ [9, 2, 1, 9, 9, 11, 11, 2, 4, 11, 4, 7, 5, 10, 10, 6, 6, 5],
51304
+ [4, 7, 11, 5, 5, 3, 5, 1, 11, 6, 6, 5],
51305
+ [5, 1, 1, 11, 11, 5, 11, 6, 6, 5, 0, 11, 11, 4, 4, 7],
51306
+ [0, 5, 5, 9, 0, 6, 6, 5, 3, 6, 11, 6, 4, 7],
51307
+ [6, 5, 5, 9, 9, 6, 9, 11, 11, 6, 4, 7, 7, 9],
51308
+ [10, 4, 9, 10, 6, 4, 10, 6],
51309
+ [4, 10, 10, 6, 6, 4, 9, 10],
51310
+ [10, 0, 1, 10, 10, 6, 6, 0, 6, 4],
51311
+ [1, 8, 1, 6, 6, 8, 6, 4, 1, 10, 10, 6],
51312
+ [1, 4, 9, 1, 2, 4, 2, 6, 6, 4],
51313
+ [2, 9, 9, 1, 2, 4, 2, 6, 6, 4],
51314
+ [2, 4, 2, 6, 6, 4],
51315
+ [2, 8, 2, 4, 2, 6, 6, 4],
51316
+ [10, 4, 9, 10, 10, 6, 6, 4, 11, 2],
51317
+ [8, 2, 11, 2, 9, 10, 10, 4, 10, 6, 6, 4],
51318
+ [11, 2, 1, 6, 6, 0, 6, 4, 1, 10, 10, 6],
51319
+ [6, 4, 4, 1, 1, 6, 1, 10, 10, 6, 8, 1, 1, 11, 11, 2],
51320
+ [9, 6, 6, 4, 9, 3, 3, 6, 9, 1, 11, 6],
51321
+ [11, 1, 1, 8, 11, 6, 6, 1, 9, 1, 1, 4, 6, 4],
51322
+ [11, 6, 6, 3, 6, 0, 6, 4],
51323
+ [6, 4, 8, 6, 11, 6],
51324
+ [7, 10, 10, 6, 6, 7, 8, 10, 9, 10],
51325
+ [0, 7, 0, 10, 10, 7, 9, 10, 6, 7, 10, 6],
51326
+ [10, 6, 6, 7, 7, 10, 1, 10, 7, 1, 8, 1],
51327
+ [10, 6, 6, 7, 7, 10, 7, 1, 1, 10],
51328
+ [2, 6, 6, 1, 6, 8, 8, 1, 9, 1, 6, 7],
51329
+ [2, 6, 6, 9, 9, 2, 9, 1, 6, 7, 7, 9, 9, 3],
51330
+ [0, 7, 0, 6, 6, 7, 2, 6],
51331
+ [2, 7, 6, 7, 2, 6],
51332
+ [11, 2, 10, 6, 6, 8, 8, 10, 9, 10, 6, 7],
51333
+ [0, 7, 7, 2, 11, 2, 9, 7, 6, 7, 7, 10, 10, 6, 9, 10],
51334
+ [1, 8, 1, 7, 1, 10, 10, 7, 6, 7, 10, 6, 11, 2],
51335
+ [11, 2, 1, 11, 1, 7, 10, 6, 6, 1, 1, 10, 6, 7],
51336
+ [9, 6, 6, 8, 6, 7, 9, 1, 1, 6, 11, 6, 6, 3],
51337
+ [9, 1, 11, 6, 6, 7],
51338
+ [0, 7, 0, 6, 6, 7, 11, 0, 11, 6],
51339
+ [11, 6, 6, 7],
51340
+ [7, 6, 6, 11],
51341
+ [7, 6, 6, 11],
51342
+ [1, 9, 7, 6, 6, 11],
51343
+ [8, 1, 1, 9, 7, 6, 6, 11],
51344
+ [10, 1, 2, 10, 6, 11, 7, 6],
51345
+ [2, 10, 10, 1, 6, 11, 7, 6],
51346
+ [2, 9, 2, 10, 10, 9, 6, 11, 7, 6],
51347
+ [6, 11, 7, 6, 2, 10, 10, 3, 10, 8, 10, 9],
51348
+ [7, 2, 6, 2, 7, 6],
51349
+ [7, 0, 7, 6, 6, 0, 6, 2],
51350
+ [2, 7, 7, 6, 6, 2, 1, 9],
51351
+ [1, 6, 6, 2, 1, 8, 8, 6, 1, 9, 7, 6],
51352
+ [10, 7, 7, 6, 6, 10, 10, 1, 1, 7],
51353
+ [10, 7, 7, 6, 6, 10, 1, 7, 10, 1, 1, 8],
51354
+ [7, 0, 7, 10, 10, 0, 10, 9, 6, 10, 7, 6],
51355
+ [7, 6, 6, 10, 10, 7, 10, 8, 10, 9],
51356
+ [6, 8, 4, 6, 6, 11],
51357
+ [3, 6, 6, 11, 0, 6, 4, 6],
51358
+ [8, 6, 6, 11, 4, 6, 1, 9],
51359
+ [4, 6, 6, 9, 6, 3, 3, 9, 1, 9, 6, 11],
51360
+ [6, 8, 4, 6, 6, 11, 2, 10, 10, 1],
51361
+ [2, 10, 10, 1, 0, 11, 0, 6, 6, 11, 4, 6],
51362
+ [4, 11, 4, 6, 6, 11, 2, 9, 2, 10, 10, 9],
51363
+ [10, 9, 9, 3, 3, 10, 2, 10, 4, 3, 3, 6, 6, 11, 4, 6],
51364
+ [8, 2, 4, 2, 4, 6, 6, 2],
51365
+ [4, 2, 4, 6, 6, 2],
51366
+ [1, 9, 3, 4, 4, 2, 4, 6, 6, 2],
51367
+ [1, 9, 4, 1, 4, 2, 4, 6, 6, 2],
51368
+ [8, 1, 8, 6, 6, 1, 4, 6, 6, 10, 10, 1],
51369
+ [10, 1, 0, 10, 0, 6, 6, 10, 4, 6],
51370
+ [4, 6, 6, 3, 3, 4, 6, 10, 10, 3, 3, 9, 10, 9],
51371
+ [10, 9, 4, 10, 6, 10, 4, 6],
51372
+ [9, 5, 5, 4, 7, 6, 6, 11],
51373
+ [9, 5, 5, 4, 7, 6, 6, 11],
51374
+ [5, 0, 1, 5, 5, 4, 7, 6, 6, 11],
51375
+ [7, 6, 6, 11, 3, 4, 3, 5, 5, 4, 1, 5],
51376
+ [9, 5, 5, 4, 10, 1, 2, 10, 7, 6, 6, 11],
51377
+ [6, 11, 7, 6, 2, 10, 10, 1, 9, 5, 5, 4],
51378
+ [7, 6, 6, 11, 5, 4, 4, 10, 10, 5, 4, 2, 2, 10],
51379
+ [3, 4, 3, 5, 5, 4, 2, 5, 10, 5, 2, 10, 7, 6, 6, 11],
51380
+ [7, 2, 7, 6, 6, 2, 5, 4, 9, 5],
51381
+ [9, 5, 5, 4, 8, 6, 6, 0, 6, 2, 7, 6],
51382
+ [3, 6, 6, 2, 7, 6, 1, 5, 5, 0, 5, 4],
51383
+ [6, 2, 2, 8, 8, 6, 7, 6, 1, 8, 8, 5, 5, 4, 1, 5],
51384
+ [9, 5, 5, 4, 10, 1, 1, 6, 6, 10, 1, 7, 7, 6],
51385
+ [1, 6, 6, 10, 10, 1, 1, 7, 7, 6, 0, 7, 9, 5, 5, 4],
51386
+ [0, 10, 10, 4, 10, 5, 5, 4, 3, 10, 6, 10, 10, 7, 7, 6],
51387
+ [7, 6, 6, 10, 10, 7, 10, 8, 5, 4, 4, 10, 10, 5],
51388
+ [6, 9, 9, 5, 5, 6, 6, 11, 11, 9],
51389
+ [3, 6, 6, 11, 0, 6, 0, 5, 5, 6, 9, 5],
51390
+ [0, 11, 0, 5, 5, 11, 1, 5, 5, 6, 6, 11],
51391
+ [6, 11, 3, 6, 3, 5, 5, 6, 1, 5],
51392
+ [2, 10, 10, 1, 9, 5, 5, 11, 11, 9, 5, 6, 6, 11],
51393
+ [0, 11, 0, 6, 6, 11, 9, 6, 5, 6, 9, 5, 2, 10, 10, 1],
51394
+ [8, 5, 5, 11, 5, 6, 6, 11, 0, 5, 10, 5, 5, 2, 2, 10],
51395
+ [6, 11, 3, 6, 3, 5, 5, 6, 2, 10, 10, 3, 10, 5],
51396
+ [5, 8, 9, 5, 5, 2, 2, 8, 5, 6, 6, 2],
51397
+ [9, 5, 5, 6, 6, 9, 6, 0, 6, 2],
51398
+ [1, 5, 5, 8, 8, 1, 5, 6, 6, 8, 8, 2, 6, 2],
51399
+ [1, 5, 5, 6, 6, 1, 6, 2],
51400
+ [3, 6, 6, 1, 6, 10, 10, 1, 8, 6, 5, 6, 6, 9, 9, 5],
51401
+ [10, 1, 0, 10, 0, 6, 6, 10, 9, 5, 5, 0, 5, 6],
51402
+ [5, 6, 6, 10, 10, 5],
51403
+ [10, 5, 5, 6, 6, 10],
51404
+ [11, 5, 5, 10, 10, 11, 7, 5],
51405
+ [11, 5, 5, 10, 10, 11, 7, 5],
51406
+ [5, 11, 7, 5, 5, 10, 10, 11, 1, 9],
51407
+ [10, 7, 7, 5, 5, 10, 10, 11, 8, 1, 1, 9],
51408
+ [11, 1, 2, 11, 7, 1, 7, 5, 5, 1],
51409
+ [2, 7, 7, 1, 7, 5, 5, 1, 2, 11],
51410
+ [9, 7, 7, 5, 5, 9, 9, 2, 2, 7, 2, 11],
51411
+ [7, 5, 5, 2, 2, 7, 2, 11, 5, 9, 9, 2, 2, 8],
51412
+ [2, 5, 5, 10, 10, 2, 3, 5, 7, 5],
51413
+ [8, 2, 8, 5, 5, 2, 7, 5, 10, 2, 5, 10],
51414
+ [1, 9, 5, 10, 10, 3, 3, 5, 7, 5, 10, 2],
51415
+ [8, 2, 2, 9, 1, 9, 7, 2, 10, 2, 2, 5, 5, 10, 7, 5],
51416
+ [3, 5, 5, 1, 7, 5],
51417
+ [7, 0, 7, 1, 7, 5, 5, 1],
51418
+ [3, 9, 3, 5, 5, 9, 7, 5],
51419
+ [7, 9, 5, 9, 7, 5],
51420
+ [5, 8, 4, 5, 5, 10, 10, 8, 10, 11],
51421
+ [5, 0, 4, 5, 5, 11, 11, 0, 5, 10, 10, 11],
51422
+ [1, 9, 4, 10, 10, 8, 10, 11, 4, 5, 5, 10],
51423
+ [10, 11, 11, 4, 4, 10, 4, 5, 5, 10, 3, 4, 4, 1, 1, 9],
51424
+ [2, 5, 5, 1, 2, 8, 8, 5, 2, 11, 4, 5],
51425
+ [4, 11, 11, 0, 4, 5, 5, 11, 2, 11, 11, 1, 5, 1],
51426
+ [2, 5, 5, 0, 5, 9, 2, 11, 11, 5, 4, 5, 5, 8],
51427
+ [4, 5, 5, 9, 2, 11],
51428
+ [2, 5, 5, 10, 10, 2, 3, 5, 3, 4, 4, 5],
51429
+ [5, 10, 10, 2, 2, 5, 2, 4, 4, 5],
51430
+ [3, 10, 10, 2, 3, 5, 5, 10, 8, 5, 4, 5, 1, 9],
51431
+ [5, 10, 10, 2, 2, 5, 2, 4, 4, 5, 1, 9, 9, 2],
51432
+ [4, 5, 5, 8, 5, 3, 5, 1],
51433
+ [4, 5, 5, 0, 5, 1],
51434
+ [4, 5, 5, 8, 5, 3, 0, 5, 5, 9],
51435
+ [4, 5, 5, 9],
51436
+ [4, 11, 7, 4, 9, 11, 9, 10, 10, 11],
51437
+ [9, 7, 7, 4, 9, 11, 9, 10, 10, 11],
51438
+ [1, 10, 10, 11, 11, 1, 11, 4, 4, 1, 7, 4],
51439
+ [1, 4, 4, 3, 1, 10, 10, 4, 7, 4, 4, 11, 10, 11],
51440
+ [4, 11, 7, 4, 9, 11, 9, 2, 2, 11, 9, 1],
51441
+ [9, 7, 7, 4, 9, 11, 9, 1, 1, 11, 2, 11],
51442
+ [7, 4, 4, 11, 4, 2, 2, 11],
51443
+ [7, 4, 4, 11, 4, 2, 2, 11, 3, 4],
51444
+ [2, 9, 9, 10, 10, 2, 2, 7, 7, 9, 7, 4],
51445
+ [9, 10, 10, 7, 7, 9, 7, 4, 10, 2, 2, 7, 7, 0],
51446
+ [7, 10, 10, 3, 10, 2, 7, 4, 4, 10, 1, 10, 10, 0],
51447
+ [1, 10, 10, 2, 7, 4],
51448
+ [9, 1, 1, 4, 1, 7, 7, 4],
51449
+ [9, 1, 1, 4, 1, 7, 7, 4, 8, 1],
51450
+ [3, 4, 7, 4],
51451
+ [7, 4],
51452
+ [9, 10, 10, 8, 10, 11],
51453
+ [9, 3, 9, 11, 9, 10, 10, 11],
51454
+ [1, 10, 10, 0, 10, 8, 10, 11],
51455
+ [1, 10, 10, 3, 10, 11],
51456
+ [2, 11, 11, 1, 11, 9, 9, 1],
51457
+ [9, 3, 9, 11, 2, 9, 9, 1, 2, 11],
51458
+ [2, 11, 11, 0],
51459
+ [2, 11],
51460
+ [8, 2, 8, 10, 10, 2, 9, 10],
51461
+ [9, 10, 10, 2, 2, 9],
51462
+ [8, 2, 8, 10, 10, 2, 1, 8, 1, 10],
51463
+ [1, 10, 10, 2],
51464
+ [8, 1, 9, 1],
51465
+ [9, 1],
51466
+ [],
51467
+ []];
51468
+
51469
+ const snap = (method === 'snapped MC');
51470
+ // const seg_table = (method === 'squarish' ? segTable2 : segTable);
51471
+ const seg_table = segTable;
51472
+
51473
+ let vlist = new Array(12);
51474
+ const vert_offsets = this.calculateVertOffsets(dims);
51475
+
51476
+ const edgeIndex = [[0,1], [1,2], [2,3], [3,0], [4,5], [5,6],
51477
+ [6,7], [7,4], [0,4], [1,5], [2,6], [3,7]];
51478
+
51479
+ let vertex_values = new Float32Array(8);
51480
+ let p0 = [0, 0, 0]; // unused initial value - to make Flow happy
51481
+ let vertex_points = [p0, p0, p0, p0, p0, p0, p0, p0];
51482
+ const size_x = dims[0];
51483
+ const size_y = dims[1];
51484
+ const size_z = dims[2];
51485
+ if (values == null || points == null) return;
51486
+ let vertices = [];
51487
+ let segments = [];
51488
+ let vertex_count = 0;
51489
+ for (let x = 0; x < size_x - 1; x++) {
51490
+ for (let y = 0; y < size_y - 1; y++) {
51491
+ for (let z = 0; z < size_z - 1; z++) {
51492
+ const offset0 = z + size_z * (y + size_y * x);
51493
+ let cubeindex = 0;
51494
+ let i;
51495
+ let j;
51496
+ for (i = 0; i < 8; ++i) {
51497
+ j = offset0 + vert_offsets[i];
51498
+ cubeindex |= (values[j] < isolevel) ? 1 << i : 0;
51499
+ }
51500
+ if (cubeindex === 0 || cubeindex === 255) continue;
51501
+ for (i = 0; i < 8; ++i) {
51502
+ j = offset0 + vert_offsets[i];
51503
+ vertex_values[i] = values[j];
51504
+ vertex_points[i] = points[j];
51505
+ }
51506
+
51507
+ // 12 bit number, indicates which edges are crossed by the isosurface
51508
+ const edge_mask = edgeTable[cubeindex];
51509
+
51510
+ // check which edges are crossed, and estimate the point location
51511
+ // using a weighted average of scalar values at edge endpoints.
51512
+ for (i = 0; i < 12; ++i) {
51513
+ if ((edge_mask & (1 << i)) !== 0) {
51514
+ const e = edgeIndex[i];
51515
+ let mu = (isolevel - vertex_values[e[0]]) /
51516
+ (vertex_values[e[1]] - vertex_values[e[0]]);
51517
+ if (snap === true) {
51518
+ if (mu > 0.85) mu = 1;
51519
+ else if (mu < 0.15) mu = 0;
51520
+ }
51521
+ const p1 = vertex_points[e[0]];
51522
+ const p2 = vertex_points[e[1]];
51523
+ // The number of added vertices could be roughly halved
51524
+ // if we avoided duplicates between neighbouring cells.
51525
+ // Using a map for lookups is too slow, perhaps a big
51526
+ // array would do?
51527
+ vertices.push(p1[0] + (p2[0] - p1[0]) * mu,
51528
+ p1[1] + (p2[1] - p1[1]) * mu,
51529
+ p1[2] + (p2[2] - p1[2]) * mu);
51530
+ vlist[i] = vertex_count++;
51531
+ }
51532
+ }
51533
+ const t = seg_table[cubeindex];
51534
+ for (i = 0; i < t.length; i++) {
51535
+ segments.push(vlist[t[i]]);
51536
+ }
51537
+ }
51538
+ }
51539
+ }
51540
+
51541
+ return { vertices: vertices, segments: segments };
51542
+ }
51543
+
51544
+ // return offsets relative to vertex [0,0,0]
51545
+ calculateVertOffsets(dims) { let ic = this.icn3d; ic.icn3dui;
51546
+ let vert_offsets = [];
51547
+ const cubeVerts = [[0,0,0], [1,0,0], [1,1,0], [0,1,0],
51548
+ [0,0,1], [1,0,1], [1,1,1], [0,1,1]];
51549
+
51550
+ for (let i = 0; i < 8; ++i) {
51551
+ const v = cubeVerts[i];
51552
+ vert_offsets.push(v[0] + dims[2] * (v[1] + dims[1] * v[2]));
51553
+ }
51554
+ return vert_offsets;
51555
+ }
51556
+
51557
+ makeChickenWire(data, typeDetail) { let ic = this.icn3d, me = ic.icn3dui;
51558
+ let geom = new THREE.BufferGeometry();
51559
+ let position = new Float32Array(data.vertices);
51560
+ geom.setAttribute('position', new THREE.BufferAttribute(position, 3));
51561
+
51562
+ // Although almost all browsers support OES_element_index_uint nowadays,
51563
+ // use Uint32 indexes only when needed.
51564
+ let arr = (data.vertices.length < 3*65536 ? new Uint16Array(data.segments) : new Uint32Array(data.segments));
51565
+
51566
+ geom.setIndex(new THREE.BufferAttribute(arr, 1));
51567
+
51568
+ let colorFor2fofc = me.parasCls.thr('#00FFFF');
51569
+ let colorForfofcPos = me.parasCls.thr('#00FF00');
51570
+ let colorForfofcNeg = me.parasCls.thr('#ff0000');
51571
+
51572
+ let color = (typeDetail == '2fofc') ? colorFor2fofc : ((typeDetail == 'fofc_pos') ? colorForfofcPos : colorForfofcNeg);
51573
+ let material = new THREE.LineBasicMaterial({ linewidth: 1, color: color });
51574
+ //return new THREE.LineSegments(geom, material);
51575
+
51576
+ let mesh = new THREE.LineSegments(geom, material);
51577
+ ic.mdl.add(mesh);
51578
+
51579
+ ic.prevMaps.push(mesh);
51580
+ }
51581
+ }
51582
+
51583
+
51584
+ class UnitCell {
51585
+ /*::
51586
+ parameters: number[]
51587
+ orth: number[]
51588
+ frac: number[]
51589
+ */
51590
+ // eslint-disable-next-line max-params
51591
+ constructor(a /*:number*/, b /*:number*/, c /*:number*/,
51592
+ alpha /*:number*/, beta /*:number*/, gamma /*:number*/) {
51593
+ if (a <= 0 || b <= 0 || c <= 0 || alpha <= 0 || beta <= 0 || gamma <= 0) {
51594
+ throw Error('Zero or negative unit cell parameter(s).');
51595
+ }
51596
+ this.parameters = [a, b, c, alpha, beta, gamma];
51597
+ const deg2rad = Math.PI / 180.0;
51598
+ const cos_alpha = Math.cos(deg2rad * alpha);
51599
+ const cos_beta = Math.cos(deg2rad * beta);
51600
+ const cos_gamma = Math.cos(deg2rad * gamma);
51601
+ const sin_alpha = Math.sin(deg2rad * alpha);
51602
+ const sin_beta = Math.sin(deg2rad * beta);
51603
+ const sin_gamma = Math.sin(deg2rad * gamma);
51604
+ if (sin_alpha === 0 || sin_beta === 0 || sin_gamma === 0) {
51605
+ throw Error('Impossible angle - N*180deg.');
51606
+ }
51607
+ const cos_alpha_star_sin_beta = (cos_beta * cos_gamma - cos_alpha) /
51608
+ sin_gamma;
51609
+ const cos_alpha_star = cos_alpha_star_sin_beta / sin_beta;
51610
+ const s1rca2 = Math.sqrt(1.0 - cos_alpha_star * cos_alpha_star);
51611
+ // The orthogonalization matrix we use is described in ITfC B p.262:
51612
+ // "An alternative mode of orthogonalization, used by the Protein
51613
+ // Data Bank and most programs, is to align the a1 axis of the unit
51614
+ // cell with the Cartesian X_1 axis, and to align the a*_3 axis with the
51615
+ // Cartesian X_3 axis."
51616
+ //
51617
+ // Zeros in the matrices below are kept to make matrix multiplication
51618
+ // faster: they make extract_block() 2x (!) faster on V8 4.5.103,
51619
+ // no difference on FF 50.
51620
+ /* eslint-disable no-multi-spaces, comma-spacing */
51621
+ this.orth = [a, b * cos_gamma, c * cos_beta,
51622
+ 0.0, b * sin_gamma, -c * cos_alpha_star_sin_beta,
51623
+ 0.0, 0.0 , c * sin_beta * s1rca2];
51624
+ // based on xtal.js which is based on cctbx.uctbx
51625
+ this.frac = [
51626
+ 1.0 / a,
51627
+ -cos_gamma / (sin_gamma * a),
51628
+ -(cos_gamma * cos_alpha_star_sin_beta + cos_beta * sin_gamma) /
51629
+ (sin_beta * s1rca2 * sin_gamma * a),
51630
+ 0.0,
51631
+ 1.0 / (sin_gamma * b),
51632
+ cos_alpha_star / (s1rca2 * sin_gamma * b),
51633
+ 0.0,
51634
+ 0.0,
51635
+ 1.0 / (sin_beta * s1rca2 * c),
51636
+ ];
51637
+ }
51638
+
51639
+ // This function is only used with matrices frac and orth, which have 3 zeros.
51640
+ // We skip these elements, but it doesn't affect performance (on FF50 and V8).
51641
+ multiply(xyz, mat) {
51642
+ /* eslint-disable indent */
51643
+ return [mat[0] * xyz[0] + mat[1] * xyz[1] + mat[2] * xyz[2],
51644
+ /*mat[3] * xyz[0]*/+ mat[4] * xyz[1] + mat[5] * xyz[2],
51645
+ /*mat[6] * xyz[0] + mat[7] * xyz[1]*/+ mat[8] * xyz[2]];
51646
+ }
51647
+
51648
+ fractionalize(xyz /*:[number,number,number]*/) {
51649
+ return this.multiply(xyz, this.frac);
51650
+ }
51651
+
51652
+ orthogonalize(xyz /*:[number,number,number]*/) {
51653
+ return this.multiply(xyz, this.orth);
51654
+ }
51655
+ }
51656
+
51657
+
51658
+ class GridArray {
51659
+ /*::
51660
+ dim: number[]
51661
+ values: Float32Array
51662
+ */
51663
+ constructor(dim /*:number[]*/) {
51664
+ this.dim = dim; // dimensions of the grid for the entire unit cell
51665
+ this.values = new Float32Array(dim[0] * dim[1] * dim[2]);
51666
+ }
51667
+
51668
+ modulo(a, b) {
51669
+ const reminder = a % b;
51670
+ return reminder >= 0 ? reminder : reminder + b;
51671
+ }
51672
+
51673
+ grid2index(i/*:number*/, j/*:number*/, k/*:number*/) {
51674
+ i = this.modulo(i, this.dim[0]);
51675
+ j = this.modulo(j, this.dim[1]);
51676
+ k = this.modulo(k, this.dim[2]);
51677
+ return this.dim[2] * (this.dim[1] * i + j) + k;
51678
+ }
51679
+
51680
+ grid2index_unchecked(i/*:number*/, j/*:number*/, k/*:number*/) {
51681
+ return this.dim[2] * (this.dim[1] * i + j) + k;
51682
+ }
51683
+
51684
+ grid2frac(i/*:number*/, j/*:number*/, k/*:number*/) {
51685
+ return [i / this.dim[0], j / this.dim[1], k / this.dim[2]];
51686
+ }
51687
+
51688
+ // return grid coordinates (rounded down) for the given fractional coordinates
51689
+ frac2grid(xyz/*:number[]*/) {
51690
+ // at one point "| 0" here made extract_block() 40% faster on V8 3.14,
51691
+ // but I don't see any effect now
51692
+ return [Math.floor(xyz[0] * this.dim[0]) | 0,
51693
+ Math.floor(xyz[1] * this.dim[1]) | 0,
51694
+ Math.floor(xyz[2] * this.dim[2]) | 0];
51695
+ }
51696
+
51697
+ set_grid_value(i/*:number*/, j/*:number*/, k/*:number*/, value/*:number*/) {
51698
+ const idx = this.grid2index(i, j, k);
51699
+ this.values[idx] = value;
51700
+ }
51701
+
51702
+ get_grid_value(i/*:number*/, j/*:number*/, k/*:number*/) {
51703
+ const idx = this.grid2index(i, j, k);
51704
+ return this.values[idx];
51705
+ }
51706
+ }
51707
+
51708
+ /**
51709
+ * @file Mtz Parser
51710
+ * @author Marcin Wojdyr <wojdyr@gmail.com>
51711
+ * @private
51712
+ * Modified by Jiyao Wang / https://github.com/ncbi/icn3d
51713
+ */
51714
+
51715
+ class MtzParser {
51716
+ constructor(icn3d) {
51717
+ this.icn3d = icn3d;
51718
+ }
51719
+
51720
+ async mtzParserBase(url, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
51721
+ let thisClass = this;
51722
+
51723
+ //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
51724
+ // if(type == '2fofc' && ic.bAjax2fofcccp4) {
51725
+ // ic.mapData.sigma2 = sigma;
51726
+ // ic.setOptionCls.setOption('map', type);
51727
+ // }
51728
+ // else if(type == 'fofc' && ic.bAjaxfofcccp4) {
51729
+ // ic.mapData.sigma = sigma;
51730
+ // ic.setOptionCls.setOption('map', type);
51731
+ // }
51732
+ // else {
51733
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', '');
51734
+ sigma = await thisClass.loadMtzFileBase(arrayBuffer, type, sigma, location, bInputSigma, url);
51735
+
51736
+ // if(type == '2fofc') {
51737
+ // ic.bAjax2fofcccp4 = true;
51738
+ // }
51739
+ // else if(type == 'fofc') {
51740
+ // ic.bAjaxfofcccp4 = true;
51741
+ // }
51742
+
51743
+ ic.setOptionCls.setOption('map', type);
51744
+
51745
+ return sigma;
51746
+ // }
51747
+ }
51748
+
51749
+ loadMtzFile(type) {var ic = this.icn3d, me = ic.icn3dui;
51750
+ let thisClass = this;
51751
+
51752
+ let file = $("#" + ic.pre + "dsn6file" + type)[0].files[0];
51753
+ let sigma = $("#" + ic.pre + "dsn6sigma" + type).val();
51754
+ if(!file) {
51755
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
51756
+ }
51757
+ else {
51758
+ me.utilsCls.checkFileAPI();
51759
+ let reader = new FileReader();
51760
+ reader.onload = async function(e) { let ic = thisClass.icn3d;
51761
+ sigma = await thisClass.loadMtzFileBase(e.target.result, type, sigma, 'file');
51762
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
51763
+ };
51764
+ reader.readAsArrayBuffer(file);
51765
+ }
51766
+ }
51767
+
51768
+ async loadMtzFileBase(data, type, sigma, location, bInputSigma, url) {var ic = this.icn3d, me = ic.icn3dui;
51769
+ if(ic.bMtz === undefined) {
51770
+ let url = "./script/mtz.js";
51771
+ await me.getAjaxPromise(url, 'script');
51772
+
51773
+ ic.bMtz = true;
51774
+ }
51775
+
51776
+ GemmiMtz().then(function(Gemmi) {
51777
+ let mtz = Gemmi.readMtz(data);
51778
+
51779
+ sigma = ic.ccp4ParserCls.load_maps_from_mtz_buffer(mtz, type, sigma, location, bInputSigma);
51780
+
51781
+ // if(type == '2fofc') {
51782
+ // ic.bAjax2fofcCcp4 = true;
51783
+ // }
51784
+ // else if(type == 'fofc') {
51785
+ // ic.bAjaxfofcCcp4 = true;
51786
+ // }
51787
+ ic.setOptionCls.setOption('map', type);
51788
+ if(url) me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file mtz | ' + encodeURIComponent(url), true);
51789
+
51790
+ return sigma;
51791
+ });
51792
+ }
51793
+
51794
+ async loadMtzFileUrl(type) {var ic = this.icn3d; ic.icn3dui;
51795
+ let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
51796
+ let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
51797
+ if(!url) {
51798
+ var aaa = 1; //alert("Please input the file URL before clicking 'Load'");
51799
+ }
51800
+ else {
51801
+ sigma = await this.mtzParserBase(url, type, sigma, 'url');
51802
+
51803
+ //me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file mtz | ' + encodeURIComponent(url), true);
50540
51804
  }
50541
51805
  }
50542
51806
 
@@ -53308,7 +54572,7 @@ class DensityCifParser {
53308
54572
  this.icn3d = icn3d;
53309
54573
  }
53310
54574
 
53311
- async densityCifParser(pdbid, type, sigma, emd) { let ic = this.icn3d, me = ic.icn3dui;
54575
+ async densityCifParser(pdbid, type, sigma, emd, bOutput) { let ic = this.icn3d, me = ic.icn3dui;
53312
54576
  let thisClass = this;
53313
54577
 
53314
54578
  let url;
@@ -53370,6 +54634,9 @@ class DensityCifParser {
53370
54634
  ic.mapData.header2 = header;
53371
54635
 
53372
54636
  ic.mapData.data2 = density.data;
54637
+ for(let i = 0; i < density.data.length; ++i) {
54638
+ density.data[i];
54639
+ }
53373
54640
 
53374
54641
  let origin = density.box.origin;
53375
54642
  let dimensions = density.box.dimensions;
@@ -53404,6 +54671,7 @@ class DensityCifParser {
53404
54671
  origin = density.box.origin;
53405
54672
  dimensions = density.box.dimensions;
53406
54673
  basis = density.spacegroup.basis;
54674
+
53407
54675
  scale = new THREE.Matrix4().makeScale(
53408
54676
  dimensions[0] / (sampleCount[0] ),
53409
54677
  dimensions[1] / (sampleCount[1] ),
@@ -55032,7 +56300,10 @@ class ParserUtils {
55032
56300
 
55033
56301
  if(bAppend) {
55034
56302
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
55035
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
56303
+ if(ic.bAnnoShown) {
56304
+ await ic.showAnnoCls.showAnnotations();
56305
+ ic.annotationCls.resetAnnoTabAll();
56306
+ }
55036
56307
  }
55037
56308
 
55038
56309
  // Realign by sequence alignment with the residues in "segment", i.e., transmembrane helix
@@ -55223,7 +56494,7 @@ class LoadAtomData {
55223
56494
  if(!bTitle) ic.molTitle = '';
55224
56495
  }
55225
56496
  else { // mmdbid or mmcifid
55226
- if(data.descr !== undefined) ic.molTitle += data.descr.name;
56497
+ if(data.descr !== undefined) ic.molTitle = data.descr.name;
55227
56498
  if(type === 'mmdbid') {
55228
56499
  let pdbidTmp = (isNaN(id)) ? id : data.pdbId;
55229
56500
  let chainHash = {};
@@ -56362,12 +57633,12 @@ class SetSeqAlign {
56362
57633
 
56363
57634
  if(i > 0) {
56364
57635
  let index1 = alignIndex;
56365
-
57636
+
56366
57637
  for(let j = prevIndex1 + 1, jl = start1; j < jl; ++j) {
56367
- if(posChain1[j]) continue;
57638
+ //if(posChain1[j]) continue;
56368
57639
  posChain1[j] = 1;
56369
57640
 
56370
- if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
57641
+ //if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
56371
57642
 
56372
57643
  //let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
56373
57644
  let resi = this.getResiAferAlign(chainid1, bRealign, j);
@@ -56378,18 +57649,19 @@ class SetSeqAlign {
56378
57649
 
56379
57650
  color = me.htmlCls.GREY8;
56380
57651
  classname = 'icn3d-nalign';
56381
-
57652
+
56382
57653
  ic.nalignHash1[chainid1 + '_' + resi] = 1;
56383
57654
  this.setSeqPerResi(chainid1, chainid1, chainid2, resi, resn, false, color, undefined, classname, true, false, index1);
56384
57655
  ++index1;
56385
57656
  }
56386
57657
 
56387
57658
  let index2 = alignIndex;
57659
+
56388
57660
  for(let j = prevIndex2 + 1, jl = start2; j < jl; ++j) {
56389
- if(posChain2[j]) continue;
57661
+ //if(posChain2[j]) continue;
56390
57662
  posChain2[j] = 1;
56391
57663
 
56392
- if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57664
+ //if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
56393
57665
 
56394
57666
  //let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
56395
57667
  let resi = this.getResiAferAlign(chainid2, bRealign, j);
@@ -56435,7 +57707,7 @@ class SetSeqAlign {
56435
57707
  }
56436
57708
 
56437
57709
  for(let j = 0; j <= end1 - start1; ++j) {
56438
- if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57710
+ ///if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
56439
57711
 
56440
57712
  let resi1, resi2, resn1, resn2;
56441
57713
  /*
@@ -56465,15 +57737,17 @@ class SetSeqAlign {
56465
57737
  if(resn1 == '?' || resn2 == '?') continue;
56466
57738
  }
56467
57739
  else {
56468
- if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
57740
+ ///if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
56469
57741
 
56470
57742
  // resi1 = ic.chainsSeq[chainid1][j + start1].resi;
56471
57743
  // resi2 = ic.chainsSeq[chainid2][j + start2].resi;
56472
57744
  // resn1 = ic.chainsSeq[chainid1][j + start1].name.toUpperCase();
56473
57745
  // resn2 = ic.chainsSeq[chainid2][j + start2].name.toUpperCase();
56474
57746
 
56475
- resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
56476
- resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
57747
+ // resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
57748
+ // resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
57749
+ resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1);
57750
+ resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2);
56477
57751
  resn1 = this.getResnFromResi(chainid1, resi1).toUpperCase();
56478
57752
  resn2 = this.getResnFromResi(chainid2, resi2).toUpperCase();
56479
57753
  }
@@ -60851,7 +62125,7 @@ class DefinedSets {
60851
62125
  }
60852
62126
 
60853
62127
  //Set the menu of defined sets with an array of defined names "commandnameArray".
60854
- setAtomMenu(commandnameArray) { let ic = this.icn3d; ic.icn3dui;
62128
+ setAtomMenu(commandnameArray) { let ic = this.icn3d, me = ic.icn3dui;
60855
62129
  let html = "";
60856
62130
 
60857
62131
  let nameArray1 =(ic.defNames2Residues !== undefined) ? Object.keys(ic.defNames2Residues) : [];
@@ -60860,12 +62134,22 @@ class DefinedSets {
60860
62134
  let nameArrayTmp = nameArray1.concat(nameArray2).sort();
60861
62135
 
60862
62136
  let nameArray = [];
60863
- // $.each(nameArrayTmp, function(i, el){
60864
- // if($.inArray(el, nameArray) === -1) nameArray.push(el);
60865
- // });
60866
- nameArrayTmp.forEach(elem => {
60867
- if($.inArray(elem, nameArray) === -1) nameArray.push(elem);
60868
- });
62137
+ // $.each(nameArrayTmp, function(i, el){
62138
+ // if($.inArray(el, nameArray) === -1) nameArray.push(el);
62139
+ // });
62140
+ // nameArrayTmp.forEach(elem => {
62141
+ // if($.inArray(elem, nameArray) === -1) nameArray.push(elem);
62142
+ // });
62143
+
62144
+ let structureArray = Object.keys(me.utilsCls.getStructures(ic.dAtoms));
62145
+
62146
+ nameArrayTmp.forEach((elem) => {
62147
+ structureArray.forEach((structure) => {
62148
+ if (ic.defNames2Residues[elem][0].split("_")[0].includes(structure.split("_")[0])){
62149
+ if ($.inArray(elem, nameArray) === -1) nameArray.push(elem);
62150
+ }
62151
+ });
62152
+ });
60869
62153
 
60870
62154
  //for(let i in ic.defNames2Atoms) {
60871
62155
  for(let i = 0, il = nameArray.length; i < il; ++i) {
@@ -61431,6 +62715,124 @@ class DefinedSets {
61431
62715
 
61432
62716
  }
61433
62717
 
62718
+ class SelectCollections {
62719
+ constructor(icn3d) {
62720
+ this.icn3d = icn3d;
62721
+ }
62722
+
62723
+ //Set the menu of defined sets with an array of defined names "commandnameArray".
62724
+ setAtomMenu(nameArray, titleArray) {
62725
+ let ic = this.icn3d;
62726
+ ic.icn3dui;
62727
+ let html = "";
62728
+ let commandnameArray = [nameArray[0]];
62729
+ //for(let i in ic.defNames2Atoms) {
62730
+ for (let i = 0, il = nameArray.length; i < il; ++i) {
62731
+ let name = nameArray[i];
62732
+ let title = titleArray[i];
62733
+
62734
+ let atomHash;
62735
+ if (
62736
+ ic.defNames2Atoms !== undefined &&
62737
+ ic.defNames2Atoms.hasOwnProperty(name)
62738
+ ) {
62739
+ let atomArray = ic.defNames2Atoms[name];
62740
+
62741
+ if (atomArray.length > 0) ic.atoms[atomArray[0]];
62742
+ } else if (
62743
+ ic.defNames2Residues !== undefined &&
62744
+ ic.defNames2Residues.hasOwnProperty(name)
62745
+ ) {
62746
+ let residueArray = ic.defNames2Residues[name];
62747
+ if (residueArray.length > 0) {
62748
+ atomHash = ic.residues[residueArray[0]];
62749
+ if (atomHash) {
62750
+ ic.atoms[Object.keys(atomHash)[0]];
62751
+ }
62752
+ }
62753
+ }
62754
+
62755
+ if (commandnameArray.indexOf(name) != -1) {
62756
+ html +=
62757
+ "<option value='" +
62758
+ name +
62759
+ "' selected='selected'>" +
62760
+ title +
62761
+ "</option>";
62762
+ } else {
62763
+ html += "<option value='" + name + "'>" + title + "</option>";
62764
+ }
62765
+ }
62766
+
62767
+ return html;
62768
+ }
62769
+
62770
+ clickStructure() {
62771
+ let ic = this.icn3d,
62772
+ me = ic.icn3dui;
62773
+ let thisClass = this;
62774
+
62775
+ //me.myEventCls.onIds("#" + ic.pre + "atomsCustom", "change", function(e) { let ic = thisClass.icn3d;
62776
+ $("#" + ic.pre + "collections_menu").change(async function (e) {
62777
+ let ic = thisClass.icn3d;
62778
+ // ic.init()
62779
+ let nameArray = $(this).val();
62780
+ let nameStructure = $(this).find("option:selected").text();
62781
+
62782
+ ic.nameArray = nameArray;
62783
+ if (nameArray !== null) {
62784
+ ic.bShowHighlight = false;
62785
+ await ic.chainalignParserCls.downloadMmdbAf(nameArray.toString());
62786
+
62787
+ ic.dAtoms = {};
62788
+ ic.hAtoms = {};
62789
+ // ic.ssbondpnts = {};
62790
+ let chainIdHash = {};
62791
+
62792
+ for (const name in nameArray) {
62793
+ for (const key in ic.chains) {
62794
+ if (key.includes(nameArray[name])) {
62795
+ chainIdHash[key] = 1;
62796
+ if (ic.chains.hasOwnProperty(key)) {
62797
+ const innerDict = ic.chains[key];
62798
+ for (const innerKey in innerDict) {
62799
+ if (innerDict.hasOwnProperty(innerKey)) {
62800
+ ic.dAtoms[innerKey] = innerDict[innerKey];
62801
+ ic.hAtoms[innerKey] = innerDict[innerKey];
62802
+ }
62803
+ }
62804
+ }
62805
+ }
62806
+ }
62807
+ }
62808
+
62809
+ ic.transformCls.zoominSelection();
62810
+ ic.definedSetsCls.showSets();
62811
+
62812
+
62813
+ await ic.drawCls.draw();
62814
+ ic.saveFileCls.showTitle();
62815
+
62816
+ me.htmlCls.clickMenuCls.setLogCmd(
62817
+ "select structure " + "[" + nameStructure + "]",
62818
+ true
62819
+ );
62820
+ ic.bSelectResidue = false;
62821
+ }
62822
+ });
62823
+
62824
+ me.myEventCls.onIds(
62825
+ "#" + ic.pre + "collections_menu",
62826
+ "focus",
62827
+ function (e) {
62828
+ let ic = thisClass.icn3d;
62829
+ if (me.utilsCls.isMobile())
62830
+ $("#" + ic.pre + "collections_menu").val("");
62831
+ }
62832
+ );
62833
+ }
62834
+ }
62835
+
61434
62836
  /**
61435
62837
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
61436
62838
  */
@@ -61522,14 +62924,15 @@ class LoadScript {
61522
62924
  let bFinalStep =(i === steps - 1) ? true : false;
61523
62925
 
61524
62926
  if(!ic.commands[i].trim()) continue;
61525
- let nAtoms = Object.keys(ic.atoms).length;
62927
+ let nAtoms = (ic.atoms) ? Object.keys(ic.atoms).length : 0;
61526
62928
 
61527
62929
  if(nAtoms == 0 && ic.commands[i].indexOf('load') == -1) continue;
61528
62930
 
61529
62931
  let strArray = ic.commands[i].split("|||");
61530
62932
  let command = strArray[0].trim();
61531
62933
 
61532
- if(ic.inputid) ic.bNotLoadStructure = true;
62934
+ // sometimes URL has an ID input, then load a structure in commands
62935
+ //if(ic.inputid) ic.bNotLoadStructure = true;
61533
62936
 
61534
62937
  if(command.indexOf('load') !== -1) {
61535
62938
  if(end === 0 && start === end) {
@@ -61565,18 +62968,7 @@ class LoadScript {
61565
62968
  }
61566
62969
  }
61567
62970
  else if(command.indexOf('set map') == 0 && command.indexOf('set map wireframe') == -1) {
61568
- //set map 2fofc sigma 1.5
61569
- let urlArray = strArray[0].trim().split(' | ');
61570
-
61571
- let str = urlArray[0].substr(8);
61572
- let paraArray = str.split(" ");
61573
-
61574
- if(paraArray.length == 3 && paraArray[1] == 'sigma') {
61575
- paraArray[2];
61576
- paraArray[0];
61577
-
61578
- await thisClass.applyCommandMap(strArray[0].trim());
61579
- }
62971
+ await thisClass.applyCommandMap(strArray[0].trim());
61580
62972
  }
61581
62973
  else if(command.indexOf('set emmap') == 0 && command.indexOf('set emmap wireframe') == -1) {
61582
62974
  //set emmap percentage 70
@@ -62076,17 +63468,34 @@ class LoadScript {
62076
63468
  // ic.deferredMap = $.Deferred(function() { let ic = thisClass.icn3d;
62077
63469
  //"set map 2fofc sigma 1.5"
62078
63470
  // or "set map 2fofc sigma 1.5 | [url]"
63471
+
63472
+ // added more para later
63473
+ //"set map 2fofc sigma 1.5 file dsn6"
63474
+ // or "set map 2fofc sigma 1.5 file dsn6 | [url]"
62079
63475
  let urlArray = command.split(" | ");
62080
63476
 
62081
63477
  let str = urlArray[0].substr(8);
62082
63478
  let paraArray = str.split(" ");
62083
63479
 
62084
- if(paraArray.length == 3 && paraArray[1] == 'sigma') {
63480
+ //if(paraArray.length == 3 && paraArray[1] == 'sigma') {
63481
+ if(paraArray[1] == 'sigma') {
62085
63482
  let sigma = paraArray[2];
62086
63483
  let type = paraArray[0];
62087
63484
 
63485
+ let fileType = 'dsn6';
63486
+ if(paraArray.length == 5) fileType = paraArray[4];
63487
+
62088
63488
  if(urlArray.length == 2) {
62089
- await ic.dsn6ParserCls.dsn6ParserBase(urlArray[1], type, sigma);
63489
+ let bInputSigma = true;
63490
+ if(fileType == 'dsn6') {
63491
+ await ic.dsn6ParserCls.dsn6ParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
63492
+ }
63493
+ else if(fileType == 'ccp4') {
63494
+ await ic.ccp4ParserCls.ccp4ParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
63495
+ }
63496
+ else if(fileType == 'mtz') {
63497
+ await ic.mtzParserCls.mtzParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
63498
+ }
62090
63499
  }
62091
63500
  else {
62092
63501
  await ic.dsn6ParserCls.dsn6Parser(ic.inputid, type, sigma);
@@ -71030,7 +72439,7 @@ class Ray {
71030
72439
  }
71031
72440
 
71032
72441
  // from iview (http://istar.cse.cuhk.edu.hk/iview/)
71033
- getAtomsFromPosition(point, threshold) { let ic = this.icn3d, me = ic.icn3dui;
72442
+ getAtomsFromPosition(point, threshold, atoms) { let ic = this.icn3d, me = ic.icn3dui;
71034
72443
  let i;
71035
72444
 
71036
72445
  if(threshold === undefined || threshold === null) {
@@ -71038,7 +72447,8 @@ class Ray {
71038
72447
  }
71039
72448
 
71040
72449
  //for (i in ic.atoms) {
71041
- for (i in ic.dAtoms) {
72450
+ let atomHash = (atoms) ? atoms : ic.dAtoms;
72451
+ for (i in atomHash) {
71042
72452
  let atom = ic.atoms[i];
71043
72453
 
71044
72454
  if(ic.ions.hasOwnProperty(i) && ic.opts['ions'] === 'sphere') {
@@ -71431,13 +72841,25 @@ class Picking {
71431
72841
  y += me.htmlCls.MENU_HEIGHT;
71432
72842
  }
71433
72843
  let text =(ic.pk == 1) ? atom.resn + atom.resi + '@' + atom.name : atom.resn + atom.resi;
72844
+ let chainid = atom.structure + '_' + atom.chain;
72845
+ let textWidth;
71434
72846
  if(ic.structures !== undefined && Object.keys(ic.structures).length > 1) {
71435
- text = atom.structure + '_' + atom.chain + ' ' + text;
71436
- $("#" + ic.pre + "popup").css("width", "160px");
72847
+ text = chainid + ' ' + text;
72848
+ textWidth = (ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) ? 160 + 80 : 160;
72849
+ $("#" + ic.pre + "popup").css("width", textWidth + "px");
71437
72850
  }
71438
72851
  else {
71439
- $("#" + ic.pre + "popup").css("width", "80px");
72852
+ textWidth = (ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) ? 80 + 80 : 80;
72853
+ $("#" + ic.pre + "popup").css("width", textWidth + "px");
71440
72854
  }
72855
+
72856
+
72857
+ if(ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) {
72858
+ let refnumLabel = ic.resid2refnum[chainid + '_' + atom.resi];
72859
+
72860
+ if(refnumLabel) text += ', Ig: ' + refnumLabel;
72861
+ }
72862
+
71441
72863
  $("#" + ic.pre + "popup").html(text);
71442
72864
  $("#" + ic.pre + "popup").css("top", y).css("left", x+20).show();
71443
72865
  }
@@ -72598,6 +74020,8 @@ class iCn3D {
72598
74020
  this.alignParserCls = new AlignParser(this);
72599
74021
  this.chainalignParserCls = new ChainalignParser(this);
72600
74022
  this.dsn6ParserCls = new Dsn6Parser(this);
74023
+ this.ccp4ParserCls = new Ccp4Parser(this);
74024
+ this.mtzParserCls = new MtzParser(this);
72601
74025
  this.mmcifParserCls = new MmcifParser(this);
72602
74026
  this.mmdbParserCls = new MmdbParser(this);
72603
74027
  this.mmtfParserCls = new MmtfParser(this);
@@ -72613,7 +74037,8 @@ class iCn3D {
72613
74037
  this.setSeqAlignCls = new SetSeqAlign(this);
72614
74038
 
72615
74039
  this.applyCommandCls = new ApplyCommand(this);
72616
- this.definedSetsCls = new DefinedSets(this);
74040
+ this.definedSetsCls = new DefinedSets(this);
74041
+ this.selectCollectionsCls = new SelectCollections(this);
72617
74042
  this.legendTableCls = new LegendTable(this);
72618
74043
  this.loadScriptCls = new LoadScript(this);
72619
74044
  this.selByCommCls = new SelectByCommand(this);
@@ -72860,7 +74285,7 @@ class iCn3DUI {
72860
74285
  //even when multiple iCn3D viewers are shown together.
72861
74286
  this.pre = this.cfg.divid + "_";
72862
74287
 
72863
- this.REVISION = '3.28.4';
74288
+ this.REVISION = '3.29.1';
72864
74289
 
72865
74290
  // In nodejs, iCn3D defines "window = {navigator: {}}"
72866
74291
  this.bNode = (Object.keys(window).length < 2) ? true : false;