icn3d 3.28.10 → 3.28.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/icn3d.js CHANGED
@@ -6469,7 +6469,7 @@ class ClickMenu {
6469
6469
  ic.resid2specCls.selectProperty('polar');
6470
6470
  });
6471
6471
  me.myEventCls.onIds("#" + me.pre + "mn2_propBfactor", "click", function(e) { me.icn3d; //e.preventDefault();
6472
- me.htmlCls.dialogCls.openDlg('dl_propbybfactor', 'Select residue based on B-factor');
6472
+ me.htmlCls.dialogCls.openDlg('dl_propbybfactor', 'Select residue based on B-factor/pLDDT');
6473
6473
  });
6474
6474
  me.myEventCls.onIds("#" + me.pre + "mn2_propSolAcc", "click", function(e) { me.icn3d; //e.preventDefault();
6475
6475
  me.htmlCls.dialogCls.openDlg('dl_propbypercentout', 'Select residue based on the percentage of solvent accessilbe surface area');
@@ -7596,7 +7596,8 @@ class ClickMenu {
7596
7596
  // var aaa = 1; //alert("The url is more than 4000 characters and may not work.");
7597
7597
  //}
7598
7598
  //else {
7599
- url = url.replace("full.html", "full2.html");
7599
+ url = url.replace("icn3d/full.html?", "icn3d/full2.html?");
7600
+ url = url.replace("icn3d/?", "icn3d/full2.html?");
7600
7601
  url += '&closepopup=1';
7601
7602
  let urlTarget = (ic.structures && Object.keys(ic.structures).length > 0) ? '_blank' : '_self';
7602
7603
  window.open(url, urlTarget);
@@ -7925,6 +7926,14 @@ class ClickMenu {
7925
7926
  let pos = str.indexOf('|||');
7926
7927
  if(pos !== -1) str = str.substr(0, pos);
7927
7928
  let transformation = {};
7929
+
7930
+ if(!ic.quaternion) {
7931
+ // reset parameters
7932
+ ic._zoomFactor = 1.0;
7933
+ ic.mouseChange = new THREE.Vector2(0,0);
7934
+ ic.quaternion = new THREE.Quaternion(0,0,0,1);
7935
+ }
7936
+
7928
7937
  transformation.factor = ic._zoomFactor;
7929
7938
  transformation.mouseChange = ic.mouseChange;
7930
7939
  transformation.quaternion = {};
@@ -8640,7 +8649,9 @@ class SetMenu {
8640
8649
 
8641
8650
  html += this.getLink('mn1_exportPdbRes', 'PDB', 1, 2);
8642
8651
  html += this.getLink('profixpdb', 'PDB with Missing Atoms', undefined, 2);
8643
- html += this.getLink('profixpdbh', 'PDB with Hydrogens', undefined, 2);
8652
+
8653
+ // the quality is not good to add hydrogen
8654
+ //html += this.getLink('profixpdbh', 'PDB with Hydrogens', undefined, 2);
8644
8655
 
8645
8656
  if(me.cfg.cid === undefined) {
8646
8657
  html += this.getLink('mn1_exportSecondary', 'Secondary Structure', undefined, 2);
@@ -9491,7 +9502,7 @@ class SetMenu {
9491
9502
 
9492
9503
  //if(me.cfg.afid) html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
9493
9504
  //if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) {
9494
- html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AlphaFold<br><span style="padding-left:1.5em;">Confidence</span>', undefined, 1, 1);
9505
+ html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'pLDDT', undefined, 1, 1);
9495
9506
  //}
9496
9507
 
9497
9508
  //!!!
@@ -11812,10 +11823,10 @@ class SetDialog {
11812
11823
  html += "</div>";
11813
11824
 
11814
11825
  html += me.htmlCls.divStr + "dl_propbybfactor' class='" + dialogClass + "'>";
11815
- html += this.addNotebookTitle('dl_propbybfactor', 'Select residues basen on B-factor');
11816
- html += "<div style='width:400px'>Select residue based on B-factor. The values are in the range of 0-100.</div><br>";
11817
- html += "<b>Min B-factor</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "minbfactor' value='0' size='10'>% <br>";
11818
- html += "<b>Max B-factor</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "maxbfactor' value='100' size='10'>% <br>";
11826
+ html += this.addNotebookTitle('dl_propbybfactor', 'Select residues basen on B-factor/pLDDT');
11827
+ html += "<div style='width:400px'>Select residue based on B-factor/pLDDT. The values are in the range of 0-100.</div><br>";
11828
+ html += "<b>Min B-factor/pLDDT</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "minbfactor' value='0' size='10'>% <br>";
11829
+ html += "<b>Max B-factor/pLDDT</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "maxbfactor' value='100' size='10'>% <br>";
11819
11830
  html += "<button style='white-space:nowrap;' id='" + me.pre + "applypropbybfactor'>Apply</button><br/><br/>";
11820
11831
  html += "</div>";
11821
11832
 
@@ -12275,9 +12286,9 @@ class Events {
12275
12286
  thisClass.setLogCmd("clear selection", true);
12276
12287
  });
12277
12288
 
12278
- me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", function(e) { let ic = me.icn3d;
12289
+ me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", async function(e) { let ic = me.icn3d;
12279
12290
  ic.bAlternate = true;
12280
- ic.alternateCls.alternateStructures();
12291
+ await ic.alternateCls.alternateStructures();
12281
12292
  ic.bAlternate = false;
12282
12293
 
12283
12294
  thisClass.setLogCmd("alternate structures", false);
@@ -15456,10 +15467,11 @@ class SetHtml {
15456
15467
 
15457
15468
  let pdbstr = '';
15458
15469
 
15459
- pdbstr += ic.saveFileCls.getAtomPDB(atomHash);
15470
+ let bMergeIntoOne = true;
15471
+ pdbstr += ic.saveFileCls.getAtomPDB(atomHash, undefined, undefined, undefined, undefined, undefined, bMergeIntoOne);
15460
15472
  pdbstr += ic.saveFileCls.getAtomPDB(ionHash, true, undefined, true);
15461
15473
 
15462
- let url = "https://www.ncbi.nlm.nih.gov/Structure/delphi/delphi.fcgi";
15474
+ let url = me.htmlCls.baseUrl + "delphi/delphi.cgi";
15463
15475
 
15464
15476
  let pdbid =(me.cfg.cid) ? me.cfg.cid : Object.keys(ic.structures).toString();
15465
15477
 
@@ -15555,6 +15567,7 @@ class SetHtml {
15555
15567
  let matchedStrData = "Start of data file======\n";
15556
15568
  let posData = imageStr.indexOf(matchedStrData);
15557
15569
  ic.bInputfile =(posData == -1) ? false : true;
15570
+ ic.bInputPNGWithData = ic.bInputfile;
15558
15571
  let commandStr = (command) ? command.replace(/;/g, "\n") : '';
15559
15572
 
15560
15573
  let statefile;
@@ -32499,8 +32512,8 @@ class Alternate {
32499
32512
 
32500
32513
  // change the display atom when alternating
32501
32514
  //Show structures one by one.
32502
- alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
32503
- ic.bAlernate = true;
32515
+ async alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
32516
+ ic.bAlternate = true;
32504
32517
 
32505
32518
  //ic.transformCls.zoominSelection();
32506
32519
 
@@ -32597,16 +32610,24 @@ class Alternate {
32597
32610
  ic.applyMapCls.removeEmmaps();
32598
32611
  ic.applyMapCls.applyEmmapOptions();
32599
32612
 
32600
- // disallow the alternation of DelPhi map
32613
+ // allow the alternation of DelPhi map
32614
+ /*
32615
+ // Option 1: recalculate =========
32601
32616
  ic.applyMapCls.removePhimaps();
32602
- // ic.applyMapCls.applyPhimapOptions();
32603
- // should recalculate the potential
32604
- //ic.loadDelphiFileBase('delphi');
32617
+ await ic.delphiCls.loadDelphiFile('delphi');
32605
32618
 
32606
- // ic.applyMapCls.removeSurfaces();
32607
- // ic.applyMapCls.applyphisurfaceOptions();
32608
- // should recalculate the potential
32609
- //ic.loadDelphiFileBase('delphi2');
32619
+ ic.applyMapCls.removeSurfaces();
32620
+ await ic.delphiCls.loadDelphiFile('delphi2');
32621
+ // ==============
32622
+ */
32623
+
32624
+ // Option 2: NO recalculate, just show separately =========
32625
+ ic.applyMapCls.removePhimaps();
32626
+ ic.applyMapCls.applyPhimapOptions();
32627
+
32628
+ ic.applyMapCls.removeSurfaces();
32629
+ ic.applyMapCls.applyphisurfaceOptions();
32630
+ // ==============
32610
32631
 
32611
32632
  // alternate the PCA axes
32612
32633
  ic.axes = [];
@@ -32623,9 +32644,9 @@ class Alternate {
32623
32644
  ic.bShowHighlight = true;
32624
32645
  }
32625
32646
 
32626
- alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
32647
+ async alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
32627
32648
  ic.bAlternate = true;
32628
- this.alternateStructures();
32649
+ await this.alternateStructures();
32629
32650
  ic.bAlternate = false;
32630
32651
  }
32631
32652
 
@@ -35734,7 +35755,7 @@ class SetOption {
35734
35755
 
35735
35756
  let colorLabel = colorType.substr(0, 1).toUpperCase() + colorType.substr(1);
35736
35757
  if(colorType == 'confidence') {
35737
- colorLabel = 'AlphaFold Confidence (pLDDT)';
35758
+ colorLabel = 'pLDDT';
35738
35759
  }
35739
35760
  else if(colorType == 'normalized hydrophobic') {
35740
35761
  colorLabel = 'Normalized Hydrophobicity';
@@ -36029,7 +36050,7 @@ class SetOption {
36029
36050
  "C' Strand": "6495ED",
36030
36051
  "C'' Strand": "006400",
36031
36052
  "D Strand": "00FF00",
36032
- "E Strand": "FFFF00", //"F0E68C",
36053
+ "E Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36033
36054
  "F Strand": "FFA500",
36034
36055
  "G Strand": "FF0000",
36035
36056
  //"G+ Strand": "8B0000",
@@ -36057,14 +36078,14 @@ class SetOption {
36057
36078
  "<b>Protodomain 1</b>": "",
36058
36079
  "A Strand": "0000FF",
36059
36080
  "B Strand": "006400",
36060
- "C Strand": "FFFF00", //"F0E68C",
36081
+ "C Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36061
36082
  "C' Strand": "FFA500",
36062
36083
  "<br><b>Linker</b>": "",
36063
36084
  "C'' Strand": "FF0000",
36064
36085
  "<br><b>Protodomain 2</b>": "",
36065
36086
  "D Strand": "0000FF",
36066
36087
  "E Strand": "006400",
36067
- "F Strand": "FFFF00", //"F0E68C",
36088
+ "F Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36068
36089
  "G Strand": "FFA500",
36069
36090
  "": "",
36070
36091
  "Loop": "CCCCCC"
@@ -42224,7 +42245,7 @@ class ShowAnno {
42224
42245
  let proteinName = fullProteinName;
42225
42246
  //if(proteinName.length > 40) proteinName = proteinName.substr(0, 40) + "...";
42226
42247
  let categoryStr =(index == 0) ? "<span class='icn3d-annoLargeTitle'><b>Proteins</b>: </span><br><br>" : "";
42227
- let geneLink =(ic.chainsGene[chnid] && ic.chainsGene[chnid].geneId) ? "(Gene: <a href='https://www.ncbi.nlm.nih.gov/gene/" + ic.chainsGene[chnid].geneId + "?report=gene_table' target='_blank' title='" + ic.chainsGene[chnid].geneDesc + "'>" + ic.chainsGene[chnid].geneSymbol + "</a>)" : '';
42248
+ let geneLink =(ic.chainsGene[chnid] && ic.chainsGene[chnid].geneId && ic.chainsGene[chnid].geneDesc) ? "(Gene: <a href='https://www.ncbi.nlm.nih.gov/gene/" + ic.chainsGene[chnid].geneId + "?report=gene_table' target='_blank' title='" + ic.chainsGene[chnid].geneDesc + "'>" + ic.chainsGene[chnid].geneSymbol + "</a>)" : '';
42228
42249
  let structure = chnid.substr(0, chnid.indexOf('_'));
42229
42250
  let chainLink = (structure.length > 5) ? '<a href="https://alphafold.ebi.ac.uk/entry/' + structure + '" target="_blank">' + chnid + '</a>' : chnid;
42230
42251
  let chainHtml = "<div id='" + ic.pre + "anno_" + chnid + "' class='icn3d-annotation'>" + categoryStr
@@ -42901,7 +42922,7 @@ class ShowSeq {
42901
42922
  html += '<span>-</span>'; //'<span>-</span>';
42902
42923
  }
42903
42924
  }
42904
-
42925
+
42905
42926
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html += this.insertMulGap(ic.seqEndLen[chnid], '-');
42906
42927
 
42907
42928
  html += '<span class="icn3d-residueNum"></span>';
@@ -43120,7 +43141,7 @@ class ShowSeq {
43120
43141
  html += '</div>';
43121
43142
  html2 += '</div>';
43122
43143
  html3 += '</div>';
43123
-
43144
+
43124
43145
  //if(Object.keys(ic.chains[chnid]).length > 10) {
43125
43146
  if(ic.giSeq[chnid].length > 10) {
43126
43147
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
@@ -43169,8 +43190,9 @@ class ShowSeq {
43169
43190
  html3 += '</div></div>';
43170
43191
  }
43171
43192
 
43172
- if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
43193
+ if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
43173
43194
  let result = this.showAllRefNum(giSeq, chnid);
43195
+
43174
43196
  html += result.html;
43175
43197
  html3 += result.html3;
43176
43198
  }
@@ -43182,7 +43204,7 @@ class ShowSeq {
43182
43204
  html3 += result.html3;
43183
43205
  }
43184
43206
  }
43185
-
43207
+
43186
43208
  // highlight reference numbers
43187
43209
  if(ic.bShowRefnum) {
43188
43210
  // comment out so that this process didn't change the selection
@@ -43191,7 +43213,7 @@ class ShowSeq {
43191
43213
  // commented out because it produced too many commands
43192
43214
  // let name = 'refnum_anchors';
43193
43215
  // ic.selectionCls.saveSelection(name, name);
43194
-
43216
+
43195
43217
  ic.hlUpdateCls.updateHlAll();
43196
43218
  }
43197
43219
 
@@ -43222,7 +43244,7 @@ class ShowSeq {
43222
43244
  //ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
43223
43245
  ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
43224
43246
 
43225
- ic.selectionCls.selectAll_base();
43247
+ //ic.selectionCls.selectAll_base();
43226
43248
  ic.hlUpdateCls.updateHlAll();
43227
43249
  //ic.drawCls.draw();
43228
43250
  ic.drawCls.draw();
@@ -43342,8 +43364,10 @@ class ShowSeq {
43342
43364
 
43343
43365
  postfix = strandPostfix + '_' + index;
43344
43366
 
43367
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // A- strand
43368
+
43345
43369
  if(currStrand && currStrand != ' ') {
43346
- if(refnum3c.substr(0,1) != '9') {
43370
+ if(refnum3c.substr(0,1) != '9' || firstTwo == 10) {
43347
43371
  let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
43348
43372
 
43349
43373
  if(currStrand != prevStrand) { // reset currCnt
@@ -43370,6 +43394,10 @@ class ShowSeq {
43370
43394
  resCntAtAnchor = 0;
43371
43395
  }
43372
43396
 
43397
+ if(firstTwo == 10) {
43398
+ strandArray[strandCnt].anchorRefnum = 0;
43399
+ }
43400
+
43373
43401
  strandArray[strandCnt].strandPostfix = strandPostfix; // a in A1250a
43374
43402
  strandArray[strandCnt].strand = currStrand; // A in A1250a
43375
43403
 
@@ -43392,6 +43420,10 @@ class ShowSeq {
43392
43420
  resCntAtAnchor = 0;
43393
43421
  }
43394
43422
 
43423
+ if(firstTwo == 10) {
43424
+ strandArray[strandCnt - 1].anchorRefnum = 0;
43425
+ }
43426
+
43395
43427
  strandArray[strandCnt - 1].endResi = currResi;
43396
43428
  strandArray[strandCnt - 1].endRefnum = refnum; // 1250a
43397
43429
  strandArray[strandCnt - 1].resCntAtAnchor = resCntAtAnchor;
@@ -43726,13 +43758,13 @@ class ShowSeq {
43726
43758
 
43727
43759
  let html = '';
43728
43760
 
43729
- if(refnumLabel && lastTwo == 50 && !bLoop) {
43761
+ if(refnumLabel && (lastTwo == 50 || refnum == 1094) && !bLoop) {
43730
43762
  // highlight the anchor residues
43731
43763
  ic.hAtomsRefnum = me.hashUtilsCls.unionHash(ic.hAtomsRefnum, ic.residues[residueid]);
43732
43764
 
43733
43765
  html += '<span ' + colorStr + ' title="' + refnumLabel + '"><b>' + refnumLabel.substr(0, 1) + '</b>' + refnumLabel.substr(1) + '</span>';
43734
43766
  }
43735
- else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
43767
+ else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && refnum != 1096 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
43736
43768
  // e.g., 2152a
43737
43769
  lastTwoStr = isNaN(refnumStr) ? lastTwoStr + refnumStr.substr(refnumStr.length - 1, 1) : lastTwoStr;
43738
43770
  html += '<span ' + colorStr + ' title="' + refnumLabel + '">' + lastTwoStr + '</span>';
@@ -43774,7 +43806,8 @@ class ShowSeq {
43774
43806
  return '#00FF00';
43775
43807
  }
43776
43808
  else if(currStrand == "E") {
43777
- return (bText) ? "#F7DC6F" : "#FFFF00";
43809
+ //return (bText) ? "#F7DC6F" : "#FFFF00";
43810
+ return "#F7DC6F";
43778
43811
  }
43779
43812
  else if(currStrand == "F") {
43780
43813
  return '#FFA500';
@@ -43798,7 +43831,7 @@ class ShowSeq {
43798
43831
  return '#006400';
43799
43832
  }
43800
43833
  else if(currStrand == "C" || currStrand == "F") {
43801
- return "#FFFF00"; //'#F0E68C';
43834
+ return "#F7DC6F"; //"#FFFF00"; //'#F0E68C';
43802
43835
  }
43803
43836
  else if(currStrand == "C'" || (currStrand && currStrand.substr(0, 1) == "G")) {
43804
43837
  return '#FFA500';
@@ -45501,27 +45534,27 @@ class LineGraph {
45501
45534
  let thisClass = this;
45502
45535
 
45503
45536
  // round 1, 16 templates
45504
- ic.refpdbArray = ['1InsulinR_8guyE_human_FN3-n1', '1Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4', '1CoAtomerGamma1_1r4xA_human', '1C3_2qkiD_human_n1', '1CuZnSuperoxideDismutase_1hl5C_human', '1ASF1A_2iijA_human', '1FAB-LIGHT_5esv_C1-n2', '1CD2_1hnfA_human_C2-n2', '1NaCaExchanger_2fwuA_dog_n2', '1FAB-HEAVY_5esv_V-n1', '1PDL1_4z18B_human_V-n1', '1BTLA_2aw2A_human_Iset', '1LaminAC_1ifrA_human', '1IsdA_2iteA_bacteria', '1TCRa_6jxrm_human_C1-n2', '1CD19_6al5A_human_C2orV-n1', '1CD28_1yjdC_human_V'];
45537
+ ic.refpdbArray = ['1InsulinR_8guyE_human_FN3-n1', '1Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4', '1CoAtomerGamma1_1r4xA_human', '1C3_2qkiD_human_n1', '1CuZnSuperoxideDismutase_1hl5C_human', '1ASF1A_2iijA_human', '1FAB-LIGHT_5esv_C1-n2', '1CD2_1hnfA_human_C2-n2', '1NaCaExchanger_2fwuA_dog_n2', '1NaKATPaseTransporterBeta_2zxeB_spurdogshark', '1FAB-HEAVY_5esv_V-n1', '1PDL1_4z18B_human_V-n1', '1BTLA_2aw2A_human_Iset', '1LaminAC_1ifrA_human', '1CD3g_6jxrg_human_Iset', '1CD28_1yjdC_human_V', '1CD19_6al5A_human_C2orV-n1'];
45505
45538
 
45506
45539
  // round 2
45507
45540
  ic.refpdbHash = {};
45508
45541
  ic.refpdbHash['1InsulinR_8guyE_human_FN3-n1'] = ['InsulinR_8guyE_human_FN3-n1', 'IL6Rb_1bquB_human_FN3-n3', 'Sidekick2_1wf5A_human_FN3-n7', 'InsulinR_8guyE_human_FN3-n2', 'Contactin1_2ee2A_human_FN3-n9', 'IL6Rb_1bquB_human_FN3-n2'];
45509
45542
  ic.refpdbHash['1Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4'] = ['Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4', 'ICOS_6x4gA_human_V'];
45510
- ic.refpdbHash['1CoAtomerGamma1_1r4xA_human'] = ['CoAtomerGamma1_1r4xA_human', 'TP34_2o6cA_bacteria', 'RBPJ_6py8C_human_Unk-n2', 'TP47_1o75A_bacteria'];
45543
+ ic.refpdbHash['1CoAtomerGamma1_1r4xA_human'] = ['CoAtomerGamma1_1r4xA_human', 'TP34_2o6cA_bacteria'];
45511
45544
  ic.refpdbHash['1C3_2qkiD_human_n1'] = ['C3_2qkiD_human_n1', 'BArrestin1_4jqiA_rat_n1', 'RBPJ_6py8C_human_Unk-n1'];
45512
45545
  ic.refpdbHash['1CuZnSuperoxideDismutase_1hl5C_human'] = ['CuZnSuperoxideDismutase_1hl5C_human', 'TEAD1_3kysC_human'];
45513
- ic.refpdbHash['1ASF1A_2iijA_human'] = ['ASF1A_2iijA_human', 'MPT63_1lmiA_bacteria'];
45546
+ ic.refpdbHash['1ASF1A_2iijA_human'] = ['ASF1A_2iijA_human', 'RBPJ_6py8C_human_Unk-n2', 'TP47_1o75A_bacteria'];
45514
45547
  ic.refpdbHash['1FAB-LIGHT_5esv_C1-n2'] = ['FAB-LIGHT_5esv_C1-n2', 'GHR_1axiB_human_FN3-n1', 'VTCN1_Q7Z7D3_human_V-n2', 'B2Microglobulin_7phrL_human_C1', 'FAB-HEAVY_5esv_C1-n2', 'MHCIa_7phrH_human_C1'];
45515
45548
  ic.refpdbHash['1CD2_1hnfA_human_C2-n2'] = ['CD2_1hnfA_human_C2-n2', 'Siglec3_5j0bB_human_C2-n2'];
45516
- ic.refpdbHash['1NaCaExchanger_2fwuA_dog_n2'] = ['NaCaExchanger_2fwuA_dog_n2', 'ORF7a_1xakA_virus', 'ECadherin_4zt1A_human_n2', 'NaKATPaseTransporterBeta_2zxeB_spurdogshark'];
45549
+ ic.refpdbHash['1NaCaExchanger_2fwuA_dog_n2'] = ['NaCaExchanger_2fwuA_dog_n2', 'ORF7a_1xakA_virus', 'ECadherin_4zt1A_human_n2'];
45550
+ ic.refpdbHash['1NaKATPaseTransporterBeta_2zxeB_spurdogshark'] = ['NaKATPaseTransporterBeta_2zxeB_spurdogshark'];
45517
45551
  ic.refpdbHash['1FAB-HEAVY_5esv_V-n1'] = ['FAB-HEAVY_5esv_V-n1', 'FAB-LIGHT_5esv_V-n1', 'VNAR_1t6vN_shark_V', 'TCRa_6jxrm_human_V-n1', 'VISTA_6oilA_human_V', 'CD8a_1cd8A_human_V', 'PD1_4zqkB_human_V'];
45518
45552
  ic.refpdbHash['1PDL1_4z18B_human_V-n1'] = ['PDL1_4z18B_human_V-n1', 'CD2_1hnfA_human_V-n1', 'LAG3_7tzgD_human_V-n1'];
45519
45553
  ic.refpdbHash['1BTLA_2aw2A_human_Iset'] = ['BTLA_2aw2A_human_Iset', 'Palladin_2dm3A_human_Iset-n1', 'Titin_4uowM_human_Unk-n152', 'LAG3_7tzgD_human_C2-n2', 'JAM1_1nbqA_human_VorIset-n2', 'Contactin1_3s97C_human_C2-n2'];
45520
- ic.refpdbHash['1LaminAC_1ifrA_human'] = ['LaminAC_1ifrA_human'];
45521
- ic.refpdbHash['1IsdA_2iteA_bacteria'] = ['IsdA_2iteA_bacteria'];
45522
- ic.refpdbHash['1TCRa_6jxrm_human_C1-n2'] = ['TCRa_6jxrm_human_C1-n2'];
45523
- ic.refpdbHash['1CD19_6al5A_human_C2orV-n1'] = ['CD19_6al5A_human_C2orV-n1'];
45524
- ic.refpdbHash['1CD28_1yjdC_human_V'] = ['CD28_1yjdC_human_V'];
45554
+ ic.refpdbHash['1LaminAC_1ifrA_human'] = ['LaminAC_1ifrA_human', 'CD3d_6jxrd_human_Iset'];
45555
+ ic.refpdbHash['1CD3g_6jxrg_human_Iset'] = ['CD3g_6jxrg_human_Iset', 'TCRa_6jxrm_human_C1-n2', 'IsdA_2iteA_bacteria'];
45556
+ ic.refpdbHash['1CD28_1yjdC_human_V'] = ['CD28_1yjdC_human_V', 'MPT63_1lmiA_bacteria', 'CD3e_6jxrf_human_Iset'];
45557
+ ic.refpdbHash['1CD19_6al5A_human_C2orV-n1'] = ['CD19_6al5A_human_C2orV-n1'];
45525
45558
 
45526
45559
  // use known ref structure
45527
45560
  ic.refpdbHash['5ESV_C'] = ['FAB-HEAVY_5esv_V-n1', 'FAB-HEAVY_5esv_C1-n2'];
@@ -45569,11 +45602,14 @@ class LineGraph {
45569
45602
  ic.refpdbHash['6A15_A'] = ['CD19_6al5A_human_C2orV-n1'];
45570
45603
  ic.refpdbHash['2QKI_D'] = ['C3_2qkiD_human_n1'];
45571
45604
  ic.refpdbHash['1YJD_C'] = ['CD28_1yjdC_human_V'];
45605
+ ic.refpdbHash['6JXR_d'] = ['CD3d_6jxrd_human_Iset'];
45606
+ ic.refpdbHash['6JXR_f'] = ['CD3e_6jxrf_human_Iset'];
45607
+ ic.refpdbHash['6JXR_g'] = ['CD3g_6jxrg_human_Iset'];
45572
45608
 
45573
45609
  let pdbAjaxArray = [];
45574
45610
  for(let k = 0, kl = ic.refpdbArray.length; k < kl; ++k) {
45575
- //let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refpdbid=" + ic.refpdbArray[k];
45576
- let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refjsonid=" + ic.refpdbArray[k];
45611
+ let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refpdbid=" + ic.refpdbArray[k];
45612
+ //let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refjsonid=" + ic.refpdbArray[k];
45577
45613
 
45578
45614
  let pdbAjax = me.getAjaxPromise(urlpdb, 'text');
45579
45615
 
@@ -45604,8 +45640,8 @@ class LineGraph {
45604
45640
  let ajaxArray = [];
45605
45641
  let domainidpairArray = [];
45606
45642
 
45607
- me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
45608
- let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi";
45643
+ let urltmalign = me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
45644
+ me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi";
45609
45645
 
45610
45646
  if(!ic.resid2domainid) ic.resid2domainid = {};
45611
45647
  //ic.resid2domainid = {};
@@ -45643,7 +45679,7 @@ class LineGraph {
45643
45679
 
45644
45680
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(currAtoms);
45645
45681
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(currAtoms);
45646
- let resiSum = parseInt(atomFirst.resi) + parseInt(atomLast.resi);
45682
+ let resiSum = atomFirst.resi + ':' + atomLast.resi;
45647
45683
 
45648
45684
  for(let n = 0, nl = residueArray.length; n < nl; ++n) {
45649
45685
  let resid = residueArray[n];
@@ -45679,7 +45715,7 @@ class LineGraph {
45679
45715
 
45680
45716
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtoms);
45681
45717
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtoms);
45682
- let resiSum = parseInt(atomFirst.resi) + parseInt(atomLast.resi);
45718
+ let resiSum = atomFirst.resi + ':' + atomLast.resi;
45683
45719
 
45684
45720
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
45685
45721
  let startResi = segArray[m];
@@ -45697,31 +45733,30 @@ class LineGraph {
45697
45733
 
45698
45734
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
45699
45735
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
45700
- let bForceOneDomain = true;
45701
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
45736
+ //let bForceOneDomain = true;
45737
+ //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
45702
45738
 
45703
45739
  // ig strand for any subset will have the same k, use the number of residue to separate them
45704
45740
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
45705
45741
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtomsArray[k]);
45706
- let resiSum = parseInt(atomFirst.resi) + parseInt(atomLast.resi);
45742
+ let resiSum = atomFirst.resi + ':' + atomLast.resi;
45707
45743
  //let domainid = chainid + '-' + k + '_' + Object.keys(domainAtomsArray[k]).length;
45708
45744
  let domainid = chainid + '-' + k + '_' + resiSum;
45709
45745
  ic.domainid2pdb[domainid] = pdb_target;
45710
45746
 
45711
45747
  if(!template) {
45712
45748
  for(let index = 0, indexl = dataArray.length; index < indexl; ++index) {
45713
- // let struct2 = ic.defaultPdbId + index;
45714
- // let pdb_query = dataArray[index].value; //[0];
45715
- // let header = 'HEADER ' + struct2 + '\n';
45716
- // pdb_query = header + pdb_query;
45717
- let jsonStr_q = dataArray[index].value; //[0];
45749
+ let struct2 = ic.defaultPdbId + index;
45750
+ let pdb_query = dataArray[index].value; //[0];
45751
+ let header = 'HEADER ' + struct2 + '\n';
45752
+ pdb_query = header + pdb_query;
45753
+ //let jsonStr_q = dataArray[index].value; //[0];
45718
45754
 
45719
- // TM-align is not good when you align a full structure with the strand-only structure. VAST is better in this case.
45720
- // let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbArray[index]};
45721
- // let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
45755
+ let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbArray[index]};
45756
+ let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
45722
45757
 
45723
- let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
45724
- let alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
45758
+ // let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
45759
+ // let alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
45725
45760
 
45726
45761
  ajaxArray.push(alignAjax);
45727
45762
 
@@ -45743,8 +45778,8 @@ class LineGraph {
45743
45778
  // let allPromise = Promise.allSettled(ajaxArray);
45744
45779
  // dataArray2 = await allPromise;
45745
45780
 
45746
- //split arrays into chunks of 96 jobs or me.cfg.maxajax jobs
45747
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : 96;
45781
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
45782
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
45748
45783
 
45749
45784
  for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
45750
45785
  let currAjaxArray = [];
@@ -45851,7 +45886,6 @@ class LineGraph {
45851
45886
  let thisClass = this;
45852
45887
 
45853
45888
  let tmscoreThreshold = 0.4; // 0.4; //0.5;
45854
- let rmsdThreshold = 10;
45855
45889
 
45856
45890
  // find the best alignment for each chain
45857
45891
  let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
@@ -45885,7 +45919,10 @@ class LineGraph {
45885
45919
  }
45886
45920
  }
45887
45921
  else {
45888
- if(queryData[0].super_rmsd > rmsdThreshold || queryData[0].num_res < minResidues) {
45922
+ // if(queryData[0].super_rmsd > rmsdThreshold || queryData[0].num_res < minResidues) {
45923
+ // continue;
45924
+ // }
45925
+ if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < minResidues) {
45889
45926
  continue;
45890
45927
  }
45891
45928
  }
@@ -45900,7 +45937,8 @@ class LineGraph {
45900
45937
  if(!me.bNode) console.log("refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
45901
45938
  }
45902
45939
  else {
45903
- if(!me.bNode) console.log("domainid: " + domainid + " refpdbname " + refpdbname + " RMSD: " + queryData[0].super_rmsd + ", num_res: " + queryData[0].num_res + ", 10/RMSD + num_res/5: " + (10 / queryData[0].super_rmsd + queryData[0].num_seg / 5).toFixed(1));
45940
+ // if(!me.bNode) console.log("domainid: " + domainid + " refpdbname " + refpdbname + " RMSD: " + queryData[0].super_rmsd + ", num_seg: " + queryData[0].num_seg + ", 10/RMSD + num_seg/5: " + (10 / queryData[0].super_rmsd + queryData[0].num_seg / 5).toFixed(1));
45941
+ if(!me.bNode) console.log("domainid: " + domainid + " refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
45904
45942
  }
45905
45943
 
45906
45944
  // Ig-like domains: B (2150, 2150a, 2150b), C (3150, 3250), E (7150, 7250), F (8150, 8250) strands
@@ -45948,7 +45986,8 @@ class LineGraph {
45948
45986
  }
45949
45987
  }
45950
45988
  else {
45951
- let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
45989
+ //let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
45990
+ let mixScore = queryData[0].score;
45952
45991
 
45953
45992
  if(!domainid2score.hasOwnProperty(domainid) || mixScore > domainid2score[domainid]) {
45954
45993
  domainid2score[domainid] = mixScore;
@@ -46019,8 +46058,8 @@ class LineGraph {
46019
46058
  //let allPromise = Promise.allSettled(ajaxArray);
46020
46059
  //dataArray3 = await allPromise;
46021
46060
 
46022
- //split arrays into chunks of 96 jobs or me.cfg.maxajax jobs
46023
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : 96;
46061
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46062
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46024
46063
 
46025
46064
  for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46026
46065
  let currAjaxArray = [];
@@ -46137,7 +46176,7 @@ class LineGraph {
46137
46176
  else {
46138
46177
  await ic.showAnnoCls.showAnnotations();
46139
46178
  }
46140
-
46179
+
46141
46180
  ic.annotationCls.setAnnoViewAndDisplay('detailed view');
46142
46181
  }
46143
46182
  else {
@@ -49549,7 +49588,7 @@ class ChainalignParser {
49549
49588
  //hAtoms = me.hashUtilsCls.unionHash(hAtoms, ic.chains[chainidArray[0]]);
49550
49589
  //hAtoms = me.hashUtilsCls.unionHash(hAtoms, ic.chains[chainidArray[1]]);
49551
49590
  }
49552
-
49591
+
49553
49592
  // set up the view of sequence alignment for each pair
49554
49593
  for(let mmdbidpair in mmdbidpairFinalHash) {
49555
49594
  if(ic.q_rotation !== undefined) {
@@ -49980,7 +50019,11 @@ class ChainalignParser {
49980
50019
  if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
49981
50020
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
49982
50021
  let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
49983
- if(me.cfg.aligntool == 'tmalign') html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
50022
+ if(me.cfg.aligntool == 'tmalign') {
50023
+ html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
50024
+ ic.tmscore = align[0].score.toPrecision(4);
50025
+ }
50026
+
49984
50027
  $("#" + ic.pre + "dl_rmsd_html").html(html);
49985
50028
  if(!me.cfg.bSidebyside) me.htmlCls.dialogCls.openDlg('dl_rmsd', 'RMSD of alignment');
49986
50029
 
@@ -52043,7 +52086,7 @@ class PdbParser {
52043
52086
 
52044
52087
  if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
52045
52088
 
52046
- if(bAppend) {
52089
+ if(bAppend && !me.bNode) {
52047
52090
  // show all
52048
52091
  ic.definedSetsCls.setModeAndDisplay('all');
52049
52092
  }
@@ -54361,16 +54404,20 @@ class ParserUtils {
54361
54404
 
54362
54405
  getMissingResidues(seqArray, type, chainid) { let ic = this.icn3d, me = ic.icn3dui;
54363
54406
  ic.chainsSeq[chainid] = [];
54407
+
54408
+ // find the offset of MMDB sequence
54409
+ let offset = 0;
54364
54410
  if(type === 'mmdbid' || type === 'align') {
54365
54411
  for(let i = 0, il = seqArray.length; i < il; ++i) {
54366
54412
  if(seqArray[i][0] != 0) {
54367
- seqArray[i][0] - (i + 1);
54413
+ offset = seqArray[i][0] - (i + 1);
54368
54414
  break;
54369
54415
  }
54370
54416
  }
54371
54417
  }
54372
54418
 
54373
- let prevResi = 0;
54419
+ //let prevResi = 0;
54420
+ let prevResi = offset;
54374
54421
  for(let i = 0, il = seqArray.length; i < il; ++i) {
54375
54422
  let seqName, resiPos;
54376
54423
  // mmdbid: ["0","R","ARG"],["502","V","VAL"]; mmcifid: [1, "ARG"]; align: ["0","R","ARG"] //align: [1, "0","R","ARG"]
@@ -55259,6 +55306,7 @@ class LoadAtomData {
55259
55306
  let CSerial, prevCSerial, OSerial, prevOSerial;
55260
55307
 
55261
55308
  let biopolymerChainsHash = {};
55309
+
55262
55310
  for(let i in atoms) {
55263
55311
  ++serial;
55264
55312
 
@@ -55288,21 +55336,21 @@ class LoadAtomData {
55288
55336
  atm.chain = ic.molid2chain[molid].substr(pos + 1);
55289
55337
  }
55290
55338
  else {
55291
- let miscName = 'Misc';
55339
+ let miscName = 'Misc';
55292
55340
 
55293
- //if(atm.resn != prevResn || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH' || atm.name == atm.elem) {
55294
- if((chainid2kind[chainNum] === 'protein' && chainid2kind[chainNum] === 'nucleotide' && atm.resi != prevResiOri)
55295
- ||(chainid2kind[chainNum] !== 'protein' && chainid2kind[chainNum] !== 'nucleotide'
55296
- &&(atm.resn.substr(0,3) != prevResn.substr(0,3) || atm.resi != prevResiOri || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH')) ) {
55297
- ++miscCnt;
55298
- }
55341
+ //if(atm.resn != prevResn || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH' || atm.name == atm.elem) {
55342
+ if((chainid2kind[chainNum] === 'protein' && chainid2kind[chainNum] === 'nucleotide' && atm.resi != prevResiOri)
55343
+ ||(chainid2kind[chainNum] !== 'protein' && chainid2kind[chainNum] !== 'nucleotide'
55344
+ &&(atm.resn.substr(0,3) != prevResn.substr(0,3) || atm.resi != prevResiOri || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH')) ) {
55345
+ ++miscCnt;
55346
+ }
55299
55347
 
55300
- atm.resi_ori = atm.resi;
55301
- atm.resi = miscCnt;
55302
- bSetResi = true;
55348
+ atm.resi_ori = atm.resi;
55349
+ atm.resi = miscCnt;
55350
+ bSetResi = true;
55303
55351
 
55304
- //if all are defined in the chain section, no "Misc" should appear
55305
- atm.chain = miscName;
55352
+ //if all are defined in the chain section, no "Misc" should appear
55353
+ atm.chain = miscName;
55306
55354
  }
55307
55355
 
55308
55356
  //if(ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t && alignType === 'query') {
@@ -56321,7 +56369,8 @@ class SetSeqAlign {
56321
56369
 
56322
56370
  if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
56323
56371
 
56324
- let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
56372
+ //let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
56373
+ let resi = this.getResiAferAlign(chainid1, bRealign, j);
56325
56374
  // let resn = (bRealign && me.cfg.aligntool == 'tmalign') ? this.getResnFromResi(chainid1, j).toLowerCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
56326
56375
  let resn = this.getResnFromResi(chainid1, resi).toLowerCase();
56327
56376
 
@@ -56342,11 +56391,11 @@ class SetSeqAlign {
56342
56391
 
56343
56392
  if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
56344
56393
 
56345
- let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
56394
+ //let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
56395
+ let resi = this.getResiAferAlign(chainid2, bRealign, j);
56346
56396
  // let resn = (bRealign && me.cfg.aligntool == 'tmalign') ? this.getResnFromResi(chainid2, j).toLowerCase() : ic.chainsSeq[chainid2][j].name.toLowerCase();
56347
56397
  let resn = this.getResnFromResi(chainid2, resi).toLowerCase();
56348
56398
 
56349
-
56350
56399
  if(resn == '?') continue;
56351
56400
 
56352
56401
  color = me.htmlCls.GREY8;
@@ -56887,7 +56936,6 @@ class SetSeqAlign {
56887
56936
  start1Pos = start1;
56888
56937
  end1Pos = end1;
56889
56938
  }
56890
-
56891
56939
  //let range = resi2range_t[resiStart1];
56892
56940
 
56893
56941
  // if the mapping does not start from start_t, add gaps to the query seq
@@ -56911,7 +56959,7 @@ class SetSeqAlign {
56911
56959
  pos2 = result.pos2;
56912
56960
  let notAlnLen1 = pos2 - (pos1 + 1);
56913
56961
  let notAlnLen2 = start2 - (prevIndex2 + 1);
56914
-
56962
+
56915
56963
  // insert non-aligned residues in query seq
56916
56964
  this.insertNotAlignRes(chainid2, prevIndex2+1, notAlnLen2, bRealign);
56917
56965
 
@@ -57753,10 +57801,7 @@ class LoadPDB {
57753
57801
 
57754
57802
  if(ic.atoms[oriSerial2NewSerial[from]] !== undefined) ic.atoms[oriSerial2NewSerial[from]].bonds.push(oriSerial2NewSerial[to]);
57755
57803
  }
57756
- } else if (record.substr(0,3) === 'TER') {
57757
- // Concatenation of two pdbs will have several atoms for the same serial
57758
- ++serial;
57759
- }
57804
+ } else if (record.substr(0,3) === 'TER') ;
57760
57805
  }
57761
57806
 
57762
57807
  // add the last residue set
@@ -59330,24 +59375,28 @@ class ApplyCommand {
59330
59375
  else if(command == 'rotate left') {
59331
59376
  ic.bStopRotate = false;
59332
59377
  ic.ROT_DIR = 'left';
59378
+ ic.transformCls.rotateCountMax = 6000;
59333
59379
 
59334
59380
  ic.resizeCanvasCls.rotStruc('left');
59335
59381
  }
59336
59382
  else if(command == 'rotate right') {
59337
59383
  ic.bStopRotate = false;
59338
59384
  ic.ROT_DIR = 'right';
59385
+ ic.transformCls.rotateCountMax = 6000;
59339
59386
 
59340
59387
  ic.resizeCanvasCls.rotStruc('right');
59341
59388
  }
59342
59389
  else if(command == 'rotate up') {
59343
59390
  ic.bStopRotate = false;
59344
59391
  ic.ROT_DIR = 'up';
59392
+ ic.transformCls.rotateCountMax = 6000;
59345
59393
 
59346
59394
  ic.resizeCanvasCls.rotStruc('up');
59347
59395
  }
59348
59396
  else if(command == 'rotate down') {
59349
59397
  ic.bStopRotate = false;
59350
59398
  ic.ROT_DIR = 'down';
59399
+ ic.transformCls.rotateCountMax = 6000;
59351
59400
 
59352
59401
  ic.resizeCanvasCls.rotStruc('down');
59353
59402
  }
@@ -61892,8 +61941,10 @@ class LoadScript {
61892
61941
  let id = loadStr.substr(loadStr.lastIndexOf(' ') + 1);
61893
61942
  if(id.length == 4) id = id.toUpperCase();
61894
61943
 
61895
- // skip loading the structure if it was loaded before
61896
- if(ic.structures && ic.structures.hasOwnProperty(id)) return;
61944
+ // skip loading the structure if
61945
+ // 1. PDB was in the iCn3D PNG Image file
61946
+ // 2. it was loaded before
61947
+ if(ic.bInputPNGWithData || (ic.structures && ic.structures.hasOwnProperty(id))) return;
61897
61948
 
61898
61949
  ic.inputid = id;
61899
61950
  if(command.indexOf('load mmtf') !== -1) {
@@ -64046,7 +64097,8 @@ class Delphi {
64046
64097
  let pdbstr = '';
64047
64098
  /// pdbstr += ic.saveFileCls.getPDBHeader();
64048
64099
 
64049
- pdbstr +=(me.cfg.cid) ? ic.saveFileCls.getAtomPDB(atomHash, true) : ic.saveFileCls.getAtomPDB(atomHash);
64100
+ let bMergeIntoOne = true;
64101
+ pdbstr +=(me.cfg.cid) ? ic.saveFileCls.getAtomPDB(atomHash, true, undefined, undefined, undefined, undefined, bMergeIntoOne) : ic.saveFileCls.getAtomPDB(atomHash, undefined, undefined, undefined, undefined, undefined, bMergeIntoOne);
64050
64102
  pdbstr += ic.saveFileCls.getAtomPDB(ionHash, true, undefined, true);
64051
64103
 
64052
64104
  return pdbstr;
@@ -65019,7 +65071,8 @@ console.log("free energy: " + energy + " kcal/mol");
65019
65071
  }
65020
65072
  else {
65021
65073
  let atoms = me.hashUtilsCls.intHash(ic.dAtoms, ic.hAtoms);
65022
- pdbStr = ic.saveFileCls.getAtomPDB(atoms);
65074
+ let bMergeIntoOne = true;
65075
+ pdbStr = ic.saveFileCls.getAtomPDB(atoms, undefined, undefined, undefined, undefined, undefined, bMergeIntoOne);
65023
65076
  }
65024
65077
 
65025
65078
  let url = me.htmlCls.baseUrl + "scap/scap.cgi";
@@ -68940,7 +68993,7 @@ class SaveFile {
68940
68993
  }
68941
68994
 
68942
68995
  //getAtomPDB: function(atomHash, bPqr, bPdb, bNoChem) { let ic = this.icn3d, me = ic.icn3dui;
68943
- getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader, chainResi2pdb, pdbid) { let ic = this.icn3d, me = ic.icn3dui;
68996
+ getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader, chainResi2pdb, pdbid, bMergeIntoOne) { let ic = this.icn3d, me = ic.icn3dui;
68944
68997
  let pdbStr = '';
68945
68998
 
68946
68999
  // get all phosphate groups in lipids
@@ -69093,6 +69146,7 @@ class SaveFile {
69093
69146
  let bMulStruc =(struArray.length > 1) ? true : false;
69094
69147
 
69095
69148
  let molNum = 1, prevStru = '', prevChain = '';
69149
+ let chainIndex = 0, fakeChain = '', chainNameArray = 'abcdefghijklmnopqrstuvwxyz0123456789';
69096
69150
 
69097
69151
  let addedChainResiHash = {};
69098
69152
  for(let i in atomHash) {
@@ -69103,20 +69157,22 @@ class SaveFile {
69103
69157
 
69104
69158
  //if(bMulStruc && atom.structure != prevStru) {
69105
69159
  if(atom.structure != prevStru) {
69106
- pdbStr += connStr;
69107
- connStr = '';
69160
+ if(!bMergeIntoOne || !bMulStruc) {
69161
+ pdbStr += connStr;
69162
+ connStr = '';
69108
69163
 
69109
- if(molNum > 1) pdbStr += '\nENDMDL\n';
69164
+ if(molNum > 1) pdbStr += '\nENDMDL\n';
69110
69165
 
69111
- if(bMulStruc) pdbStr += 'MODEL ' + molNum + '\n';
69166
+ if(bMulStruc) pdbStr += 'MODEL ' + molNum + '\n';
69167
+ }
69112
69168
 
69113
69169
  // add header
69114
69170
  let mutantInfo = (chainResi2pdb) ? "Mutated chain_residue " + Object.keys(chainResi2pdb) + '; ' : '';
69115
69171
  if(!bNoHeader) {
69116
69172
  //pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo, pdbid);
69117
69173
 
69118
- // make sur ethe PDB ID is correct
69119
- pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo, atom.structure);
69174
+ // make sure the PDB ID is correct
69175
+ if(!bMergeIntoOne || !bMulStruc) pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo, atom.structure);
69120
69176
 
69121
69177
  //pdbStr += '\n'; // separate from incomplete secondary structures
69122
69178
  }
@@ -69124,6 +69180,7 @@ class SaveFile {
69124
69180
  //prevStru = atom.structure;
69125
69181
  ++molNum;
69126
69182
  }
69183
+
69127
69184
  //else {
69128
69185
  //if(atom.chain != prevChain) {
69129
69186
  if(atom.chain != prevChain && atom.structure == prevStru) {
@@ -69197,17 +69254,28 @@ class SaveFile {
69197
69254
  */
69198
69255
 
69199
69256
  line +=(resn.length <= 3) ? resn.padStart(3, ' ') : resn.substr(0, 3);
69200
- //line += ' ';
69201
- //line +=(atom.chain.length <= 1) ? atom.chain.padStart(1, ' ') : atom.chain.substr(0, 1);
69202
- if(atom.chain.length >= 2) {
69203
- let chainTmp = atom.chain.replace(/_/gi, '').substr(0, 2);
69204
- line += chainTmp;
69205
- }
69206
- else if(atom.chain.length == 1) {
69207
- line += ' ' + atom.chain.substr(0, 1);
69257
+
69258
+ if(bMergeIntoOne && molNum > 2 && (ic.proteins.hasOwnProperty(atom.serial) || ic.nucleotides.hasOwnProperty(atom.serial))) {
69259
+ if(atom.structure != prevStru || atom.chain != prevChain) {
69260
+ fakeChain = (chainIndex < 36) ? chainNameArray[chainIndex] : '?';
69261
+ ++chainIndex;
69262
+ }
69263
+
69264
+ line += ' ' + fakeChain;
69208
69265
  }
69209
- else if(atom.chain.length == 0) {
69210
- line += ' A';
69266
+ else {
69267
+ //line += ' ';
69268
+ //line +=(atom.chain.length <= 1) ? atom.chain.padStart(1, ' ') : atom.chain.substr(0, 1);
69269
+ if(atom.chain.length >= 2) {
69270
+ let chainTmp = atom.chain.replace(/_/gi, '').substr(0, 2);
69271
+ line += chainTmp;
69272
+ }
69273
+ else if(atom.chain.length == 1) {
69274
+ line += ' ' + atom.chain.substr(0, 1);
69275
+ }
69276
+ else if(atom.chain.length == 0) {
69277
+ line += ' A';
69278
+ }
69211
69279
  }
69212
69280
 
69213
69281
  let resi = atom.resi;
@@ -69303,9 +69371,11 @@ class SaveFile {
69303
69371
  prevChain = atom.chain;
69304
69372
  }
69305
69373
 
69306
- pdbStr += connStr;
69307
-
69308
- if(bMulStruc) pdbStr += '\nENDMDL\n';
69374
+ if(!bMergeIntoOne || !bMulStruc) {
69375
+ pdbStr += connStr;
69376
+
69377
+ if(bMulStruc) pdbStr += '\nENDMDL\n';
69378
+ }
69309
69379
 
69310
69380
  return pdbStr;
69311
69381
  }
@@ -71040,7 +71110,7 @@ class Control {
71040
71110
  ic.typetext = false;
71041
71111
  });
71042
71112
 
71043
- $(document).bind('keydown', function (e) {
71113
+ $(document).bind('keydown', async function (e) {
71044
71114
  //document.addEventListener('keydown', function (e) {
71045
71115
  if(e.shiftKey || e.keyCode === 16) {
71046
71116
  ic.bShift = true;
@@ -71178,7 +71248,7 @@ class Control {
71178
71248
 
71179
71249
  else if(e.keyCode === 65 ) { // A, alternate
71180
71250
  if(Object.keys(ic.structures).length > 1) {
71181
- ic.alternateCls.alternateWrapper();
71251
+ await ic.alternateCls.alternateWrapper();
71182
71252
  }
71183
71253
  }
71184
71254
 
@@ -72790,7 +72860,7 @@ class iCn3DUI {
72790
72860
  //even when multiple iCn3D viewers are shown together.
72791
72861
  this.pre = this.cfg.divid + "_";
72792
72862
 
72793
- this.REVISION = '3.28.3';
72863
+ this.REVISION = '3.28.4';
72794
72864
 
72795
72865
  // In nodejs, iCn3D defines "window = {navigator: {}}"
72796
72866
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -72997,16 +73067,17 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
72997
73067
  }
72998
73068
  }
72999
73069
 
73000
- // realign
73001
- ic.chainidArray = [chain_t].concat(chainidArray);
73002
- ic.chainidArray = ic.chainalignParserCls.addPostfixForChainids(ic.chainidArray);
73003
-
73070
+ // get the matched structures, do not include the template
73004
73071
  let mmdbafid = '';
73005
- for(let i = 0, il = ic.chainidArray.length; i < il; ++i) {
73072
+ for(let i = 0, il = chainidArray.length; i < il; ++i) {
73006
73073
  if(i > 0) mmdbafid += ',';
73007
- mmdbafid += ic.chainidArray[i].substr(0, ic.chainidArray[i].indexOf('_'));
73074
+ mmdbafid += chainidArray[i].substr(0, chainidArray[i].indexOf('_'));
73008
73075
  }
73009
73076
 
73077
+ // realign, include the template
73078
+ ic.chainidArray = [chain_t].concat(chainidArray);
73079
+ ic.chainidArray = ic.chainalignParserCls.addPostfixForChainids(ic.chainidArray);
73080
+
73010
73081
  me.htmlCls.clickMenuCls.setLogCmd('resdef ' + me.cfg.resdef, true);
73011
73082
 
73012
73083
  ic.loadCmd = 'vast_search_chainid ' + ic.chainidArray;
@@ -73222,7 +73293,7 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
73222
73293
  // ic.bNCBI = true;
73223
73294
 
73224
73295
  // remove space
73225
- me.cfg.mmdbafid = me.cfg.mmdbafid.replace(/\s+/g, '');
73296
+ me.cfg.mmdbafid = me.cfg.mmdbafid.replace(/\s+/g, '').toUpperCase();
73226
73297
 
73227
73298
  ic.bMmdbafid = true;
73228
73299
  ic.inputid = me.cfg.mmdbafid;