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.js CHANGED
@@ -7611,6 +7611,13 @@ class ClickMenu {
7611
7611
  //}
7612
7612
  });
7613
7613
 
7614
+ $(document).on("click", "#" + me.pre + "mn2_translate", function(e) { me.icn3d; //e.preventDefault();
7615
+ me.htmlCls.dialogCls.openDlg('dl_translate', 'Translate the X,Y,Z coordinates of the structure');
7616
+ });
7617
+
7618
+ $(document).on("click", "#" + me.pre + "mn2_matrix", function(e) { me.icn3d; //e.preventDefault();
7619
+ me.htmlCls.dialogCls.openDlg('dl_matrix', 'Apply matrix to the X,Y,Z coordinates of the structure');
7620
+ });
7614
7621
 
7615
7622
  $(document).on("click", "." + me.pre + "mn6_rotate", function(e) { let ic = me.icn3d; //e.preventDefault();
7616
7623
  let value = $(this).attr('v').toLowerCase();
@@ -7626,7 +7633,7 @@ class ClickMenu {
7626
7633
 
7627
7634
  $(document).on("click", "." + me.pre + "mn6_rotate90", function(e) { let ic = me.icn3d; //e.preventDefault();
7628
7635
  let value = $(this).attr('v').toLowerCase();
7629
- let direction = value.split('-')[0];
7636
+ let direction = value.split(' ')[1];
7630
7637
 
7631
7638
  thisClass.setLogCmd(value, true);
7632
7639
  let axis;
@@ -8894,6 +8901,9 @@ class SetMenu {
8894
8901
  html += "</ul>";
8895
8902
  html += "</li>";
8896
8903
 
8904
+ html += this.getLink('mn2_translate', 'Translate XYZ', undefined, 1);
8905
+ html += this.getLink('mn2_matrix', 'Rotate with Matrix', undefined, 1);
8906
+
8897
8907
  html += this.getMenuText('mn2_camera', 'Camera', undefined, undefined, 1);
8898
8908
  html += "<ul>";
8899
8909
  html += this.getRadio('mn6_camera', 'mn6_cameraPers', 'Perspective', true, undefined, 2);
@@ -11855,6 +11865,39 @@ class SetDialog {
11855
11865
  html += this.addNotebookTitle('dl_disttable', 'Distance Table', true);
11856
11866
  html += "</div>";
11857
11867
 
11868
+ html += me.htmlCls.divStr + "dl_translate' class='" + dialogClass + "'>";
11869
+ html += this.addNotebookTitle('dl_translate', 'Translate the X,Y,Z coordinates of the structure');
11870
+ html += "X: " + me.htmlCls.inputTextStr + "id='" + me.pre + "translateX' value='' size=4> ";
11871
+ html += "Y: " + me.htmlCls.inputTextStr + "id='" + me.pre + "translateY' value='' size=4> ";
11872
+ html += "Z: " + me.htmlCls.inputTextStr + "id='" + me.pre + "translateZ' value='' size=4> ";
11873
+ html += me.htmlCls.buttonStr + "translate_pdb'>Translate</button>";
11874
+ html += "</div>";
11875
+
11876
+ html += me.htmlCls.divStr + "dl_matrix' class='" + dialogClass + "'>";
11877
+ html += this.addNotebookTitle('dl_matrix', 'Apply matrix to the X,Y,Z coordinates of the structure');
11878
+ html += "0: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix0' value='1' size=2> ";
11879
+ html += "4: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix4' value='0' size=2> ";
11880
+ html += "8: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix8' value='0' size=2> ";
11881
+ html += "12: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix12' value='0' size=2><br>";
11882
+
11883
+ html += "1: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix1' value='0' size=2> ";
11884
+ html += "5: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix5' value='1' size=2> ";
11885
+ html += "9: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix9' value='0' size=2> ";
11886
+ html += "13: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix13' value='0' size=2><br>";
11887
+
11888
+ html += "2: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix2' value='0' size=2> ";
11889
+ html += "6: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix6' value='0' size=2> ";
11890
+ html += "10: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix10' value='1' size=2> ";
11891
+ html += "14: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix14' value='0' size=2><br>";
11892
+
11893
+ html += "3: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix3' value='0' size=2> ";
11894
+ html += "7: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix7' value='0' size=2> ";
11895
+ html += "11: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix11' value='0' size=2> ";
11896
+ html += "15: " + me.htmlCls.inputTextStr + "id='" + me.pre + "matrix15' value='1' size=2><br>";
11897
+
11898
+ html += me.htmlCls.buttonStr + "matrix_pdb'>Rotate with Matrix</button>";
11899
+ html += "</div>";
11900
+
11858
11901
  html += me.htmlCls.divStr + "dl_igrefTpl' class='" + dialogClass + "'>";
11859
11902
  html += this.addNotebookTitle('dl_igrefTpl', 'Choose an Ig template');
11860
11903
  html += "<span style='white-space:nowrap;font-weight:bold;'>Choose an Ig template for selected residues:</span> <br><br><select id='" + me.pre + "igrefTpl'>";
@@ -12580,6 +12623,33 @@ class Events {
12580
12623
  window.open(hostUrl + '?pdbid=' + $("#" + me.pre + "pdbid").val(), urlTarget);
12581
12624
  });
12582
12625
 
12626
+ me.myEventCls.onIds("#" + me.pre + "translate_pdb", "click", function(e) { let ic = me.icn3d;
12627
+ e.preventDefault();
12628
+ if(!me.cfg.notebook) dialog.dialog( "close" );
12629
+ let dx = $("#" + me.pre + "translateX").val();
12630
+ let dy = $("#" + me.pre + "translateY").val();
12631
+ let dz = $("#" + me.pre + "translateZ").val();
12632
+
12633
+ ic.transformCls.translateCoord(ic.hAtoms, parseFloat(dx), parseFloat(dy), parseFloat(dz));
12634
+ ic.drawCls.draw();
12635
+
12636
+ thisClass.setLogCmd("translate pdb " + dx + " " + dy + " " + dz, true);
12637
+ });
12638
+
12639
+ me.myEventCls.onIds("#" + me.pre + "matrix_pdb", "click", function(e) { let ic = me.icn3d;
12640
+ e.preventDefault();
12641
+ if(!me.cfg.notebook) dialog.dialog( "close" );
12642
+ let mArray = [];
12643
+ for(let i = 0; i< 16; ++i) {
12644
+ mArray.push(parseFloat($("#" + me.pre + "matrix" + i).val()));
12645
+ }
12646
+
12647
+ ic.transformCls.rotateCoord(ic.hAtoms, mArray);
12648
+ ic.drawCls.draw();
12649
+
12650
+ thisClass.setLogCmd("rotate pdb " + mArray, true);
12651
+ });
12652
+
12583
12653
  me.myEventCls.onIds("#" + me.pre + "pdbid", "keyup", function(e) { let ic = me.icn3d;
12584
12654
  if (e.keyCode === 13) {
12585
12655
  e.preventDefault();
@@ -35142,6 +35212,7 @@ class SetColor {
35142
35212
  break;
35143
35213
 
35144
35214
  case 'secondary structure green':
35215
+ case 'secondary structure':
35145
35216
  ic.sheetcolor = 'green';
35146
35217
  for (let i in atoms) {
35147
35218
  let atom = ic.atoms[i];
@@ -35154,7 +35225,7 @@ class SetColor {
35154
35225
  break;
35155
35226
 
35156
35227
  case 'secondary structure yellow':
35157
- case 'secondary structure':
35228
+ //case 'secondary structure':
35158
35229
  ic.sheetcolor = 'yellow';
35159
35230
  for (let i in atoms) {
35160
35231
  let atom = ic.atoms[i];
@@ -39260,6 +39331,7 @@ class Domain3d {
39260
39331
  substructItem.z2 = atom.coord.z;
39261
39332
 
39262
39333
  substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
39334
+
39263
39335
  substruct.push(substructItem);
39264
39336
  substructItem = {};
39265
39337
  }
@@ -40245,14 +40317,16 @@ class AddTrack {
40245
40317
 
40246
40318
  html += '<span id="' + pre + '_' + ic.pre + chnid + '_' + pos + '" title="' + c + pos + '" class="icn3d-residue" ' + tmpStr + '>' + c + '</span>';
40247
40319
 
40248
- let tmpStrExon = 'style="background-color:' + pos2exonColor[cnt] + '"';
40249
- htmlExon += '<span id="' + pre + '_' + ic.pre + chnid + '_' + pos + '" title="' + c + pos + ', Exon ' + (pos2exonIndex[cnt] + 1) + ': ' + pos2genome[cnt] + '" class="icn3d-residue" ' + tmpStrExon + '>&nbsp;</span>';
40320
+ if(exonArray) {
40321
+ let tmpStrExon = 'style="background-color:' + pos2exonColor[cnt] + '"';
40322
+ htmlExon += '<span id="' + pre + '_' + ic.pre + chnid + '_' + pos + '" title="' + c + pos + ', Exon ' + (pos2exonIndex[cnt] + 1) + ': ' + pos2genome[cnt] + '" class="icn3d-residue" ' + tmpStrExon + '>&nbsp;</span>';
40250
40323
 
40251
- // set atom color
40252
- for(let serial in ic.residues[chnid + '_' + pos]) {
40253
- let atom = ic.atoms[serial];
40254
- atom.color = me.parasCls.thr(pos2exonColor[cnt]);
40255
- ic.atomPrevColors[serial] = atom.color;
40324
+ // set atom color
40325
+ for(let serial in ic.residues[chnid + '_' + pos]) {
40326
+ let atom = ic.atoms[serial];
40327
+ atom.color = me.parasCls.thr(pos2exonColor[cnt]);
40328
+ ic.atomPrevColors[serial] = atom.color;
40329
+ }
40256
40330
  }
40257
40331
 
40258
40332
  htmlTmp2 += ic.showSeqCls.insertGapOverview(chnid, i);
@@ -42976,6 +43050,8 @@ class ShowSeq {
42976
43050
  giSeq = ic.giSeq[chnid];
42977
43051
  }
42978
43052
 
43053
+ if(!giSeq) return;
43054
+
42979
43055
  // remove null giSeq[i]
42980
43056
  let giSeqTmp = [];
42981
43057
  for(let i = 0, il = giSeq.length; i < il; ++i) {
@@ -42985,8 +43061,8 @@ class ShowSeq {
42985
43061
  }
42986
43062
  giSeq = giSeqTmp;
42987
43063
 
42988
- //let divLength = me.htmlCls.RESIDUE_WIDTH * ic.giSeq[chnid].length + 200;
42989
- let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
43064
+ //let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
43065
+ let divLength = me.htmlCls.RESIDUE_WIDTH * (giSeq.length + ic.nTotalGap) + 200;
42990
43066
 
42991
43067
  // let seqLength = ic.giSeq[chnid].length
42992
43068
  // if(seqLength > ic.maxAnnoLength) {
@@ -43006,7 +43082,7 @@ class ShowSeq {
43006
43082
  // html to display protein positions(10, 20, etc)
43007
43083
  //if(Object.keys(ic.chains[chnid]).length > 10) {
43008
43084
 
43009
- if(ic.giSeq[chnid].length > 10) {
43085
+ if(giSeq.length > 10) {
43010
43086
  htmlTmp = '<div class="icn3d-residueLine" style="white-space:nowrap;">';
43011
43087
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
43012
43088
  //if(ic.baseResi[chnid] != 0 &&(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.align !== undefined)) {
@@ -43368,7 +43444,7 @@ class ShowSeq {
43368
43444
  html3 += '</div>';
43369
43445
 
43370
43446
  //if(Object.keys(ic.chains[chnid]).length > 10) {
43371
- if(ic.giSeq[chnid].length > 10) {
43447
+ if(giSeq.length > 10) {
43372
43448
  let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chnid]);
43373
43449
  //if(ic.baseResi[chnid] != 0 &&(me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.align !== undefined)) {
43374
43450
  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 ) {
@@ -43555,12 +43631,12 @@ class ShowSeq {
43555
43631
  // reset ic.residIgLoop for the current selection, which could be the second round of ref num assignment
43556
43632
  // just current chain
43557
43633
  let atomHash = me.hashUtilsCls.intHash(ic.chains[chnid], ic.hAtoms);
43558
- let residHash = ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
43634
+ ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
43559
43635
 
43560
- for(let resid in residHash) {
43561
- // not in loop any more if you assign ref numbers multiple times
43562
- delete ic.residIgLoop[resid];
43563
- }
43636
+ // for(let resid in residHash) {
43637
+ // // not in loop any more if you assign ref numbers multiple times
43638
+ // delete ic.residIgLoop[resid];
43639
+ // }
43564
43640
  }
43565
43641
 
43566
43642
  // 1. get the range of each strand excluding loops
@@ -43690,6 +43766,76 @@ class ShowSeq {
43690
43766
  }
43691
43767
  }
43692
43768
 
43769
+ // 2b. extend the strand to end of sheet
43770
+ let maxExtend = 8;
43771
+ for(let i = 0, il = strandArray.length; i < il; ++i) {
43772
+ let startAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].startResi]);
43773
+ let endAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].endResi]);
43774
+
43775
+ let startPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].startResi);
43776
+ let endPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].endResi);
43777
+
43778
+ if(startAtom.ss == 'sheet' && !startAtom.ssbegin) {
43779
+ for(let j = 1; j <= maxExtend; ++j) {
43780
+ let currPos = startPos - j;
43781
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
43782
+ if(i > 0 && parseInt(currResi) <= parseInt(strandArray[i-1].endResi)) break;
43783
+
43784
+ let currResid = chnid + '_' + currResi;
43785
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
43786
+ if(currAtom.ssbegin) { // find the start of the sheet
43787
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
43788
+ strandArray[i].startResi = currResi;
43789
+ strandArray[i].startRefnum -= j;
43790
+ strandArray[i].loopResCnt -= j;
43791
+ if(strandArray[i].loopResCnt < 0) strandArray[i].loopResCnt = 0;
43792
+ strandArray[i].resCntBfAnchor += j;
43793
+
43794
+ // update ic.resid2refnum
43795
+ for(let k = 1; k <= j; ++k) {
43796
+ currPos = startPos - k;
43797
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
43798
+ let currResid = chnid + '_' + currResi;
43799
+ delete ic.residIgLoop[currResid];
43800
+ }
43801
+
43802
+ break;
43803
+ }
43804
+ }
43805
+ }
43806
+
43807
+ if(endAtom.ss == 'sheet' && !endAtom.ssend) {
43808
+ for(let j = 1; j <= maxExtend; ++j) {
43809
+ let currPos = endPos + j;
43810
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
43811
+ if(i < il - 1 && parseInt(currResi) >= parseInt(strandArray[i+1].startResi)) break;
43812
+
43813
+ let currResid = chnid + '_' + currResi;
43814
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
43815
+ if(currAtom.ssend) { // find the end of the sheet
43816
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
43817
+ strandArray[i].endResi = currResi;
43818
+ strandArray[i].endRefnum += j;
43819
+ if(i < il - 1) {
43820
+ strandArray[i + 1].loopResCnt -= j;
43821
+ if(strandArray[i + 1].loopResCnt < 0) strandArray[i + 1].loopResCnt = 0;
43822
+ }
43823
+ strandArray[i].resCntAtAnchor += j;
43824
+
43825
+ // update ic.residIgLoop[resid];
43826
+ for(let k = 1; k <= j; ++k) {
43827
+ currPos = endPos + k;
43828
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
43829
+ let currResid = chnid + '_' + currResi;
43830
+ delete ic.residIgLoop[currResid];
43831
+ }
43832
+
43833
+ break;
43834
+ }
43835
+ }
43836
+ }
43837
+ }
43838
+
43693
43839
  // 3. assign refnumLabel for each resid
43694
43840
  strandCnt = 0;
43695
43841
  let loopCnt = 0;
@@ -45872,7 +46018,15 @@ class LineGraph {
45872
46018
 
45873
46019
  ic.pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
45874
46020
 
45875
- await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46021
+ let bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template);
46022
+ let numRound = 0;
46023
+
46024
+ //while(!bNoMoreIg) {
46025
+ while(!bNoMoreIg && numRound < 10) {
46026
+ let bRerun = true;
46027
+ bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun);
46028
+ ++numRound;
46029
+ }
45876
46030
  }
45877
46031
  else {
45878
46032
  await thisClass.parseRefPdbData(undefined, template);
@@ -45884,7 +46038,7 @@ class LineGraph {
45884
46038
  // }
45885
46039
  }
45886
46040
 
45887
- async parseRefPdbData(dataArray, template) { let ic = this.icn3d, me = ic.icn3dui;
46041
+ async parseRefPdbData(dataArray, template, bRerun) { let ic = this.icn3d, me = ic.icn3dui;
45888
46042
  let thisClass = this;
45889
46043
 
45890
46044
  let struArray = Object.keys(ic.structures);
@@ -45899,6 +46053,7 @@ class LineGraph {
45899
46053
  //ic.resid2domainid = {};
45900
46054
  ic.domainid2pdb = {};
45901
46055
 
46056
+ let bNoMoreIg = true;
45902
46057
  for(let i = 0, il = struArray.length; i < il; ++i) {
45903
46058
  let struct = struArray[i];
45904
46059
  let chainidArray = ic.structures[struct];
@@ -45906,12 +46061,14 @@ class LineGraph {
45906
46061
  for(let j = 0, jl = chainidArray.length; j < jl; ++j) {
45907
46062
  let chainid = chainidArray[j];
45908
46063
 
45909
- let domainAtomsArray = this.getDomainAtomsArray(chainid);
45910
-
46064
+ let domainAtomsArray = this.getDomainAtomsArray(chainid, bRerun);
46065
+
45911
46066
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
45912
46067
  if(!ic.domainid2score) ic.domainid2score = {};
45913
46068
 
45914
46069
  for(let k = 0, kl = domainAtomsArray.length; k < kl; ++k) {
46070
+ bNoMoreIg = false;
46071
+
45915
46072
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
45916
46073
  //let bForceOneDomain = true;
45917
46074
  //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
@@ -46012,6 +46169,8 @@ class LineGraph {
46012
46169
 
46013
46170
  await thisClass.parseAlignData(dataArray3, domainidpairArray3);
46014
46171
  }
46172
+
46173
+ return bNoMoreIg;
46015
46174
  /*
46016
46175
  }
46017
46176
  catch(err) {
@@ -46028,10 +46187,12 @@ class LineGraph {
46028
46187
  */
46029
46188
  }
46030
46189
 
46031
- getDomainAtomsArray(chainid) { let ic = this.icn3d, me = ic.icn3dui;
46190
+ getDomainAtomsArray(chainid, bRerunDomain) { let ic = this.icn3d, me = ic.icn3dui;
46032
46191
  let domainAtomsArray = [];
46033
46192
 
46034
- let minResidues = 20;
46193
+ let minResidues = 20, minAtoms = 200;
46194
+
46195
+ if(!ic.chainid2atomsLeft) ic.chainid2atomsLeft = {};
46035
46196
 
46036
46197
  if(!ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]).serial)
46037
46198
  && !ic.proteins.hasOwnProperty(ic.firstAtomObjCls.getMiddleAtomObj(ic.chains[chainid]).serial)) return domainAtomsArray;
@@ -46040,18 +46201,37 @@ class LineGraph {
46040
46201
  let currAtoms = me.hashUtilsCls.intHash(ic.chains[chainid], ic.hAtoms);
46041
46202
  if(Object.keys(currAtoms).length == 0) return domainAtomsArray;
46042
46203
 
46204
+ if(bRerunDomain) {
46205
+ let atomsAssigned = {};
46206
+ for(let resid in ic.resid2refnum_ori) {
46207
+ atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
46208
+ }
46209
+ // for(let resid in ic.resid2refnum) {
46210
+ // if(ic.resid2refnum[resid]) atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
46211
+ // }
46212
+
46213
+ currAtoms = me.hashUtilsCls.exclHash(currAtoms, atomsAssigned);
46214
+
46215
+ // no need to rerun the rest residues any more
46216
+ if(ic.chainid2atomsLeft[chainid] == Object.keys(currAtoms).length) {
46217
+ return domainAtomsArray;
46218
+ }
46219
+
46220
+ ic.chainid2atomsLeft[chainid] = Object.keys(currAtoms).length;
46221
+
46222
+ if(Object.keys(currAtoms).length < minAtoms) return domainAtomsArray;
46223
+ }
46224
+
46043
46225
  // align each 3D domain with reference structure
46044
46226
  //let result = ic.domain3dCls.c2b_NewSplitChain(ic.chains[chainid]);
46045
46227
  // assign ref numbers to selected residues
46046
- let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms);
46228
+ let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
46047
46229
  let subdomains = result.subdomains;
46048
46230
  let pos2resi = result.pos2resi;
46049
46231
 
46050
46232
  if(subdomains.length <= 1) {
46051
- //domainAtomsArray.push(ic.chains[chainid]);
46052
- domainAtomsArray.push(currAtoms);
46053
-
46054
46233
  let residueArray = ic.resid2specCls.atoms2residues(Object.keys(currAtoms));
46234
+ if(residueArray.length < minResidues) return domainAtomsArray;
46055
46235
 
46056
46236
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(currAtoms);
46057
46237
  let atomLast = ic.firstAtomObjCls.getLastAtomObj(currAtoms);
@@ -46062,31 +46242,41 @@ class LineGraph {
46062
46242
  ic.resid2domainid[resid] = chainid + '-0' + '_' + resiSum;
46063
46243
 
46064
46244
  // clear previous refnum assignment if any
46065
- if(ic.resid2refnum && ic.resid2refnum[resid]) {
46245
+ // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
46246
+ // if(ic.resid2refnum && ic.resid2refnum[resid]) {
46066
46247
  delete ic.resid2refnum[resid];
46067
- }
46248
+ delete ic.residIgLoop[resid];
46249
+ // }
46068
46250
  }
46251
+
46252
+ domainAtomsArray.push(currAtoms);
46069
46253
  }
46070
46254
  else {
46071
46255
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
46072
46256
  let domainAtoms = {};
46073
46257
  let segArray = subdomains[k];
46074
46258
 
46259
+ let resCnt = 0;
46075
46260
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
46076
46261
  let startResi = segArray[m];
46077
46262
  let endResi = segArray[m+1];
46078
46263
  for(let n = parseInt(startResi); n <= parseInt(endResi); ++n) {
46079
46264
  let resid = chainid + '_' + pos2resi[n];
46265
+ ++resCnt;
46080
46266
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
46081
46267
  //ic.resid2domainid[resid] = chainid + '-' + k;
46082
46268
 
46083
46269
  // clear previous refnum assignment if any
46084
- if(ic.resid2refnum && ic.resid2refnum[resid]) {
46270
+ // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
46271
+ // if(ic.resid2refnum && ic.resid2refnum[resid]) {
46085
46272
  delete ic.resid2refnum[resid];
46086
- }
46273
+ delete ic.residIgLoop[resid];
46274
+ // }
46087
46275
  }
46088
46276
  }
46089
46277
 
46278
+ if(resCnt < minResidues) continue;
46279
+
46090
46280
  domainAtomsArray.push(domainAtoms);
46091
46281
 
46092
46282
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtoms);
@@ -46171,12 +46361,14 @@ class LineGraph {
46171
46361
 
46172
46362
  for(let i = 0, il = domainidpairArray.length; i < il; ++i) {
46173
46363
  //let queryData = (me.bNode) ? dataArray[i] : dataArray[i].value; //[0];
46174
- let queryData = dataArray[i].value; //[0];
46364
+ let queryData = (dataArray[i]) ? dataArray[i].value : undefined; //[0];
46175
46365
 
46176
46366
  if(!queryData || queryData.length == 0) {
46177
46367
  if(!me.bNode) console.log("The alignment data for " + domainidpairArray[i] + " is unavailable...");
46178
46368
  continue;
46179
46369
  }
46370
+
46371
+ if(queryData[0].score === undefined) continue;
46180
46372
 
46181
46373
  //let domainid_index = domainidpairArray[i].split(',');
46182
46374
  //let domainid = domainid_index[0];
@@ -46209,31 +46401,45 @@ class LineGraph {
46209
46401
 
46210
46402
  // Ig-like domains: B (2150, 2150a, 2150b), C (3150, 3250), E (7150, 7250), F (8150, 8250) strands
46211
46403
  // Ig domain may require G (7050). But we'll leave that out for now.
46212
- if(!bRound1) {
46404
+ if(!bRound1 && queryData[0].segs) {
46213
46405
  let bBstrand = false, bCstrand = false, bEstrand = false, bFstrand = false;
46214
- for(let i = 0, il = queryData[0].segs.length; i < il; ++i) {
46215
- let seg = queryData[0].segs[i];
46406
+ let bBSheet = true, bCSheet = true, bESheet = true, bFSheet = true;
46407
+ let chainid = domainid.split(',')[0];
46408
+
46409
+ for(let j = 0, jl = queryData[0].segs.length; j < jl; ++j) {
46410
+ let seg = queryData[0].segs[j];
46411
+ let resi = seg.t_start;
46412
+ let resid = chainid + '_' + resi;
46216
46413
 
46217
46414
  if(seg.q_start.indexOf('2550') != -1) {
46218
46415
  bBstrand = true;
46416
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
46417
+ bBSheet = (atom.ss == 'sheet');
46219
46418
  }
46220
46419
  else if(seg.q_start.indexOf('3550') != -1) {
46221
46420
  bCstrand = true;
46421
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
46422
+ bBSheet = (atom.ss == 'sheet');
46222
46423
  }
46223
46424
  else if(seg.q_start.indexOf('7550') != -1) {
46224
46425
  bEstrand = true;
46426
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
46427
+ bBSheet = (atom.ss == 'sheet');
46225
46428
  }
46226
46429
  else if(seg.q_start.indexOf('8550') != -1) {
46227
46430
  bFstrand = true;
46431
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
46432
+ bBSheet = (atom.ss == 'sheet');
46228
46433
  }
46229
46434
 
46230
46435
  //if(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand) break;
46231
46436
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
46232
46437
  }
46233
46438
 
46234
- //if(!(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand)) continue;
46235
- if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
46236
- if(!me.bNode) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
46439
+ if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
46440
+ //if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
46441
+ if(!me.bNode && !(bBstrand && bCstrand && bEstrand && bFstrand)) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
46442
+ if(!me.bNode && !(bBSheet && bCSheet && bESheet && bFSheet)) console.log("Some of the Ig strands B, C, E, F are not beta sheets...");
46237
46443
  if(ic.domainid2refpdbname[domainid] == refpdbname) {
46238
46444
  delete ic.domainid2refpdbname[domainid];
46239
46445
  delete ic.domainid2score[domainid];
@@ -46370,11 +46576,12 @@ class LineGraph {
46370
46576
 
46371
46577
  // assign ic.resid2refnum, ic.refnum2residArray, ic.chainsMapping
46372
46578
  if(!ic.resid2refnum) ic.resid2refnum = {};
46579
+ if(!ic.resid2refnum_ori) ic.resid2refnum_ori = {};
46373
46580
  if(!ic.refnum2residArray) ic.refnum2residArray = {};
46374
46581
  if(!ic.chainsMapping) ic.chainsMapping = {};
46375
46582
 
46376
46583
  if(!ic.refPdbList) ic.refPdbList = [];
46377
-
46584
+
46378
46585
  for(let chainid in chainid2segs) {
46379
46586
  let segArray = chainid2segs[chainid];
46380
46587
 
@@ -46393,10 +46600,79 @@ class LineGraph {
46393
46600
  }
46394
46601
  ic.refPdbList.push(message);
46395
46602
 
46396
- let prevStrand;
46397
- let bCd19 = refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
46603
+ // adjust C' and D strands ======start
46604
+ let bCstrand = false, bCpstrand = false, bCppstrand = false, bDstrand = false, bEstrand = false;
46605
+ let CAtom, CpAtom, DAtom, EAtom;
46606
+ //let chainid = domainid.split(',')[0];
46607
+
46608
+ let cntBtwCE;
46609
+ let CpToDResi = [], DToCpResi = [];
46398
46610
  for(let i = 0, il = segArray.length; i < il; ++i) {
46399
46611
  let seg = segArray[i];
46612
+ if(!seg) continue;
46613
+
46614
+ let resi = seg.t_start;
46615
+ let resid = chainid + '_' + resi;
46616
+
46617
+ if(seg.q_start.indexOf('3550') != -1) {
46618
+ bCstrand = true;
46619
+ CAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
46620
+
46621
+ // a chain could have multiple Ig domains
46622
+ cntBtwCE = 0;
46623
+ }
46624
+ else if(seg.q_start.indexOf('4550') != -1) {
46625
+ bCpstrand = true;
46626
+ CpAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
46627
+ ++cntBtwCE;
46628
+ }
46629
+ // else if(seg.q_start.indexOf('5550') != -1) {
46630
+ // bCppstrand = true;
46631
+ // CppAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
46632
+ // ++cntBtwCE;
46633
+ // }
46634
+ else if(seg.q_start.indexOf('6550') != -1) {
46635
+ bDstrand = true;
46636
+ DAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
46637
+ ++cntBtwCE;
46638
+ }
46639
+ else if(seg.q_start.indexOf('7550') != -1) {
46640
+ bEstrand = true;
46641
+ EAtom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
46642
+
46643
+ // check C' and D strands
46644
+ if(cntBtwCE == 1) {
46645
+ let distToC = (bCpstrand) ? CpAtom.coord.distanceTo(CAtom.coord) : DAtom.coord.distanceTo(CAtom.coord);
46646
+ let distToE = (bCpstrand) ? CpAtom.coord.distanceTo(EAtom.coord) : DAtom.coord.distanceTo(EAtom.coord);
46647
+ distToC = parseInt(distToC);
46648
+ distToE = parseInt(distToE);
46649
+
46650
+ let resiDistToC = (bCpstrand) ? parseInt(CpAtom.resi) - parseInt(CAtom.resi) : parseInt(DAtom.resi) - parseInt(CAtom.resi);
46651
+ let resiDistToE = (bCpstrand) ? parseInt(EAtom.resi) - parseInt(CpAtom.resi) : parseInt(EAtom.resi) - parseInt(DAtom.resi);
46652
+
46653
+ if(bCpstrand) {
46654
+ if(distToC > distToE || (distToC == distToE && resiDistToC > resiDistToE)) { // rename C' to D
46655
+ CpToDResi.push(CpAtom.resi);
46656
+ }
46657
+ }
46658
+ else if(bDstrand) {
46659
+ if(distToC < distToE || (distToC == distToE && resiDistToC < resiDistToE)) { // rename D to C'
46660
+ DToCpResi.push(DAtom.resi);
46661
+ }
46662
+ }
46663
+ }
46664
+ }
46665
+
46666
+ if(bCstrand && bCpstrand && bCppstrand && bDstrand && bEstrand) break;
46667
+ }
46668
+
46669
+
46670
+ let currStrand;
46671
+ refpdbnameArray.length == 1 && refpdbnameArray[0] == 'CD19_6al5A_human_C2orV-n1';
46672
+ for(let i = 0, il = segArray.length; i < il; ++i) {
46673
+ let seg = segArray[i];
46674
+ if(!seg) continue;
46675
+
46400
46676
  let qStart = seg.q_start;
46401
46677
  parseInt(seg.q_start);
46402
46678
  if(isNaN(seg.q_start)) seg.q_start.substr(seg.q_start.length - 1, 1);
@@ -46413,10 +46689,33 @@ class LineGraph {
46413
46689
  //let refnum = qStart + postfix;
46414
46690
  let refnum = qStart;
46415
46691
 
46416
- let refnumLabel = this.getLabelFromRefnum(refnum, prevStrand, bCd19);
46417
- prevStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
46692
+ let refnumLabel = this.getLabelFromRefnum(refnum);
46693
+ currStrand = (refnumLabel) ? refnumLabel.replace(new RegExp(refnum,'g'), '') : undefined;
46418
46694
 
46419
- ic.resid2refnum[resid] = refnumLabel;
46695
+ let currStrandFinal = currStrand;
46696
+ if(currStrand == "C'" && CpToDResi.length > 0) {
46697
+ for(let j = 0, jl = CpToDResi.length; j < jl; ++j) {
46698
+ if(parseInt(seg.t_start) < parseInt(CpToDResi[j]) + 10 && parseInt(seg.t_start) > parseInt(CpToDResi[j]) - 10 ) {
46699
+ currStrandFinal = "D";
46700
+ break;
46701
+ }
46702
+ }
46703
+ }
46704
+ else if(currStrand == "D" && DToCpResi.length > 0) {
46705
+ for(let j = 0, jl = DToCpResi.length; j < jl; ++j) {
46706
+ if(parseInt(seg.t_start) < parseInt(DToCpResi[j]) + 10 && parseInt(seg.t_start) > parseInt(DToCpResi[j]) - 10 ) {
46707
+ currStrandFinal = "C'";
46708
+ break;
46709
+ }
46710
+ }
46711
+ }
46712
+
46713
+ if(currStrand != currStrandFinal) {
46714
+ refnumLabel = this.getLabelFromRefnum(refnum, currStrandFinal);
46715
+ }
46716
+
46717
+ ic.resid2refnum[resid] = refnumLabel;
46718
+ ic.resid2refnum_ori[resid] = refnumLabel;
46420
46719
 
46421
46720
  // final reference numbers will be assign in ic.showSeqCls.showRefNum()
46422
46721
 
@@ -46458,7 +46757,7 @@ class LineGraph {
46458
46757
  }
46459
46758
  }
46460
46759
 
46461
- getLabelFromRefnum(oriRefnum, prevStrand, bCd19) { let ic = this.icn3d; ic.icn3dui;
46760
+ getLabelFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
46462
46761
  let refnum = parseInt(oriRefnum);
46463
46762
 
46464
46763
  //N-terminus = 0999-0001
@@ -46485,28 +46784,34 @@ class LineGraph {
46485
46784
 
46486
46785
  // loops may have numbers such as 1310, 1410
46487
46786
 
46488
- if(refnum < 1000) return undefined;
46489
- else if(refnum >= 1200 && refnum < 1290) return "A---" + oriRefnum;
46490
- else if(refnum >= 1320 && refnum < 1390) return "A--" + oriRefnum;
46491
- else if(refnum >= 1420 && refnum < 1490) return "A-" + oriRefnum;
46492
- else if(refnum >= 1520 && refnum < 1590) return "A" + oriRefnum;
46493
- else if(refnum >= 1620 && refnum < 1690) return "A+" + oriRefnum;
46494
- else if(refnum >= 1820 && refnum < 1890) return "A'" + oriRefnum;
46495
- else if(refnum >= 2000 && refnum < 2900) return "B" + oriRefnum;
46496
- else if(refnum >= 3300 && refnum < 3390) return "C--" + oriRefnum;
46497
- else if(refnum >= 3420 && refnum < 3490) return "C-" + oriRefnum;
46498
- else if(refnum >= 3520 && refnum < 3590) return "C" + oriRefnum;
46499
- else if(refnum >= 4000 && refnum < 4900) return "C'" + oriRefnum;
46500
- else if(refnum >= 5000 && refnum < 5900) return "C''" + oriRefnum;
46501
- else if(refnum >= 6000 && refnum < 6900) return "D" + oriRefnum;
46502
- else if(refnum >= 7500 && refnum < 7590) return "E" + oriRefnum;
46503
- else if(refnum >= 7620 && refnum < 7900) return "E+" + oriRefnum;
46504
- else if(refnum >= 8000 && refnum < 8900) return "F" + oriRefnum;
46505
- else if(refnum >= 9500 && refnum < 9590) return "G" + oriRefnum;
46506
- else if(refnum >= 9620 && refnum < 9690) return "G+" + oriRefnum;
46507
- else if(refnum >= 9720 && refnum < 9790) return "G++" + oriRefnum;
46508
- else if(refnum > 9900) return undefined;
46509
- else return " " + oriRefnum; }
46787
+ let refnumLabel;
46788
+
46789
+ if(refnum < 1000) refnumLabel = undefined;
46790
+ else if(refnum >= 1200 && refnum < 1290) refnumLabel = "A---" + oriRefnum;
46791
+ else if(refnum >= 1320 && refnum < 1390) refnumLabel = "A--" + oriRefnum;
46792
+ else if(refnum >= 1420 && refnum < 1490) refnumLabel = "A-" + oriRefnum;
46793
+ else if(refnum >= 1520 && refnum < 1590) refnumLabel = "A" + oriRefnum;
46794
+ else if(refnum >= 1620 && refnum < 1690) refnumLabel = "A+" + oriRefnum;
46795
+ else if(refnum >= 1820 && refnum < 1890) refnumLabel = "A'" + oriRefnum;
46796
+ else if(refnum >= 2000 && refnum < 2900) refnumLabel = "B" + oriRefnum;
46797
+ else if(refnum >= 3300 && refnum < 3390) refnumLabel = "C--" + oriRefnum;
46798
+ else if(refnum >= 3420 && refnum < 3490) refnumLabel = "C-" + oriRefnum;
46799
+ else if(refnum >= 3520 && refnum < 3590) refnumLabel = "C" + oriRefnum;
46800
+ else if(refnum >= 4000 && refnum < 4900) refnumLabel = "C'" + oriRefnum;
46801
+ else if(refnum >= 5000 && refnum < 5900) refnumLabel = "C''" + oriRefnum;
46802
+ else if(refnum >= 6000 && refnum < 6900) refnumLabel = "D" + oriRefnum;
46803
+ else if(refnum >= 7500 && refnum < 7590) refnumLabel = "E" + oriRefnum;
46804
+ else if(refnum >= 7620 && refnum < 7900) refnumLabel = "E+" + oriRefnum;
46805
+ else if(refnum >= 8000 && refnum < 8900) refnumLabel = "F" + oriRefnum;
46806
+ else if(refnum >= 9500 && refnum < 9590) refnumLabel = "G" + oriRefnum;
46807
+ else if(refnum >= 9620 && refnum < 9690) refnumLabel = "G+" + oriRefnum;
46808
+ else if(refnum >= 9720 && refnum < 9790) refnumLabel = "G++" + oriRefnum;
46809
+ else if(refnum > 9900) refnumLabel = undefined;
46810
+ else refnumLabel = " " + oriRefnum;
46811
+ if(prevStrand) refnumLabel = prevStrand + oriRefnum;
46812
+
46813
+ return refnumLabel
46814
+ }
46510
46815
 
46511
46816
  async parseCustomRefFile(data) { let ic = this.icn3d; ic.icn3dui;
46512
46817
  ic.bShowCustomRefnum = true;
@@ -50642,7 +50947,7 @@ class Dsn6Parser {
50642
50947
  return sigma;
50643
50948
  }
50644
50949
 
50645
- loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d; ic.icn3dui;
50950
+ loadDsn6Data(dsn6data, type, sigma, location, bInputSigma) { let ic = this.icn3d, me = ic.icn3dui;
50646
50951
  // DSN6 http://www.uoxray.uoregon.edu/tnt/manual/node104.html
50647
50952
  // BRIX http://svn.cgl.ucsf.edu/svn/chimera/trunk/libs/VolumeData/dsn6/brix-1.html
50648
50953
 
@@ -50719,6 +51024,8 @@ class Dsn6Parser {
50719
51024
  summand = intView[ 16 ];
50720
51025
  }
50721
51026
 
51027
+ if(!me.bNode) console.log("header: " + JSON.stringify(header));
51028
+
50722
51029
  let data = new Float32Array(
50723
51030
  header.xExtent * header.yExtent * header.zExtent
50724
51031
  );
@@ -51916,8 +52223,11 @@ class MmcifParser {
51916
52223
  }
51917
52224
 
51918
52225
  async downloadMmcifSymmetry(mmcifid, type) { let ic = this.icn3d, me = ic.icn3dui;
52226
+ try {
51919
52227
  // https://files.rcsb.org/header/ is not accessible in Node.js and Mac
51920
- let url = (me.bNode || me.utilsCls.isMac()) ? "https://files.rcsb.org/view/" + mmcifid + ".cif" : "https://files.rcsb.org/header/" + mmcifid + ".cif";
52228
+ // Some header files are in the wrong format. So we use the full mmCIF file
52229
+ //let url = (me.bNode || me.utilsCls.isMac()) ? "https://files.rcsb.org/view/" + mmcifid + ".cif" : "https://files.rcsb.org/header/" + mmcifid + ".cif";
52230
+ let url = "https://files.rcsb.org/view/" + mmcifid + ".cif";
51921
52231
 
51922
52232
  //ic.bCid = undefined;
51923
52233
  let data1 = await me.getAjaxPromise(url, 'text', false, "The structure " + mmcifid + " was not found...");
@@ -51979,6 +52289,11 @@ class MmcifParser {
51979
52289
  }
51980
52290
 
51981
52291
  ///// if(ic.deferredSymmetry !== undefined) ic.deferredSymmetry.resolve();
52292
+ }
52293
+ catch (err) {
52294
+ if(!me.bNode) console.log("mmcifparser.cgi issues: " + err);
52295
+ return;
52296
+ }
51982
52297
  }
51983
52298
 
51984
52299
  //Atom "data" from mmCIF file was parsed to set up parameters for the 3D viewer by calling the function
@@ -58800,6 +59115,8 @@ class LoadPDB {
58800
59115
 
58801
59116
  let bHeader = false, bFirstAtom = true;
58802
59117
 
59118
+ let segId, prevSegId;
59119
+
58803
59120
  for (let i in lines) {
58804
59121
  let line = lines[i];
58805
59122
  let record = line.substr(0, 6);
@@ -58959,11 +59276,36 @@ class LoadPDB {
58959
59276
  ic.pmid = line.substr(19).trim();
58960
59277
  }
58961
59278
  } else if (record === 'ATOM ' || record === 'HETATM') {
59279
+ //73 - 76 LString(4) segID Segment identifier, left-justified.
59280
+ // deal with PDBs from MD trajectories
59281
+ segId = line.substr(72, 4).trim();
59282
+
58962
59283
  if(bFirstAtom) {
58963
59284
  structure = this.getStructureId(id, moleculeNum, bMutation);
58964
59285
 
58965
59286
  bFirstAtom = false;
58966
59287
  }
59288
+ else if(segId != prevSegId) {
59289
+ ++moleculeNum;
59290
+ id = ic.defaultPdbId;
59291
+
59292
+ structure = this.getStructureId(id, moleculeNum, bMutation);
59293
+
59294
+ //helices = [];
59295
+ //sheets = [];
59296
+ if(!bNMR) {
59297
+ sheetArray = [];
59298
+ sheetStart = [];
59299
+ sheetEnd = [];
59300
+ helixArray = [];
59301
+ helixStart = [];
59302
+ helixEnd = [];
59303
+ }
59304
+
59305
+ bHeader = false; // reinitialize to read structure name from the header
59306
+ }
59307
+
59308
+ prevSegId = segId;
58967
59309
 
58968
59310
  let alt = line.substr(16, 1);
58969
59311
  //if (alt !== " " && alt !== "A") continue;
@@ -61733,6 +62075,22 @@ class ApplyCommand {
61733
62075
  else if(command.indexOf('hide ref number') == 0) {
61734
62076
  ic.bShownRefnum = false;
61735
62077
  }
62078
+ else if(command.indexOf('translate pdb') == 0) {
62079
+ let xyz = command.substr(14 + 1).split(' ');
62080
+
62081
+ ic.transformCls.translateCoord(ic.hAtoms, parseFloat(xyz[0]), parseFloat(xyz[1]), parseFloat(xyz[2]));
62082
+ ic.drawCls.draw();
62083
+ }
62084
+ else if(command.indexOf('rotate pdb') == 0) {
62085
+ let mArray = command.substr(10 + 1).split(',');
62086
+ let mArrayFloat = [];
62087
+ for(let i = 0, il = mArray.length; i < il; ++i) {
62088
+ mArrayFloat.push(parseFloat(mArray[i]));
62089
+ }
62090
+
62091
+ ic.transformCls.rotateCoord(ic.hAtoms, mArrayFloat);
62092
+ ic.drawCls.draw();
62093
+ }
61736
62094
 
61737
62095
  // special, select ==========
61738
62096
 
@@ -62913,6 +63271,14 @@ class SelectCollections {
62913
63271
  ic.transformCls.zoominSelection();
62914
63272
  ic.definedSetsCls.showSets();
62915
63273
 
63274
+ ic.bResetAnno = true;
63275
+ if(ic.bAnnoShown) {
63276
+ await ic.showAnnoCls.showAnnotations();
63277
+
63278
+ ic.hlUpdateCls.updateHlAll(nameArray);
63279
+ // show selected chains in annotation window
63280
+ ic.annotationCls.showAnnoSelectedChains();
63281
+ }
62916
63282
 
62917
63283
  await ic.drawCls.draw();
62918
63284
  ic.saveFileCls.showTitle();
@@ -63999,6 +64365,9 @@ class SelectByCommand {
63999
64365
  }
64000
64366
  else {
64001
64367
  chainStr = testStr.substr(periodPos + 1);
64368
+ //replace "A_1" with "A"
64369
+ chainStr = chainStr.replace(/_/g, '');
64370
+
64002
64371
  testStr = testStr.substr(0, periodPos);
64003
64372
  }
64004
64373
 
@@ -69861,7 +70230,7 @@ class ResizeCanvas {
69861
70230
  //let itemArray = ['dl_selectannotations', 'dl_alignment', 'dl_2ddgm', 'dl_definedsets', 'dl_graph',
69862
70231
  // 'dl_linegraph', 'dl_scatterplot', 'dl_contactmap', 'dl_allinteraction', 'dl_copyurl',
69863
70232
  // 'dl_symmetry', 'dl_symd', 'dl_rmsd', 'dl_legend', 'dl_disttable'];
69864
- 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'];
70233
+ 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'];
69865
70234
 
69866
70235
  for(let i in itemArray) {
69867
70236
  let item = itemArray[i];
@@ -70025,6 +70394,8 @@ class Transform {
70025
70394
  }
70026
70395
 
70027
70396
  setRotation(axis, angle) { let ic = this.icn3d, me = ic.icn3dui;
70397
+ if(!axis) return;
70398
+
70028
70399
  if(ic.bControlGl && !me.bNode && window.cam) {
70029
70400
  axis.applyQuaternion( window.cam.quaternion ).normalize();
70030
70401
  }
@@ -70089,6 +70460,25 @@ class Transform {
70089
70460
  if(ic.bRender) ic.drawCls.render();
70090
70461
  }
70091
70462
 
70463
+ translateCoord(atoms, dx, dy, dz) { let ic = this.icn3d; ic.icn3dui;
70464
+ for(let i in atoms) {
70465
+ let atom = ic.atoms[i];
70466
+ atom.coord.x += dx;
70467
+ atom.coord.y += dy;
70468
+ atom.coord.z += dz;
70469
+ }
70470
+ }
70471
+
70472
+ rotateCoord(atoms, mArray) { let ic = this.icn3d; ic.icn3dui;
70473
+ const m = new THREE.Matrix4();
70474
+ m.elements = mArray;
70475
+
70476
+ for(let i in atoms) {
70477
+ let atom = ic.atoms[i];
70478
+ atom.coord = atom.coord.applyMatrix4(m);
70479
+ }
70480
+ }
70481
+
70092
70482
  //Center on the selected atoms and zoom in.
70093
70483
  zoominSelection(atoms) { let ic = this.icn3d, me = ic.icn3dui;
70094
70484
  let para = {};
@@ -70646,7 +71036,7 @@ class SaveFile {
70646
71036
  // }
70647
71037
 
70648
71038
  // export assembly symmetry matrix "BIOMT"
70649
- if(ic.biomtMatrices) {
71039
+ if(ic.biomtMatrices && Object.keys(atomHash).length == Object.keys(ic.atoms).length) {
70650
71040
  let stru = Object.keys(ic.structures)[0];
70651
71041
  for(let m = 0, ml = ic.biomtMatrices.length; m < ml; ++m) {
70652
71042
  let mNum = m + 1;
@@ -74416,7 +74806,7 @@ class iCn3DUI {
74416
74806
  //even when multiple iCn3D viewers are shown together.
74417
74807
  this.pre = this.cfg.divid + "_";
74418
74808
 
74419
- this.REVISION = '3.29.2';
74809
+ this.REVISION = '3.29.4';
74420
74810
 
74421
74811
  // In nodejs, iCn3D defines "window = {navigator: {}}"
74422
74812
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -75036,8 +75426,8 @@ iCn3DUI.prototype.getAjaxPostPromise = async function(url, data, beforeSend, ale
75036
75426
  },
75037
75427
  error : function() {
75038
75428
  //if(alertMess) var aaa = 1; //alert(alertMess);
75039
- if(alertMess) console.log(alertMess);
75040
- if(logMess) console.log(logMess);
75429
+ if(!me.bNode && alertMess) console.log(alertMess);
75430
+ if(!me.bNode && logMess) console.log(logMess);
75041
75431
 
75042
75432
  // reject('error');
75043
75433
  // keep running the program