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.module.js CHANGED
@@ -7370,7 +7370,7 @@ class ClickMenu {
7370
7370
  ic.resid2specCls.selectProperty('polar');
7371
7371
  });
7372
7372
  me.myEventCls.onIds("#" + me.pre + "mn2_propBfactor", "click", function(e) { me.icn3d; //e.preventDefault();
7373
- me.htmlCls.dialogCls.openDlg('dl_propbybfactor', 'Select residue based on B-factor');
7373
+ me.htmlCls.dialogCls.openDlg('dl_propbybfactor', 'Select residue based on B-factor/pLDDT');
7374
7374
  });
7375
7375
  me.myEventCls.onIds("#" + me.pre + "mn2_propSolAcc", "click", function(e) { me.icn3d; //e.preventDefault();
7376
7376
  me.htmlCls.dialogCls.openDlg('dl_propbypercentout', 'Select residue based on the percentage of solvent accessilbe surface area');
@@ -8497,7 +8497,8 @@ class ClickMenu {
8497
8497
  // alert("The url is more than 4000 characters and may not work.");
8498
8498
  //}
8499
8499
  //else {
8500
- url = url.replace("full.html", "full2.html");
8500
+ url = url.replace("icn3d/full.html?", "icn3d/full2.html?");
8501
+ url = url.replace("icn3d/?", "icn3d/full2.html?");
8501
8502
  url += '&closepopup=1';
8502
8503
  let urlTarget = (ic.structures && Object.keys(ic.structures).length > 0) ? '_blank' : '_self';
8503
8504
  window.open(url, urlTarget);
@@ -8826,6 +8827,14 @@ class ClickMenu {
8826
8827
  let pos = str.indexOf('|||');
8827
8828
  if(pos !== -1) str = str.substr(0, pos);
8828
8829
  let transformation = {};
8830
+
8831
+ if(!ic.quaternion) {
8832
+ // reset parameters
8833
+ ic._zoomFactor = 1.0;
8834
+ ic.mouseChange = new THREE.Vector2(0,0);
8835
+ ic.quaternion = new THREE.Quaternion(0,0,0,1);
8836
+ }
8837
+
8829
8838
  transformation.factor = ic._zoomFactor;
8830
8839
  transformation.mouseChange = ic.mouseChange;
8831
8840
  transformation.quaternion = {};
@@ -9541,7 +9550,9 @@ class SetMenu {
9541
9550
 
9542
9551
  html += this.getLink('mn1_exportPdbRes', 'PDB', 1, 2);
9543
9552
  html += this.getLink('profixpdb', 'PDB with Missing Atoms', undefined, 2);
9544
- html += this.getLink('profixpdbh', 'PDB with Hydrogens', undefined, 2);
9553
+
9554
+ // the quality is not good to add hydrogen
9555
+ //html += this.getLink('profixpdbh', 'PDB with Hydrogens', undefined, 2);
9545
9556
 
9546
9557
  if(me.cfg.cid === undefined) {
9547
9558
  html += this.getLink('mn1_exportSecondary', 'Secondary Structure', undefined, 2);
@@ -10392,7 +10403,7 @@ class SetMenu {
10392
10403
 
10393
10404
  //if(me.cfg.afid) html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
10394
10405
  //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) {
10395
- html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'AlphaFold<br><span style="padding-left:1.5em;">Confidence</span>', undefined, 1, 1);
10406
+ html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'pLDDT', undefined, 1, 1);
10396
10407
  //}
10397
10408
 
10398
10409
  //!!!
@@ -12713,10 +12724,10 @@ class SetDialog {
12713
12724
  html += "</div>";
12714
12725
 
12715
12726
  html += me.htmlCls.divStr + "dl_propbybfactor' class='" + dialogClass + "'>";
12716
- html += this.addNotebookTitle('dl_propbybfactor', 'Select residues basen on B-factor');
12717
- html += "<div style='width:400px'>Select residue based on B-factor. The values are in the range of 0-100.</div><br>";
12718
- html += "<b>Min B-factor</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "minbfactor' value='0' size='10'>% <br>";
12719
- html += "<b>Max B-factor</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "maxbfactor' value='100' size='10'>% <br>";
12727
+ html += this.addNotebookTitle('dl_propbybfactor', 'Select residues basen on B-factor/pLDDT');
12728
+ html += "<div style='width:400px'>Select residue based on B-factor/pLDDT. The values are in the range of 0-100.</div><br>";
12729
+ html += "<b>Min B-factor/pLDDT</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "minbfactor' value='0' size='10'>% <br>";
12730
+ html += "<b>Max B-factor/pLDDT</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "maxbfactor' value='100' size='10'>% <br>";
12720
12731
  html += "<button style='white-space:nowrap;' id='" + me.pre + "applypropbybfactor'>Apply</button><br/><br/>";
12721
12732
  html += "</div>";
12722
12733
 
@@ -13176,9 +13187,9 @@ class Events {
13176
13187
  thisClass.setLogCmd("clear selection", true);
13177
13188
  });
13178
13189
 
13179
- me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", function(e) { let ic = me.icn3d;
13190
+ me.myEventCls.onIds(["#" + me.pre + "alternate", "#" + me.pre + "mn2_alternate", "#" + me.pre + "alternate2"], "click", async function(e) { let ic = me.icn3d;
13180
13191
  ic.bAlternate = true;
13181
- ic.alternateCls.alternateStructures();
13192
+ await ic.alternateCls.alternateStructures();
13182
13193
  ic.bAlternate = false;
13183
13194
 
13184
13195
  thisClass.setLogCmd("alternate structures", false);
@@ -16357,10 +16368,11 @@ class SetHtml {
16357
16368
 
16358
16369
  let pdbstr = '';
16359
16370
 
16360
- pdbstr += ic.saveFileCls.getAtomPDB(atomHash);
16371
+ let bMergeIntoOne = true;
16372
+ pdbstr += ic.saveFileCls.getAtomPDB(atomHash, undefined, undefined, undefined, undefined, undefined, bMergeIntoOne);
16361
16373
  pdbstr += ic.saveFileCls.getAtomPDB(ionHash, true, undefined, true);
16362
16374
 
16363
- let url = "https://www.ncbi.nlm.nih.gov/Structure/delphi/delphi.fcgi";
16375
+ let url = me.htmlCls.baseUrl + "delphi/delphi.cgi";
16364
16376
 
16365
16377
  let pdbid =(me.cfg.cid) ? me.cfg.cid : Object.keys(ic.structures).toString();
16366
16378
 
@@ -16456,6 +16468,7 @@ class SetHtml {
16456
16468
  let matchedStrData = "Start of data file======\n";
16457
16469
  let posData = imageStr.indexOf(matchedStrData);
16458
16470
  ic.bInputfile =(posData == -1) ? false : true;
16471
+ ic.bInputPNGWithData = ic.bInputfile;
16459
16472
  let commandStr = (command) ? command.replace(/;/g, "\n") : '';
16460
16473
 
16461
16474
  let statefile;
@@ -33400,8 +33413,8 @@ class Alternate {
33400
33413
 
33401
33414
  // change the display atom when alternating
33402
33415
  //Show structures one by one.
33403
- alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
33404
- ic.bAlernate = true;
33416
+ async alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
33417
+ ic.bAlternate = true;
33405
33418
 
33406
33419
  //ic.transformCls.zoominSelection();
33407
33420
 
@@ -33498,16 +33511,24 @@ class Alternate {
33498
33511
  ic.applyMapCls.removeEmmaps();
33499
33512
  ic.applyMapCls.applyEmmapOptions();
33500
33513
 
33501
- // disallow the alternation of DelPhi map
33514
+ // allow the alternation of DelPhi map
33515
+ /*
33516
+ // Option 1: recalculate =========
33502
33517
  ic.applyMapCls.removePhimaps();
33503
- // ic.applyMapCls.applyPhimapOptions();
33504
- // should recalculate the potential
33505
- //ic.loadDelphiFileBase('delphi');
33518
+ await ic.delphiCls.loadDelphiFile('delphi');
33506
33519
 
33507
- // ic.applyMapCls.removeSurfaces();
33508
- // ic.applyMapCls.applyphisurfaceOptions();
33509
- // should recalculate the potential
33510
- //ic.loadDelphiFileBase('delphi2');
33520
+ ic.applyMapCls.removeSurfaces();
33521
+ await ic.delphiCls.loadDelphiFile('delphi2');
33522
+ // ==============
33523
+ */
33524
+
33525
+ // Option 2: NO recalculate, just show separately =========
33526
+ ic.applyMapCls.removePhimaps();
33527
+ ic.applyMapCls.applyPhimapOptions();
33528
+
33529
+ ic.applyMapCls.removeSurfaces();
33530
+ ic.applyMapCls.applyphisurfaceOptions();
33531
+ // ==============
33511
33532
 
33512
33533
  // alternate the PCA axes
33513
33534
  ic.axes = [];
@@ -33524,9 +33545,9 @@ class Alternate {
33524
33545
  ic.bShowHighlight = true;
33525
33546
  }
33526
33547
 
33527
- alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
33548
+ async alternateWrapper() { let ic = this.icn3d; ic.icn3dui;
33528
33549
  ic.bAlternate = true;
33529
- this.alternateStructures();
33550
+ await this.alternateStructures();
33530
33551
  ic.bAlternate = false;
33531
33552
  }
33532
33553
 
@@ -36635,7 +36656,7 @@ class SetOption {
36635
36656
 
36636
36657
  let colorLabel = colorType.substr(0, 1).toUpperCase() + colorType.substr(1);
36637
36658
  if(colorType == 'confidence') {
36638
- colorLabel = 'AlphaFold Confidence (pLDDT)';
36659
+ colorLabel = 'pLDDT';
36639
36660
  }
36640
36661
  else if(colorType == 'normalized hydrophobic') {
36641
36662
  colorLabel = 'Normalized Hydrophobicity';
@@ -36930,7 +36951,7 @@ class SetOption {
36930
36951
  "C' Strand": "6495ED",
36931
36952
  "C'' Strand": "006400",
36932
36953
  "D Strand": "00FF00",
36933
- "E Strand": "FFFF00", //"F0E68C",
36954
+ "E Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36934
36955
  "F Strand": "FFA500",
36935
36956
  "G Strand": "FF0000",
36936
36957
  //"G+ Strand": "8B0000",
@@ -36958,14 +36979,14 @@ class SetOption {
36958
36979
  "<b>Protodomain 1</b>": "",
36959
36980
  "A Strand": "0000FF",
36960
36981
  "B Strand": "006400",
36961
- "C Strand": "FFFF00", //"F0E68C",
36982
+ "C Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36962
36983
  "C' Strand": "FFA500",
36963
36984
  "<br><b>Linker</b>": "",
36964
36985
  "C'' Strand": "FF0000",
36965
36986
  "<br><b>Protodomain 2</b>": "",
36966
36987
  "D Strand": "0000FF",
36967
36988
  "E Strand": "006400",
36968
- "F Strand": "FFFF00", //"F0E68C",
36989
+ "F Strand": "F7DC6F", //"FFFF00", //"F0E68C",
36969
36990
  "G Strand": "FFA500",
36970
36991
  "": "",
36971
36992
  "Loop": "CCCCCC"
@@ -43125,7 +43146,7 @@ class ShowAnno {
43125
43146
  let proteinName = fullProteinName;
43126
43147
  //if(proteinName.length > 40) proteinName = proteinName.substr(0, 40) + "...";
43127
43148
  let categoryStr =(index == 0) ? "<span class='icn3d-annoLargeTitle'><b>Proteins</b>: </span><br><br>" : "";
43128
- 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>)" : '';
43149
+ 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>)" : '';
43129
43150
  let structure = chnid.substr(0, chnid.indexOf('_'));
43130
43151
  let chainLink = (structure.length > 5) ? '<a href="https://alphafold.ebi.ac.uk/entry/' + structure + '" target="_blank">' + chnid + '</a>' : chnid;
43131
43152
  let chainHtml = "<div id='" + ic.pre + "anno_" + chnid + "' class='icn3d-annotation'>" + categoryStr
@@ -43802,7 +43823,7 @@ class ShowSeq {
43802
43823
  html += '<span>-</span>'; //'<span>-</span>';
43803
43824
  }
43804
43825
  }
43805
-
43826
+
43806
43827
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html += this.insertMulGap(ic.seqEndLen[chnid], '-');
43807
43828
 
43808
43829
  html += '<span class="icn3d-residueNum"></span>';
@@ -44021,7 +44042,7 @@ class ShowSeq {
44021
44042
  html += '</div>';
44022
44043
  html2 += '</div>';
44023
44044
  html3 += '</div>';
44024
-
44045
+
44025
44046
  //if(Object.keys(ic.chains[chnid]).length > 10) {
44026
44047
  if(ic.giSeq[chnid].length > 10) {
44027
44048
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
@@ -44070,8 +44091,9 @@ class ShowSeq {
44070
44091
  html3 += '</div></div>';
44071
44092
  }
44072
44093
 
44073
- if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
44094
+ if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
44074
44095
  let result = this.showAllRefNum(giSeq, chnid);
44096
+
44075
44097
  html += result.html;
44076
44098
  html3 += result.html3;
44077
44099
  }
@@ -44083,7 +44105,7 @@ class ShowSeq {
44083
44105
  html3 += result.html3;
44084
44106
  }
44085
44107
  }
44086
-
44108
+
44087
44109
  // highlight reference numbers
44088
44110
  if(ic.bShowRefnum) {
44089
44111
  // comment out so that this process didn't change the selection
@@ -44092,7 +44114,7 @@ class ShowSeq {
44092
44114
  // commented out because it produced too many commands
44093
44115
  // let name = 'refnum_anchors';
44094
44116
  // ic.selectionCls.saveSelection(name, name);
44095
-
44117
+
44096
44118
  ic.hlUpdateCls.updateHlAll();
44097
44119
  }
44098
44120
 
@@ -44123,7 +44145,7 @@ class ShowSeq {
44123
44145
  //ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
44124
44146
  ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
44125
44147
 
44126
- ic.selectionCls.selectAll_base();
44148
+ //ic.selectionCls.selectAll_base();
44127
44149
  ic.hlUpdateCls.updateHlAll();
44128
44150
  //ic.drawCls.draw();
44129
44151
  ic.drawCls.draw();
@@ -44243,8 +44265,10 @@ class ShowSeq {
44243
44265
 
44244
44266
  postfix = strandPostfix + '_' + index;
44245
44267
 
44268
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // A- strand
44269
+
44246
44270
  if(currStrand && currStrand != ' ') {
44247
- if(refnum3c.substr(0,1) != '9') {
44271
+ if(refnum3c.substr(0,1) != '9' || firstTwo == 10) {
44248
44272
  let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
44249
44273
 
44250
44274
  if(currStrand != prevStrand) { // reset currCnt
@@ -44271,6 +44295,10 @@ class ShowSeq {
44271
44295
  resCntAtAnchor = 0;
44272
44296
  }
44273
44297
 
44298
+ if(firstTwo == 10) {
44299
+ strandArray[strandCnt].anchorRefnum = 0;
44300
+ }
44301
+
44274
44302
  strandArray[strandCnt].strandPostfix = strandPostfix; // a in A1250a
44275
44303
  strandArray[strandCnt].strand = currStrand; // A in A1250a
44276
44304
 
@@ -44293,6 +44321,10 @@ class ShowSeq {
44293
44321
  resCntAtAnchor = 0;
44294
44322
  }
44295
44323
 
44324
+ if(firstTwo == 10) {
44325
+ strandArray[strandCnt - 1].anchorRefnum = 0;
44326
+ }
44327
+
44296
44328
  strandArray[strandCnt - 1].endResi = currResi;
44297
44329
  strandArray[strandCnt - 1].endRefnum = refnum; // 1250a
44298
44330
  strandArray[strandCnt - 1].resCntAtAnchor = resCntAtAnchor;
@@ -44627,13 +44659,13 @@ class ShowSeq {
44627
44659
 
44628
44660
  let html = '';
44629
44661
 
44630
- if(refnumLabel && lastTwo == 50 && !bLoop) {
44662
+ if(refnumLabel && (lastTwo == 50 || refnum == 1094) && !bLoop) {
44631
44663
  // highlight the anchor residues
44632
44664
  ic.hAtomsRefnum = me.hashUtilsCls.unionHash(ic.hAtomsRefnum, ic.residues[residueid]);
44633
44665
 
44634
44666
  html += '<span ' + colorStr + ' title="' + refnumLabel + '"><b>' + refnumLabel.substr(0, 1) + '</b>' + refnumLabel.substr(1) + '</span>';
44635
44667
  }
44636
- else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
44668
+ else if(refnumLabel && lastTwo % 2 == 0 && lastTwo != 52 && refnum != 1096 && !bHidelabel) { // don't show label for the first, middle, and last loop residues
44637
44669
  // e.g., 2152a
44638
44670
  lastTwoStr = isNaN(refnumStr) ? lastTwoStr + refnumStr.substr(refnumStr.length - 1, 1) : lastTwoStr;
44639
44671
  html += '<span ' + colorStr + ' title="' + refnumLabel + '">' + lastTwoStr + '</span>';
@@ -44675,7 +44707,8 @@ class ShowSeq {
44675
44707
  return '#00FF00';
44676
44708
  }
44677
44709
  else if(currStrand == "E") {
44678
- return (bText) ? "#F7DC6F" : "#FFFF00";
44710
+ //return (bText) ? "#F7DC6F" : "#FFFF00";
44711
+ return "#F7DC6F";
44679
44712
  }
44680
44713
  else if(currStrand == "F") {
44681
44714
  return '#FFA500';
@@ -44699,7 +44732,7 @@ class ShowSeq {
44699
44732
  return '#006400';
44700
44733
  }
44701
44734
  else if(currStrand == "C" || currStrand == "F") {
44702
- return "#FFFF00"; //'#F0E68C';
44735
+ return "#F7DC6F"; //"#FFFF00"; //'#F0E68C';
44703
44736
  }
44704
44737
  else if(currStrand == "C'" || (currStrand && currStrand.substr(0, 1) == "G")) {
44705
44738
  return '#FFA500';
@@ -46402,27 +46435,27 @@ class LineGraph {
46402
46435
  let thisClass = this;
46403
46436
 
46404
46437
  // round 1, 16 templates
46405
- 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'];
46438
+ 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'];
46406
46439
 
46407
46440
  // round 2
46408
46441
  ic.refpdbHash = {};
46409
46442
  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'];
46410
46443
  ic.refpdbHash['1Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4'] = ['Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4', 'ICOS_6x4gA_human_V'];
46411
- ic.refpdbHash['1CoAtomerGamma1_1r4xA_human'] = ['CoAtomerGamma1_1r4xA_human', 'TP34_2o6cA_bacteria', 'RBPJ_6py8C_human_Unk-n2', 'TP47_1o75A_bacteria'];
46444
+ ic.refpdbHash['1CoAtomerGamma1_1r4xA_human'] = ['CoAtomerGamma1_1r4xA_human', 'TP34_2o6cA_bacteria'];
46412
46445
  ic.refpdbHash['1C3_2qkiD_human_n1'] = ['C3_2qkiD_human_n1', 'BArrestin1_4jqiA_rat_n1', 'RBPJ_6py8C_human_Unk-n1'];
46413
46446
  ic.refpdbHash['1CuZnSuperoxideDismutase_1hl5C_human'] = ['CuZnSuperoxideDismutase_1hl5C_human', 'TEAD1_3kysC_human'];
46414
- ic.refpdbHash['1ASF1A_2iijA_human'] = ['ASF1A_2iijA_human', 'MPT63_1lmiA_bacteria'];
46447
+ ic.refpdbHash['1ASF1A_2iijA_human'] = ['ASF1A_2iijA_human', 'RBPJ_6py8C_human_Unk-n2', 'TP47_1o75A_bacteria'];
46415
46448
  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'];
46416
46449
  ic.refpdbHash['1CD2_1hnfA_human_C2-n2'] = ['CD2_1hnfA_human_C2-n2', 'Siglec3_5j0bB_human_C2-n2'];
46417
- ic.refpdbHash['1NaCaExchanger_2fwuA_dog_n2'] = ['NaCaExchanger_2fwuA_dog_n2', 'ORF7a_1xakA_virus', 'ECadherin_4zt1A_human_n2', 'NaKATPaseTransporterBeta_2zxeB_spurdogshark'];
46450
+ ic.refpdbHash['1NaCaExchanger_2fwuA_dog_n2'] = ['NaCaExchanger_2fwuA_dog_n2', 'ORF7a_1xakA_virus', 'ECadherin_4zt1A_human_n2'];
46451
+ ic.refpdbHash['1NaKATPaseTransporterBeta_2zxeB_spurdogshark'] = ['NaKATPaseTransporterBeta_2zxeB_spurdogshark'];
46418
46452
  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'];
46419
46453
  ic.refpdbHash['1PDL1_4z18B_human_V-n1'] = ['PDL1_4z18B_human_V-n1', 'CD2_1hnfA_human_V-n1', 'LAG3_7tzgD_human_V-n1'];
46420
46454
  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'];
46421
- ic.refpdbHash['1LaminAC_1ifrA_human'] = ['LaminAC_1ifrA_human'];
46422
- ic.refpdbHash['1IsdA_2iteA_bacteria'] = ['IsdA_2iteA_bacteria'];
46423
- ic.refpdbHash['1TCRa_6jxrm_human_C1-n2'] = ['TCRa_6jxrm_human_C1-n2'];
46424
- ic.refpdbHash['1CD19_6al5A_human_C2orV-n1'] = ['CD19_6al5A_human_C2orV-n1'];
46425
- ic.refpdbHash['1CD28_1yjdC_human_V'] = ['CD28_1yjdC_human_V'];
46455
+ ic.refpdbHash['1LaminAC_1ifrA_human'] = ['LaminAC_1ifrA_human', 'CD3d_6jxrd_human_Iset'];
46456
+ ic.refpdbHash['1CD3g_6jxrg_human_Iset'] = ['CD3g_6jxrg_human_Iset', 'TCRa_6jxrm_human_C1-n2', 'IsdA_2iteA_bacteria'];
46457
+ ic.refpdbHash['1CD28_1yjdC_human_V'] = ['CD28_1yjdC_human_V', 'MPT63_1lmiA_bacteria', 'CD3e_6jxrf_human_Iset'];
46458
+ ic.refpdbHash['1CD19_6al5A_human_C2orV-n1'] = ['CD19_6al5A_human_C2orV-n1'];
46426
46459
 
46427
46460
  // use known ref structure
46428
46461
  ic.refpdbHash['5ESV_C'] = ['FAB-HEAVY_5esv_V-n1', 'FAB-HEAVY_5esv_C1-n2'];
@@ -46470,11 +46503,14 @@ class LineGraph {
46470
46503
  ic.refpdbHash['6A15_A'] = ['CD19_6al5A_human_C2orV-n1'];
46471
46504
  ic.refpdbHash['2QKI_D'] = ['C3_2qkiD_human_n1'];
46472
46505
  ic.refpdbHash['1YJD_C'] = ['CD28_1yjdC_human_V'];
46506
+ ic.refpdbHash['6JXR_d'] = ['CD3d_6jxrd_human_Iset'];
46507
+ ic.refpdbHash['6JXR_f'] = ['CD3e_6jxrf_human_Iset'];
46508
+ ic.refpdbHash['6JXR_g'] = ['CD3g_6jxrg_human_Iset'];
46473
46509
 
46474
46510
  let pdbAjaxArray = [];
46475
46511
  for(let k = 0, kl = ic.refpdbArray.length; k < kl; ++k) {
46476
- //let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refpdbid=" + ic.refpdbArray[k];
46477
- let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refjsonid=" + ic.refpdbArray[k];
46512
+ let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refpdbid=" + ic.refpdbArray[k];
46513
+ //let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refjsonid=" + ic.refpdbArray[k];
46478
46514
 
46479
46515
  let pdbAjax = me.getAjaxPromise(urlpdb, 'text');
46480
46516
 
@@ -46505,8 +46541,8 @@ class LineGraph {
46505
46541
  let ajaxArray = [];
46506
46542
  let domainidpairArray = [];
46507
46543
 
46508
- me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
46509
- let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi";
46544
+ let urltmalign = me.htmlCls.baseUrl + "tmalign/tmalign.cgi";
46545
+ me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi";
46510
46546
 
46511
46547
  if(!ic.resid2domainid) ic.resid2domainid = {};
46512
46548
  //ic.resid2domainid = {};
@@ -46544,7 +46580,7 @@ class LineGraph {
46544
46580
 
46545
46581
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(currAtoms);
46546
46582
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(currAtoms);
46547
- let resiSum = parseInt(atomFirst.resi) + parseInt(atomLast.resi);
46583
+ let resiSum = atomFirst.resi + ':' + atomLast.resi;
46548
46584
 
46549
46585
  for(let n = 0, nl = residueArray.length; n < nl; ++n) {
46550
46586
  let resid = residueArray[n];
@@ -46580,7 +46616,7 @@ class LineGraph {
46580
46616
 
46581
46617
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtoms);
46582
46618
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtoms);
46583
- let resiSum = parseInt(atomFirst.resi) + parseInt(atomLast.resi);
46619
+ let resiSum = atomFirst.resi + ':' + atomLast.resi;
46584
46620
 
46585
46621
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
46586
46622
  let startResi = segArray[m];
@@ -46598,31 +46634,30 @@ class LineGraph {
46598
46634
 
46599
46635
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
46600
46636
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
46601
- let bForceOneDomain = true;
46602
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
46637
+ //let bForceOneDomain = true;
46638
+ //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
46603
46639
 
46604
46640
  // ig strand for any subset will have the same k, use the number of residue to separate them
46605
46641
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
46606
46642
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(domainAtomsArray[k]);
46607
- let resiSum = parseInt(atomFirst.resi) + parseInt(atomLast.resi);
46643
+ let resiSum = atomFirst.resi + ':' + atomLast.resi;
46608
46644
  //let domainid = chainid + '-' + k + '_' + Object.keys(domainAtomsArray[k]).length;
46609
46645
  let domainid = chainid + '-' + k + '_' + resiSum;
46610
46646
  ic.domainid2pdb[domainid] = pdb_target;
46611
46647
 
46612
46648
  if(!template) {
46613
46649
  for(let index = 0, indexl = dataArray.length; index < indexl; ++index) {
46614
- // let struct2 = ic.defaultPdbId + index;
46615
- // let pdb_query = dataArray[index].value; //[0];
46616
- // let header = 'HEADER ' + struct2 + '\n';
46617
- // pdb_query = header + pdb_query;
46618
- let jsonStr_q = dataArray[index].value; //[0];
46650
+ let struct2 = ic.defaultPdbId + index;
46651
+ let pdb_query = dataArray[index].value; //[0];
46652
+ let header = 'HEADER ' + struct2 + '\n';
46653
+ pdb_query = header + pdb_query;
46654
+ //let jsonStr_q = dataArray[index].value; //[0];
46619
46655
 
46620
- // TM-align is not good when you align a full structure with the strand-only structure. VAST is better in this case.
46621
- // let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbArray[index]};
46622
- // let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
46656
+ let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbArray[index]};
46657
+ let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
46623
46658
 
46624
- let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
46625
- let alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
46659
+ // let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
46660
+ // let alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
46626
46661
 
46627
46662
  ajaxArray.push(alignAjax);
46628
46663
 
@@ -46644,8 +46679,8 @@ class LineGraph {
46644
46679
  // let allPromise = Promise.allSettled(ajaxArray);
46645
46680
  // dataArray2 = await allPromise;
46646
46681
 
46647
- //split arrays into chunks of 96 jobs or me.cfg.maxajax jobs
46648
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : 96;
46682
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46683
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46649
46684
 
46650
46685
  for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46651
46686
  let currAjaxArray = [];
@@ -46752,7 +46787,6 @@ class LineGraph {
46752
46787
  let thisClass = this;
46753
46788
 
46754
46789
  let tmscoreThreshold = 0.4; // 0.4; //0.5;
46755
- let rmsdThreshold = 10;
46756
46790
 
46757
46791
  // find the best alignment for each chain
46758
46792
  let domainid2score = {}, domainid2segs = {}, chainid2segs = {};
@@ -46786,7 +46820,10 @@ class LineGraph {
46786
46820
  }
46787
46821
  }
46788
46822
  else {
46789
- if(queryData[0].super_rmsd > rmsdThreshold || queryData[0].num_res < minResidues) {
46823
+ // if(queryData[0].super_rmsd > rmsdThreshold || queryData[0].num_res < minResidues) {
46824
+ // continue;
46825
+ // }
46826
+ if(queryData[0].score < tmscoreThreshold || queryData[0].num_res < minResidues) {
46790
46827
  continue;
46791
46828
  }
46792
46829
  }
@@ -46801,7 +46838,8 @@ class LineGraph {
46801
46838
  if(!me.bNode) console.log("refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
46802
46839
  }
46803
46840
  else {
46804
- 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));
46841
+ // 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));
46842
+ if(!me.bNode) console.log("domainid: " + domainid + " refpdbname " + refpdbname + " TM-score: " + queryData[0].score);
46805
46843
  }
46806
46844
 
46807
46845
  // Ig-like domains: B (2150, 2150a, 2150b), C (3150, 3250), E (7150, 7250), F (8150, 8250) strands
@@ -46849,7 +46887,8 @@ class LineGraph {
46849
46887
  }
46850
46888
  }
46851
46889
  else {
46852
- let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
46890
+ //let mixScore = 10 / queryData[0].super_rmsd + queryData[0].num_seg / 5;
46891
+ let mixScore = queryData[0].score;
46853
46892
 
46854
46893
  if(!domainid2score.hasOwnProperty(domainid) || mixScore > domainid2score[domainid]) {
46855
46894
  domainid2score[domainid] = mixScore;
@@ -46920,8 +46959,8 @@ class LineGraph {
46920
46959
  //let allPromise = Promise.allSettled(ajaxArray);
46921
46960
  //dataArray3 = await allPromise;
46922
46961
 
46923
- //split arrays into chunks of 96 jobs or me.cfg.maxajax jobs
46924
- let n = (me.cfg.maxajax) ? me.cfg.maxajax : 96;
46962
+ //split arrays into chunks of 48 jobs or me.cfg.maxajax jobs
46963
+ let n = (me.cfg.maxajax) ? me.cfg.maxajax : ic.refpdbArray.length * 6;
46925
46964
 
46926
46965
  for(let i = 0, il = parseInt((ajaxArray.length - 1) / n + 1); i < il; ++i) {
46927
46966
  let currAjaxArray = [];
@@ -47038,7 +47077,7 @@ class LineGraph {
47038
47077
  else {
47039
47078
  await ic.showAnnoCls.showAnnotations();
47040
47079
  }
47041
-
47080
+
47042
47081
  ic.annotationCls.setAnnoViewAndDisplay('detailed view');
47043
47082
  }
47044
47083
  else {
@@ -50450,7 +50489,7 @@ class ChainalignParser {
50450
50489
  //hAtoms = me.hashUtilsCls.unionHash(hAtoms, ic.chains[chainidArray[0]]);
50451
50490
  //hAtoms = me.hashUtilsCls.unionHash(hAtoms, ic.chains[chainidArray[1]]);
50452
50491
  }
50453
-
50492
+
50454
50493
  // set up the view of sequence alignment for each pair
50455
50494
  for(let mmdbidpair in mmdbidpairFinalHash) {
50456
50495
  if(ic.q_rotation !== undefined) {
@@ -50881,7 +50920,11 @@ class ChainalignParser {
50881
50920
  if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
50882
50921
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
50883
50922
  let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
50884
- if(me.cfg.aligntool == 'tmalign') html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
50923
+ if(me.cfg.aligntool == 'tmalign') {
50924
+ html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
50925
+ ic.tmscore = align[0].score.toPrecision(4);
50926
+ }
50927
+
50885
50928
  $("#" + ic.pre + "dl_rmsd_html").html(html);
50886
50929
  if(!me.cfg.bSidebyside) me.htmlCls.dialogCls.openDlg('dl_rmsd', 'RMSD of alignment');
50887
50930
 
@@ -52944,7 +52987,7 @@ class PdbParser {
52944
52987
 
52945
52988
  if(me.cfg.rotate !== undefined) ic.resizeCanvasCls.rotStruc(me.cfg.rotate, true);
52946
52989
 
52947
- if(bAppend) {
52990
+ if(bAppend && !me.bNode) {
52948
52991
  // show all
52949
52992
  ic.definedSetsCls.setModeAndDisplay('all');
52950
52993
  }
@@ -55262,16 +55305,20 @@ class ParserUtils {
55262
55305
 
55263
55306
  getMissingResidues(seqArray, type, chainid) { let ic = this.icn3d, me = ic.icn3dui;
55264
55307
  ic.chainsSeq[chainid] = [];
55308
+
55309
+ // find the offset of MMDB sequence
55310
+ let offset = 0;
55265
55311
  if(type === 'mmdbid' || type === 'align') {
55266
55312
  for(let i = 0, il = seqArray.length; i < il; ++i) {
55267
55313
  if(seqArray[i][0] != 0) {
55268
- seqArray[i][0] - (i + 1);
55314
+ offset = seqArray[i][0] - (i + 1);
55269
55315
  break;
55270
55316
  }
55271
55317
  }
55272
55318
  }
55273
55319
 
55274
- let prevResi = 0;
55320
+ //let prevResi = 0;
55321
+ let prevResi = offset;
55275
55322
  for(let i = 0, il = seqArray.length; i < il; ++i) {
55276
55323
  let seqName, resiPos;
55277
55324
  // mmdbid: ["0","R","ARG"],["502","V","VAL"]; mmcifid: [1, "ARG"]; align: ["0","R","ARG"] //align: [1, "0","R","ARG"]
@@ -56160,6 +56207,7 @@ class LoadAtomData {
56160
56207
  let CSerial, prevCSerial, OSerial, prevOSerial;
56161
56208
 
56162
56209
  let biopolymerChainsHash = {};
56210
+
56163
56211
  for(let i in atoms) {
56164
56212
  ++serial;
56165
56213
 
@@ -56189,21 +56237,21 @@ class LoadAtomData {
56189
56237
  atm.chain = ic.molid2chain[molid].substr(pos + 1);
56190
56238
  }
56191
56239
  else {
56192
- let miscName = 'Misc';
56240
+ let miscName = 'Misc';
56193
56241
 
56194
- //if(atm.resn != prevResn || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH' || atm.name == atm.elem) {
56195
- if((chainid2kind[chainNum] === 'protein' && chainid2kind[chainNum] === 'nucleotide' && atm.resi != prevResiOri)
56196
- ||(chainid2kind[chainNum] !== 'protein' && chainid2kind[chainNum] !== 'nucleotide'
56197
- &&(atm.resn.substr(0,3) != prevResn.substr(0,3) || atm.resi != prevResiOri || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH')) ) {
56198
- ++miscCnt;
56199
- }
56242
+ //if(atm.resn != prevResn || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH' || atm.name == atm.elem) {
56243
+ if((chainid2kind[chainNum] === 'protein' && chainid2kind[chainNum] === 'nucleotide' && atm.resi != prevResiOri)
56244
+ ||(chainid2kind[chainNum] !== 'protein' && chainid2kind[chainNum] !== 'nucleotide'
56245
+ &&(atm.resn.substr(0,3) != prevResn.substr(0,3) || atm.resi != prevResiOri || chainid2kind[chainNum] === 'solvent' || atm.resn === 'HOH')) ) {
56246
+ ++miscCnt;
56247
+ }
56200
56248
 
56201
- atm.resi_ori = atm.resi;
56202
- atm.resi = miscCnt;
56203
- bSetResi = true;
56249
+ atm.resi_ori = atm.resi;
56250
+ atm.resi = miscCnt;
56251
+ bSetResi = true;
56204
56252
 
56205
- //if all are defined in the chain section, no "Misc" should appear
56206
- atm.chain = miscName;
56253
+ //if all are defined in the chain section, no "Misc" should appear
56254
+ atm.chain = miscName;
56207
56255
  }
56208
56256
 
56209
56257
  //if(ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t && alignType === 'query') {
@@ -57222,7 +57270,8 @@ class SetSeqAlign {
57222
57270
 
57223
57271
  if(ic.chainsSeq[chainid1] === undefined || ic.chainsSeq[chainid1][j] === undefined) break;
57224
57272
 
57225
- let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
57273
+ //let resi = this.getResiAferAlign(chainid1, bRealign, j + 1);
57274
+ let resi = this.getResiAferAlign(chainid1, bRealign, j);
57226
57275
  // let resn = (bRealign && me.cfg.aligntool == 'tmalign') ? this.getResnFromResi(chainid1, j).toLowerCase() : ic.chainsSeq[chainid1][j].name.toLowerCase();
57227
57276
  let resn = this.getResnFromResi(chainid1, resi).toLowerCase();
57228
57277
 
@@ -57243,11 +57292,11 @@ class SetSeqAlign {
57243
57292
 
57244
57293
  if(ic.chainsSeq[chainid2] === undefined || ic.chainsSeq[chainid2] === undefined) break;
57245
57294
 
57246
- let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
57295
+ //let resi = this.getResiAferAlign(chainid2, bRealign, j + 1);
57296
+ let resi = this.getResiAferAlign(chainid2, bRealign, j);
57247
57297
  // let resn = (bRealign && me.cfg.aligntool == 'tmalign') ? this.getResnFromResi(chainid2, j).toLowerCase() : ic.chainsSeq[chainid2][j].name.toLowerCase();
57248
57298
  let resn = this.getResnFromResi(chainid2, resi).toLowerCase();
57249
57299
 
57250
-
57251
57300
  if(resn == '?') continue;
57252
57301
 
57253
57302
  color = me.htmlCls.GREY8;
@@ -57788,7 +57837,6 @@ class SetSeqAlign {
57788
57837
  start1Pos = start1;
57789
57838
  end1Pos = end1;
57790
57839
  }
57791
-
57792
57840
  //let range = resi2range_t[resiStart1];
57793
57841
 
57794
57842
  // if the mapping does not start from start_t, add gaps to the query seq
@@ -57812,7 +57860,7 @@ class SetSeqAlign {
57812
57860
  pos2 = result.pos2;
57813
57861
  let notAlnLen1 = pos2 - (pos1 + 1);
57814
57862
  let notAlnLen2 = start2 - (prevIndex2 + 1);
57815
-
57863
+
57816
57864
  // insert non-aligned residues in query seq
57817
57865
  this.insertNotAlignRes(chainid2, prevIndex2+1, notAlnLen2, bRealign);
57818
57866
 
@@ -58654,10 +58702,7 @@ class LoadPDB {
58654
58702
 
58655
58703
  if(ic.atoms[oriSerial2NewSerial[from]] !== undefined) ic.atoms[oriSerial2NewSerial[from]].bonds.push(oriSerial2NewSerial[to]);
58656
58704
  }
58657
- } else if (record.substr(0,3) === 'TER') {
58658
- // Concatenation of two pdbs will have several atoms for the same serial
58659
- ++serial;
58660
- }
58705
+ } else if (record.substr(0,3) === 'TER') ;
58661
58706
  }
58662
58707
 
58663
58708
  // add the last residue set
@@ -60231,24 +60276,28 @@ class ApplyCommand {
60231
60276
  else if(command == 'rotate left') {
60232
60277
  ic.bStopRotate = false;
60233
60278
  ic.ROT_DIR = 'left';
60279
+ ic.transformCls.rotateCountMax = 6000;
60234
60280
 
60235
60281
  ic.resizeCanvasCls.rotStruc('left');
60236
60282
  }
60237
60283
  else if(command == 'rotate right') {
60238
60284
  ic.bStopRotate = false;
60239
60285
  ic.ROT_DIR = 'right';
60286
+ ic.transformCls.rotateCountMax = 6000;
60240
60287
 
60241
60288
  ic.resizeCanvasCls.rotStruc('right');
60242
60289
  }
60243
60290
  else if(command == 'rotate up') {
60244
60291
  ic.bStopRotate = false;
60245
60292
  ic.ROT_DIR = 'up';
60293
+ ic.transformCls.rotateCountMax = 6000;
60246
60294
 
60247
60295
  ic.resizeCanvasCls.rotStruc('up');
60248
60296
  }
60249
60297
  else if(command == 'rotate down') {
60250
60298
  ic.bStopRotate = false;
60251
60299
  ic.ROT_DIR = 'down';
60300
+ ic.transformCls.rotateCountMax = 6000;
60252
60301
 
60253
60302
  ic.resizeCanvasCls.rotStruc('down');
60254
60303
  }
@@ -62793,8 +62842,10 @@ class LoadScript {
62793
62842
  let id = loadStr.substr(loadStr.lastIndexOf(' ') + 1);
62794
62843
  if(id.length == 4) id = id.toUpperCase();
62795
62844
 
62796
- // skip loading the structure if it was loaded before
62797
- if(ic.structures && ic.structures.hasOwnProperty(id)) return;
62845
+ // skip loading the structure if
62846
+ // 1. PDB was in the iCn3D PNG Image file
62847
+ // 2. it was loaded before
62848
+ if(ic.bInputPNGWithData || (ic.structures && ic.structures.hasOwnProperty(id))) return;
62798
62849
 
62799
62850
  ic.inputid = id;
62800
62851
  if(command.indexOf('load mmtf') !== -1) {
@@ -64947,7 +64998,8 @@ class Delphi {
64947
64998
  let pdbstr = '';
64948
64999
  /// pdbstr += ic.saveFileCls.getPDBHeader();
64949
65000
 
64950
- pdbstr +=(me.cfg.cid) ? ic.saveFileCls.getAtomPDB(atomHash, true) : ic.saveFileCls.getAtomPDB(atomHash);
65001
+ let bMergeIntoOne = true;
65002
+ pdbstr +=(me.cfg.cid) ? ic.saveFileCls.getAtomPDB(atomHash, true, undefined, undefined, undefined, undefined, bMergeIntoOne) : ic.saveFileCls.getAtomPDB(atomHash, undefined, undefined, undefined, undefined, undefined, bMergeIntoOne);
64951
65003
  pdbstr += ic.saveFileCls.getAtomPDB(ionHash, true, undefined, true);
64952
65004
 
64953
65005
  return pdbstr;
@@ -65920,7 +65972,8 @@ console.log("free energy: " + energy + " kcal/mol");
65920
65972
  }
65921
65973
  else {
65922
65974
  let atoms = me.hashUtilsCls.intHash(ic.dAtoms, ic.hAtoms);
65923
- pdbStr = ic.saveFileCls.getAtomPDB(atoms);
65975
+ let bMergeIntoOne = true;
65976
+ pdbStr = ic.saveFileCls.getAtomPDB(atoms, undefined, undefined, undefined, undefined, undefined, bMergeIntoOne);
65924
65977
  }
65925
65978
 
65926
65979
  let url = me.htmlCls.baseUrl + "scap/scap.cgi";
@@ -69841,7 +69894,7 @@ class SaveFile {
69841
69894
  }
69842
69895
 
69843
69896
  //getAtomPDB: function(atomHash, bPqr, bPdb, bNoChem) { let ic = this.icn3d, me = ic.icn3dui;
69844
- getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader, chainResi2pdb, pdbid) { let ic = this.icn3d, me = ic.icn3dui;
69897
+ getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader, chainResi2pdb, pdbid, bMergeIntoOne) { let ic = this.icn3d, me = ic.icn3dui;
69845
69898
  let pdbStr = '';
69846
69899
 
69847
69900
  // get all phosphate groups in lipids
@@ -69994,6 +70047,7 @@ class SaveFile {
69994
70047
  let bMulStruc =(struArray.length > 1) ? true : false;
69995
70048
 
69996
70049
  let molNum = 1, prevStru = '', prevChain = '';
70050
+ let chainIndex = 0, fakeChain = '', chainNameArray = 'abcdefghijklmnopqrstuvwxyz0123456789';
69997
70051
 
69998
70052
  let addedChainResiHash = {};
69999
70053
  for(let i in atomHash) {
@@ -70004,20 +70058,22 @@ class SaveFile {
70004
70058
 
70005
70059
  //if(bMulStruc && atom.structure != prevStru) {
70006
70060
  if(atom.structure != prevStru) {
70007
- pdbStr += connStr;
70008
- connStr = '';
70061
+ if(!bMergeIntoOne || !bMulStruc) {
70062
+ pdbStr += connStr;
70063
+ connStr = '';
70009
70064
 
70010
- if(molNum > 1) pdbStr += '\nENDMDL\n';
70065
+ if(molNum > 1) pdbStr += '\nENDMDL\n';
70011
70066
 
70012
- if(bMulStruc) pdbStr += 'MODEL ' + molNum + '\n';
70067
+ if(bMulStruc) pdbStr += 'MODEL ' + molNum + '\n';
70068
+ }
70013
70069
 
70014
70070
  // add header
70015
70071
  let mutantInfo = (chainResi2pdb) ? "Mutated chain_residue " + Object.keys(chainResi2pdb) + '; ' : '';
70016
70072
  if(!bNoHeader) {
70017
70073
  //pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo, pdbid);
70018
70074
 
70019
- // make sur ethe PDB ID is correct
70020
- pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo, atom.structure);
70075
+ // make sure the PDB ID is correct
70076
+ if(!bMergeIntoOne || !bMulStruc) pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo, atom.structure);
70021
70077
 
70022
70078
  //pdbStr += '\n'; // separate from incomplete secondary structures
70023
70079
  }
@@ -70025,6 +70081,7 @@ class SaveFile {
70025
70081
  //prevStru = atom.structure;
70026
70082
  ++molNum;
70027
70083
  }
70084
+
70028
70085
  //else {
70029
70086
  //if(atom.chain != prevChain) {
70030
70087
  if(atom.chain != prevChain && atom.structure == prevStru) {
@@ -70098,17 +70155,28 @@ class SaveFile {
70098
70155
  */
70099
70156
 
70100
70157
  line +=(resn.length <= 3) ? resn.padStart(3, ' ') : resn.substr(0, 3);
70101
- //line += ' ';
70102
- //line +=(atom.chain.length <= 1) ? atom.chain.padStart(1, ' ') : atom.chain.substr(0, 1);
70103
- if(atom.chain.length >= 2) {
70104
- let chainTmp = atom.chain.replace(/_/gi, '').substr(0, 2);
70105
- line += chainTmp;
70106
- }
70107
- else if(atom.chain.length == 1) {
70108
- line += ' ' + atom.chain.substr(0, 1);
70158
+
70159
+ if(bMergeIntoOne && molNum > 2 && (ic.proteins.hasOwnProperty(atom.serial) || ic.nucleotides.hasOwnProperty(atom.serial))) {
70160
+ if(atom.structure != prevStru || atom.chain != prevChain) {
70161
+ fakeChain = (chainIndex < 36) ? chainNameArray[chainIndex] : '?';
70162
+ ++chainIndex;
70163
+ }
70164
+
70165
+ line += ' ' + fakeChain;
70109
70166
  }
70110
- else if(atom.chain.length == 0) {
70111
- line += ' A';
70167
+ else {
70168
+ //line += ' ';
70169
+ //line +=(atom.chain.length <= 1) ? atom.chain.padStart(1, ' ') : atom.chain.substr(0, 1);
70170
+ if(atom.chain.length >= 2) {
70171
+ let chainTmp = atom.chain.replace(/_/gi, '').substr(0, 2);
70172
+ line += chainTmp;
70173
+ }
70174
+ else if(atom.chain.length == 1) {
70175
+ line += ' ' + atom.chain.substr(0, 1);
70176
+ }
70177
+ else if(atom.chain.length == 0) {
70178
+ line += ' A';
70179
+ }
70112
70180
  }
70113
70181
 
70114
70182
  let resi = atom.resi;
@@ -70204,9 +70272,11 @@ class SaveFile {
70204
70272
  prevChain = atom.chain;
70205
70273
  }
70206
70274
 
70207
- pdbStr += connStr;
70208
-
70209
- if(bMulStruc) pdbStr += '\nENDMDL\n';
70275
+ if(!bMergeIntoOne || !bMulStruc) {
70276
+ pdbStr += connStr;
70277
+
70278
+ if(bMulStruc) pdbStr += '\nENDMDL\n';
70279
+ }
70210
70280
 
70211
70281
  return pdbStr;
70212
70282
  }
@@ -71941,7 +72011,7 @@ class Control {
71941
72011
  ic.typetext = false;
71942
72012
  });
71943
72013
 
71944
- $(document).bind('keydown', function (e) {
72014
+ $(document).bind('keydown', async function (e) {
71945
72015
  //document.addEventListener('keydown', function (e) {
71946
72016
  if(e.shiftKey || e.keyCode === 16) {
71947
72017
  ic.bShift = true;
@@ -72079,7 +72149,7 @@ class Control {
72079
72149
 
72080
72150
  else if(e.keyCode === 65 ) { // A, alternate
72081
72151
  if(Object.keys(ic.structures).length > 1) {
72082
- ic.alternateCls.alternateWrapper();
72152
+ await ic.alternateCls.alternateWrapper();
72083
72153
  }
72084
72154
  }
72085
72155
 
@@ -73691,7 +73761,7 @@ class iCn3DUI {
73691
73761
  //even when multiple iCn3D viewers are shown together.
73692
73762
  this.pre = this.cfg.divid + "_";
73693
73763
 
73694
- this.REVISION = '3.28.3';
73764
+ this.REVISION = '3.28.4';
73695
73765
 
73696
73766
  // In nodejs, iCn3D defines "window = {navigator: {}}"
73697
73767
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -73898,16 +73968,17 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
73898
73968
  }
73899
73969
  }
73900
73970
 
73901
- // realign
73902
- ic.chainidArray = [chain_t].concat(chainidArray);
73903
- ic.chainidArray = ic.chainalignParserCls.addPostfixForChainids(ic.chainidArray);
73904
-
73971
+ // get the matched structures, do not include the template
73905
73972
  let mmdbafid = '';
73906
- for(let i = 0, il = ic.chainidArray.length; i < il; ++i) {
73973
+ for(let i = 0, il = chainidArray.length; i < il; ++i) {
73907
73974
  if(i > 0) mmdbafid += ',';
73908
- mmdbafid += ic.chainidArray[i].substr(0, ic.chainidArray[i].indexOf('_'));
73975
+ mmdbafid += chainidArray[i].substr(0, chainidArray[i].indexOf('_'));
73909
73976
  }
73910
73977
 
73978
+ // realign, include the template
73979
+ ic.chainidArray = [chain_t].concat(chainidArray);
73980
+ ic.chainidArray = ic.chainalignParserCls.addPostfixForChainids(ic.chainidArray);
73981
+
73911
73982
  me.htmlCls.clickMenuCls.setLogCmd('resdef ' + me.cfg.resdef, true);
73912
73983
 
73913
73984
  ic.loadCmd = 'vast_search_chainid ' + ic.chainidArray;
@@ -74123,7 +74194,7 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
74123
74194
  // ic.bNCBI = true;
74124
74195
 
74125
74196
  // remove space
74126
- me.cfg.mmdbafid = me.cfg.mmdbafid.replace(/\s+/g, '');
74197
+ me.cfg.mmdbafid = me.cfg.mmdbafid.replace(/\s+/g, '').toUpperCase();
74127
74198
 
74128
74199
  ic.bMmdbafid = true;
74129
74200
  ic.inputid = me.cfg.mmdbafid;