icn3d 3.29.5 → 3.29.7

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
@@ -8512,6 +8512,13 @@ class ClickMenu {
8512
8512
  //}
8513
8513
  });
8514
8514
 
8515
+ $(document).on("click", "#" + me.pre + "mn2_translate", function(e) { me.icn3d; //e.preventDefault();
8516
+ me.htmlCls.dialogCls.openDlg('dl_translate', 'Translate the X,Y,Z coordinates of the structure');
8517
+ });
8518
+
8519
+ $(document).on("click", "#" + me.pre + "mn2_matrix", function(e) { me.icn3d; //e.preventDefault();
8520
+ me.htmlCls.dialogCls.openDlg('dl_matrix', 'Apply matrix to the X,Y,Z coordinates of the structure');
8521
+ });
8515
8522
 
8516
8523
  $(document).on("click", "." + me.pre + "mn6_rotate", function(e) { let ic = me.icn3d; //e.preventDefault();
8517
8524
  let value = $(this).attr('v').toLowerCase();
@@ -8527,7 +8534,7 @@ class ClickMenu {
8527
8534
 
8528
8535
  $(document).on("click", "." + me.pre + "mn6_rotate90", function(e) { let ic = me.icn3d; //e.preventDefault();
8529
8536
  let value = $(this).attr('v').toLowerCase();
8530
- let direction = value.split('-')[0];
8537
+ let direction = value.split(' ')[1];
8531
8538
 
8532
8539
  thisClass.setLogCmd(value, true);
8533
8540
  let axis;
@@ -9795,6 +9802,9 @@ class SetMenu {
9795
9802
  html += "</ul>";
9796
9803
  html += "</li>";
9797
9804
 
9805
+ html += this.getLink('mn2_translate', 'Translate XYZ', undefined, 1);
9806
+ html += this.getLink('mn2_matrix', 'Rotate with Matrix', undefined, 1);
9807
+
9798
9808
  html += this.getMenuText('mn2_camera', 'Camera', undefined, undefined, 1);
9799
9809
  html += "<ul>";
9800
9810
  html += this.getRadio('mn6_camera', 'mn6_cameraPers', 'Perspective', true, undefined, 2);
@@ -12756,6 +12766,39 @@ class SetDialog {
12756
12766
  html += this.addNotebookTitle('dl_disttable', 'Distance Table', true);
12757
12767
  html += "</div>";
12758
12768
 
12769
+ html += me.htmlCls.divStr + "dl_translate' class='" + dialogClass + "'>";
12770
+ html += this.addNotebookTitle('dl_translate', 'Translate the X,Y,Z coordinates of the structure');
12771
+ html += "X: " + me.htmlCls.inputTextStr + "id='" + me.pre + "translateX' value='' size=4> ";
12772
+ html += "Y: " + me.htmlCls.inputTextStr + "id='" + me.pre + "translateY' value='' size=4> ";
12773
+ html += "Z: " + me.htmlCls.inputTextStr + "id='" + me.pre + "translateZ' value='' size=4> ";
12774
+ html += me.htmlCls.buttonStr + "translate_pdb'>Translate</button>";
12775
+ html += "</div>";
12776
+
12777
+ html += me.htmlCls.divStr + "dl_matrix' class='" + dialogClass + "'>";
12778
+ html += this.addNotebookTitle('dl_matrix', 'Apply matrix to the X,Y,Z coordinates of the structure');
12779
+ html += "0: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix0' value='1' size=2> ";
12780
+ html += "4: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix4' value='0' size=2> ";
12781
+ html += "8: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix8' value='0' size=2> ";
12782
+ html += "12: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix12' value='0' size=2><br>";
12783
+
12784
+ html += "1: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix1' value='0' size=2> ";
12785
+ html += "5: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix5' value='1' size=2> ";
12786
+ html += "9: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix9' value='0' size=2> ";
12787
+ html += "13: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix13' value='0' size=2><br>";
12788
+
12789
+ html += "2: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix2' value='0' size=2> ";
12790
+ html += "6: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix6' value='0' size=2> ";
12791
+ html += "10: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix10' value='1' size=2> ";
12792
+ html += "14: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix14' value='0' size=2><br>";
12793
+
12794
+ html += "3: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix3' value='0' size=2> ";
12795
+ html += "7: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix7' value='0' size=2> ";
12796
+ html += "11: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix11' value='0' size=2> ";
12797
+ html += "15: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix15' value='1' size=2><br>";
12798
+
12799
+ html += me.htmlCls.buttonStr + "matrix_pdb'>Rotate with Matrix</button>";
12800
+ html += "</div>";
12801
+
12759
12802
  html += me.htmlCls.divStr + "dl_igrefTpl' class='" + dialogClass + "'>";
12760
12803
  html += this.addNotebookTitle('dl_igrefTpl', 'Choose an Ig template');
12761
12804
  html += "<span style='white-space:nowrap;font-weight:bold;'>Choose an Ig template for selected residues:</span> <br><br><select id='" + me.pre + "igrefTpl'>";
@@ -13481,6 +13524,33 @@ class Events {
13481
13524
  window.open(hostUrl + '?pdbid=' + $("#" + me.pre + "pdbid").val(), urlTarget);
13482
13525
  });
13483
13526
 
13527
+ me.myEventCls.onIds("#" + me.pre + "translate_pdb", "click", function(e) { let ic = me.icn3d;
13528
+ e.preventDefault();
13529
+ if(!me.cfg.notebook) dialog.dialog( "close" );
13530
+ let dx = $("#" + me.pre + "translateX").val();
13531
+ let dy = $("#" + me.pre + "translateY").val();
13532
+ let dz = $("#" + me.pre + "translateZ").val();
13533
+
13534
+ ic.transformCls.translateCoord(ic.hAtoms, parseFloat(dx), parseFloat(dy), parseFloat(dz));
13535
+ ic.drawCls.draw();
13536
+
13537
+ thisClass.setLogCmd("translate pdb " + dx + " " + dy + " " + dz, true);
13538
+ });
13539
+
13540
+ me.myEventCls.onIds("#" + me.pre + "matrix_pdb", "click", function(e) { let ic = me.icn3d;
13541
+ e.preventDefault();
13542
+ if(!me.cfg.notebook) dialog.dialog( "close" );
13543
+ let mArray = [];
13544
+ for(let i = 0; i< 16; ++i) {
13545
+ mArray.push(parseFloat($("#" + me.pre + "matrix" + i).val()));
13546
+ }
13547
+
13548
+ ic.transformCls.rotateCoord(ic.hAtoms, mArray);
13549
+ ic.drawCls.draw();
13550
+
13551
+ thisClass.setLogCmd("rotate pdb " + mArray, true);
13552
+ });
13553
+
13484
13554
  me.myEventCls.onIds("#" + me.pre + "pdbid", "keyup", function(e) { let ic = me.icn3d;
13485
13555
  if (e.keyCode === 13) {
13486
13556
  e.preventDefault();
@@ -36043,6 +36113,7 @@ class SetColor {
36043
36113
  break;
36044
36114
 
36045
36115
  case 'secondary structure green':
36116
+ case 'secondary structure':
36046
36117
  ic.sheetcolor = 'green';
36047
36118
  for (let i in atoms) {
36048
36119
  let atom = ic.atoms[i];
@@ -36055,7 +36126,7 @@ class SetColor {
36055
36126
  break;
36056
36127
 
36057
36128
  case 'secondary structure yellow':
36058
- case 'secondary structure':
36129
+ //case 'secondary structure':
36059
36130
  ic.sheetcolor = 'yellow';
36060
36131
  for (let i in atoms) {
36061
36132
  let atom = ic.atoms[i];
@@ -40161,6 +40232,7 @@ class Domain3d {
40161
40232
  substructItem.z2 = atom.coord.z;
40162
40233
 
40163
40234
  substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
40235
+
40164
40236
  substruct.push(substructItem);
40165
40237
  substructItem = {};
40166
40238
  }
@@ -41146,14 +41218,16 @@ class AddTrack {
41146
41218
 
41147
41219
  html += '<span id="' + pre + '_' + ic.pre + chnid + '_' + pos + '" title="' + c + pos + '" class="icn3d-residue" ' + tmpStr + '>' + c + '</span>';
41148
41220
 
41149
- let tmpStrExon = 'style="background-color:' + pos2exonColor[cnt] + '"';
41150
- htmlExon += '<span id="' + pre + '_' + ic.pre + chnid + '_' + pos + '" title="' + c + pos + ', Exon ' + (pos2exonIndex[cnt] + 1) + ': ' + pos2genome[cnt] + '" class="icn3d-residue" ' + tmpStrExon + '>&nbsp;</span>';
41221
+ if(exonArray) {
41222
+ let tmpStrExon = 'style="background-color:' + pos2exonColor[cnt] + '"';
41223
+ htmlExon += '<span id="' + pre + '_' + ic.pre + chnid + '_' + pos + '" title="' + c + pos + ', Exon ' + (pos2exonIndex[cnt] + 1) + ': ' + pos2genome[cnt] + '" class="icn3d-residue" ' + tmpStrExon + '>&nbsp;</span>';
41151
41224
 
41152
- // set atom color
41153
- for(let serial in ic.residues[chnid + '_' + pos]) {
41154
- let atom = ic.atoms[serial];
41155
- atom.color = me.parasCls.thr(pos2exonColor[cnt]);
41156
- ic.atomPrevColors[serial] = atom.color;
41225
+ // set atom color
41226
+ for(let serial in ic.residues[chnid + '_' + pos]) {
41227
+ let atom = ic.atoms[serial];
41228
+ atom.color = me.parasCls.thr(pos2exonColor[cnt]);
41229
+ ic.atomPrevColors[serial] = atom.color;
41230
+ }
41157
41231
  }
41158
41232
 
41159
41233
  htmlTmp2 += ic.showSeqCls.insertGapOverview(chnid, i);
@@ -43877,6 +43951,8 @@ class ShowSeq {
43877
43951
  giSeq = ic.giSeq[chnid];
43878
43952
  }
43879
43953
 
43954
+ if(!giSeq) return;
43955
+
43880
43956
  // remove null giSeq[i]
43881
43957
  let giSeqTmp = [];
43882
43958
  for(let i = 0, il = giSeq.length; i < il; ++i) {
@@ -43886,8 +43962,8 @@ class ShowSeq {
43886
43962
  }
43887
43963
  giSeq = giSeqTmp;
43888
43964
 
43889
- //let divLength = me.htmlCls.RESIDUE_WIDTH * ic.giSeq[chnid].length + 200;
43890
- let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
43965
+ //let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
43966
+ let divLength = me.htmlCls.RESIDUE_WIDTH * (giSeq.length + ic.nTotalGap) + 200;
43891
43967
 
43892
43968
  // let seqLength = ic.giSeq[chnid].length
43893
43969
  // if(seqLength > ic.maxAnnoLength) {
@@ -43907,7 +43983,7 @@ class ShowSeq {
43907
43983
  // html to display protein positions(10, 20, etc)
43908
43984
  //if(Object.keys(ic.chains[chnid]).length > 10) {
43909
43985
 
43910
- if(ic.giSeq[chnid].length > 10) {
43986
+ if(giSeq.length > 10) {
43911
43987
  htmlTmp = '<div class="icn3d-residueLine" style="white-space:nowrap;">';
43912
43988
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
43913
43989
  //if(ic.baseResi[chnid] != 0 &&(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.align !== undefined)) {
@@ -44269,7 +44345,7 @@ class ShowSeq {
44269
44345
  html3 += '</div>';
44270
44346
 
44271
44347
  //if(Object.keys(ic.chains[chnid]).length > 10) {
44272
- if(ic.giSeq[chnid].length > 10) {
44348
+ if(giSeq.length > 10) {
44273
44349
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
44274
44350
  //if(ic.baseResi[chnid] != 0 &&(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.align !== undefined)) {
44275
44351
  if((me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined || me.cfg.align !== undefined || me.cfg.chainalign !== undefined || me.cfg.mmdbafid !== undefined) && atom.resi_ori !== undefined && atom.resi_ori != atom.resi && chnid.indexOf('Misc') == -1 ) {
@@ -44456,12 +44532,12 @@ class ShowSeq {
44456
44532
  // reset ic.residIgLoop for the current selection, which could be the second round of ref num assignment
44457
44533
  // just current chain
44458
44534
  let atomHash = me.hashUtilsCls.intHash(ic.chains[chnid], ic.hAtoms);
44459
- let residHash = ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
44535
+ ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
44460
44536
 
44461
- for(let resid in residHash) {
44462
- // not in loop any more if you assign ref numbers multiple times
44463
- delete ic.residIgLoop[resid];
44464
- }
44537
+ // for(let resid in residHash) {
44538
+ // // not in loop any more if you assign ref numbers multiple times
44539
+ // delete ic.residIgLoop[resid];
44540
+ // }
44465
44541
  }
44466
44542
 
44467
44543
  // 1. get the range of each strand excluding loops
@@ -44591,6 +44667,76 @@ class ShowSeq {
44591
44667
  }
44592
44668
  }
44593
44669
 
44670
+ // 2b. extend the strand to end of sheet
44671
+ let maxExtend = 8;
44672
+ for(let i = 0, il = strandArray.length; i < il; ++i) {
44673
+ let startAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].startResi]);
44674
+ let endAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].endResi]);
44675
+
44676
+ let startPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].startResi);
44677
+ let endPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].endResi);
44678
+
44679
+ if(startAtom.ss == 'sheet' && !startAtom.ssbegin) {
44680
+ for(let j = 1; j <= maxExtend; ++j) {
44681
+ let currPos = startPos - j;
44682
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44683
+ if(i > 0 && parseInt(currResi) <= parseInt(strandArray[i-1].endResi)) break;
44684
+
44685
+ let currResid = chnid + '_' + currResi;
44686
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
44687
+ if(currAtom.ssbegin) { // find the start of the sheet
44688
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
44689
+ strandArray[i].startResi = currResi;
44690
+ strandArray[i].startRefnum -= j;
44691
+ strandArray[i].loopResCnt -= j;
44692
+ if(strandArray[i].loopResCnt < 0) strandArray[i].loopResCnt = 0;
44693
+ strandArray[i].resCntBfAnchor += j;
44694
+
44695
+ // update ic.resid2refnum
44696
+ for(let k = 1; k <= j; ++k) {
44697
+ currPos = startPos - k;
44698
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44699
+ let currResid = chnid + '_' + currResi;
44700
+ delete ic.residIgLoop[currResid];
44701
+ }
44702
+
44703
+ break;
44704
+ }
44705
+ }
44706
+ }
44707
+
44708
+ if(endAtom.ss == 'sheet' && !endAtom.ssend) {
44709
+ for(let j = 1; j <= maxExtend; ++j) {
44710
+ let currPos = endPos + j;
44711
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44712
+ if(i < il - 1 && parseInt(currResi) >= parseInt(strandArray[i+1].startResi)) break;
44713
+
44714
+ let currResid = chnid + '_' + currResi;
44715
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
44716
+ if(currAtom.ssend) { // find the end of the sheet
44717
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
44718
+ strandArray[i].endResi = currResi;
44719
+ strandArray[i].endRefnum += j;
44720
+ if(i < il - 1) {
44721
+ strandArray[i + 1].loopResCnt -= j;
44722
+ if(strandArray[i + 1].loopResCnt < 0) strandArray[i + 1].loopResCnt = 0;
44723
+ }
44724
+ strandArray[i].resCntAtAnchor += j;
44725
+
44726
+ // update ic.residIgLoop[resid];
44727
+ for(let k = 1; k <= j; ++k) {
44728
+ currPos = endPos + k;
44729
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44730
+ let currResid = chnid + '_' + currResi;
44731
+ delete ic.residIgLoop[currResid];
44732
+ }
44733
+
44734
+ break;
44735
+ }
44736
+ }
44737
+ }
44738
+ }
44739
+
44594
44740
  // 3. assign refnumLabel for each resid
44595
44741
  strandCnt = 0;
44596
44742
  let loopCnt = 0;
@@ -46773,7 +46919,15 @@ class LineGraph {
46773
46919
 
46774
46920
  ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46775
46921
 
46776
- await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46922
+ let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46923
+ let numRound = 0;
46924
+
46925
+ //while(!bNoMoreIg) {
46926
+ while(!bNoMoreIg && numRound < 10) {
46927
+ let bRerun = true;
46928
+ bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun);
46929
+ ++numRound;
46930
+ }
46777
46931
  }
46778
46932
  else {
46779
46933
  await thisClass.parseRefPdbData(undefined, template);
@@ -46785,7 +46939,7 @@ class LineGraph {
46785
46939
  // }
46786
46940
  }
46787
46941
 
46788
- async parseRefPdbData(dataArray, template) { let ic = this.icn3d, me = ic.icn3dui;
46942
+ async parseRefPdbData(dataArray, template, bRerun) { let ic = this.icn3d, me = ic.icn3dui;
46789
46943
  let thisClass = this;
46790
46944
 
46791
46945
  let struArray = Object.keys(ic.structures);
@@ -46800,6 +46954,7 @@ class LineGraph {
46800
46954
  //ic.resid2domainid = {};
46801
46955
  ic.domainid2pdb = {};
46802
46956
 
46957
+ let bNoMoreIg = true;
46803
46958
  for(let i = 0, il = struArray.length; i < il; ++i) {
46804
46959
  let struct = struArray[i];
46805
46960
  let chainidArray = ic.structures[struct];
@@ -46807,12 +46962,14 @@ class LineGraph {
46807
46962
  for(let j = 0, jl = chainidArray.length; j < jl; ++j) {
46808
46963
  let chainid = chainidArray[j];
46809
46964
 
46810
- let domainAtomsArray = this.getDomainAtomsArray(chainid);
46811
-
46965
+ let domainAtomsArray = this.getDomainAtomsArray(chainid, bRerun);
46966
+
46812
46967
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
46813
46968
  if(!ic.domainid2score) ic.domainid2score = {};
46814
46969
 
46815
46970
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
46971
+ bNoMoreIg = false;
46972
+
46816
46973
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
46817
46974
  //let bForceOneDomain = true;
46818
46975
  //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
@@ -46913,6 +47070,8 @@ class LineGraph {
46913
47070
 
46914
47071
  await thisClass.parseAlignData(dataArray3, domainidpairArray3);
46915
47072
  }
47073
+
47074
+ return bNoMoreIg;
46916
47075
  /*
46917
47076
  }
46918
47077
  catch(err) {
@@ -46929,10 +47088,12 @@ class LineGraph {
46929
47088
  */
46930
47089
  }
46931
47090
 
46932
- getDomainAtomsArray(chainid) { let ic = this.icn3d, me = ic.icn3dui;
47091
+ getDomainAtomsArray(chainid, bRerunDomain) { let ic = this.icn3d, me = ic.icn3dui;
46933
47092
  let domainAtomsArray = [];
46934
47093
 
46935
- let minResidues = 20;
47094
+ let minResidues = 20, minAtoms = 200;
47095
+
47096
+ if(!ic.chainid2atomsLeft) ic.chainid2atomsLeft = {};
46936
47097
 
46937
47098
  if(!ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]).serial)
46938
47099
  && !ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getMiddleAtomObj(ic.chains[chainid]).serial)) return domainAtomsArray;
@@ -46941,18 +47102,37 @@ class LineGraph {
46941
47102
  let currAtoms = me.hashUtilsCls.intHash(ic.chains[chainid], ic.hAtoms);
46942
47103
  if(Object.keys(currAtoms).length == 0) return domainAtomsArray;
46943
47104
 
47105
+ if(bRerunDomain) {
47106
+ let atomsAssigned = {};
47107
+ for(let resid in ic.resid2refnum_ori) {
47108
+ atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
47109
+ }
47110
+ // for(let resid in ic.resid2refnum) {
47111
+ // if(ic.resid2refnum[resid]) atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
47112
+ // }
47113
+
47114
+ currAtoms = me.hashUtilsCls.exclHash(currAtoms, atomsAssigned);
47115
+
47116
+ // no need to rerun the rest residues any more
47117
+ if(ic.chainid2atomsLeft[chainid] == Object.keys(currAtoms).length) {
47118
+ return domainAtomsArray;
47119
+ }
47120
+
47121
+ ic.chainid2atomsLeft[chainid] = Object.keys(currAtoms).length;
47122
+
47123
+ if(Object.keys(currAtoms).length < minAtoms) return domainAtomsArray;
47124
+ }
47125
+
46944
47126
  // align each 3D domain with reference structure
46945
47127
  //let result = ic.domain3dCls.c2b_NewSplitChain(ic.chains[chainid]);
46946
47128
  // assign ref numbers to selected residues
46947
- let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms);
47129
+ let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
46948
47130
  let subdomains = result.subdomains;
46949
47131
  let pos2resi = result.pos2resi;
46950
47132
 
46951
47133
  if(subdomains.length <= 1) {
46952
- //domainAtomsArray.push(ic.chains[chainid]);
46953
- domainAtomsArray.push(currAtoms);
46954
-
46955
47134
  let residueArray = ic.resid2specCls.atoms2residues(Object.keys(currAtoms));
47135
+ if(residueArray.length < minResidues) return domainAtomsArray;
46956
47136
 
46957
47137
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(currAtoms);
46958
47138
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(currAtoms);
@@ -46963,31 +47143,41 @@ class LineGraph {
46963
47143
  ic.resid2domainid[resid] = chainid + '-0' + '_' + resiSum;
46964
47144
 
46965
47145
  // clear previous refnum assignment if any
46966
- if(ic.resid2refnum && ic.resid2refnum[resid]) {
47146
+ // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
47147
+ // if(ic.resid2refnum && ic.resid2refnum[resid]) {
46967
47148
  delete ic.resid2refnum[resid];
46968
- }
47149
+ delete ic.residIgLoop[resid];
47150
+ // }
46969
47151
  }
47152
+
47153
+ domainAtomsArray.push(currAtoms);
46970
47154
  }
46971
47155
  else {
46972
47156
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
46973
47157
  let domainAtoms = {};
46974
47158
  let segArray = subdomains[k];
46975
47159
 
47160
+ let resCnt = 0;
46976
47161
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
46977
47162
  let startResi = segArray[m];
46978
47163
  let endResi = segArray[m+1];
46979
47164
  for(let n = parseInt(startResi); n <= parseInt(endResi); ++n) {
46980
47165
  let resid = chainid + '_' + pos2resi[n];
47166
+ ++resCnt;
46981
47167
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
46982
47168
  //ic.resid2domainid[resid] = chainid + '-' + k;
46983
47169
 
46984
47170
  // clear previous refnum assignment if any
46985
- if(ic.resid2refnum && ic.resid2refnum[resid]) {
47171
+ // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
47172
+ // if(ic.resid2refnum && ic.resid2refnum[resid]) {
46986
47173
  delete ic.resid2refnum[resid];
46987
- }
47174
+ delete ic.residIgLoop[resid];
47175
+ // }
46988
47176
  }
46989
47177
  }
46990
47178
 
47179
+ if(resCnt < minResidues) continue;
47180
+
46991
47181
  domainAtomsArray.push(domainAtoms);
46992
47182
 
46993
47183
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtoms);
@@ -47072,12 +47262,14 @@ class LineGraph {
47072
47262
 
47073
47263
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
47074
47264
  //let queryData = (me.bNode) ? dataArray[i] : dataArray[i].value; //[0];
47075
- let queryData = dataArray[i].value; //[0];
47265
+ let queryData = (dataArray[i]) ? dataArray[i].value : undefined; //[0];
47076
47266
 
47077
47267
  if(!queryData || queryData.length == 0) {
47078
47268
  if(!me.bNode) console.log("The alignment data for " + domainidpairArray[i] + " is unavailable...");
47079
47269
  continue;
47080
47270
  }
47271
+
47272
+ if(queryData[0].score === undefined) continue;
47081
47273
 
47082
47274
  //let domainid_index = domainidpairArray[i].split(',');
47083
47275
  //let domainid = domainid_index[0];
@@ -47110,31 +47302,45 @@ class LineGraph {
47110
47302
 
47111
47303
  // Ig-like domains: B (2150, 2150a, 2150b), C (3150, 3250), E (7150, 7250), F (8150, 8250) strands
47112
47304
  // Ig domain may require G (7050). But we'll leave that out for now.
47113
- if(!bRound1) {
47305
+ if(!bRound1 && queryData[0].segs) {
47114
47306
  let bBstrand = false, bCstrand = false, bEstrand = false, bFstrand = false;
47115
- for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
47116
- let seg = queryData[0].segs[i];
47307
+ let bBSheet = true, bCSheet = true, bESheet = true, bFSheet = true;
47308
+ let chainid = domainid.split(',')[0];
47309
+
47310
+ for(let j = 0, jl = queryData[0].segs.length; j < jl; ++j) {
47311
+ let seg = queryData[0].segs[j];
47312
+ let resi = seg.t_start;
47313
+ let resid = chainid + '_' + resi;
47117
47314
 
47118
47315
  if(seg.q_start.indexOf('2550') != -1) {
47119
47316
  bBstrand = true;
47317
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47318
+ bBSheet = (atom.ss == 'sheet');
47120
47319
  }
47121
47320
  else if(seg.q_start.indexOf('3550') != -1) {
47122
47321
  bCstrand = true;
47322
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47323
+ bBSheet = (atom.ss == 'sheet');
47123
47324
  }
47124
47325
  else if(seg.q_start.indexOf('7550') != -1) {
47125
47326
  bEstrand = true;
47327
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47328
+ bBSheet = (atom.ss == 'sheet');
47126
47329
  }
47127
47330
  else if(seg.q_start.indexOf('8550') != -1) {
47128
47331
  bFstrand = true;
47332
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47333
+ bBSheet = (atom.ss == 'sheet');
47129
47334
  }
47130
47335
 
47131
47336
  //if(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand) break;
47132
47337
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
47133
47338
  }
47134
47339
 
47135
- //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
47136
- if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
47137
- if(!me.bNode) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
47340
+ if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
47341
+ //if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
47342
+ if(!me.bNode && !(bBstrand && bCstrand && bEstrand && bFstrand)) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
47343
+ if(!me.bNode && !(bBSheet && bCSheet && bESheet && bFSheet)) console.log("Some of the Ig strands B, C, E, F are not beta sheets...");
47138
47344
  if(ic.domainid2refpdbname[domainid] == refpdbname) {
47139
47345
  delete ic.domainid2refpdbname[domainid];
47140
47346
  delete ic.domainid2score[domainid];
@@ -47271,11 +47477,12 @@ class LineGraph {
47271
47477
 
47272
47478
  // assign ic.resid2refnum, ic.refnum2residArray, ic.chainsMapping
47273
47479
  if(!ic.resid2refnum) ic.resid2refnum = {};
47480
+ if(!ic.resid2refnum_ori) ic.resid2refnum_ori = {};
47274
47481
  if(!ic.refnum2residArray) ic.refnum2residArray = {};
47275
47482
  if(!ic.chainsMapping) ic.chainsMapping = {};
47276
47483
 
47277
47484
  if(!ic.refPdbList) ic.refPdbList = [];
47278
-
47485
+
47279
47486
  for(let chainid in chainid2segs) {
47280
47487
  let segArray = chainid2segs[chainid];
47281
47488
 
@@ -47294,10 +47501,79 @@ class LineGraph {
47294
47501
  }
47295
47502
  ic.refPdbList.push(message);
47296
47503
 
47297
- let prevStrand;
47298
- let bCd19 = refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
47504
+ // adjust C' and D strands ======start
47505
+ let bCstrand = false, bCpstrand = false, bCppstrand = false, bDstrand = false, bEstrand = false;
47506
+ let CAtom, CpAtom, DAtom, EAtom;
47507
+ //let chainid = domainid.split(',')[0];
47508
+
47509
+ let cntBtwCE;
47510
+ let CpToDResi = [], DToCpResi = [];
47299
47511
  for(let i = 0, il = segArray.length; i < il; ++i) {
47300
47512
  let seg = segArray[i];
47513
+ if(!seg) continue;
47514
+
47515
+ let resi = seg.t_start;
47516
+ let resid = chainid + '_' + resi;
47517
+
47518
+ if(seg.q_start.indexOf('3550') != -1) {
47519
+ bCstrand = true;
47520
+ CAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
47521
+
47522
+ // a chain could have multiple Ig domains
47523
+ cntBtwCE = 0;
47524
+ }
47525
+ else if(seg.q_start.indexOf('4550') != -1) {
47526
+ bCpstrand = true;
47527
+ CpAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
47528
+ ++cntBtwCE;
47529
+ }
47530
+ // else if(seg.q_start.indexOf('5550') != -1) {
47531
+ // bCppstrand = true;
47532
+ // CppAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
47533
+ // ++cntBtwCE;
47534
+ // }
47535
+ else if(seg.q_start.indexOf('6550') != -1) {
47536
+ bDstrand = true;
47537
+ DAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
47538
+ ++cntBtwCE;
47539
+ }
47540
+ else if(seg.q_start.indexOf('7550') != -1) {
47541
+ bEstrand = true;
47542
+ EAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
47543
+
47544
+ // check C' and D strands
47545
+ if(cntBtwCE == 1) {
47546
+ let distToC = (bCpstrand) ? CpAtom.coord.distanceTo(CAtom.coord) : DAtom.coord.distanceTo(CAtom.coord);
47547
+ let distToE = (bCpstrand) ? CpAtom.coord.distanceTo(EAtom.coord) : DAtom.coord.distanceTo(EAtom.coord);
47548
+ distToC = parseInt(distToC);
47549
+ distToE = parseInt(distToE);
47550
+
47551
+ let resiDistToC = (bCpstrand) ? parseInt(CpAtom.resi) - parseInt(CAtom.resi) : parseInt(DAtom.resi) - parseInt(CAtom.resi);
47552
+ let resiDistToE = (bCpstrand) ? parseInt(EAtom.resi) - parseInt(CpAtom.resi) : parseInt(EAtom.resi) - parseInt(DAtom.resi);
47553
+
47554
+ if(bCpstrand) {
47555
+ if(distToC > distToE || (distToC == distToE && resiDistToC > resiDistToE)) { // rename C' to D
47556
+ CpToDResi.push(CpAtom.resi);
47557
+ }
47558
+ }
47559
+ else if(bDstrand) {
47560
+ if(distToC < distToE || (distToC == distToE && resiDistToC < resiDistToE)) { // rename D to C'
47561
+ DToCpResi.push(DAtom.resi);
47562
+ }
47563
+ }
47564
+ }
47565
+ }
47566
+
47567
+ if(bCstrand && bCpstrand && bCppstrand && bDstrand && bEstrand) break;
47568
+ }
47569
+
47570
+
47571
+ let currStrand;
47572
+ refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
47573
+ for(let i = 0, il = segArray.length; i < il; ++i) {
47574
+ let seg = segArray[i];
47575
+ if(!seg) continue;
47576
+
47301
47577
  let qStart = seg.q_start;
47302
47578
  parseInt(seg.q_start);
47303
47579
  if(isNaN(seg.q_start)) seg.q_start.substr(seg.q_start.length - 1, 1);
@@ -47314,10 +47590,33 @@ class LineGraph {
47314
47590
  //let refnum = qStart + postfix;
47315
47591
  let refnum = qStart;
47316
47592
 
47317
- let refnumLabel = this.getLabelFromRefnum(refnum, prevStrand, bCd19);
47318
- prevStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
47593
+ let refnumLabel = this.getLabelFromRefnum(refnum);
47594
+ currStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
47319
47595
 
47320
- ic.resid2refnum[resid] = refnumLabel;
47596
+ let currStrandFinal = currStrand;
47597
+ if(currStrand == "C'" && CpToDResi.length > 0) {
47598
+ for(let j = 0, jl = CpToDResi.length; j < jl; ++j) {
47599
+ if(parseInt(seg.t_start) < parseInt(CpToDResi[j]) + 10 && parseInt(seg.t_start) > parseInt(CpToDResi[j]) - 10 ) {
47600
+ currStrandFinal = "D";
47601
+ break;
47602
+ }
47603
+ }
47604
+ }
47605
+ else if(currStrand == "D" && DToCpResi.length > 0) {
47606
+ for(let j = 0, jl = DToCpResi.length; j < jl; ++j) {
47607
+ if(parseInt(seg.t_start) < parseInt(DToCpResi[j]) + 10 && parseInt(seg.t_start) > parseInt(DToCpResi[j]) - 10 ) {
47608
+ currStrandFinal = "C'";
47609
+ break;
47610
+ }
47611
+ }
47612
+ }
47613
+
47614
+ if(currStrand != currStrandFinal) {
47615
+ refnumLabel = this.getLabelFromRefnum(refnum, currStrandFinal);
47616
+ }
47617
+
47618
+ ic.resid2refnum[resid] = refnumLabel;
47619
+ ic.resid2refnum_ori[resid] = refnumLabel;
47321
47620
 
47322
47621
  // final reference numbers will be assign in ic.showSeqCls.showRefNum()
47323
47622
 
@@ -47359,7 +47658,7 @@ class LineGraph {
47359
47658
  }
47360
47659
  }
47361
47660
 
47362
- getLabelFromRefnum(oriRefnum, prevStrand, bCd19) { let ic = this.icn3d; ic.icn3dui;
47661
+ getLabelFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
47363
47662
  let refnum = parseInt(oriRefnum);
47364
47663
 
47365
47664
  //N-terminus = 0999-0001
@@ -47386,28 +47685,34 @@ class LineGraph {
47386
47685
 
47387
47686
  // loops may have numbers such as 1310, 1410
47388
47687
 
47389
- if(refnum < 1000) return undefined;
47390
- else if(refnum >= 1200 && refnum < 1290) return "A---" + oriRefnum;
47391
- else if(refnum >= 1320 && refnum < 1390) return "A--" + oriRefnum;
47392
- else if(refnum >= 1420 && refnum < 1490) return "A-" + oriRefnum;
47393
- else if(refnum >= 1520 && refnum < 1590) return "A" + oriRefnum;
47394
- else if(refnum >= 1620 && refnum < 1690) return "A+" + oriRefnum;
47395
- else if(refnum >= 1820 && refnum < 1890) return "A'" + oriRefnum;
47396
- else if(refnum >= 2000 && refnum < 2900) return "B" + oriRefnum;
47397
- else if(refnum >= 3300 && refnum < 3390) return "C--" + oriRefnum;
47398
- else if(refnum >= 3420 && refnum < 3490) return "C-" + oriRefnum;
47399
- else if(refnum >= 3520 && refnum < 3590) return "C" + oriRefnum;
47400
- else if(refnum >= 4000 && refnum < 4900) return "C'" + oriRefnum;
47401
- else if(refnum >= 5000 && refnum < 5900) return "C''" + oriRefnum;
47402
- else if(refnum >= 6000 && refnum < 6900) return "D" + oriRefnum;
47403
- else if(refnum >= 7500 && refnum < 7590) return "E" + oriRefnum;
47404
- else if(refnum >= 7620 && refnum < 7900) return "E+" + oriRefnum;
47405
- else if(refnum >= 8000 && refnum < 8900) return "F" + oriRefnum;
47406
- else if(refnum >= 9500 && refnum < 9590) return "G" + oriRefnum;
47407
- else if(refnum >= 9620 && refnum < 9690) return "G+" + oriRefnum;
47408
- else if(refnum >= 9720 && refnum < 9790) return "G++" + oriRefnum;
47409
- else if(refnum > 9900) return undefined;
47410
- else return " " + oriRefnum; }
47688
+ let refnumLabel;
47689
+
47690
+ if(refnum < 1000) refnumLabel = undefined;
47691
+ else if(refnum >= 1200 && refnum < 1290) refnumLabel = "A---" + oriRefnum;
47692
+ else if(refnum >= 1320 && refnum < 1390) refnumLabel = "A--" + oriRefnum;
47693
+ else if(refnum >= 1420 && refnum < 1490) refnumLabel = "A-" + oriRefnum;
47694
+ else if(refnum >= 1520 && refnum < 1590) refnumLabel = "A" + oriRefnum;
47695
+ else if(refnum >= 1620 && refnum < 1690) refnumLabel = "A+" + oriRefnum;
47696
+ else if(refnum >= 1820 && refnum < 1890) refnumLabel = "A'" + oriRefnum;
47697
+ else if(refnum >= 2000 && refnum < 2900) refnumLabel = "B" + oriRefnum;
47698
+ else if(refnum >= 3300 && refnum < 3390) refnumLabel = "C--" + oriRefnum;
47699
+ else if(refnum >= 3420 && refnum < 3490) refnumLabel = "C-" + oriRefnum;
47700
+ else if(refnum >= 3520 && refnum < 3590) refnumLabel = "C" + oriRefnum;
47701
+ else if(refnum >= 4000 && refnum < 4900) refnumLabel = "C'" + oriRefnum;
47702
+ else if(refnum >= 5000 && refnum < 5900) refnumLabel = "C''" + oriRefnum;
47703
+ else if(refnum >= 6000 && refnum < 6900) refnumLabel = "D" + oriRefnum;
47704
+ else if(refnum >= 7500 && refnum < 7590) refnumLabel = "E" + oriRefnum;
47705
+ else if(refnum >= 7620 && refnum < 7900) refnumLabel = "E+" + oriRefnum;
47706
+ else if(refnum >= 8000 && refnum < 8900) refnumLabel = "F" + oriRefnum;
47707
+ else if(refnum >= 9500 && refnum < 9590) refnumLabel = "G" + oriRefnum;
47708
+ else if(refnum >= 9620 && refnum < 9690) refnumLabel = "G+" + oriRefnum;
47709
+ else if(refnum >= 9720 && refnum < 9790) refnumLabel = "G++" + oriRefnum;
47710
+ else if(refnum > 9900) refnumLabel = undefined;
47711
+ else refnumLabel = " " + oriRefnum;
47712
+ if(prevStrand) refnumLabel = prevStrand + oriRefnum;
47713
+
47714
+ return refnumLabel
47715
+ }
47411
47716
 
47412
47717
  async parseCustomRefFile(data) { let ic = this.icn3d; ic.icn3dui;
47413
47718
  ic.bShowCustomRefnum = true;
@@ -51543,7 +51848,7 @@ class Dsn6Parser {
51543
51848
  return sigma;
51544
51849
  }
51545
51850
 
51546
- loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51851
+ loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
51547
51852
  // DSN6 http://www.uoxray.uoregon.edu/tnt/manual/node104.html
51548
51853
  // BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
51549
51854
 
@@ -51620,6 +51925,8 @@ class Dsn6Parser {
51620
51925
  summand = intView[ 16 ];
51621
51926
  }
51622
51927
 
51928
+ if(!me.bNode) console.log("header: " + JSON.stringify(header));
51929
+
51623
51930
  let data = new Float32Array(
51624
51931
  header.xExtent * header.yExtent * header.zExtent
51625
51932
  );
@@ -52817,8 +53124,11 @@ class MmcifParser {
52817
53124
  }
52818
53125
 
52819
53126
  async downloadMmcifSymmetry(mmcifid, type) { let ic = this.icn3d, me = ic.icn3dui;
53127
+ try {
52820
53128
  // https://files.rcsb.org/header/ is not accessible in Node.js and Mac
52821
- let url = (me.bNode || me.utilsCls.isMac()) ? "https://files.rcsb.org/view/" + mmcifid + ".cif" : "https://files.rcsb.org/header/" + mmcifid + ".cif";
53129
+ // Some header files are in the wrong format. So we use the full mmCIF file
53130
+ //let url = (me.bNode || me.utilsCls.isMac()) ? "https://files.rcsb.org/view/" + mmcifid + ".cif" : "https://files.rcsb.org/header/" + mmcifid + ".cif";
53131
+ let url = "https://files.rcsb.org/view/" + mmcifid + ".cif";
52822
53132
 
52823
53133
  //ic.bCid = undefined;
52824
53134
  let data1 = await me.getAjaxPromise(url, 'text', false, "The structure " + mmcifid + " was not found...");
@@ -52880,6 +53190,11 @@ class MmcifParser {
52880
53190
  }
52881
53191
 
52882
53192
  ///// if(ic.deferredSymmetry !== undefined) ic.deferredSymmetry.resolve();
53193
+ }
53194
+ catch (err) {
53195
+ if(!me.bNode) console.log("mmcifparser.cgi issues: " + err);
53196
+ return;
53197
+ }
52883
53198
  }
52884
53199
 
52885
53200
  //Atom "data" from mmCIF file was parsed to set up parameters for the 3D viewer by calling the function
@@ -59701,6 +60016,8 @@ class LoadPDB {
59701
60016
 
59702
60017
  let bHeader = false, bFirstAtom = true;
59703
60018
 
60019
+ let segId, prevSegId;
60020
+
59704
60021
  for (let i in lines) {
59705
60022
  let line = lines[i];
59706
60023
  let record = line.substr(0, 6);
@@ -59860,11 +60177,36 @@ class LoadPDB {
59860
60177
  ic.pmid = line.substr(19).trim();
59861
60178
  }
59862
60179
  } else if (record === 'ATOM ' || record === 'HETATM') {
60180
+ //73 - 76 LString(4) segID Segment identifier, left-justified.
60181
+ // deal with PDBs from MD trajectories
60182
+ segId = line.substr(72, 4).trim();
60183
+
59863
60184
  if(bFirstAtom) {
59864
60185
  structure = this.getStructureId(id, moleculeNum, bMutation);
59865
60186
 
59866
60187
  bFirstAtom = false;
59867
60188
  }
60189
+ else if(segId != prevSegId) {
60190
+ ++moleculeNum;
60191
+ id = ic.defaultPdbId;
60192
+
60193
+ structure = this.getStructureId(id, moleculeNum, bMutation);
60194
+
60195
+ //helices = [];
60196
+ //sheets = [];
60197
+ if(!bNMR) {
60198
+ sheetArray = [];
60199
+ sheetStart = [];
60200
+ sheetEnd = [];
60201
+ helixArray = [];
60202
+ helixStart = [];
60203
+ helixEnd = [];
60204
+ }
60205
+
60206
+ bHeader = false; // reinitialize to read structure name from the header
60207
+ }
60208
+
60209
+ prevSegId = segId;
59868
60210
 
59869
60211
  let alt = line.substr(16, 1);
59870
60212
  //if (alt !== " " && alt !== "A") continue;
@@ -62634,6 +62976,22 @@ class ApplyCommand {
62634
62976
  else if(command.indexOf('hide ref number') == 0) {
62635
62977
  ic.bShownRefnum = false;
62636
62978
  }
62979
+ else if(command.indexOf('translate pdb') == 0) {
62980
+ let xyz = command.substr(14 + 1).split(' ');
62981
+
62982
+ ic.transformCls.translateCoord(ic.hAtoms, parseFloat(xyz[0]), parseFloat(xyz[1]), parseFloat(xyz[2]));
62983
+ ic.drawCls.draw();
62984
+ }
62985
+ else if(command.indexOf('rotate pdb') == 0) {
62986
+ let mArray = command.substr(10 + 1).split(',');
62987
+ let mArrayFloat = [];
62988
+ for(let i = 0, il = mArray.length; i < il; ++i) {
62989
+ mArrayFloat.push(parseFloat(mArray[i]));
62990
+ }
62991
+
62992
+ ic.transformCls.rotateCoord(ic.hAtoms, mArrayFloat);
62993
+ ic.drawCls.draw();
62994
+ }
62637
62995
 
62638
62996
  // special, select ==========
62639
62997
 
@@ -63814,6 +64172,14 @@ class SelectCollections {
63814
64172
  ic.transformCls.zoominSelection();
63815
64173
  ic.definedSetsCls.showSets();
63816
64174
 
64175
+ ic.bResetAnno = true;
64176
+ if(ic.bAnnoShown) {
64177
+ await ic.showAnnoCls.showAnnotations();
64178
+
64179
+ ic.hlUpdateCls.updateHlAll(nameArray);
64180
+ // show selected chains in annotation window
64181
+ ic.annotationCls.showAnnoSelectedChains();
64182
+ }
63817
64183
 
63818
64184
  await ic.drawCls.draw();
63819
64185
  ic.saveFileCls.showTitle();
@@ -64900,6 +65266,9 @@ class SelectByCommand {
64900
65266
  }
64901
65267
  else {
64902
65268
  chainStr = testStr.substr(periodPos + 1);
65269
+ //replace "A_1" with "A"
65270
+ chainStr = chainStr.replace(/_/g, '');
65271
+
64903
65272
  testStr = testStr.substr(0, periodPos);
64904
65273
  }
64905
65274
 
@@ -70762,7 +71131,7 @@ class ResizeCanvas {
70762
71131
  //let itemArray = ['dl_selectannotations', 'dl_alignment', 'dl_2ddgm', 'dl_definedsets', 'dl_graph',
70763
71132
  // 'dl_linegraph', 'dl_scatterplot', 'dl_contactmap', 'dl_allinteraction', 'dl_copyurl',
70764
71133
  // 'dl_symmetry', 'dl_symd', 'dl_rmsd', 'dl_legend', 'dl_disttable'];
70765
- let itemArray = ['dl_2ddgm', 'dl_2dctn', 'dl_alignment', 'dl_sequence2', 'dl_definedsets', 'dl_setsmenu', 'dl_command', 'dl_setoperations', 'dl_vast', 'dl_foldseek', 'dl_mmtfid', 'dl_pdbid', 'dl_afid', 'dl_opmid', 'dl_pdbfile', 'dl_pdbfile_app', 'dl_rescolorfile', 'dl_customcolor', 'dl_align', 'dl_alignaf', 'dl_chainalign', 'dl_chainalign2', 'dl_chainalign3', 'dl_mutation', 'dl_mol2file', 'dl_sdffile', 'dl_xyzfile', 'dl_afmapfile', 'dl_urlfile', 'dl_mmciffile', 'dl_mmcifid', 'dl_mmdbid', 'dl_mmdbafid', 'dl_blast_rep_id', 'dl_yournote', 'dl_proteinname', 'dl_refseqid', 'dl_cid', 'dl_pngimage', 'dl_state', 'dl_fixedversion', 'dl_selection', 'dl_dsn6', 'dl_dsn6url', 'dl_clr', 'dl_symmetry', 'dl_symd', 'dl_contact', 'dl_hbonds', 'dl_realign', 'dl_realignbystruct', 'dl_allinteracton', 'dl_interactionsorted', 'dl_linegraph', 'dl_linegraphcolor', 'dl_scatterplot', 'dl_scatterploitcolor', 'dl_contactmap', 'dl_alignerrormap', 'dl_elecmap2fofc', 'dl_elecmapfofc', 'dl_emmap', 'dl_aroundsphere', 'dl_adjustmem', 'dl_selectplane', 'dl_addlabel', 'dl_addlabelselection', 'dl_labelColor', 'dl_distance', 'dl_stabilizer', 'dl_disttwosets', 'dl_distmanysets', 'dl_stabilizer_rm', 'dl_thickness', 'dl_thickness2', 'dl_addtrack', 'dl_addtrack_tabs', 'dl_saveselection', 'dl_copyurl', 'dl_selectannotations', 'dl_annotations_tabs', 'dl_anno_view_tabs', 'dl_annotations', 'dl_graph', 'dl_svgcolor', 'dl_area', 'dl_colorbyarea', 'dl_rmsd', 'dl_buriedarea', 'dl_propbypercentout', 'dl_propbybfactor', 'dl_legend', 'dl_disttable'];
71134
+ let itemArray = ['dl_2ddgm', 'dl_2dctn', 'dl_alignment', 'dl_sequence2', 'dl_definedsets', 'dl_setsmenu', 'dl_command', 'dl_setoperations', 'dl_vast', 'dl_foldseek', 'dl_mmtfid', 'dl_pdbid', 'dl_afid', 'dl_opmid', 'dl_pdbfile', 'dl_pdbfile_app', 'dl_rescolorfile', 'dl_customcolor', 'dl_align', 'dl_alignaf', 'dl_chainalign', 'dl_chainalign2', 'dl_chainalign3', 'dl_mutation', 'dl_mol2file', 'dl_sdffile', 'dl_xyzfile', 'dl_afmapfile', 'dl_urlfile', 'dl_mmciffile', 'dl_mmcifid', 'dl_mmdbid', 'dl_mmdbafid', 'dl_blast_rep_id', 'dl_yournote', 'dl_proteinname', 'dl_refseqid', 'dl_cid', 'dl_pngimage', 'dl_state', 'dl_fixedversion', 'dl_selection', 'dl_dsn6', 'dl_dsn6url', 'dl_clr', 'dl_symmetry', 'dl_symd', 'dl_contact', 'dl_hbonds', 'dl_realign', 'dl_realignbystruct', 'dl_allinteracton', 'dl_interactionsorted', 'dl_linegraph', 'dl_linegraphcolor', 'dl_scatterplot', 'dl_scatterploitcolor', 'dl_contactmap', 'dl_alignerrormap', 'dl_elecmap2fofc', 'dl_elecmapfofc', 'dl_emmap', 'dl_aroundsphere', 'dl_adjustmem', 'dl_selectplane', 'dl_addlabel', 'dl_addlabelselection', 'dl_labelColor', 'dl_distance', 'dl_stabilizer', 'dl_disttwosets', 'dl_distmanysets', 'dl_stabilizer_rm', 'dl_thickness', 'dl_thickness2', 'dl_addtrack', 'dl_addtrack_tabs', 'dl_saveselection', 'dl_copyurl', 'dl_selectannotations', 'dl_annotations_tabs', 'dl_anno_view_tabs', 'dl_annotations', 'dl_graph', 'dl_svgcolor', 'dl_area', 'dl_colorbyarea', 'dl_rmsd', 'dl_buriedarea', 'dl_propbypercentout', 'dl_propbybfactor', 'dl_legend', 'dl_disttable', 'dl_translate'];
70766
71135
 
70767
71136
  for(let i in itemArray) {
70768
71137
  let item = itemArray[i];
@@ -70926,6 +71295,8 @@ class Transform {
70926
71295
  }
70927
71296
 
70928
71297
  setRotation(axis, angle) { let ic = this.icn3d, me = ic.icn3dui;
71298
+ if(!axis) return;
71299
+
70929
71300
  if(ic.bControlGl && !me.bNode && window.cam) {
70930
71301
  axis.applyQuaternion( window.cam.quaternion ).normalize();
70931
71302
  }
@@ -70990,6 +71361,25 @@ class Transform {
70990
71361
  if(ic.bRender) ic.drawCls.render();
70991
71362
  }
70992
71363
 
71364
+ translateCoord(atoms, dx, dy, dz) { let ic = this.icn3d; ic.icn3dui;
71365
+ for(let i in atoms) {
71366
+ let atom = ic.atoms[i];
71367
+ atom.coord.x += dx;
71368
+ atom.coord.y += dy;
71369
+ atom.coord.z += dz;
71370
+ }
71371
+ }
71372
+
71373
+ rotateCoord(atoms, mArray) { let ic = this.icn3d; ic.icn3dui;
71374
+ const m = new THREE.Matrix4();
71375
+ m.elements = mArray;
71376
+
71377
+ for(let i in atoms) {
71378
+ let atom = ic.atoms[i];
71379
+ atom.coord = atom.coord.applyMatrix4(m);
71380
+ }
71381
+ }
71382
+
70993
71383
  //Center on the selected atoms and zoom in.
70994
71384
  zoominSelection(atoms) { let ic = this.icn3d, me = ic.icn3dui;
70995
71385
  let para = {};
@@ -71547,7 +71937,7 @@ class SaveFile {
71547
71937
  // }
71548
71938
 
71549
71939
  // export assembly symmetry matrix "BIOMT"
71550
- if(ic.biomtMatrices) {
71940
+ if(ic.biomtMatrices && Object.keys(atomHash).length == Object.keys(ic.atoms).length) {
71551
71941
  let stru = Object.keys(ic.structures)[0];
71552
71942
  for(let m = 0, ml = ic.biomtMatrices.length; m < ml; ++m) {
71553
71943
  let mNum = m + 1;
@@ -75317,7 +75707,7 @@ class iCn3DUI {
75317
75707
  //even when multiple iCn3D viewers are shown together.
75318
75708
  this.pre = this.cfg.divid + "_";
75319
75709
 
75320
- this.REVISION = '3.29.2';
75710
+ this.REVISION = '3.29.4';
75321
75711
 
75322
75712
  // In nodejs, iCn3D defines "window = {navigator: {}}"
75323
75713
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -75937,8 +76327,8 @@ iCn3DUI.prototype.getAjaxPostPromise = async function(url, data, beforeSend, ale
75937
76327
  },
75938
76328
  error : function() {
75939
76329
  //if(alertMess) alert(alertMess);
75940
- if(alertMess) console.log(alertMess);
75941
- if(logMess) console.log(logMess);
76330
+ if(!me.bNode && alertMess) console.log(alertMess);
76331
+ if(!me.bNode && logMess) console.log(logMess);
75942
76332
 
75943
76333
  // reject('error');
75944
76334
  // keep running the program