icn3d 3.29.12 → 3.29.15

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
@@ -8309,6 +8309,26 @@ class ClickMenu {
8309
8309
  await ic.annotationCls.setAnnoTabIg(bSelection, template);
8310
8310
  });
8311
8311
 
8312
+ me.myEventCls.onIds("#" + me.pre + "mn6_alignrefTpl", "click", async function(e) { me.icn3d; //e.preventDefault();
8313
+ me.htmlCls.dialogCls.openDlg('dl_alignrefTpl', 'Align with an Ig template');
8314
+ });
8315
+
8316
+ me.myEventCls.onIds("#" + me.pre + "mn6_alignrefTpl_apply", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
8317
+ if(!me.cfg.notebook) dialog.dialog( "close" );
8318
+
8319
+ let template = $("#" + me.pre + "refTpl2").val();
8320
+
8321
+ // load the template
8322
+ let url = me.htmlCls.baseUrl + "icn3d/refpdb/" + template + ".pdb";
8323
+ await ic.pdbParserCls.downloadUrl(url, 'pdb', undefined, template);
8324
+ thisClass.setLogCmd('load url ' + url + ' | type pdb', true);
8325
+
8326
+ // align the template with the selection
8327
+ me.cfg.aligntool = 'tmalign';
8328
+ await ic.realignParserCls.realignOnStructAlign();
8329
+ thisClass.setLogCmd('realign on tmalign', true);
8330
+ });
8331
+
8312
8332
  me.myEventCls.onIds("#" + me.pre + "mn6_igrefNo", "click", async function(e) { let ic = me.icn3d; //e.preventDefault();
8313
8333
  thisClass.setLogCmd('ig refnum off', true);
8314
8334
  await ic.refnumCls.hideIgRefNum();
@@ -10660,11 +10680,14 @@ class SetMenu {
10660
10680
  /*
10661
10681
  html += this.getLink('mn6_igrefYes', 'Show Ig for Selection', undefined, 2);
10662
10682
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
10683
+ html += this.getLink('mn6_alignrefTpl', 'Align w/ Specified Template', undefined, 2);
10663
10684
  html += this.getLink('mn6_igrefNo', 'Reset Ig Ref. Number', undefined, 2);
10664
10685
 
10665
10686
  html += this.getMenuSep();
10666
10687
  */
10667
10688
 
10689
+
10690
+
10668
10691
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
10669
10692
  html += "</ul>";
10670
10693
  html += "</li>";
@@ -12811,8 +12834,24 @@ class SetDialog {
12811
12834
  html += me.htmlCls.divStr + "dl_igrefTpl' class='" + dialogClass + "'>";
12812
12835
  html += this.addNotebookTitle('dl_igrefTpl', 'Choose an Ig template');
12813
12836
  html += "<span style='white-space:nowrap;font-weight:bold;'>Choose an Ig template for selected residues:</span> <br><br><select id='" + me.pre + "refTpl'>";
12837
+ html += this.setTemplateMenu();
12838
+ html += "</select><br><br><span style='white-space:nowrap;'>" + me.htmlCls.buttonStr + "mn6_igrefTpl_apply'>Show Ig Ref. Number</button></span>";
12839
+ html += "</div>";
12840
+
12841
+ html += me.htmlCls.divStr + "dl_alignrefTpl' class='" + dialogClass + "'>";
12842
+ html += this.addNotebookTitle('dl_alignrefTpl', 'Align with an Ig template');
12843
+ html += "<span style='white-space:nowrap;font-weight:bold;'>Choose an Ig template to align with selected residues:</span> <br><br><select id='" + me.pre + "refTpl2'>";
12844
+ html += this.setTemplateMenu();
12845
+ html += "</select><br><br><span style='white-space:nowrap;'>" + me.htmlCls.buttonStr + "mn6_alignrefTpl_apply'>Align Template with Selection</button></span>";
12846
+ html += "</div>";
12814
12847
 
12815
- //html += me.htmlCls.setHtmlCls.getOptionHtml(['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100'], 3);
12848
+ html += "</div>";
12849
+ html += "<!--/form-->";
12850
+
12851
+ return html;
12852
+ }
12853
+
12854
+ setTemplateMenu() { let me = this.icn3dui; me.icn3d;
12816
12855
  let group2tpl = {};
12817
12856
  group2tpl['V'] = ['CD28_1yjdC_human_V', 'CD2_1hnfA_human_V-n1', 'CD8a_1cd8A_human_V', 'FAB-HEAVY_5esv_V-n1', 'FAB-LIGHT_5esv_V-n1', 'ICOS_6x4gA_human_V', 'LAG3_7tzgD_human_V-n1', 'PDL1_4z18B_human_V-n1', 'PD1_4zqkB_human_V', 'TCRa_6jxrm_human_V-n1', 'VISTA_6oilA_human_V', 'VNAR_1t6vN_shark_V'];
12818
12857
  group2tpl['C1'] = ['B2Microglobulin_7phrL_human_C1', 'FAB-LIGHT_5esv_C1-n2', 'FAB-HEAVY_5esv_C1-n2', 'GHR_1axiB_human_FN3-n1', 'MHCIa_7phrH_human_C1', 'TCRa_6jxrm_human_C1-n2', 'VTCN1_Q7Z7D3_human_V-n2'];
@@ -12826,6 +12865,7 @@ class SetDialog {
12826
12865
 
12827
12866
  group2tpl['Other'] = ['CuZnSuperoxideDismutase_1hl5C_human', 'ECadherin_4zt1A_human_n2', 'LaminAC_1ifrA_human', 'ORF7a_1xakA_virus'];
12828
12867
 
12868
+ let html = '';
12829
12869
  for(let group in group2tpl) {
12830
12870
  html += "<optgroup label='" + group + "'>";
12831
12871
  for(let i = 0, il = group2tpl[group].length; i < il; ++i) {
@@ -12835,12 +12875,6 @@ class SetDialog {
12835
12875
  html += "</optgroup>";
12836
12876
  }
12837
12877
 
12838
- html += "</select><br><br><span style='white-space:nowrap;'>" + me.htmlCls.buttonStr + "mn6_igrefTpl_apply'>Show Ig Ref. Number</button></span>";
12839
- html += "</div>";
12840
-
12841
- html += "</div>";
12842
- html += "<!--/form-->";
12843
-
12844
12878
  return html;
12845
12879
  }
12846
12880
 
@@ -12880,6 +12914,7 @@ class SetDialog {
12880
12914
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_ig'>Ig Domains" + me.htmlCls.space2 + "</span></td>";
12881
12915
  */
12882
12916
 
12917
+
12883
12918
  html += "<td></td>";
12884
12919
  html += "</tr></table></div></div>";
12885
12920
 
@@ -37644,7 +37679,7 @@ class AnnoCddSite {
37644
37679
  let fromArray = [], toArray = [];
37645
37680
  let resiHash = {};
37646
37681
  let resCnt = 0;
37647
- let segArray =(type == 'domain') ? domainRepeatArray[r].segs : [domainRepeatArray[r]];
37682
+ let segArray =(type == 'domain' || type == 'ig') ? domainRepeatArray[r].segs : [domainRepeatArray[r]];
37648
37683
  for(let s = 0, sl = segArray.length; s < sl; ++s) {
37649
37684
  let domainFrom = Math.round(segArray[s].from);
37650
37685
  let domainTo = Math.round(segArray[s].to);
@@ -37748,7 +37783,7 @@ class AnnoCddSite {
37748
37783
 
37749
37784
  if(me.cfg.blast_rep_id != chnid) { // regular
37750
37785
  for(let i = 0, il = fromArray.length; i < il; ++i) {
37751
- let color = this.getColorFromPos(chnid, i, titleArray);
37786
+ let color = this.getColorFromPos(chnid, fromArray[i], titleArray);
37752
37787
 
37753
37788
  let emptyWidth;
37754
37789
  if(titleArray) {
@@ -37775,7 +37810,7 @@ class AnnoCddSite {
37775
37810
  toArray2.push(toArray[i]);
37776
37811
  }
37777
37812
  for(let i = 0, il = fromArray2.length; i < il; ++i) {
37778
- let color = this.getColorFromPos(chnid, i, titleArray);
37813
+ let color = this.getColorFromPos(chnid, fromArray2[i], titleArray);
37779
37814
 
37780
37815
  html2 += ic.showSeqCls.insertGapOverview(chnid, fromArray2[i]);
37781
37816
  let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray2[i] - ic.baseResi[chnid] - 1) /(ic.maxAnnoLength + ic.nTotalGap)) : Math.round(ic.seqAnnWidth *(fromArray2[i] - toArray2[i-1] - 1) /(ic.maxAnnoLength + ic.nTotalGap));
@@ -38485,7 +38520,7 @@ class AnnoIg {
38485
38520
  if(ic.bShowRefnum && ic.chainid2refpdbname.hasOwnProperty(chnid) && ic.chainid2refpdbname[chnid].length > 0) {
38486
38521
  let giSeq = ic.showSeqCls.getSeq(chnid);
38487
38522
  let result = ic.annoIgCls.showAllRefNum(giSeq, chnid);
38488
-
38523
+
38489
38524
  html += result.html;
38490
38525
  html2 += result.html2;
38491
38526
  html3 += result.html3;
@@ -38499,38 +38534,12 @@ class AnnoIg {
38499
38534
  showAllRefNum(giSeq, chnid) { let ic = this.icn3d; ic.icn3dui;
38500
38535
  let html = '', html2 = '', html3 = '';
38501
38536
 
38502
- let result = this.showRefNum(giSeq, chnid);
38503
- html += result.html;
38504
- html2 += result.html2;
38505
- html3 += result.html3;
38506
-
38507
- let kabat_or_imgt = 1;
38508
- result = this.showRefNum(giSeq, chnid, kabat_or_imgt);
38509
- html += result.html;
38510
- html2 += result.html2;
38511
- html3 += result.html3;
38512
-
38513
- kabat_or_imgt = 2;
38514
- result = this.showRefNum(giSeq, chnid, kabat_or_imgt);
38515
- html += result.html;
38516
- html2 += result.html2;
38517
- html3 += result.html3;
38518
-
38519
- return {'html': html, 'html2': html2, 'html3': html3};
38520
- }
38521
-
38522
- showRefNum(giSeq, chnid, kabat_or_imgt, bCustom) { let ic = this.icn3d, me = ic.icn3dui;
38523
- let html = '', html2 = '', html3 = '';
38524
-
38525
- if(!ic.chainid2refpdbname[chnid]) return {html: html, html2: html2, html3: html3};
38526
-
38527
38537
  //check if Kabat refnum available
38528
38538
  let bKabatFound = false;
38529
-
38530
38539
  for(let i = 0, il = giSeq.length; i < il; ++i) {
38531
38540
  let currResi = ic.ParserUtilsCls.getResi(chnid, i);
38532
38541
  let residueid = chnid + '_' + currResi;
38533
- let domainid = (bCustom) ? 0 : ic.resid2domainid[residueid];
38542
+ let domainid = ic.resid2domainid[residueid];
38534
38543
 
38535
38544
  if(ic.domainid2ig2kabat[domainid] && Object.keys(ic.domainid2ig2kabat[domainid]).length > 0) {
38536
38545
  bKabatFound = true;
@@ -38538,473 +38547,52 @@ class AnnoIg {
38538
38547
  }
38539
38548
  }
38540
38549
 
38541
- if(kabat_or_imgt == 1 && !bKabatFound) {
38542
- return {html: '', html2: '', html3: ''};
38543
- }
38544
-
38545
38550
  //check if IMGT refnum available
38546
38551
  let bImgtFound = false;
38547
38552
  for(let i = 0, il = giSeq.length; i < il; ++i) {
38548
38553
  let currResi = ic.ParserUtilsCls.getResi(chnid, i);
38549
38554
  let residueid = chnid + '_' + currResi;
38550
- let domainid = (bCustom) ? 0 : ic.resid2domainid[residueid];
38555
+ let domainid = ic.resid2domainid[residueid];
38551
38556
 
38552
38557
  if(ic.domainid2ig2imgt[domainid] && Object.keys(ic.domainid2ig2imgt[domainid]).length > 0) {
38553
38558
  bImgtFound = true;
38554
38559
  break;
38555
38560
  }
38556
38561
  }
38557
- if(kabat_or_imgt == 2 && !bImgtFound) {
38558
- return {html: '', html2: '', html3: ''};
38559
- }
38560
38562
 
38561
- // auto-generate ref numbers for loops
38562
- let currStrand = '', prevStrand = '';
38563
- let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c, refnum2c;
38564
- let bExtendedStrand = false, bSecThird9 = false;
38565
-
38566
- // sometimes one chain may have several Ig domains,set an index for each IgDomain
38567
- let index = 1, bStart = false;
38563
+ let result = this.showRefNum(giSeq, chnid);
38564
+ html += result.html;
38565
+ html2 += result.html2;
38566
+ html3 += result.html3;
38568
38567
 
38569
- if(!bCustom && !kabat_or_imgt && !me.bNode) { // do not overwrite loops in node
38570
- // reset ic.residIgLoop for the current selection, which could be the second round of ref num assignment
38571
- // just current chain
38572
- let atomHash = me.hashUtilsCls.intHash(ic.chains[chnid], ic.hAtoms);
38573
- ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
38574
-
38575
- // for(let resid in residHash) {
38576
- // // not in loop any more if you assign ref numbers multiple times
38577
- // delete ic.residIgLoop[resid];
38578
- // }
38568
+ let kabat_or_imgt = 1;
38569
+ if(!bKabatFound) {
38570
+ return {html: html, html2: html2, html3: html3};
38571
+ }
38572
+ else {
38573
+ result = this.showRefNum(giSeq, chnid, kabat_or_imgt);
38574
+ html += result.html;
38575
+ html2 += result.html2;
38576
+ html3 += result.html3;
38579
38577
  }
38580
38578
 
38581
- // 1. get the range of each strand excluding loops
38582
- let strandArray = [], strandHash = {}, strandCnt = 0, resCnt = 0, resCntBfAnchor = 0, resCntAtAnchor = 0;
38583
- let bFoundAnchor = false;
38584
- if(!bCustom && !kabat_or_imgt) {
38585
- for(let i = 0, il = giSeq.length; i < il; ++i, ++resCnt, ++resCntBfAnchor, ++resCntAtAnchor) {
38586
- let currResi = ic.ParserUtilsCls.getResi(chnid, i);
38587
- let residueid = chnid + '_' + currResi;
38588
-
38589
- refnumLabel = ic.resid2refnum[residueid];
38590
-
38591
- let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : '';
38592
- if(!bStart && refnumLabel && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
38593
- bStart = true;
38594
- resCnt = 1; // the first one is included
38595
- bFoundAnchor = false;
38596
- }
38597
-
38598
- if((prevStrand.substr(0,1) == 'F' || prevStrand.substr(0,1) == 'G') && !refnumLabel) { // indicate the end of an IG domain
38599
- bStart = false;
38600
- }
38601
-
38602
- if(refnumLabel) {
38603
- refnumStr_ori = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
38604
- currStrand = refnumLabel.replace(new RegExp(refnumStr_ori,'g'), '');
38605
- refnumStr_ori.substr(0, 1);
38606
-
38607
- refnumStr = refnumStr_ori;
38608
- refnum = parseInt(refnumStr);
38609
- refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
38610
- refnum2c = (refnum - parseInt(refnum/100) * 100).toString();
38611
-
38612
- // for extended strands, since A is 1550 and A+ is 1650, then the AA+ loop will be 1591, 1592, ... 1610, 1611, etc
38613
- bSecThird9 = refnum3c.substr(0,1) == '9' || refnum2c.substr(0,1) == '9' || refnum2c.substr(0,1) == '0' || refnum2c.substr(0,1) == '1';
38614
- if(bSecThird9) ic.residIgLoop[residueid] = 1;
38615
-
38616
- strandPostfix = refnumStr.replace(refnum.toString(), '');
38617
-
38618
- postfix = strandPostfix + '_' + index;
38619
-
38620
- let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
38621
- bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
38622
-
38623
- if(currStrand && currStrand != ' ') {
38624
- if(!bSecThird9 || (bExtendedStrand && !bSecThird9)) {
38625
- let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
38626
-
38627
- if(currStrand != prevStrand) { // reset currCnt
38628
- bFoundAnchor = false;
38629
-
38630
- if(strandHash[currStrand + postfix]) {
38631
- ++index;
38632
- postfix = refnumStr.replace(refnum.toString(), '') + '_' + index;
38633
- }
38634
-
38635
- strandHash[currStrand + postfix] = 1;
38636
-
38637
- strandArray[strandCnt] = {};
38638
- strandArray[strandCnt].startResi = currResi;
38639
- strandArray[strandCnt].startRefnum = refnum; // 1250 in A1250a
38640
-
38641
- resCntBfAnchor = 0;
38642
-
38643
- strandArray[strandCnt].endResi = currResi;
38644
- strandArray[strandCnt].endRefnum = refnum; // 1250a
38645
-
38646
- if(lastTwo == 50) {
38647
- strandArray[strandCnt].anchorRefnum = refnum;
38648
- strandArray[strandCnt].resCntBfAnchor = resCntBfAnchor;
38649
-
38650
- resCntAtAnchor = 0;
38651
-
38652
- bFoundAnchor = true;
38653
- }
38654
-
38655
- // in case A1550 is not found, but A1551 is found
38656
- if(!bFoundAnchor && (lastTwo == 51 || lastTwo == 52 || lastTwo == 53) ) {
38657
- let offset = lastTwo - 50;
38658
- strandArray[strandCnt].anchorRefnum = refnum - offset;
38659
- strandArray[strandCnt].resCntBfAnchor = resCntBfAnchor - offset;
38660
-
38661
- resCntAtAnchor = offset;
38662
-
38663
- bFoundAnchor = true;
38664
- }
38665
-
38666
- if(bExtendedStrand) {
38667
- strandArray[strandCnt].anchorRefnum = 0;
38668
- }
38669
-
38670
- strandArray[strandCnt].strandPostfix = strandPostfix; // a in A1250a
38671
- strandArray[strandCnt].strand = currStrand; // A in A1250a
38672
-
38673
- strandArray[strandCnt].postfix = postfix; // Aa_1
38674
-
38675
- strandArray[strandCnt].loopResCnt = resCnt - 1;
38676
-
38677
- ++strandCnt;
38678
- resCnt = 0;
38679
- }
38680
- else {
38681
- if(strandHash[currStrand + postfix]) {
38682
- if(lastTwo == 50) {
38683
- strandArray[strandCnt - 1].anchorRefnum = refnum;
38684
- strandArray[strandCnt - 1].resCntBfAnchor = resCntBfAnchor;
38685
-
38686
- // update
38687
- strandArray[strandCnt - 1].startRefnum = strandArray[strandCnt - 1].anchorRefnum - strandArray[strandCnt - 1].resCntBfAnchor;
38688
-
38689
- resCntAtAnchor = 0;
38690
-
38691
- bFoundAnchor = true;
38692
- }
38693
-
38694
- // in case A1550 is not found, but A1551 is found
38695
- if(!bFoundAnchor && (lastTwo == 51 || lastTwo == 52 || lastTwo == 53) ) {
38696
- let offset = lastTwo - 50;
38697
- strandArray[strandCnt - 1].anchorRefnum = refnum - offset;
38698
- strandArray[strandCnt - 1].resCntBfAnchor = resCntBfAnchor - offset;
38699
-
38700
- // update
38701
- strandArray[strandCnt - 1].startRefnum = strandArray[strandCnt - 1].anchorRefnum - strandArray[strandCnt - 1].resCntBfAnchor;
38702
-
38703
- resCntAtAnchor = offset;
38704
-
38705
- bFoundAnchor = true;
38706
- }
38707
-
38708
- if(bExtendedStrand) {
38709
- strandArray[strandCnt - 1].anchorRefnum = 0;
38710
- }
38711
-
38712
- strandArray[strandCnt - 1].endResi = currResi;
38713
- strandArray[strandCnt - 1].endRefnum = refnum; // 1250a
38714
- strandArray[strandCnt - 1].resCntAtAnchor = resCntAtAnchor;
38715
-
38716
- if(strandArray[strandCnt - 1].anchorRefnum) {
38717
- strandArray[strandCnt - 1].endRefnum = strandArray[strandCnt - 1].anchorRefnum + strandArray[strandCnt - 1].resCntAtAnchor;
38718
- }
38719
-
38720
- resCnt = 0;
38721
- }
38722
- }
38723
- }
38724
- }
38725
- }
38726
-
38727
- prevStrand = currStrand;
38728
- }
38729
-
38730
- // 2. remove strands with less than 3 residues except G strand
38731
- for(let il = strandArray.length, i = il - 1; i >= 0; --i) {
38732
- if(strandArray[i].strand.substr(0, 1) != 'G' && strandArray[i].endRefnum - strandArray[i].startRefnum + 1 < 3) { // remove the strand
38733
- if(i != il - 1) { // modify
38734
- strandArray[i + 1].loopResCnt += strandArray[i].loopResCnt + parseInt(strandArray[i].endResi) - parseInt(strandArray[i].startResi) + 1;
38735
- }
38736
-
38737
- strandArray.splice(i, 1);
38738
- }
38739
- }
38740
-
38741
- // 2b. extend the strand to end of sheet
38742
- let maxExtend = 8;
38743
- for(let i = 0, il = strandArray.length; i < il; ++i) {
38744
- let startAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].startResi]);
38745
- let endAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].endResi]);
38746
-
38747
- let startPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].startResi);
38748
- let endPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].endResi);
38749
-
38750
- if(startAtom.ss == 'sheet' && !startAtom.ssbegin) {
38751
- for(let j = 1; j <= maxExtend; ++j) {
38752
- let currPos = startPos - j;
38753
- let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
38754
- if(i > 0 && parseInt(currResi) <= parseInt(strandArray[i-1].endResi)) break;
38755
-
38756
- let currResid = chnid + '_' + currResi;
38757
- let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
38758
- if(currAtom.ssbegin) { // find the start of the sheet
38759
- // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
38760
- strandArray[i].startResi = currResi;
38761
- strandArray[i].startRefnum -= j;
38762
- strandArray[i].loopResCnt -= j;
38763
- if(strandArray[i].loopResCnt < 0) strandArray[i].loopResCnt = 0;
38764
- strandArray[i].resCntBfAnchor += j;
38765
-
38766
- // update ic.resid2refnum
38767
- for(let k = 1; k <= j; ++k) {
38768
- currPos = startPos - k;
38769
- currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
38770
- let currResid = chnid + '_' + currResi;
38771
- delete ic.residIgLoop[currResid];
38772
- }
38773
-
38774
- break;
38775
- }
38776
- }
38777
- }
38778
-
38779
- if(endAtom.ss == 'sheet' && !endAtom.ssend) {
38780
- for(let j = 1; j <= maxExtend; ++j) {
38781
- let currPos = endPos + j;
38782
- let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
38783
- if(i < il - 1 && parseInt(currResi) >= parseInt(strandArray[i+1].startResi)) break;
38784
-
38785
- let currResid = chnid + '_' + currResi;
38786
- let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
38787
- if(currAtom.ssend) { // find the end of the sheet
38788
- // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
38789
- strandArray[i].endResi = currResi;
38790
- strandArray[i].endRefnum += j;
38791
- if(i < il - 1) {
38792
- strandArray[i + 1].loopResCnt -= j;
38793
- if(strandArray[i + 1].loopResCnt < 0) strandArray[i + 1].loopResCnt = 0;
38794
- }
38795
- strandArray[i].resCntAtAnchor += j;
38796
-
38797
- // update ic.residIgLoop[resid];
38798
- for(let k = 1; k <= j; ++k) {
38799
- currPos = endPos + k;
38800
- currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
38801
- let currResid = chnid + '_' + currResi;
38802
- delete ic.residIgLoop[currResid];
38803
- }
38804
-
38805
- break;
38806
- }
38807
- }
38808
- }
38809
- }
38810
-
38811
- // 3. assign refnumLabel for each resid
38812
- strandCnt = 0;
38813
- let loopCnt = 0;
38814
-
38815
- let bBeforeAstrand = true, bAfterGstrand = true, refnumLabelNoPostfix, prevStrandCnt = 0, currRefnum;
38816
- bStart = false;
38817
- let refnumInStrand = 0;
38818
- if(strandArray.length > 0) {
38819
- for(let i = 0, il = giSeq.length; i < il; ++i, ++loopCnt, ++refnumInStrand) {
38820
- let currResi = ic.ParserUtilsCls.getResi(chnid, i);
38821
- let residueid = chnid + '_' + currResi;
38822
- refnumLabel = ic.resid2refnum[residueid];
38823
-
38824
- currStrand = strandArray[strandCnt].strand;
38825
-
38826
- if(refnumLabel) {
38827
- refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
38828
- currRefnum = parseInt(refnumStr);
38829
- refnumLabelNoPostfix = currStrand + currRefnum;
38830
-
38831
- currStrand = refnumLabel.replace(new RegExp(refnumStr,'g'), '');
38832
-
38833
- let firstChar = refnumLabel.substr(0,1);
38834
- if(!bStart && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
38835
- bStart = true;
38836
- bBeforeAstrand = true;
38837
- loopCnt = 0;
38838
- }
38839
- }
38840
-
38841
- let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[residueid]);
38842
-
38843
- // skip non-protein residues
38844
- if(!atom || !ic.proteins.hasOwnProperty(atom.serial)) {
38845
- refnumLabel = undefined;
38846
- }
38847
- else {
38848
- let bBefore = false, bInRange= false, bAfter = false;
38849
- // 100, 100A
38850
- if(parseInt(currResi) == parseInt(strandArray[strandCnt].startResi) && currResi != strandArray[strandCnt].startResi) {
38851
- bBefore = currResi < strandArray[strandCnt].startResi;
38852
- }
38853
- else {
38854
- bBefore = parseInt(currResi) < parseInt(strandArray[strandCnt].startResi);
38855
- }
38856
-
38857
- // 100, 100A
38858
- if(parseInt(currResi) == parseInt(strandArray[strandCnt].endResi) && currResi != strandArray[strandCnt].endResi) {
38859
- bAfter = currResi > strandArray[strandCnt].endResi;
38860
- }
38861
- else {
38862
- bAfter = parseInt(currResi) > parseInt(strandArray[strandCnt].endResi);
38863
- }
38864
-
38865
- bInRange = (!bBefore && !bAfter) ? true : false;
38866
-
38867
- if(bBefore) {
38868
- ic.residIgLoop[residueid] = 1;
38869
-
38870
- if(bBeforeAstrand) { // make it continuous to the 1st strand
38871
- if(bStart) {
38872
- currRefnum = strandArray[strandCnt].startRefnum - strandArray[strandCnt].loopResCnt + loopCnt;
38873
- refnumLabelNoPostfix = strandArray[strandCnt].strand + currRefnum;
38874
- refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
38875
- }
38876
- else {
38877
- //loopCnt = 0;
38878
- refnumLabelNoPostfix = undefined;
38879
- refnumLabel = undefined;
38880
- }
38881
- }
38882
- else {
38883
- if(prevStrandCnt >= 0
38884
- && (strandArray[prevStrandCnt].strand.substr(0, 1) == 'F' || strandArray[prevStrandCnt].strand.substr(0, 1) == 'G')) {
38885
- if(!bAfterGstrand) {
38886
- //loopCnt = 0;
38887
- refnumLabelNoPostfix = undefined;
38888
- refnumLabel = undefined;
38889
- }
38890
- else {
38891
- if(bStart && ic.resid2refnum[residueid]) {
38892
- bAfterGstrand = true;
38893
-
38894
- currRefnum = strandArray[prevStrandCnt].endRefnum + loopCnt;
38895
- refnumLabelNoPostfix = strandArray[prevStrandCnt].strand + currRefnum;
38896
- refnumLabel = refnumLabelNoPostfix + strandArray[prevStrandCnt].strandPostfix;
38897
- }
38898
- else {
38899
- bStart = false;
38900
- bBeforeAstrand = true;
38901
- //loopCnt = 0;
38902
-
38903
- bAfterGstrand = false;
38904
-
38905
- refnumLabelNoPostfix = undefined;
38906
- refnumLabel = undefined;
38907
- }
38908
- }
38909
- }
38910
- else {
38911
- bAfterGstrand = true; // reset
38912
-
38913
- let len = strandArray[strandCnt].loopResCnt;
38914
- let halfLen = parseInt(len / 2.0 + 0.5);
38915
-
38916
- if(loopCnt <= halfLen) {
38917
- currRefnum = strandArray[prevStrandCnt].endRefnum + loopCnt;
38918
- refnumLabelNoPostfix = strandArray[prevStrandCnt].strand + currRefnum;
38919
- refnumLabel = refnumLabelNoPostfix + strandArray[prevStrandCnt].strandPostfix;
38920
- }
38921
- else {
38922
- currRefnum = strandArray[strandCnt].startRefnum - len + loopCnt - 1;
38923
- refnumLabelNoPostfix = strandArray[strandCnt].strand + currRefnum;
38924
- refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
38925
- }
38926
- }
38927
- }
38928
- }
38929
- else if(bInRange) {
38930
- // not in loop any more if you assign ref numbers multiple times
38931
- //delete ic.residIgLoop[residueid];
38932
-
38933
- bBeforeAstrand = false;
38934
-
38935
- if(strandArray[strandCnt].anchorRefnum) { // use anchor to name refnum
38936
- if(currResi == strandArray[strandCnt].startResi) {
38937
- refnumInStrand = strandArray[strandCnt].anchorRefnum - strandArray[strandCnt].resCntBfAnchor;
38938
- strandArray[strandCnt].startRefnum = refnumInStrand;
38939
- }
38940
- else if(currResi == strandArray[strandCnt].endResi) {
38941
- strandArray[strandCnt].endRefnum = refnumInStrand;
38942
- }
38943
-
38944
- refnumLabelNoPostfix = strandArray[strandCnt].strand + refnumInStrand;
38945
- refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
38946
- }
38947
-
38948
- if(currResi == strandArray[strandCnt].endResi) {
38949
- ++strandCnt; // next strand
38950
- loopCnt = 0;
38951
-
38952
- if(!strandArray[strandCnt]) { // last strand
38953
- --strandCnt;
38954
- }
38955
- }
38956
- }
38957
- else if(bAfter) {
38958
- ic.residIgLoop[residueid] = 1;
38959
-
38960
- if(!bAfterGstrand) {
38961
- refnumLabelNoPostfix = undefined;
38962
- refnumLabel = undefined;
38963
- }
38964
- else {
38965
- // C-terminal
38966
- if(!ic.resid2refnum[residueid]) {
38967
- bAfterGstrand = false;
38968
-
38969
- refnumLabelNoPostfix = undefined;
38970
- refnumLabel = undefined;
38971
- }
38972
- else {
38973
- bAfterGstrand = true;
38974
-
38975
- currRefnum = strandArray[strandCnt].endRefnum + loopCnt;
38976
- refnumLabelNoPostfix = strandArray[strandCnt].strand + currRefnum;
38977
- refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
38978
- }
38979
- }
38980
- }
38981
- }
38982
-
38983
- prevStrand = currStrand;
38984
- prevStrandCnt = strandCnt - 1;
38985
-
38986
- // assign the adjusted reference numbers
38987
- ic.resid2refnum[residueid] = refnumLabel;
38988
-
38989
- refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
38990
-
38991
- if(!ic.refnum2residArray.hasOwnProperty(refnumStr)) {
38992
- ic.refnum2residArray[refnumStr] = [residueid];
38993
- }
38994
- else {
38995
- ic.refnum2residArray[refnumStr].push(residueid);
38996
- }
38579
+ kabat_or_imgt = 2;
38580
+ if(!bImgtFound) {
38581
+ return {html: html, html2: html2, html3: html3};
38582
+ }
38583
+ else {
38584
+ result = this.showRefNum(giSeq, chnid, kabat_or_imgt);
38585
+ html += result.html;
38586
+ html2 += result.html2;
38587
+ html3 += result.html3;
38588
+ }
38997
38589
 
38998
- if(!ic.chainsMapping.hasOwnProperty(chnid)) {
38999
- ic.chainsMapping[chnid] = {};
39000
- }
38590
+ return {html: html, html2: html2, html3: html3};
38591
+ }
39001
38592
 
39002
- // remove the postfix when comparing interactions
39003
- //ic.chainsMapping[chnid][residueid] = refnumLabel;
39004
- ic.chainsMapping[chnid][residueid] = refnumLabelNoPostfix;
39005
- }
39006
- }
39007
- }
38593
+ showRefNum(giSeq, chnid, kabat_or_imgt, bCustom) { let ic = this.icn3d; ic.icn3dui;
38594
+ let bResult = ic.chainid2igtrack[chnid];
38595
+ if(!bResult) return {html: '', html2: '', html3: ''};
39008
38596
 
39009
38597
  // add color to atoms
39010
38598
  if(ic.bShowRefnum) {
@@ -39022,15 +38610,11 @@ class AnnoIg {
39022
38610
  if(!ic.chain2igArray) ic.chain2igArray = {};
39023
38611
  ic.chain2igArray[chnid] = [];
39024
38612
 
39025
- let igElem = {};
39026
- let currStrand_ori;
39027
- let prevStrand = undefined;
39028
- let prevPos;
39029
-
39030
38613
  let bLoop = false, currStrand = '';
39031
38614
  let refnumLabel, refnumStr_ori, refnumStr;
39032
38615
 
39033
38616
  // show tracks
38617
+ let domainid2respos = {};
39034
38618
  let htmlIg = '';
39035
38619
  for(let i = 0, il = giSeq.length; i < il; ++i) {
39036
38620
  htmlIg += ic.showSeqCls.insertGap(chnid, i, '-');
@@ -39038,6 +38622,7 @@ class AnnoIg {
39038
38622
  let currResi = ic.ParserUtilsCls.getResi(chnid, i);
39039
38623
  let residueid = chnid + '_' + currResi;
39040
38624
  let domainid = (bCustom) ? 0 : ic.resid2domainid[residueid];
38625
+
39041
38626
  //if(!ic.residues.hasOwnProperty(residueid)) {
39042
38627
  // htmlIg += '<span></span>';
39043
38628
  //}
@@ -39045,10 +38630,12 @@ class AnnoIg {
39045
38630
  refnumLabel = ic.resid2refnum[residueid];
39046
38631
  let bHidelabel = false;
39047
38632
 
39048
- if(refnumLabel) {
38633
+ if(refnumLabel) {
38634
+ if(!domainid2respos[domainid]) domainid2respos[domainid] = [];
38635
+ domainid2respos[domainid].push(i);
38636
+
39049
38637
  refnumStr_ori = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
39050
38638
  currStrand = refnumLabel.replace(new RegExp(refnumStr_ori,'g'), '');
39051
- currStrand_ori = currStrand;
39052
38639
 
39053
38640
  refnumStr_ori.substr(0, 1);
39054
38641
 
@@ -39064,21 +38651,6 @@ class AnnoIg {
39064
38651
  else {
39065
38652
  refnumStr = refnumStr_ori;
39066
38653
  }
39067
-
39068
- let prevStrandFirstLet = (prevStrand) ? prevStrand.substr(0, 1) : '';
39069
- let currStrandFirstLet = (currStrand) ? currStrand.substr(0, 1) : '';
39070
-
39071
- if(prevStrand != currStrand && (!prevStrandFirstLet || prevStrandFirstLet == 'F' || prevStrandFirstLet == 'G') && (currStrandFirstLet == 'A' || currStrandFirstLet == 'B') ) { // a new Ig domain starts
39072
- if(prevStrand) {
39073
- igElem.endPos = prevPos;
39074
- ic.chain2igArray[chnid].push(igElem);
39075
- }
39076
-
39077
- igElem = {};
39078
- igElem.startPos = i;
39079
- }
39080
-
39081
- if(domainid) igElem.domainid = domainid;
39082
38654
 
39083
38655
  if(bCustom) {
39084
38656
  if(!refnumStr) {
@@ -39124,9 +38696,6 @@ class AnnoIg {
39124
38696
  htmlIg += '<span></span>';
39125
38697
  }
39126
38698
  }
39127
-
39128
- prevStrand = currStrand_ori; //currStrand;
39129
- prevPos = i;
39130
38699
  }
39131
38700
  else {
39132
38701
  htmlIg += '<span></span>';
@@ -39134,10 +38703,33 @@ class AnnoIg {
39134
38703
  //}
39135
38704
  }
39136
38705
 
39137
- igElem.endPos = prevPos;
39138
- ic.chain2igArray[chnid].push(igElem);
38706
+ // igElem.endPos = prevPos;
38707
+ // ic.chain2igArray[chnid].push(igElem);
38708
+
38709
+ for(let domainid in domainid2respos) {
38710
+ let posArray = domainid2respos[domainid];
38711
+ let pos, prevPos, startPosArray = [], endPosArray = [];
38712
+ for(let i = 0, il = posArray.length; i < il; ++i) {
38713
+ pos = posArray[i];
38714
+ if(i == 0) startPosArray.push(pos);
38715
+
38716
+ if(i > 0 && pos != prevPos + 1) { // a new range
38717
+ endPosArray.push(prevPos);
38718
+ startPosArray.push(pos);
38719
+ }
38720
+
38721
+ prevPos = pos;
38722
+ }
38723
+ endPosArray.push(pos);
39139
38724
 
39140
- if(me.bNode) return {html: '', html2: '', html3: ''};
38725
+ let igElem = {};
38726
+ igElem.domainid = domainid;
38727
+ igElem.startPosArray = startPosArray;
38728
+ igElem.endPosArray = endPosArray;
38729
+ ic.chain2igArray[chnid].push(igElem);
38730
+ }
38731
+
38732
+ if(me.bNode) return {html: html, html2: html2, html3: html3}
39141
38733
  let titleSpace = 120;
39142
38734
 
39143
38735
  let linkStr = 'icn3d-link icn3d-blue';
@@ -39145,10 +38737,16 @@ class AnnoIg {
39145
38737
 
39146
38738
  let igCnt = ic.chain2igArray[chnid].length;
39147
38739
  let fromArray = [], toArray = [];
38740
+ let posindex2domainindex = {};
39148
38741
  for(let i = 0; i < igCnt; ++i) {
39149
38742
  let igElem = ic.chain2igArray[chnid][i];
39150
- fromArray.push(igElem.startPos);
39151
- toArray.push(igElem.endPos);
38743
+ fromArray = fromArray.concat(igElem.startPosArray);
38744
+ toArray = toArray.concat(igElem.endPosArray);
38745
+
38746
+ for(let j = 0, jl = igElem.startPosArray.length; j < jl; ++j) {
38747
+ let pos = igElem.startPosArray[j];
38748
+ posindex2domainindex[pos] = i;
38749
+ }
39152
38750
  }
39153
38751
 
39154
38752
  // let htmlCnt = '<span class="icn3d-residueNum" title="Ig domain count">' + igCnt.toString() + ' Igs</span>';
@@ -39180,11 +38778,6 @@ class AnnoIg {
39180
38778
  html3 += htmlTmp + '<br>';
39181
38779
  html += htmlTmp + '<span class="icn3d-seqLine">';
39182
38780
 
39183
- // summary html2
39184
- html2 += htmlTitle;
39185
- html2 += htmlCnt + '<span class="icn3d-seqLine">';
39186
-
39187
-
39188
38781
  html += htmlIg;
39189
38782
 
39190
38783
  html += htmlCnt;
@@ -39194,7 +38787,8 @@ class AnnoIg {
39194
38787
  html += '</div>';
39195
38788
 
39196
38789
  let igArray = ic.chain2igArray[chnid];
39197
- if(igArray.length == 0) return {html: '', html2: '', html3: ''};
38790
+
38791
+ if(igArray.length == 0) return {html: html, html2: html2, html3: html3}
39198
38792
  let rangeArray = [], titleArray = [], fullTitleArray = [], domainArray = [];
39199
38793
 
39200
38794
  for(let i = 0, il = igArray.length; i < il; ++i) {
@@ -39204,45 +38798,59 @@ class AnnoIg {
39204
38798
 
39205
38799
  let tmscore = info.score;
39206
38800
  let igType = ic.ref2igtype[info.refpdbname];
39207
- titleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + ')');
39208
- fullTitleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + '), template: ' + info.refpdbname + ', Seq. identity: ' + parseFloat(info.seqid).toFixed(2) + ', aligned residues: ' + info.nresAlign);
38801
+ let confidance = (parseFloat(tmscore) < 0.75 ) ? '?' : '';
38802
+ titleArray.push(igType + confidance + ' (TM:' + parseFloat(tmscore).toFixed(2) + ')');
38803
+ fullTitleArray.push(igType + confidance + ' (TM:' + parseFloat(tmscore).toFixed(2) + '), template: ' + info.refpdbname + ', Seq. identity: ' + parseFloat(info.seqid).toFixed(2) + ', aligned residues: ' + info.nresAlign);
39209
38804
  domainArray.push(igType);
39210
38805
 
38806
+ let segs = [];
38807
+ for(let j = 0, jl = igArray[i].startPosArray.length; j < jl; ++j) {
38808
+ segs.push({"from":igArray[i].startPosArray[j], "to":igArray[i].endPosArray[j]});
38809
+ }
39211
38810
  let range = {};
39212
- range.locs = [{"from":igArray[i].startPos, "to":igArray[i].endPos}];
38811
+ range.locs = [{"segs": segs}];
39213
38812
  rangeArray.push(range);
39214
38813
  }
39215
- if(titleArray.length == 0) return {html: '', html2: '', html3: ''};
38814
+
38815
+ if(titleArray.length == 0) return {html: html, html2: html2, html3: html3}
39216
38816
 
39217
38817
  // add tracks for the summary view
39218
- for(let i = 0, il = fromArray.length; i < il; ++i) {
39219
- let resi = ic.ParserUtilsCls.getResi(chnid, fromArray[i]);
39220
- let resid = chnid + "_" + resi;
39221
- let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
39222
- let colorStr =(!atom || atom.color === undefined || atom.color.getHexString() === 'FFFFFF') ? 'DDDDDD' : atom.color.getHexString();
39223
- let color =(atom && atom.color !== undefined) ? colorStr : "CCCCCC";
38818
+ if(!kabat_or_imgt && !bCustom) {
38819
+ // summary html2
38820
+ html2 += htmlTitle;
38821
+ html2 += htmlCnt + '<span class="icn3d-seqLine">';
39224
38822
 
39225
- let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i]) / ic.maxAnnoLength) :
39226
- Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
39227
- html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
39228
- html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(toArray[i] - fromArray[i] + 1) / ic.maxAnnoLength) + 'px;" class="icn3d-seqTitle ' + linkStr + '" ig="0" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + domainArray[i] + '" index="0" setname="' + chnid + '_igs" id="' + chnid + '_igs" anno="sequence" chain="' + chnid + '" title="' + domainArray[i] + '">' + domainArray[i] + ' </div>';
39229
- }
38823
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
38824
+ let resi = ic.ParserUtilsCls.getResi(chnid, fromArray[i]);
38825
+ let resid = chnid + "_" + resi;
38826
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
38827
+ let colorStr =(!atom || atom.color === undefined || atom.color.getHexString() === 'FFFFFF') ? 'DDDDDD' : atom.color.getHexString();
38828
+ let color =(atom && atom.color !== undefined) ? colorStr : "CCCCCC";
39230
38829
 
39231
- html2 += htmlCnt;
38830
+ let domainindex = posindex2domainindex[fromArray[i]];
39232
38831
 
39233
- html2 += '</div></div>';
39234
- html3 += '</div></div>';
38832
+ let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i]) / ic.maxAnnoLength) :
38833
+ Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
38834
+ html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
38835
+ html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(toArray[i] - fromArray[i] + 1) / ic.maxAnnoLength) + 'px;" class="icn3d-seqTitle ' + linkStr + '" ig="0" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + domainArray[domainindex] + '" index="0" setname="' + chnid + '_igs" id="' + chnid + '_igs" anno="sequence" chain="' + chnid + '" title="' + domainArray[domainindex] + '">' + domainArray[domainindex] + ' </div>';
38836
+ }
39235
38837
 
39236
- // add tracks for each Ig domain
39237
- htmlTmp = '<div id="' + ic.pre + chnid + '_igseq_sequence" class="icn3d-ig icn3d-dl_sequence">';
39238
- let htmlTmp2 = htmlTmp;
39239
- let htmlTmp3 = htmlTmp;
38838
+ html2 += htmlCnt;
39240
38839
 
39241
- let result = ic.annoCddSiteCls.setDomainFeature(rangeArray, chnid, 'ig', htmlTmp, htmlTmp2, htmlTmp3, undefined, titleArray, fullTitleArray);
38840
+ html2 += '</div></div>';
38841
+ html3 += '</div></div>';
39242
38842
 
39243
- html += result.html + '</div>';
39244
- html2 += result.html2 + '</div>';
39245
- html3 += result.html3 + '</div>';
38843
+ // add tracks for each Ig domain
38844
+ htmlTmp = '<div id="' + ic.pre + chnid + '_igseq_sequence" class="icn3d-ig icn3d-dl_sequence">';
38845
+ let htmlTmp2 = htmlTmp;
38846
+ let htmlTmp3 = htmlTmp;
38847
+
38848
+ let result = ic.annoCddSiteCls.setDomainFeature(rangeArray, chnid, 'ig', htmlTmp, htmlTmp2, htmlTmp3, undefined, titleArray, fullTitleArray);
38849
+
38850
+ html += result.html + '</div>';
38851
+ html2 += result.html2 + '</div>';
38852
+ html3 += result.html3 + '</div>';
38853
+ }
39246
38854
 
39247
38855
  return {html: html, html2: html2, html3: html3}
39248
38856
  }
@@ -44187,7 +43795,8 @@ class Annotation {
44187
43795
 
44188
43796
  ic.hlUpdateCls.updateHlAll();
44189
43797
  ic.drawCls.draw();
44190
- }
43798
+ }
43799
+
44191
43800
  }
44192
43801
  }
44193
43802
 
@@ -53797,7 +53406,7 @@ class PdbParser {
53797
53406
  //Load structures from a "URL". Due to the same domain policy of Ajax call, the URL should be in the same
53798
53407
  //domain. "type" could be "pdb", "mol2", "sdf", "xyz", "icn3dpng", or "pae"
53799
53408
  //for pdb file, mol2file, sdf file, xyz file, iCn3D PNG image, and ALphaFold PAE file, respectively.
53800
- async downloadUrl(url, type, command) { let ic = this.icn3d, me = ic.icn3dui;
53409
+ async downloadUrl(url, type, command, template) { let ic = this.icn3d, me = ic.icn3dui;
53801
53410
  let pos = url.lastIndexOf('/');
53802
53411
  if(pos != -1) {
53803
53412
  let posDot = url.lastIndexOf('.');
@@ -53815,9 +53424,19 @@ class PdbParser {
53815
53424
  ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + data : data;
53816
53425
  ic.InputfileType = type;
53817
53426
 
53427
+ // append
53428
+ ic.hAtoms = {};
53429
+ ic.dAtoms = {};
53430
+
53431
+ ic.resetConfig();
53432
+ ic.bResetAnno = true;
53433
+ ic.bResetSets = true;
53434
+
53818
53435
  if(type === 'pdb') {
53819
- await this.loadPdbData(data);
53820
- //await ic.loadScriptCls.loadScript(command, undefined, true);
53436
+ // await this.loadPdbData(data);
53437
+ let bAppend = true;
53438
+ let id = (template) ? template.replace(/_/g, '').substr(0, 4) : undefined;
53439
+ await this.loadPdbData(data, id, undefined, bAppend);
53821
53440
  }
53822
53441
  else if(type === 'mmcif') {
53823
53442
  let url = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi";
@@ -53845,6 +53464,17 @@ class PdbParser {
53845
53464
  let bFull = true;
53846
53465
  ic.contactMapCls.processAfErrorMap(JSON.parse(data), bFull);
53847
53466
  }
53467
+
53468
+ //append
53469
+ if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
53470
+
53471
+ ic.bResetAnno = true;
53472
+
53473
+ if(ic.bAnnoShown) {
53474
+ await ic.showAnnoCls.showAnnotations();
53475
+
53476
+ ic.annotationCls.resetAnnoTabAll();
53477
+ }
53848
53478
  }
53849
53479
 
53850
53480
  //Atom "data" from PDB file was parsed to set up parameters for the 3D viewer. The deferred parameter
@@ -66999,7 +66629,7 @@ class Dssp {
66999
66629
  ic.ref2igtype['BArrestin1_4jqiA_rat_n1'] = 'IgFN3-like';
67000
66630
  ic.ref2igtype['BTLA_2aw2A_human_Iset'] = 'IgI';
67001
66631
  ic.ref2igtype['C3_2qkiD_human_n1'] = 'IgFN3-like';
67002
- ic.ref2igtype['CD19_6al5A_human_C2orV-n1'] = 'other Ig'; //'CD19';
66632
+ ic.ref2igtype['CD19_6al5A_human_C2orV-n1'] = 'CD19';
67003
66633
  ic.ref2igtype['CD28_1yjdC_human_V'] = 'IgV';
67004
66634
  ic.ref2igtype['CD2_1hnfA_human_C2-n2'] = 'IgC2';
67005
66635
  ic.ref2igtype['CD2_1hnfA_human_V-n1'] = 'IgV';
@@ -67010,8 +66640,8 @@ class Dssp {
67010
66640
  ic.ref2igtype['CoAtomerGamma1_1r4xA_human'] = 'IgE';
67011
66641
  ic.ref2igtype['Contactin1_2ee2A_human_FN3-n9'] = 'IgFN3';
67012
66642
  ic.ref2igtype['Contactin1_3s97C_human_C2-n2'] = 'IgC2';
67013
- ic.ref2igtype['CuZnSuperoxideDismutase_1hl5C_human'] = 'other Ig'; //'SOD';
67014
- ic.ref2igtype['ECadherin_4zt1A_human_n2'] = 'other Ig'; //'Cadherin';
66643
+ ic.ref2igtype['CuZnSuperoxideDismutase_1hl5C_human'] = 'SOD';
66644
+ ic.ref2igtype['ECadherin_4zt1A_human_n2'] = 'Cadherin';
67015
66645
  ic.ref2igtype['Endo-1,4-BetaXylanase10A_1i8aA_bacteria_n4'] = 'IgE';
67016
66646
  ic.ref2igtype['FAB-HEAVY_5esv_C1-n2'] = 'IgC1';
67017
66647
  ic.ref2igtype['FAB-HEAVY_5esv_V-n1'] = 'IgV';
@@ -67027,12 +66657,12 @@ class Dssp {
67027
66657
  ic.ref2igtype['JAM1_1nbqA_human_VorIset-n2'] = 'IgI';
67028
66658
  ic.ref2igtype['LAG3_7tzgD_human_C2-n2'] = 'IgC2';
67029
66659
  ic.ref2igtype['LAG3_7tzgD_human_V-n1'] = 'IgV';
67030
- ic.ref2igtype['LaminAC_1ifrA_human'] = 'other Ig'; //'Lamin';
66660
+ ic.ref2igtype['LaminAC_1ifrA_human'] = 'Lamin';
67031
66661
  ic.ref2igtype['MHCIa_7phrH_human_C1'] = 'IgC1';
67032
66662
  ic.ref2igtype['MPT63_1lmiA_bacteria'] = 'IgE';
67033
66663
  ic.ref2igtype['NaCaExchanger_2fwuA_dog_n2'] = 'IgE';
67034
66664
  ic.ref2igtype['NaKATPaseTransporterBeta_2zxeB_spurdogshark'] = 'IgE';
67035
- ic.ref2igtype['ORF7a_1xakA_virus'] = 'other Ig'; //'ORF';
66665
+ ic.ref2igtype['ORF7a_1xakA_virus'] = 'ORF';
67036
66666
  ic.ref2igtype['PD1_4zqkB_human_V'] = 'IgV';
67037
66667
  ic.ref2igtype['PDL1_4z18B_human_V-n1'] = 'IgV';
67038
66668
  ic.ref2igtype['Palladin_2dm3A_human_Iset-n1'] = 'IgI';
@@ -67083,7 +66713,7 @@ class Dssp {
67083
66713
  let numRound = 0;
67084
66714
 
67085
66715
  //while(!bNoMoreIg) {
67086
- while(!bNoMoreIg && numRound < 10) {
66716
+ while(!bNoMoreIg && numRound < 15) {
67087
66717
  let bRerun = true;
67088
66718
  bNoMoreIg = await thisClass.parseRefPdbData(ic.pdbDataArray, template, bRerun);
67089
66719
  ++numRound;
@@ -67122,7 +66752,7 @@ class Dssp {
67122
66752
  for(let j = 0, jl = chainidArray.length; j < jl; ++j) {
67123
66753
  let chainid = chainidArray[j];
67124
66754
 
67125
- // for selected atoms only, assign ic.resid2domainid[resid]
66755
+ // for selected atoms only
67126
66756
  let domainAtomsArray = this.getDomainAtomsArray(chainid, bRerun);
67127
66757
 
67128
66758
  if(!ic.domainid2refpdbname) ic.domainid2refpdbname = {};
@@ -67163,7 +66793,7 @@ class Dssp {
67163
66793
  }
67164
66794
  }
67165
66795
  else {
67166
- ic.domainid2refpdbname[domainid] = template;
66796
+ ic.domainid2refpdbname[domainid] = [template];
67167
66797
  domainidpairArray.push(domainid + "|1" + template); // "1" was added for the first round strand-only template
67168
66798
  }
67169
66799
  }
@@ -67203,9 +66833,6 @@ class Dssp {
67203
66833
  let pdbDataArray = await this.promiseWithFixedJobs(pdbAjaxArray);
67204
66834
 
67205
66835
  for(let domainid in ic.domainid2refpdbname) {
67206
- ic.domainid2refpdbname[domainid];
67207
- domainid.substr(0, domainid.indexOf(','));
67208
-
67209
66836
  let pdb_target = ic.domainid2pdb[domainid];
67210
66837
  for(let index = 0, indexl = pdbDataArray.length; index < indexl; ++index) {
67211
66838
  let struct2 = ic.defaultPdbId + index;
@@ -67266,12 +66893,10 @@ class Dssp {
67266
66893
 
67267
66894
  if(bRerunDomain) {
67268
66895
  let atomsAssigned = {};
66896
+ //ic.resid2refnum_ori should be used
67269
66897
  for(let resid in ic.resid2refnum_ori) {
67270
66898
  atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
67271
66899
  }
67272
- // for(let resid in ic.resid2refnum) {
67273
- // if(ic.resid2refnum[resid]) atomsAssigned = me.hashUtilsCls.unionHash(atomsAssigned, ic.residues[resid]);
67274
- // }
67275
66900
 
67276
66901
  currAtoms = me.hashUtilsCls.exclHash(currAtoms, atomsAssigned);
67277
66902
 
@@ -67295,19 +66920,12 @@ class Dssp {
67295
66920
  if(subdomains.length <= 1) {
67296
66921
  let residueArray = ic.resid2specCls.atoms2residues(Object.keys(currAtoms));
67297
66922
  if(residueArray.length < minResidues) return domainAtomsArray;
67298
- /*
67299
- let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(currAtoms);
67300
- let atomLast = ic.firstAtomObjCls.getLastAtomObj(currAtoms);
67301
- let resiSum = atomFirst.resi + ':' + atomLast.resi + ':' + Object.keys(currAtoms).length;
67302
- */
66923
+
67303
66924
  for(let n = 0, nl = residueArray.length; n < nl; ++n) {
67304
66925
  let resid = residueArray[n];
67305
- /*
67306
- ic.resid2domainid[resid] = chainid + ',0' + '_' + resiSum;
67307
- */
66926
+
67308
66927
  // clear previous refnum assignment if any
67309
- // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
67310
- // if(ic.resid2refnum && ic.resid2refnum[resid]) {
66928
+ // if(bRerunDomain) {
67311
66929
  delete ic.resid2refnum[resid];
67312
66930
  delete ic.residIgLoop[resid];
67313
66931
  // }
@@ -67328,11 +66946,9 @@ class Dssp {
67328
66946
  let resid = chainid + '_' + pos2resi[n];
67329
66947
  ++resCnt;
67330
66948
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
67331
- //ic.resid2domainid[resid] = chainid + '-' + k;
67332
66949
 
67333
66950
  // clear previous refnum assignment if any
67334
- // if(!bRerunDomain && ic.resid2refnum && ic.resid2refnum[resid]) {
67335
- // if(ic.resid2refnum && ic.resid2refnum[resid]) {
66951
+ // if(bRerunDomain) {
67336
66952
  delete ic.resid2refnum[resid];
67337
66953
  delete ic.residIgLoop[resid];
67338
66954
  // }
@@ -67366,7 +66982,7 @@ class Dssp {
67366
66982
  getTemplateList(domainid) { let ic = this.icn3d; ic.icn3dui;
67367
66983
  let refpdbname = '', score = '', seqid = '', nresAlign = '';
67368
66984
 
67369
- refpdbname = ic.domainid2refpdbname[domainid];
66985
+ refpdbname = ic.domainid2refpdbname[domainid][0]; // one template in round 2
67370
66986
 
67371
66987
  if(ic.domainid2score[domainid]) {
67372
66988
  let itemArray = ic.domainid2score[domainid].split('_');
@@ -67386,6 +67002,8 @@ class Dssp {
67386
67002
 
67387
67003
  // find the best alignment for each chain
67388
67004
  let domainid2segs = {};
67005
+ let domainid2strandcnt = {};
67006
+ let domainid2refpdbnamelist = {};
67389
67007
 
67390
67008
  if(!ic.chainid2refpdbname) ic.chainid2refpdbname = {};
67391
67009
  // if(!ic.chainid2score) ic.chainid2score = {};
@@ -67440,7 +67058,6 @@ class Dssp {
67440
67058
  if(!bRound1 && queryData[0].segs) {
67441
67059
  let bBstrand = false, bCstrand = false, bEstrand = false, bFstrand = false;
67442
67060
  let bBSheet = true, bCSheet = true, bESheet = true, bFSheet = true;
67443
- let BCnt = 0, CCnt = 0, ECnt = 0, FCnt = 0;
67444
67061
  let chainid = domainid.split(',')[0];
67445
67062
 
67446
67063
  for(let j = 0, jl = queryData[0].segs.length; j < jl; ++j) {
@@ -67453,38 +67070,33 @@ class Dssp {
67453
67070
  bBstrand = true;
67454
67071
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
67455
67072
  if(atom.ss == 'helix') bBSheet = false;
67456
- ++BCnt;
67457
67073
  }
67458
67074
  else if(q_start > 3540 && q_start < 3560) {
67459
67075
  bCstrand = true;
67460
67076
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
67461
67077
  if(atom.ss == 'helix') bCSheet = false;
67462
- ++CCnt;
67463
67078
  }
67464
67079
  else if(q_start > 7540 && q_start < 7560) {
67465
67080
  bEstrand = true;
67466
67081
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
67467
67082
  if(atom.ss == 'helix') bESheet = false;
67468
- ++ECnt;
67469
67083
  }
67470
67084
  else if(q_start > 8540 && q_start < 8560) {
67471
67085
  bFstrand = true;
67472
67086
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
67473
67087
  if(atom.ss == 'helix') bFSheet = false;
67474
- ++FCnt;
67475
67088
  }
67476
67089
 
67477
67090
  //if(bBstrand && bCstrand && bEstrand && bFstrand && bGstrand) break;
67478
67091
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
67479
67092
  }
67480
-
67481
- if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)
67482
- || BCnt < 3 || CCnt < 3 || ECnt < 3 || FCnt < 3) {
67093
+
67094
+ if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
67483
67095
  // if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
67484
67096
  if(!me.bNode && !(bBstrand && bCstrand && bEstrand && bFstrand)) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
67485
67097
  if(!me.bNode && !(bBSheet && bCSheet && bESheet && bFSheet)) console.log("Some of the Ig strands B, C, E, F are not beta sheets...");
67486
- if(!me.bNode && (BCnt < 3 || CCnt < 3 || ECnt < 3 || FCnt < 3)) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
67487
- if(ic.domainid2refpdbname[domainid] == refpdbname) {
67098
+ // if(!me.bNode && (BCnt < 3 || CCnt < 3 || ECnt < 3 || FCnt < 3)) console.log("Some of the Ig strands B, C, E, F are missing in the domain " + domainid + "...");
67099
+ if(ic.domainid2refpdbname[domainid][0] == refpdbname) {
67488
67100
  delete ic.domainid2refpdbname[domainid];
67489
67101
  delete ic.domainid2score[domainid];
67490
67102
  }
@@ -67496,21 +67108,65 @@ class Dssp {
67496
67108
  if(!me.bNode) console.log("domainid: " + domainid);
67497
67109
  }
67498
67110
 
67499
- if(!domainid2segs.hasOwnProperty(domainid) || queryData[0].score >= ic.domainid2score[domainid].split('_')[0]) {
67111
+ // count the number of matched strands
67112
+ let strandHash = {};
67113
+ for(let j = 0, jl = queryData[0].segs.length; j < jl; ++j) {
67114
+ let seg = queryData[0].segs[j];
67115
+ let q_start = parseInt(seg.q_start);
67116
+
67117
+ let strand = this.getStrandFromRefnum(q_start);
67118
+ strandHash[strand] = 1;
67119
+ }
67120
+ let score = parseFloat(queryData[0].score);
67121
+ //!!!
67122
+ // if the TM score difference is within 0.1 and more strands are found, use the template with more strands
67123
+ // if(!domainid2segs.hasOwnProperty(domainid) ||
67124
+ // (score >= parseFloat(ic.domainid2score[domainid].split('_')[0]) + tmAdjust)
67125
+ // || (score >= parseFloat(ic.domainid2score[domainid].split('_')[0]) - tmAdjust && score < parseFloat(ic.domainid2score[domainid].split('_')[0]) + tmAdjust && Object.keys(strandHash).length > domainid2strandcnt[domainid])
67126
+ // ) {
67127
+
67128
+ // use TM-score alone
67129
+ if(!domainid2segs.hasOwnProperty(domainid) || score >= parseFloat(ic.domainid2score[domainid].split('_')[0])) {
67500
67130
  ic.domainid2score[domainid] = queryData[0].score + '_' + queryData[0].frac_identical + '_' + queryData[0].num_res ;
67131
+
67501
67132
  if(bRound1) {
67502
- ic.domainid2refpdbname[domainid] = parseFloat(queryData[0].score) > 0.75 ? refpdbname : 'all_templates';
67133
+ ic.domainid2refpdbname[domainid] = score > 0.75 ? [refpdbname] : ['all_templates'];
67503
67134
  }
67504
67135
  else {
67505
- ic.domainid2refpdbname[domainid] = refpdbname;
67136
+ ic.domainid2refpdbname[domainid] = [refpdbname];
67506
67137
  }
67138
+
67507
67139
  domainid2segs[domainid] = queryData[0].segs;
67140
+ domainid2strandcnt[domainid] = Object.keys(strandHash).length;
67141
+
67508
67142
  ic.domainid2ig2kabat[domainid] = queryData[0].ig2kabat;
67509
67143
  ic.domainid2ig2imgt[domainid] = queryData[0].ig2imgt;
67510
67144
  }
67511
- }
67512
67145
 
67513
- return domainid2segs;
67146
+ if(bRound1) {
67147
+ if(!domainid2refpdbnamelist[domainid]) domainid2refpdbnamelist[domainid] = {};
67148
+ domainid2refpdbnamelist[domainid][refpdbname] = score;
67149
+ }
67150
+ }
67151
+ /* !!!
67152
+ // combine the top three clusters for the 2nd round alignment
67153
+ if(bRound1) {
67154
+ for(let domainid in domainid2refpdbnamelist) {
67155
+ console.log("###score " + ic.domainid2score[domainid].split('_')[0] + " ic.domainid2refpdbname[domainid][0] " + ic.domainid2refpdbname[domainid][0])
67156
+ if(!me.bNode && ic.domainid2refpdbname[domainid][0] == 'all_templates') {
67157
+ let refpdbname2score = domainid2refpdbnamelist[domainid];
67158
+ let refpdbnameList = Object.keys(refpdbname2score);
67159
+ refpdbnameList.sort(function(a, b) {
67160
+ return refpdbname2score[b] - refpdbname2score[a]
67161
+ });
67162
+ // top 3 templates
67163
+ ic.domainid2refpdbname[domainid] = refpdbnameList.slice(0,3);
67164
+ }
67165
+ console.log("###bb ic.domainid2refpdbname[domainid] " + ic.domainid2refpdbname[domainid])
67166
+ }
67167
+ }
67168
+ */
67169
+ return domainid2segs; // only used in round 2
67514
67170
  }
67515
67171
 
67516
67172
  async parseAlignData(dataArray, domainidpairArray, bRound1) { let ic = this.icn3d, me = ic.icn3dui;
@@ -67518,6 +67174,7 @@ class Dssp {
67518
67174
 
67519
67175
  let domainid2segs = this.parseAlignData_part1(dataArray, domainidpairArray, bRound1);
67520
67176
 
67177
+ // !!!no more Igs to detect
67521
67178
  if(Object.keys(domainid2segs).length == 0) {
67522
67179
  bNoMoreIg = true;
67523
67180
  return bNoMoreIg;
@@ -67532,25 +67189,30 @@ class Dssp {
67532
67189
  let urltmalign = me.htmlCls.tmalignUrl;
67533
67190
  for(let domainid in ic.domainid2refpdbname) {
67534
67191
  let pdbAjaxArray = [];
67535
- let refpdbname = ic.domainid2refpdbname[domainid];
67192
+ let refpdbnameList = ic.domainid2refpdbname[domainid];
67536
67193
  //let pdbid = domainid.substr(0, domainid.indexOf('_'));
67537
67194
  let chainid = domainid.substr(0, domainid.indexOf(','));
67538
67195
 
67539
- //if(ic.refpdbHash.hasOwnProperty(pdbid)) {
67540
67196
  if(ic.refpdbHash.hasOwnProperty(chainid)) {
67541
- // use itself as the ref structure
67542
- //refpdbname = pdbid;
67543
- refpdbname = chainid;
67197
+ refpdbnameList = [chainid];
67544
67198
 
67545
- if(!me.bNode) console.log("Adjusted refpdbname for domainid " + domainid + ": " + refpdbname);
67199
+ if(!me.bNode) console.log("Adjusted refpdbname for domainid " + domainid + ": " + chainid);
67546
67200
  }
67547
67201
 
67548
- if(!ic.refpdbHash[refpdbname]) {
67202
+ let templates = [];
67203
+ for(let i = 0, il = refpdbnameList.length; i < il; ++i) {
67204
+ let refpdbname = refpdbnameList[i];
67205
+ if(!ic.refpdbHash[refpdbname]) continue;
67206
+ templates = templates.concat(ic.refpdbHash[refpdbname]);
67207
+ }
67208
+
67209
+ // if(!ic.refpdbHash[refpdbname]) {
67210
+ if(templates.length == 0) {
67549
67211
  continue;
67550
67212
  }
67551
67213
 
67552
- for(let k = 0, kl = ic.refpdbHash[refpdbname].length; k < kl; ++k) {
67553
- let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refpdbid=" + ic.refpdbHash[refpdbname][k];
67214
+ for(let k = 0, kl = templates.length; k < kl; ++k) {
67215
+ let urlpdb = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi?refpdbid=" + templates[k];
67554
67216
 
67555
67217
  let pdbAjax = me.getAjaxPromise(urlpdb, 'text');
67556
67218
 
@@ -67570,12 +67232,11 @@ class Dssp {
67570
67232
  let header = 'HEADER ' + struct2 + '\n';
67571
67233
  pdb_query = header + pdb_query;
67572
67234
 
67573
- let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": ic.refpdbHash[refpdbname][index]};
67235
+ let dataObj = {'pdb_query': pdb_query, 'pdb_target': pdb_target, "queryid": templates[index]};
67574
67236
  let alignAjax = me.getAjaxPostPromise(urltmalign, dataObj);
67575
67237
  ajaxArray.push(alignAjax);
67576
67238
 
67577
- //domainidpairArray3.push(domainid + "," + refpdbname);
67578
- domainidpairArray3.push(domainid + "|" + ic.refpdbHash[refpdbname][index]);
67239
+ domainidpairArray3.push(domainid + "|" + templates[index]);
67579
67240
  }
67580
67241
  }
67581
67242
 
@@ -67591,19 +67252,19 @@ class Dssp {
67591
67252
  return bNoMoreIg;
67592
67253
  }
67593
67254
 
67594
- await this.parseAlignData_part3(domainid2segs);
67255
+ this.parseAlignData_part3(domainid2segs);
67595
67256
 
67596
67257
  return bNoMoreIg;
67597
67258
  }
67598
67259
 
67599
- async parseAlignData_part3(domainid2segs) { let ic = this.icn3d, me = ic.icn3dui;
67260
+ parseAlignData_part3(domainid2segs) { let ic = this.icn3d, me = ic.icn3dui;
67600
67261
 
67601
67262
  // combine domainid into chainid
67602
67263
  let processedChainid = {};
67603
67264
 
67604
67265
  for(let domainid in ic.domainid2refpdbname) {
67605
67266
  // remove the first round template
67606
- if(ic.domainid2refpdbname[domainid].substr(0,1) == '1') {
67267
+ if(ic.domainid2refpdbname[domainid][0].substr(0,1) == '1') {
67607
67268
  delete ic.domainid2refpdbname[domainid];
67608
67269
  delete ic.domainid2score[domainid];
67609
67270
  continue;
@@ -67618,7 +67279,7 @@ class Dssp {
67618
67279
  processedChainid[chainid] = 1;
67619
67280
 
67620
67281
  if(!ic.chainid2refpdbname.hasOwnProperty(chainid)) ic.chainid2refpdbname[chainid] = [];
67621
- ic.chainid2refpdbname[chainid].push(ic.domainid2refpdbname[domainid] + '|' + domainid);
67282
+ ic.chainid2refpdbname[chainid].push(ic.domainid2refpdbname[domainid][0] + '|' + domainid);
67622
67283
 
67623
67284
  // if(!ic.chainid2score.hasOwnProperty(chainid)) ic.chainid2score[chainid] = [];
67624
67285
  // ic.chainid2score[chainid].push(ic.domainid2score[domainid] + '|' + domainid);
@@ -67648,9 +67309,6 @@ class Dssp {
67648
67309
  let segArray = domainid2segs[domainid];
67649
67310
  let chainid = domainid.split(',')[0];
67650
67311
 
67651
- // let refpdbnameArray = ic.chainid2refpdbname[chainid];
67652
-
67653
- // let result = this.getTemplateList(chainid);
67654
67312
  let result = this.getTemplateList(domainid);
67655
67313
  let refpdbname = result.refpdbname;
67656
67314
  let score = result.score;
@@ -67818,6 +67476,15 @@ class Dssp {
67818
67476
  }
67819
67477
  }
67820
67478
 
67479
+ if(!ic.chainid2igtrack) ic.chainid2igtrack = {};
67480
+ for(let chainid in ic.chains) {
67481
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chainid]);
67482
+ if(ic.proteins.hasOwnProperty(atom.serial)) {
67483
+ let giSeq = ic.showSeqCls.getSeq(chainid);
67484
+ ic.chainid2igtrack[chainid] = this.ajdustRefnum(giSeq, chainid);
67485
+ }
67486
+ }
67487
+
67821
67488
  /*
67822
67489
  if(Object.keys(ic.resid2refnum).length > 0) {
67823
67490
  ic.bShowRefnum = true;
@@ -67847,7 +67514,7 @@ class Dssp {
67847
67514
  */
67848
67515
  }
67849
67516
 
67850
- getLabelFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
67517
+ getStrandFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
67851
67518
  let refnum = parseInt(oriRefnum);
67852
67519
 
67853
67520
  //N-terminus = 0999-0001
@@ -67874,33 +67541,44 @@ class Dssp {
67874
67541
 
67875
67542
  // loops may have numbers such as 1310, 1410
67876
67543
 
67877
- let refnumLabel;
67878
-
67879
- if(refnum < 1000) refnumLabel = undefined;
67880
- else if(refnum >= 1200 && refnum < 1290) refnumLabel = "A---" + oriRefnum;
67881
- else if(refnum >= 1320 && refnum < 1390) refnumLabel = "A--" + oriRefnum;
67882
- else if(refnum >= 1420 && refnum < 1490) refnumLabel = "A-" + oriRefnum;
67883
- else if(refnum >= 1520 && refnum < 1590) refnumLabel = "A" + oriRefnum;
67884
- else if(refnum >= 1620 && refnum < 1690) refnumLabel = "A+" + oriRefnum;
67885
- else if(refnum >= 1820 && refnum < 1890) refnumLabel = "A'" + oriRefnum;
67886
- else if(refnum >= 2000 && refnum < 2900) refnumLabel = "B" + oriRefnum;
67887
- else if(refnum >= 3300 && refnum < 3390) refnumLabel = "C--" + oriRefnum;
67888
- else if(refnum >= 3420 && refnum < 3490) refnumLabel = "C-" + oriRefnum;
67889
- else if(refnum >= 3520 && refnum < 3590) refnumLabel = "C" + oriRefnum;
67890
- else if(refnum >= 4000 && refnum < 4900) refnumLabel = "C'" + oriRefnum;
67891
- else if(refnum >= 5000 && refnum < 5900) refnumLabel = "C''" + oriRefnum;
67892
- else if(refnum >= 6000 && refnum < 6900) refnumLabel = "D" + oriRefnum;
67893
- else if(refnum >= 7500 && refnum < 7590) refnumLabel = "E" + oriRefnum;
67894
- else if(refnum >= 7620 && refnum < 7900) refnumLabel = "E+" + oriRefnum;
67895
- else if(refnum >= 8000 && refnum < 8900) refnumLabel = "F" + oriRefnum;
67896
- else if(refnum >= 9500 && refnum < 9590) refnumLabel = "G" + oriRefnum;
67897
- else if(refnum >= 9620 && refnum < 9690) refnumLabel = "G+" + oriRefnum;
67898
- else if(refnum >= 9720 && refnum < 9790) refnumLabel = "G++" + oriRefnum;
67899
- else if(refnum > 9900) refnumLabel = undefined;
67900
- else refnumLabel = " " + oriRefnum;
67901
- if(prevStrand) refnumLabel = prevStrand + oriRefnum;
67902
-
67903
- return refnumLabel
67544
+ let strand;
67545
+
67546
+ if(refnum < 1000) strand = undefined;
67547
+ else if(refnum >= 1200 && refnum < 1290) strand = "A---";
67548
+ else if(refnum >= 1320 && refnum < 1390) strand = "A--";
67549
+ else if(refnum >= 1420 && refnum < 1490) strand = "A-";
67550
+ else if(refnum >= 1520 && refnum < 1590) strand = "A";
67551
+ else if(refnum >= 1620 && refnum < 1690) strand = "A+";
67552
+ else if(refnum >= 1820 && refnum < 1890) strand = "A'";
67553
+ else if(refnum >= 2000 && refnum < 2900) strand = "B";
67554
+ else if(refnum >= 3300 && refnum < 3390) strand = "C--";
67555
+ else if(refnum >= 3420 && refnum < 3490) strand = "C-";
67556
+ else if(refnum >= 3520 && refnum < 3590) strand = "C";
67557
+ else if(refnum >= 4000 && refnum < 4900) strand = "C'";
67558
+ else if(refnum >= 5000 && refnum < 5900) strand = "C''";
67559
+ else if(refnum >= 6000 && refnum < 6900) strand = "D";
67560
+ else if(refnum >= 7500 && refnum < 7590) strand = "E";
67561
+ else if(refnum >= 7620 && refnum < 7900) strand = "E+";
67562
+ else if(refnum >= 8000 && refnum < 8900) strand = "F";
67563
+ else if(refnum >= 9500 && refnum < 9590) strand = "G";
67564
+ else if(refnum >= 9620 && refnum < 9690) strand = "G+";
67565
+ else if(refnum >= 9720 && refnum < 9790) strand = "G++";
67566
+ else if(refnum > 9900) strand = undefined;
67567
+ else strand = " ";
67568
+ if(prevStrand) strand = prevStrand;
67569
+
67570
+ return strand
67571
+ }
67572
+
67573
+ getLabelFromRefnum(oriRefnum, prevStrand) { let ic = this.icn3d; ic.icn3dui;
67574
+ let strand = this.getStrandFromRefnum(oriRefnum, prevStrand);
67575
+
67576
+ if(strand) {
67577
+ return strand + oriRefnum;
67578
+ }
67579
+ else {
67580
+ return undefined;
67581
+ }
67904
67582
  }
67905
67583
 
67906
67584
  async parseCustomRefFile(data) { let ic = this.icn3d; ic.icn3dui;
@@ -67979,7 +67657,8 @@ class Dssp {
67979
67657
  // 1. show IgStrand ref numbers
67980
67658
  if(type == 'igstrand' || type == 'IgStrand') {
67981
67659
  // iGStrand reference numbers were adjusted when showing in sequences
67982
- if(me.bNode) {
67660
+ // if(me.bNode) {
67661
+ if(ic.bShowRefnum) {
67983
67662
  for(let chnid in ic.chains) {
67984
67663
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chnid]);
67985
67664
  if(ic.proteins.hasOwnProperty(atom.serial)) {
@@ -68021,29 +67700,6 @@ class Dssp {
68021
67700
 
68022
67701
  // refData += '{"Ig domain" : ' + bIgDomain + ', "ref PDB" : ' + JSON.stringify(ic.refPdbList) + ',\n';
68023
67702
  refData += '{"Ig domain" : ' + bIgDomain + ',\n';
68024
- /*
68025
- if(bIgDomain) {
68026
- refData += '"data": {\n';
68027
- for(let chnid in ic.chains) {
68028
- let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.chains[chnid]);
68029
- if(ic.proteins.hasOwnProperty(atom.serial)) {
68030
- let bIgChain = false;
68031
- let chainRefData = '"' + chnid + '": [\n';
68032
- for(let i = 0; i < ic.chainsSeq[chnid].length; ++i) {
68033
- const resid = chnid + '_' + ic.chainsSeq[chnid][i].resi + '_' + ic.chainsSeq[chnid][i].name;
68034
- chainRefData += '{"' + resid + '": "' + resid2refnum[resid] + '"},\n';
68035
- if(resid2refnum[resid]) bIgChain = true;
68036
- }
68037
- chainRefData += '],\n';
68038
-
68039
- if(bIgChain) {
68040
- refData += chainRefData;
68041
- }
68042
- }
68043
- }
68044
- refData += '}\n';
68045
- }
68046
- */
68047
67703
 
68048
67704
  if(bIgDomain) {
68049
67705
  refData += '"igs": [\n';
@@ -68054,8 +67710,8 @@ class Dssp {
68054
67710
  refData += '{"' + chnid + '": {\n';
68055
67711
 
68056
67712
  for(let i = 0, il = igArray.length; i < il; ++i) {
68057
- let startPos = igArray[i].startPos;
68058
- let endPos = igArray[i].endPos;
67713
+ let startPosArray = igArray[i].startPosArray;
67714
+ let endPosArray = igArray[i].endPosArray;
68059
67715
  let domainid = igArray[i].domainid;
68060
67716
  let info = ic.domainid2info[domainid];
68061
67717
  if(!info) continue;
@@ -68063,9 +67719,13 @@ class Dssp {
68063
67719
  refData += '"' + domainid + '": {\n';
68064
67720
 
68065
67721
  refData += '"refpdbname":"' + info.refpdbname + '", "score":' + info.score + ', "seqid":' + info.seqid + ', "nresAlign":' + info.nresAlign + ', "data": [';
68066
- for(let i = startPos; i <= endPos; ++i) {
68067
- const resid = chnid + '_' + ic.chainsSeq[chnid][i].resi + '_' + ic.chainsSeq[chnid][i].name;
68068
- refData += '{"' + resid + '": "' + resid2refnum[resid] + '"},\n';
67722
+ for(let j = 0, jl = startPosArray.length; j < jl; ++j) {
67723
+ let startPos = startPosArray[j];
67724
+ let endPos = endPosArray[j];
67725
+ for(let k = startPos; k <= endPos; ++k) {
67726
+ const resid = chnid + '_' + ic.chainsSeq[chnid][k].resi + '_' + ic.chainsSeq[chnid][k].name;
67727
+ refData += '{"' + resid + '": "' + resid2refnum[resid] + '"},\n';
67728
+ }
68069
67729
  }
68070
67730
  refData += '],\n';
68071
67731
 
@@ -68162,6 +67822,487 @@ class Dssp {
68162
67822
 
68163
67823
  return dataArray3;
68164
67824
  }
67825
+
67826
+ ajdustRefnum(giSeq, chnid) { let ic = this.icn3d, me = ic.icn3dui;
67827
+ if(!ic.chainid2refpdbname[chnid]) return false;
67828
+
67829
+ // auto-generate ref numbers for loops
67830
+ let currStrand = '', prevStrand = '';
67831
+ let refnumLabel, refnumStr_ori, refnumStr, postfix, strandPostfix, refnum, refnum3c, refnum2c;
67832
+ let bExtendedStrand = false, bSecThird9 = false;
67833
+
67834
+ // sometimes one chain may have several Ig domains,set an index for each IgDomain
67835
+ let index = 1, bStart = false;
67836
+
67837
+ if(!me.bNode) { // do not overwrite loops in node
67838
+ // reset ic.residIgLoop for the current selection, which could be the second round of ref num assignment
67839
+ // just current chain
67840
+ let atomHash = me.hashUtilsCls.intHash(ic.chains[chnid], ic.hAtoms);
67841
+ ic.firstAtomObjCls.getResiduesFromAtoms(atomHash);
67842
+ }
67843
+
67844
+ // 1. get the range of each strand excluding loops
67845
+ let strandArray = [], strandHash = {}, strandCnt = 0, resCnt = 0, resCntBfAnchor = 0, resCntAtAnchor = 0;
67846
+ let bFoundAnchor = false;
67847
+
67848
+ for(let i = 0, il = giSeq.length; i < il; ++i, ++resCnt, ++resCntBfAnchor, ++resCntAtAnchor) {
67849
+ let currResi = ic.ParserUtilsCls.getResi(chnid, i);
67850
+ let residueid = chnid + '_' + currResi;
67851
+ let domainid;
67852
+
67853
+ refnumLabel = ic.resid2refnum[residueid];
67854
+
67855
+ let firstChar = (refnumLabel) ? refnumLabel.substr(0,1) : '';
67856
+ if(!bStart && refnumLabel && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
67857
+ bStart = true;
67858
+ resCnt = 1; // the first one is included
67859
+ bFoundAnchor = false;
67860
+ }
67861
+
67862
+ //if((prevStrand.substr(0,1) == 'F' || prevStrand.substr(0,1) == 'G') && !refnumLabel) { // indicate the end of an IG domain
67863
+ if((prevStrand.substr(0,1) == 'G') && !refnumLabel) { // indicate the end of an IG domain
67864
+ bStart = false;
67865
+ }
67866
+
67867
+ if(refnumLabel) {
67868
+ domainid = ic.resid2domainid[residueid];
67869
+
67870
+ refnumStr_ori = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
67871
+ currStrand = refnumLabel.replace(new RegExp(refnumStr_ori,'g'), '');
67872
+ refnumStr_ori.substr(0, 1);
67873
+
67874
+ refnumStr = refnumStr_ori;
67875
+ refnum = parseInt(refnumStr);
67876
+ refnum3c = (refnum - parseInt(refnum/1000) * 1000).toString();
67877
+ refnum2c = (refnum - parseInt(refnum/100) * 100).toString();
67878
+
67879
+ // for extended strands, since A is 1550 and A+ is 1650, then the AA+ loop will be 1591, 1592, ... 1610, 1611, etc
67880
+ bSecThird9 = refnum3c.substr(0,1) == '9' || refnum2c.substr(0,1) == '9' || refnum2c.substr(0,1) == '0' || refnum2c.substr(0,1) == '1';
67881
+ if(bSecThird9) ic.residIgLoop[residueid] = 1;
67882
+
67883
+ strandPostfix = refnumStr.replace(refnum.toString(), '');
67884
+
67885
+ postfix = strandPostfix + '_' + index;
67886
+
67887
+ let firstTwo = parseInt(refnum.toString().substr(0, 2)); // check extended strands
67888
+ bExtendedStrand = refnum3c.substr(0,1) != '5' && firstTwo != '18'; // all strands and A' (18##)
67889
+
67890
+ if(currStrand && currStrand != ' ') {
67891
+ if(!bSecThird9 || (bExtendedStrand && !bSecThird9)) {
67892
+ let lastTwo = parseInt(refnum.toString().substr(refnum.toString().length - 2, 2));
67893
+
67894
+ if(currStrand != prevStrand) { // reset currCnt
67895
+ bFoundAnchor = false;
67896
+
67897
+ if(strandHash[currStrand + postfix]) {
67898
+ ++index;
67899
+ postfix = refnumStr.replace(refnum.toString(), '') + '_' + index;
67900
+ }
67901
+
67902
+ strandHash[currStrand + postfix] = 1;
67903
+
67904
+ strandArray[strandCnt] = {};
67905
+
67906
+ strandArray[strandCnt].startResi = currResi;
67907
+ strandArray[strandCnt].startRefnum = refnum; // 1250 in A1250a
67908
+
67909
+ resCntBfAnchor = 0;
67910
+
67911
+ strandArray[strandCnt].domainid = domainid;
67912
+
67913
+ strandArray[strandCnt].endResi = currResi;
67914
+ strandArray[strandCnt].endRefnum = refnum; // 1250a
67915
+
67916
+ if(lastTwo == 50) {
67917
+ strandArray[strandCnt].anchorRefnum = refnum;
67918
+ strandArray[strandCnt].resCntBfAnchor = resCntBfAnchor;
67919
+
67920
+ resCntAtAnchor = 0;
67921
+
67922
+ bFoundAnchor = true;
67923
+ }
67924
+
67925
+ // in case A1550 is not found, but A1551 is found
67926
+ if(!bFoundAnchor && (lastTwo == 51 || lastTwo == 52 || lastTwo == 53 || lastTwo == 54) ) {
67927
+ let offset = lastTwo - 50;
67928
+ strandArray[strandCnt].anchorRefnum = refnum - offset;
67929
+ strandArray[strandCnt].resCntBfAnchor = resCntBfAnchor - offset;
67930
+
67931
+ resCntAtAnchor = offset;
67932
+
67933
+ bFoundAnchor = true;
67934
+ }
67935
+
67936
+ if(bExtendedStrand) {
67937
+ strandArray[strandCnt].anchorRefnum = 0;
67938
+ }
67939
+
67940
+ strandArray[strandCnt].strandPostfix = strandPostfix; // a in A1250a
67941
+ strandArray[strandCnt].strand = currStrand; // A in A1250a
67942
+
67943
+ strandArray[strandCnt].postfix = postfix; // Aa_1
67944
+
67945
+ strandArray[strandCnt].loopResCnt = resCnt - 1;
67946
+
67947
+ ++strandCnt;
67948
+ resCnt = 0;
67949
+ }
67950
+ else {
67951
+ if(strandHash[currStrand + postfix]) {
67952
+ if(lastTwo == 50) {
67953
+ strandArray[strandCnt - 1].anchorRefnum = refnum;
67954
+ strandArray[strandCnt - 1].resCntBfAnchor = resCntBfAnchor;
67955
+
67956
+ // update
67957
+ strandArray[strandCnt - 1].startRefnum = strandArray[strandCnt - 1].anchorRefnum - strandArray[strandCnt - 1].resCntBfAnchor;
67958
+
67959
+ resCntAtAnchor = 0;
67960
+
67961
+ bFoundAnchor = true;
67962
+ }
67963
+
67964
+ // in case A1550 is not found, but A1551 is found
67965
+ if(!bFoundAnchor && (lastTwo == 51 || lastTwo == 52 || lastTwo == 53 || lastTwo == 54) ) {
67966
+ let offset = lastTwo - 50;
67967
+ strandArray[strandCnt - 1].anchorRefnum = refnum - offset;
67968
+ strandArray[strandCnt - 1].resCntBfAnchor = resCntBfAnchor - offset;
67969
+
67970
+ // update
67971
+ strandArray[strandCnt - 1].startRefnum = strandArray[strandCnt - 1].anchorRefnum - strandArray[strandCnt - 1].resCntBfAnchor;
67972
+
67973
+ resCntAtAnchor = offset;
67974
+
67975
+ bFoundAnchor = true;
67976
+ }
67977
+
67978
+ if(bExtendedStrand) {
67979
+ strandArray[strandCnt - 1].anchorRefnum = 0;
67980
+ }
67981
+
67982
+ strandArray[strandCnt - 1].domainid = domainid;
67983
+
67984
+ strandArray[strandCnt - 1].endResi = currResi;
67985
+ strandArray[strandCnt - 1].endRefnum = refnum; // 1250a
67986
+ strandArray[strandCnt - 1].resCntAtAnchor = resCntAtAnchor;
67987
+
67988
+ if(strandArray[strandCnt - 1].anchorRefnum) {
67989
+ strandArray[strandCnt - 1].endRefnum = strandArray[strandCnt - 1].anchorRefnum + strandArray[strandCnt - 1].resCntAtAnchor;
67990
+ }
67991
+
67992
+ resCnt = 0;
67993
+ }
67994
+ }
67995
+ }
67996
+ }
67997
+ }
67998
+
67999
+ prevStrand = currStrand;
68000
+ }
68001
+
68002
+ // 2. extend the strand to end of sheet
68003
+ let maxExtend = 8;
68004
+ for(let i = 0, il = strandArray.length; i < il; ++i) {
68005
+ let startAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].startResi]);
68006
+ let endAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[chnid + '_' + strandArray[i].endResi]);
68007
+
68008
+ let startPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].startResi);
68009
+ let endPos = ic.setSeqAlignCls.getPosFromResi(chnid, strandArray[i].endResi);
68010
+
68011
+ if(startAtom.ss == 'sheet' && !startAtom.ssbegin) {
68012
+ for(let j = 1; j <= maxExtend; ++j) {
68013
+ let currPos = startPos - j;
68014
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
68015
+ if(i > 0 && parseInt(currResi) <= parseInt(strandArray[i-1].endResi)) break;
68016
+
68017
+ let currResid = chnid + '_' + currResi;
68018
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
68019
+ let domainid = ic.resid2domainid[currResid];
68020
+ if(currAtom.ssbegin) { // find the start of the sheet
68021
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
68022
+ strandArray[i].startResi = currResi;
68023
+ strandArray[i].startRefnum -= j;
68024
+ strandArray[i].loopResCnt -= j;
68025
+ if(strandArray[i].loopResCnt < 0) strandArray[i].loopResCnt = 0;
68026
+ strandArray[i].resCntBfAnchor += j;
68027
+
68028
+ // update ic.resid2refnum
68029
+ for(let k = 1; k <= j; ++k) {
68030
+ currPos = startPos - k;
68031
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
68032
+ let currResid = chnid + '_' + currResi;
68033
+ delete ic.residIgLoop[currResid];
68034
+ ic.resid2domainid[currResid] = domainid;
68035
+ }
68036
+
68037
+ break;
68038
+ }
68039
+ }
68040
+ }
68041
+
68042
+ if(endAtom.ss == 'sheet' && !endAtom.ssend) {
68043
+ for(let j = 1; j <= maxExtend; ++j) {
68044
+ let currPos = endPos + j;
68045
+ let currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
68046
+ if(i < il - 1 && parseInt(currResi) >= parseInt(strandArray[i+1].startResi)) break;
68047
+
68048
+ let currResid = chnid + '_' + currResi;
68049
+ let currAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[currResid]);
68050
+ let domainid = ic.resid2domainid[currResid];
68051
+ if(currAtom.ssend) { // find the end of the sheet
68052
+ // update the following: startResi,startRefnum,endResi,endRefnum,loopResCnt,resCntBfAnchor,resCntAtAnchor
68053
+ strandArray[i].endResi = currResi;
68054
+ strandArray[i].endRefnum += j;
68055
+ if(i < il - 1) {
68056
+ strandArray[i + 1].loopResCnt -= j;
68057
+ if(strandArray[i + 1].loopResCnt < 0) strandArray[i + 1].loopResCnt = 0;
68058
+ }
68059
+ strandArray[i].resCntAtAnchor += j;
68060
+
68061
+ // update ic.residIgLoop[resid];
68062
+ for(let k = 1; k <= j; ++k) {
68063
+ currPos = endPos + k;
68064
+ currResi = ic.ParserUtilsCls.getResi(chnid, currPos);
68065
+ let currResid = chnid + '_' + currResi;
68066
+ delete ic.residIgLoop[currResid];
68067
+ ic.resid2domainid[currResid] = domainid;
68068
+ }
68069
+
68070
+ break;
68071
+ }
68072
+ }
68073
+ }
68074
+ }
68075
+ /*
68076
+ // 2b. remove strands with less than 3 residues except G strand
68077
+ for(let il = strandArray.length, i = il - 1; i >= 0; --i) {
68078
+ let strandTmp = strandArray[i].strand.substr(0, 1);
68079
+ if(strandTmp != 'G' && strandArray[i].endRefnum - strandArray[i].startRefnum + 1 < 3) { // remove the strand
68080
+ if(strandTmp == 'B' || strandTmp == 'C' || strandTmp == 'E' || strandTmp == 'F') {
68081
+ if(!me.bNode) console.log("Some of the Ig strands B, C, E, F are removed since they are too short...");
68082
+
68083
+ console.log("### strandTmp " + strandTmp + " strandArray[i].endRefnum - strandArray[i].startRefnum + 1 " + (strandArray[i].endRefnum - strandArray[i].startRefnum + 1))
68084
+ return false;
68085
+ }
68086
+
68087
+ if(i != il - 1) { // modify
68088
+ strandArray[i + 1].loopResCnt += strandArray[i].loopResCnt + parseInt(strandArray[i].endResi) - parseInt(strandArray[i].startResi) + 1;
68089
+ }
68090
+
68091
+ strandArray.splice(i, 1);
68092
+ }
68093
+ }
68094
+ */
68095
+ // 3. assign refnumLabel for each resid
68096
+ strandCnt = 0;
68097
+ let loopCnt = 0;
68098
+
68099
+ let bBeforeAstrand = true, bAfterGstrand = true, refnumLabelNoPostfix, prevStrandCnt = 0, currRefnum;
68100
+ bStart = false;
68101
+ let refnumInStrand = 0;
68102
+ if(strandArray.length > 0) {
68103
+ for(let i = 0, il = giSeq.length; i < il; ++i, ++loopCnt, ++refnumInStrand) {
68104
+ let currResi = ic.ParserUtilsCls.getResi(chnid, i);
68105
+ let residueid = chnid + '_' + currResi;
68106
+ refnumLabel = ic.resid2refnum[residueid];
68107
+
68108
+ currStrand = strandArray[strandCnt].strand;
68109
+
68110
+ let domainid;
68111
+
68112
+ if(refnumLabel) {
68113
+ domainid = ic.resid2domainid[residueid];
68114
+
68115
+ refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
68116
+ currRefnum = parseInt(refnumStr);
68117
+ refnumLabelNoPostfix = currStrand + currRefnum;
68118
+
68119
+ currStrand = refnumLabel.replace(new RegExp(refnumStr,'g'), '');
68120
+
68121
+ let firstChar = refnumLabel.substr(0,1);
68122
+ if(!bStart && (firstChar == 'A' || firstChar == 'B')) { // start of a new IG domain
68123
+ bStart = true;
68124
+ bBeforeAstrand = true;
68125
+ loopCnt = 0;
68126
+ }
68127
+ }
68128
+
68129
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[residueid]);
68130
+
68131
+ // skip non-protein residues
68132
+ if(!atom || !ic.proteins.hasOwnProperty(atom.serial)) {
68133
+ refnumLabel = undefined;
68134
+ }
68135
+ else {
68136
+ let bBefore = false, bInRange= false, bAfter = false;
68137
+ // 100, 100A
68138
+ if(parseInt(currResi) == parseInt(strandArray[strandCnt].startResi) && currResi != strandArray[strandCnt].startResi) {
68139
+ bBefore = currResi < strandArray[strandCnt].startResi;
68140
+ }
68141
+ else {
68142
+ bBefore = parseInt(currResi) < parseInt(strandArray[strandCnt].startResi);
68143
+ }
68144
+
68145
+ // 100, 100A
68146
+ if(parseInt(currResi) == parseInt(strandArray[strandCnt].endResi) && currResi != strandArray[strandCnt].endResi) {
68147
+ bAfter = currResi > strandArray[strandCnt].endResi;
68148
+ }
68149
+ else {
68150
+ bAfter = parseInt(currResi) > parseInt(strandArray[strandCnt].endResi);
68151
+ }
68152
+
68153
+ bInRange = (!bBefore && !bAfter) ? true : false;
68154
+
68155
+ if(bBefore) {
68156
+ ic.residIgLoop[residueid] = 1;
68157
+
68158
+ if(bBeforeAstrand) { // make it continuous to the 1st strand
68159
+ if(bStart) {
68160
+ currRefnum = strandArray[strandCnt].startRefnum - strandArray[strandCnt].loopResCnt + loopCnt;
68161
+ refnumLabelNoPostfix = strandArray[strandCnt].strand + currRefnum;
68162
+ refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
68163
+ domainid = strandArray[strandCnt].domainid;
68164
+ }
68165
+ else {
68166
+ //loopCnt = 0;
68167
+ refnumLabelNoPostfix = undefined;
68168
+ refnumLabel = undefined;
68169
+ }
68170
+ }
68171
+ else {
68172
+ if(prevStrandCnt >= 0
68173
+ // && (strandArray[prevStrandCnt].strand.substr(0, 1) == 'F' || strandArray[prevStrandCnt].strand.substr(0, 1) == 'G')) {
68174
+ && (strandArray[prevStrandCnt].strand.substr(0, 1) == 'G')) {
68175
+ if(!bAfterGstrand) {
68176
+ //loopCnt = 0;
68177
+ refnumLabelNoPostfix = undefined;
68178
+ refnumLabel = undefined;
68179
+ }
68180
+ else {
68181
+ if(bStart && ic.resid2refnum[residueid]) {
68182
+ bAfterGstrand = true;
68183
+
68184
+ currRefnum = strandArray[prevStrandCnt].endRefnum + loopCnt;
68185
+ refnumLabelNoPostfix = strandArray[prevStrandCnt].strand + currRefnum;
68186
+ refnumLabel = refnumLabelNoPostfix + strandArray[prevStrandCnt].strandPostfix;
68187
+ domainid = strandArray[prevStrandCnt].domainid;
68188
+ }
68189
+ else {
68190
+ bStart = false;
68191
+ bBeforeAstrand = true;
68192
+ //loopCnt = 0;
68193
+
68194
+ bAfterGstrand = false;
68195
+
68196
+ refnumLabelNoPostfix = undefined;
68197
+ refnumLabel = undefined;
68198
+ }
68199
+ }
68200
+ }
68201
+ else {
68202
+ bAfterGstrand = true; // reset
68203
+
68204
+ let len = strandArray[strandCnt].loopResCnt;
68205
+ let halfLen = parseInt(len / 2.0 + 0.5);
68206
+
68207
+ if(loopCnt <= halfLen) {
68208
+ currRefnum = strandArray[prevStrandCnt].endRefnum + loopCnt;
68209
+ refnumLabelNoPostfix = strandArray[prevStrandCnt].strand + currRefnum;
68210
+ refnumLabel = refnumLabelNoPostfix + strandArray[prevStrandCnt].strandPostfix;
68211
+ domainid = strandArray[prevStrandCnt].domainid;
68212
+ }
68213
+ else {
68214
+ currRefnum = strandArray[strandCnt].startRefnum - len + loopCnt - 1;
68215
+ refnumLabelNoPostfix = strandArray[strandCnt].strand + currRefnum;
68216
+ refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
68217
+ domainid = strandArray[strandCnt].domainid;
68218
+ }
68219
+ }
68220
+ }
68221
+ }
68222
+ else if(bInRange) {
68223
+ // not in loop any more if you assign ref numbers multiple times
68224
+ //delete ic.residIgLoop[residueid];
68225
+
68226
+ bBeforeAstrand = false;
68227
+
68228
+ if(strandArray[strandCnt].anchorRefnum) { // use anchor to name refnum
68229
+ if(currResi == strandArray[strandCnt].startResi) {
68230
+ refnumInStrand = strandArray[strandCnt].anchorRefnum - strandArray[strandCnt].resCntBfAnchor;
68231
+ strandArray[strandCnt].startRefnum = refnumInStrand;
68232
+ }
68233
+ else if(currResi == strandArray[strandCnt].endResi) {
68234
+ strandArray[strandCnt].endRefnum = refnumInStrand;
68235
+ }
68236
+
68237
+ refnumLabelNoPostfix = strandArray[strandCnt].strand + refnumInStrand;
68238
+ refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
68239
+ domainid = strandArray[strandCnt].domainid;
68240
+ }
68241
+
68242
+ if(currResi == strandArray[strandCnt].endResi) {
68243
+ ++strandCnt; // next strand
68244
+ loopCnt = 0;
68245
+
68246
+ if(!strandArray[strandCnt]) { // last strand
68247
+ --strandCnt;
68248
+ }
68249
+ }
68250
+ }
68251
+ else if(bAfter) {
68252
+ ic.residIgLoop[residueid] = 1;
68253
+
68254
+ if(!bAfterGstrand) {
68255
+ refnumLabelNoPostfix = undefined;
68256
+ refnumLabel = undefined;
68257
+ }
68258
+ else {
68259
+ // C-terminal
68260
+ if(!ic.resid2refnum[residueid]) {
68261
+ bAfterGstrand = false;
68262
+
68263
+ refnumLabelNoPostfix = undefined;
68264
+ refnumLabel = undefined;
68265
+ }
68266
+ else {
68267
+ bAfterGstrand = true;
68268
+
68269
+ currRefnum = strandArray[strandCnt].endRefnum + loopCnt;
68270
+ refnumLabelNoPostfix = strandArray[strandCnt].strand + currRefnum;
68271
+ refnumLabel = refnumLabelNoPostfix + strandArray[strandCnt].strandPostfix;
68272
+ domainid = strandArray[strandCnt].domainid;
68273
+ }
68274
+ }
68275
+ }
68276
+ }
68277
+
68278
+ prevStrand = currStrand;
68279
+ prevStrandCnt = strandCnt - 1;
68280
+
68281
+ // assign the adjusted reference numbers
68282
+ ic.resid2refnum[residueid] = refnumLabel;
68283
+ ic.resid2domainid[residueid] = domainid;
68284
+
68285
+ refnumStr = ic.refnumCls.rmStrandFromRefnumlabel(refnumLabel);
68286
+
68287
+ if(!ic.refnum2residArray.hasOwnProperty(refnumStr)) {
68288
+ ic.refnum2residArray[refnumStr] = [residueid];
68289
+ }
68290
+ else {
68291
+ ic.refnum2residArray[refnumStr].push(residueid);
68292
+ }
68293
+
68294
+ if(!ic.chainsMapping.hasOwnProperty(chnid)) {
68295
+ ic.chainsMapping[chnid] = {};
68296
+ }
68297
+
68298
+ // remove the postfix when comparing interactions
68299
+ //ic.chainsMapping[chnid][residueid] = refnumLabel;
68300
+ ic.chainsMapping[chnid][residueid] = refnumLabelNoPostfix;
68301
+ }
68302
+ }
68303
+
68304
+ return true;
68305
+ }
68165
68306
  }
68166
68307
 
68167
68308
  /**