icn3d 3.28.11 → 3.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/icn3d.js +1600 -349
  2. package/icn3d.min.js +7 -5
  3. package/icn3d.module.js +1600 -349
  4. package/package.json +1 -1
package/icn3d.module.js CHANGED
@@ -6860,7 +6860,7 @@ class ClickMenu {
6860
6860
  });
6861
6861
 
6862
6862
  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');
6863
+ me.htmlCls.dialogCls.openDlg('dl_dsn6', 'Please input the map file to display electron density map');
6864
6864
  });
6865
6865
 
6866
6866
 
@@ -6887,7 +6887,7 @@ class ClickMenu {
6887
6887
 
6888
6888
 
6889
6889
  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');
6890
+ me.htmlCls.dialogCls.openDlg('dl_dsn6url', 'Please input the map file to display electron density map');
6891
6891
  });
6892
6892
 
6893
6893
  me.myEventCls.onIds("#" + me.pre + "mn1_exportState", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
@@ -8192,6 +8192,8 @@ class ClickMenu {
8192
8192
  let sigma2fofc = parseFloat($("#" + me.pre + "sigma2fofc" ).val());
8193
8193
  let type = '2fofc';
8194
8194
  await ic.dsn6ParserCls.dsn6Parser(ic.inputid, type, sigma2fofc);
8195
+ //ic.densityCifParserCls.densityCifParser(ic.inputid, type, sigma2fofc);
8196
+
8195
8197
  //ic.setOptionCls.setOption('map', '2fofc');
8196
8198
  thisClass.setLogCmd('set map 2fofc sigma ' + sigma2fofc, true);
8197
8199
  });
@@ -9448,12 +9450,14 @@ class SetMenu {
9448
9450
 
9449
9451
  html += this.getMenuSep();
9450
9452
 
9451
- html += this.getMenuText('mn1_dsn6wrap', 'Electron Density(DSN6)', undefined, undefined, 2);
9453
+ html += this.getMenuText('mn1_dsn6wrap', 'Electron Density', undefined, undefined, 2);
9452
9454
  html += "<ul>";
9453
9455
  html += this.getLink('mn1_dsn6', 'Local File', undefined, 3);
9454
9456
  html += this.getLink('mn1_dsn6url', 'URL(CORS) ' + me.htmlCls.wifiStr, undefined, 3);
9455
9457
  html += "</ul>";
9456
9458
 
9459
+ html += "<li><br/></li>";
9460
+
9457
9461
  html += "</ul>";
9458
9462
  html += "</li>";
9459
9463
 
@@ -9559,14 +9563,14 @@ class SetMenu {
9559
9563
  }
9560
9564
 
9561
9565
  //!!!
9562
- /*
9566
+
9563
9567
  html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
9564
9568
  html += "<ul>";
9565
9569
  html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
9566
9570
  html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
9567
9571
  html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
9568
9572
  html += "</ul>";
9569
- */
9573
+
9570
9574
 
9571
9575
  html += "<li><br/></li>";
9572
9576
 
@@ -10407,8 +10411,8 @@ class SetMenu {
10407
10411
  //}
10408
10412
 
10409
10413
  //!!!
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);
10414
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
10415
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
10412
10416
  }
10413
10417
  else {
10414
10418
  //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 +10543,7 @@ class SetMenu {
10539
10543
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
10540
10544
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
10541
10545
  //!!!
10542
- //html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
10546
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
10543
10547
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
10544
10548
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
10545
10549
  }
@@ -10631,11 +10635,11 @@ class SetMenu {
10631
10635
 
10632
10636
  html += "<ul>";
10633
10637
  //!!!
10634
- /*
10638
+
10635
10639
  html += this.getLink('mn6_igrefYes', 'Show Ig Ref. Number', undefined, 2);
10636
10640
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
10637
10641
  html += this.getLink('mn6_igrefNo', 'Hide Ig Ref. Number', undefined, 2);
10638
- */
10642
+
10639
10643
  html += this.getMenuSep();
10640
10644
 
10641
10645
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
@@ -11875,23 +11879,19 @@ class SetDialog {
11875
11879
  html += "</div>";
11876
11880
 
11877
11881
  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'>";
11882
-
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);
11885
-
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/>";
11882
+ html += this.addNotebookTitle('dl_dsn6', 'Load a map file');
11883
+ 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/>";
11888
11884
 
11889
- html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at: <select id='" + me.pre + "dsn6sigmafofc'>";
11885
+ html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at default threshold or at: "
11886
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigma2fofc' value='' size=8> &sigma;</span><br/>";
11887
+ //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/>";
11888
+ 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/>";
11890
11889
 
11891
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 5);
11890
+ html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at default threshold or at: "
11891
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmafofc' value='' size=8> &sigma;</span><br/>";
11892
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>";
11893
+ //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>";
11894
+ 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
11895
 
11896
11896
  html += me.htmlCls.buttonStr + "elecmapNo4'>Remove Map</button><br>";
11897
11897
 
@@ -11899,21 +11899,17 @@ class SetDialog {
11899
11899
 
11900
11900
  html += me.htmlCls.divStr + "dl_dsn6url' class='" + dialogClass + "'>";
11901
11901
  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/>";
11903
-
11904
- html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at: <select id='" + me.pre + "dsn6sigmaurl2fofc'>";
11905
-
11906
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
11902
+ 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/>";
11907
11903
 
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/>";
11904
+ html += "<span style='white-space:nowrap;font-weight:bold;'>2fofc contour at default threshold or at: "
11905
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmaurl2fofc' value='' size=8> &sigma;</span><br/>";
11910
11906
 
11911
- html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at: <select id='" + me.pre + "dsn6sigmaurlfofc'>";
11907
+ 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/>";
11912
11908
 
11913
- html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 5);
11909
+ html += "<span style='white-space:nowrap;font-weight:bold;'>fofc contour at default threshold or at: "
11910
+ + me.htmlCls.inputTextStr + "id='" + me.pre + "dsn6sigmaurlfofc' value='' size=8> &sigma;</span><br/>";
11914
11911
 
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/>";
11912
+ 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
11913
 
11918
11914
  html += me.htmlCls.buttonStr + "elecmapNo5'>Remove Map</button><br>";
11919
11915
 
@@ -12253,6 +12249,7 @@ class SetDialog {
12253
12249
  html += this.addNotebookTitle('dl_elecmap2fofc', 'Electron Density 2F0-Fc Map');
12254
12250
  html += "<span style='white-space:nowrap;font-weight:bold;'>Contour at: <select id='" + me.pre + "sigma2fofc'>";
12255
12251
 
12252
+ let optArray1 = ['0', '0.5', '1', '1.5', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
12256
12253
  html += me.htmlCls.setHtmlCls.getOptionHtml(optArray1, 3);
12257
12254
 
12258
12255
  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 +12896,7 @@ class Events {
12899
12896
  }
12900
12897
  }
12901
12898
 
12902
- readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
12899
+ async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
12903
12900
  let file = files[index];
12904
12901
  let commandName = (bAppend) ? 'append': 'load';
12905
12902
 
@@ -12936,7 +12933,20 @@ class Events {
12936
12933
  await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
12937
12934
  }
12938
12935
  else {
12939
- thisClass.readFile(bAppend, files, index + 1, dataStrAll);
12936
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
12937
+ }
12938
+
12939
+ if(bAppend) {
12940
+ if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
12941
+ //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
12942
+
12943
+ ic.bResetAnno = true;
12944
+
12945
+ if(ic.bAnnoShown) {
12946
+ await ic.showAnnoCls.showAnnotations();
12947
+
12948
+ ic.annotationCls.resetAnnoTabAll();
12949
+ }
12940
12950
  }
12941
12951
  };
12942
12952
 
@@ -12971,13 +12981,7 @@ class Events {
12971
12981
 
12972
12982
  ic.dataStrAll = '';
12973
12983
 
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
- }
12984
+ await this.readFile(bAppend, files, 0, '');
12981
12985
  }
12982
12986
  }
12983
12987
 
@@ -13061,7 +13065,10 @@ class Events {
13061
13065
 
13062
13066
  if(bStructures) {
13063
13067
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
13064
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
13068
+ if(ic.bAnnoShown) {
13069
+ await ic.showAnnoCls.showAnnotations();
13070
+ ic.annotationCls.resetAnnoTabAll();
13071
+ }
13065
13072
  }
13066
13073
  }
13067
13074
  }
@@ -13187,9 +13194,9 @@ class Events {
13187
13194
  thisClass.setLogCmd("clear selection", true);
13188
13195
  });
13189
13196
 
13190
- me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", function(e) { let ic = me.icn3d;
13197
+ me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", async function(e) { let ic = me.icn3d;
13191
13198
  ic.bAlternate = true;
13192
- ic.alternateCls.alternateStructures();
13199
+ await ic.alternateCls.alternateStructures();
13193
13200
  ic.bAlternate = false;
13194
13201
 
13195
13202
  thisClass.setLogCmd("alternate structures", false);
@@ -14071,15 +14078,37 @@ class Events {
14071
14078
 
14072
14079
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6file2fofc", "click", function(e) { let ic = me.icn3d;
14073
14080
  e.preventDefault();
14074
- if(!me.cfg.notebook) dialog.dialog( "close" );
14081
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14075
14082
  ic.dsn6ParserCls.loadDsn6File('2fofc');
14076
14083
  });
14077
14084
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6filefofc", "click", function(e) { let ic = me.icn3d;
14078
14085
  e.preventDefault();
14079
- if(!me.cfg.notebook) dialog.dialog( "close" );
14086
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14080
14087
  ic.dsn6ParserCls.loadDsn6File('fofc');
14081
14088
  });
14082
14089
 
14090
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4file2fofc", "click", function(e) { let ic = me.icn3d;
14091
+ e.preventDefault();
14092
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14093
+ ic.ccp4ParserCls.loadCcp4File('2fofc');
14094
+ });
14095
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4filefofc", "click", function(e) { let ic = me.icn3d;
14096
+ e.preventDefault();
14097
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14098
+ ic.ccp4ParserCls.loadCcp4File('fofc');
14099
+ });
14100
+
14101
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfile2fofc", "click", function(e) { let ic = me.icn3d;
14102
+ e.preventDefault();
14103
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14104
+ ic.mtzParserCls.loadMtzFile('2fofc');
14105
+ });
14106
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfilefofc", "click", function(e) { let ic = me.icn3d;
14107
+ e.preventDefault();
14108
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14109
+ ic.mtzParserCls.loadMtzFile('fofc');
14110
+ });
14111
+
14083
14112
  me.myEventCls.onIds("#" + me.pre + "reload_delphifile", "click", async function(e) { let ic = me.icn3d;
14084
14113
  e.preventDefault();
14085
14114
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -14169,15 +14198,37 @@ class Events {
14169
14198
 
14170
14199
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6fileurl2fofc", "click", function(e) { let ic = me.icn3d;
14171
14200
  e.preventDefault();
14172
- if(!me.cfg.notebook) dialog.dialog( "close" );
14201
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14173
14202
  ic.dsn6ParserCls.loadDsn6FileUrl('2fofc');
14174
14203
  });
14175
14204
  me.myEventCls.onIds("#" + me.pre + "reload_dsn6fileurlfofc", "click", function(e) { let ic = me.icn3d;
14176
14205
  e.preventDefault();
14177
- if(!me.cfg.notebook) dialog.dialog( "close" );
14206
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14178
14207
  ic.dsn6ParserCls.loadDsn6FileUrl('fofc');
14179
14208
  });
14180
14209
 
14210
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4fileurl2fofc", "click", function(e) { let ic = me.icn3d;
14211
+ e.preventDefault();
14212
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14213
+ ic.ccp4ParserCls.loadCcp4FileUrl('2fofc');
14214
+ });
14215
+ me.myEventCls.onIds("#" + me.pre + "reload_ccp4fileurlfofc", "click", function(e) { let ic = me.icn3d;
14216
+ e.preventDefault();
14217
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14218
+ ic.ccp4ParserCls.loadCcp4FileUrl('fofc');
14219
+ });
14220
+
14221
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfileurl2fofc", "click", function(e) { let ic = me.icn3d;
14222
+ e.preventDefault();
14223
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14224
+ ic.mtzParserCls.loadMtzFileUrl('2fofc');
14225
+ });
14226
+ me.myEventCls.onIds("#" + me.pre + "reload_mtzfileurlfofc", "click", function(e) { let ic = me.icn3d;
14227
+ e.preventDefault();
14228
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
14229
+ ic.mtzParserCls.loadMtzFileUrl('fofc');
14230
+ });
14231
+
14181
14232
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile", "click", async function(e) { me.icn3d;
14182
14233
  e.preventDefault();
14183
14234
 
@@ -15565,7 +15616,7 @@ class AlignSeq {
15565
15616
  // for(let i in ic.alnChains) {
15566
15617
  for (let m = 0, ml = alignChainArray.length; m < ml; ++m) {
15567
15618
  let i = alignChainArray[m];
15568
-
15619
+
15569
15620
  if (index == 0) firstChainid = i;
15570
15621
 
15571
15622
  if (bOnechain && index > 0) {
@@ -16468,6 +16519,7 @@ class SetHtml {
16468
16519
  let matchedStrData = "Start of data file======\n";
16469
16520
  let posData = imageStr.indexOf(matchedStrData);
16470
16521
  ic.bInputfile =(posData == -1) ? false : true;
16522
+ ic.bInputPNGWithData = ic.bInputfile;
16471
16523
  let commandStr = (command) ? command.replace(/;/g, "\n") : '';
16472
16524
 
16473
16525
  let statefile;
@@ -29339,8 +29391,8 @@ class ElectronMap {
29339
29391
  this.pLength = 0;
29340
29392
  this.cutRadius = 0;
29341
29393
  this.vpBits = null; // uint8 array of bitmasks
29342
- this.vpDistance = null; // floatarray of _squared_ distances
29343
- this.vpAtomID = null; // intarray
29394
+ this.vpGridTrans = null; // array of translated number of grids
29395
+ this.vpAtomID = null; // uint8 array
29344
29396
  this.vertnumber = 0;
29345
29397
  this.facenumber = 0;
29346
29398
  this.pminx = 0;
@@ -29390,12 +29442,27 @@ ElectronMap.prototype.getFacesAndVertices = function(allatoms, atomlist) {
29390
29442
  atomsToShow[atomlist[i]] = 1;
29391
29443
  let vertices = this.verts;
29392
29444
 
29445
+ let vertTrans = {};
29393
29446
  for(i = 0, il = vertices.length; i < il; i++) {
29394
29447
  let r;
29395
29448
  if(this.type == 'phi') {
29396
29449
  r = new THREE.Vector3(vertices[i].x, vertices[i].y, vertices[i].z).multiplyScalar(1.0/this.header.scale).applyMatrix4(this.matrix);
29397
29450
  }
29398
29451
  else {
29452
+ // ccp4 has no translation vector. Only translated vertices are used.
29453
+ if(this.header.ccp4) {
29454
+ let index = vertices[i].index;
29455
+ let finalIndex;
29456
+ if(this.vpGridTrans[index]) {
29457
+ finalIndex = index;
29458
+
29459
+ vertices[i].x += this.vpGridTrans[finalIndex][0] * this.header.xExtent * this.scaleFactor;
29460
+ vertices[i].y += this.vpGridTrans[finalIndex][1] * this.header.xExtent * this.scaleFactor;
29461
+ vertices[i].z += this.vpGridTrans[finalIndex][2] * this.header.xExtent * this.scaleFactor;
29462
+
29463
+ vertTrans[finalIndex] = 1;
29464
+ }
29465
+ }
29399
29466
  r = new THREE.Vector3(vertices[i].x, vertices[i].y, vertices[i].z).applyMatrix4(this.matrix);
29400
29467
  }
29401
29468
  // vertices[i].x = r.x / this.scaleFactor - this.ptranx;
@@ -29414,13 +29481,22 @@ ElectronMap.prototype.getFacesAndVertices = function(allatoms, atomlist) {
29414
29481
  let fa = this.faces[i], fb = this.faces[i+1], fc = this.faces[i+2];
29415
29482
 
29416
29483
  if(fa !== fb && fb !== fc && fa !== fc){
29417
- finalfaces.push({"a":fa, "b":fb, "c":fc});
29484
+ if(this.header.ccp4) {
29485
+ // only transfered vertices will be used
29486
+ if(vertTrans.hasOwnProperty(vertices[fa].index) && vertTrans.hasOwnProperty(vertices[fb].index)
29487
+ && vertTrans.hasOwnProperty(vertices[fc].index)) {
29488
+ finalfaces.push({"a":fa, "b":fb, "c":fc});
29489
+ }
29490
+ }
29491
+ else {
29492
+ finalfaces.push({"a":fa, "b":fb, "c":fc});
29493
+ }
29418
29494
  }
29419
29495
  }
29420
29496
 
29421
29497
  //try to help the garbage collector
29422
29498
  this.vpBits = null; // uint8 array of bitmasks
29423
- this.vpDistance = null; // floatarray
29499
+ this.vpGridTrans = null; // uint8 array
29424
29500
  this.vpAtomID = null; // intarray
29425
29501
 
29426
29502
  return {
@@ -29479,6 +29555,8 @@ ElectronMap.prototype.initparm = function(inHeader, inData, inMatrix, inIsovalue
29479
29555
  this.cutRadius = this.probeRadius * this.scaleFactor;
29480
29556
 
29481
29557
  this.vpBits = new Uint8Array(this.pLength * this.pWidth * this.pHeight);
29558
+ if(this.header.ccp4) this.vpGridTrans = new Array(this.pLength * this.pWidth * this.pHeight);
29559
+
29482
29560
  this.vpAtomID = new Uint8Array(this.pLength * this.pWidth * this.pHeight);
29483
29561
  };
29484
29562
 
@@ -29504,7 +29582,6 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29504
29582
  let i, j, k, il, jl, kl;
29505
29583
  for(i = 0, il = this.vpBits.length; i < il; i++) {
29506
29584
  this.vpBits[i] = 0;
29507
- //this.vpDistance[i] = -1.0;
29508
29585
  this.vpAtomID[i] = 0;
29509
29586
  }
29510
29587
 
@@ -29666,6 +29743,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29666
29743
  }
29667
29744
  }
29668
29745
  else {
29746
+ // let index2ori = {};
29669
29747
  for(let serial in atomlist) {
29670
29748
  let atom = atoms[atomlist[serial]];
29671
29749
 
@@ -29696,6 +29774,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29696
29774
 
29697
29775
  for(i = 0, il = indexArray.length; i < il; ++i) {
29698
29776
  let index = indexArray[i];
29777
+
29699
29778
  if(this.type == '2fofc') {
29700
29779
  this.vpBits[index] =(this.dataArray[index] >= this.isovalue) ? 1 : 0;
29701
29780
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
@@ -29709,6 +29788,7 @@ ElectronMap.prototype.fillvoxels = function(atoms, atomlist) { //(int seqinit,in
29709
29788
  //this.vpAtomID[index] =(this.dataArray[index] >= 0) ? 1 : 0; // determine whether it's positive
29710
29789
  }
29711
29790
  }
29791
+
29712
29792
  }
29713
29793
  }
29714
29794
 
@@ -29932,7 +30012,18 @@ class Surface {
29932
30012
  cfg.isovalue = ic.mapData.sigma2;
29933
30013
  cfg.type = '2fofc';
29934
30014
 
29935
- ps = this.SetupMap(cfg);
30015
+ //ccp4
30016
+ cfg.ccp4 = ic.mapData.ccp4;
30017
+ cfg.grid = ic.mapData.grid2;
30018
+ cfg.unit_cell = ic.mapData.unit_cell2;
30019
+
30020
+ if(cfg.header || cfg.ccp4) ps = this.SetupMap(cfg);
30021
+ else return;
30022
+
30023
+ if(cfg.ccp4) {
30024
+ ic.mapData = {};
30025
+ return;
30026
+ }
29936
30027
  }
29937
30028
  else if(type == 12) { // fofc
29938
30029
  cfg.header = ic.mapData.header;
@@ -29941,7 +30032,18 @@ class Surface {
29941
30032
  cfg.isovalue = ic.mapData.sigma;
29942
30033
  cfg.type = 'fofc';
29943
30034
 
29944
- ps = this.SetupMap(cfg);
30035
+ //ccp4
30036
+ cfg.ccp4 = ic.mapData.ccp4;
30037
+ cfg.grid = ic.mapData.grid;
30038
+ cfg.unit_cell = ic.mapData.unit_cell;
30039
+
30040
+ if(cfg.header || cfg.ccp4) ps = this.SetupMap(cfg);
30041
+ else return;
30042
+
30043
+ if(cfg.ccp4) {
30044
+ ic.mapData = {};
30045
+ return;
30046
+ }
29945
30047
  }
29946
30048
  else if(type == 13) { // em
29947
30049
  cfg.maxdist = 3; // EM map has no unit cell. It could include more gird space.
@@ -30429,29 +30531,60 @@ class Surface {
30429
30531
  }
30430
30532
 
30431
30533
  SetupMap(data) { let ic = this.icn3d; ic.icn3dui;
30432
- let ps = new ElectronMap(ic);
30433
-
30434
- ps.initparm(data.header, data.data, data.matrix, data.isovalue, data.center, data.maxdist,
30435
- data.pmin, data.pmax, data.water, data.type, data.rmsd_supr, data.loadPhiFrom, data.icn3d);
30534
+ if(data.ccp4) {
30535
+ let radius = 10;
30536
+ let center = (ic.center) ? [ic.center.x, ic.center.y, ic.center.z] : [0,0,0];
30537
+
30538
+ let typeDetail;
30539
+ if(data.type == '2fofc') {
30540
+ typeDetail = '2fofc';
30541
+ let result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
30542
+ let iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
30543
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
30544
+
30545
+ result = null;
30546
+ iso = null;
30547
+ }
30548
+ else if(data.type == 'fofc') {
30549
+ typeDetail = 'fofc_neg';
30550
+ let result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
30551
+ let iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
30552
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
30553
+
30554
+ typeDetail = 'fofc_pos';
30555
+ result = ic.ccp4ParserCls.extract_block(data.grid, data.unit_cell, radius, center, typeDetail);
30556
+ iso = ic.ccp4ParserCls.marchingCubes(result.size, result.values, result.points, data.isovalue, 'marching cubes');
30557
+ ic.ccp4ParserCls.makeChickenWire(iso, typeDetail);
30436
30558
 
30437
- ps.fillvoxels(data.allatoms, data.extendedAtoms);
30559
+ result = null;
30560
+ iso = null;
30561
+ }
30562
+ }
30563
+ else {
30564
+ let ps = new ElectronMap(ic);
30565
+
30566
+ ps.initparm(data.header, data.data, data.matrix, data.isovalue, data.center, data.maxdist,
30567
+ data.pmin, data.pmax, data.water, data.type, data.rmsd_supr, data.loadPhiFrom, data.icn3d);
30438
30568
 
30439
- if(!data.header.bSurface) ps.buildboundary();
30569
+ ps.fillvoxels(data.allatoms, data.extendedAtoms);
30440
30570
 
30441
- if(!data.header.bSurface) ps.marchingcube();
30442
-
30443
- ps.vpBits = null; // uint8 array of bitmasks
30444
- //ps.vpDistance = null; // floatarray of _squared_ distances
30445
- ps.vpAtomID = null; // intarray
30571
+ if(!data.header.bSurface) ps.buildboundary();
30446
30572
 
30447
- let result;
30573
+ if(!data.header.bSurface) ps.marchingcube();
30574
+
30575
+ ps.vpBits = null; // uint8 array of bitmasks
30576
+ //ps.vpDistance = null; // floatarray of _squared_ distances
30577
+ ps.vpAtomID = null; // intarray
30448
30578
 
30449
- if(!data.header.bSurface) result = ps.getFacesAndVertices(data.allatoms, data.atomsToShow);
30579
+ let result;
30450
30580
 
30451
- ps.faces = null;
30452
- ps.verts = null;
30581
+ if(!data.header.bSurface) result = ps.getFacesAndVertices(data.allatoms, data.atomsToShow);
30453
30582
 
30454
- return result;
30583
+ ps.faces = null;
30584
+ ps.verts = null;
30585
+
30586
+ return result;
30587
+ }
30455
30588
  }
30456
30589
  }
30457
30590
 
@@ -33412,7 +33545,7 @@ class Alternate {
33412
33545
 
33413
33546
  // change the display atom when alternating
33414
33547
  //Show structures one by one.
33415
- alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
33548
+ async alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
33416
33549
  ic.bAlternate = true;
33417
33550
 
33418
33551
  //ic.transformCls.zoominSelection();
@@ -33510,16 +33643,24 @@ class Alternate {
33510
33643
  ic.applyMapCls.removeEmmaps();
33511
33644
  ic.applyMapCls.applyEmmapOptions();
33512
33645
 
33513
- // allow the alternation of DelPhi map
33646
+ // allow the alternation of DelPhi map
33647
+ /*
33648
+ // Option 1: recalculate =========
33649
+ ic.applyMapCls.removePhimaps();
33650
+ await ic.delphiCls.loadDelphiFile('delphi');
33651
+
33652
+ ic.applyMapCls.removeSurfaces();
33653
+ await ic.delphiCls.loadDelphiFile('delphi2');
33654
+ // ==============
33655
+ */
33656
+
33657
+ // Option 2: NO recalculate, just show separately =========
33514
33658
  ic.applyMapCls.removePhimaps();
33515
33659
  ic.applyMapCls.applyPhimapOptions();
33516
- // should recalculate the potential
33517
- //ic.loadDelphiFileBase('delphi');
33518
33660
 
33519
33661
  ic.applyMapCls.removeSurfaces();
33520
33662
  ic.applyMapCls.applyphisurfaceOptions();
33521
- // should recalculate the potential
33522
- //ic.loadDelphiFileBase('delphi2');
33663
+ // ==============
33523
33664
 
33524
33665
  // alternate the PCA axes
33525
33666
  ic.axes = [];
@@ -33536,9 +33677,9 @@ class Alternate {
33536
33677
  ic.bShowHighlight = true;
33537
33678
  }
33538
33679
 
33539
- alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
33680
+ async alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
33540
33681
  ic.bAlternate = true;
33541
- this.alternateStructures();
33682
+ await this.alternateStructures();
33542
33683
  ic.bAlternate = false;
33543
33684
  }
33544
33685
 
@@ -35930,7 +36071,7 @@ class SetColor {
35930
36071
 
35931
36072
  for(let resid in residueHash) {
35932
36073
  if(!ic.resid2refnum[resid]) {
35933
- color = me.parasCls.thr('#FFFFFF');
36074
+ color = me.parasCls.thr('#00FFFF'); //('#FFFFFF');
35934
36075
  }
35935
36076
  else {
35936
36077
  let refnumLabel = ic.resid2refnum[resid];
@@ -35965,7 +36106,7 @@ class SetColor {
35965
36106
  let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
35966
36107
  for(let resid in residueHash) {
35967
36108
  if(!ic.resid2refnum[resid]) {
35968
- color = me.parasCls.thr('#FFFFFF');
36109
+ color = me.parasCls.thr('#00FFFF'); //('#FFFFFF');
35969
36110
  }
35970
36111
  else {
35971
36112
  let refnumLabel = ic.resid2refnum[resid];
@@ -36935,15 +37076,13 @@ class SetOption {
36935
37076
  const name2color = {
36936
37077
  //"A- Strand": "FF00FF",
36937
37078
  "A Strand": "9400D3", //"663399",
36938
- //"A+ Strand": "9400D3", //"663399",
36939
- "A' Strand": "9400D3", //"663399",
36940
37079
  "B Strand": "ba55d3",
36941
37080
  "C Strand": "0000FF",
36942
37081
  "C' Strand": "6495ED",
36943
37082
  "C'' Strand": "006400",
36944
37083
  "D Strand": "00FF00",
36945
- "E Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36946
- "F Strand": "FFA500",
37084
+ "E Strand": "FFD700", //"FFFF00", //"F0E68C",
37085
+ "F Strand": "FF8C00",
36947
37086
  "G Strand": "FF0000",
36948
37087
  //"G+ Strand": "8B0000",
36949
37088
  "Loop": "CCCCCC"
@@ -36970,15 +37109,15 @@ class SetOption {
36970
37109
  "<b>Protodomain 1</b>": "",
36971
37110
  "A Strand": "0000FF",
36972
37111
  "B Strand": "006400",
36973
- "C Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36974
- "C' Strand": "FFA500",
37112
+ "C Strand": "FFD700", //"FFFF00", //"F0E68C",
37113
+ "C' Strand": "FF8C00",
36975
37114
  "<br><b>Linker</b>": "",
36976
37115
  "C'' Strand": "FF0000",
36977
37116
  "<br><b>Protodomain 2</b>": "",
36978
37117
  "D Strand": "0000FF",
36979
37118
  "E Strand": "006400",
36980
- "F Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36981
- "G Strand": "FFA500",
37119
+ "F Strand": "FFD700", //"FFFF00", //"F0E68C",
37120
+ "G Strand": "FF8C00",
36982
37121
  "": "",
36983
37122
  "Loop": "CCCCCC"
36984
37123
  };
@@ -38180,14 +38319,14 @@ class AnnoDomain {
38180
38319
  let pdbid = pdbArray[index];
38181
38320
  //let url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=" + pdbid;
38182
38321
 
38183
- if(index == 0 && ic.mmdb_data !== undefined) {
38322
+ if(!ic.bResetAnno && index == 0 && ic.mmdb_data !== undefined) {
38184
38323
  for(let chnid in ic.protein_chainid) {
38185
38324
  if(chnid.indexOf(pdbid) !== -1) {
38186
38325
  this.showDomainWithData(chnid, ic.mmdb_data);
38187
38326
  }
38188
38327
  }
38189
38328
  }
38190
- else if(ic.mmdb_dataArray[index] !== undefined) {
38329
+ else if(!ic.bResetAnno && ic.mmdb_dataArray[index] !== undefined) {
38191
38330
  for(let chnid in ic.protein_chainid) {
38192
38331
  if(chnid.indexOf(pdbid) !== -1) {
38193
38332
  this.showDomainWithData(chnid, ic.mmdb_dataArray[index]);
@@ -38262,6 +38401,10 @@ class AnnoDomain {
38262
38401
  let domainArray, proteinname;
38263
38402
  let pos = chnid.indexOf('_');
38264
38403
  let chain = chnid.substr(pos + 1);
38404
+ // MMDB symmetry chain has the form of 'A1'
38405
+ if(chain.length > 1 && chain.substr(chain.length - 1) == '1') {
38406
+ chain = chain.substr(0, chain.length - 1);
38407
+ }
38265
38408
 
38266
38409
  if(bCalcDirect) {
38267
38410
  proteinname = chnid;
@@ -39267,7 +39410,11 @@ class Domain3d {
39267
39410
  //this.dcut = 8; // threshold for C-alpha interactions
39268
39411
 
39269
39412
  // It seemed the threshold 7 angstrom works better
39270
- this.dcut = 7; // threshold for C-alpha interactions
39413
+ //this.dcut = 7; // threshold for C-alpha interactions
39414
+ this.dcut = 8; // threshold for C-alpha interactions
39415
+
39416
+ // added by Jiyao
39417
+ this.min_contacts = 5; //3; // minimum number of contacts to be considered as neighbors
39271
39418
 
39272
39419
  this.MAX_SSE = 512;
39273
39420
 
@@ -39301,9 +39448,6 @@ class Domain3d {
39301
39448
  this.c_delta = 3; // cut set parameter
39302
39449
  this.nc_fact = 0.0; // size factor for internal contacts
39303
39450
 
39304
- // added by Jiyao
39305
- this.min_contacts = 3; // minimum number of contacts to be considered as neighbors
39306
-
39307
39451
  //let this.elements[2*this.MAX_SSE]; // sets of this.elements to be split
39308
39452
  this.elements = [];
39309
39453
  this.elements.length = 2*this.MAX_SSE;
@@ -42881,6 +43025,10 @@ class ShowAnno {
42881
43025
  chainLetter = chainLetter.substr(0, chainLetter.indexOf('_'));
42882
43026
  chainidBase = chainArray[i].substr(0, chainArray[i].indexOf('_')) + '_' + chainLetter;
42883
43027
  }
43028
+ else if(chainLetter.length > 1 && chainLetter.substr(chainLetter.length - 1) == '1') { // NCBI modified chainid, e.g., A1
43029
+ chainLetter = chainLetter.substr(0, chainLetter.length - 1);
43030
+ chainidBase = chainArray[i].substr(0, chainArray[i].indexOf('_')) + '_' + chainLetter;
43031
+ }
42884
43032
  else {
42885
43033
  chainidBase = chainArray[i];
42886
43034
  }
@@ -44081,7 +44229,7 @@ class ShowSeq {
44081
44229
  html += '</div>';
44082
44230
  html3 += '</div></div>';
44083
44231
  }
44084
-
44232
+
44085
44233
  if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
44086
44234
  let result = this.showAllRefNum(giSeq, chnid);
44087
44235
 
@@ -44150,9 +44298,13 @@ class ShowSeq {
44150
44298
 
44151
44299
  if(!ic.chainid2refpdbname[chnid]) return {html: html, html3: html3};
44152
44300
 
44153
- let chainList = ic.refnumCls.getTemplateList(chnid);
44301
+ let result = ic.refnumCls.getTemplateList(chnid);
44302
+ let refpdbnameList = result.refpdbnameList;
44303
+ let scoreList = result.scoreList;
44304
+ let seqidList = result.seqidList;
44305
+ let nresAlignList = result.nresAlignList;
44154
44306
 
44155
- let refStruTitle = (chainList) ? "based on " + chainList : "";
44307
+ 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 + "." : "";
44156
44308
 
44157
44309
  let htmlTmp = '<div class="icn3d-dl_sequence">';
44158
44310
  htmlTmp += '<div class="icn3d-residueLine" style="white-space:nowrap;">';
@@ -44208,7 +44360,8 @@ class ShowSeq {
44208
44360
 
44209
44361
  // auto-generate ref numbers for loops
44210
44362
  let bLoop = false, currStrand = '', prevStrand = '';
44211
- let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c;
44363
+ let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c, refnum2c;
44364
+ let bExtendedStrand = false, bSecThird9 = false;
44212
44365
 
44213
44366
  // sometimes one chain may have several Ig domains,set an index for each IgDomain
44214
44367
  let index = 1, bStart = false;
@@ -44234,8 +44387,8 @@ class ShowSeq {
44234
44387
 
44235
44388
  refnumLabel = ic.resid2refnum[residueid];
44236
44389
 
44237
- let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : ' ';
44238
- if(!bStart && refnumLabel && (firstChar == ' ' || firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44390
+ let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : '';
44391
+ if(!bStart && refnumLabel && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44239
44392
  bStart = true;
44240
44393
  resCnt = 1; // the first oen is included
44241
44394
  }
@@ -44252,14 +44405,21 @@ class ShowSeq {
44252
44405
  refnumStr = refnumStr_ori;
44253
44406
  refnum = parseInt(refnumStr);
44254
44407
  refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
44408
+ refnum2c = (refnum - parseInt(refnum/100) * 100).toString();
44409
+
44410
+ // for extended strands, since A is 1550 and A+ is 1650, then the AA+ loop will be 1591, 1592, ... 1610, 1611, etc
44411
+ bSecThird9 = refnum3c.substr(0,1) == '9' || refnum2c.substr(0,1) == '9' || refnum2c.substr(0,1) == '0' || refnum2c.substr(0,1) == '1';
44412
+ if(bSecThird9) ic.residIgLoop[residueid] = 1;
44413
+
44255
44414
  strandPostfix = refnumStr.replace(refnum.toString(), '');
44256
44415
 
44257
44416
  postfix = strandPostfix + '_' + index;
44258
44417
 
44259
- let firstTwo = parseInt(refnum.toString().substr(0, 2)); // A- strand
44418
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
44419
+ bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
44260
44420
 
44261
44421
  if(currStrand && currStrand != ' ') {
44262
- if(refnum3c.substr(0,1) != '9' || firstTwo == 10) {
44422
+ if(!bSecThird9 || (bExtendedStrand && !bSecThird9)) {
44263
44423
  let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
44264
44424
 
44265
44425
  if(currStrand != prevStrand) { // reset currCnt
@@ -44286,7 +44446,7 @@ class ShowSeq {
44286
44446
  resCntAtAnchor = 0;
44287
44447
  }
44288
44448
 
44289
- if(firstTwo == 10) {
44449
+ if(bExtendedStrand) {
44290
44450
  strandArray[strandCnt].anchorRefnum = 0;
44291
44451
  }
44292
44452
 
@@ -44312,7 +44472,7 @@ class ShowSeq {
44312
44472
  resCntAtAnchor = 0;
44313
44473
  }
44314
44474
 
44315
- if(firstTwo == 10) {
44475
+ if(bExtendedStrand) {
44316
44476
  strandArray[strandCnt - 1].anchorRefnum = 0;
44317
44477
  }
44318
44478
 
@@ -44368,7 +44528,7 @@ class ShowSeq {
44368
44528
  currStrand = refnumLabel.replace(new RegExp(refnumStr,'g'), '');
44369
44529
 
44370
44530
  let firstChar = refnumLabel.substr(0,1);
44371
- if(!bStart && (firstChar == ' ' || firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44531
+ if(!bStart && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
44372
44532
  bStart = true;
44373
44533
  bBeforeAstrand = true;
44374
44534
  loopCnt = 0;
@@ -44641,6 +44801,11 @@ class ShowSeq {
44641
44801
 
44642
44802
  getRefnumHtml(residueid, refnumStr, refnumStr_ori, refnumLabel, currStrand, bLoop, bHidelabel) { let ic = this.icn3d, me = ic.icn3dui;
44643
44803
  let refnum = parseInt(refnumStr).toString();
44804
+
44805
+ let refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
44806
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
44807
+ let bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
44808
+
44644
44809
  let color = this.getRefnumColor(currStrand, true);
44645
44810
  let colorStr = (!bLoop) ? 'style="color:' + color + '; text-decoration: underline overline;"' : 'style="color:' + color + '"';
44646
44811
 
@@ -44650,13 +44815,13 @@ class ShowSeq {
44650
44815
 
44651
44816
  let html = '';
44652
44817
 
44653
- if(refnumLabel && (lastTwo == 50 || refnum == 1094) && !bLoop) {
44818
+ if(refnumLabel && lastTwo == 50 && !bExtendedStrand && !bLoop) {
44654
44819
  // highlight the anchor residues
44655
44820
  ic.hAtomsRefnum = me.hashUtilsCls.unionHash(ic.hAtomsRefnum, ic.residues[residueid]);
44656
44821
 
44657
44822
  html += '<span ' + colorStr + ' title="' + refnumLabel + '"><b>' + refnumLabel.substr(0, 1) + '</b>' + refnumLabel.substr(1) + '</span>';
44658
44823
  }
44659
- else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && refnum != 1096 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
44824
+ else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
44660
44825
  // e.g., 2152a
44661
44826
  lastTwoStr = isNaN(refnumStr) ? lastTwoStr + refnumStr.substr(refnumStr.length - 1, 1) : lastTwoStr;
44662
44827
  html += '<span ' + colorStr + ' title="' + refnumLabel + '">' + lastTwoStr + '</span>';
@@ -44669,23 +44834,9 @@ class ShowSeq {
44669
44834
  }
44670
44835
 
44671
44836
  getRefnumColor(currStrand, bText) { let ic = this.icn3d, me = ic.icn3dui;
44672
- if(currStrand == "A-") {
44673
- return '#9400D3'; //'#663399';
44674
- }
44675
- else if(currStrand == "A") {
44676
- return '#9400D3'; //'#663399';
44677
- }
44678
- //else if(currStrand == "A*") {
44679
- else if(currStrand == "A+") {
44680
- return '#9400D3'; //'#663399';
44681
- }
44682
- else if(currStrand == "A'") {
44683
- return '#9400D3'; //'#663399';
44684
- }
44685
- else if(currStrand == "B") {
44686
- return '#ba55d3';
44687
- }
44688
- else if(currStrand == "C") {
44837
+ let strand = (currStrand) ? currStrand.substr(0,1) : '';
44838
+
44839
+ if(currStrand == "C") {
44689
44840
  return '#0000FF';
44690
44841
  }
44691
44842
  else if(currStrand == "C'") {
@@ -44694,39 +44845,44 @@ class ShowSeq {
44694
44845
  else if(currStrand == "C''") {
44695
44846
  return '#006400';
44696
44847
  }
44697
- else if(currStrand == "D") {
44848
+
44849
+ else if(strand == "A") {
44850
+ return '#9400D3'; //'#663399';
44851
+ }
44852
+ else if(strand == "B") {
44853
+ return '#ba55d3';
44854
+ }
44855
+ else if(strand == "D") {
44698
44856
  return '#00FF00';
44699
44857
  }
44700
- else if(currStrand == "E") {
44701
- //return (bText) ? "#F7DC6F" : "#FFFF00";
44702
- return "#F7DC6F";
44858
+ else if(strand == "E") {
44859
+ return "#FFD700";
44703
44860
  }
44704
- else if(currStrand == "F") {
44705
- return '#FFA500';
44861
+ else if(strand == "F") {
44862
+ return '#FF8C00';
44706
44863
  }
44707
- else if(currStrand == "G") {
44864
+ else if(strand == "G") {
44708
44865
  return '#FF0000';
44709
44866
  }
44710
- else if(currStrand == "G+") {
44711
- return '#8B0000';
44712
- }
44713
44867
  else {
44714
44868
  return me.htmlCls.GREYB;
44715
44869
  }
44716
44870
  }
44717
44871
 
44718
44872
  getProtodomainColor(currStrand) { let ic = this.icn3d, me = ic.icn3dui;
44719
- if((currStrand && currStrand.substr(0,1) == "A") || currStrand == "D") {
44873
+ let strand = (currStrand) ? currStrand.substr(0,1) : '';
44874
+
44875
+ if(strand == "A" || strand == "D") {
44720
44876
  return '#0000FF';
44721
44877
  }
44722
- else if(currStrand == "B" || currStrand == "E") {
44878
+ else if(strand == "B" || strand == "E") {
44723
44879
  return '#006400';
44724
44880
  }
44725
- else if(currStrand == "C" || currStrand == "F") {
44726
- return "#F7DC6F"; //"#FFFF00"; //'#F0E68C';
44881
+ else if(currStrand == "C" || strand == "F") {
44882
+ return "#FFD700"; //"#FFFF00"; //'#F0E68C';
44727
44883
  }
44728
- else if(currStrand == "C'" || (currStrand && currStrand.substr(0, 1) == "G")) {
44729
- return '#FFA500';
44884
+ else if(currStrand == "C'" || strand == "G") {
44885
+ return '#FF8C00';
44730
44886
  }
44731
44887
  else if(currStrand == "C''") { //linker
44732
44888
  return '#FF0000';
@@ -45429,8 +45585,8 @@ class HlUpdate {
45429
45585
  updateHlObjects(bForceHighlight) { let ic = this.icn3d; ic.icn3dui;
45430
45586
  ic.hlObjectsCls.removeHlObjects();
45431
45587
 
45432
- if((ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length < Object.keys(ic.atoms).length) || bForceHighlight) {
45433
- ic.hlObjectsCls.addHlObjects();
45588
+ if((ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length < Object.keys(ic.dAtoms).length) || bForceHighlight) {
45589
+ if(ic.bShowHighlight === undefined || ic.bShowHighlight) ic.hlObjectsCls.addHlObjects();
45434
45590
  ic.definedSetsCls.setMode('selection');
45435
45591
  }
45436
45592
  }
@@ -46510,8 +46666,11 @@ class LineGraph {
46510
46666
 
46511
46667
  // try {
46512
46668
  if(!template) {
46513
- let allPromise = Promise.allSettled(pdbAjaxArray);
46514
- ic.pdbDataArray = await allPromise;
46669
+ //let allPromise = Promise.allSettled(pdbAjaxArray);
46670
+ //ic.pdbDataArray = await allPromise;
46671
+
46672
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46673
+
46515
46674
  await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46516
46675
  }
46517
46676
  else {
@@ -46622,6 +46781,7 @@ class LineGraph {
46622
46781
  }
46623
46782
 
46624
46783
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
46784
+ if(!ic.domainid2score) ic.domainid2score = {};
46625
46785
 
46626
46786
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
46627
46787
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
@@ -46633,7 +46793,7 @@ class LineGraph {
46633
46793
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtomsArray[k]);
46634
46794
  let resiSum = atomFirst.resi + ':' + atomLast.resi;
46635
46795
  //let domainid = chainid + '-' + k + '_' + Object.keys(domainAtomsArray[k]).length;
46636
- let domainid = chainid + '-' + k + '_' + resiSum;
46796
+ let domainid = chainid + ',' + k + '_' + resiSum;
46637
46797
  ic.domainid2pdb[domainid] = pdb_target;
46638
46798
 
46639
46799
  if(!template) {
@@ -46663,30 +46823,14 @@ class LineGraph {
46663
46823
  }
46664
46824
  }
46665
46825
 
46666
- try {
46826
+ //try {
46667
46827
  if(!template) {
46668
46828
  let dataArray2 = [];
46669
46829
 
46670
46830
  // let allPromise = Promise.allSettled(ajaxArray);
46671
46831
  // dataArray2 = await allPromise;
46672
46832
 
46673
- //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46674
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46675
-
46676
- for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46677
- let currAjaxArray = [];
46678
- if(i == il - 1) { // last one
46679
- currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
46680
- }
46681
- else {
46682
- currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
46683
- }
46684
-
46685
- let currPromise = Promise.allSettled(currAjaxArray);
46686
- let currDataArray = await currPromise;
46687
-
46688
- dataArray2 = dataArray2.concat(currDataArray);
46689
- }
46833
+ dataArray2 = await this.promiseWithFixedJobs(ajaxArray);
46690
46834
 
46691
46835
  let bRound1 = true;
46692
46836
  await thisClass.parseAlignData(dataArray2, domainidpairArray, bRound1);
@@ -46706,12 +46850,14 @@ class LineGraph {
46706
46850
  let pdbAjaxArray = [];
46707
46851
  pdbAjaxArray.push(pdbAjax);
46708
46852
 
46709
- let allPromise2 = Promise.allSettled(pdbAjaxArray);
46710
- ic.pdbDataArray = await allPromise2;
46853
+ //let allPromise2 = Promise.allSettled(pdbAjaxArray);
46854
+ //ic.pdbDataArray = await allPromise2;
46855
+
46856
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46711
46857
 
46712
46858
  for(let domainid in ic.domainid2refpdbname) {
46713
- let refpdbname = ic.domainid2refpdbname[domainid];
46714
- let chainid = domainid.substr(0, domainid.indexOf('-'));
46859
+ ic.domainid2refpdbname[domainid];
46860
+ domainid.substr(0, domainid.indexOf(','));
46715
46861
 
46716
46862
  let pdb_target = ic.domainid2pdb[domainid];
46717
46863
  for(let index = 0, indexl = ic.pdbDataArray.length; index < indexl; ++index) {
@@ -46731,11 +46877,14 @@ class LineGraph {
46731
46877
  }
46732
46878
 
46733
46879
  let dataArray3 = [];
46734
- let allPromise = Promise.allSettled(ajaxArray);
46735
- dataArray3 = await allPromise;
46880
+ //let allPromise = Promise.allSettled(ajaxArray);
46881
+ //dataArray3 = await allPromise;
46882
+
46883
+ dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
46736
46884
 
46737
46885
  await thisClass.parseAlignData(dataArray3, domainidpairArray3);
46738
46886
  }
46887
+ /*
46739
46888
  }
46740
46889
  catch(err) {
46741
46890
  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...";
@@ -46747,17 +46896,23 @@ class LineGraph {
46747
46896
  }
46748
46897
  //console.log("Error in aligning with TM-align...");
46749
46898
  return;
46750
- }
46899
+ }
46900
+ */
46751
46901
  }
46752
46902
 
46753
46903
  getTemplateList(chainid) { let ic = this.icn3d; ic.icn3dui;
46754
- let domainid2refpdbname = {};
46904
+ let domainid2refpdbname = {}, domainid2score = {};
46755
46905
 
46756
46906
  for(let i = 0, il = ic.chainid2refpdbname[chainid].length; i < il; ++i) {
46757
46907
  let refpdbname_domainid = ic.chainid2refpdbname[chainid][i].split('|');
46758
46908
  domainid2refpdbname[refpdbname_domainid[1]] = refpdbname_domainid[0];
46759
46909
  }
46760
46910
 
46911
+ for(let i = 0, il = ic.chainid2score[chainid].length; i < il; ++i) {
46912
+ let score_domainid = ic.chainid2score[chainid][i].split('|');
46913
+ domainid2score[score_domainid[1]] = score_domainid[0];
46914
+ }
46915
+
46761
46916
  let domainidArray = Object.keys(domainid2refpdbname);
46762
46917
  domainidArray.sort(function(id1, id2) {
46763
46918
  let resi1 = parseInt(id1.substr(id1.lastIndexOf('_') + 1));
@@ -46765,13 +46920,28 @@ class LineGraph {
46765
46920
  return resi1 - resi2;
46766
46921
  });
46767
46922
 
46768
- let chainList = '';
46923
+ let refpdbnameList = '';
46924
+ for(let i = 0, il = domainidArray.length; i < il; ++i) {
46925
+ refpdbnameList += domainid2refpdbname[domainidArray[i]];
46926
+ if(i < il - 1) refpdbnameList += ", ";
46927
+ }
46928
+
46929
+ let scoreList = '', seqidList = '', nresAlignList = '';
46769
46930
  for(let i = 0, il = domainidArray.length; i < il; ++i) {
46770
- chainList += domainid2refpdbname[domainidArray[i]];
46771
- if(i < il - 1) chainList += ", ";
46931
+ let itemArray = domainid2score[domainidArray[i]].split('_');
46932
+
46933
+ scoreList += itemArray[0];
46934
+ seqidList += itemArray[1];
46935
+ nresAlignList += itemArray[2];
46936
+
46937
+ if(i < il - 1) {
46938
+ scoreList += ", ";
46939
+ seqidList += ", ";
46940
+ nresAlignList += ", ";
46941
+ }
46772
46942
  }
46773
46943
 
46774
- return chainList;
46944
+ return {'refpdbnameList': refpdbnameList, 'scoreList': scoreList, 'seqidList': seqidList, 'nresAlignList': nresAlignList};
46775
46945
  }
46776
46946
 
46777
46947
  async parseAlignData(dataArray, domainidpairArray, bRound1) { let ic = this.icn3d, me = ic.icn3dui;
@@ -46780,33 +46950,35 @@ class LineGraph {
46780
46950
  let tmscoreThreshold = 0.4; // 0.4; //0.5;
46781
46951
 
46782
46952
  // find the best alignment for each chain
46783
- let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
46953
+ let domainid2segs = {}, chainid2segs = {};
46784
46954
 
46785
46955
  if(!ic.chainid2refpdbname) ic.chainid2refpdbname = {};
46956
+ if(!ic.chainid2score) ic.chainid2score = {};
46786
46957
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
46958
+ if(!ic.domainid2score) ic.domainid2score = {};
46787
46959
  if(!ic.domainid2ig2kabat) ic.domainid2ig2kabat = {};
46788
46960
  if(!ic.domainid2ig2imgt) ic.domainid2ig2imgt = {};
46789
46961
 
46790
- // ic.chainid2refpdbname = {};
46791
- // ic.domainid2refpdbname = {};
46792
- // ic.domainid2ig2kabat = {};
46793
- // ic.domainid2ig2imgt = {};
46794
-
46795
46962
  let minResidues = 20;
46796
46963
 
46797
46964
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
46798
46965
  //let queryData = (me.bNode) ? dataArray[i] : dataArray[i].value; //[0];
46799
46966
  let queryData = dataArray[i].value; //[0];
46800
46967
 
46801
- if(!queryData) {
46968
+ if(!queryData || queryData.length == 0) {
46802
46969
  if(!me.bNode) console.log("The alignment data for " + domainidpairArray[i] + " is unavailable...");
46803
46970
  continue;
46804
46971
  }
46805
-
46806
- if(queryData.length == 0) continue;
46807
46972
 
46973
+ //let domainid_index = domainidpairArray[i].split(',');
46974
+ //let domainid = domainid_index[0];
46975
+ let domainid = domainidpairArray[i].substr(0, domainidpairArray[i].indexOf('|'));
46976
+ let refpdbname = domainidpairArray[i].substr(domainidpairArray[i].indexOf('|') + 1);
46977
+ //let chainid = domainid.split('-')[0];
46978
+
46808
46979
  if(!bRound1) {
46809
46980
  if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < minResidues) {
46981
+ if(!me.bNode) console.log("domainid " + domainid + " and refpdbname " + refpdbname + " were skipped due to a TM-score less than " + tmscoreThreshold);
46810
46982
  continue;
46811
46983
  }
46812
46984
  }
@@ -46818,12 +46990,6 @@ class LineGraph {
46818
46990
  continue;
46819
46991
  }
46820
46992
  }
46821
-
46822
- //let domainid_index = domainidpairArray[i].split(',');
46823
- //let domainid = domainid_index[0];
46824
- let domainid = domainidpairArray[i].substr(0, domainidpairArray[i].indexOf('|'));
46825
- let refpdbname = domainidpairArray[i].substr(domainidpairArray[i].indexOf('|') + 1);
46826
- //let chainid = domainid.split('-')[0];
46827
46993
 
46828
46994
  if(!bRound1) {
46829
46995
  if(!me.bNode) console.log("refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
@@ -46840,16 +47006,16 @@ class LineGraph {
46840
47006
  for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
46841
47007
  let seg = queryData[0].segs[i];
46842
47008
 
46843
- if(seg.q_start.indexOf('2150') != -1 || seg.q_start.indexOf('2250') != -1) {
47009
+ if(seg.q_start.indexOf('2550') != -1) {
46844
47010
  bBstrand = true;
46845
47011
  }
46846
- else if(seg.q_start.indexOf('3150') != -1 || seg.q_start.indexOf('3250') != -1) {
47012
+ else if(seg.q_start.indexOf('3550') != -1) {
46847
47013
  bCstrand = true;
46848
47014
  }
46849
- else if(seg.q_start.indexOf('7150') != -1 || seg.q_start.indexOf('7250') != -1) {
47015
+ else if(seg.q_start.indexOf('7550') != -1) {
46850
47016
  bEstrand = true;
46851
47017
  }
46852
- else if(seg.q_start.indexOf('8150') != -1 || seg.q_start.indexOf('8250') != -1) {
47018
+ else if(seg.q_start.indexOf('8550') != -1) {
46853
47019
  bFstrand = true;
46854
47020
  }
46855
47021
 
@@ -46860,35 +47026,25 @@ class LineGraph {
46860
47026
  //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
46861
47027
  if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
46862
47028
  if(!me.bNode) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
46863
- if(ic.domainid2refpdbname[domainid] == refpdbname) delete ic.domainid2refpdbname[domainid];
47029
+ if(ic.domainid2refpdbname[domainid] == refpdbname) {
47030
+ delete ic.domainid2refpdbname[domainid];
47031
+ delete ic.domainid2score[domainid];
47032
+ }
46864
47033
  continue;
46865
47034
  }
46866
47035
  }
46867
47036
 
46868
47037
  if(!bRound1) {
46869
47038
  console.log("domainid: " + domainid);
46870
-
46871
- if(!domainid2score.hasOwnProperty(domainid) || queryData[0].score > domainid2score[domainid]) {
46872
- domainid2score[domainid] = queryData[0].score;
46873
-
46874
- ic.domainid2refpdbname[domainid] = refpdbname;
46875
- domainid2segs[domainid] = queryData[0].segs;
46876
- ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
46877
- ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46878
- }
46879
47039
  }
46880
- else {
46881
- //let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
46882
- let mixScore = queryData[0].score;
46883
47040
 
46884
- if(!domainid2score.hasOwnProperty(domainid) || mixScore > domainid2score[domainid]) {
46885
- domainid2score[domainid] = mixScore;
46886
-
46887
- ic.domainid2refpdbname[domainid] = refpdbname;
46888
- domainid2segs[domainid] = queryData[0].segs;
46889
- ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
46890
- ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46891
- }
47041
+ if(!ic.domainid2score.hasOwnProperty(domainid) || queryData[0].score >= ic.domainid2score[domainid].split('_')[0]) {
47042
+ ic.domainid2score[domainid] = queryData[0].score + '_' + queryData[0].frac_identical + '_' + queryData[0].num_res ;
47043
+
47044
+ ic.domainid2refpdbname[domainid] = refpdbname;
47045
+ domainid2segs[domainid] = queryData[0].segs;
47046
+ ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
47047
+ ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
46892
47048
  }
46893
47049
  }
46894
47050
 
@@ -46903,7 +47059,7 @@ class LineGraph {
46903
47059
  let pdbAjaxArray = [];
46904
47060
  let refpdbname = ic.domainid2refpdbname[domainid];
46905
47061
  //let pdbid = domainid.substr(0, domainid.indexOf('_'));
46906
- let chainid = domainid.substr(0, domainid.indexOf('-'));
47062
+ let chainid = domainid.substr(0, domainid.indexOf(','));
46907
47063
 
46908
47064
  //if(ic.refpdbHash.hasOwnProperty(pdbid)) {
46909
47065
  if(ic.refpdbHash.hasOwnProperty(chainid)) {
@@ -46926,8 +47082,10 @@ class LineGraph {
46926
47082
  pdbAjaxArray.push(pdbAjax);
46927
47083
  }
46928
47084
 
46929
- let allPromise2 = Promise.allSettled(pdbAjaxArray);
46930
- ic.pdbDataArray = await allPromise2;
47085
+ //let allPromise2 = Promise.allSettled(pdbAjaxArray);
47086
+ //ic.pdbDataArray = await allPromise2;
47087
+
47088
+ ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46931
47089
 
46932
47090
  let pdb_target = ic.domainid2pdb[domainid];
46933
47091
  for(let index = 0, indexl = ic.pdbDataArray.length; index < indexl; ++index) {
@@ -46950,49 +47108,46 @@ class LineGraph {
46950
47108
  //let allPromise = Promise.allSettled(ajaxArray);
46951
47109
  //dataArray3 = await allPromise;
46952
47110
 
46953
- //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46954
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46955
-
46956
- for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46957
- let currAjaxArray = [];
46958
- if(i == il - 1) { // last one
46959
- currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
46960
- }
46961
- else {
46962
- currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
46963
- }
46964
-
46965
- let currPromise = Promise.allSettled(currAjaxArray);
46966
- let currDataArray = await currPromise;
46967
-
46968
- dataArray3 = dataArray3.concat(currDataArray);
46969
- }
47111
+ dataArray3 = await this.promiseWithFixedJobs(ajaxArray);
46970
47112
 
46971
47113
  await thisClass.parseAlignData(dataArray3, domainidpairArray3, false);
46972
47114
 
46973
47115
  // end of round 2
46974
47116
  return;
46975
47117
  }
46976
-
47118
+
46977
47119
  // combine domainid into chainid
46978
47120
  let processedChainid = {};
46979
47121
  for(let domainid in ic.domainid2refpdbname) {
46980
- let chainid = domainid.split('-')[0];
47122
+ // remove the first round template
47123
+ if(ic.domainid2refpdbname[domainid].substr(0,1) == '1') {
47124
+ delete ic.domainid2refpdbname[domainid];
47125
+ delete ic.domainid2score[domainid];
47126
+ continue;
47127
+ }
46981
47128
 
46982
- if(!processedChainid.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
47129
+ let chainid = domainid.split(',')[0];
47130
+
47131
+ if(!processedChainid.hasOwnProperty(chainid)) {
47132
+ ic.chainid2refpdbname[chainid] = [];
47133
+ ic.chainid2score[chainid] = [];
47134
+ }
46983
47135
  processedChainid[chainid] = 1;
46984
47136
 
46985
47137
  if(!ic.chainid2refpdbname.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
46986
47138
  ic.chainid2refpdbname[chainid].push(ic.domainid2refpdbname[domainid] + '|' + domainid);
47139
+
47140
+ if(!ic.chainid2score.hasOwnProperty(chainid)) ic.chainid2score[chainid] = [];
47141
+ ic.chainid2score[chainid].push(ic.domainid2score[domainid] + '|' + domainid);
46987
47142
  }
46988
-
47143
+
46989
47144
  // combine domainid into chainid
46990
47145
  for(let domainid in domainid2segs) {
46991
- let chainid = domainid.split('-')[0];
47146
+ let chainid = domainid.split(',')[0];
46992
47147
  if(!chainid2segs[chainid]) chainid2segs[chainid] = [];
46993
47148
  chainid2segs[chainid] = chainid2segs[chainid].concat(domainid2segs[domainid]);
46994
47149
  }
46995
-
47150
+
46996
47151
  // assign ic.resid2refnum, ic.refnum2residArray, ic.chainsMapping
46997
47152
  if(!ic.resid2refnum) ic.resid2refnum = {};
46998
47153
  if(!ic.refnum2residArray) ic.refnum2residArray = {};
@@ -47005,11 +47160,18 @@ class LineGraph {
47005
47160
 
47006
47161
  let refpdbnameArray = ic.chainid2refpdbname[chainid];
47007
47162
 
47008
- let chainList = this.getTemplateList(chainid);
47163
+ let result = this.getTemplateList(chainid);
47164
+ let refpdbnameList = result.refpdbnameList;
47165
+ let scoreList = result.scoreList;
47166
+ let seqidList = result.seqidList;
47167
+ let nresAlignList = result.nresAlignList;
47009
47168
 
47010
- //if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
47011
- if(!me.bNode) console.log("The reference PDB(s) for chain " + chainid + " are " + chainList);
47012
- ic.refPdbList.push("The reference PDB(s) for chain " + chainid + " are " + chainList);
47169
+ 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 + ".";
47170
+ if(!me.bNode) {
47171
+ console.log(message);
47172
+ me.htmlCls.clickMenuCls.setLogCmd(message, true);
47173
+ }
47174
+ ic.refPdbList.push(message);
47013
47175
 
47014
47176
  let prevStrand;
47015
47177
  let bCd19 = refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
@@ -47079,51 +47241,52 @@ class LineGraph {
47079
47241
  getLabelFromRefnum(oriRefnum, prevStrand, bCd19) { let ic = this.icn3d; ic.icn3dui;
47080
47242
  let refnum = parseInt(oriRefnum);
47081
47243
 
47082
- // A-: 10xx
47083
- // A: 11xx
47084
- // A+ continue A
47085
- // A': 12xx
47086
- // B: 21xx
47087
- // C: 32xx
47088
- // C': 42xx
47089
- // C'': 51xx, 52xx
47090
- // D: 61xx
47091
- // E: 71xx
47092
- // E+: continue E
47093
- // F: 82xx
47094
- // G: 91xx, 92xx
47095
- // G+: continue G
47096
-
47097
- // if(refnum < 100) return " " + oriRefnum;
47098
- // else if(refnum >= 100 && refnum < 1000) {
47099
- // if(bCd19) return " " + oriRefnum;
47100
- // else return "A^" + oriRefnum;
47101
- // }
47102
- if(refnum < 900) return undefined;
47103
- else if(refnum >= 900 && refnum < 1000) return " " + oriRefnum;
47104
- else if(refnum >= 1000 && refnum < 1100) return "A-" + oriRefnum;
47105
- else if(refnum >= 1100 && refnum < 1200) return "A" + oriRefnum; // could be A+
47106
- else if(refnum >= 1200 && refnum < 1300) return "A'" + oriRefnum;
47107
- //else if(refnum >= 1300 && refnum < 1400) return "A+" + oriRefnum;
47108
- else if(refnum >= 1300 && refnum < 2000) {
47109
- if(prevStrand && prevStrand.substr(0, 1) == 'A') {
47110
- return prevStrand + oriRefnum;
47111
- }
47112
- else {
47113
- return "A" + oriRefnum;
47114
- }
47115
- }
47116
- else if(refnum >= 2000 && refnum < 3000) return "B" + oriRefnum;
47117
- else if(refnum >= 3000 && refnum < 4000) return "C" + oriRefnum;
47118
- else if(refnum >= 4000 && refnum < 5000) return "C'" + oriRefnum;
47119
- else if(refnum >= 5000 && refnum < 6000) return "C''" + oriRefnum;
47120
- else if(refnum >= 6000 && refnum < 7000) return "D" + oriRefnum;
47121
- else if(refnum >= 7000 && refnum < 8000) return "E" + oriRefnum; // could be E+
47122
- else if(refnum >= 8000 && refnum < 9000) return "F" + oriRefnum;
47123
- else if(refnum >= 9000 && refnum < 9300) return "G" + oriRefnum; // could be G+
47124
- //else if(refnum >= 9400 && refnum < 9500) return "G+" + oriRefnum;
47125
- else if(refnum >= 9300) return "G" + oriRefnum;
47126
- }
47244
+ //N-terminus = 0999-0001
47245
+ //A--- = 12xx
47246
+ //A-- = 13xx
47247
+ //A- = 14xx
47248
+ //A = 15xx (anchor 1550)
47249
+ //A+ = 16xx
47250
+ //A' = 18xx (anchor 1850)
47251
+ //B = 25xx (anchor 2550)
47252
+ //C-- = 33xx
47253
+ //C- = 34xx
47254
+ //C = 35xx (anchor 3550)
47255
+ //C' = 45xx (anchor 4550)
47256
+ //C'' = 55xx (anchor 5550)
47257
+ //D = 65xx (anchor 3550)
47258
+ //E = 75xx (anchor 7550)
47259
+ //E+ = 76xx
47260
+ //F = 85xx (anchor 8550)
47261
+ //G = 95xx (anchor 9550)
47262
+ //G+ = 96xx
47263
+ //G++ = 97xx
47264
+ //C-terminus = 9901-9999 (no anchor, numbering going forward)
47265
+
47266
+ // loops may have numbers such as 1310, 1410
47267
+
47268
+ if(refnum < 1000) return undefined;
47269
+ else if(refnum >= 1200 && refnum < 1290) return "A---" + oriRefnum;
47270
+ else if(refnum >= 1320 && refnum < 1390) return "A--" + oriRefnum;
47271
+ else if(refnum >= 1420 && refnum < 1490) return "A-" + oriRefnum;
47272
+ else if(refnum >= 1520 && refnum < 1590) return "A" + oriRefnum;
47273
+ else if(refnum >= 1620 && refnum < 1690) return "A+" + oriRefnum;
47274
+ else if(refnum >= 1820 && refnum < 1890) return "A'" + oriRefnum;
47275
+ else if(refnum >= 2000 && refnum < 2900) return "B" + oriRefnum;
47276
+ else if(refnum >= 3300 && refnum < 3390) return "C--" + oriRefnum;
47277
+ else if(refnum >= 3420 && refnum < 3490) return "C-" + oriRefnum;
47278
+ else if(refnum >= 3520 && refnum < 3590) return "C" + oriRefnum;
47279
+ else if(refnum >= 4000 && refnum < 4900) return "C'" + oriRefnum;
47280
+ else if(refnum >= 5000 && refnum < 5900) return "C''" + oriRefnum;
47281
+ else if(refnum >= 6000 && refnum < 6900) return "D" + oriRefnum;
47282
+ else if(refnum >= 7500 && refnum < 7590) return "E" + oriRefnum;
47283
+ else if(refnum >= 7620 && refnum < 7900) return "E+" + oriRefnum;
47284
+ else if(refnum >= 8000 && refnum < 8900) return "F" + oriRefnum;
47285
+ else if(refnum >= 9500 && refnum < 9590) return "G" + oriRefnum;
47286
+ else if(refnum >= 9620 && refnum < 9690) return "G+" + oriRefnum;
47287
+ else if(refnum >= 9720 && refnum < 9790) return "G++" + oriRefnum;
47288
+ else if(refnum > 9900) return undefined;
47289
+ else return " " + oriRefnum; }
47127
47290
 
47128
47291
  async parseCustomRefFile(data) { let ic = this.icn3d; ic.icn3dui;
47129
47292
  ic.bShowCustomRefnum = true;
@@ -47305,6 +47468,32 @@ class LineGraph {
47305
47468
  return refData;
47306
47469
  }
47307
47470
  }
47471
+
47472
+ async promiseWithFixedJobs(ajaxArray) { let ic = this.icn3d, me = ic.icn3dui;
47473
+ let dataArray3 = [];
47474
+ //let allPromise = Promise.allSettled(ajaxArray);
47475
+ //dataArray3 = await allPromise;
47476
+
47477
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
47478
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
47479
+
47480
+ for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
47481
+ let currAjaxArray = [];
47482
+ if(i == il - 1) { // last one
47483
+ currAjaxArray = ajaxArray.slice(i * n, ajaxArray.length);
47484
+ }
47485
+ else {
47486
+ currAjaxArray = ajaxArray.slice(i * n, (i + 1) * n);
47487
+ }
47488
+
47489
+ let currPromise = Promise.allSettled(currAjaxArray);
47490
+ let currDataArray = await currPromise;
47491
+
47492
+ dataArray3 = dataArray3.concat(currDataArray);
47493
+ }
47494
+
47495
+ return dataArray3;
47496
+ }
47308
47497
  }
47309
47498
 
47310
47499
  /**
@@ -48613,7 +48802,7 @@ class ViewInterPairs {
48613
48802
 
48614
48803
  if(ic.bD3 === undefined) {
48615
48804
  //let url = "https://d3js.org/d3.v4.min.js";
48616
- let url = "https://www.ncbi.nlm.nih.gov/Structure/icn3d/script/d3v4-force-all.min.js";
48805
+ let url = "./script/d3v4-force-all.min.js";
48617
48806
  await me.getAjaxPromise(url, 'script');
48618
48807
 
48619
48808
  ic.bD3 = true;
@@ -49888,7 +50077,7 @@ class AlignParser {
49888
50077
  for(let j = 0, jl = mmdbTmp.molecules.length; j < jl; ++j) {
49889
50078
  let molecule = mmdbTmp.molecules[j];
49890
50079
  let molid = molecule.moleculeId;
49891
- let chainName = molecule.chain.trim();
50080
+ let chainName = molecule.chain.trim().replace(/_/g, ''); // change "A_1" to "A1"
49892
50081
  if(chainNameHash[chainName] === undefined) {
49893
50082
  chainNameHash[chainName] = 1;
49894
50083
  }
@@ -50299,6 +50488,8 @@ class ChainalignParser {
50299
50488
 
50300
50489
  let queryData = {}; // check whether undefined
50301
50490
 
50491
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
50492
+
50302
50493
  this.processAlign(align, index, queryData, bEqualMmdbid, bEqualChain);
50303
50494
  }
50304
50495
 
@@ -50396,6 +50587,8 @@ class ChainalignParser {
50396
50587
  continue;
50397
50588
  }
50398
50589
 
50590
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid1 + " with " + mmdbid2, false);
50591
+
50399
50592
  let bNoAlert = true;
50400
50593
  let bAligned = this.processAlign(align, i, queryData, bEqualMmdbid, bEqualChain, bNoAlert);
50401
50594
 
@@ -50846,6 +51039,8 @@ class ChainalignParser {
50846
51039
  let bEqualMmdbid = (mmdbid_q == mmdbid_t);
50847
51040
  let bEqualChain = (chain_q == chain_t);
50848
51041
 
51042
+ me.htmlCls.clickMenuCls.setLogCmd("Align " + mmdbid_t + " with " + mmdbid_q, false);
51043
+
50849
51044
  this.processAlign(align, index-1, queryData, bEqualMmdbid, bEqualChain);
50850
51045
  }
50851
51046
  }
@@ -50906,6 +51101,7 @@ class ChainalignParser {
50906
51101
  ic.qt_start_end[index] = align[0].segs;
50907
51102
 
50908
51103
  let rmsd = align[0].super_rmsd;
51104
+ console.log();
50909
51105
 
50910
51106
  let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
50911
51107
  if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
@@ -51175,10 +51371,10 @@ class Dsn6Parser {
51175
51371
  // https://edmaps.rcsb.org/maps/1kq2_fofc.dsn6
51176
51372
 
51177
51373
  let url = "https://edmaps.rcsb.org/maps/" + pdbid.toLowerCase() + "_" + type + ".dsn6";
51178
- await this.dsn6ParserBase(url, type, sigma);
51374
+ await this.dsn6ParserBase(url, type, sigma, 'url', true);
51179
51375
  }
51180
51376
 
51181
- async dsn6ParserBase(url, type, sigma) { let ic = this.icn3d, me = ic.icn3dui;
51377
+ async dsn6ParserBase(url, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
51182
51378
  let thisClass = this;
51183
51379
 
51184
51380
  //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
@@ -51192,7 +51388,7 @@ class Dsn6Parser {
51192
51388
  }
51193
51389
  else {
51194
51390
  let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', 'rcsbEdmaps');
51195
- thisClass.loadDsn6Data(arrayBuffer, type, sigma);
51391
+ sigma = thisClass.loadDsn6Data(arrayBuffer, type, sigma, location, bInputSigma);
51196
51392
 
51197
51393
  if(type == '2fofc') {
51198
51394
  ic.bAjax2fofc = true;
@@ -51203,9 +51399,11 @@ class Dsn6Parser {
51203
51399
 
51204
51400
  ic.setOptionCls.setOption('map', type);
51205
51401
  }
51402
+
51403
+ return sigma;
51206
51404
  }
51207
51405
 
51208
- loadDsn6Data(dsn6data, type, sigma) { let ic = this.icn3d; ic.icn3dui;
51406
+ loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51209
51407
  // DSN6 http://www.uoxray.uoregon.edu/tnt/manual/node104.html
51210
51408
  // BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
51211
51409
 
@@ -51254,9 +51452,9 @@ class Dsn6Parser {
51254
51452
  }
51255
51453
  }
51256
51454
 
51257
- header.zStart = intView[ 2 ];
51258
51455
  header.xStart = intView[ 0 ]; // NXSTART
51259
51456
  header.yStart = intView[ 1 ];
51457
+ header.zStart = intView[ 2 ];
51260
51458
 
51261
51459
  header.xExtent = intView[ 3 ]; // NX
51262
51460
  header.yExtent = intView[ 4 ];
@@ -51292,6 +51490,7 @@ class Dsn6Parser {
51292
51490
  let zBlocks = Math.ceil(header.zExtent / 8);
51293
51491
 
51294
51492
  // loop over blocks
51493
+ let maxValue = -999;
51295
51494
  for(let zz = 0; zz < zBlocks; ++zz) {
51296
51495
  for(let yy = 0; yy < yBlocks; ++yy) {
51297
51496
  for(let xx = 0; xx < xBlocks; ++xx) {
@@ -51307,6 +51506,7 @@ class Dsn6Parser {
51307
51506
  if(x < header.xExtent && y < header.yExtent && z < header.zExtent) {
51308
51507
  let idx =((((x * header.yExtent) + y) * header.zExtent) + z);
51309
51508
  data[ idx ] =(byteView[ offset ] - summand) / divisor;
51509
+ if(data[ idx ] > maxValue) maxValue = data[ idx ];
51310
51510
  ++offset;
51311
51511
  } else {
51312
51512
  offset += 8 - i;
@@ -51319,6 +51519,10 @@ class Dsn6Parser {
51319
51519
  }
51320
51520
  }
51321
51521
 
51522
+ if(!bInputSigma) {
51523
+ sigma = this.setSigma(maxValue, location, type, sigma);
51524
+ }
51525
+
51322
51526
  if(type == '2fofc') {
51323
51527
  ic.mapData.header2 = header;
51324
51528
  ic.mapData.data2 = data;
@@ -51333,6 +51537,32 @@ class Dsn6Parser {
51333
51537
  ic.mapData.type = type;
51334
51538
  ic.mapData.sigma = sigma;
51335
51539
  }
51540
+
51541
+ return sigma;
51542
+ }
51543
+
51544
+ setSigma(maxValue, location, type, sigma) { let ic = this.icn3d, me = ic.icn3dui;
51545
+ let inputId;
51546
+ if(location == 'file') {
51547
+ inputId = 'dsn6sigma' + type;
51548
+ }
51549
+ else if(location == 'url') {
51550
+ inputId = 'dsn6sigmaurl' + type;
51551
+ }
51552
+
51553
+ let factor = (type == '2fofc') ? 0.5 : 0.3;
51554
+
51555
+ if(inputId) {
51556
+ if(!($("#" + me.pre + inputId).val())) {
51557
+ sigma = (factor * maxValue).toFixed(2);
51558
+ $("#" + me.pre + inputId).val(sigma);
51559
+ }
51560
+ else {
51561
+ sigma = $("#" + me.pre + inputId).val();
51562
+ }
51563
+ }
51564
+
51565
+ return sigma;
51336
51566
  }
51337
51567
 
51338
51568
  getMatrix(header) { let ic = this.icn3d; ic.icn3dui;
@@ -51406,7 +51636,9 @@ class Dsn6Parser {
51406
51636
  let reader = new FileReader();
51407
51637
  reader.onload = function(e) { let ic = thisClass.icn3d;
51408
51638
  let arrayBuffer = e.target.result; // or = reader.result;
51409
- thisClass.loadDsn6Data(arrayBuffer, type, sigma);
51639
+
51640
+ sigma = thisClass.loadDsn6Data(arrayBuffer, type, sigma, 'file');
51641
+
51410
51642
  if(type == '2fofc') {
51411
51643
  ic.bAjax2fofc = true;
51412
51644
  }
@@ -51414,21 +51646,1006 @@ class Dsn6Parser {
51414
51646
  ic.bAjaxfofc = true;
51415
51647
  }
51416
51648
  ic.setOptionCls.setOption('map', type);
51417
- me.htmlCls.clickMenuCls.setLogCmd('load dsn6 file ' + $("#" + ic.pre + "dsn6file" + type).val(), false);
51649
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
51418
51650
  };
51419
51651
  reader.readAsArrayBuffer(file);
51420
51652
  }
51421
51653
  }
51422
51654
 
51423
51655
  loadDsn6FileUrl(type) {var ic = this.icn3d, me = ic.icn3dui;
51656
+ let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
51657
+ let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
51658
+ if(!url) {
51659
+ alert("Please input the file URL before clicking 'Load'");
51660
+ }
51661
+ else {
51662
+ sigma = this.dsn6ParserBase(url, type, sigma, 'url');
51663
+ me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file dsn6 | ' + encodeURIComponent(url), true);
51664
+ }
51665
+ }
51666
+
51667
+ }
51668
+
51669
+ /**
51670
+ * @file Ccp4 Parser
51671
+ * @author Marcin Wojdyr <wojdyr@gmail.com>
51672
+ * @private
51673
+ * Modified by Jiyao Wang / https://github.com/ncbi/icn3d
51674
+ */
51675
+
51676
+ class Ccp4Parser {
51677
+ constructor(icn3d) {
51678
+ this.icn3d = icn3d;
51679
+ }
51680
+
51681
+ async ccp4ParserBase(url, type, sigma, location) { let ic = this.icn3d, me = ic.icn3dui;
51682
+ let thisClass = this;
51683
+
51684
+ //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
51685
+ // if(type == '2fofc' && ic.bAjax2fofcccp4) {
51686
+ // ic.mapData.sigma2 = sigma;
51687
+ // ic.setOptionCls.setOption('map', type);
51688
+ // }
51689
+ // else if(type == 'fofc' && ic.bAjaxfofcccp4) {
51690
+ // ic.mapData.sigma = sigma;
51691
+ // ic.setOptionCls.setOption('map', type);
51692
+ // }
51693
+ // else {
51694
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', '');
51695
+ let bInputSigma = true;
51696
+ sigma = thisClass.load_map_from_buffer(arrayBuffer, type, sigma, location, bInputSigma);
51697
+
51698
+ // if(type == '2fofc') {
51699
+ // ic.bAjax2fofcccp4 = true;
51700
+ // }
51701
+ // else if(type == 'fofc') {
51702
+ // ic.bAjaxfofcccp4 = true;
51703
+ // }
51704
+
51705
+ ic.setOptionCls.setOption('map', type);
51706
+
51707
+ return sigma;
51708
+ // }
51709
+ }
51710
+
51711
+ // modified from_ccp4() at https://github.com/uglymol/uglymol.github.io/blob/master/src/elmap.js
51712
+ load_map_from_buffer(buf, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51713
+ if (buf.byteLength < 1024) throw Error('File shorter than 1024 bytes.');
51714
+
51715
+ //console.log('buf type: ' + Object.prototype.toString.call(buf));
51716
+ // for now we assume both file and host are little endian
51717
+ const iview = new Int32Array(buf, 0, 256);
51718
+ // word 53 - character string 'MAP ' to identify file type
51719
+ if (iview[52] !== 0x2050414d) throw Error('not a CCP4 map');
51720
+
51721
+ // map has 3 dimensions referred to as columns (fastest changing), rows
51722
+ // and sections (c-r-s)
51723
+ const n_crs = [iview[0], iview[1], iview[2]]; // 108, 108, 108
51724
+ const mode = iview[3]; //2
51725
+ let nb;
51726
+ if (mode === 2) nb = 4;
51727
+ else if (mode === 0) nb = 1;
51728
+ else throw Error('Only Mode 2 and Mode 0 of CCP4 map is supported.');
51729
+
51730
+ const start = [iview[4], iview[5], iview[6]]; // 0,0,0
51731
+ const n_grid = [iview[7], iview[8], iview[9]]; // 108,108,108
51732
+ const nsymbt = iview[23]; // size of extended header in bytes
51733
+ // nsymbt = 1920
51734
+
51735
+ if (1024 + nsymbt + nb*n_crs[0]*n_crs[1]*n_crs[2] !== buf.byteLength) {
51736
+ throw Error('ccp4 file too short or too long');
51737
+ }
51738
+
51739
+ const fview = new Float32Array(buf, 0, buf.byteLength / 4);
51740
+ const grid = new GridArray(n_grid);
51741
+ 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
51742
+
51743
+ // MAPC, MAPR, MAPS - axis corresp to cols, rows, sections (1,2,3 for X,Y,Z)
51744
+ const map_crs = [iview[16], iview[17], iview[18]]; // 2,1,3
51745
+ const ax = map_crs.indexOf(1);
51746
+ const ay = map_crs.indexOf(2);
51747
+ const az = map_crs.indexOf(3);
51748
+
51749
+ const min = fview[19]; // -0.49
51750
+ const max = fview[20]; // 0.94
51751
+ //const sg_number = iview[22];
51752
+ //const lskflg = iview[24];
51753
+
51754
+ if (nsymbt % 4 !== 0) {
51755
+ throw Error('CCP4 map with NSYMBT not divisible by 4 is not supported.');
51756
+ }
51757
+ let data_view;
51758
+ if (mode === 2) data_view = fview;
51759
+ else /* mode === 0 */ data_view = new Int8Array(buf);
51760
+ let idx = (1024 + nsymbt) / nb | 0; //736
51761
+
51762
+ // We assume that if DMEAN and RMS from the header are not clearly wrong
51763
+ // they are what the user wants. Because the map can cover a small part
51764
+ // of the asu and its rmsd may be different than the total rmsd.
51765
+ // let stats = { mean: 0.0, rms: 1.0 };
51766
+ // stats.mean = fview[21]; //0
51767
+ // stats.rms = fview[54]; //0.15
51768
+ // if (stats.mean < min || stats.mean > max || stats.rms <= 0) {
51769
+ // stats = this.calculate_stddev(data_view, idx);
51770
+ // }
51771
+
51772
+ let b1 = 1;
51773
+ let b0 = 0;
51774
+ // if the file was converted by mapmode2to0 - scale the data
51775
+ if (mode === 0 && iview[39] === -128 && iview[40] === 127) { //39:0, 40:0
51776
+ // scaling f(x)=b1*x+b0 such that f(-128)=min and f(127)=max
51777
+ b1 = (max - min) / 255.0;
51778
+ b0 = 0.5 * (min + max + b1);
51779
+ }
51780
+
51781
+ const end = [start[0] + n_crs[0], start[1] + n_crs[1], start[2] + n_crs[2]];
51782
+ let it = [0, 0, 0];
51783
+ let maxValue = -999;
51784
+ for (it[2] = start[2]; it[2] < end[2]; it[2]++) { // sections
51785
+ for (it[1] = start[1]; it[1] < end[1]; it[1]++) { // rows
51786
+ for (it[0] = start[0]; it[0] < end[0]; it[0]++) { // cols
51787
+ let value = b1 * data_view[idx] + b0;
51788
+ grid.set_grid_value(it[ax], it[ay], it[az], value);
51789
+
51790
+ if(value > maxValue) maxValue = value;
51791
+ idx++;
51792
+ }
51793
+ }
51794
+ }
51795
+
51796
+ /*
51797
+ if (expand_symmetry && nsymbt > 0) {
51798
+ const u8view = new Uint8Array(buf);
51799
+ for (let i = 0; i+80 <= nsymbt; i += 80) {
51800
+ let j;
51801
+ let symop = '';
51802
+ for (j = 0; j < 80; ++j) {
51803
+ symop += String.fromCharCode(u8view[1024 + i + j]);
51804
+ }
51805
+ if (/^\s*x\s*,\s*y\s*,\s*z\s*$/i.test(symop)) continue; // skip x,y,z
51806
+ //console.log('sym ops', symop.trim());
51807
+ let mat = this.parse_symop(symop);
51808
+ // Note: we apply here symops to grid points instead of coordinates.
51809
+ // In the cases we came across it is equivalent, but in general not.
51810
+ for (j = 0; j < 3; ++j) {
51811
+ mat[j][3] = Math.round(mat[j][3] * n_grid[j]) | 0;
51812
+ }
51813
+ idx = (1024 + nsymbt) / nb | 0;
51814
+ let xyz = [0, 0, 0];
51815
+ for (it[2] = start[2]; it[2] < end[2]; it[2]++) { // sections
51816
+ for (it[1] = start[1]; it[1] < end[1]; it[1]++) { // rows
51817
+ for (it[0] = start[0]; it[0] < end[0]; it[0]++) { // cols
51818
+ for (j = 0; j < 3; ++j) {
51819
+ xyz[j] = it[ax] * mat[j][0] + it[ay] * mat[j][1] +
51820
+ it[az] * mat[j][2] + mat[j][3];
51821
+ }
51822
+ let value = b1 * data_view[idx] + b0;
51823
+ grid.set_grid_value(xyz[0], xyz[1], xyz[2], value);
51824
+
51825
+ if(value > maxValue) maxValue = value;
51826
+ idx++;
51827
+ }
51828
+ }
51829
+ }
51830
+ }
51831
+ }
51832
+ */
51833
+
51834
+ if(!bInputSigma) {
51835
+ sigma = ic.dsn6ParserCls.setSigma(maxValue, location, type, sigma);
51836
+ }
51837
+
51838
+ if(type == '2fofc') {
51839
+ ic.mapData.ccp4 = 1;
51840
+ ic.mapData.grid2 = grid;
51841
+ ic.mapData.unit_cell2 = unit_cell;
51842
+ ic.mapData.type2 = type;
51843
+ ic.mapData.sigma2 = sigma;
51844
+ }
51845
+ else {
51846
+ ic.mapData.ccp4 = 1;
51847
+ ic.mapData.grid = grid;
51848
+ ic.mapData.unit_cell = unit_cell;
51849
+ ic.mapData.type = type;
51850
+ ic.mapData.sigma = sigma;
51851
+ }
51852
+
51853
+ return sigma;
51854
+ }
51855
+
51856
+ load_maps_from_mtz_buffer(mtz, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51857
+ let is_diff = (type == 'fofc'); // diff: fofc, non-diff: 2fofc
51858
+ let dataArray = mtz.calculate_map(is_diff);
51859
+
51860
+ let mc = mtz.cell;
51861
+ const unit_cell = new UnitCell(mc.a, mc.b, mc.c, mc.alpha, mc.beta, mc.gamma);
51862
+
51863
+ let maxValue = -999;
51864
+ for(let i = 0, il = dataArray.length; i < il; ++i) {
51865
+ if(dataArray[i] > maxValue) maxValue = dataArray[i];
51866
+ }
51867
+
51868
+ if(!bInputSigma) {
51869
+ sigma = ic.dsn6ParserCls.setSigma(maxValue, location, type, sigma);
51870
+ }
51871
+
51872
+ const grid = new GridArray([mtz.nx, mtz.ny, mtz.nz]);
51873
+ grid.values.set(dataArray);
51874
+
51875
+ if(type == '2fofc') {
51876
+ ic.mapData.ccp4 = 1;
51877
+ ic.mapData.grid2 = grid;
51878
+ ic.mapData.unit_cell2 = unit_cell;
51879
+ ic.mapData.type2 = type;
51880
+ ic.mapData.sigma2 = sigma;
51881
+ }
51882
+ else {
51883
+ ic.mapData.ccp4 = 1;
51884
+ ic.mapData.grid = grid;
51885
+ ic.mapData.unit_cell = unit_cell;
51886
+ ic.mapData.type = type;
51887
+ ic.mapData.sigma = sigma;
51888
+ }
51889
+
51890
+ mtz.delete();
51891
+
51892
+ return sigma;
51893
+ }
51894
+
51895
+ // calculate_stddev(a, offset) {
51896
+ // let sum = 0;
51897
+ // let sq_sum = 0;
51898
+ // const alen = a.length;
51899
+ // for (let i = offset; i < alen; i++) {
51900
+ // sum += a[i];
51901
+ // sq_sum += a[i] * a[i];
51902
+ // }
51903
+ // const mean = sum / (alen - offset);
51904
+ // const variance = sq_sum / (alen - offset) - mean * mean;
51905
+ // return {mean: mean, rms: Math.sqrt(variance)};
51906
+ // }
51907
+
51908
+ parse_symop(symop) {
51909
+ const ops = symop.toLowerCase().replace(/\s+/g, '').split(',');
51910
+ if (ops.length !== 3) throw Error('Unexpected symop: ' + symop);
51911
+ let mat = [];
51912
+ for (let i = 0; i < 3; i++) {
51913
+ const terms = ops[i].split(/(?=[+-])/);
51914
+ let row = [0, 0, 0, 0];
51915
+ for (let j = 0; j < terms.length; j++) {
51916
+ const term = terms[j];
51917
+ const sign = (term[0] === '-' ? -1 : 1);
51918
+ let m = terms[j].match(/^[+-]?([xyz])$/);
51919
+ if (m) {
51920
+ const pos = {x: 0, y: 1, z: 2}[m[1]];
51921
+ row[pos] = sign;
51922
+ } else {
51923
+ m = terms[j].match(/^[+-]?(\d)\/(\d)$/);
51924
+ if (!m) throw Error('What is ' + terms[j] + ' in ' + symop);
51925
+ row[3] = sign * Number(m[1]) / Number(m[2]);
51926
+ }
51927
+ }
51928
+ mat.push(row);
51929
+ }
51930
+ return mat;
51931
+ }
51932
+
51933
+ loadCcp4File(type) {let ic = this.icn3d, me = ic.icn3dui;
51934
+ let thisClass = this;
51935
+
51936
+ let file = $("#" + ic.pre + "dsn6file" + type)[0].files[0];
51937
+ let sigma = $("#" + ic.pre + "dsn6sigma" + type).val();
51938
+ if(!file) {
51939
+ alert("Please select a file before clicking 'Load'");
51940
+ }
51941
+ else {
51942
+ me.utilsCls.checkFileAPI();
51943
+ let reader = new FileReader();
51944
+ reader.onload = function(e) { let ic = thisClass.icn3d;
51945
+ let arrayBuffer = e.target.result; // or = reader.result;
51946
+ sigma = thisClass.load_map_from_buffer(arrayBuffer, type, sigma, 'file');
51947
+
51948
+ // if(type == '2fofc') {
51949
+ // ic.bAjax2fofcCcp4 = true;
51950
+ // }
51951
+ // else if(type == 'fofc') {
51952
+ // ic.bAjaxfofcCcp4 = true;
51953
+ // }
51954
+ ic.setOptionCls.setOption('map', type);
51955
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
51956
+ };
51957
+ reader.readAsArrayBuffer(file);
51958
+ }
51959
+ }
51960
+
51961
+ async loadCcp4FileUrl(type) { let ic = this.icn3d, me = ic.icn3dui;
51962
+ let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
51963
+ let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
51964
+ if(!url) {
51965
+ alert("Please input the file URL before clicking 'Load'");
51966
+ }
51967
+ else {
51968
+ sigma = await this.ccp4ParserBase(url, type, sigma, 'file');
51969
+
51970
+ me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file ccp4 | ' + encodeURIComponent(url), true);
51971
+ }
51972
+ }
51973
+
51974
+ // Extract a block of density for calculating an isosurface using the
51975
+ // separate marching cubes implementation.
51976
+ extract_block(grid, unit_cell, radius, center, typeDetail) { let ic = this.icn3d; ic.icn3dui;
51977
+ // let grid = this.grid;
51978
+ // let unit_cell = this.unit_cell;
51979
+ if (grid == null || unit_cell == null) { return; }
51980
+ let fc = unit_cell.fractionalize(center);
51981
+
51982
+ let r = [radius / unit_cell.parameters[0],
51983
+ radius / unit_cell.parameters[1],
51984
+ radius / unit_cell.parameters[2]];
51985
+ let grid_min = grid.frac2grid([fc[0] - r[0], fc[1] - r[1], fc[2] - r[2]]);
51986
+ let grid_max = grid.frac2grid([fc[0] + r[0], fc[1] + r[1], fc[2] + r[2]]);
51987
+
51988
+ let size = [grid_max[0] - grid_min[0] + 1,
51989
+ grid_max[1] - grid_min[1] + 1,
51990
+ grid_max[2] - grid_min[2] + 1];
51991
+ let points = [];
51992
+ let values = [];
51993
+ let threshold = 1;
51994
+ let bAtoms = ic.hAtoms && Object.keys(ic.hAtoms).length > 0;
51995
+ for (let i = grid_min[0]; i <= grid_max[0]; i++) {
51996
+ for (let j = grid_min[1]; j <= grid_max[1]; j++) {
51997
+ for (let k = grid_min[2]; k <= grid_max[2]; k++) {
51998
+ let frac = grid.grid2frac(i, j, k);
51999
+ let orth = unit_cell.orthogonalize(frac);
52000
+ points.push(orth);
52001
+
52002
+ // get overlap between map and atoms
52003
+ let positoin = new THREE.Vector3(orth[0], orth[1], orth[2]);
52004
+ let atomsNear = ic.rayCls.getAtomsFromPosition(positoin, threshold, ic.hAtoms);
52005
+
52006
+ let map_value = (atomsNear || !bAtoms) ? grid.get_grid_value(i, j, k) : 0;
52007
+
52008
+ if(typeDetail == 'fofc_pos' && map_value < 0) map_value = 0;
52009
+ if(typeDetail == 'fofc_neg') map_value = (map_value > 0) ? 0 : -map_value;
52010
+
52011
+ values.push(map_value);
52012
+ }
52013
+ }
52014
+ }
52015
+
52016
+ return {size: size, values: values, points: points};
52017
+ // this.block.set(points, values, size);
52018
+ };
52019
+
52020
+ marchingCubes(dims, values, points, isolevel, method) { let ic = this.icn3d; ic.icn3dui;
52021
+ const edgeTable = new Int32Array([
52022
+ 0x0 , 0x0 , 0x202, 0x302, 0x406, 0x406, 0x604, 0x704,
52023
+ 0x804, 0x805, 0xa06, 0xa06, 0xc0a, 0xd03, 0xe08, 0xf00,
52024
+ 0x90 , 0x98 , 0x292, 0x292, 0x496, 0x49e, 0x694, 0x694,
52025
+ 0x894, 0x894, 0xa96, 0xa96, 0xc9a, 0xc92, 0xe91, 0xe90,
52026
+ 0x230, 0x230, 0x33 , 0x13a, 0x636, 0x636, 0x434, 0x43c,
52027
+ 0xa34, 0xa35, 0x837, 0x936, 0xe3a, 0xf32, 0xc31, 0xd30,
52028
+ 0x2a0, 0x2a8, 0xa3 , 0xaa , 0x6a6, 0x6af, 0x5a4, 0x4ac,
52029
+ 0xaa4, 0xaa4, 0x9a6, 0x8a6, 0xfaa, 0xea3, 0xca1, 0xca0,
52030
+ 0x460, 0x460, 0x662, 0x762, 0x66 , 0x66 , 0x265, 0x364,
52031
+ 0xc64, 0xc65, 0xe66, 0xe66, 0x86a, 0x863, 0xa69, 0xa60,
52032
+ 0x4f0, 0x4f8, 0x6f2, 0x6f2, 0xf6 , 0xfe , 0x2f5, 0x2fc,
52033
+ 0xcf4, 0xcf4, 0xef6, 0xef6, 0x8fa, 0x8f3, 0xaf9, 0xaf0,
52034
+ 0x650, 0x650, 0x453, 0x552, 0x256, 0x256, 0x54 , 0x154,
52035
+ 0xe54, 0xf54, 0xc57, 0xd56, 0xa5a, 0xb52, 0x859, 0x950,
52036
+ 0x7c0, 0x6c1, 0x5c2, 0x4c2, 0x3c6, 0x2ce, 0xc5 , 0xc4 ,
52037
+ 0xfc4, 0xec5, 0xdc6, 0xcc6, 0xbca, 0xac2, 0x8c1, 0x8c0,
52038
+ 0x8c0, 0x8c0, 0xac2, 0xbc2, 0xcc6, 0xcc6, 0xec4, 0xfcc,
52039
+ 0xc4 , 0xc5 , 0x2c6, 0x3c6, 0x4c2, 0x5c2, 0x6c1, 0x7c0,
52040
+ 0x950, 0x859, 0xb52, 0xa5a, 0xd56, 0xc57, 0xe54, 0xe5c,
52041
+ 0x154, 0x54 , 0x25e, 0x256, 0x552, 0x453, 0x658, 0x650,
52042
+ 0xaf0, 0xaf0, 0x8f3, 0x8fa, 0xef6, 0xef6, 0xcf4, 0xcfc,
52043
+ 0x2f4, 0x3f5, 0xff , 0x1f6, 0x6f2, 0x6f3, 0x4f9, 0x5f0,
52044
+ 0xa60, 0xa69, 0x863, 0x86a, 0xe66, 0xe67, 0xd65, 0xc6c,
52045
+ 0x364, 0x265, 0x166, 0x66 , 0x76a, 0x663, 0x460, 0x460,
52046
+ 0xca0, 0xca0, 0xea2, 0xfa2, 0x8a6, 0x8a6, 0xaa4, 0xba4,
52047
+ 0x4ac, 0x5a4, 0x6ae, 0x7a6, 0xaa , 0xa3 , 0x2a8, 0x2a0,
52048
+ 0xd30, 0xc31, 0xf32, 0xe3a, 0x936, 0x837, 0xb35, 0xa34,
52049
+ 0x43c, 0x434, 0x73e, 0x636, 0x13a, 0x33 , 0x339, 0x230,
52050
+ 0xe90, 0xe90, 0xc92, 0xc9a, 0xa96, 0xa96, 0x894, 0x89c,
52051
+ 0x694, 0x695, 0x49f, 0x496, 0x292, 0x392, 0x98 , 0x90 ,
52052
+ 0xf00, 0xe08, 0xd03, 0xc0a, 0xa06, 0xa0e, 0x805, 0x804,
52053
+ 0x704, 0x604, 0x506, 0x406, 0x302, 0x202, 0x0 , 0x0]);
52054
+
52055
+ const segTable = [
52056
+ [],
52057
+ [],
52058
+ [1, 9],
52059
+ [1, 8, 1, 9],
52060
+ [2, 10, 10, 1],
52061
+ [2, 10, 10, 1],
52062
+ [9, 2, 2, 10, 10, 9],
52063
+ [2, 8, 2, 10, 10, 8, 10, 9],
52064
+ [11, 2],
52065
+ [0, 11, 11, 2],
52066
+ [1, 9, 11, 2],
52067
+ [1, 11, 11, 2, 1, 9, 9, 11],
52068
+ [3, 10, 10, 1, 11, 10],
52069
+ [0, 10, 10, 1, 8, 10, 11, 10],
52070
+ [3, 9, 11, 9, 11, 10, 10, 9],
52071
+ [8, 10, 10, 9, 11, 10],
52072
+ [4, 7],
52073
+ [4, 3, 4, 7],
52074
+ [1, 9, 4, 7],
52075
+ [4, 1, 1, 9, 4, 7, 7, 1],
52076
+ [2, 10, 10, 1, 4, 7],
52077
+ [3, 4, 4, 7, 2, 10, 10, 1],
52078
+ [9, 2, 2, 10, 10, 9, 4, 7],
52079
+ [2, 10, 10, 9, 9, 2, 9, 7, 7, 2, 4, 7],
52080
+ [4, 7, 11, 2],
52081
+ [11, 4, 4, 7, 11, 2, 2, 4],
52082
+ [1, 9, 4, 7, 11, 2],
52083
+ [4, 7, 11, 4, 11, 9, 11, 2, 2, 9, 1, 9],
52084
+ [3, 10, 10, 1, 11, 10, 4, 7],
52085
+ [1, 11, 11, 10, 10, 1, 1, 4, 4, 11, 4, 7],
52086
+ [4, 7, 0, 11, 11, 9, 11, 10, 10, 9],
52087
+ [4, 7, 11, 4, 11, 9, 11, 10, 10, 9],
52088
+ [9, 5, 5, 4],
52089
+ [9, 5, 5, 4],
52090
+ [0, 5, 5, 4, 1, 5],
52091
+ [8, 5, 5, 4, 3, 5, 1, 5],
52092
+ [2, 10, 10, 1, 9, 5, 5, 4],
52093
+ [2, 10, 10, 1, 9, 5, 5, 4],
52094
+ [5, 2, 2, 10, 10, 5, 5, 4, 4, 2],
52095
+ [2, 10, 10, 5, 5, 2, 5, 3, 5, 4, 4, 3],
52096
+ [9, 5, 5, 4, 11, 2],
52097
+ [0, 11, 11, 2, 9, 5, 5, 4],
52098
+ [0, 5, 5, 4, 1, 5, 11, 2],
52099
+ [1, 5, 5, 2, 5, 8, 8, 2, 11, 2, 5, 4],
52100
+ [10, 3, 11, 10, 10, 1, 9, 5, 5, 4],
52101
+ [9, 5, 5, 4, 8, 1, 8, 10, 10, 1, 11, 10],
52102
+ [5, 4, 0, 5, 0, 11, 11, 5, 11, 10, 10, 5],
52103
+ [5, 4, 8, 5, 8, 10, 10, 5, 11, 10],
52104
+ [9, 7, 5, 7, 9, 5],
52105
+ [9, 3, 9, 5, 5, 3, 5, 7],
52106
+ [0, 7, 1, 7, 1, 5, 5, 7],
52107
+ [1, 5, 5, 3, 5, 7],
52108
+ [9, 7, 9, 5, 5, 7, 10, 1, 2, 10],
52109
+ [10, 1, 2, 10, 9, 5, 5, 0, 5, 3, 5, 7],
52110
+ [2, 8, 2, 5, 5, 8, 5, 7, 10, 5, 2, 10],
52111
+ [2, 10, 10, 5, 5, 2, 5, 3, 5, 7],
52112
+ [7, 9, 9, 5, 5, 7, 11, 2],
52113
+ [9, 5, 5, 7, 7, 9, 7, 2, 2, 9, 11, 2],
52114
+ [11, 2, 1, 8, 1, 7, 1, 5, 5, 7],
52115
+ [11, 2, 1, 11, 1, 7, 1, 5, 5, 7],
52116
+ [9, 5, 5, 8, 5, 7, 10, 1, 3, 10, 11, 10],
52117
+ [5, 7, 7, 0, 0, 5, 9, 5, 11, 0, 0, 10, 10, 1, 11, 10],
52118
+ [11, 10, 10, 0, 0, 11, 10, 5, 5, 0, 0, 7, 5, 7],
52119
+ [11, 10, 10, 5, 5, 11, 5, 7],
52120
+ [10, 6, 6, 5, 5, 10],
52121
+ [5, 10, 10, 6, 6, 5],
52122
+ [1, 9, 5, 10, 10, 6, 6, 5],
52123
+ [1, 8, 1, 9, 5, 10, 10, 6, 6, 5],
52124
+ [1, 6, 6, 5, 5, 1, 2, 6],
52125
+ [1, 6, 6, 5, 5, 1, 2, 6],
52126
+ [9, 6, 6, 5, 5, 9, 0, 6, 2, 6],
52127
+ [5, 9, 8, 5, 8, 2, 2, 5, 2, 6, 6, 5],
52128
+ [11, 2, 10, 6, 6, 5, 5, 10],
52129
+ [11, 0, 11, 2, 10, 6, 6, 5, 5, 10],
52130
+ [1, 9, 11, 2, 5, 10, 10, 6, 6, 5],
52131
+ [5, 10, 10, 6, 6, 5, 1, 9, 9, 2, 9, 11, 11, 2],
52132
+ [6, 3, 11, 6, 6, 5, 5, 3, 5, 1],
52133
+ [11, 0, 11, 5, 5, 0, 5, 1, 11, 6, 6, 5],
52134
+ [11, 6, 6, 3, 6, 0, 6, 5, 5, 0, 5, 9],
52135
+ [6, 5, 5, 9, 9, 6, 9, 11, 11, 6],
52136
+ [5, 10, 10, 6, 6, 5, 4, 7],
52137
+ [4, 3, 4, 7, 6, 5, 5, 10, 10, 6],
52138
+ [1, 9, 5, 10, 10, 6, 6, 5, 4, 7],
52139
+ [10, 6, 6, 5, 5, 10, 1, 9, 9, 7, 7, 1, 4, 7],
52140
+ [6, 1, 2, 6, 6, 5, 5, 1, 4, 7],
52141
+ [2, 5, 5, 1, 2, 6, 6, 5, 4, 3, 4, 7],
52142
+ [4, 7, 0, 5, 5, 9, 0, 6, 6, 5, 2, 6],
52143
+ [3, 9, 9, 7, 4, 7, 2, 9, 5, 9, 9, 6, 6, 5, 2, 6],
52144
+ [11, 2, 4, 7, 10, 6, 6, 5, 5, 10],
52145
+ [5, 10, 10, 6, 6, 5, 4, 7, 7, 2, 2, 4, 11, 2],
52146
+ [1, 9, 4, 7, 11, 2, 5, 10, 10, 6, 6, 5],
52147
+ [9, 2, 1, 9, 9, 11, 11, 2, 4, 11, 4, 7, 5, 10, 10, 6, 6, 5],
52148
+ [4, 7, 11, 5, 5, 3, 5, 1, 11, 6, 6, 5],
52149
+ [5, 1, 1, 11, 11, 5, 11, 6, 6, 5, 0, 11, 11, 4, 4, 7],
52150
+ [0, 5, 5, 9, 0, 6, 6, 5, 3, 6, 11, 6, 4, 7],
52151
+ [6, 5, 5, 9, 9, 6, 9, 11, 11, 6, 4, 7, 7, 9],
52152
+ [10, 4, 9, 10, 6, 4, 10, 6],
52153
+ [4, 10, 10, 6, 6, 4, 9, 10],
52154
+ [10, 0, 1, 10, 10, 6, 6, 0, 6, 4],
52155
+ [1, 8, 1, 6, 6, 8, 6, 4, 1, 10, 10, 6],
52156
+ [1, 4, 9, 1, 2, 4, 2, 6, 6, 4],
52157
+ [2, 9, 9, 1, 2, 4, 2, 6, 6, 4],
52158
+ [2, 4, 2, 6, 6, 4],
52159
+ [2, 8, 2, 4, 2, 6, 6, 4],
52160
+ [10, 4, 9, 10, 10, 6, 6, 4, 11, 2],
52161
+ [8, 2, 11, 2, 9, 10, 10, 4, 10, 6, 6, 4],
52162
+ [11, 2, 1, 6, 6, 0, 6, 4, 1, 10, 10, 6],
52163
+ [6, 4, 4, 1, 1, 6, 1, 10, 10, 6, 8, 1, 1, 11, 11, 2],
52164
+ [9, 6, 6, 4, 9, 3, 3, 6, 9, 1, 11, 6],
52165
+ [11, 1, 1, 8, 11, 6, 6, 1, 9, 1, 1, 4, 6, 4],
52166
+ [11, 6, 6, 3, 6, 0, 6, 4],
52167
+ [6, 4, 8, 6, 11, 6],
52168
+ [7, 10, 10, 6, 6, 7, 8, 10, 9, 10],
52169
+ [0, 7, 0, 10, 10, 7, 9, 10, 6, 7, 10, 6],
52170
+ [10, 6, 6, 7, 7, 10, 1, 10, 7, 1, 8, 1],
52171
+ [10, 6, 6, 7, 7, 10, 7, 1, 1, 10],
52172
+ [2, 6, 6, 1, 6, 8, 8, 1, 9, 1, 6, 7],
52173
+ [2, 6, 6, 9, 9, 2, 9, 1, 6, 7, 7, 9, 9, 3],
52174
+ [0, 7, 0, 6, 6, 7, 2, 6],
52175
+ [2, 7, 6, 7, 2, 6],
52176
+ [11, 2, 10, 6, 6, 8, 8, 10, 9, 10, 6, 7],
52177
+ [0, 7, 7, 2, 11, 2, 9, 7, 6, 7, 7, 10, 10, 6, 9, 10],
52178
+ [1, 8, 1, 7, 1, 10, 10, 7, 6, 7, 10, 6, 11, 2],
52179
+ [11, 2, 1, 11, 1, 7, 10, 6, 6, 1, 1, 10, 6, 7],
52180
+ [9, 6, 6, 8, 6, 7, 9, 1, 1, 6, 11, 6, 6, 3],
52181
+ [9, 1, 11, 6, 6, 7],
52182
+ [0, 7, 0, 6, 6, 7, 11, 0, 11, 6],
52183
+ [11, 6, 6, 7],
52184
+ [7, 6, 6, 11],
52185
+ [7, 6, 6, 11],
52186
+ [1, 9, 7, 6, 6, 11],
52187
+ [8, 1, 1, 9, 7, 6, 6, 11],
52188
+ [10, 1, 2, 10, 6, 11, 7, 6],
52189
+ [2, 10, 10, 1, 6, 11, 7, 6],
52190
+ [2, 9, 2, 10, 10, 9, 6, 11, 7, 6],
52191
+ [6, 11, 7, 6, 2, 10, 10, 3, 10, 8, 10, 9],
52192
+ [7, 2, 6, 2, 7, 6],
52193
+ [7, 0, 7, 6, 6, 0, 6, 2],
52194
+ [2, 7, 7, 6, 6, 2, 1, 9],
52195
+ [1, 6, 6, 2, 1, 8, 8, 6, 1, 9, 7, 6],
52196
+ [10, 7, 7, 6, 6, 10, 10, 1, 1, 7],
52197
+ [10, 7, 7, 6, 6, 10, 1, 7, 10, 1, 1, 8],
52198
+ [7, 0, 7, 10, 10, 0, 10, 9, 6, 10, 7, 6],
52199
+ [7, 6, 6, 10, 10, 7, 10, 8, 10, 9],
52200
+ [6, 8, 4, 6, 6, 11],
52201
+ [3, 6, 6, 11, 0, 6, 4, 6],
52202
+ [8, 6, 6, 11, 4, 6, 1, 9],
52203
+ [4, 6, 6, 9, 6, 3, 3, 9, 1, 9, 6, 11],
52204
+ [6, 8, 4, 6, 6, 11, 2, 10, 10, 1],
52205
+ [2, 10, 10, 1, 0, 11, 0, 6, 6, 11, 4, 6],
52206
+ [4, 11, 4, 6, 6, 11, 2, 9, 2, 10, 10, 9],
52207
+ [10, 9, 9, 3, 3, 10, 2, 10, 4, 3, 3, 6, 6, 11, 4, 6],
52208
+ [8, 2, 4, 2, 4, 6, 6, 2],
52209
+ [4, 2, 4, 6, 6, 2],
52210
+ [1, 9, 3, 4, 4, 2, 4, 6, 6, 2],
52211
+ [1, 9, 4, 1, 4, 2, 4, 6, 6, 2],
52212
+ [8, 1, 8, 6, 6, 1, 4, 6, 6, 10, 10, 1],
52213
+ [10, 1, 0, 10, 0, 6, 6, 10, 4, 6],
52214
+ [4, 6, 6, 3, 3, 4, 6, 10, 10, 3, 3, 9, 10, 9],
52215
+ [10, 9, 4, 10, 6, 10, 4, 6],
52216
+ [9, 5, 5, 4, 7, 6, 6, 11],
52217
+ [9, 5, 5, 4, 7, 6, 6, 11],
52218
+ [5, 0, 1, 5, 5, 4, 7, 6, 6, 11],
52219
+ [7, 6, 6, 11, 3, 4, 3, 5, 5, 4, 1, 5],
52220
+ [9, 5, 5, 4, 10, 1, 2, 10, 7, 6, 6, 11],
52221
+ [6, 11, 7, 6, 2, 10, 10, 1, 9, 5, 5, 4],
52222
+ [7, 6, 6, 11, 5, 4, 4, 10, 10, 5, 4, 2, 2, 10],
52223
+ [3, 4, 3, 5, 5, 4, 2, 5, 10, 5, 2, 10, 7, 6, 6, 11],
52224
+ [7, 2, 7, 6, 6, 2, 5, 4, 9, 5],
52225
+ [9, 5, 5, 4, 8, 6, 6, 0, 6, 2, 7, 6],
52226
+ [3, 6, 6, 2, 7, 6, 1, 5, 5, 0, 5, 4],
52227
+ [6, 2, 2, 8, 8, 6, 7, 6, 1, 8, 8, 5, 5, 4, 1, 5],
52228
+ [9, 5, 5, 4, 10, 1, 1, 6, 6, 10, 1, 7, 7, 6],
52229
+ [1, 6, 6, 10, 10, 1, 1, 7, 7, 6, 0, 7, 9, 5, 5, 4],
52230
+ [0, 10, 10, 4, 10, 5, 5, 4, 3, 10, 6, 10, 10, 7, 7, 6],
52231
+ [7, 6, 6, 10, 10, 7, 10, 8, 5, 4, 4, 10, 10, 5],
52232
+ [6, 9, 9, 5, 5, 6, 6, 11, 11, 9],
52233
+ [3, 6, 6, 11, 0, 6, 0, 5, 5, 6, 9, 5],
52234
+ [0, 11, 0, 5, 5, 11, 1, 5, 5, 6, 6, 11],
52235
+ [6, 11, 3, 6, 3, 5, 5, 6, 1, 5],
52236
+ [2, 10, 10, 1, 9, 5, 5, 11, 11, 9, 5, 6, 6, 11],
52237
+ [0, 11, 0, 6, 6, 11, 9, 6, 5, 6, 9, 5, 2, 10, 10, 1],
52238
+ [8, 5, 5, 11, 5, 6, 6, 11, 0, 5, 10, 5, 5, 2, 2, 10],
52239
+ [6, 11, 3, 6, 3, 5, 5, 6, 2, 10, 10, 3, 10, 5],
52240
+ [5, 8, 9, 5, 5, 2, 2, 8, 5, 6, 6, 2],
52241
+ [9, 5, 5, 6, 6, 9, 6, 0, 6, 2],
52242
+ [1, 5, 5, 8, 8, 1, 5, 6, 6, 8, 8, 2, 6, 2],
52243
+ [1, 5, 5, 6, 6, 1, 6, 2],
52244
+ [3, 6, 6, 1, 6, 10, 10, 1, 8, 6, 5, 6, 6, 9, 9, 5],
52245
+ [10, 1, 0, 10, 0, 6, 6, 10, 9, 5, 5, 0, 5, 6],
52246
+ [5, 6, 6, 10, 10, 5],
52247
+ [10, 5, 5, 6, 6, 10],
52248
+ [11, 5, 5, 10, 10, 11, 7, 5],
52249
+ [11, 5, 5, 10, 10, 11, 7, 5],
52250
+ [5, 11, 7, 5, 5, 10, 10, 11, 1, 9],
52251
+ [10, 7, 7, 5, 5, 10, 10, 11, 8, 1, 1, 9],
52252
+ [11, 1, 2, 11, 7, 1, 7, 5, 5, 1],
52253
+ [2, 7, 7, 1, 7, 5, 5, 1, 2, 11],
52254
+ [9, 7, 7, 5, 5, 9, 9, 2, 2, 7, 2, 11],
52255
+ [7, 5, 5, 2, 2, 7, 2, 11, 5, 9, 9, 2, 2, 8],
52256
+ [2, 5, 5, 10, 10, 2, 3, 5, 7, 5],
52257
+ [8, 2, 8, 5, 5, 2, 7, 5, 10, 2, 5, 10],
52258
+ [1, 9, 5, 10, 10, 3, 3, 5, 7, 5, 10, 2],
52259
+ [8, 2, 2, 9, 1, 9, 7, 2, 10, 2, 2, 5, 5, 10, 7, 5],
52260
+ [3, 5, 5, 1, 7, 5],
52261
+ [7, 0, 7, 1, 7, 5, 5, 1],
52262
+ [3, 9, 3, 5, 5, 9, 7, 5],
52263
+ [7, 9, 5, 9, 7, 5],
52264
+ [5, 8, 4, 5, 5, 10, 10, 8, 10, 11],
52265
+ [5, 0, 4, 5, 5, 11, 11, 0, 5, 10, 10, 11],
52266
+ [1, 9, 4, 10, 10, 8, 10, 11, 4, 5, 5, 10],
52267
+ [10, 11, 11, 4, 4, 10, 4, 5, 5, 10, 3, 4, 4, 1, 1, 9],
52268
+ [2, 5, 5, 1, 2, 8, 8, 5, 2, 11, 4, 5],
52269
+ [4, 11, 11, 0, 4, 5, 5, 11, 2, 11, 11, 1, 5, 1],
52270
+ [2, 5, 5, 0, 5, 9, 2, 11, 11, 5, 4, 5, 5, 8],
52271
+ [4, 5, 5, 9, 2, 11],
52272
+ [2, 5, 5, 10, 10, 2, 3, 5, 3, 4, 4, 5],
52273
+ [5, 10, 10, 2, 2, 5, 2, 4, 4, 5],
52274
+ [3, 10, 10, 2, 3, 5, 5, 10, 8, 5, 4, 5, 1, 9],
52275
+ [5, 10, 10, 2, 2, 5, 2, 4, 4, 5, 1, 9, 9, 2],
52276
+ [4, 5, 5, 8, 5, 3, 5, 1],
52277
+ [4, 5, 5, 0, 5, 1],
52278
+ [4, 5, 5, 8, 5, 3, 0, 5, 5, 9],
52279
+ [4, 5, 5, 9],
52280
+ [4, 11, 7, 4, 9, 11, 9, 10, 10, 11],
52281
+ [9, 7, 7, 4, 9, 11, 9, 10, 10, 11],
52282
+ [1, 10, 10, 11, 11, 1, 11, 4, 4, 1, 7, 4],
52283
+ [1, 4, 4, 3, 1, 10, 10, 4, 7, 4, 4, 11, 10, 11],
52284
+ [4, 11, 7, 4, 9, 11, 9, 2, 2, 11, 9, 1],
52285
+ [9, 7, 7, 4, 9, 11, 9, 1, 1, 11, 2, 11],
52286
+ [7, 4, 4, 11, 4, 2, 2, 11],
52287
+ [7, 4, 4, 11, 4, 2, 2, 11, 3, 4],
52288
+ [2, 9, 9, 10, 10, 2, 2, 7, 7, 9, 7, 4],
52289
+ [9, 10, 10, 7, 7, 9, 7, 4, 10, 2, 2, 7, 7, 0],
52290
+ [7, 10, 10, 3, 10, 2, 7, 4, 4, 10, 1, 10, 10, 0],
52291
+ [1, 10, 10, 2, 7, 4],
52292
+ [9, 1, 1, 4, 1, 7, 7, 4],
52293
+ [9, 1, 1, 4, 1, 7, 7, 4, 8, 1],
52294
+ [3, 4, 7, 4],
52295
+ [7, 4],
52296
+ [9, 10, 10, 8, 10, 11],
52297
+ [9, 3, 9, 11, 9, 10, 10, 11],
52298
+ [1, 10, 10, 0, 10, 8, 10, 11],
52299
+ [1, 10, 10, 3, 10, 11],
52300
+ [2, 11, 11, 1, 11, 9, 9, 1],
52301
+ [9, 3, 9, 11, 2, 9, 9, 1, 2, 11],
52302
+ [2, 11, 11, 0],
52303
+ [2, 11],
52304
+ [8, 2, 8, 10, 10, 2, 9, 10],
52305
+ [9, 10, 10, 2, 2, 9],
52306
+ [8, 2, 8, 10, 10, 2, 1, 8, 1, 10],
52307
+ [1, 10, 10, 2],
52308
+ [8, 1, 9, 1],
52309
+ [9, 1],
52310
+ [],
52311
+ []];
52312
+
52313
+ const snap = (method === 'snapped MC');
52314
+ // const seg_table = (method === 'squarish' ? segTable2 : segTable);
52315
+ const seg_table = segTable;
52316
+
52317
+ let vlist = new Array(12);
52318
+ const vert_offsets = this.calculateVertOffsets(dims);
52319
+
52320
+ const edgeIndex = [[0,1], [1,2], [2,3], [3,0], [4,5], [5,6],
52321
+ [6,7], [7,4], [0,4], [1,5], [2,6], [3,7]];
52322
+
52323
+ let vertex_values = new Float32Array(8);
52324
+ let p0 = [0, 0, 0]; // unused initial value - to make Flow happy
52325
+ let vertex_points = [p0, p0, p0, p0, p0, p0, p0, p0];
52326
+ const size_x = dims[0];
52327
+ const size_y = dims[1];
52328
+ const size_z = dims[2];
52329
+ if (values == null || points == null) return;
52330
+ let vertices = [];
52331
+ let segments = [];
52332
+ let vertex_count = 0;
52333
+ for (let x = 0; x < size_x - 1; x++) {
52334
+ for (let y = 0; y < size_y - 1; y++) {
52335
+ for (let z = 0; z < size_z - 1; z++) {
52336
+ const offset0 = z + size_z * (y + size_y * x);
52337
+ let cubeindex = 0;
52338
+ let i;
52339
+ let j;
52340
+ for (i = 0; i < 8; ++i) {
52341
+ j = offset0 + vert_offsets[i];
52342
+ cubeindex |= (values[j] < isolevel) ? 1 << i : 0;
52343
+ }
52344
+ if (cubeindex === 0 || cubeindex === 255) continue;
52345
+ for (i = 0; i < 8; ++i) {
52346
+ j = offset0 + vert_offsets[i];
52347
+ vertex_values[i] = values[j];
52348
+ vertex_points[i] = points[j];
52349
+ }
52350
+
52351
+ // 12 bit number, indicates which edges are crossed by the isosurface
52352
+ const edge_mask = edgeTable[cubeindex];
52353
+
52354
+ // check which edges are crossed, and estimate the point location
52355
+ // using a weighted average of scalar values at edge endpoints.
52356
+ for (i = 0; i < 12; ++i) {
52357
+ if ((edge_mask & (1 << i)) !== 0) {
52358
+ const e = edgeIndex[i];
52359
+ let mu = (isolevel - vertex_values[e[0]]) /
52360
+ (vertex_values[e[1]] - vertex_values[e[0]]);
52361
+ if (snap === true) {
52362
+ if (mu > 0.85) mu = 1;
52363
+ else if (mu < 0.15) mu = 0;
52364
+ }
52365
+ const p1 = vertex_points[e[0]];
52366
+ const p2 = vertex_points[e[1]];
52367
+ // The number of added vertices could be roughly halved
52368
+ // if we avoided duplicates between neighbouring cells.
52369
+ // Using a map for lookups is too slow, perhaps a big
52370
+ // array would do?
52371
+ vertices.push(p1[0] + (p2[0] - p1[0]) * mu,
52372
+ p1[1] + (p2[1] - p1[1]) * mu,
52373
+ p1[2] + (p2[2] - p1[2]) * mu);
52374
+ vlist[i] = vertex_count++;
52375
+ }
52376
+ }
52377
+ const t = seg_table[cubeindex];
52378
+ for (i = 0; i < t.length; i++) {
52379
+ segments.push(vlist[t[i]]);
52380
+ }
52381
+ }
52382
+ }
52383
+ }
52384
+
52385
+ return { vertices: vertices, segments: segments };
52386
+ }
52387
+
52388
+ // return offsets relative to vertex [0,0,0]
52389
+ calculateVertOffsets(dims) { let ic = this.icn3d; ic.icn3dui;
52390
+ let vert_offsets = [];
52391
+ const cubeVerts = [[0,0,0], [1,0,0], [1,1,0], [0,1,0],
52392
+ [0,0,1], [1,0,1], [1,1,1], [0,1,1]];
52393
+
52394
+ for (let i = 0; i < 8; ++i) {
52395
+ const v = cubeVerts[i];
52396
+ vert_offsets.push(v[0] + dims[2] * (v[1] + dims[1] * v[2]));
52397
+ }
52398
+ return vert_offsets;
52399
+ }
52400
+
52401
+ makeChickenWire(data, typeDetail) { let ic = this.icn3d, me = ic.icn3dui;
52402
+ let geom = new THREE.BufferGeometry();
52403
+ let position = new Float32Array(data.vertices);
52404
+ geom.setAttribute('position', new THREE.BufferAttribute(position, 3));
52405
+
52406
+ // Although almost all browsers support OES_element_index_uint nowadays,
52407
+ // use Uint32 indexes only when needed.
52408
+ let arr = (data.vertices.length < 3*65536 ? new Uint16Array(data.segments) : new Uint32Array(data.segments));
52409
+
52410
+ geom.setIndex(new THREE.BufferAttribute(arr, 1));
52411
+
52412
+ let colorFor2fofc = me.parasCls.thr('#00FFFF');
52413
+ let colorForfofcPos = me.parasCls.thr('#00FF00');
52414
+ let colorForfofcNeg = me.parasCls.thr('#ff0000');
52415
+
52416
+ let color = (typeDetail == '2fofc') ? colorFor2fofc : ((typeDetail == 'fofc_pos') ? colorForfofcPos : colorForfofcNeg);
52417
+ let material = new THREE.LineBasicMaterial({ linewidth: 1, color: color });
52418
+ //return new THREE.LineSegments(geom, material);
52419
+
52420
+ let mesh = new THREE.LineSegments(geom, material);
52421
+ ic.mdl.add(mesh);
52422
+
52423
+ ic.prevMaps.push(mesh);
52424
+ }
52425
+ }
52426
+
52427
+
52428
+ class UnitCell {
52429
+ /*::
52430
+ parameters: number[]
52431
+ orth: number[]
52432
+ frac: number[]
52433
+ */
52434
+ // eslint-disable-next-line max-params
52435
+ constructor(a /*:number*/, b /*:number*/, c /*:number*/,
52436
+ alpha /*:number*/, beta /*:number*/, gamma /*:number*/) {
52437
+ if (a <= 0 || b <= 0 || c <= 0 || alpha <= 0 || beta <= 0 || gamma <= 0) {
52438
+ throw Error('Zero or negative unit cell parameter(s).');
52439
+ }
52440
+ this.parameters = [a, b, c, alpha, beta, gamma];
52441
+ const deg2rad = Math.PI / 180.0;
52442
+ const cos_alpha = Math.cos(deg2rad * alpha);
52443
+ const cos_beta = Math.cos(deg2rad * beta);
52444
+ const cos_gamma = Math.cos(deg2rad * gamma);
52445
+ const sin_alpha = Math.sin(deg2rad * alpha);
52446
+ const sin_beta = Math.sin(deg2rad * beta);
52447
+ const sin_gamma = Math.sin(deg2rad * gamma);
52448
+ if (sin_alpha === 0 || sin_beta === 0 || sin_gamma === 0) {
52449
+ throw Error('Impossible angle - N*180deg.');
52450
+ }
52451
+ const cos_alpha_star_sin_beta = (cos_beta * cos_gamma - cos_alpha) /
52452
+ sin_gamma;
52453
+ const cos_alpha_star = cos_alpha_star_sin_beta / sin_beta;
52454
+ const s1rca2 = Math.sqrt(1.0 - cos_alpha_star * cos_alpha_star);
52455
+ // The orthogonalization matrix we use is described in ITfC B p.262:
52456
+ // "An alternative mode of orthogonalization, used by the Protein
52457
+ // Data Bank and most programs, is to align the a1 axis of the unit
52458
+ // cell with the Cartesian X_1 axis, and to align the a*_3 axis with the
52459
+ // Cartesian X_3 axis."
52460
+ //
52461
+ // Zeros in the matrices below are kept to make matrix multiplication
52462
+ // faster: they make extract_block() 2x (!) faster on V8 4.5.103,
52463
+ // no difference on FF 50.
52464
+ /* eslint-disable no-multi-spaces, comma-spacing */
52465
+ this.orth = [a, b * cos_gamma, c * cos_beta,
52466
+ 0.0, b * sin_gamma, -c * cos_alpha_star_sin_beta,
52467
+ 0.0, 0.0 , c * sin_beta * s1rca2];
52468
+ // based on xtal.js which is based on cctbx.uctbx
52469
+ this.frac = [
52470
+ 1.0 / a,
52471
+ -cos_gamma / (sin_gamma * a),
52472
+ -(cos_gamma * cos_alpha_star_sin_beta + cos_beta * sin_gamma) /
52473
+ (sin_beta * s1rca2 * sin_gamma * a),
52474
+ 0.0,
52475
+ 1.0 / (sin_gamma * b),
52476
+ cos_alpha_star / (s1rca2 * sin_gamma * b),
52477
+ 0.0,
52478
+ 0.0,
52479
+ 1.0 / (sin_beta * s1rca2 * c),
52480
+ ];
52481
+ }
52482
+
52483
+ // This function is only used with matrices frac and orth, which have 3 zeros.
52484
+ // We skip these elements, but it doesn't affect performance (on FF50 and V8).
52485
+ multiply(xyz, mat) {
52486
+ /* eslint-disable indent */
52487
+ return [mat[0] * xyz[0] + mat[1] * xyz[1] + mat[2] * xyz[2],
52488
+ /*mat[3] * xyz[0]*/+ mat[4] * xyz[1] + mat[5] * xyz[2],
52489
+ /*mat[6] * xyz[0] + mat[7] * xyz[1]*/+ mat[8] * xyz[2]];
52490
+ }
52491
+
52492
+ fractionalize(xyz /*:[number,number,number]*/) {
52493
+ return this.multiply(xyz, this.frac);
52494
+ }
52495
+
52496
+ orthogonalize(xyz /*:[number,number,number]*/) {
52497
+ return this.multiply(xyz, this.orth);
52498
+ }
52499
+ }
52500
+
52501
+
52502
+ class GridArray {
52503
+ /*::
52504
+ dim: number[]
52505
+ values: Float32Array
52506
+ */
52507
+ constructor(dim /*:number[]*/) {
52508
+ this.dim = dim; // dimensions of the grid for the entire unit cell
52509
+ this.values = new Float32Array(dim[0] * dim[1] * dim[2]);
52510
+ }
52511
+
52512
+ modulo(a, b) {
52513
+ const reminder = a % b;
52514
+ return reminder >= 0 ? reminder : reminder + b;
52515
+ }
52516
+
52517
+ grid2index(i/*:number*/, j/*:number*/, k/*:number*/) {
52518
+ i = this.modulo(i, this.dim[0]);
52519
+ j = this.modulo(j, this.dim[1]);
52520
+ k = this.modulo(k, this.dim[2]);
52521
+ return this.dim[2] * (this.dim[1] * i + j) + k;
52522
+ }
52523
+
52524
+ grid2index_unchecked(i/*:number*/, j/*:number*/, k/*:number*/) {
52525
+ return this.dim[2] * (this.dim[1] * i + j) + k;
52526
+ }
52527
+
52528
+ grid2frac(i/*:number*/, j/*:number*/, k/*:number*/) {
52529
+ return [i / this.dim[0], j / this.dim[1], k / this.dim[2]];
52530
+ }
52531
+
52532
+ // return grid coordinates (rounded down) for the given fractional coordinates
52533
+ frac2grid(xyz/*:number[]*/) {
52534
+ // at one point "| 0" here made extract_block() 40% faster on V8 3.14,
52535
+ // but I don't see any effect now
52536
+ return [Math.floor(xyz[0] * this.dim[0]) | 0,
52537
+ Math.floor(xyz[1] * this.dim[1]) | 0,
52538
+ Math.floor(xyz[2] * this.dim[2]) | 0];
52539
+ }
52540
+
52541
+ set_grid_value(i/*:number*/, j/*:number*/, k/*:number*/, value/*:number*/) {
52542
+ const idx = this.grid2index(i, j, k);
52543
+ this.values[idx] = value;
52544
+ }
52545
+
52546
+ get_grid_value(i/*:number*/, j/*:number*/, k/*:number*/) {
52547
+ const idx = this.grid2index(i, j, k);
52548
+ return this.values[idx];
52549
+ }
52550
+ }
52551
+
52552
+ /**
52553
+ * @file Mtz Parser
52554
+ * @author Marcin Wojdyr <wojdyr@gmail.com>
52555
+ * @private
52556
+ * Modified by Jiyao Wang / https://github.com/ncbi/icn3d
52557
+ */
52558
+
52559
+ class MtzParser {
52560
+ constructor(icn3d) {
52561
+ this.icn3d = icn3d;
52562
+ }
52563
+
52564
+ async mtzParserBase(url, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
52565
+ let thisClass = this;
52566
+
52567
+ //https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file
52568
+ // if(type == '2fofc' && ic.bAjax2fofcccp4) {
52569
+ // ic.mapData.sigma2 = sigma;
52570
+ // ic.setOptionCls.setOption('map', type);
52571
+ // }
52572
+ // else if(type == 'fofc' && ic.bAjaxfofcccp4) {
52573
+ // ic.mapData.sigma = sigma;
52574
+ // ic.setOptionCls.setOption('map', type);
52575
+ // }
52576
+ // else {
52577
+ let arrayBuffer = await me.getXMLHttpRqstPromise(url, 'GET', 'arraybuffer', '');
52578
+ sigma = await thisClass.loadMtzFileBase(arrayBuffer, type, sigma, location, bInputSigma, url);
52579
+
52580
+ // if(type == '2fofc') {
52581
+ // ic.bAjax2fofcccp4 = true;
52582
+ // }
52583
+ // else if(type == 'fofc') {
52584
+ // ic.bAjaxfofcccp4 = true;
52585
+ // }
52586
+
52587
+ ic.setOptionCls.setOption('map', type);
52588
+
52589
+ return sigma;
52590
+ // }
52591
+ }
52592
+
52593
+ loadMtzFile(type) {var ic = this.icn3d, me = ic.icn3dui;
52594
+ let thisClass = this;
52595
+
52596
+ let file = $("#" + ic.pre + "dsn6file" + type)[0].files[0];
52597
+ let sigma = $("#" + ic.pre + "dsn6sigma" + type).val();
52598
+ if(!file) {
52599
+ alert("Please select a file before clicking 'Load'");
52600
+ }
52601
+ else {
52602
+ me.utilsCls.checkFileAPI();
52603
+ let reader = new FileReader();
52604
+ reader.onload = async function(e) { let ic = thisClass.icn3d;
52605
+ sigma = await thisClass.loadMtzFileBase(e.target.result, type, sigma, 'file');
52606
+ me.htmlCls.clickMenuCls.setLogCmd('load map file ' + $("#" + ic.pre + "dsn6file" + type).val() + ' with sigma ' + sigma, false);
52607
+ };
52608
+ reader.readAsArrayBuffer(file);
52609
+ }
52610
+ }
52611
+
52612
+ async loadMtzFileBase(data, type, sigma, location, bInputSigma, url) {var ic = this.icn3d, me = ic.icn3dui;
52613
+ if(ic.bMtz === undefined) {
52614
+ let url = "./script/mtz.js";
52615
+ await me.getAjaxPromise(url, 'script');
52616
+
52617
+ ic.bMtz = true;
52618
+ }
52619
+
52620
+ GemmiMtz().then(function(Gemmi) {
52621
+ let mtz = Gemmi.readMtz(data);
52622
+
52623
+ sigma = ic.ccp4ParserCls.load_maps_from_mtz_buffer(mtz, type, sigma, location, bInputSigma);
52624
+
52625
+ // if(type == '2fofc') {
52626
+ // ic.bAjax2fofcCcp4 = true;
52627
+ // }
52628
+ // else if(type == 'fofc') {
52629
+ // ic.bAjaxfofcCcp4 = true;
52630
+ // }
52631
+ ic.setOptionCls.setOption('map', type);
52632
+ if(url) me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file mtz | ' + encodeURIComponent(url), true);
52633
+
52634
+ return sigma;
52635
+ });
52636
+ }
52637
+
52638
+ async loadMtzFileUrl(type) {var ic = this.icn3d; ic.icn3dui;
51424
52639
  let url = $("#" + ic.pre + "dsn6fileurl" + type).val();
51425
52640
  let sigma = $("#" + ic.pre + "dsn6sigmaurl" + type).val();
51426
52641
  if(!url) {
51427
52642
  alert("Please input the file URL before clicking 'Load'");
51428
52643
  }
51429
52644
  else {
51430
- this.dsn6ParserBase(url, type, sigma);
51431
- me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' | ' + encodeURIComponent(url), true);
52645
+ sigma = await this.mtzParserBase(url, type, sigma, 'url');
52646
+
52647
+ console.log("### sigma " + sigma);
52648
+ //me.htmlCls.clickMenuCls.setLogCmd('set map ' + type + ' sigma ' + sigma + ' file mtz | ' + encodeURIComponent(url), true);
51432
52649
  }
51433
52650
  }
51434
52651
 
@@ -54200,7 +55417,7 @@ class DensityCifParser {
54200
55417
  this.icn3d = icn3d;
54201
55418
  }
54202
55419
 
54203
- async densityCifParser(pdbid, type, sigma, emd) { let ic = this.icn3d, me = ic.icn3dui;
55420
+ async densityCifParser(pdbid, type, sigma, emd, bOutput) { let ic = this.icn3d, me = ic.icn3dui;
54204
55421
  let thisClass = this;
54205
55422
 
54206
55423
  let url;
@@ -54262,6 +55479,9 @@ class DensityCifParser {
54262
55479
  ic.mapData.header2 = header;
54263
55480
 
54264
55481
  ic.mapData.data2 = density.data;
55482
+ for(let i = 0; i < density.data.length; ++i) {
55483
+ density.data[i];
55484
+ }
54265
55485
 
54266
55486
  let origin = density.box.origin;
54267
55487
  let dimensions = density.box.dimensions;
@@ -54296,6 +55516,7 @@ class DensityCifParser {
54296
55516
  origin = density.box.origin;
54297
55517
  dimensions = density.box.dimensions;
54298
55518
  basis = density.spacegroup.basis;
55519
+
54299
55520
  scale = new THREE.Matrix4().makeScale(
54300
55521
  dimensions[0] / (sampleCount[0] ),
54301
55522
  dimensions[1] / (sampleCount[1] ),
@@ -55924,7 +57145,10 @@ class ParserUtils {
55924
57145
 
55925
57146
  if(bAppend) {
55926
57147
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
55927
- if(ic.bAnnoShown) await ic.showAnnoCls.showAnnotations();
57148
+ if(ic.bAnnoShown) {
57149
+ await ic.showAnnoCls.showAnnotations();
57150
+ ic.annotationCls.resetAnnoTabAll();
57151
+ }
55928
57152
  }
55929
57153
 
55930
57154
  // Realign by sequence alignment with the residues in "segment", i.e., transmembrane helix
@@ -57254,14 +58478,15 @@ class SetSeqAlign {
57254
58478
 
57255
58479
  if(i > 0) {
57256
58480
  let index1 = alignIndex;
57257
-
58481
+
57258
58482
  for(let j = prevIndex1 + 1, jl = start1; j < jl; ++j) {
57259
- if(posChain1[j]) continue;
58483
+ //if(posChain1[j]) continue;
57260
58484
  posChain1[j] = 1;
57261
58485
 
57262
- if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
58486
+ //if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
57263
58487
 
57264
- let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
58488
+ //let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
58489
+ let resi = this.getResiAferAlign(chainid1, bRealign, j);
57265
58490
  // let resn = (bRealign && me.cfg.aligntool == 'tmalign') ? this.getResnFromResi(chainid1, j).toLowerCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
57266
58491
  let resn = this.getResnFromResi(chainid1, resi).toLowerCase();
57267
58492
 
@@ -57269,24 +58494,25 @@ class SetSeqAlign {
57269
58494
 
57270
58495
  color = me.htmlCls.GREY8;
57271
58496
  classname = 'icn3d-nalign';
57272
-
58497
+
57273
58498
  ic.nalignHash1[chainid1 + '_' + resi] = 1;
57274
58499
  this.setSeqPerResi(chainid1, chainid1, chainid2, resi, resn, false, color, undefined, classname, true, false, index1);
57275
58500
  ++index1;
57276
58501
  }
57277
58502
 
57278
58503
  let index2 = alignIndex;
58504
+
57279
58505
  for(let j = prevIndex2 + 1, jl = start2; j < jl; ++j) {
57280
- if(posChain2[j]) continue;
58506
+ //if(posChain2[j]) continue;
57281
58507
  posChain2[j] = 1;
57282
58508
 
57283
- if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
58509
+ //if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57284
58510
 
57285
- let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
58511
+ //let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
58512
+ let resi = this.getResiAferAlign(chainid2, bRealign, j);
57286
58513
  // let resn = (bRealign && me.cfg.aligntool == 'tmalign') ? this.getResnFromResi(chainid2, j).toLowerCase() : ic.chainsSeq[chainid2][j].name.toLowerCase();
57287
58514
  let resn = this.getResnFromResi(chainid2, resi).toLowerCase();
57288
58515
 
57289
-
57290
58516
  if(resn == '?') continue;
57291
58517
 
57292
58518
  color = me.htmlCls.GREY8;
@@ -57326,7 +58552,7 @@ class SetSeqAlign {
57326
58552
  }
57327
58553
 
57328
58554
  for(let j = 0; j <= end1 - start1; ++j) {
57329
- if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
58555
+ ///if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57330
58556
 
57331
58557
  let resi1, resi2, resn1, resn2;
57332
58558
  /*
@@ -57356,15 +58582,17 @@ class SetSeqAlign {
57356
58582
  if(resn1 == '?' || resn2 == '?') continue;
57357
58583
  }
57358
58584
  else {
57359
- if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
58585
+ ///if(ic.chainsSeq[chainid1][j + start1] === undefined || ic.chainsSeq[chainid2][j + start2] === undefined) continue;
57360
58586
 
57361
58587
  // resi1 = ic.chainsSeq[chainid1][j + start1].resi;
57362
58588
  // resi2 = ic.chainsSeq[chainid2][j + start2].resi;
57363
58589
  // resn1 = ic.chainsSeq[chainid1][j + start1].name.toUpperCase();
57364
58590
  // resn2 = ic.chainsSeq[chainid2][j + start2].name.toUpperCase();
57365
58591
 
57366
- resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
57367
- resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
58592
+ // resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1 + 1);
58593
+ // resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2 + 1);
58594
+ resi1 = this.getResiAferAlign(chainid1, bRealign, j + start1);
58595
+ resi2 = this.getResiAferAlign(chainid2, bRealign, j + start2);
57368
58596
  resn1 = this.getResnFromResi(chainid1, resi1).toUpperCase();
57369
58597
  resn2 = this.getResnFromResi(chainid2, resi2).toUpperCase();
57370
58598
  }
@@ -57827,7 +59055,6 @@ class SetSeqAlign {
57827
59055
  start1Pos = start1;
57828
59056
  end1Pos = end1;
57829
59057
  }
57830
-
57831
59058
  //let range = resi2range_t[resiStart1];
57832
59059
 
57833
59060
  // if the mapping does not start from start_t, add gaps to the query seq
@@ -57851,7 +59078,7 @@ class SetSeqAlign {
57851
59078
  pos2 = result.pos2;
57852
59079
  let notAlnLen1 = pos2 - (pos1 + 1);
57853
59080
  let notAlnLen2 = start2 - (prevIndex2 + 1);
57854
-
59081
+
57855
59082
  // insert non-aligned residues in query seq
57856
59083
  this.insertNotAlignRes(chainid2, prevIndex2+1, notAlnLen2, bRealign);
57857
59084
 
@@ -62414,14 +63641,15 @@ class LoadScript {
62414
63641
  let bFinalStep =(i === steps - 1) ? true : false;
62415
63642
 
62416
63643
  if(!ic.commands[i].trim()) continue;
62417
- let nAtoms = Object.keys(ic.atoms).length;
63644
+ let nAtoms = (ic.atoms) ? Object.keys(ic.atoms).length : 0;
62418
63645
 
62419
63646
  if(nAtoms == 0 && ic.commands[i].indexOf('load') == -1) continue;
62420
63647
 
62421
63648
  let strArray = ic.commands[i].split("|||");
62422
63649
  let command = strArray[0].trim();
62423
63650
 
62424
- if(ic.inputid) ic.bNotLoadStructure = true;
63651
+ // sometimes URL has an ID input, then load a structure in commands
63652
+ //if(ic.inputid) ic.bNotLoadStructure = true;
62425
63653
 
62426
63654
  if(command.indexOf('load') !== -1) {
62427
63655
  if(end === 0 && start === end) {
@@ -62457,18 +63685,7 @@ class LoadScript {
62457
63685
  }
62458
63686
  }
62459
63687
  else if(command.indexOf('set map') == 0 && command.indexOf('set map wireframe') == -1) {
62460
- //set map 2fofc sigma 1.5
62461
- let urlArray = strArray[0].trim().split(' | ');
62462
-
62463
- let str = urlArray[0].substr(8);
62464
- let paraArray = str.split(" ");
62465
-
62466
- if(paraArray.length == 3 && paraArray[1] == 'sigma') {
62467
- paraArray[2];
62468
- paraArray[0];
62469
-
62470
- await thisClass.applyCommandMap(strArray[0].trim());
62471
- }
63688
+ await thisClass.applyCommandMap(strArray[0].trim());
62472
63689
  }
62473
63690
  else if(command.indexOf('set emmap') == 0 && command.indexOf('set emmap wireframe') == -1) {
62474
63691
  //set emmap percentage 70
@@ -62833,8 +64050,10 @@ class LoadScript {
62833
64050
  let id = loadStr.substr(loadStr.lastIndexOf(' ') + 1);
62834
64051
  if(id.length == 4) id = id.toUpperCase();
62835
64052
 
62836
- // skip loading the structure if it was loaded before
62837
- if(ic.structures && ic.structures.hasOwnProperty(id)) return;
64053
+ // skip loading the structure if
64054
+ // 1. PDB was in the iCn3D PNG Image file
64055
+ // 2. it was loaded before
64056
+ if(ic.bInputPNGWithData || (ic.structures && ic.structures.hasOwnProperty(id))) return;
62838
64057
 
62839
64058
  ic.inputid = id;
62840
64059
  if(command.indexOf('load mmtf') !== -1) {
@@ -62966,17 +64185,34 @@ class LoadScript {
62966
64185
  // ic.deferredMap = $.Deferred(function() { let ic = thisClass.icn3d;
62967
64186
  //"set map 2fofc sigma 1.5"
62968
64187
  // or "set map 2fofc sigma 1.5 | [url]"
64188
+
64189
+ // added more para later
64190
+ //"set map 2fofc sigma 1.5 file dsn6"
64191
+ // or "set map 2fofc sigma 1.5 file dsn6 | [url]"
62969
64192
  let urlArray = command.split(" | ");
62970
64193
 
62971
64194
  let str = urlArray[0].substr(8);
62972
64195
  let paraArray = str.split(" ");
62973
64196
 
62974
- if(paraArray.length == 3 && paraArray[1] == 'sigma') {
64197
+ //if(paraArray.length == 3 && paraArray[1] == 'sigma') {
64198
+ if(paraArray[1] == 'sigma') {
62975
64199
  let sigma = paraArray[2];
62976
64200
  let type = paraArray[0];
62977
64201
 
64202
+ let fileType = 'dsn6';
64203
+ if(paraArray.length == 5) fileType = paraArray[4];
64204
+
62978
64205
  if(urlArray.length == 2) {
62979
- await ic.dsn6ParserCls.dsn6ParserBase(urlArray[1], type, sigma);
64206
+ let bInputSigma = true;
64207
+ if(fileType == 'dsn6') {
64208
+ await ic.dsn6ParserCls.dsn6ParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
64209
+ }
64210
+ else if(fileType == 'ccp4') {
64211
+ await ic.ccp4ParserCls.ccp4ParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
64212
+ }
64213
+ else if(fileType == 'mtz') {
64214
+ await ic.mtzParserCls.mtzParserBase(urlArray[1], type, sigma, 'url', bInputSigma);
64215
+ }
62980
64216
  }
62981
64217
  else {
62982
64218
  await ic.dsn6ParserCls.dsn6Parser(ic.inputid, type, sigma);
@@ -71920,7 +73156,7 @@ class Ray {
71920
73156
  }
71921
73157
 
71922
73158
  // from iview (http://istar.cse.cuhk.edu.hk/iview/)
71923
- getAtomsFromPosition(point, threshold) { let ic = this.icn3d, me = ic.icn3dui;
73159
+ getAtomsFromPosition(point, threshold, atoms) { let ic = this.icn3d, me = ic.icn3dui;
71924
73160
  let i;
71925
73161
 
71926
73162
  if(threshold === undefined || threshold === null) {
@@ -71928,7 +73164,8 @@ class Ray {
71928
73164
  }
71929
73165
 
71930
73166
  //for (i in ic.atoms) {
71931
- for (i in ic.dAtoms) {
73167
+ let atomHash = (atoms) ? atoms : ic.dAtoms;
73168
+ for (i in atomHash) {
71932
73169
  let atom = ic.atoms[i];
71933
73170
 
71934
73171
  if(ic.ions.hasOwnProperty(i) && ic.opts['ions'] === 'sphere') {
@@ -72000,7 +73237,7 @@ class Control {
72000
73237
  ic.typetext = false;
72001
73238
  });
72002
73239
 
72003
- $(document).bind('keydown', function (e) {
73240
+ $(document).bind('keydown', async function (e) {
72004
73241
  //document.addEventListener('keydown', function (e) {
72005
73242
  if(e.shiftKey || e.keyCode === 16) {
72006
73243
  ic.bShift = true;
@@ -72138,7 +73375,7 @@ class Control {
72138
73375
 
72139
73376
  else if(e.keyCode === 65 ) { // A, alternate
72140
73377
  if(Object.keys(ic.structures).length > 1) {
72141
- ic.alternateCls.alternateWrapper();
73378
+ await ic.alternateCls.alternateWrapper();
72142
73379
  }
72143
73380
  }
72144
73381
 
@@ -72321,13 +73558,25 @@ class Picking {
72321
73558
  y += me.htmlCls.MENU_HEIGHT;
72322
73559
  }
72323
73560
  let text =(ic.pk == 1) ? atom.resn + atom.resi + '@' + atom.name : atom.resn + atom.resi;
73561
+ let chainid = atom.structure + '_' + atom.chain;
73562
+ let textWidth;
72324
73563
  if(ic.structures !== undefined && Object.keys(ic.structures).length > 1) {
72325
- text = atom.structure + '_' + atom.chain + ' ' + text;
72326
- $("#" + ic.pre + "popup").css("width", "160px");
73564
+ text = chainid + ' ' + text;
73565
+ textWidth = (ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) ? 160 + 80 : 160;
73566
+ $("#" + ic.pre + "popup").css("width", textWidth + "px");
72327
73567
  }
72328
73568
  else {
72329
- $("#" + ic.pre + "popup").css("width", "80px");
73569
+ textWidth = (ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) ? 80 + 80 : 80;
73570
+ $("#" + ic.pre + "popup").css("width", textWidth + "px");
72330
73571
  }
73572
+
73573
+
73574
+ if(ic.chainid2refpdbname && ic.chainid2refpdbname[chainid]) {
73575
+ let refnumLabel = ic.resid2refnum[chainid + '_' + atom.resi];
73576
+
73577
+ if(refnumLabel) text += ', Ig: ' + refnumLabel;
73578
+ }
73579
+
72331
73580
  $("#" + ic.pre + "popup").html(text);
72332
73581
  $("#" + ic.pre + "popup").css("top", y).css("left", x+20).show();
72333
73582
  }
@@ -73488,6 +74737,8 @@ class iCn3D {
73488
74737
  this.alignParserCls = new AlignParser(this);
73489
74738
  this.chainalignParserCls = new ChainalignParser(this);
73490
74739
  this.dsn6ParserCls = new Dsn6Parser(this);
74740
+ this.ccp4ParserCls = new Ccp4Parser(this);
74741
+ this.mtzParserCls = new MtzParser(this);
73491
74742
  this.mmcifParserCls = new MmcifParser(this);
73492
74743
  this.mmdbParserCls = new MmdbParser(this);
73493
74744
  this.mmtfParserCls = new MmtfParser(this);
@@ -73750,7 +75001,7 @@ class iCn3DUI {
73750
75001
  //even when multiple iCn3D viewers are shown together.
73751
75002
  this.pre = this.cfg.divid + "_";
73752
75003
 
73753
- this.REVISION = '3.28.4';
75004
+ this.REVISION = '3.29.0';
73754
75005
 
73755
75006
  // In nodejs, iCn3D defines "window = {navigator: {}}"
73756
75007
  this.bNode = (Object.keys(window).length < 2) ? true : false;