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.module.js CHANGED
@@ -6858,9 +6858,13 @@ class ClickMenu {
6858
6858
  me.myEventCls.onIds("#" + me.pre + "mn1_selection", "click", function(e) { me.icn3d; //e.preventDefault();
6859
6859
  me.htmlCls.dialogCls.openDlg('dl_selection', 'Please input the selection file');
6860
6860
  });
6861
+
6862
+ me.myEventCls.onIds("#" + me.pre + "mn1_collection", "click", function (e) { me.icn3d; //e.preventDefault();
6863
+ me.htmlCls.dialogCls.openDlg('dl_collection', 'Please input the collection file');
6864
+ });
6861
6865
 
6862
6866
  me.myEventCls.onIds("#" + me.pre + "mn1_dsn6", "click", function(e) { me.icn3d; //e.preventDefault();
6863
- me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the DSN6 file to display electron density map');
6867
+ me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the map file to display electron density map');
6864
6868
  });
6865
6869
 
6866
6870
 
@@ -6887,7 +6891,7 @@ class ClickMenu {
6887
6891
 
6888
6892
 
6889
6893
  me.myEventCls.onIds("#" + me.pre + "mn1_dsn6url", "click", function(e) { me.icn3d; //e.preventDefault();
6890
- me.htmlCls.dialogCls.openDlg('dl_dsn6url', 'Please input the DSN6 file to display electron density map');
6894
+ me.htmlCls.dialogCls.openDlg('dl_dsn6url', 'Please input the map file to display electron density map');
6891
6895
  });
6892
6896
 
6893
6897
  me.myEventCls.onIds("#" + me.pre + "mn1_exportState", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
@@ -8192,6 +8196,8 @@ class ClickMenu {
8192
8196
  let sigma2fofc = parseFloat($("#" + me.pre + "sigma2fofc" ).val());
8193
8197
  let type = '2fofc';
8194
8198
  await ic.dsn6ParserCls.dsn6Parser(ic.inputid, type, sigma2fofc);
8199
+ //ic.densityCifParserCls.densityCifParser(ic.inputid, type, sigma2fofc);
8200
+
8195
8201
  //ic.setOptionCls.setOption('map', '2fofc');
8196
8202
  thisClass.setLogCmd('set map 2fofc sigma ' + sigma2fofc, true);
8197
8203
  });
@@ -9445,15 +9451,18 @@ class SetMenu {
9445
9451
  html += this.getLink('mn1_state', 'State/Script File', undefined, 2);
9446
9452
  html += this.getLink('mn1_fixedversion', 'Share Link in Archived Ver. ' + me.htmlCls.wifiStr, undefined, 2);
9447
9453
  html += this.getLink('mn1_selection', 'Selection File', undefined, 2);
9454
+ html += this.getLink("mn1_collection", "Collection File", undefined, 2);
9448
9455
 
9449
9456
  html += this.getMenuSep();
9450
9457
 
9451
- html += this.getMenuText('mn1_dsn6wrap', 'Electron Density(DSN6)', undefined, undefined, 2);
9458
+ html += this.getMenuText('mn1_dsn6wrap', 'Electron Density', undefined, undefined, 2);
9452
9459
  html += "<ul>";
9453
9460
  html += this.getLink('mn1_dsn6', 'Local File', undefined, 3);
9454
9461
  html += this.getLink('mn1_dsn6url', 'URL(CORS) ' + me.htmlCls.wifiStr, undefined, 3);
9455
9462
  html += "</ul>";
9456
9463
 
9464
+ html += "<li><br/></li>";
9465
+
9457
9466
  html += "</ul>";
9458
9467
  html += "</li>";
9459
9468
 
@@ -9559,14 +9568,14 @@ class SetMenu {
9559
9568
  }
9560
9569
 
9561
9570
  //!!!
9562
- /*
9571
+
9563
9572
  html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
9564
9573
  html += "<ul>";
9565
9574
  html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
9566
9575
  html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
9567
9576
  html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
9568
9577
  html += "</ul>";
9569
- */
9578
+
9570
9579
 
9571
9580
  html += "<li><br/></li>";
9572
9581
 
@@ -10407,8 +10416,8 @@ class SetMenu {
10407
10416
  //}
10408
10417
 
10409
10418
  //!!!
10410
- //html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
10411
- //html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
10419
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
10420
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
10412
10421
  }
10413
10422
  else {
10414
10423
  //if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
@@ -10539,7 +10548,7 @@ class SetMenu {
10539
10548
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
10540
10549
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
10541
10550
  //!!!
10542
- //html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
10551
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
10543
10552
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
10544
10553
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
10545
10554
  }
@@ -10631,11 +10640,11 @@ class SetMenu {
10631
10640
 
10632
10641
  html += "<ul>";
10633
10642
  //!!!
10634
- /*
10643
+
10635
10644
  html += this.getLink('mn6_igrefYes', 'Show Ig Ref. Number', undefined, 2);
10636
10645
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
10637
10646
  html += this.getLink('mn6_igrefNo', 'Hide Ig Ref. Number', undefined, 2);
10638
- */
10647
+
10639
10648
  html += this.getMenuSep();
10640
10649
 
10641
10650
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
@@ -11868,6 +11877,19 @@ class SetDialog {
11868
11877
  html += me.htmlCls.buttonStr + "reload_selectionfile' style='margin-top: 6px;'>Load</button>";
11869
11878
  html += "</div>";
11870
11879
 
11880
+ html += me.htmlCls.divStr + "dl_collection' class='" + dialogClass + "'>";
11881
+ html += "Collection file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "collectionfile'><br/>";
11882
+ html += me.htmlCls.buttonStr + "reload_collectionfile' style='margin-top: 6px;'>Load</button>";
11883
+ html += "</div>";
11884
+
11885
+ html += me.htmlCls.divStr + "dl_selectCollections' class='" + dialogClass + "'>";
11886
+ html += me.htmlCls.divStr + "dl_collectionsMenu'>";
11887
+ html += "<b>Structures:</b> <br/>";
11888
+ html += "<select id='" + me.pre + "collections_menu' multiple size='6' style='min-width:130px;'>";
11889
+ html += "</select>";
11890
+ html += "</div>";
11891
+ html += "</div>";
11892
+
11871
11893
  html += me.htmlCls.divStr + "dl_menuloadpref' class='" + dialogClass + "'>";
11872
11894
  html += this.addNotebookTitle('dl_menuloadpref', 'Load a preference file');
11873
11895
  html += "Preference file: " + me.htmlCls.inputFileStr + "id='" + me.pre + "menupreffile'><br/>";
@@ -11875,23 +11897,19 @@ class SetDialog {
11875
11897
  html += "</div>";
11876
11898
 
11877
11899
  html += me.htmlCls.divStr + "dl_dsn6' class='" + dialogClass + "'>";
11878
- html += this.addNotebookTitle('dl_dsn6', 'Load a DSN6 file');
11879
- html += "<b>Note</b>: Always load a PDB file before loading DSN6 files. <br/><br/><br/>";
11880
-
11881
- html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at: <select id='" + me.pre + "dsn6sigma2fofc'>";
11900
+ html += this.addNotebookTitle('dl_dsn6', 'Load a map file');
11901
+ 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/>";
11882
11902
 
11883
- let optArray1 = ['0', '0.5', '1', '1.5', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
11884
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
11903
+ html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at default threshold or at: "
11904
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigma2fofc' value='' size=8> &sigma;</span><br/>";
11905
+ //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/>";
11906
+ 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/>";
11885
11907
 
11886
- html += "</select> &sigma;</span><br/>";
11887
- html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6file2fofc'> " + me.htmlCls.buttonStr + "reload_dsn6file2fofc' style='margin-top: 6px;'>Load</button><br><br><br/>";
11908
+ html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at default threshold or at: "
11909
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmafofc' value='' size=8> &sigma;</span><br/>";
11888
11910
 
11889
- html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at: <select id='" + me.pre + "dsn6sigmafofc'>";
11890
-
11891
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 5);
11892
-
11893
- html += "</select> &sigma;</span><br/>";
11894
- html += me.htmlCls.inputFileStr + "id='" + me.pre + "dsn6filefofc'> " + me.htmlCls.buttonStr + "reload_dsn6filefofc' style='margin-top: 6px;'>Load</button><br><br><br>";
11911
+ //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>";
11912
+ 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>";
11895
11913
 
11896
11914
  html += me.htmlCls.buttonStr + "elecmapNo4'>Remove Map</button><br>";
11897
11915
 
@@ -11899,21 +11917,17 @@ class SetDialog {
11899
11917
 
11900
11918
  html += me.htmlCls.divStr + "dl_dsn6url' class='" + dialogClass + "'>";
11901
11919
  html += this.addNotebookTitle('dl_dsn6url', 'Load a selection file via a URL');
11902
- html += "<b>Note</b>: Always load a PDB file before loading DSN6 files. <br/><br/><br/>";
11920
+ 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/>";
11903
11921
 
11904
- html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at: <select id='" + me.pre + "dsn6sigmaurl2fofc'>";
11922
+ html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at default threshold or at: "
11923
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmaurl2fofc' value='' size=8> &sigma;</span><br/>";
11905
11924
 
11906
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
11925
+ 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/>";
11907
11926
 
11908
- html += "</select> &sigma;</span><br/>";
11909
- 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/>";
11927
+ html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at default threshold or at: "
11928
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmaurlfofc' value='' size=8> &sigma;</span><br/>";
11910
11929
 
11911
- html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at: <select id='" + me.pre + "dsn6sigmaurlfofc'>";
11912
-
11913
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 5);
11914
-
11915
- html += "</select> &sigma;</span><br/>";
11916
- 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/>";
11930
+ 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>";
11917
11931
 
11918
11932
  html += me.htmlCls.buttonStr + "elecmapNo5'>Remove Map</button><br>";
11919
11933
 
@@ -12253,6 +12267,7 @@ class SetDialog {
12253
12267
  html += this.addNotebookTitle('dl_elecmap2fofc', 'Electron Density 2F0-Fc Map');
12254
12268
  html += "<span style='white-space:nowrap;font-weight:bold;'>Contour at: <select id='" + me.pre + "sigma2fofc'>";
12255
12269
 
12270
+ let optArray1 = ['0', '0.5', '1', '1.5', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
12256
12271
  html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
12257
12272
 
12258
12273
  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>";
@@ -12899,7 +12914,7 @@ class Events {
12899
12914
  }
12900
12915
  }
12901
12916
 
12902
- readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
12917
+ async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
12903
12918
  let file = files[index];
12904
12919
  let commandName = (bAppend) ? 'append': 'load';
12905
12920
 
@@ -12936,7 +12951,20 @@ class Events {
12936
12951
  await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
12937
12952
  }
12938
12953
  else {
12939
- thisClass.readFile(bAppend, files, index + 1, dataStrAll);
12954
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
12955
+ }
12956
+
12957
+ if(bAppend) {
12958
+ if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
12959
+ //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
12960
+
12961
+ ic.bResetAnno = true;
12962
+
12963
+ if(ic.bAnnoShown) {
12964
+ await ic.showAnnoCls.showAnnotations();
12965
+
12966
+ ic.annotationCls.resetAnnoTabAll();
12967
+ }
12940
12968
  }
12941
12969
  };
12942
12970
 
@@ -12971,13 +12999,7 @@ class Events {
12971
12999
 
12972
13000
  ic.dataStrAll = '';
12973
13001
 
12974
- this.readFile(bAppend, files, 0, '');
12975
-
12976
- if(bAppend) {
12977
- if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
12978
- //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
12979
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
12980
- }
13002
+ await this.readFile(bAppend, files, 0, '');
12981
13003
  }
12982
13004
  }
12983
13005
 
@@ -13061,7 +13083,10 @@ class Events {
13061
13083
 
13062
13084
  if(bStructures) {
13063
13085
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
13064
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
13086
+ if(ic.bAnnoShown) {
13087
+ await ic.showAnnoCls.showAnnotations();
13088
+ ic.annotationCls.resetAnnoTabAll();
13089
+ }
13065
13090
  }
13066
13091
  }
13067
13092
  }
@@ -14069,17 +14094,78 @@ class Events {
14069
14094
  }
14070
14095
  });
14071
14096
 
14097
+ me.myEventCls.onIds("#" + me.pre + "reload_collectionfile", "click", function (e) { let ic = me.icn3d;
14098
+ e.preventDefault();
14099
+ let file = $("#" + me.pre + "collectionfile")[0].files[0];
14100
+ if (!file) {
14101
+ alert("Please select a file before clicking 'Load'");
14102
+ } else {
14103
+ if (!me.cfg.notebook) dialog.dialog("close");
14104
+ if (!me.cfg.notebook) {
14105
+ $(".ui-dialog-content").dialog("close");
14106
+ } else {
14107
+ ic.resizeCanvasCls.closeDialogs();
14108
+ }
14109
+ me.htmlCls.setHtmlCls.fileSupport();
14110
+ let reader = new FileReader();
14111
+ reader.onload = async function (e) {
14112
+ let dataStr = JSON.parse(e.target.result);
14113
+ let collection = [dataStr["structures"].map(({ id }) => id), dataStr["structures"].map(({ title }) => title)];
14114
+ let collectionHtml = ic.selectCollectionsCls.setAtomMenu(collection[0], collection[1]);
14115
+ await ic.chainalignParserCls.downloadMmdbAf(collection[0][0]);
14116
+
14117
+ ic.opts["color"] = "structure";
14118
+ ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
14119
+
14120
+ $("#" + ic.pre + "collections_menu").html(collectionHtml);
14121
+ ic.selectCollectionsCls.clickStructure();
14122
+
14123
+ $("#" + ic.pre + "collections_menu").trigger("change");
14124
+
14125
+ me.htmlCls.clickMenuCls.setLogCmd(
14126
+ "load collection file " +
14127
+ $("#" + me.pre + "collectionfile").val(),
14128
+ false
14129
+ );
14130
+ };
14131
+ reader.readAsText(file);
14132
+ me.htmlCls.dialogCls.openDlg("dl_selectCollections", "Select Collections");
14133
+ }
14134
+ });
14135
+
14072
14136
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6file2fofc", "click", function(e) { let ic = me.icn3d;
14073
14137
  e.preventDefault();
14074
- if(!me.cfg.notebook) dialog.dialog( "close" );
14138
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14075
14139
  ic.dsn6ParserCls.loadDsn6File('2fofc');
14076
14140
  });
14077
14141
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6filefofc", "click", function(e) { let ic = me.icn3d;
14078
14142
  e.preventDefault();
14079
- if(!me.cfg.notebook) dialog.dialog( "close" );
14143
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14080
14144
  ic.dsn6ParserCls.loadDsn6File('fofc');
14081
14145
  });
14082
14146
 
14147
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4file2fofc", "click", function(e) { let ic = me.icn3d;
14148
+ e.preventDefault();
14149
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14150
+ ic.ccp4ParserCls.loadCcp4File('2fofc');
14151
+ });
14152
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4filefofc", "click", function(e) { let ic = me.icn3d;
14153
+ e.preventDefault();
14154
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14155
+ ic.ccp4ParserCls.loadCcp4File('fofc');
14156
+ });
14157
+
14158
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfile2fofc", "click", function(e) { let ic = me.icn3d;
14159
+ e.preventDefault();
14160
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14161
+ ic.mtzParserCls.loadMtzFile('2fofc');
14162
+ });
14163
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfilefofc", "click", function(e) { let ic = me.icn3d;
14164
+ e.preventDefault();
14165
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14166
+ ic.mtzParserCls.loadMtzFile('fofc');
14167
+ });
14168
+
14083
14169
  me.myEventCls.onIds("#" + me.pre + "reload_delphifile", "click", async function(e) { let ic = me.icn3d;
14084
14170
  e.preventDefault();
14085
14171
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -14169,15 +14255,37 @@ class Events {
14169
14255
 
14170
14256
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6fileurl2fofc", "click", function(e) { let ic = me.icn3d;
14171
14257
  e.preventDefault();
14172
- if(!me.cfg.notebook) dialog.dialog( "close" );
14258
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14173
14259
  ic.dsn6ParserCls.loadDsn6FileUrl('2fofc');
14174
14260
  });
14175
14261
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6fileurlfofc", "click", function(e) { let ic = me.icn3d;
14176
14262
  e.preventDefault();
14177
- if(!me.cfg.notebook) dialog.dialog( "close" );
14263
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14178
14264
  ic.dsn6ParserCls.loadDsn6FileUrl('fofc');
14179
14265
  });
14180
14266
 
14267
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4fileurl2fofc", "click", function(e) { let ic = me.icn3d;
14268
+ e.preventDefault();
14269
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14270
+ ic.ccp4ParserCls.loadCcp4FileUrl('2fofc');
14271
+ });
14272
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4fileurlfofc", "click", function(e) { let ic = me.icn3d;
14273
+ e.preventDefault();
14274
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14275
+ ic.ccp4ParserCls.loadCcp4FileUrl('fofc');
14276
+ });
14277
+
14278
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfileurl2fofc", "click", function(e) { let ic = me.icn3d;
14279
+ e.preventDefault();
14280
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14281
+ ic.mtzParserCls.loadMtzFileUrl('2fofc');
14282
+ });
14283
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfileurlfofc", "click", function(e) { let ic = me.icn3d;
14284
+ e.preventDefault();
14285
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14286
+ ic.mtzParserCls.loadMtzFileUrl('fofc');
14287
+ });
14288
+
14181
14289
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile", "click", async function(e) { me.icn3d;
14182
14290
  e.preventDefault();
14183
14291
 
@@ -15565,7 +15673,7 @@ class AlignSeq {
15565
15673
  // for(let i in ic.alnChains) {
15566
15674
  for (let m = 0, ml = alignChainArray.length; m < ml; ++m) {
15567
15675
  let i = alignChainArray[m];
15568
-
15676
+
15569
15677
  if (index == 0) firstChainid = i;
15570
15678
 
15571
15679
  if (bOnechain && index > 0) {
@@ -29340,8 +29448,8 @@ class ElectronMap {
29340
29448
  this.pLength = 0;
29341
29449
  this.cutRadius = 0;
29342
29450
  this.vpBits = null; // uint8 array of bitmasks
29343
- this.vpDistance = null; // floatarray of _squared_ distances
29344
- this.vpAtomID = null; // intarray
29451
+ this.vpGridTrans = null; // array of translated number of grids
29452
+ this.vpAtomID = null; // uint8 array
29345
29453
  this.vertnumber = 0;
29346
29454
  this.facenumber = 0;
29347
29455
  this.pminx = 0;
@@ -29391,12 +29499,27 @@ ElectronMap.prototype.getFacesAndVertices = function(allatoms, atomlist) {
29391
29499
  atomsToShow[atomlist[i]] = 1;
29392
29500
  let vertices = this.verts;
29393
29501
 
29502
+ let vertTrans = {};
29394
29503
  for(i = 0, il = vertices.length; i < il; i++) {
29395
29504
  let r;
29396
29505
  if(this.type == 'phi') {
29397
29506
  r = new THREE.Vector3(vertices[i].x, vertices[i].y, vertices[i].z).multiplyScalar(1.0/this.header.scale).applyMatrix4(this.matrix);
29398
29507
  }
29399
29508
  else {
29509
+ // ccp4 has no translation vector. Only translated vertices are used.
29510
+ if(this.header.ccp4) {
29511
+ let index = vertices[i].index;
29512
+ let finalIndex;
29513
+ if(this.vpGridTrans[index]) {
29514
+ finalIndex = index;
29515
+
29516
+ vertices[i].x += this.vpGridTrans[finalIndex][0] * this.header.xExtent * this.scaleFactor;
29517
+ vertices[i].y += this.vpGridTrans[finalIndex][1] * this.header.xExtent * this.scaleFactor;
29518
+ vertices[i].z += this.vpGridTrans[finalIndex][2] * this.header.xExtent * this.scaleFactor;
29519
+
29520
+ vertTrans[finalIndex] = 1;
29521
+ }
29522
+ }
29400
29523
  r = new THREE.Vector3(vertices[i].x, vertices[i].y, vertices[i].z).applyMatrix4(this.matrix);
29401
29524
  }
29402
29525
  // vertices[i].x = r.x / this.scaleFactor - this.ptranx;
@@ -29415,13 +29538,22 @@ ElectronMap.prototype.getFacesAndVertices = function(allatoms, atomlist) {
29415
29538
  let fa = this.faces[i], fb = this.faces[i+1], fc = this.faces[i+2];
29416
29539
 
29417
29540
  if(fa !== fb && fb !== fc && fa !== fc){
29418
- finalfaces.push({"a":fa, "b":fb, "c":fc});
29541
+ if(this.header.ccp4) {
29542
+ // only transfered vertices will be used
29543
+ if(vertTrans.hasOwnProperty(vertices[fa].index) && vertTrans.hasOwnProperty(vertices[fb].index)
29544
+ && vertTrans.hasOwnProperty(vertices[fc].index)) {
29545
+ finalfaces.push({"a":fa, "b":fb, "c":fc});
29546
+ }
29547
+ }
29548
+ else {
29549
+ finalfaces.push({"a":fa, "b":fb, "c":fc});
29550
+ }
29419
29551
  }
29420
29552
  }
29421
29553
 
29422
29554
  //try to help the garbage collector
29423
29555
  this.vpBits = null; // uint8 array of bitmasks
29424
- this.vpDistance = null; // floatarray
29556
+ this.vpGridTrans = null; // uint8 array
29425
29557
  this.vpAtomID = null; // intarray
29426
29558
 
29427
29559
  return {
@@ -29480,6 +29612,8 @@ ElectronMap.prototype.initparm = function(inHeader, inData, inMatrix, inIsovalue
29480
29612
  this.cutRadius = this.probeRadius * this.scaleFactor;
29481
29613
 
29482
29614
  this.vpBits = new Uint8Array(this.pLength * this.pWidth * this.pHeight);
29615
+ if(this.header.ccp4) this.vpGridTrans = new Array(this.pLength * this.pWidth * this.pHeight);
29616
+
29483
29617
  this.vpAtomID = new Uint8Array(this.pLength * this.pWidth * this.pHeight);
29484
29618
  };
29485
29619
 
@@ -29505,7 +29639,6 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29505
29639
  let i, j, k, il, jl, kl;
29506
29640
  for(i = 0, il = this.vpBits.length; i < il; i++) {
29507
29641
  this.vpBits[i] = 0;
29508
- //this.vpDistance[i] = -1.0;
29509
29642
  this.vpAtomID[i] = 0;
29510
29643
  }
29511
29644
 
@@ -29667,6 +29800,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29667
29800
  }
29668
29801
  }
29669
29802
  else {
29803
+ // let index2ori = {};
29670
29804
  for(let serial in atomlist) {
29671
29805
  let atom = atoms[atomlist[serial]];
29672
29806
 
@@ -29697,6 +29831,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29697
29831
 
29698
29832
  for(i = 0, il = indexArray.length; i < il; ++i) {
29699
29833
  let index = indexArray[i];
29834
+
29700
29835
  if(this.type == '2fofc') {
29701
29836
  this.vpBits[index] =(this.dataArray[index] >= this.isovalue) ? 1 : 0;
29702
29837
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
@@ -29710,6 +29845,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29710
29845
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
29711
29846
  }
29712
29847
  }
29848
+
29713
29849
  }
29714
29850
  }
29715
29851
 
@@ -29933,7 +30069,18 @@ class Surface {
29933
30069
  cfg.isovalue = ic.mapData.sigma2;
29934
30070
  cfg.type = '2fofc';
29935
30071
 
29936
- ps = this.SetupMap(cfg);
30072
+ //ccp4
30073
+ cfg.ccp4 = ic.mapData.ccp4;
30074
+ cfg.grid = ic.mapData.grid2;
30075
+ cfg.unit_cell = ic.mapData.unit_cell2;
30076
+
30077
+ if(cfg.header || cfg.ccp4) ps = this.SetupMap(cfg);
30078
+ else return;
30079
+
30080
+ if(cfg.ccp4) {
30081
+ ic.mapData = {};
30082
+ return;
30083
+ }
29937
30084
  }
29938
30085
  else if(type == 12) { // fofc
29939
30086
  cfg.header = ic.mapData.header;
@@ -29942,7 +30089,18 @@ class Surface {
29942
30089
  cfg.isovalue = ic.mapData.sigma;
29943
30090
  cfg.type = 'fofc';
29944
30091
 
29945
- ps = this.SetupMap(cfg);
30092
+ //ccp4
30093
+ cfg.ccp4 = ic.mapData.ccp4;
30094
+ cfg.grid = ic.mapData.grid;
30095
+ cfg.unit_cell = ic.mapData.unit_cell;
30096
+
30097
+ if(cfg.header || cfg.ccp4) ps = this.SetupMap(cfg);
30098
+ else return;
30099
+
30100
+ if(cfg.ccp4) {
30101
+ ic.mapData = {};
30102
+ return;
30103
+ }
29946
30104
  }
29947
30105
  else if(type == 13) { // em
29948
30106
  cfg.maxdist = 3; // EM map has no unit cell. It could include more gird space.
@@ -30430,29 +30588,60 @@ class Surface {
30430
30588
  }
30431
30589
 
30432
30590
  SetupMap(data) { let ic = this.icn3d; ic.icn3dui;
30433
- let ps = new ElectronMap(ic);
30434
-
30435
- ps.initparm(data.header, data.data, data.matrix, data.isovalue, data.center, data.maxdist,
30436
- data.pmin, data.pmax, data.water, data.type, data.rmsd_supr, data.loadPhiFrom, data.icn3d);
30591
+ if(data.ccp4) {
30592
+ let radius = 10;
30593
+ let center = (ic.center) ? [ic.center.x, ic.center.y, ic.center.z] : [0,0,0];
30594
+
30595
+ let typeDetail;
30596
+ if(data.type == '2fofc') {
30597
+ typeDetail = '2fofc';
30598
+ let result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
30599
+ let iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
30600
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
30601
+
30602
+ result = null;
30603
+ iso = null;
30604
+ }
30605
+ else if(data.type == 'fofc') {
30606
+ typeDetail = 'fofc_neg';
30607
+ let result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
30608
+ let iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
30609
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
30610
+
30611
+ typeDetail = 'fofc_pos';
30612
+ result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
30613
+ iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
30614
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
30437
30615
 
30438
- ps.fillvoxels(data.allatoms, data.extendedAtoms);
30616
+ result = null;
30617
+ iso = null;
30618
+ }
30619
+ }
30620
+ else {
30621
+ let ps = new ElectronMap(ic);
30622
+
30623
+ ps.initparm(data.header, data.data, data.matrix, data.isovalue, data.center, data.maxdist,
30624
+ data.pmin, data.pmax, data.water, data.type, data.rmsd_supr, data.loadPhiFrom, data.icn3d);
30439
30625
 
30440
- if(!data.header.bSurface) ps.buildboundary();
30626
+ ps.fillvoxels(data.allatoms, data.extendedAtoms);
30441
30627
 
30442
- if(!data.header.bSurface) ps.marchingcube();
30443
-
30444
- ps.vpBits = null; // uint8 array of bitmasks
30445
- //ps.vpDistance = null; // floatarray of _squared_ distances
30446
- ps.vpAtomID = null; // intarray
30628
+ if(!data.header.bSurface) ps.buildboundary();
30447
30629
 
30448
- let result;
30630
+ if(!data.header.bSurface) ps.marchingcube();
30631
+
30632
+ ps.vpBits = null; // uint8 array of bitmasks
30633
+ //ps.vpDistance = null; // floatarray of _squared_ distances
30634
+ ps.vpAtomID = null; // intarray
30449
30635
 
30450
- if(!data.header.bSurface) result = ps.getFacesAndVertices(data.allatoms, data.atomsToShow);
30636
+ let result;
30451
30637
 
30452
- ps.faces = null;
30453
- ps.verts = null;
30638
+ if(!data.header.bSurface) result = ps.getFacesAndVertices(data.allatoms, data.atomsToShow);
30454
30639
 
30455
- return result;
30640
+ ps.faces = null;
30641
+ ps.verts = null;
30642
+
30643
+ return result;
30644
+ }
30456
30645
  }
30457
30646
  }
30458
30647
 
@@ -35939,7 +36128,7 @@ class SetColor {
35939
36128
 
35940
36129
  for(let resid in residueHash) {
35941
36130
  if(!ic.resid2refnum[resid]) {
35942
- color = me.parasCls.thr('#FFFFFF');
36131
+ color = me.parasCls.thr('#00FFFF'); //('#FFFFFF');
35943
36132
  }
35944
36133
  else {
35945
36134
  let refnumLabel = ic.resid2refnum[resid];
@@ -35974,7 +36163,7 @@ class SetColor {
35974
36163
  let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
35975
36164
  for(let resid in residueHash) {
35976
36165
  if(!ic.resid2refnum[resid]) {
35977
- color = me.parasCls.thr('#FFFFFF');
36166
+ color = me.parasCls.thr('#00FFFF'); //('#FFFFFF');
35978
36167
  }
35979
36168
  else {
35980
36169
  let refnumLabel = ic.resid2refnum[resid];
@@ -36944,15 +37133,13 @@ class SetOption {
36944
37133
  const name2color = {
36945
37134
  //"A- Strand": "FF00FF",
36946
37135
  "A Strand": "9400D3", //"663399",
36947
- //"A+ Strand": "9400D3", //"663399",
36948
- "A' Strand": "9400D3", //"663399",
36949
37136
  "B Strand": "ba55d3",
36950
37137
  "C Strand": "0000FF",
36951
37138
  "C' Strand": "6495ED",
36952
37139
  "C'' Strand": "006400",
36953
37140
  "D Strand": "00FF00",
36954
- "E Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36955
- "F Strand": "FFA500",
37141
+ "E Strand": "FFD700", //"FFFF00", //"F0E68C",
37142
+ "F Strand": "FF8C00",
36956
37143
  "G Strand": "FF0000",
36957
37144
  //"G+ Strand": "8B0000",
36958
37145
  "Loop": "CCCCCC"
@@ -36979,15 +37166,15 @@ class SetOption {
36979
37166
  "<b>Protodomain 1</b>": "",
36980
37167
  "A Strand": "0000FF",
36981
37168
  "B Strand": "006400",
36982
- "C Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36983
- "C' Strand": "FFA500",
37169
+ "C Strand": "FFD700", //"FFFF00", //"F0E68C",
37170
+ "C' Strand": "FF8C00",
36984
37171
  "<br><b>Linker</b>": "",
36985
37172
  "C'' Strand": "FF0000",
36986
37173
  "<br><b>Protodomain 2</b>": "",
36987
37174
  "D Strand": "0000FF",
36988
37175
  "E Strand": "006400",
36989
- "F Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36990
- "G Strand": "FFA500",
37176
+ "F Strand": "FFD700", //"FFFF00", //"F0E68C",
37177
+ "G Strand": "FF8C00",
36991
37178
  "": "",
36992
37179
  "Loop": "CCCCCC"
36993
37180
  };
@@ -38189,14 +38376,14 @@ class AnnoDomain {
38189
38376
  let pdbid = pdbArray[index];
38190
38377
  //let url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=" + pdbid;
38191
38378
 
38192
- if(index == 0 && ic.mmdb_data !== undefined) {
38379
+ if(!ic.bResetAnno && index == 0 && ic.mmdb_data !== undefined) {
38193
38380
  for(let chnid in ic.protein_chainid) {
38194
38381
  if(chnid.indexOf(pdbid) !== -1) {
38195
38382
  this.showDomainWithData(chnid, ic.mmdb_data);
38196
38383
  }
38197
38384
  }
38198
38385
  }
38199
- else if(ic.mmdb_dataArray[index] !== undefined) {
38386
+ else if(!ic.bResetAnno && ic.mmdb_dataArray[index] !== undefined) {
38200
38387
  for(let chnid in ic.protein_chainid) {
38201
38388
  if(chnid.indexOf(pdbid) !== -1) {
38202
38389
  this.showDomainWithData(chnid, ic.mmdb_dataArray[index]);
@@ -38271,6 +38458,10 @@ class AnnoDomain {
38271
38458
  let domainArray, proteinname;
38272
38459
  let pos = chnid.indexOf('_');
38273
38460
  let chain = chnid.substr(pos + 1);
38461
+ // MMDB symmetry chain has the form of 'A1'
38462
+ if(chain.length > 1 && chain.substr(chain.length - 1) == '1') {
38463
+ chain = chain.substr(0, chain.length - 1);
38464
+ }
38274
38465
 
38275
38466
  if(bCalcDirect) {
38276
38467
  proteinname = chnid;
@@ -39276,7 +39467,11 @@ class Domain3d {
39276
39467
  //this.dcut = 8; // threshold for C-alpha interactions
39277
39468
 
39278
39469
  // It seemed the threshold 7 angstrom works better
39279
- this.dcut = 7; // threshold for C-alpha interactions
39470
+ //this.dcut = 7; // threshold for C-alpha interactions
39471
+ this.dcut = 8; // threshold for C-alpha interactions
39472
+
39473
+ // added by Jiyao
39474
+ this.min_contacts = 5; //3; // minimum number of contacts to be considered as neighbors
39280
39475
 
39281
39476
  this.MAX_SSE = 512;
39282
39477
 
@@ -39310,9 +39505,6 @@ class Domain3d {
39310
39505
  this.c_delta = 3; // cut set parameter
39311
39506
  this.nc_fact = 0.0; // size factor for internal contacts
39312
39507
 
39313
- // added by Jiyao
39314
- this.min_contacts = 3; // minimum number of contacts to be considered as neighbors
39315
-
39316
39508
  //let this.elements[2*this.MAX_SSE]; // sets of this.elements to be split
39317
39509
  this.elements = [];
39318
39510
  this.elements.length = 2*this.MAX_SSE;
@@ -42890,6 +43082,10 @@ class ShowAnno {
42890
43082
  chainLetter = chainLetter.substr(0, chainLetter.indexOf('_'));
42891
43083
  chainidBase = chainArray[i].substr(0, chainArray[i].indexOf('_')) + '_' + chainLetter;
42892
43084
  }
43085
+ else if(chainLetter.length > 1 && chainLetter.substr(chainLetter.length - 1) == '1') { // NCBI modified chainid, e.g., A1
43086
+ chainLetter = chainLetter.substr(0, chainLetter.length - 1);
43087
+ chainidBase = chainArray[i].substr(0, chainArray[i].indexOf('_')) + '_' + chainLetter;
43088
+ }
42893
43089
  else {
42894
43090
  chainidBase = chainArray[i];
42895
43091
  }
@@ -44090,7 +44286,7 @@ class ShowSeq {
44090
44286
  html += '</div>';
44091
44287
  html3 += '</div></div>';
44092
44288
  }
44093
-
44289
+
44094
44290
  if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
44095
44291
  let result = this.showAllRefNum(giSeq, chnid);
44096
44292
 
@@ -44159,9 +44355,13 @@ class ShowSeq {
44159
44355
 
44160
44356
  if(!ic.chainid2refpdbname[chnid]) return {html: html, html3: html3};
44161
44357
 
44162
- let chainList = ic.refnumCls.getTemplateList(chnid);
44358
+ let result = ic.refnumCls.getTemplateList(chnid);
44359
+ let refpdbnameList = result.refpdbnameList;
44360
+ let scoreList = result.scoreList;
44361
+ let seqidList = result.seqidList;
44362
+ let nresAlignList = result.nresAlignList;
44163
44363
 
44164
- let refStruTitle = (chainList) ? "based on " + chainList : "";
44364
+ 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 + "." : "";
44165
44365
 
44166
44366
  let htmlTmp = '<div class="icn3d-dl_sequence">';
44167
44367
  htmlTmp += '<div class="icn3d-residueLine" style="white-space:nowrap;">';
@@ -44217,7 +44417,8 @@ class ShowSeq {
44217
44417
 
44218
44418
  // auto-generate ref numbers for loops
44219
44419
  let bLoop = false, currStrand = '', prevStrand = '';
44220
- let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c;
44420
+ let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c, refnum2c;
44421
+ let bExtendedStrand = false, bSecThird9 = false;
44221
44422
 
44222
44423
  // sometimes one chain may have several Ig domains,set an index for each IgDomain
44223
44424
  let index = 1, bStart = false;
@@ -44243,8 +44444,8 @@ class ShowSeq {
44243
44444
 
44244
44445
  refnumLabel = ic.resid2refnum[residueid];
44245
44446
 
44246
- let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : ' ';
44247
- if(!bStart && refnumLabel && (firstChar == ' ' || firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44447
+ let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : '';
44448
+ if(!bStart && refnumLabel && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44248
44449
  bStart = true;
44249
44450
  resCnt = 1; // the first oen is included
44250
44451
  }
@@ -44261,14 +44462,21 @@ class ShowSeq {
44261
44462
  refnumStr = refnumStr_ori;
44262
44463
  refnum = parseInt(refnumStr);
44263
44464
  refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
44465
+ refnum2c = (refnum - parseInt(refnum/100) * 100).toString();
44466
+
44467
+ // for extended strands, since A is 1550 and A+ is 1650, then the AA+ loop will be 1591, 1592, ... 1610, 1611, etc
44468
+ bSecThird9 = refnum3c.substr(0,1) == '9' || refnum2c.substr(0,1) == '9' || refnum2c.substr(0,1) == '0' || refnum2c.substr(0,1) == '1';
44469
+ if(bSecThird9) ic.residIgLoop[residueid] = 1;
44470
+
44264
44471
  strandPostfix = refnumStr.replace(refnum.toString(), '');
44265
44472
 
44266
44473
  postfix = strandPostfix + '_' + index;
44267
44474
 
44268
- let firstTwo = parseInt(refnum.toString().substr(0, 2)); // A- strand
44475
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
44476
+ bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
44269
44477
 
44270
44478
  if(currStrand && currStrand != ' ') {
44271
- if(refnum3c.substr(0,1) != '9' || firstTwo == 10) {
44479
+ if(!bSecThird9 || (bExtendedStrand && !bSecThird9)) {
44272
44480
  let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
44273
44481
 
44274
44482
  if(currStrand != prevStrand) { // reset currCnt
@@ -44295,7 +44503,7 @@ class ShowSeq {
44295
44503
  resCntAtAnchor = 0;
44296
44504
  }
44297
44505
 
44298
- if(firstTwo == 10) {
44506
+ if(bExtendedStrand) {
44299
44507
  strandArray[strandCnt].anchorRefnum = 0;
44300
44508
  }
44301
44509
 
@@ -44321,7 +44529,7 @@ class ShowSeq {
44321
44529
  resCntAtAnchor = 0;
44322
44530
  }
44323
44531
 
44324
- if(firstTwo == 10) {
44532
+ if(bExtendedStrand) {
44325
44533
  strandArray[strandCnt - 1].anchorRefnum = 0;
44326
44534
  }
44327
44535
 
@@ -44377,7 +44585,7 @@ class ShowSeq {
44377
44585
  currStrand = refnumLabel.replace(new RegExp(refnumStr,'g'), '');
44378
44586
 
44379
44587
  let firstChar = refnumLabel.substr(0,1);
44380
- if(!bStart && (firstChar == ' ' || firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44588
+ if(!bStart && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44381
44589
  bStart = true;
44382
44590
  bBeforeAstrand = true;
44383
44591
  loopCnt = 0;
@@ -44650,6 +44858,11 @@ class ShowSeq {
44650
44858
 
44651
44859
  getRefnumHtml(residueid, refnumStr, refnumStr_ori, refnumLabel, currStrand, bLoop, bHidelabel) { let ic = this.icn3d, me = ic.icn3dui;
44652
44860
  let refnum = parseInt(refnumStr).toString();
44861
+
44862
+ let refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
44863
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
44864
+ let bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
44865
+
44653
44866
  let color = this.getRefnumColor(currStrand, true);
44654
44867
  let colorStr = (!bLoop) ? 'style="color:' + color + '; text-decoration: underline overline;"' : 'style="color:' + color + '"';
44655
44868
 
@@ -44659,13 +44872,13 @@ class ShowSeq {
44659
44872
 
44660
44873
  let html = '';
44661
44874
 
44662
- if(refnumLabel && (lastTwo == 50 || refnum == 1094) && !bLoop) {
44875
+ if(refnumLabel && lastTwo == 50 && !bExtendedStrand && !bLoop) {
44663
44876
  // highlight the anchor residues
44664
44877
  ic.hAtomsRefnum = me.hashUtilsCls.unionHash(ic.hAtomsRefnum, ic.residues[residueid]);
44665
44878
 
44666
44879
  html += '<span ' + colorStr + ' title="' + refnumLabel + '"><b>' + refnumLabel.substr(0, 1) + '</b>' + refnumLabel.substr(1) + '</span>';
44667
44880
  }
44668
- else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && refnum != 1096 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
44881
+ else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
44669
44882
  // e.g., 2152a
44670
44883
  lastTwoStr = isNaN(refnumStr) ? lastTwoStr + refnumStr.substr(refnumStr.length - 1, 1) : lastTwoStr;
44671
44884
  html += '<span ' + colorStr + ' title="' + refnumLabel + '">' + lastTwoStr + '</span>';
@@ -44678,23 +44891,9 @@ class ShowSeq {
44678
44891
  }
44679
44892
 
44680
44893
  getRefnumColor(currStrand, bText) { let ic = this.icn3d, me = ic.icn3dui;
44681
- if(currStrand == "A-") {
44682
- return '#9400D3'; //'#663399';
44683
- }
44684
- else if(currStrand == "A") {
44685
- return '#9400D3'; //'#663399';
44686
- }
44687
- //else if(currStrand == "A*") {
44688
- else if(currStrand == "A+") {
44689
- return '#9400D3'; //'#663399';
44690
- }
44691
- else if(currStrand == "A'") {
44692
- return '#9400D3'; //'#663399';
44693
- }
44694
- else if(currStrand == "B") {
44695
- return '#ba55d3';
44696
- }
44697
- else if(currStrand == "C") {
44894
+ let strand = (currStrand) ? currStrand.substr(0,1) : '';
44895
+
44896
+ if(currStrand == "C") {
44698
44897
  return '#0000FF';
44699
44898
  }
44700
44899
  else if(currStrand == "C'") {
@@ -44703,39 +44902,44 @@ class ShowSeq {
44703
44902
  else if(currStrand == "C''") {
44704
44903
  return '#006400';
44705
44904
  }
44706
- else if(currStrand == "D") {
44905
+
44906
+ else if(strand == "A") {
44907
+ return '#9400D3'; //'#663399';
44908
+ }
44909
+ else if(strand == "B") {
44910
+ return '#ba55d3';
44911
+ }
44912
+ else if(strand == "D") {
44707
44913
  return '#00FF00';
44708
44914
  }
44709
- else if(currStrand == "E") {
44710
- //return (bText) ? "#F7DC6F" : "#FFFF00";
44711
- return "#F7DC6F";
44915
+ else if(strand == "E") {
44916
+ return "#FFD700";
44712
44917
  }
44713
- else if(currStrand == "F") {
44714
- return '#FFA500';
44918
+ else if(strand == "F") {
44919
+ return '#FF8C00';
44715
44920
  }
44716
- else if(currStrand == "G") {
44921
+ else if(strand == "G") {
44717
44922
  return '#FF0000';
44718
44923
  }
44719
- else if(currStrand == "G+") {
44720
- return '#8B0000';
44721
- }
44722
44924
  else {
44723
44925
  return me.htmlCls.GREYB;
44724
44926
  }
44725
44927
  }
44726
44928
 
44727
44929
  getProtodomainColor(currStrand) { let ic = this.icn3d, me = ic.icn3dui;
44728
- if((currStrand && currStrand.substr(0,1) == "A") || currStrand == "D") {
44930
+ let strand = (currStrand) ? currStrand.substr(0,1) : '';
44931
+
44932
+ if(strand == "A" || strand == "D") {
44729
44933
  return '#0000FF';
44730
44934
  }
44731
- else if(currStrand == "B" || currStrand == "E") {
44935
+ else if(strand == "B" || strand == "E") {
44732
44936
  return '#006400';
44733
44937
  }
44734
- else if(currStrand == "C" || currStrand == "F") {
44735
- return "#F7DC6F"; //"#FFFF00"; //'#F0E68C';
44938
+ else if(currStrand == "C" || strand == "F") {
44939
+ return "#FFD700"; //"#FFFF00"; //'#F0E68C';
44736
44940
  }
44737
- else if(currStrand == "C'" || (currStrand && currStrand.substr(0, 1) == "G")) {
44738
- return '#FFA500';
44941
+ else if(currStrand == "C'" || strand == "G") {
44942
+ return '#FF8C00';
44739
44943
  }
44740
44944
  else if(currStrand == "C''") { //linker
44741
44945
  return '#FF0000';
@@ -45438,8 +45642,8 @@ class HlUpdate {
45438
45642
  updateHlObjects(bForceHighlight) { let ic = this.icn3d; ic.icn3dui;
45439
45643
  ic.hlObjectsCls.removeHlObjects();
45440
45644
 
45441
- if((ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length < Object.keys(ic.atoms).length) || bForceHighlight) {
45442
- ic.hlObjectsCls.addHlObjects();
45645
+ if((ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length < Object.keys(ic.dAtoms).length) || bForceHighlight) {
45646
+ if(ic.bShowHighlight === undefined || ic.bShowHighlight) ic.hlObjectsCls.addHlObjects();
45443
45647
  ic.definedSetsCls.setMode('selection');
45444
45648
  }
45445
45649
  }
@@ -46519,8 +46723,11 @@ class LineGraph {
46519
46723
 
46520
46724
  // try {
46521
46725
  if(!template) {
46522
- let allPromise = Promise.allSettled(pdbAjaxArray);
46523
- ic.pdbDataArray = await allPromise;
46726
+ //let allPromise = Promise.allSettled(pdbAjaxArray);
46727
+ //ic.pdbDataArray = await allPromise;
46728
+
46729
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46730
+
46524
46731
  await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46525
46732
  }
46526
46733
  else {
@@ -46631,6 +46838,7 @@ class LineGraph {
46631
46838
  }
46632
46839
 
46633
46840
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
46841
+ if(!ic.domainid2score) ic.domainid2score = {};
46634
46842
 
46635
46843
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
46636
46844
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
@@ -46642,7 +46850,7 @@ class LineGraph {
46642
46850
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtomsArray[k]);
46643
46851
  let resiSum = atomFirst.resi + ':' + atomLast.resi;
46644
46852
  //let domainid = chainid + '-' + k + '_' + Object.keys(domainAtomsArray[k]).length;
46645
- let domainid = chainid + '-' + k + '_' + resiSum;
46853
+ let domainid = chainid + ',' + k + '_' + resiSum;
46646
46854
  ic.domainid2pdb[domainid] = pdb_target;
46647
46855
 
46648
46856
  if(!template) {
@@ -46672,30 +46880,14 @@ class LineGraph {
46672
46880
  }
46673
46881
  }
46674
46882
 
46675
- try {
46883
+ //try {
46676
46884
  if(!template) {
46677
46885
  let dataArray2 = [];
46678
46886
 
46679
46887
  // let allPromise = Promise.allSettled(ajaxArray);
46680
46888
  // dataArray2 = await allPromise;
46681
46889
 
46682
- //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46683
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46684
-
46685
- for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46686
- let currAjaxArray = [];
46687
- if(i == il - 1) { // last one
46688
- currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
46689
- }
46690
- else {
46691
- currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
46692
- }
46693
-
46694
- let currPromise = Promise.allSettled(currAjaxArray);
46695
- let currDataArray = await currPromise;
46696
-
46697
- dataArray2 = dataArray2.concat(currDataArray);
46698
- }
46890
+ dataArray2 = await this.promiseWithFixedJobs(ajaxArray);
46699
46891
 
46700
46892
  let bRound1 = true;
46701
46893
  await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1);
@@ -46715,12 +46907,14 @@ class LineGraph {
46715
46907
  let pdbAjaxArray = [];
46716
46908
  pdbAjaxArray.push(pdbAjax);
46717
46909
 
46718
- let allPromise2 = Promise.allSettled(pdbAjaxArray);
46719
- ic.pdbDataArray = await allPromise2;
46910
+ //let allPromise2 = Promise.allSettled(pdbAjaxArray);
46911
+ //ic.pdbDataArray = await allPromise2;
46912
+
46913
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46720
46914
 
46721
46915
  for(let domainid in ic.domainid2refpdbname) {
46722
- let refpdbname = ic.domainid2refpdbname[domainid];
46723
- let chainid = domainid.substr(0, domainid.indexOf('-'));
46916
+ ic.domainid2refpdbname[domainid];
46917
+ domainid.substr(0, domainid.indexOf(','));
46724
46918
 
46725
46919
  let pdb_target = ic.domainid2pdb[domainid];
46726
46920
  for(let index = 0, indexl = ic.pdbDataArray.length; index < indexl; ++index) {
@@ -46740,11 +46934,14 @@ class LineGraph {
46740
46934
  }
46741
46935
 
46742
46936
  let dataArray3 = [];
46743
- let allPromise = Promise.allSettled(ajaxArray);
46744
- dataArray3 = await allPromise;
46937
+ //let allPromise = Promise.allSettled(ajaxArray);
46938
+ //dataArray3 = await allPromise;
46939
+
46940
+ dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
46745
46941
 
46746
46942
  await thisClass.parseAlignData(dataArray3, domainidpairArray3);
46747
46943
  }
46944
+ /*
46748
46945
  }
46749
46946
  catch(err) {
46750
46947
  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...";
@@ -46756,17 +46953,23 @@ class LineGraph {
46756
46953
  }
46757
46954
  //console.log("Error in aligning with TM-align...");
46758
46955
  return;
46759
- }
46956
+ }
46957
+ */
46760
46958
  }
46761
46959
 
46762
46960
  getTemplateList(chainid) { let ic = this.icn3d; ic.icn3dui;
46763
- let domainid2refpdbname = {};
46961
+ let domainid2refpdbname = {}, domainid2score = {};
46764
46962
 
46765
46963
  for(let i = 0, il = ic.chainid2refpdbname[chainid].length; i < il; ++i) {
46766
46964
  let refpdbname_domainid = ic.chainid2refpdbname[chainid][i].split('|');
46767
46965
  domainid2refpdbname[refpdbname_domainid[1]] = refpdbname_domainid[0];
46768
46966
  }
46769
46967
 
46968
+ for(let i = 0, il = ic.chainid2score[chainid].length; i < il; ++i) {
46969
+ let score_domainid = ic.chainid2score[chainid][i].split('|');
46970
+ domainid2score[score_domainid[1]] = score_domainid[0];
46971
+ }
46972
+
46770
46973
  let domainidArray = Object.keys(domainid2refpdbname);
46771
46974
  domainidArray.sort(function(id1, id2) {
46772
46975
  let resi1 = parseInt(id1.substr(id1.lastIndexOf('_') + 1));
@@ -46774,13 +46977,28 @@ class LineGraph {
46774
46977
  return resi1 - resi2;
46775
46978
  });
46776
46979
 
46777
- let chainList = '';
46980
+ let refpdbnameList = '';
46778
46981
  for(let i = 0, il = domainidArray.length; i < il; ++i) {
46779
- chainList += domainid2refpdbname[domainidArray[i]];
46780
- if(i < il - 1) chainList += ", ";
46982
+ refpdbnameList += domainid2refpdbname[domainidArray[i]];
46983
+ if(i < il - 1) refpdbnameList += ", ";
46781
46984
  }
46782
46985
 
46783
- return chainList;
46986
+ let scoreList = '', seqidList = '', nresAlignList = '';
46987
+ for(let i = 0, il = domainidArray.length; i < il; ++i) {
46988
+ let itemArray = domainid2score[domainidArray[i]].split('_');
46989
+
46990
+ scoreList += itemArray[0];
46991
+ seqidList += itemArray[1];
46992
+ nresAlignList += itemArray[2];
46993
+
46994
+ if(i < il - 1) {
46995
+ scoreList += ", ";
46996
+ seqidList += ", ";
46997
+ nresAlignList += ", ";
46998
+ }
46999
+ }
47000
+
47001
+ return {'refpdbnameList': refpdbnameList, 'scoreList': scoreList, 'seqidList': seqidList, 'nresAlignList': nresAlignList};
46784
47002
  }
46785
47003
 
46786
47004
  async parseAlignData(dataArray, domainidpairArray, bRound1) { let ic = this.icn3d, me = ic.icn3dui;
@@ -46789,33 +47007,35 @@ class LineGraph {
46789
47007
  let tmscoreThreshold = 0.4; // 0.4; //0.5;
46790
47008
 
46791
47009
  // find the best alignment for each chain
46792
- let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
47010
+ let domainid2segs = {}, chainid2segs = {};
46793
47011
 
46794
47012
  if(!ic.chainid2refpdbname) ic.chainid2refpdbname = {};
47013
+ if(!ic.chainid2score) ic.chainid2score = {};
46795
47014
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
47015
+ if(!ic.domainid2score) ic.domainid2score = {};
46796
47016
  if(!ic.domainid2ig2kabat) ic.domainid2ig2kabat = {};
46797
47017
  if(!ic.domainid2ig2imgt) ic.domainid2ig2imgt = {};
46798
47018
 
46799
- // ic.chainid2refpdbname = {};
46800
- // ic.domainid2refpdbname = {};
46801
- // ic.domainid2ig2kabat = {};
46802
- // ic.domainid2ig2imgt = {};
46803
-
46804
47019
  let minResidues = 20;
46805
47020
 
46806
47021
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
46807
47022
  //let queryData = (me.bNode) ? dataArray[i] : dataArray[i].value; //[0];
46808
47023
  let queryData = dataArray[i].value; //[0];
46809
47024
 
46810
- if(!queryData) {
47025
+ if(!queryData || queryData.length == 0) {
46811
47026
  if(!me.bNode) console.log("The alignment data for " + domainidpairArray[i] + " is unavailable...");
46812
47027
  continue;
46813
47028
  }
46814
-
46815
- if(queryData.length == 0) continue;
46816
47029
 
47030
+ //let domainid_index = domainidpairArray[i].split(',');
47031
+ //let domainid = domainid_index[0];
47032
+ let domainid = domainidpairArray[i].substr(0, domainidpairArray[i].indexOf('|'));
47033
+ let refpdbname = domainidpairArray[i].substr(domainidpairArray[i].indexOf('|') + 1);
47034
+ //let chainid = domainid.split('-')[0];
47035
+
46817
47036
  if(!bRound1) {
46818
47037
  if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < minResidues) {
47038
+ if(!me.bNode) console.log("domainid " + domainid + " and refpdbname " + refpdbname + " were skipped due to a TM-score less than " + tmscoreThreshold);
46819
47039
  continue;
46820
47040
  }
46821
47041
  }
@@ -46827,12 +47047,6 @@ class LineGraph {
46827
47047
  continue;
46828
47048
  }
46829
47049
  }
46830
-
46831
- //let domainid_index = domainidpairArray[i].split(',');
46832
- //let domainid = domainid_index[0];
46833
- let domainid = domainidpairArray[i].substr(0, domainidpairArray[i].indexOf('|'));
46834
- let refpdbname = domainidpairArray[i].substr(domainidpairArray[i].indexOf('|') + 1);
46835
- //let chainid = domainid.split('-')[0];
46836
47050
 
46837
47051
  if(!bRound1) {
46838
47052
  if(!me.bNode) console.log("refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
@@ -46849,16 +47063,16 @@ class LineGraph {
46849
47063
  for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
46850
47064
  let seg = queryData[0].segs[i];
46851
47065
 
46852
- if(seg.q_start.indexOf('2150') != -1 || seg.q_start.indexOf('2250') != -1) {
47066
+ if(seg.q_start.indexOf('2550') != -1) {
46853
47067
  bBstrand = true;
46854
47068
  }
46855
- else if(seg.q_start.indexOf('3150') != -1 || seg.q_start.indexOf('3250') != -1) {
47069
+ else if(seg.q_start.indexOf('3550') != -1) {
46856
47070
  bCstrand = true;
46857
47071
  }
46858
- else if(seg.q_start.indexOf('7150') != -1 || seg.q_start.indexOf('7250') != -1) {
47072
+ else if(seg.q_start.indexOf('7550') != -1) {
46859
47073
  bEstrand = true;
46860
47074
  }
46861
- else if(seg.q_start.indexOf('8150') != -1 || seg.q_start.indexOf('8250') != -1) {
47075
+ else if(seg.q_start.indexOf('8550') != -1) {
46862
47076
  bFstrand = true;
46863
47077
  }
46864
47078
 
@@ -46869,35 +47083,25 @@ class LineGraph {
46869
47083
  //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
46870
47084
  if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
46871
47085
  if(!me.bNode) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
46872
- if(ic.domainid2refpdbname[domainid] == refpdbname) delete ic.domainid2refpdbname[domainid];
47086
+ if(ic.domainid2refpdbname[domainid] == refpdbname) {
47087
+ delete ic.domainid2refpdbname[domainid];
47088
+ delete ic.domainid2score[domainid];
47089
+ }
46873
47090
  continue;
46874
47091
  }
46875
47092
  }
46876
47093
 
46877
47094
  if(!bRound1) {
46878
47095
  console.log("domainid: " + domainid);
46879
-
46880
- if(!domainid2score.hasOwnProperty(domainid) || queryData[0].score > domainid2score[domainid]) {
46881
- domainid2score[domainid] = queryData[0].score;
46882
-
46883
- ic.domainid2refpdbname[domainid] = refpdbname;
46884
- domainid2segs[domainid] = queryData[0].segs;
46885
- ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
46886
- ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46887
- }
46888
47096
  }
46889
- else {
46890
- //let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
46891
- let mixScore = queryData[0].score;
46892
47097
 
46893
- if(!domainid2score.hasOwnProperty(domainid) || mixScore > domainid2score[domainid]) {
46894
- domainid2score[domainid] = mixScore;
46895
-
46896
- ic.domainid2refpdbname[domainid] = refpdbname;
46897
- domainid2segs[domainid] = queryData[0].segs;
46898
- ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
46899
- ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46900
- }
47098
+ if(!ic.domainid2score.hasOwnProperty(domainid) || queryData[0].score >= ic.domainid2score[domainid].split('_')[0]) {
47099
+ ic.domainid2score[domainid] = queryData[0].score + '_' + queryData[0].frac_identical + '_' + queryData[0].num_res ;
47100
+
47101
+ ic.domainid2refpdbname[domainid] = refpdbname;
47102
+ domainid2segs[domainid] = queryData[0].segs;
47103
+ ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
47104
+ ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46901
47105
  }
46902
47106
  }
46903
47107
 
@@ -46912,7 +47116,7 @@ class LineGraph {
46912
47116
  let pdbAjaxArray = [];
46913
47117
  let refpdbname = ic.domainid2refpdbname[domainid];
46914
47118
  //let pdbid = domainid.substr(0, domainid.indexOf('_'));
46915
- let chainid = domainid.substr(0, domainid.indexOf('-'));
47119
+ let chainid = domainid.substr(0, domainid.indexOf(','));
46916
47120
 
46917
47121
  //if(ic.refpdbHash.hasOwnProperty(pdbid)) {
46918
47122
  if(ic.refpdbHash.hasOwnProperty(chainid)) {
@@ -46935,8 +47139,10 @@ class LineGraph {
46935
47139
  pdbAjaxArray.push(pdbAjax);
46936
47140
  }
46937
47141
 
46938
- let allPromise2 = Promise.allSettled(pdbAjaxArray);
46939
- ic.pdbDataArray = await allPromise2;
47142
+ //let allPromise2 = Promise.allSettled(pdbAjaxArray);
47143
+ //ic.pdbDataArray = await allPromise2;
47144
+
47145
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46940
47146
 
46941
47147
  let pdb_target = ic.domainid2pdb[domainid];
46942
47148
  for(let index = 0, indexl = ic.pdbDataArray.length; index < indexl; ++index) {
@@ -46959,49 +47165,46 @@ class LineGraph {
46959
47165
  //let allPromise = Promise.allSettled(ajaxArray);
46960
47166
  //dataArray3 = await allPromise;
46961
47167
 
46962
- //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46963
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46964
-
46965
- for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46966
- let currAjaxArray = [];
46967
- if(i == il - 1) { // last one
46968
- currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
46969
- }
46970
- else {
46971
- currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
46972
- }
46973
-
46974
- let currPromise = Promise.allSettled(currAjaxArray);
46975
- let currDataArray = await currPromise;
46976
-
46977
- dataArray3 = dataArray3.concat(currDataArray);
46978
- }
47168
+ dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
46979
47169
 
46980
47170
  await thisClass.parseAlignData(dataArray3, domainidpairArray3, false);
46981
47171
 
46982
47172
  // end of round 2
46983
47173
  return;
46984
47174
  }
46985
-
47175
+
46986
47176
  // combine domainid into chainid
46987
47177
  let processedChainid = {};
46988
47178
  for(let domainid in ic.domainid2refpdbname) {
46989
- let chainid = domainid.split('-')[0];
47179
+ // remove the first round template
47180
+ if(ic.domainid2refpdbname[domainid].substr(0,1) == '1') {
47181
+ delete ic.domainid2refpdbname[domainid];
47182
+ delete ic.domainid2score[domainid];
47183
+ continue;
47184
+ }
47185
+
47186
+ let chainid = domainid.split(',')[0];
46990
47187
 
46991
- if(!processedChainid.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
47188
+ if(!processedChainid.hasOwnProperty(chainid)) {
47189
+ ic.chainid2refpdbname[chainid] = [];
47190
+ ic.chainid2score[chainid] = [];
47191
+ }
46992
47192
  processedChainid[chainid] = 1;
46993
47193
 
46994
47194
  if(!ic.chainid2refpdbname.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
46995
47195
  ic.chainid2refpdbname[chainid].push(ic.domainid2refpdbname[domainid] + '|' + domainid);
47196
+
47197
+ if(!ic.chainid2score.hasOwnProperty(chainid)) ic.chainid2score[chainid] = [];
47198
+ ic.chainid2score[chainid].push(ic.domainid2score[domainid] + '|' + domainid);
46996
47199
  }
46997
-
47200
+
46998
47201
  // combine domainid into chainid
46999
47202
  for(let domainid in domainid2segs) {
47000
- let chainid = domainid.split('-')[0];
47203
+ let chainid = domainid.split(',')[0];
47001
47204
  if(!chainid2segs[chainid]) chainid2segs[chainid] = [];
47002
47205
  chainid2segs[chainid] = chainid2segs[chainid].concat(domainid2segs[domainid]);
47003
47206
  }
47004
-
47207
+
47005
47208
  // assign ic.resid2refnum, ic.refnum2residArray, ic.chainsMapping
47006
47209
  if(!ic.resid2refnum) ic.resid2refnum = {};
47007
47210
  if(!ic.refnum2residArray) ic.refnum2residArray = {};
@@ -47014,11 +47217,18 @@ class LineGraph {
47014
47217
 
47015
47218
  let refpdbnameArray = ic.chainid2refpdbname[chainid];
47016
47219
 
47017
- let chainList = this.getTemplateList(chainid);
47220
+ let result = this.getTemplateList(chainid);
47221
+ let refpdbnameList = result.refpdbnameList;
47222
+ let scoreList = result.scoreList;
47223
+ let seqidList = result.seqidList;
47224
+ let nresAlignList = result.nresAlignList;
47018
47225
 
47019
- //if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
47020
- if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
47021
- ic.refPdbList.push("The reference PDB(s) for chain " + chainid + " are " + chainList);
47226
+ 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 + ".";
47227
+ if(!me.bNode) {
47228
+ console.log(message);
47229
+ me.htmlCls.clickMenuCls.setLogCmd(message, true);
47230
+ }
47231
+ ic.refPdbList.push(message);
47022
47232
 
47023
47233
  let prevStrand;
47024
47234
  let bCd19 = refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
@@ -47088,51 +47298,52 @@ class LineGraph {
47088
47298
  getLabelFromRefnum(oriRefnum, prevStrand, bCd19) { let ic = this.icn3d; ic.icn3dui;
47089
47299
  let refnum = parseInt(oriRefnum);
47090
47300
 
47091
- // A-: 10xx
47092
- // A: 11xx
47093
- // A+ continue A
47094
- // A': 12xx
47095
- // B: 21xx
47096
- // C: 32xx
47097
- // C': 42xx
47098
- // C'': 51xx, 52xx
47099
- // D: 61xx
47100
- // E: 71xx
47101
- // E+: continue E
47102
- // F: 82xx
47103
- // G: 91xx, 92xx
47104
- // G+: continue G
47105
-
47106
- // if(refnum < 100) return " " + oriRefnum;
47107
- // else if(refnum >= 100 && refnum < 1000) {
47108
- // if(bCd19) return " " + oriRefnum;
47109
- // else return "A^" + oriRefnum;
47110
- // }
47111
- if(refnum < 900) return undefined;
47112
- else if(refnum >= 900 && refnum < 1000) return " " + oriRefnum;
47113
- else if(refnum >= 1000 && refnum < 1100) return "A-" + oriRefnum;
47114
- else if(refnum >= 1100 && refnum < 1200) return "A" + oriRefnum; // could be A+
47115
- else if(refnum >= 1200 && refnum < 1300) return "A'" + oriRefnum;
47116
- //else if(refnum >= 1300 && refnum < 1400) return "A+" + oriRefnum;
47117
- else if(refnum >= 1300 && refnum < 2000) {
47118
- if(prevStrand && prevStrand.substr(0, 1) == 'A') {
47119
- return prevStrand + oriRefnum;
47120
- }
47121
- else {
47122
- return "A" + oriRefnum;
47123
- }
47124
- }
47125
- else if(refnum >= 2000 && refnum < 3000) return "B" + oriRefnum;
47126
- else if(refnum >= 3000 && refnum < 4000) return "C" + oriRefnum;
47127
- else if(refnum >= 4000 && refnum < 5000) return "C'" + oriRefnum;
47128
- else if(refnum >= 5000 && refnum < 6000) return "C''" + oriRefnum;
47129
- else if(refnum >= 6000 && refnum < 7000) return "D" + oriRefnum;
47130
- else if(refnum >= 7000 && refnum < 8000) return "E" + oriRefnum; // could be E+
47131
- else if(refnum >= 8000 && refnum < 9000) return "F" + oriRefnum;
47132
- else if(refnum >= 9000 && refnum < 9300) return "G" + oriRefnum; // could be G+
47133
- //else if(refnum >= 9400 && refnum < 9500) return "G+" + oriRefnum;
47134
- else if(refnum >= 9300) return "G" + oriRefnum;
47135
- }
47301
+ //N-terminus = 0999-0001
47302
+ //A--- = 12xx
47303
+ //A-- = 13xx
47304
+ //A- = 14xx
47305
+ //A = 15xx (anchor 1550)
47306
+ //A+ = 16xx
47307
+ //A' = 18xx (anchor 1850)
47308
+ //B = 25xx (anchor 2550)
47309
+ //C-- = 33xx
47310
+ //C- = 34xx
47311
+ //C = 35xx (anchor 3550)
47312
+ //C' = 45xx (anchor 4550)
47313
+ //C'' = 55xx (anchor 5550)
47314
+ //D = 65xx (anchor 3550)
47315
+ //E = 75xx (anchor 7550)
47316
+ //E+ = 76xx
47317
+ //F = 85xx (anchor 8550)
47318
+ //G = 95xx (anchor 9550)
47319
+ //G+ = 96xx
47320
+ //G++ = 97xx
47321
+ //C-terminus = 9901-9999 (no anchor, numbering going forward)
47322
+
47323
+ // loops may have numbers such as 1310, 1410
47324
+
47325
+ if(refnum < 1000) return undefined;
47326
+ else if(refnum >= 1200 && refnum < 1290) return "A---" + oriRefnum;
47327
+ else if(refnum >= 1320 && refnum < 1390) return "A--" + oriRefnum;
47328
+ else if(refnum >= 1420 && refnum < 1490) return "A-" + oriRefnum;
47329
+ else if(refnum >= 1520 && refnum < 1590) return "A" + oriRefnum;
47330
+ else if(refnum >= 1620 && refnum < 1690) return "A+" + oriRefnum;
47331
+ else if(refnum >= 1820 && refnum < 1890) return "A'" + oriRefnum;
47332
+ else if(refnum >= 2000 && refnum < 2900) return "B" + oriRefnum;
47333
+ else if(refnum >= 3300 && refnum < 3390) return "C--" + oriRefnum;
47334
+ else if(refnum >= 3420 && refnum < 3490) return "C-" + oriRefnum;
47335
+ else if(refnum >= 3520 && refnum < 3590) return "C" + oriRefnum;
47336
+ else if(refnum >= 4000 && refnum < 4900) return "C'" + oriRefnum;
47337
+ else if(refnum >= 5000 && refnum < 5900) return "C''" + oriRefnum;
47338
+ else if(refnum >= 6000 && refnum < 6900) return "D" + oriRefnum;
47339
+ else if(refnum >= 7500 && refnum < 7590) return "E" + oriRefnum;
47340
+ else if(refnum >= 7620 && refnum < 7900) return "E+" + oriRefnum;
47341
+ else if(refnum >= 8000 && refnum < 8900) return "F" + oriRefnum;
47342
+ else if(refnum >= 9500 && refnum < 9590) return "G" + oriRefnum;
47343
+ else if(refnum >= 9620 && refnum < 9690) return "G+" + oriRefnum;
47344
+ else if(refnum >= 9720 && refnum < 9790) return "G++" + oriRefnum;
47345
+ else if(refnum > 9900) return undefined;
47346
+ else return " " + oriRefnum; }
47136
47347
 
47137
47348
  async parseCustomRefFile(data) { let ic = this.icn3d; ic.icn3dui;
47138
47349
  ic.bShowCustomRefnum = true;
@@ -47314,6 +47525,32 @@ class LineGraph {
47314
47525
  return refData;
47315
47526
  }
47316
47527
  }
47528
+
47529
+ async promiseWithFixedJobs(ajaxArray) { let ic = this.icn3d, me = ic.icn3dui;
47530
+ let dataArray3 = [];
47531
+ //let allPromise = Promise.allSettled(ajaxArray);
47532
+ //dataArray3 = await allPromise;
47533
+
47534
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
47535
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
47536
+
47537
+ for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
47538
+ let currAjaxArray = [];
47539
+ if(i == il - 1) { // last one
47540
+ currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
47541
+ }
47542
+ else {
47543
+ currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
47544
+ }
47545
+
47546
+ let currPromise = Promise.allSettled(currAjaxArray);
47547
+ let currDataArray = await currPromise;
47548
+
47549
+ dataArray3 = dataArray3.concat(currDataArray);
47550
+ }
47551
+
47552
+ return dataArray3;
47553
+ }
47317
47554
  }
47318
47555
 
47319
47556
  /**
@@ -48622,7 +48859,7 @@ class ViewInterPairs {
48622
48859
 
48623
48860
  if(ic.bD3 === undefined) {
48624
48861
  //let url = "https://d3js.org/d3.v4.min.js";
48625
- let url = "https://www.ncbi.nlm.nih.gov/Structure/icn3d/script/d3v4-force-all.min.js";
48862
+ let url = "./script/d3v4-force-all.min.js";
48626
48863
  await me.getAjaxPromise(url, 'script');
48627
48864
 
48628
48865
  ic.bD3 = true;
@@ -49897,7 +50134,7 @@ class AlignParser {
49897
50134
  for(let j = 0, jl = mmdbTmp.molecules.length; j < jl; ++j) {
49898
50135
  let molecule = mmdbTmp.molecules[j];
49899
50136
  let molid = molecule.moleculeId;
49900
- let chainName = molecule.chain.trim();
50137
+ let chainName = molecule.chain.trim().replace(/_/g, ''); // change "A_1" to "A1"
49901
50138
  if(chainNameHash[chainName] === undefined) {
49902
50139
  chainNameHash[chainName] = 1;
49903
50140
  }
@@ -50308,6 +50545,8 @@ class ChainalignParser {
50308
50545
 
50309
50546
  let queryData = {}; // check whether undefined
50310
50547
 
50548
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
50549
+
50311
50550
  this.processAlign(align, index, queryData, bEqualMmdbid, bEqualChain);
50312
50551
  }
50313
50552
 
@@ -50405,6 +50644,8 @@ class ChainalignParser {
50405
50644
  continue;
50406
50645
  }
50407
50646
 
50647
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid1 + " with " + mmdbid2, false);
50648
+
50408
50649
  let bNoAlert = true;
50409
50650
  let bAligned = this.processAlign(align, i, queryData, bEqualMmdbid, bEqualChain, bNoAlert);
50410
50651
 
@@ -50855,6 +51096,8 @@ class ChainalignParser {
50855
51096
  let bEqualMmdbid = (mmdbid_q == mmdbid_t);
50856
51097
  let bEqualChain = (chain_q == chain_t);
50857
51098
 
51099
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
51100
+
50858
51101
  this.processAlign(align, index-1, queryData, bEqualMmdbid, bEqualChain);
50859
51102
  }
50860
51103
  }
@@ -50915,6 +51158,7 @@ class ChainalignParser {
50915
51158
  ic.qt_start_end[index] = align[0].segs;
50916
51159
 
50917
51160
  let rmsd = align[0].super_rmsd;
51161
+ console.log();
50918
51162
 
50919
51163
  let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
50920
51164
  if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
@@ -51184,10 +51428,10 @@ class Dsn6Parser {
51184
51428
  // https://edmaps.rcsb.org/maps/1kq2_fofc.dsn6
51185
51429
 
51186
51430
  let url = "https://edmaps.rcsb.org/maps/" + pdbid.toLowerCase() + "_" + type + ".dsn6";
51187
- await this.dsn6ParserBase(url, type, sigma);
51431
+ await this.dsn6ParserBase(url, type, sigma, 'url', true);
51188
51432
  }
51189
51433
 
51190
- async dsn6ParserBase(url, type, sigma) { let ic = this.icn3d, me = ic.icn3dui;
51434
+ async dsn6ParserBase(url, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
51191
51435
  let thisClass = this;
51192
51436
 
51193
51437
  //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
@@ -51201,7 +51445,7 @@ class Dsn6Parser {
51201
51445
  }
51202
51446
  else {
51203
51447
  let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'rcsbEdmaps');
51204
- thisClass.loadDsn6Data(arrayBuffer, type, sigma);
51448
+ sigma = thisClass.loadDsn6Data(arrayBuffer, type, sigma, location, bInputSigma);
51205
51449
 
51206
51450
  if(type == '2fofc') {
51207
51451
  ic.bAjax2fofc = true;
@@ -51212,9 +51456,11 @@ class Dsn6Parser {
51212
51456
 
51213
51457
  ic.setOptionCls.setOption('map', type);
51214
51458
  }
51459
+
51460
+ return sigma;
51215
51461
  }
51216
51462
 
51217
- loadDsn6Data(dsn6data, type, sigma) { let ic = this.icn3d; ic.icn3dui;
51463
+ loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51218
51464
  // DSN6 http://www.uoxray.uoregon.edu/tnt/manual/node104.html
51219
51465
  // BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
51220
51466
 
@@ -51263,9 +51509,9 @@ class Dsn6Parser {
51263
51509
  }
51264
51510
  }
51265
51511
 
51266
- header.zStart = intView[ 2 ];
51267
51512
  header.xStart = intView[ 0 ]; // NXSTART
51268
51513
  header.yStart = intView[ 1 ];
51514
+ header.zStart = intView[ 2 ];
51269
51515
 
51270
51516
  header.xExtent = intView[ 3 ]; // NX
51271
51517
  header.yExtent = intView[ 4 ];
@@ -51301,6 +51547,7 @@ class Dsn6Parser {
51301
51547
  let zBlocks = Math.ceil(header.zExtent / 8);
51302
51548
 
51303
51549
  // loop over blocks
51550
+ let maxValue = -999;
51304
51551
  for(let zz = 0; zz < zBlocks; ++zz) {
51305
51552
  for(let yy = 0; yy < yBlocks; ++yy) {
51306
51553
  for(let xx = 0; xx < xBlocks; ++xx) {
@@ -51316,6 +51563,7 @@ class Dsn6Parser {
51316
51563
  if(x < header.xExtent && y < header.yExtent && z < header.zExtent) {
51317
51564
  let idx =((((x * header.yExtent) + y) * header.zExtent) + z);
51318
51565
  data[ idx ] =(byteView[ offset ] - summand) / divisor;
51566
+ if(data[ idx ] > maxValue) maxValue = data[ idx ];
51319
51567
  ++offset;
51320
51568
  } else {
51321
51569
  offset += 8 - i;
@@ -51328,6 +51576,10 @@ class Dsn6Parser {
51328
51576
  }
51329
51577
  }
51330
51578
 
51579
+ if(!bInputSigma) {
51580
+ sigma = this.setSigma(maxValue, location, type, sigma);
51581
+ }
51582
+
51331
51583
  if(type == '2fofc') {
51332
51584
  ic.mapData.header2 = header;
51333
51585
  ic.mapData.data2 = data;
@@ -51342,6 +51594,32 @@ class Dsn6Parser {
51342
51594
  ic.mapData.type = type;
51343
51595
  ic.mapData.sigma = sigma;
51344
51596
  }
51597
+
51598
+ return sigma;
51599
+ }
51600
+
51601
+ setSigma(maxValue, location, type, sigma) { let ic = this.icn3d, me = ic.icn3dui;
51602
+ let inputId;
51603
+ if(location == 'file') {
51604
+ inputId = 'dsn6sigma' + type;
51605
+ }
51606
+ else if(location == 'url') {
51607
+ inputId = 'dsn6sigmaurl' + type;
51608
+ }
51609
+
51610
+ let factor = (type == '2fofc') ? 0.5 : 0.3;
51611
+
51612
+ if(inputId) {
51613
+ if(!($("#" + me.pre + inputId).val())) {
51614
+ sigma = (factor * maxValue).toFixed(2);
51615
+ $("#" + me.pre + inputId).val(sigma);
51616
+ }
51617
+ else {
51618
+ sigma = $("#" + me.pre + inputId).val();
51619
+ }
51620
+ }
51621
+
51622
+ return sigma;
51345
51623
  }
51346
51624
 
51347
51625
  getMatrix(header) { let ic = this.icn3d; ic.icn3dui;
@@ -51415,7 +51693,9 @@ class Dsn6Parser {
51415
51693
  let reader = new FileReader();
51416
51694
  reader.onload = function(e) { let ic = thisClass.icn3d;
51417
51695
  let arrayBuffer = e.target.result; // or = reader.result;
51418
- thisClass.loadDsn6Data(arrayBuffer, type, sigma);
51696
+
51697
+ sigma = thisClass.loadDsn6Data(arrayBuffer, type, sigma, 'file');
51698
+
51419
51699
  if(type == '2fofc') {
51420
51700
  ic.bAjax2fofc = true;
51421
51701
  }
@@ -51423,21 +51703,1005 @@ class Dsn6Parser {
51423
51703
  ic.bAjaxfofc = true;
51424
51704
  }
51425
51705
  ic.setOptionCls.setOption('map', type);
51426
- me.htmlCls.clickMenuCls.setLogCmd('load dsn6 file ' + $("#" + ic.pre + "dsn6file" + type).val(), false);
51706
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
51427
51707
  };
51428
51708
  reader.readAsArrayBuffer(file);
51429
51709
  }
51430
51710
  }
51431
51711
 
51432
51712
  loadDsn6FileUrl(type) {var ic = this.icn3d, me = ic.icn3dui;
51713
+ let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
51714
+ let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
51715
+ if(!url) {
51716
+ alert("Please input the file URL before clicking 'Load'");
51717
+ }
51718
+ else {
51719
+ sigma = this.dsn6ParserBase(url, type, sigma, 'url');
51720
+ me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file dsn6 | ' + encodeURIComponent(url), true);
51721
+ }
51722
+ }
51723
+
51724
+ }
51725
+
51726
+ /**
51727
+ * @file Ccp4 Parser
51728
+ * @author Marcin Wojdyr <wojdyr@gmail.com>
51729
+ * @private
51730
+ * Modified by Jiyao Wang / https://github.com/ncbi/icn3d
51731
+ */
51732
+
51733
+ class Ccp4Parser {
51734
+ constructor(icn3d) {
51735
+ this.icn3d = icn3d;
51736
+ }
51737
+
51738
+ async ccp4ParserBase(url, type, sigma, location) { let ic = this.icn3d, me = ic.icn3dui;
51739
+ let thisClass = this;
51740
+
51741
+ //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
51742
+ // if(type == '2fofc' && ic.bAjax2fofcccp4) {
51743
+ // ic.mapData.sigma2 = sigma;
51744
+ // ic.setOptionCls.setOption('map', type);
51745
+ // }
51746
+ // else if(type == 'fofc' && ic.bAjaxfofcccp4) {
51747
+ // ic.mapData.sigma = sigma;
51748
+ // ic.setOptionCls.setOption('map', type);
51749
+ // }
51750
+ // else {
51751
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', '');
51752
+ let bInputSigma = true;
51753
+ sigma = thisClass.load_map_from_buffer(arrayBuffer, type, sigma, location, bInputSigma);
51754
+
51755
+ // if(type == '2fofc') {
51756
+ // ic.bAjax2fofcccp4 = true;
51757
+ // }
51758
+ // else if(type == 'fofc') {
51759
+ // ic.bAjaxfofcccp4 = true;
51760
+ // }
51761
+
51762
+ ic.setOptionCls.setOption('map', type);
51763
+
51764
+ return sigma;
51765
+ // }
51766
+ }
51767
+
51768
+ // modified from_ccp4() at https://github.com/uglymol/uglymol.github.io/blob/master/src/elmap.js
51769
+ load_map_from_buffer(buf, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51770
+ if (buf.byteLength < 1024) throw Error('File shorter than 1024 bytes.');
51771
+
51772
+ //console.log('buf type: ' + Object.prototype.toString.call(buf));
51773
+ // for now we assume both file and host are little endian
51774
+ const iview = new Int32Array(buf, 0, 256);
51775
+ // word 53 - character string 'MAP ' to identify file type
51776
+ if (iview[52] !== 0x2050414d) throw Error('not a CCP4 map');
51777
+
51778
+ // map has 3 dimensions referred to as columns (fastest changing), rows
51779
+ // and sections (c-r-s)
51780
+ const n_crs = [iview[0], iview[1], iview[2]]; // 108, 108, 108
51781
+ const mode = iview[3]; //2
51782
+ let nb;
51783
+ if (mode === 2) nb = 4;
51784
+ else if (mode === 0) nb = 1;
51785
+ else throw Error('Only Mode 2 and Mode 0 of CCP4 map is supported.');
51786
+
51787
+ const start = [iview[4], iview[5], iview[6]]; // 0,0,0
51788
+ const n_grid = [iview[7], iview[8], iview[9]]; // 108,108,108
51789
+ const nsymbt = iview[23]; // size of extended header in bytes
51790
+ // nsymbt = 1920
51791
+
51792
+ if (1024 + nsymbt + nb*n_crs[0]*n_crs[1]*n_crs[2] !== buf.byteLength) {
51793
+ throw Error('ccp4 file too short or too long');
51794
+ }
51795
+
51796
+ const fview = new Float32Array(buf, 0, buf.byteLength / 4);
51797
+ const grid = new GridArray(n_grid);
51798
+ 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
51799
+
51800
+ // MAPC, MAPR, MAPS - axis corresp to cols, rows, sections (1,2,3 for X,Y,Z)
51801
+ const map_crs = [iview[16], iview[17], iview[18]]; // 2,1,3
51802
+ const ax = map_crs.indexOf(1);
51803
+ const ay = map_crs.indexOf(2);
51804
+ const az = map_crs.indexOf(3);
51805
+
51806
+ const min = fview[19]; // -0.49
51807
+ const max = fview[20]; // 0.94
51808
+ //const sg_number = iview[22];
51809
+ //const lskflg = iview[24];
51810
+
51811
+ if (nsymbt % 4 !== 0) {
51812
+ throw Error('CCP4 map with NSYMBT not divisible by 4 is not supported.');
51813
+ }
51814
+ let data_view;
51815
+ if (mode === 2) data_view = fview;
51816
+ else /* mode === 0 */ data_view = new Int8Array(buf);
51817
+ let idx = (1024 + nsymbt) / nb | 0; //736
51818
+
51819
+ // We assume that if DMEAN and RMS from the header are not clearly wrong
51820
+ // they are what the user wants. Because the map can cover a small part
51821
+ // of the asu and its rmsd may be different than the total rmsd.
51822
+ // let stats = { mean: 0.0, rms: 1.0 };
51823
+ // stats.mean = fview[21]; //0
51824
+ // stats.rms = fview[54]; //0.15
51825
+ // if (stats.mean < min || stats.mean > max || stats.rms <= 0) {
51826
+ // stats = this.calculate_stddev(data_view, idx);
51827
+ // }
51828
+
51829
+ let b1 = 1;
51830
+ let b0 = 0;
51831
+ // if the file was converted by mapmode2to0 - scale the data
51832
+ if (mode === 0 && iview[39] === -128 && iview[40] === 127) { //39:0, 40:0
51833
+ // scaling f(x)=b1*x+b0 such that f(-128)=min and f(127)=max
51834
+ b1 = (max - min) / 255.0;
51835
+ b0 = 0.5 * (min + max + b1);
51836
+ }
51837
+
51838
+ const end = [start[0] + n_crs[0], start[1] + n_crs[1], start[2] + n_crs[2]];
51839
+ let it = [0, 0, 0];
51840
+ let maxValue = -999;
51841
+ for (it[2] = start[2]; it[2] < end[2]; it[2]++) { // sections
51842
+ for (it[1] = start[1]; it[1] < end[1]; it[1]++) { // rows
51843
+ for (it[0] = start[0]; it[0] < end[0]; it[0]++) { // cols
51844
+ let value = b1 * data_view[idx] + b0;
51845
+ grid.set_grid_value(it[ax], it[ay], it[az], value);
51846
+
51847
+ if(value > maxValue) maxValue = value;
51848
+ idx++;
51849
+ }
51850
+ }
51851
+ }
51852
+
51853
+ /*
51854
+ if (expand_symmetry && nsymbt > 0) {
51855
+ const u8view = new Uint8Array(buf);
51856
+ for (let i = 0; i+80 <= nsymbt; i += 80) {
51857
+ let j;
51858
+ let symop = '';
51859
+ for (j = 0; j < 80; ++j) {
51860
+ symop += String.fromCharCode(u8view[1024 + i + j]);
51861
+ }
51862
+ if (/^\s*x\s*,\s*y\s*,\s*z\s*$/i.test(symop)) continue; // skip x,y,z
51863
+ //console.log('sym ops', symop.trim());
51864
+ let mat = this.parse_symop(symop);
51865
+ // Note: we apply here symops to grid points instead of coordinates.
51866
+ // In the cases we came across it is equivalent, but in general not.
51867
+ for (j = 0; j < 3; ++j) {
51868
+ mat[j][3] = Math.round(mat[j][3] * n_grid[j]) | 0;
51869
+ }
51870
+ idx = (1024 + nsymbt) / nb | 0;
51871
+ let xyz = [0, 0, 0];
51872
+ for (it[2] = start[2]; it[2] < end[2]; it[2]++) { // sections
51873
+ for (it[1] = start[1]; it[1] < end[1]; it[1]++) { // rows
51874
+ for (it[0] = start[0]; it[0] < end[0]; it[0]++) { // cols
51875
+ for (j = 0; j < 3; ++j) {
51876
+ xyz[j] = it[ax] * mat[j][0] + it[ay] * mat[j][1] +
51877
+ it[az] * mat[j][2] + mat[j][3];
51878
+ }
51879
+ let value = b1 * data_view[idx] + b0;
51880
+ grid.set_grid_value(xyz[0], xyz[1], xyz[2], value);
51881
+
51882
+ if(value > maxValue) maxValue = value;
51883
+ idx++;
51884
+ }
51885
+ }
51886
+ }
51887
+ }
51888
+ }
51889
+ */
51890
+
51891
+ if(!bInputSigma) {
51892
+ sigma = ic.dsn6ParserCls.setSigma(maxValue, location, type, sigma);
51893
+ }
51894
+
51895
+ if(type == '2fofc') {
51896
+ ic.mapData.ccp4 = 1;
51897
+ ic.mapData.grid2 = grid;
51898
+ ic.mapData.unit_cell2 = unit_cell;
51899
+ ic.mapData.type2 = type;
51900
+ ic.mapData.sigma2 = sigma;
51901
+ }
51902
+ else {
51903
+ ic.mapData.ccp4 = 1;
51904
+ ic.mapData.grid = grid;
51905
+ ic.mapData.unit_cell = unit_cell;
51906
+ ic.mapData.type = type;
51907
+ ic.mapData.sigma = sigma;
51908
+ }
51909
+
51910
+ return sigma;
51911
+ }
51912
+
51913
+ load_maps_from_mtz_buffer(mtz, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51914
+ let is_diff = (type == 'fofc'); // diff: fofc, non-diff: 2fofc
51915
+ let dataArray = mtz.calculate_map(is_diff);
51916
+
51917
+ let mc = mtz.cell;
51918
+ const unit_cell = new UnitCell(mc.a, mc.b, mc.c, mc.alpha, mc.beta, mc.gamma);
51919
+
51920
+ let maxValue = -999;
51921
+ for(let i = 0, il = dataArray.length; i < il; ++i) {
51922
+ if(dataArray[i] > maxValue) maxValue = dataArray[i];
51923
+ }
51924
+
51925
+ if(!bInputSigma) {
51926
+ sigma = ic.dsn6ParserCls.setSigma(maxValue, location, type, sigma);
51927
+ }
51928
+
51929
+ const grid = new GridArray([mtz.nx, mtz.ny, mtz.nz]);
51930
+ grid.values.set(dataArray);
51931
+
51932
+ if(type == '2fofc') {
51933
+ ic.mapData.ccp4 = 1;
51934
+ ic.mapData.grid2 = grid;
51935
+ ic.mapData.unit_cell2 = unit_cell;
51936
+ ic.mapData.type2 = type;
51937
+ ic.mapData.sigma2 = sigma;
51938
+ }
51939
+ else {
51940
+ ic.mapData.ccp4 = 1;
51941
+ ic.mapData.grid = grid;
51942
+ ic.mapData.unit_cell = unit_cell;
51943
+ ic.mapData.type = type;
51944
+ ic.mapData.sigma = sigma;
51945
+ }
51946
+
51947
+ mtz.delete();
51948
+
51949
+ return sigma;
51950
+ }
51951
+
51952
+ // calculate_stddev(a, offset) {
51953
+ // let sum = 0;
51954
+ // let sq_sum = 0;
51955
+ // const alen = a.length;
51956
+ // for (let i = offset; i < alen; i++) {
51957
+ // sum += a[i];
51958
+ // sq_sum += a[i] * a[i];
51959
+ // }
51960
+ // const mean = sum / (alen - offset);
51961
+ // const variance = sq_sum / (alen - offset) - mean * mean;
51962
+ // return {mean: mean, rms: Math.sqrt(variance)};
51963
+ // }
51964
+
51965
+ parse_symop(symop) {
51966
+ const ops = symop.toLowerCase().replace(/\s+/g, '').split(',');
51967
+ if (ops.length !== 3) throw Error('Unexpected symop: ' + symop);
51968
+ let mat = [];
51969
+ for (let i = 0; i < 3; i++) {
51970
+ const terms = ops[i].split(/(?=[+-])/);
51971
+ let row = [0, 0, 0, 0];
51972
+ for (let j = 0; j < terms.length; j++) {
51973
+ const term = terms[j];
51974
+ const sign = (term[0] === '-' ? -1 : 1);
51975
+ let m = terms[j].match(/^[+-]?([xyz])$/);
51976
+ if (m) {
51977
+ const pos = {x: 0, y: 1, z: 2}[m[1]];
51978
+ row[pos] = sign;
51979
+ } else {
51980
+ m = terms[j].match(/^[+-]?(\d)\/(\d)$/);
51981
+ if (!m) throw Error('What is ' + terms[j] + ' in ' + symop);
51982
+ row[3] = sign * Number(m[1]) / Number(m[2]);
51983
+ }
51984
+ }
51985
+ mat.push(row);
51986
+ }
51987
+ return mat;
51988
+ }
51989
+
51990
+ loadCcp4File(type) {let ic = this.icn3d, me = ic.icn3dui;
51991
+ let thisClass = this;
51992
+
51993
+ let file = $("#" + ic.pre + "dsn6file" + type)[0].files[0];
51994
+ let sigma = $("#" + ic.pre + "dsn6sigma" + type).val();
51995
+ if(!file) {
51996
+ alert("Please select a file before clicking 'Load'");
51997
+ }
51998
+ else {
51999
+ me.utilsCls.checkFileAPI();
52000
+ let reader = new FileReader();
52001
+ reader.onload = function(e) { let ic = thisClass.icn3d;
52002
+ let arrayBuffer = e.target.result; // or = reader.result;
52003
+ sigma = thisClass.load_map_from_buffer(arrayBuffer, type, sigma, 'file');
52004
+
52005
+ // if(type == '2fofc') {
52006
+ // ic.bAjax2fofcCcp4 = true;
52007
+ // }
52008
+ // else if(type == 'fofc') {
52009
+ // ic.bAjaxfofcCcp4 = true;
52010
+ // }
52011
+ ic.setOptionCls.setOption('map', type);
52012
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
52013
+ };
52014
+ reader.readAsArrayBuffer(file);
52015
+ }
52016
+ }
52017
+
52018
+ async loadCcp4FileUrl(type) { let ic = this.icn3d, me = ic.icn3dui;
51433
52019
  let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
51434
52020
  let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
51435
52021
  if(!url) {
51436
52022
  alert("Please input the file URL before clicking 'Load'");
51437
52023
  }
51438
52024
  else {
51439
- this.dsn6ParserBase(url, type, sigma);
51440
- me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' | ' + encodeURIComponent(url), true);
52025
+ sigma = await this.ccp4ParserBase(url, type, sigma, 'file');
52026
+
52027
+ me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file ccp4 | ' + encodeURIComponent(url), true);
52028
+ }
52029
+ }
52030
+
52031
+ // Extract a block of density for calculating an isosurface using the
52032
+ // separate marching cubes implementation.
52033
+ extract_block(grid, unit_cell, radius, center, typeDetail) { let ic = this.icn3d; ic.icn3dui;
52034
+ // let grid = this.grid;
52035
+ // let unit_cell = this.unit_cell;
52036
+ if (grid == null || unit_cell == null) { return; }
52037
+ let fc = unit_cell.fractionalize(center);
52038
+
52039
+ let r = [radius / unit_cell.parameters[0],
52040
+ radius / unit_cell.parameters[1],
52041
+ radius / unit_cell.parameters[2]];
52042
+ let grid_min = grid.frac2grid([fc[0] - r[0], fc[1] - r[1], fc[2] - r[2]]);
52043
+ let grid_max = grid.frac2grid([fc[0] + r[0], fc[1] + r[1], fc[2] + r[2]]);
52044
+
52045
+ let size = [grid_max[0] - grid_min[0] + 1,
52046
+ grid_max[1] - grid_min[1] + 1,
52047
+ grid_max[2] - grid_min[2] + 1];
52048
+ let points = [];
52049
+ let values = [];
52050
+ let threshold = 1;
52051
+ let bAtoms = ic.hAtoms && Object.keys(ic.hAtoms).length > 0;
52052
+ for (let i = grid_min[0]; i <= grid_max[0]; i++) {
52053
+ for (let j = grid_min[1]; j <= grid_max[1]; j++) {
52054
+ for (let k = grid_min[2]; k <= grid_max[2]; k++) {
52055
+ let frac = grid.grid2frac(i, j, k);
52056
+ let orth = unit_cell.orthogonalize(frac);
52057
+ points.push(orth);
52058
+
52059
+ // get overlap between map and atoms
52060
+ let positoin = new THREE.Vector3(orth[0], orth[1], orth[2]);
52061
+ let atomsNear = ic.rayCls.getAtomsFromPosition(positoin, threshold, ic.hAtoms);
52062
+
52063
+ let map_value = (atomsNear || !bAtoms) ? grid.get_grid_value(i, j, k) : 0;
52064
+
52065
+ if(typeDetail == 'fofc_pos' && map_value < 0) map_value = 0;
52066
+ if(typeDetail == 'fofc_neg') map_value = (map_value > 0) ? 0 : -map_value;
52067
+
52068
+ values.push(map_value);
52069
+ }
52070
+ }
52071
+ }
52072
+
52073
+ return {size: size, values: values, points: points};
52074
+ // this.block.set(points, values, size);
52075
+ };
52076
+
52077
+ marchingCubes(dims, values, points, isolevel, method) { let ic = this.icn3d; ic.icn3dui;
52078
+ const edgeTable = new Int32Array([
52079
+ 0x0 , 0x0 , 0x202, 0x302, 0x406, 0x406, 0x604, 0x704,
52080
+ 0x804, 0x805, 0xa06, 0xa06, 0xc0a, 0xd03, 0xe08, 0xf00,
52081
+ 0x90 , 0x98 , 0x292, 0x292, 0x496, 0x49e, 0x694, 0x694,
52082
+ 0x894, 0x894, 0xa96, 0xa96, 0xc9a, 0xc92, 0xe91, 0xe90,
52083
+ 0x230, 0x230, 0x33 , 0x13a, 0x636, 0x636, 0x434, 0x43c,
52084
+ 0xa34, 0xa35, 0x837, 0x936, 0xe3a, 0xf32, 0xc31, 0xd30,
52085
+ 0x2a0, 0x2a8, 0xa3 , 0xaa , 0x6a6, 0x6af, 0x5a4, 0x4ac,
52086
+ 0xaa4, 0xaa4, 0x9a6, 0x8a6, 0xfaa, 0xea3, 0xca1, 0xca0,
52087
+ 0x460, 0x460, 0x662, 0x762, 0x66 , 0x66 , 0x265, 0x364,
52088
+ 0xc64, 0xc65, 0xe66, 0xe66, 0x86a, 0x863, 0xa69, 0xa60,
52089
+ 0x4f0, 0x4f8, 0x6f2, 0x6f2, 0xf6 , 0xfe , 0x2f5, 0x2fc,
52090
+ 0xcf4, 0xcf4, 0xef6, 0xef6, 0x8fa, 0x8f3, 0xaf9, 0xaf0,
52091
+ 0x650, 0x650, 0x453, 0x552, 0x256, 0x256, 0x54 , 0x154,
52092
+ 0xe54, 0xf54, 0xc57, 0xd56, 0xa5a, 0xb52, 0x859, 0x950,
52093
+ 0x7c0, 0x6c1, 0x5c2, 0x4c2, 0x3c6, 0x2ce, 0xc5 , 0xc4 ,
52094
+ 0xfc4, 0xec5, 0xdc6, 0xcc6, 0xbca, 0xac2, 0x8c1, 0x8c0,
52095
+ 0x8c0, 0x8c0, 0xac2, 0xbc2, 0xcc6, 0xcc6, 0xec4, 0xfcc,
52096
+ 0xc4 , 0xc5 , 0x2c6, 0x3c6, 0x4c2, 0x5c2, 0x6c1, 0x7c0,
52097
+ 0x950, 0x859, 0xb52, 0xa5a, 0xd56, 0xc57, 0xe54, 0xe5c,
52098
+ 0x154, 0x54 , 0x25e, 0x256, 0x552, 0x453, 0x658, 0x650,
52099
+ 0xaf0, 0xaf0, 0x8f3, 0x8fa, 0xef6, 0xef6, 0xcf4, 0xcfc,
52100
+ 0x2f4, 0x3f5, 0xff , 0x1f6, 0x6f2, 0x6f3, 0x4f9, 0x5f0,
52101
+ 0xa60, 0xa69, 0x863, 0x86a, 0xe66, 0xe67, 0xd65, 0xc6c,
52102
+ 0x364, 0x265, 0x166, 0x66 , 0x76a, 0x663, 0x460, 0x460,
52103
+ 0xca0, 0xca0, 0xea2, 0xfa2, 0x8a6, 0x8a6, 0xaa4, 0xba4,
52104
+ 0x4ac, 0x5a4, 0x6ae, 0x7a6, 0xaa , 0xa3 , 0x2a8, 0x2a0,
52105
+ 0xd30, 0xc31, 0xf32, 0xe3a, 0x936, 0x837, 0xb35, 0xa34,
52106
+ 0x43c, 0x434, 0x73e, 0x636, 0x13a, 0x33 , 0x339, 0x230,
52107
+ 0xe90, 0xe90, 0xc92, 0xc9a, 0xa96, 0xa96, 0x894, 0x89c,
52108
+ 0x694, 0x695, 0x49f, 0x496, 0x292, 0x392, 0x98 , 0x90 ,
52109
+ 0xf00, 0xe08, 0xd03, 0xc0a, 0xa06, 0xa0e, 0x805, 0x804,
52110
+ 0x704, 0x604, 0x506, 0x406, 0x302, 0x202, 0x0 , 0x0]);
52111
+
52112
+ const segTable = [
52113
+ [],
52114
+ [],
52115
+ [1, 9],
52116
+ [1, 8, 1, 9],
52117
+ [2, 10, 10, 1],
52118
+ [2, 10, 10, 1],
52119
+ [9, 2, 2, 10, 10, 9],
52120
+ [2, 8, 2, 10, 10, 8, 10, 9],
52121
+ [11, 2],
52122
+ [0, 11, 11, 2],
52123
+ [1, 9, 11, 2],
52124
+ [1, 11, 11, 2, 1, 9, 9, 11],
52125
+ [3, 10, 10, 1, 11, 10],
52126
+ [0, 10, 10, 1, 8, 10, 11, 10],
52127
+ [3, 9, 11, 9, 11, 10, 10, 9],
52128
+ [8, 10, 10, 9, 11, 10],
52129
+ [4, 7],
52130
+ [4, 3, 4, 7],
52131
+ [1, 9, 4, 7],
52132
+ [4, 1, 1, 9, 4, 7, 7, 1],
52133
+ [2, 10, 10, 1, 4, 7],
52134
+ [3, 4, 4, 7, 2, 10, 10, 1],
52135
+ [9, 2, 2, 10, 10, 9, 4, 7],
52136
+ [2, 10, 10, 9, 9, 2, 9, 7, 7, 2, 4, 7],
52137
+ [4, 7, 11, 2],
52138
+ [11, 4, 4, 7, 11, 2, 2, 4],
52139
+ [1, 9, 4, 7, 11, 2],
52140
+ [4, 7, 11, 4, 11, 9, 11, 2, 2, 9, 1, 9],
52141
+ [3, 10, 10, 1, 11, 10, 4, 7],
52142
+ [1, 11, 11, 10, 10, 1, 1, 4, 4, 11, 4, 7],
52143
+ [4, 7, 0, 11, 11, 9, 11, 10, 10, 9],
52144
+ [4, 7, 11, 4, 11, 9, 11, 10, 10, 9],
52145
+ [9, 5, 5, 4],
52146
+ [9, 5, 5, 4],
52147
+ [0, 5, 5, 4, 1, 5],
52148
+ [8, 5, 5, 4, 3, 5, 1, 5],
52149
+ [2, 10, 10, 1, 9, 5, 5, 4],
52150
+ [2, 10, 10, 1, 9, 5, 5, 4],
52151
+ [5, 2, 2, 10, 10, 5, 5, 4, 4, 2],
52152
+ [2, 10, 10, 5, 5, 2, 5, 3, 5, 4, 4, 3],
52153
+ [9, 5, 5, 4, 11, 2],
52154
+ [0, 11, 11, 2, 9, 5, 5, 4],
52155
+ [0, 5, 5, 4, 1, 5, 11, 2],
52156
+ [1, 5, 5, 2, 5, 8, 8, 2, 11, 2, 5, 4],
52157
+ [10, 3, 11, 10, 10, 1, 9, 5, 5, 4],
52158
+ [9, 5, 5, 4, 8, 1, 8, 10, 10, 1, 11, 10],
52159
+ [5, 4, 0, 5, 0, 11, 11, 5, 11, 10, 10, 5],
52160
+ [5, 4, 8, 5, 8, 10, 10, 5, 11, 10],
52161
+ [9, 7, 5, 7, 9, 5],
52162
+ [9, 3, 9, 5, 5, 3, 5, 7],
52163
+ [0, 7, 1, 7, 1, 5, 5, 7],
52164
+ [1, 5, 5, 3, 5, 7],
52165
+ [9, 7, 9, 5, 5, 7, 10, 1, 2, 10],
52166
+ [10, 1, 2, 10, 9, 5, 5, 0, 5, 3, 5, 7],
52167
+ [2, 8, 2, 5, 5, 8, 5, 7, 10, 5, 2, 10],
52168
+ [2, 10, 10, 5, 5, 2, 5, 3, 5, 7],
52169
+ [7, 9, 9, 5, 5, 7, 11, 2],
52170
+ [9, 5, 5, 7, 7, 9, 7, 2, 2, 9, 11, 2],
52171
+ [11, 2, 1, 8, 1, 7, 1, 5, 5, 7],
52172
+ [11, 2, 1, 11, 1, 7, 1, 5, 5, 7],
52173
+ [9, 5, 5, 8, 5, 7, 10, 1, 3, 10, 11, 10],
52174
+ [5, 7, 7, 0, 0, 5, 9, 5, 11, 0, 0, 10, 10, 1, 11, 10],
52175
+ [11, 10, 10, 0, 0, 11, 10, 5, 5, 0, 0, 7, 5, 7],
52176
+ [11, 10, 10, 5, 5, 11, 5, 7],
52177
+ [10, 6, 6, 5, 5, 10],
52178
+ [5, 10, 10, 6, 6, 5],
52179
+ [1, 9, 5, 10, 10, 6, 6, 5],
52180
+ [1, 8, 1, 9, 5, 10, 10, 6, 6, 5],
52181
+ [1, 6, 6, 5, 5, 1, 2, 6],
52182
+ [1, 6, 6, 5, 5, 1, 2, 6],
52183
+ [9, 6, 6, 5, 5, 9, 0, 6, 2, 6],
52184
+ [5, 9, 8, 5, 8, 2, 2, 5, 2, 6, 6, 5],
52185
+ [11, 2, 10, 6, 6, 5, 5, 10],
52186
+ [11, 0, 11, 2, 10, 6, 6, 5, 5, 10],
52187
+ [1, 9, 11, 2, 5, 10, 10, 6, 6, 5],
52188
+ [5, 10, 10, 6, 6, 5, 1, 9, 9, 2, 9, 11, 11, 2],
52189
+ [6, 3, 11, 6, 6, 5, 5, 3, 5, 1],
52190
+ [11, 0, 11, 5, 5, 0, 5, 1, 11, 6, 6, 5],
52191
+ [11, 6, 6, 3, 6, 0, 6, 5, 5, 0, 5, 9],
52192
+ [6, 5, 5, 9, 9, 6, 9, 11, 11, 6],
52193
+ [5, 10, 10, 6, 6, 5, 4, 7],
52194
+ [4, 3, 4, 7, 6, 5, 5, 10, 10, 6],
52195
+ [1, 9, 5, 10, 10, 6, 6, 5, 4, 7],
52196
+ [10, 6, 6, 5, 5, 10, 1, 9, 9, 7, 7, 1, 4, 7],
52197
+ [6, 1, 2, 6, 6, 5, 5, 1, 4, 7],
52198
+ [2, 5, 5, 1, 2, 6, 6, 5, 4, 3, 4, 7],
52199
+ [4, 7, 0, 5, 5, 9, 0, 6, 6, 5, 2, 6],
52200
+ [3, 9, 9, 7, 4, 7, 2, 9, 5, 9, 9, 6, 6, 5, 2, 6],
52201
+ [11, 2, 4, 7, 10, 6, 6, 5, 5, 10],
52202
+ [5, 10, 10, 6, 6, 5, 4, 7, 7, 2, 2, 4, 11, 2],
52203
+ [1, 9, 4, 7, 11, 2, 5, 10, 10, 6, 6, 5],
52204
+ [9, 2, 1, 9, 9, 11, 11, 2, 4, 11, 4, 7, 5, 10, 10, 6, 6, 5],
52205
+ [4, 7, 11, 5, 5, 3, 5, 1, 11, 6, 6, 5],
52206
+ [5, 1, 1, 11, 11, 5, 11, 6, 6, 5, 0, 11, 11, 4, 4, 7],
52207
+ [0, 5, 5, 9, 0, 6, 6, 5, 3, 6, 11, 6, 4, 7],
52208
+ [6, 5, 5, 9, 9, 6, 9, 11, 11, 6, 4, 7, 7, 9],
52209
+ [10, 4, 9, 10, 6, 4, 10, 6],
52210
+ [4, 10, 10, 6, 6, 4, 9, 10],
52211
+ [10, 0, 1, 10, 10, 6, 6, 0, 6, 4],
52212
+ [1, 8, 1, 6, 6, 8, 6, 4, 1, 10, 10, 6],
52213
+ [1, 4, 9, 1, 2, 4, 2, 6, 6, 4],
52214
+ [2, 9, 9, 1, 2, 4, 2, 6, 6, 4],
52215
+ [2, 4, 2, 6, 6, 4],
52216
+ [2, 8, 2, 4, 2, 6, 6, 4],
52217
+ [10, 4, 9, 10, 10, 6, 6, 4, 11, 2],
52218
+ [8, 2, 11, 2, 9, 10, 10, 4, 10, 6, 6, 4],
52219
+ [11, 2, 1, 6, 6, 0, 6, 4, 1, 10, 10, 6],
52220
+ [6, 4, 4, 1, 1, 6, 1, 10, 10, 6, 8, 1, 1, 11, 11, 2],
52221
+ [9, 6, 6, 4, 9, 3, 3, 6, 9, 1, 11, 6],
52222
+ [11, 1, 1, 8, 11, 6, 6, 1, 9, 1, 1, 4, 6, 4],
52223
+ [11, 6, 6, 3, 6, 0, 6, 4],
52224
+ [6, 4, 8, 6, 11, 6],
52225
+ [7, 10, 10, 6, 6, 7, 8, 10, 9, 10],
52226
+ [0, 7, 0, 10, 10, 7, 9, 10, 6, 7, 10, 6],
52227
+ [10, 6, 6, 7, 7, 10, 1, 10, 7, 1, 8, 1],
52228
+ [10, 6, 6, 7, 7, 10, 7, 1, 1, 10],
52229
+ [2, 6, 6, 1, 6, 8, 8, 1, 9, 1, 6, 7],
52230
+ [2, 6, 6, 9, 9, 2, 9, 1, 6, 7, 7, 9, 9, 3],
52231
+ [0, 7, 0, 6, 6, 7, 2, 6],
52232
+ [2, 7, 6, 7, 2, 6],
52233
+ [11, 2, 10, 6, 6, 8, 8, 10, 9, 10, 6, 7],
52234
+ [0, 7, 7, 2, 11, 2, 9, 7, 6, 7, 7, 10, 10, 6, 9, 10],
52235
+ [1, 8, 1, 7, 1, 10, 10, 7, 6, 7, 10, 6, 11, 2],
52236
+ [11, 2, 1, 11, 1, 7, 10, 6, 6, 1, 1, 10, 6, 7],
52237
+ [9, 6, 6, 8, 6, 7, 9, 1, 1, 6, 11, 6, 6, 3],
52238
+ [9, 1, 11, 6, 6, 7],
52239
+ [0, 7, 0, 6, 6, 7, 11, 0, 11, 6],
52240
+ [11, 6, 6, 7],
52241
+ [7, 6, 6, 11],
52242
+ [7, 6, 6, 11],
52243
+ [1, 9, 7, 6, 6, 11],
52244
+ [8, 1, 1, 9, 7, 6, 6, 11],
52245
+ [10, 1, 2, 10, 6, 11, 7, 6],
52246
+ [2, 10, 10, 1, 6, 11, 7, 6],
52247
+ [2, 9, 2, 10, 10, 9, 6, 11, 7, 6],
52248
+ [6, 11, 7, 6, 2, 10, 10, 3, 10, 8, 10, 9],
52249
+ [7, 2, 6, 2, 7, 6],
52250
+ [7, 0, 7, 6, 6, 0, 6, 2],
52251
+ [2, 7, 7, 6, 6, 2, 1, 9],
52252
+ [1, 6, 6, 2, 1, 8, 8, 6, 1, 9, 7, 6],
52253
+ [10, 7, 7, 6, 6, 10, 10, 1, 1, 7],
52254
+ [10, 7, 7, 6, 6, 10, 1, 7, 10, 1, 1, 8],
52255
+ [7, 0, 7, 10, 10, 0, 10, 9, 6, 10, 7, 6],
52256
+ [7, 6, 6, 10, 10, 7, 10, 8, 10, 9],
52257
+ [6, 8, 4, 6, 6, 11],
52258
+ [3, 6, 6, 11, 0, 6, 4, 6],
52259
+ [8, 6, 6, 11, 4, 6, 1, 9],
52260
+ [4, 6, 6, 9, 6, 3, 3, 9, 1, 9, 6, 11],
52261
+ [6, 8, 4, 6, 6, 11, 2, 10, 10, 1],
52262
+ [2, 10, 10, 1, 0, 11, 0, 6, 6, 11, 4, 6],
52263
+ [4, 11, 4, 6, 6, 11, 2, 9, 2, 10, 10, 9],
52264
+ [10, 9, 9, 3, 3, 10, 2, 10, 4, 3, 3, 6, 6, 11, 4, 6],
52265
+ [8, 2, 4, 2, 4, 6, 6, 2],
52266
+ [4, 2, 4, 6, 6, 2],
52267
+ [1, 9, 3, 4, 4, 2, 4, 6, 6, 2],
52268
+ [1, 9, 4, 1, 4, 2, 4, 6, 6, 2],
52269
+ [8, 1, 8, 6, 6, 1, 4, 6, 6, 10, 10, 1],
52270
+ [10, 1, 0, 10, 0, 6, 6, 10, 4, 6],
52271
+ [4, 6, 6, 3, 3, 4, 6, 10, 10, 3, 3, 9, 10, 9],
52272
+ [10, 9, 4, 10, 6, 10, 4, 6],
52273
+ [9, 5, 5, 4, 7, 6, 6, 11],
52274
+ [9, 5, 5, 4, 7, 6, 6, 11],
52275
+ [5, 0, 1, 5, 5, 4, 7, 6, 6, 11],
52276
+ [7, 6, 6, 11, 3, 4, 3, 5, 5, 4, 1, 5],
52277
+ [9, 5, 5, 4, 10, 1, 2, 10, 7, 6, 6, 11],
52278
+ [6, 11, 7, 6, 2, 10, 10, 1, 9, 5, 5, 4],
52279
+ [7, 6, 6, 11, 5, 4, 4, 10, 10, 5, 4, 2, 2, 10],
52280
+ [3, 4, 3, 5, 5, 4, 2, 5, 10, 5, 2, 10, 7, 6, 6, 11],
52281
+ [7, 2, 7, 6, 6, 2, 5, 4, 9, 5],
52282
+ [9, 5, 5, 4, 8, 6, 6, 0, 6, 2, 7, 6],
52283
+ [3, 6, 6, 2, 7, 6, 1, 5, 5, 0, 5, 4],
52284
+ [6, 2, 2, 8, 8, 6, 7, 6, 1, 8, 8, 5, 5, 4, 1, 5],
52285
+ [9, 5, 5, 4, 10, 1, 1, 6, 6, 10, 1, 7, 7, 6],
52286
+ [1, 6, 6, 10, 10, 1, 1, 7, 7, 6, 0, 7, 9, 5, 5, 4],
52287
+ [0, 10, 10, 4, 10, 5, 5, 4, 3, 10, 6, 10, 10, 7, 7, 6],
52288
+ [7, 6, 6, 10, 10, 7, 10, 8, 5, 4, 4, 10, 10, 5],
52289
+ [6, 9, 9, 5, 5, 6, 6, 11, 11, 9],
52290
+ [3, 6, 6, 11, 0, 6, 0, 5, 5, 6, 9, 5],
52291
+ [0, 11, 0, 5, 5, 11, 1, 5, 5, 6, 6, 11],
52292
+ [6, 11, 3, 6, 3, 5, 5, 6, 1, 5],
52293
+ [2, 10, 10, 1, 9, 5, 5, 11, 11, 9, 5, 6, 6, 11],
52294
+ [0, 11, 0, 6, 6, 11, 9, 6, 5, 6, 9, 5, 2, 10, 10, 1],
52295
+ [8, 5, 5, 11, 5, 6, 6, 11, 0, 5, 10, 5, 5, 2, 2, 10],
52296
+ [6, 11, 3, 6, 3, 5, 5, 6, 2, 10, 10, 3, 10, 5],
52297
+ [5, 8, 9, 5, 5, 2, 2, 8, 5, 6, 6, 2],
52298
+ [9, 5, 5, 6, 6, 9, 6, 0, 6, 2],
52299
+ [1, 5, 5, 8, 8, 1, 5, 6, 6, 8, 8, 2, 6, 2],
52300
+ [1, 5, 5, 6, 6, 1, 6, 2],
52301
+ [3, 6, 6, 1, 6, 10, 10, 1, 8, 6, 5, 6, 6, 9, 9, 5],
52302
+ [10, 1, 0, 10, 0, 6, 6, 10, 9, 5, 5, 0, 5, 6],
52303
+ [5, 6, 6, 10, 10, 5],
52304
+ [10, 5, 5, 6, 6, 10],
52305
+ [11, 5, 5, 10, 10, 11, 7, 5],
52306
+ [11, 5, 5, 10, 10, 11, 7, 5],
52307
+ [5, 11, 7, 5, 5, 10, 10, 11, 1, 9],
52308
+ [10, 7, 7, 5, 5, 10, 10, 11, 8, 1, 1, 9],
52309
+ [11, 1, 2, 11, 7, 1, 7, 5, 5, 1],
52310
+ [2, 7, 7, 1, 7, 5, 5, 1, 2, 11],
52311
+ [9, 7, 7, 5, 5, 9, 9, 2, 2, 7, 2, 11],
52312
+ [7, 5, 5, 2, 2, 7, 2, 11, 5, 9, 9, 2, 2, 8],
52313
+ [2, 5, 5, 10, 10, 2, 3, 5, 7, 5],
52314
+ [8, 2, 8, 5, 5, 2, 7, 5, 10, 2, 5, 10],
52315
+ [1, 9, 5, 10, 10, 3, 3, 5, 7, 5, 10, 2],
52316
+ [8, 2, 2, 9, 1, 9, 7, 2, 10, 2, 2, 5, 5, 10, 7, 5],
52317
+ [3, 5, 5, 1, 7, 5],
52318
+ [7, 0, 7, 1, 7, 5, 5, 1],
52319
+ [3, 9, 3, 5, 5, 9, 7, 5],
52320
+ [7, 9, 5, 9, 7, 5],
52321
+ [5, 8, 4, 5, 5, 10, 10, 8, 10, 11],
52322
+ [5, 0, 4, 5, 5, 11, 11, 0, 5, 10, 10, 11],
52323
+ [1, 9, 4, 10, 10, 8, 10, 11, 4, 5, 5, 10],
52324
+ [10, 11, 11, 4, 4, 10, 4, 5, 5, 10, 3, 4, 4, 1, 1, 9],
52325
+ [2, 5, 5, 1, 2, 8, 8, 5, 2, 11, 4, 5],
52326
+ [4, 11, 11, 0, 4, 5, 5, 11, 2, 11, 11, 1, 5, 1],
52327
+ [2, 5, 5, 0, 5, 9, 2, 11, 11, 5, 4, 5, 5, 8],
52328
+ [4, 5, 5, 9, 2, 11],
52329
+ [2, 5, 5, 10, 10, 2, 3, 5, 3, 4, 4, 5],
52330
+ [5, 10, 10, 2, 2, 5, 2, 4, 4, 5],
52331
+ [3, 10, 10, 2, 3, 5, 5, 10, 8, 5, 4, 5, 1, 9],
52332
+ [5, 10, 10, 2, 2, 5, 2, 4, 4, 5, 1, 9, 9, 2],
52333
+ [4, 5, 5, 8, 5, 3, 5, 1],
52334
+ [4, 5, 5, 0, 5, 1],
52335
+ [4, 5, 5, 8, 5, 3, 0, 5, 5, 9],
52336
+ [4, 5, 5, 9],
52337
+ [4, 11, 7, 4, 9, 11, 9, 10, 10, 11],
52338
+ [9, 7, 7, 4, 9, 11, 9, 10, 10, 11],
52339
+ [1, 10, 10, 11, 11, 1, 11, 4, 4, 1, 7, 4],
52340
+ [1, 4, 4, 3, 1, 10, 10, 4, 7, 4, 4, 11, 10, 11],
52341
+ [4, 11, 7, 4, 9, 11, 9, 2, 2, 11, 9, 1],
52342
+ [9, 7, 7, 4, 9, 11, 9, 1, 1, 11, 2, 11],
52343
+ [7, 4, 4, 11, 4, 2, 2, 11],
52344
+ [7, 4, 4, 11, 4, 2, 2, 11, 3, 4],
52345
+ [2, 9, 9, 10, 10, 2, 2, 7, 7, 9, 7, 4],
52346
+ [9, 10, 10, 7, 7, 9, 7, 4, 10, 2, 2, 7, 7, 0],
52347
+ [7, 10, 10, 3, 10, 2, 7, 4, 4, 10, 1, 10, 10, 0],
52348
+ [1, 10, 10, 2, 7, 4],
52349
+ [9, 1, 1, 4, 1, 7, 7, 4],
52350
+ [9, 1, 1, 4, 1, 7, 7, 4, 8, 1],
52351
+ [3, 4, 7, 4],
52352
+ [7, 4],
52353
+ [9, 10, 10, 8, 10, 11],
52354
+ [9, 3, 9, 11, 9, 10, 10, 11],
52355
+ [1, 10, 10, 0, 10, 8, 10, 11],
52356
+ [1, 10, 10, 3, 10, 11],
52357
+ [2, 11, 11, 1, 11, 9, 9, 1],
52358
+ [9, 3, 9, 11, 2, 9, 9, 1, 2, 11],
52359
+ [2, 11, 11, 0],
52360
+ [2, 11],
52361
+ [8, 2, 8, 10, 10, 2, 9, 10],
52362
+ [9, 10, 10, 2, 2, 9],
52363
+ [8, 2, 8, 10, 10, 2, 1, 8, 1, 10],
52364
+ [1, 10, 10, 2],
52365
+ [8, 1, 9, 1],
52366
+ [9, 1],
52367
+ [],
52368
+ []];
52369
+
52370
+ const snap = (method === 'snapped MC');
52371
+ // const seg_table = (method === 'squarish' ? segTable2 : segTable);
52372
+ const seg_table = segTable;
52373
+
52374
+ let vlist = new Array(12);
52375
+ const vert_offsets = this.calculateVertOffsets(dims);
52376
+
52377
+ const edgeIndex = [[0,1], [1,2], [2,3], [3,0], [4,5], [5,6],
52378
+ [6,7], [7,4], [0,4], [1,5], [2,6], [3,7]];
52379
+
52380
+ let vertex_values = new Float32Array(8);
52381
+ let p0 = [0, 0, 0]; // unused initial value - to make Flow happy
52382
+ let vertex_points = [p0, p0, p0, p0, p0, p0, p0, p0];
52383
+ const size_x = dims[0];
52384
+ const size_y = dims[1];
52385
+ const size_z = dims[2];
52386
+ if (values == null || points == null) return;
52387
+ let vertices = [];
52388
+ let segments = [];
52389
+ let vertex_count = 0;
52390
+ for (let x = 0; x < size_x - 1; x++) {
52391
+ for (let y = 0; y < size_y - 1; y++) {
52392
+ for (let z = 0; z < size_z - 1; z++) {
52393
+ const offset0 = z + size_z * (y + size_y * x);
52394
+ let cubeindex = 0;
52395
+ let i;
52396
+ let j;
52397
+ for (i = 0; i < 8; ++i) {
52398
+ j = offset0 + vert_offsets[i];
52399
+ cubeindex |= (values[j] < isolevel) ? 1 << i : 0;
52400
+ }
52401
+ if (cubeindex === 0 || cubeindex === 255) continue;
52402
+ for (i = 0; i < 8; ++i) {
52403
+ j = offset0 + vert_offsets[i];
52404
+ vertex_values[i] = values[j];
52405
+ vertex_points[i] = points[j];
52406
+ }
52407
+
52408
+ // 12 bit number, indicates which edges are crossed by the isosurface
52409
+ const edge_mask = edgeTable[cubeindex];
52410
+
52411
+ // check which edges are crossed, and estimate the point location
52412
+ // using a weighted average of scalar values at edge endpoints.
52413
+ for (i = 0; i < 12; ++i) {
52414
+ if ((edge_mask & (1 << i)) !== 0) {
52415
+ const e = edgeIndex[i];
52416
+ let mu = (isolevel - vertex_values[e[0]]) /
52417
+ (vertex_values[e[1]] - vertex_values[e[0]]);
52418
+ if (snap === true) {
52419
+ if (mu > 0.85) mu = 1;
52420
+ else if (mu < 0.15) mu = 0;
52421
+ }
52422
+ const p1 = vertex_points[e[0]];
52423
+ const p2 = vertex_points[e[1]];
52424
+ // The number of added vertices could be roughly halved
52425
+ // if we avoided duplicates between neighbouring cells.
52426
+ // Using a map for lookups is too slow, perhaps a big
52427
+ // array would do?
52428
+ vertices.push(p1[0] + (p2[0] - p1[0]) * mu,
52429
+ p1[1] + (p2[1] - p1[1]) * mu,
52430
+ p1[2] + (p2[2] - p1[2]) * mu);
52431
+ vlist[i] = vertex_count++;
52432
+ }
52433
+ }
52434
+ const t = seg_table[cubeindex];
52435
+ for (i = 0; i < t.length; i++) {
52436
+ segments.push(vlist[t[i]]);
52437
+ }
52438
+ }
52439
+ }
52440
+ }
52441
+
52442
+ return { vertices: vertices, segments: segments };
52443
+ }
52444
+
52445
+ // return offsets relative to vertex [0,0,0]
52446
+ calculateVertOffsets(dims) { let ic = this.icn3d; ic.icn3dui;
52447
+ let vert_offsets = [];
52448
+ const cubeVerts = [[0,0,0], [1,0,0], [1,1,0], [0,1,0],
52449
+ [0,0,1], [1,0,1], [1,1,1], [0,1,1]];
52450
+
52451
+ for (let i = 0; i < 8; ++i) {
52452
+ const v = cubeVerts[i];
52453
+ vert_offsets.push(v[0] + dims[2] * (v[1] + dims[1] * v[2]));
52454
+ }
52455
+ return vert_offsets;
52456
+ }
52457
+
52458
+ makeChickenWire(data, typeDetail) { let ic = this.icn3d, me = ic.icn3dui;
52459
+ let geom = new THREE.BufferGeometry();
52460
+ let position = new Float32Array(data.vertices);
52461
+ geom.setAttribute('position', new THREE.BufferAttribute(position, 3));
52462
+
52463
+ // Although almost all browsers support OES_element_index_uint nowadays,
52464
+ // use Uint32 indexes only when needed.
52465
+ let arr = (data.vertices.length < 3*65536 ? new Uint16Array(data.segments) : new Uint32Array(data.segments));
52466
+
52467
+ geom.setIndex(new THREE.BufferAttribute(arr, 1));
52468
+
52469
+ let colorFor2fofc = me.parasCls.thr('#00FFFF');
52470
+ let colorForfofcPos = me.parasCls.thr('#00FF00');
52471
+ let colorForfofcNeg = me.parasCls.thr('#ff0000');
52472
+
52473
+ let color = (typeDetail == '2fofc') ? colorFor2fofc : ((typeDetail == 'fofc_pos') ? colorForfofcPos : colorForfofcNeg);
52474
+ let material = new THREE.LineBasicMaterial({ linewidth: 1, color: color });
52475
+ //return new THREE.LineSegments(geom, material);
52476
+
52477
+ let mesh = new THREE.LineSegments(geom, material);
52478
+ ic.mdl.add(mesh);
52479
+
52480
+ ic.prevMaps.push(mesh);
52481
+ }
52482
+ }
52483
+
52484
+
52485
+ class UnitCell {
52486
+ /*::
52487
+ parameters: number[]
52488
+ orth: number[]
52489
+ frac: number[]
52490
+ */
52491
+ // eslint-disable-next-line max-params
52492
+ constructor(a /*:number*/, b /*:number*/, c /*:number*/,
52493
+ alpha /*:number*/, beta /*:number*/, gamma /*:number*/) {
52494
+ if (a <= 0 || b <= 0 || c <= 0 || alpha <= 0 || beta <= 0 || gamma <= 0) {
52495
+ throw Error('Zero or negative unit cell parameter(s).');
52496
+ }
52497
+ this.parameters = [a, b, c, alpha, beta, gamma];
52498
+ const deg2rad = Math.PI / 180.0;
52499
+ const cos_alpha = Math.cos(deg2rad * alpha);
52500
+ const cos_beta = Math.cos(deg2rad * beta);
52501
+ const cos_gamma = Math.cos(deg2rad * gamma);
52502
+ const sin_alpha = Math.sin(deg2rad * alpha);
52503
+ const sin_beta = Math.sin(deg2rad * beta);
52504
+ const sin_gamma = Math.sin(deg2rad * gamma);
52505
+ if (sin_alpha === 0 || sin_beta === 0 || sin_gamma === 0) {
52506
+ throw Error('Impossible angle - N*180deg.');
52507
+ }
52508
+ const cos_alpha_star_sin_beta = (cos_beta * cos_gamma - cos_alpha) /
52509
+ sin_gamma;
52510
+ const cos_alpha_star = cos_alpha_star_sin_beta / sin_beta;
52511
+ const s1rca2 = Math.sqrt(1.0 - cos_alpha_star * cos_alpha_star);
52512
+ // The orthogonalization matrix we use is described in ITfC B p.262:
52513
+ // "An alternative mode of orthogonalization, used by the Protein
52514
+ // Data Bank and most programs, is to align the a1 axis of the unit
52515
+ // cell with the Cartesian X_1 axis, and to align the a*_3 axis with the
52516
+ // Cartesian X_3 axis."
52517
+ //
52518
+ // Zeros in the matrices below are kept to make matrix multiplication
52519
+ // faster: they make extract_block() 2x (!) faster on V8 4.5.103,
52520
+ // no difference on FF 50.
52521
+ /* eslint-disable no-multi-spaces, comma-spacing */
52522
+ this.orth = [a, b * cos_gamma, c * cos_beta,
52523
+ 0.0, b * sin_gamma, -c * cos_alpha_star_sin_beta,
52524
+ 0.0, 0.0 , c * sin_beta * s1rca2];
52525
+ // based on xtal.js which is based on cctbx.uctbx
52526
+ this.frac = [
52527
+ 1.0 / a,
52528
+ -cos_gamma / (sin_gamma * a),
52529
+ -(cos_gamma * cos_alpha_star_sin_beta + cos_beta * sin_gamma) /
52530
+ (sin_beta * s1rca2 * sin_gamma * a),
52531
+ 0.0,
52532
+ 1.0 / (sin_gamma * b),
52533
+ cos_alpha_star / (s1rca2 * sin_gamma * b),
52534
+ 0.0,
52535
+ 0.0,
52536
+ 1.0 / (sin_beta * s1rca2 * c),
52537
+ ];
52538
+ }
52539
+
52540
+ // This function is only used with matrices frac and orth, which have 3 zeros.
52541
+ // We skip these elements, but it doesn't affect performance (on FF50 and V8).
52542
+ multiply(xyz, mat) {
52543
+ /* eslint-disable indent */
52544
+ return [mat[0] * xyz[0] + mat[1] * xyz[1] + mat[2] * xyz[2],
52545
+ /*mat[3] * xyz[0]*/+ mat[4] * xyz[1] + mat[5] * xyz[2],
52546
+ /*mat[6] * xyz[0] + mat[7] * xyz[1]*/+ mat[8] * xyz[2]];
52547
+ }
52548
+
52549
+ fractionalize(xyz /*:[number,number,number]*/) {
52550
+ return this.multiply(xyz, this.frac);
52551
+ }
52552
+
52553
+ orthogonalize(xyz /*:[number,number,number]*/) {
52554
+ return this.multiply(xyz, this.orth);
52555
+ }
52556
+ }
52557
+
52558
+
52559
+ class GridArray {
52560
+ /*::
52561
+ dim: number[]
52562
+ values: Float32Array
52563
+ */
52564
+ constructor(dim /*:number[]*/) {
52565
+ this.dim = dim; // dimensions of the grid for the entire unit cell
52566
+ this.values = new Float32Array(dim[0] * dim[1] * dim[2]);
52567
+ }
52568
+
52569
+ modulo(a, b) {
52570
+ const reminder = a % b;
52571
+ return reminder >= 0 ? reminder : reminder + b;
52572
+ }
52573
+
52574
+ grid2index(i/*:number*/, j/*:number*/, k/*:number*/) {
52575
+ i = this.modulo(i, this.dim[0]);
52576
+ j = this.modulo(j, this.dim[1]);
52577
+ k = this.modulo(k, this.dim[2]);
52578
+ return this.dim[2] * (this.dim[1] * i + j) + k;
52579
+ }
52580
+
52581
+ grid2index_unchecked(i/*:number*/, j/*:number*/, k/*:number*/) {
52582
+ return this.dim[2] * (this.dim[1] * i + j) + k;
52583
+ }
52584
+
52585
+ grid2frac(i/*:number*/, j/*:number*/, k/*:number*/) {
52586
+ return [i / this.dim[0], j / this.dim[1], k / this.dim[2]];
52587
+ }
52588
+
52589
+ // return grid coordinates (rounded down) for the given fractional coordinates
52590
+ frac2grid(xyz/*:number[]*/) {
52591
+ // at one point "| 0" here made extract_block() 40% faster on V8 3.14,
52592
+ // but I don't see any effect now
52593
+ return [Math.floor(xyz[0] * this.dim[0]) | 0,
52594
+ Math.floor(xyz[1] * this.dim[1]) | 0,
52595
+ Math.floor(xyz[2] * this.dim[2]) | 0];
52596
+ }
52597
+
52598
+ set_grid_value(i/*:number*/, j/*:number*/, k/*:number*/, value/*:number*/) {
52599
+ const idx = this.grid2index(i, j, k);
52600
+ this.values[idx] = value;
52601
+ }
52602
+
52603
+ get_grid_value(i/*:number*/, j/*:number*/, k/*:number*/) {
52604
+ const idx = this.grid2index(i, j, k);
52605
+ return this.values[idx];
52606
+ }
52607
+ }
52608
+
52609
+ /**
52610
+ * @file Mtz Parser
52611
+ * @author Marcin Wojdyr <wojdyr@gmail.com>
52612
+ * @private
52613
+ * Modified by Jiyao Wang / https://github.com/ncbi/icn3d
52614
+ */
52615
+
52616
+ class MtzParser {
52617
+ constructor(icn3d) {
52618
+ this.icn3d = icn3d;
52619
+ }
52620
+
52621
+ async mtzParserBase(url, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
52622
+ let thisClass = this;
52623
+
52624
+ //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
52625
+ // if(type == '2fofc' && ic.bAjax2fofcccp4) {
52626
+ // ic.mapData.sigma2 = sigma;
52627
+ // ic.setOptionCls.setOption('map', type);
52628
+ // }
52629
+ // else if(type == 'fofc' && ic.bAjaxfofcccp4) {
52630
+ // ic.mapData.sigma = sigma;
52631
+ // ic.setOptionCls.setOption('map', type);
52632
+ // }
52633
+ // else {
52634
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', '');
52635
+ sigma = await thisClass.loadMtzFileBase(arrayBuffer, type, sigma, location, bInputSigma, url);
52636
+
52637
+ // if(type == '2fofc') {
52638
+ // ic.bAjax2fofcccp4 = true;
52639
+ // }
52640
+ // else if(type == 'fofc') {
52641
+ // ic.bAjaxfofcccp4 = true;
52642
+ // }
52643
+
52644
+ ic.setOptionCls.setOption('map', type);
52645
+
52646
+ return sigma;
52647
+ // }
52648
+ }
52649
+
52650
+ loadMtzFile(type) {var ic = this.icn3d, me = ic.icn3dui;
52651
+ let thisClass = this;
52652
+
52653
+ let file = $("#" + ic.pre + "dsn6file" + type)[0].files[0];
52654
+ let sigma = $("#" + ic.pre + "dsn6sigma" + type).val();
52655
+ if(!file) {
52656
+ alert("Please select a file before clicking 'Load'");
52657
+ }
52658
+ else {
52659
+ me.utilsCls.checkFileAPI();
52660
+ let reader = new FileReader();
52661
+ reader.onload = async function(e) { let ic = thisClass.icn3d;
52662
+ sigma = await thisClass.loadMtzFileBase(e.target.result, type, sigma, 'file');
52663
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
52664
+ };
52665
+ reader.readAsArrayBuffer(file);
52666
+ }
52667
+ }
52668
+
52669
+ async loadMtzFileBase(data, type, sigma, location, bInputSigma, url) {var ic = this.icn3d, me = ic.icn3dui;
52670
+ if(ic.bMtz === undefined) {
52671
+ let url = "./script/mtz.js";
52672
+ await me.getAjaxPromise(url, 'script');
52673
+
52674
+ ic.bMtz = true;
52675
+ }
52676
+
52677
+ GemmiMtz().then(function(Gemmi) {
52678
+ let mtz = Gemmi.readMtz(data);
52679
+
52680
+ sigma = ic.ccp4ParserCls.load_maps_from_mtz_buffer(mtz, type, sigma, location, bInputSigma);
52681
+
52682
+ // if(type == '2fofc') {
52683
+ // ic.bAjax2fofcCcp4 = true;
52684
+ // }
52685
+ // else if(type == 'fofc') {
52686
+ // ic.bAjaxfofcCcp4 = true;
52687
+ // }
52688
+ ic.setOptionCls.setOption('map', type);
52689
+ if(url) me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file mtz | ' + encodeURIComponent(url), true);
52690
+
52691
+ return sigma;
52692
+ });
52693
+ }
52694
+
52695
+ async loadMtzFileUrl(type) {var ic = this.icn3d; ic.icn3dui;
52696
+ let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
52697
+ let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
52698
+ if(!url) {
52699
+ alert("Please input the file URL before clicking 'Load'");
52700
+ }
52701
+ else {
52702
+ sigma = await this.mtzParserBase(url, type, sigma, 'url');
52703
+
52704
+ //me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file mtz | ' + encodeURIComponent(url), true);
51441
52705
  }
51442
52706
  }
51443
52707
 
@@ -54209,7 +55473,7 @@ class DensityCifParser {
54209
55473
  this.icn3d = icn3d;
54210
55474
  }
54211
55475
 
54212
- async densityCifParser(pdbid, type, sigma, emd) { let ic = this.icn3d, me = ic.icn3dui;
55476
+ async densityCifParser(pdbid, type, sigma, emd, bOutput) { let ic = this.icn3d, me = ic.icn3dui;
54213
55477
  let thisClass = this;
54214
55478
 
54215
55479
  let url;
@@ -54271,6 +55535,9 @@ class DensityCifParser {
54271
55535
  ic.mapData.header2 = header;
54272
55536
 
54273
55537
  ic.mapData.data2 = density.data;
55538
+ for(let i = 0; i < density.data.length; ++i) {
55539
+ density.data[i];
55540
+ }
54274
55541
 
54275
55542
  let origin = density.box.origin;
54276
55543
  let dimensions = density.box.dimensions;
@@ -54305,6 +55572,7 @@ class DensityCifParser {
54305
55572
  origin = density.box.origin;
54306
55573
  dimensions = density.box.dimensions;
54307
55574
  basis = density.spacegroup.basis;
55575
+
54308
55576
  scale = new THREE.Matrix4().makeScale(
54309
55577
  dimensions[0] / (sampleCount[0] ),
54310
55578
  dimensions[1] / (sampleCount[1] ),
@@ -55933,7 +57201,10 @@ class ParserUtils {
55933
57201
 
55934
57202
  if(bAppend) {
55935
57203
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
55936
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
57204
+ if(ic.bAnnoShown) {
57205
+ await ic.showAnnoCls.showAnnotations();
57206
+ ic.annotationCls.resetAnnoTabAll();
57207
+ }
55937
57208
  }
55938
57209
 
55939
57210
  // Realign by sequence alignment with the residues in "segment", i.e., transmembrane helix
@@ -56124,7 +57395,7 @@ class LoadAtomData {
56124
57395
  if(!bTitle) ic.molTitle = '';
56125
57396
  }
56126
57397
  else { // mmdbid or mmcifid
56127
- if(data.descr !== undefined) ic.molTitle += data.descr.name;
57398
+ if(data.descr !== undefined) ic.molTitle = data.descr.name;
56128
57399
  if(type === 'mmdbid') {
56129
57400
  let pdbidTmp = (isNaN(id)) ? id : data.pdbId;
56130
57401
  let chainHash = {};
@@ -57263,12 +58534,12 @@ class SetSeqAlign {
57263
58534
 
57264
58535
  if(i > 0) {
57265
58536
  let index1 = alignIndex;
57266
-
58537
+
57267
58538
  for(let j = prevIndex1 + 1, jl = start1; j < jl; ++j) {
57268
- if(posChain1[j]) continue;
58539
+ //if(posChain1[j]) continue;
57269
58540
  posChain1[j] = 1;
57270
58541
 
57271
- if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
58542
+ //if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
57272
58543
 
57273
58544
  //let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
57274
58545
  let resi = this.getResiAferAlign(chainid1, bRealign, j);
@@ -57279,18 +58550,19 @@ class SetSeqAlign {
57279
58550
 
57280
58551
  color = me.htmlCls.GREY8;
57281
58552
  classname = 'icn3d-nalign';
57282
-
58553
+
57283
58554
  ic.nalignHash1[chainid1 + '_' + resi] = 1;
57284
58555
  this.setSeqPerResi(chainid1, chainid1, chainid2, resi, resn, false, color, undefined, classname, true, false, index1);
57285
58556
  ++index1;
57286
58557
  }
57287
58558
 
57288
58559
  let index2 = alignIndex;
58560
+
57289
58561
  for(let j = prevIndex2 + 1, jl = start2; j < jl; ++j) {
57290
- if(posChain2[j]) continue;
58562
+ //if(posChain2[j]) continue;
57291
58563
  posChain2[j] = 1;
57292
58564
 
57293
- if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
58565
+ //if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57294
58566
 
57295
58567
  //let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
57296
58568
  let resi = this.getResiAferAlign(chainid2, bRealign, j);
@@ -57336,7 +58608,7 @@ class SetSeqAlign {
57336
58608
  }
57337
58609
 
57338
58610
  for(let j = 0; j <= end1 - start1; ++j) {
57339
- if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
58611
+ ///if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57340
58612
 
57341
58613
  let resi1, resi2, resn1, resn2;
57342
58614
  /*
@@ -57366,15 +58638,17 @@ class SetSeqAlign {
57366
58638
  if(resn1 == '?' || resn2 == '?') continue;
57367
58639
  }
57368
58640
  else {
57369
- if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
58641
+ ///if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
57370
58642
 
57371
58643
  // resi1 = ic.chainsSeq[chainid1][j + start1].resi;
57372
58644
  // resi2 = ic.chainsSeq[chainid2][j + start2].resi;
57373
58645
  // resn1 = ic.chainsSeq[chainid1][j + start1].name.toUpperCase();
57374
58646
  // resn2 = ic.chainsSeq[chainid2][j + start2].name.toUpperCase();
57375
58647
 
57376
- resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
57377
- resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
58648
+ // resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
58649
+ // resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
58650
+ resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1);
58651
+ resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2);
57378
58652
  resn1 = this.getResnFromResi(chainid1, resi1).toUpperCase();
57379
58653
  resn2 = this.getResnFromResi(chainid2, resi2).toUpperCase();
57380
58654
  }
@@ -61752,7 +63026,7 @@ class DefinedSets {
61752
63026
  }
61753
63027
 
61754
63028
  //Set the menu of defined sets with an array of defined names "commandnameArray".
61755
- setAtomMenu(commandnameArray) { let ic = this.icn3d; ic.icn3dui;
63029
+ setAtomMenu(commandnameArray) { let ic = this.icn3d, me = ic.icn3dui;
61756
63030
  let html = "";
61757
63031
 
61758
63032
  let nameArray1 =(ic.defNames2Residues !== undefined) ? Object.keys(ic.defNames2Residues) : [];
@@ -61761,12 +63035,22 @@ class DefinedSets {
61761
63035
  let nameArrayTmp = nameArray1.concat(nameArray2).sort();
61762
63036
 
61763
63037
  let nameArray = [];
61764
- // $.each(nameArrayTmp, function(i, el){
61765
- // if($.inArray(el, nameArray) === -1) nameArray.push(el);
61766
- // });
61767
- nameArrayTmp.forEach(elem => {
61768
- if($.inArray(elem, nameArray) === -1) nameArray.push(elem);
61769
- });
63038
+ // $.each(nameArrayTmp, function(i, el){
63039
+ // if($.inArray(el, nameArray) === -1) nameArray.push(el);
63040
+ // });
63041
+ // nameArrayTmp.forEach(elem => {
63042
+ // if($.inArray(elem, nameArray) === -1) nameArray.push(elem);
63043
+ // });
63044
+
63045
+ let structureArray = Object.keys(me.utilsCls.getStructures(ic.dAtoms));
63046
+
63047
+ nameArrayTmp.forEach((elem) => {
63048
+ structureArray.forEach((structure) => {
63049
+ if (ic.defNames2Residues[elem][0].split("_")[0].includes(structure.split("_")[0])){
63050
+ if ($.inArray(elem, nameArray) === -1) nameArray.push(elem);
63051
+ }
63052
+ });
63053
+ });
61770
63054
 
61771
63055
  //for(let i in ic.defNames2Atoms) {
61772
63056
  for(let i = 0, il = nameArray.length; i < il; ++i) {
@@ -62332,6 +63616,124 @@ class DefinedSets {
62332
63616
 
62333
63617
  }
62334
63618
 
63619
+ class SelectCollections {
63620
+ constructor(icn3d) {
63621
+ this.icn3d = icn3d;
63622
+ }
63623
+
63624
+ //Set the menu of defined sets with an array of defined names "commandnameArray".
63625
+ setAtomMenu(nameArray, titleArray) {
63626
+ let ic = this.icn3d;
63627
+ ic.icn3dui;
63628
+ let html = "";
63629
+ let commandnameArray = [nameArray[0]];
63630
+ //for(let i in ic.defNames2Atoms) {
63631
+ for (let i = 0, il = nameArray.length; i < il; ++i) {
63632
+ let name = nameArray[i];
63633
+ let title = titleArray[i];
63634
+
63635
+ let atomHash;
63636
+ if (
63637
+ ic.defNames2Atoms !== undefined &&
63638
+ ic.defNames2Atoms.hasOwnProperty(name)
63639
+ ) {
63640
+ let atomArray = ic.defNames2Atoms[name];
63641
+
63642
+ if (atomArray.length > 0) ic.atoms[atomArray[0]];
63643
+ } else if (
63644
+ ic.defNames2Residues !== undefined &&
63645
+ ic.defNames2Residues.hasOwnProperty(name)
63646
+ ) {
63647
+ let residueArray = ic.defNames2Residues[name];
63648
+ if (residueArray.length > 0) {
63649
+ atomHash = ic.residues[residueArray[0]];
63650
+ if (atomHash) {
63651
+ ic.atoms[Object.keys(atomHash)[0]];
63652
+ }
63653
+ }
63654
+ }
63655
+
63656
+ if (commandnameArray.indexOf(name) != -1) {
63657
+ html +=
63658
+ "<option value='" +
63659
+ name +
63660
+ "' selected='selected'>" +
63661
+ title +
63662
+ "</option>";
63663
+ } else {
63664
+ html += "<option value='" + name + "'>" + title + "</option>";
63665
+ }
63666
+ }
63667
+
63668
+ return html;
63669
+ }
63670
+
63671
+ clickStructure() {
63672
+ let ic = this.icn3d,
63673
+ me = ic.icn3dui;
63674
+ let thisClass = this;
63675
+
63676
+ //me.myEventCls.onIds("#" + ic.pre + "atomsCustom", "change", function(e) { let ic = thisClass.icn3d;
63677
+ $("#" + ic.pre + "collections_menu").change(async function (e) {
63678
+ let ic = thisClass.icn3d;
63679
+ // ic.init()
63680
+ let nameArray = $(this).val();
63681
+ let nameStructure = $(this).find("option:selected").text();
63682
+
63683
+ ic.nameArray = nameArray;
63684
+ if (nameArray !== null) {
63685
+ ic.bShowHighlight = false;
63686
+ await ic.chainalignParserCls.downloadMmdbAf(nameArray.toString());
63687
+
63688
+ ic.dAtoms = {};
63689
+ ic.hAtoms = {};
63690
+ // ic.ssbondpnts = {};
63691
+ let chainIdHash = {};
63692
+
63693
+ for (const name in nameArray) {
63694
+ for (const key in ic.chains) {
63695
+ if (key.includes(nameArray[name])) {
63696
+ chainIdHash[key] = 1;
63697
+ if (ic.chains.hasOwnProperty(key)) {
63698
+ const innerDict = ic.chains[key];
63699
+ for (const innerKey in innerDict) {
63700
+ if (innerDict.hasOwnProperty(innerKey)) {
63701
+ ic.dAtoms[innerKey] = innerDict[innerKey];
63702
+ ic.hAtoms[innerKey] = innerDict[innerKey];
63703
+ }
63704
+ }
63705
+ }
63706
+ }
63707
+ }
63708
+ }
63709
+
63710
+ ic.transformCls.zoominSelection();
63711
+ ic.definedSetsCls.showSets();
63712
+
63713
+
63714
+ await ic.drawCls.draw();
63715
+ ic.saveFileCls.showTitle();
63716
+
63717
+ me.htmlCls.clickMenuCls.setLogCmd(
63718
+ "select structure " + "[" + nameStructure + "]",
63719
+ true
63720
+ );
63721
+ ic.bSelectResidue = false;
63722
+ }
63723
+ });
63724
+
63725
+ me.myEventCls.onIds(
63726
+ "#" + ic.pre + "collections_menu",
63727
+ "focus",
63728
+ function (e) {
63729
+ let ic = thisClass.icn3d;
63730
+ if (me.utilsCls.isMobile())
63731
+ $("#" + ic.pre + "collections_menu").val("");
63732
+ }
63733
+ );
63734
+ }
63735
+ }
63736
+
62335
63737
  /**
62336
63738
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
62337
63739
  */
@@ -62423,14 +63825,15 @@ class LoadScript {
62423
63825
  let bFinalStep =(i === steps - 1) ? true : false;
62424
63826
 
62425
63827
  if(!ic.commands[i].trim()) continue;
62426
- let nAtoms = Object.keys(ic.atoms).length;
63828
+ let nAtoms = (ic.atoms) ? Object.keys(ic.atoms).length : 0;
62427
63829
 
62428
63830
  if(nAtoms == 0 && ic.commands[i].indexOf('load') == -1) continue;
62429
63831
 
62430
63832
  let strArray = ic.commands[i].split("|||");
62431
63833
  let command = strArray[0].trim();
62432
63834
 
62433
- if(ic.inputid) ic.bNotLoadStructure = true;
63835
+ // sometimes URL has an ID input, then load a structure in commands
63836
+ //if(ic.inputid) ic.bNotLoadStructure = true;
62434
63837
 
62435
63838
  if(command.indexOf('load') !== -1) {
62436
63839
  if(end === 0 && start === end) {
@@ -62466,18 +63869,7 @@ class LoadScript {
62466
63869
  }
62467
63870
  }
62468
63871
  else if(command.indexOf('set map') == 0 && command.indexOf('set map wireframe') == -1) {
62469
- //set map 2fofc sigma 1.5
62470
- let urlArray = strArray[0].trim().split(' | ');
62471
-
62472
- let str = urlArray[0].substr(8);
62473
- let paraArray = str.split(" ");
62474
-
62475
- if(paraArray.length == 3 && paraArray[1] == 'sigma') {
62476
- paraArray[2];
62477
- paraArray[0];
62478
-
62479
- await thisClass.applyCommandMap(strArray[0].trim());
62480
- }
63872
+ await thisClass.applyCommandMap(strArray[0].trim());
62481
63873
  }
62482
63874
  else if(command.indexOf('set emmap') == 0 && command.indexOf('set emmap wireframe') == -1) {
62483
63875
  //set emmap percentage 70
@@ -62977,17 +64369,34 @@ class LoadScript {
62977
64369
  // ic.deferredMap = $.Deferred(function() { let ic = thisClass.icn3d;
62978
64370
  //"set map 2fofc sigma 1.5"
62979
64371
  // or "set map 2fofc sigma 1.5 | [url]"
64372
+
64373
+ // added more para later
64374
+ //"set map 2fofc sigma 1.5 file dsn6"
64375
+ // or "set map 2fofc sigma 1.5 file dsn6 | [url]"
62980
64376
  let urlArray = command.split(" | ");
62981
64377
 
62982
64378
  let str = urlArray[0].substr(8);
62983
64379
  let paraArray = str.split(" ");
62984
64380
 
62985
- if(paraArray.length == 3 && paraArray[1] == 'sigma') {
64381
+ //if(paraArray.length == 3 && paraArray[1] == 'sigma') {
64382
+ if(paraArray[1] == 'sigma') {
62986
64383
  let sigma = paraArray[2];
62987
64384
  let type = paraArray[0];
62988
64385
 
64386
+ let fileType = 'dsn6';
64387
+ if(paraArray.length == 5) fileType = paraArray[4];
64388
+
62989
64389
  if(urlArray.length == 2) {
62990
- await ic.dsn6ParserCls.dsn6ParserBase(urlArray[1], type, sigma);
64390
+ let bInputSigma = true;
64391
+ if(fileType == 'dsn6') {
64392
+ await ic.dsn6ParserCls.dsn6ParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
64393
+ }
64394
+ else if(fileType == 'ccp4') {
64395
+ await ic.ccp4ParserCls.ccp4ParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
64396
+ }
64397
+ else if(fileType == 'mtz') {
64398
+ await ic.mtzParserCls.mtzParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
64399
+ }
62991
64400
  }
62992
64401
  else {
62993
64402
  await ic.dsn6ParserCls.dsn6Parser(ic.inputid, type, sigma);
@@ -71931,7 +73340,7 @@ class Ray {
71931
73340
  }
71932
73341
 
71933
73342
  // from iview (http://istar.cse.cuhk.edu.hk/iview/)
71934
- getAtomsFromPosition(point, threshold) { let ic = this.icn3d, me = ic.icn3dui;
73343
+ getAtomsFromPosition(point, threshold, atoms) { let ic = this.icn3d, me = ic.icn3dui;
71935
73344
  let i;
71936
73345
 
71937
73346
  if(threshold === undefined || threshold === null) {
@@ -71939,7 +73348,8 @@ class Ray {
71939
73348
  }
71940
73349
 
71941
73350
  //for (i in ic.atoms) {
71942
- for (i in ic.dAtoms) {
73351
+ let atomHash = (atoms) ? atoms : ic.dAtoms;
73352
+ for (i in atomHash) {
71943
73353
  let atom = ic.atoms[i];
71944
73354
 
71945
73355
  if(ic.ions.hasOwnProperty(i) && ic.opts['ions'] === 'sphere') {
@@ -72332,13 +73742,25 @@ class Picking {
72332
73742
  y += me.htmlCls.MENU_HEIGHT;
72333
73743
  }
72334
73744
  let text =(ic.pk == 1) ? atom.resn + atom.resi + '@' + atom.name : atom.resn + atom.resi;
73745
+ let chainid = atom.structure + '_' + atom.chain;
73746
+ let textWidth;
72335
73747
  if(ic.structures !== undefined && Object.keys(ic.structures).length > 1) {
72336
- text = atom.structure + '_' + atom.chain + ' ' + text;
72337
- $("#" + ic.pre + "popup").css("width", "160px");
73748
+ text = chainid + ' ' + text;
73749
+ textWidth = (ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) ? 160 + 80 : 160;
73750
+ $("#" + ic.pre + "popup").css("width", textWidth + "px");
72338
73751
  }
72339
73752
  else {
72340
- $("#" + ic.pre + "popup").css("width", "80px");
73753
+ textWidth = (ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) ? 80 + 80 : 80;
73754
+ $("#" + ic.pre + "popup").css("width", textWidth + "px");
72341
73755
  }
73756
+
73757
+
73758
+ if(ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) {
73759
+ let refnumLabel = ic.resid2refnum[chainid + '_' + atom.resi];
73760
+
73761
+ if(refnumLabel) text += ', Ig: ' + refnumLabel;
73762
+ }
73763
+
72342
73764
  $("#" + ic.pre + "popup").html(text);
72343
73765
  $("#" + ic.pre + "popup").css("top", y).css("left", x+20).show();
72344
73766
  }
@@ -73499,6 +74921,8 @@ class iCn3D {
73499
74921
  this.alignParserCls = new AlignParser(this);
73500
74922
  this.chainalignParserCls = new ChainalignParser(this);
73501
74923
  this.dsn6ParserCls = new Dsn6Parser(this);
74924
+ this.ccp4ParserCls = new Ccp4Parser(this);
74925
+ this.mtzParserCls = new MtzParser(this);
73502
74926
  this.mmcifParserCls = new MmcifParser(this);
73503
74927
  this.mmdbParserCls = new MmdbParser(this);
73504
74928
  this.mmtfParserCls = new MmtfParser(this);
@@ -73514,7 +74938,8 @@ class iCn3D {
73514
74938
  this.setSeqAlignCls = new SetSeqAlign(this);
73515
74939
 
73516
74940
  this.applyCommandCls = new ApplyCommand(this);
73517
- this.definedSetsCls = new DefinedSets(this);
74941
+ this.definedSetsCls = new DefinedSets(this);
74942
+ this.selectCollectionsCls = new SelectCollections(this);
73518
74943
  this.legendTableCls = new LegendTable(this);
73519
74944
  this.loadScriptCls = new LoadScript(this);
73520
74945
  this.selByCommCls = new SelectByCommand(this);
@@ -73761,7 +75186,7 @@ class iCn3DUI {
73761
75186
  //even when multiple iCn3D viewers are shown together.
73762
75187
  this.pre = this.cfg.divid + "_";
73763
75188
 
73764
- this.REVISION = '3.28.4';
75189
+ this.REVISION = '3.29.1';
73765
75190
 
73766
75191
  // In nodejs, iCn3D defines "window = {navigator: {}}"
73767
75192
  this.bNode = (Object.keys(window).length < 2) ? true : false;