icn3d 3.29.5 → 3.29.6

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();
@@ -9568,14 +9575,14 @@ class SetMenu {
9568
9575
  }
9569
9576
 
9570
9577
  //!!!
9571
- /*
9578
+
9572
9579
  html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
9573
9580
  html += "<ul>";
9574
9581
  html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
9575
9582
  html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
9576
9583
  html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
9577
9584
  html += "</ul>";
9578
- */
9585
+
9579
9586
 
9580
9587
  html += "<li><br/></li>";
9581
9588
 
@@ -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', 'Apply 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);
@@ -10416,8 +10426,8 @@ class SetMenu {
10416
10426
  //}
10417
10427
 
10418
10428
  //!!!
10419
- //html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
10420
- //html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
10429
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
10430
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
10421
10431
  }
10422
10432
  else {
10423
10433
  //if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
@@ -10548,7 +10558,7 @@ class SetMenu {
10548
10558
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
10549
10559
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
10550
10560
  //!!!
10551
- //html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
10561
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
10552
10562
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
10553
10563
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
10554
10564
  }
@@ -10640,13 +10650,13 @@ class SetMenu {
10640
10650
 
10641
10651
  html += "<ul>";
10642
10652
  //!!!
10643
- /*
10653
+
10644
10654
  html += this.getLink('mn6_igrefYes', 'Show Ig Ref. Number', undefined, 2);
10645
10655
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
10646
10656
  html += this.getLink('mn6_igrefNo', 'Hide Ig Ref. Number', undefined, 2);
10647
10657
 
10648
10658
  html += this.getMenuSep();
10649
- */
10659
+
10650
10660
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
10651
10661
  html += "</ul>";
10652
10662
  html += "</li>";
@@ -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'>Apply 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();
@@ -40161,6 +40231,7 @@ class Domain3d {
40161
40231
  substructItem.z2 = atom.coord.z;
40162
40232
 
40163
40233
  substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
40234
+
40164
40235
  substruct.push(substructItem);
40165
40236
  substructItem = {};
40166
40237
  }
@@ -43886,8 +43957,8 @@ class ShowSeq {
43886
43957
  }
43887
43958
  giSeq = giSeqTmp;
43888
43959
 
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;
43960
+ //let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
43961
+ let divLength = me.htmlCls.RESIDUE_WIDTH * (giSeq.length + ic.nTotalGap) + 200;
43891
43962
 
43892
43963
  // let seqLength = ic.giSeq[chnid].length
43893
43964
  // if(seqLength > ic.maxAnnoLength) {
@@ -43907,7 +43978,7 @@ class ShowSeq {
43907
43978
  // html to display protein positions(10, 20, etc)
43908
43979
  //if(Object.keys(ic.chains[chnid]).length > 10) {
43909
43980
 
43910
- if(ic.giSeq[chnid].length > 10) {
43981
+ if(giSeq.length > 10) {
43911
43982
  htmlTmp = '<div class="icn3d-residueLine" style="white-space:nowrap;">';
43912
43983
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
43913
43984
  //if(ic.baseResi[chnid] != 0 &&(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.align !== undefined)) {
@@ -44269,7 +44340,7 @@ class ShowSeq {
44269
44340
  html3 += '</div>';
44270
44341
 
44271
44342
  //if(Object.keys(ic.chains[chnid]).length > 10) {
44272
- if(ic.giSeq[chnid].length > 10) {
44343
+ if(giSeq.length > 10) {
44273
44344
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
44274
44345
  //if(ic.baseResi[chnid] != 0 &&(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.align !== undefined)) {
44275
44346
  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 +44527,12 @@ class ShowSeq {
44456
44527
  // reset ic.residIgLoop for the current selection, which could be the second round of ref num assignment
44457
44528
  // just current chain
44458
44529
  let atomHash = me.hashUtilsCls.intHash(ic.chains[chnid], ic.hAtoms);
44459
- let residHash = ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
44530
+ ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
44460
44531
 
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
- }
44532
+ // for(let resid in residHash) {
44533
+ // // not in loop any more if you assign ref numbers multiple times
44534
+ // delete ic.residIgLoop[resid];
44535
+ // }
44465
44536
  }
44466
44537
 
44467
44538
  // 1. get the range of each strand excluding loops
@@ -44591,6 +44662,76 @@ class ShowSeq {
44591
44662
  }
44592
44663
  }
44593
44664
 
44665
+ // 2b. extend the strand to end of sheet
44666
+ let maxExtend = 8;
44667
+ for(let i = 0, il = strandArray.length; i < il; ++i) {
44668
+ let startAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].startResi]);
44669
+ let endAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].endResi]);
44670
+
44671
+ let startPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].startResi);
44672
+ let endPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].endResi);
44673
+
44674
+ if(startAtom.ss == 'sheet' && !startAtom.ssbegin) {
44675
+ for(let j = 1; j <= maxExtend; ++j) {
44676
+ let currPos = startPos - j;
44677
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44678
+ if(i > 0 && parseInt(currResi) <= parseInt(strandArray[i-1].endResi)) break;
44679
+
44680
+ let currResid = chnid + '_' + currResi;
44681
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
44682
+ if(currAtom.ssbegin) { // find the start of the sheet
44683
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
44684
+ strandArray[i].startResi = currResi;
44685
+ strandArray[i].startRefnum -= j;
44686
+ strandArray[i].loopResCnt -= j;
44687
+ if(strandArray[i].loopResCnt < 0) strandArray[i].loopResCnt = 0;
44688
+ strandArray[i].resCntBfAnchor += j;
44689
+
44690
+ // update ic.resid2refnum
44691
+ for(let k = 1; k <= j; ++k) {
44692
+ currPos = startPos - k;
44693
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44694
+ let currResid = chnid + '_' + currResi;
44695
+ delete ic.residIgLoop[currResid];
44696
+ }
44697
+
44698
+ break;
44699
+ }
44700
+ }
44701
+ }
44702
+
44703
+ if(endAtom.ss == 'sheet' && !endAtom.ssend) {
44704
+ for(let j = 1; j <= maxExtend; ++j) {
44705
+ let currPos = endPos + j;
44706
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44707
+ if(i < il - 1 && parseInt(currResi) >= parseInt(strandArray[i+1].startResi)) break;
44708
+
44709
+ let currResid = chnid + '_' + currResi;
44710
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
44711
+ if(currAtom.ssend) { // find the end of the sheet
44712
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
44713
+ strandArray[i].endResi = currResi;
44714
+ strandArray[i].endRefnum += j;
44715
+ if(i < il - 1) {
44716
+ strandArray[i + 1].loopResCnt -= j;
44717
+ if(strandArray[i + 1].loopResCnt < 0) strandArray[i + 1].loopResCnt = 0;
44718
+ }
44719
+ strandArray[i].resCntAtAnchor += j;
44720
+
44721
+ // update ic.residIgLoop[resid];
44722
+ for(let k = 1; k <= j; ++k) {
44723
+ currPos = endPos + k;
44724
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
44725
+ let currResid = chnid + '_' + currResi;
44726
+ delete ic.residIgLoop[currResid];
44727
+ }
44728
+
44729
+ break;
44730
+ }
44731
+ }
44732
+ }
44733
+ }
44734
+
44594
44735
  // 3. assign refnumLabel for each resid
44595
44736
  strandCnt = 0;
44596
44737
  let loopCnt = 0;
@@ -46773,7 +46914,15 @@ class LineGraph {
46773
46914
 
46774
46915
  ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
46775
46916
 
46776
- await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46917
+ let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46918
+ let numRound = 0;
46919
+
46920
+ //while(!bNoMoreIg) {
46921
+ while(!bNoMoreIg && numRound < 10) {
46922
+ let bRerun = true;
46923
+ bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun);
46924
+ ++numRound;
46925
+ }
46777
46926
  }
46778
46927
  else {
46779
46928
  await thisClass.parseRefPdbData(undefined, template);
@@ -46785,7 +46934,7 @@ class LineGraph {
46785
46934
  // }
46786
46935
  }
46787
46936
 
46788
- async parseRefPdbData(dataArray, template) { let ic = this.icn3d, me = ic.icn3dui;
46937
+ async parseRefPdbData(dataArray, template, bRerun) { let ic = this.icn3d, me = ic.icn3dui;
46789
46938
  let thisClass = this;
46790
46939
 
46791
46940
  let struArray = Object.keys(ic.structures);
@@ -46800,6 +46949,7 @@ class LineGraph {
46800
46949
  //ic.resid2domainid = {};
46801
46950
  ic.domainid2pdb = {};
46802
46951
 
46952
+ let bNoMoreIg = true;
46803
46953
  for(let i = 0, il = struArray.length; i < il; ++i) {
46804
46954
  let struct = struArray[i];
46805
46955
  let chainidArray = ic.structures[struct];
@@ -46807,12 +46957,14 @@ class LineGraph {
46807
46957
  for(let j = 0, jl = chainidArray.length; j < jl; ++j) {
46808
46958
  let chainid = chainidArray[j];
46809
46959
 
46810
- let domainAtomsArray = this.getDomainAtomsArray(chainid);
46811
-
46960
+ let domainAtomsArray = this.getDomainAtomsArray(chainid, bRerun);
46961
+
46812
46962
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
46813
46963
  if(!ic.domainid2score) ic.domainid2score = {};
46814
46964
 
46815
46965
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
46966
+ bNoMoreIg = false;
46967
+
46816
46968
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
46817
46969
  //let bForceOneDomain = true;
46818
46970
  //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
@@ -46913,6 +47065,8 @@ class LineGraph {
46913
47065
 
46914
47066
  await thisClass.parseAlignData(dataArray3, domainidpairArray3);
46915
47067
  }
47068
+
47069
+ return bNoMoreIg;
46916
47070
  /*
46917
47071
  }
46918
47072
  catch(err) {
@@ -46929,10 +47083,12 @@ class LineGraph {
46929
47083
  */
46930
47084
  }
46931
47085
 
46932
- getDomainAtomsArray(chainid) { let ic = this.icn3d, me = ic.icn3dui;
47086
+ getDomainAtomsArray(chainid, bRerunDomain) { let ic = this.icn3d, me = ic.icn3dui;
46933
47087
  let domainAtomsArray = [];
46934
47088
 
46935
- let minResidues = 20;
47089
+ let minResidues = 20, minAtoms = 200;
47090
+
47091
+ if(!ic.chainid2atomsLeft) ic.chainid2atomsLeft = {};
46936
47092
 
46937
47093
  if(!ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]).serial)
46938
47094
  && !ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getMiddleAtomObj(ic.chains[chainid]).serial)) return domainAtomsArray;
@@ -46941,18 +47097,37 @@ class LineGraph {
46941
47097
  let currAtoms = me.hashUtilsCls.intHash(ic.chains[chainid], ic.hAtoms);
46942
47098
  if(Object.keys(currAtoms).length == 0) return domainAtomsArray;
46943
47099
 
47100
+ if(bRerunDomain) {
47101
+ let atomsAssigned = {};
47102
+ // for(let resid in ic.resid2refnum_ori) {
47103
+ // atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
47104
+ // }
47105
+ for(let resid in ic.resid2refnum) {
47106
+ if(ic.resid2refnum[resid]) atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
47107
+ }
47108
+
47109
+ currAtoms = me.hashUtilsCls.exclHash(currAtoms, atomsAssigned);
47110
+
47111
+ // no need to rerun the rest residues any more
47112
+ if(ic.chainid2atomsLeft[chainid] == Object.keys(currAtoms).length) {
47113
+ return domainAtomsArray;
47114
+ }
47115
+
47116
+ ic.chainid2atomsLeft[chainid] = Object.keys(currAtoms).length;
47117
+
47118
+ if(Object.keys(currAtoms).length < minAtoms) return domainAtomsArray;
47119
+ }
47120
+
46944
47121
  // align each 3D domain with reference structure
46945
47122
  //let result = ic.domain3dCls.c2b_NewSplitChain(ic.chains[chainid]);
46946
47123
  // assign ref numbers to selected residues
46947
- let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms);
47124
+ let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
46948
47125
  let subdomains = result.subdomains;
46949
47126
  let pos2resi = result.pos2resi;
46950
47127
 
46951
47128
  if(subdomains.length <= 1) {
46952
- //domainAtomsArray.push(ic.chains[chainid]);
46953
- domainAtomsArray.push(currAtoms);
46954
-
46955
47129
  let residueArray = ic.resid2specCls.atoms2residues(Object.keys(currAtoms));
47130
+ if(residueArray.length < minResidues) return domainAtomsArray;
46956
47131
 
46957
47132
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(currAtoms);
46958
47133
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(currAtoms);
@@ -46963,31 +47138,41 @@ class LineGraph {
46963
47138
  ic.resid2domainid[resid] = chainid + '-0' + '_' + resiSum;
46964
47139
 
46965
47140
  // clear previous refnum assignment if any
46966
- if(ic.resid2refnum && ic.resid2refnum[resid]) {
47141
+ // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
47142
+ // if(ic.resid2refnum && ic.resid2refnum[resid]) {
46967
47143
  delete ic.resid2refnum[resid];
46968
- }
47144
+ delete ic.residIgLoop[resid];
47145
+ // }
46969
47146
  }
47147
+
47148
+ domainAtomsArray.push(currAtoms);
46970
47149
  }
46971
47150
  else {
46972
47151
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
46973
47152
  let domainAtoms = {};
46974
47153
  let segArray = subdomains[k];
46975
47154
 
47155
+ let resCnt = 0;
46976
47156
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
46977
47157
  let startResi = segArray[m];
46978
47158
  let endResi = segArray[m+1];
46979
47159
  for(let n = parseInt(startResi); n <= parseInt(endResi); ++n) {
46980
47160
  let resid = chainid + '_' + pos2resi[n];
47161
+ ++resCnt;
46981
47162
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
46982
47163
  //ic.resid2domainid[resid] = chainid + '-' + k;
46983
47164
 
46984
47165
  // clear previous refnum assignment if any
46985
- if(ic.resid2refnum && ic.resid2refnum[resid]) {
47166
+ // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
47167
+ // if(ic.resid2refnum && ic.resid2refnum[resid]) {
46986
47168
  delete ic.resid2refnum[resid];
46987
- }
47169
+ delete ic.residIgLoop[resid];
47170
+ // }
46988
47171
  }
46989
47172
  }
46990
47173
 
47174
+ if(resCnt < minResidues) continue;
47175
+
46991
47176
  domainAtomsArray.push(domainAtoms);
46992
47177
 
46993
47178
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtoms);
@@ -47110,31 +47295,45 @@ class LineGraph {
47110
47295
 
47111
47296
  // Ig-like domains: B (2150, 2150a, 2150b), C (3150, 3250), E (7150, 7250), F (8150, 8250) strands
47112
47297
  // Ig domain may require G (7050). But we'll leave that out for now.
47113
- if(!bRound1) {
47298
+ if(!bRound1 && queryData[0].segs) {
47114
47299
  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];
47300
+ let bBSheet = true, bCSheet = true, bESheet = true, bFSheet = true;
47301
+ let chainid = domainid.split(',')[0];
47302
+
47303
+ for(let j = 0, jl = queryData[0].segs.length; j < jl; ++j) {
47304
+ let seg = queryData[0].segs[j];
47305
+ let resi = seg.t_start;
47306
+ let resid = chainid + '_' + resi;
47117
47307
 
47118
47308
  if(seg.q_start.indexOf('2550') != -1) {
47119
47309
  bBstrand = true;
47310
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47311
+ bBSheet = (atom.ss == 'sheet');
47120
47312
  }
47121
47313
  else if(seg.q_start.indexOf('3550') != -1) {
47122
47314
  bCstrand = true;
47315
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47316
+ bBSheet = (atom.ss == 'sheet');
47123
47317
  }
47124
47318
  else if(seg.q_start.indexOf('7550') != -1) {
47125
47319
  bEstrand = true;
47320
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47321
+ bBSheet = (atom.ss == 'sheet');
47126
47322
  }
47127
47323
  else if(seg.q_start.indexOf('8550') != -1) {
47128
47324
  bFstrand = true;
47325
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47326
+ bBSheet = (atom.ss == 'sheet');
47129
47327
  }
47130
47328
 
47131
47329
  //if(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand) break;
47132
47330
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
47133
47331
  }
47134
47332
 
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 + "...");
47333
+ if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
47334
+ //if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
47335
+ if(!me.bNode && !(bBstrand && bCstrand && bEstrand && bFstrand)) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
47336
+ if(!me.bNode && !(bBSheet && bCSheet && bESheet && bFSheet)) console.log("Some of the Ig strands B, C, E, F are not beta sheets...");
47138
47337
  if(ic.domainid2refpdbname[domainid] == refpdbname) {
47139
47338
  delete ic.domainid2refpdbname[domainid];
47140
47339
  delete ic.domainid2score[domainid];
@@ -47271,11 +47470,12 @@ class LineGraph {
47271
47470
 
47272
47471
  // assign ic.resid2refnum, ic.refnum2residArray, ic.chainsMapping
47273
47472
  if(!ic.resid2refnum) ic.resid2refnum = {};
47473
+ // if(!ic.resid2refnum_ori) ic.resid2refnum_ori = {};
47274
47474
  if(!ic.refnum2residArray) ic.refnum2residArray = {};
47275
47475
  if(!ic.chainsMapping) ic.chainsMapping = {};
47276
47476
 
47277
47477
  if(!ic.refPdbList) ic.refPdbList = [];
47278
-
47478
+
47279
47479
  for(let chainid in chainid2segs) {
47280
47480
  let segArray = chainid2segs[chainid];
47281
47481
 
@@ -47294,10 +47494,66 @@ class LineGraph {
47294
47494
  }
47295
47495
  ic.refPdbList.push(message);
47296
47496
 
47497
+ // adjust C' and D strands ======start
47498
+ let bCstrand = false, bCpstrand = false, bCppstrand = false, bDstrand = false, bEstrand = false;
47499
+ let CAtom, CpAtom, DAtom, EAtom;
47500
+ //let chainid = domainid.split(',')[0];
47501
+
47502
+ let cntBtCE = 0;
47503
+ for(let i = 0, il = segArray.length; i < il; ++i) {
47504
+ let seg = segArray[i];
47505
+ if(!seg) continue;
47506
+
47507
+ let resi = seg.t_start;
47508
+ let resid = chainid + '_' + resi;
47509
+
47510
+ if(seg.q_start.indexOf('3550') != -1) {
47511
+ bCstrand = true;
47512
+ CAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47513
+ }
47514
+ else if(seg.q_start.indexOf('4550') != -1) {
47515
+ bCpstrand = true;
47516
+ CpAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47517
+ ++cntBtCE;
47518
+ }
47519
+ // else if(seg.q_start.indexOf('5550') != -1) {
47520
+ // bCppstrand = true;
47521
+ // CppAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47522
+ // ++cntBtCE;
47523
+ // }
47524
+ else if(seg.q_start.indexOf('6550') != -1) {
47525
+ bDstrand = true;
47526
+ DAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47527
+ ++cntBtCE;
47528
+ }
47529
+ else if(seg.q_start.indexOf('7550') != -1) {
47530
+ bEstrand = true;
47531
+ EAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
47532
+ }
47533
+
47534
+ if(bCstrand && bCpstrand && bCppstrand && bDstrand && bEstrand) break;
47535
+ }
47536
+
47537
+ let CpToDResi, DToCpResi;
47538
+ if(cntBtCE == 1) {
47539
+ let distToC = (bCpstrand) ? CpAtom.coord.distanceTo(CAtom.coord) : DAtom.coord.distanceTo(CAtom.coord);
47540
+ let distToE = (bCpstrand) ? CpAtom.coord.distanceTo(EAtom.coord) : DAtom.coord.distanceTo(EAtom.coord);
47541
+
47542
+ if(bCpstrand && distToC > distToE) { // rename C' to D
47543
+ CpToDResi = CAtom.resi;
47544
+ }
47545
+ else if(bDstrand && distToC < distToE) { // rename D to C'
47546
+ DToCpResi = DAtom.resi;
47547
+ }
47548
+ }
47549
+ // adjust C' and D strands ======end
47550
+
47297
47551
  let prevStrand;
47298
47552
  let bCd19 = refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
47299
47553
  for(let i = 0, il = segArray.length; i < il; ++i) {
47300
47554
  let seg = segArray[i];
47555
+ if(!seg) continue;
47556
+
47301
47557
  let qStart = seg.q_start;
47302
47558
  parseInt(seg.q_start);
47303
47559
  if(isNaN(seg.q_start)) seg.q_start.substr(seg.q_start.length - 1, 1);
@@ -47314,10 +47570,21 @@ class LineGraph {
47314
47570
  //let refnum = qStart + postfix;
47315
47571
  let refnum = qStart;
47316
47572
 
47317
- let refnumLabel = this.getLabelFromRefnum(refnum, prevStrand, bCd19);
47573
+ let prevStrandFinal = prevStrand;
47574
+ if(prevStrand == "C'" && CpToDResi && parseInt(seg.t_start) < parseInt(CpToDResi) + 10
47575
+ && parseInt(seg.t_start) > parseInt(CpToDResi) - 10 ) {
47576
+ prevStrandFinal = "D";
47577
+ }
47578
+ else if(prevStrand == "D" && DToCpResi && parseInt(seg.t_start) < parseInt(DToCpResi) + 10
47579
+ && parseInt(seg.t_start) > parseInt(DToCpResi) - 10 ) {
47580
+ prevStrandFinal = "C'";
47581
+ }
47582
+
47583
+ let refnumLabel = this.getLabelFromRefnum(refnum, prevStrandFinal, bCd19);
47318
47584
  prevStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
47319
47585
 
47320
47586
  ic.resid2refnum[resid] = refnumLabel;
47587
+ // ic.resid2refnum_ori[resid] = refnumLabel;
47321
47588
 
47322
47589
  // final reference numbers will be assign in ic.showSeqCls.showRefNum()
47323
47590
 
@@ -51543,7 +51810,7 @@ class Dsn6Parser {
51543
51810
  return sigma;
51544
51811
  }
51545
51812
 
51546
- loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
51813
+ loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
51547
51814
  // DSN6 http://www.uoxray.uoregon.edu/tnt/manual/node104.html
51548
51815
  // BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
51549
51816
 
@@ -51620,6 +51887,8 @@ class Dsn6Parser {
51620
51887
  summand = intView[ 16 ];
51621
51888
  }
51622
51889
 
51890
+ if(!me.bNode) console.log("header: " + JSON.stringify(header));
51891
+
51623
51892
  let data = new Float32Array(
51624
51893
  header.xExtent * header.yExtent * header.zExtent
51625
51894
  );
@@ -52818,7 +53087,9 @@ class MmcifParser {
52818
53087
 
52819
53088
  async downloadMmcifSymmetry(mmcifid, type) { let ic = this.icn3d, me = ic.icn3dui;
52820
53089
  // 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";
53090
+ // Some header files are in the wrong format. So we use the full mmCIF file
53091
+ //let url = (me.bNode || me.utilsCls.isMac()) ? "https://files.rcsb.org/view/" + mmcifid + ".cif" : "https://files.rcsb.org/header/" + mmcifid + ".cif";
53092
+ let url = "https://files.rcsb.org/view/" + mmcifid + ".cif";
52822
53093
 
52823
53094
  //ic.bCid = undefined;
52824
53095
  let data1 = await me.getAjaxPromise(url, 'text', false, "The structure " + mmcifid + " was not found...");
@@ -59701,6 +59972,8 @@ class LoadPDB {
59701
59972
 
59702
59973
  let bHeader = false, bFirstAtom = true;
59703
59974
 
59975
+ let segId, prevSegId;
59976
+
59704
59977
  for (let i in lines) {
59705
59978
  let line = lines[i];
59706
59979
  let record = line.substr(0, 6);
@@ -59860,11 +60133,36 @@ class LoadPDB {
59860
60133
  ic.pmid = line.substr(19).trim();
59861
60134
  }
59862
60135
  } else if (record === 'ATOM ' || record === 'HETATM') {
60136
+ //73 - 76 LString(4) segID Segment identifier, left-justified.
60137
+ // deal with PDBs from MD trajectories
60138
+ segId = line.substr(72, 4).trim();
60139
+
59863
60140
  if(bFirstAtom) {
59864
60141
  structure = this.getStructureId(id, moleculeNum, bMutation);
59865
60142
 
59866
60143
  bFirstAtom = false;
59867
60144
  }
60145
+ else if(segId != prevSegId) {
60146
+ ++moleculeNum;
60147
+ id = ic.defaultPdbId;
60148
+
60149
+ structure = this.getStructureId(id, moleculeNum, bMutation);
60150
+
60151
+ //helices = [];
60152
+ //sheets = [];
60153
+ if(!bNMR) {
60154
+ sheetArray = [];
60155
+ sheetStart = [];
60156
+ sheetEnd = [];
60157
+ helixArray = [];
60158
+ helixStart = [];
60159
+ helixEnd = [];
60160
+ }
60161
+
60162
+ bHeader = false; // reinitialize to read structure name from the header
60163
+ }
60164
+
60165
+ prevSegId = segId;
59868
60166
 
59869
60167
  let alt = line.substr(16, 1);
59870
60168
  //if (alt !== " " && alt !== "A") continue;
@@ -62634,6 +62932,22 @@ class ApplyCommand {
62634
62932
  else if(command.indexOf('hide ref number') == 0) {
62635
62933
  ic.bShownRefnum = false;
62636
62934
  }
62935
+ else if(command.indexOf('translate pdb') == 0) {
62936
+ let xyz = command.substr(14 + 1).split(' ');
62937
+
62938
+ ic.transformCls.translateCoord(ic.hAtoms, parseFloat(xyz[0]), parseFloat(xyz[1]), parseFloat(xyz[2]));
62939
+ ic.drawCls.draw();
62940
+ }
62941
+ else if(command.indexOf('rotate pdb') == 0) {
62942
+ let mArray = command.substr(10 + 1).split(',');
62943
+ let mArrayFloat = [];
62944
+ for(let i = 0, il = mArray.length; i < il; ++i) {
62945
+ mArrayFloat.push(parseFloat(mArray[i]));
62946
+ }
62947
+
62948
+ ic.transformCls.rotateCoord(ic.hAtoms, mArrayFloat);
62949
+ ic.drawCls.draw();
62950
+ }
62637
62951
 
62638
62952
  // special, select ==========
62639
62953
 
@@ -63814,6 +64128,14 @@ class SelectCollections {
63814
64128
  ic.transformCls.zoominSelection();
63815
64129
  ic.definedSetsCls.showSets();
63816
64130
 
64131
+ ic.bResetAnno = true;
64132
+ if(ic.bAnnoShown) {
64133
+ await ic.showAnnoCls.showAnnotations();
64134
+
64135
+ ic.hlUpdateCls.updateHlAll(nameArray);
64136
+ // show selected chains in annotation window
64137
+ ic.annotationCls.showAnnoSelectedChains();
64138
+ }
63817
64139
 
63818
64140
  await ic.drawCls.draw();
63819
64141
  ic.saveFileCls.showTitle();
@@ -70762,7 +71084,7 @@ class ResizeCanvas {
70762
71084
  //let itemArray = ['dl_selectannotations', 'dl_alignment', 'dl_2ddgm', 'dl_definedsets', 'dl_graph',
70763
71085
  // 'dl_linegraph', 'dl_scatterplot', 'dl_contactmap', 'dl_allinteraction', 'dl_copyurl',
70764
71086
  // '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'];
71087
+ 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
71088
 
70767
71089
  for(let i in itemArray) {
70768
71090
  let item = itemArray[i];
@@ -70926,6 +71248,8 @@ class Transform {
70926
71248
  }
70927
71249
 
70928
71250
  setRotation(axis, angle) { let ic = this.icn3d, me = ic.icn3dui;
71251
+ if(!axis) return;
71252
+
70929
71253
  if(ic.bControlGl && !me.bNode && window.cam) {
70930
71254
  axis.applyQuaternion( window.cam.quaternion ).normalize();
70931
71255
  }
@@ -70990,6 +71314,25 @@ class Transform {
70990
71314
  if(ic.bRender) ic.drawCls.render();
70991
71315
  }
70992
71316
 
71317
+ translateCoord(atoms, dx, dy, dz) { let ic = this.icn3d; ic.icn3dui;
71318
+ for(let i in atoms) {
71319
+ let atom = ic.atoms[i];
71320
+ atom.coord.x += dx;
71321
+ atom.coord.y += dy;
71322
+ atom.coord.z += dz;
71323
+ }
71324
+ }
71325
+
71326
+ rotateCoord(atoms, mArray) { let ic = this.icn3d; ic.icn3dui;
71327
+ const m = new THREE.Matrix4();
71328
+ m.elements = mArray;
71329
+
71330
+ for(let i in atoms) {
71331
+ let atom = ic.atoms[i];
71332
+ atom.coord = atom.coord.applyMatrix4(m);
71333
+ }
71334
+ }
71335
+
70993
71336
  //Center on the selected atoms and zoom in.
70994
71337
  zoominSelection(atoms) { let ic = this.icn3d, me = ic.icn3dui;
70995
71338
  let para = {};
@@ -71547,7 +71890,7 @@ class SaveFile {
71547
71890
  // }
71548
71891
 
71549
71892
  // export assembly symmetry matrix "BIOMT"
71550
- if(ic.biomtMatrices) {
71893
+ if(ic.biomtMatrices && Object.keys(atomHash).length == Object.keys(ic.atoms).length) {
71551
71894
  let stru = Object.keys(ic.structures)[0];
71552
71895
  for(let m = 0, ml = ic.biomtMatrices.length; m < ml; ++m) {
71553
71896
  let mNum = m + 1;
@@ -75317,7 +75660,7 @@ class iCn3DUI {
75317
75660
  //even when multiple iCn3D viewers are shown together.
75318
75661
  this.pre = this.cfg.divid + "_";
75319
75662
 
75320
- this.REVISION = '3.29.2';
75663
+ this.REVISION = '3.29.3';
75321
75664
 
75322
75665
  // In nodejs, iCn3D defines "window = {navigator: {}}"
75323
75666
  this.bNode = (Object.keys(window).length < 2) ? true : false;