icn3d 3.31.13 → 3.33.0

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.
Files changed (4) hide show
  1. package/icn3d.js +1134 -814
  2. package/icn3d.min.js +3 -11
  3. package/icn3d.module.js +1134 -814
  4. package/package.json +1 -1
package/icn3d.module.js CHANGED
@@ -9919,7 +9919,7 @@ class ClickMenu {
9919
9919
  });
9920
9920
 
9921
9921
  me.myEventCls.onIds("#" + me.pre + "mn1_mmciffile", "click", function(e) { me.icn3d; //e.preventDefault();
9922
- me.htmlCls.dialogCls.openDlg('dl_mmciffile', 'Please input mmCIF File');
9922
+ me.htmlCls.dialogCls.openDlg('dl_mmciffile', 'Please append mmCIF File');
9923
9923
  });
9924
9924
 
9925
9925
  me.myEventCls.onIds("#" + me.pre + "mn1_mmcifid", "click", function(e) { me.icn3d; //e.preventDefault();
@@ -11489,6 +11489,13 @@ class ClickMenu {
11489
11489
  ic.drawCls.draw();
11490
11490
  });
11491
11491
 
11492
+ me.myEventCls.onIds("#" + me.pre + "mn6_addlabelIg", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
11493
+ ic.residueLabelsCls.addIgLabels(ic.hAtoms);
11494
+ ic.selectionCls.saveSelectionIfSelected();
11495
+ thisClass.setLogCmd('add ig labels', true);
11496
+ ic.drawCls.draw();
11497
+ });
11498
+
11492
11499
  me.myEventCls.onIds("#" + me.pre + "mn6_addlabelChains", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
11493
11500
  ic.analysisCls.addChainLabels(ic.hAtoms);
11494
11501
  ic.selectionCls.saveSelectionIfSelected();
@@ -12585,7 +12592,7 @@ class SetMenu {
12585
12592
  // html += this.getLink('mn1_pdbfile', 'PDB File');
12586
12593
  // html += this.getLink('mn1_pdbfile_app', 'PDB File (append)');
12587
12594
  html += this.getLink('mn1_pdbfile_app', 'PDB Files (appendable)', 1, 2);
12588
- html += this.getLink('mn1_mmciffile', 'mmCIF File', undefined, 2);
12595
+ html += this.getLink('mn1_mmciffile', 'mmCIF Files (appendable)', undefined, 2);
12589
12596
  html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
12590
12597
  html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
12591
12598
  html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
@@ -12713,15 +12720,12 @@ class SetMenu {
12713
12720
  html += this.getLink('mn1_exportSecondary', 'Secondary Structure', undefined, 2);
12714
12721
  }
12715
12722
 
12716
- //!!!
12717
- /*
12718
12723
  html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
12719
12724
  html += "<ul>";
12720
12725
  html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
12721
12726
  html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
12722
12727
  html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
12723
12728
  html += "</ul>";
12724
- */
12725
12729
 
12726
12730
  html += "<li><br/></li>";
12727
12731
 
@@ -13564,9 +13568,8 @@ class SetMenu {
13564
13568
  html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'pLDDT', undefined, 1, 1);
13565
13569
  //}
13566
13570
 
13567
- //!!!
13568
- // html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
13569
- // html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
13571
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
13572
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
13570
13573
  }
13571
13574
  else {
13572
13575
  //if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
@@ -13696,8 +13699,10 @@ class SetMenu {
13696
13699
  if(me.cfg.cid === undefined) {
13697
13700
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
13698
13701
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
13699
- //!!!
13700
- // html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
13702
+
13703
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
13704
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelIg', 'per Ig Domain', undefined, 1, 2);
13705
+
13701
13706
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
13702
13707
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
13703
13708
  }
@@ -13790,17 +13795,13 @@ class SetMenu {
13790
13795
  html += this.getMenuText('mn6_igrefwrap', 'Ref. Number', undefined, undefined, 1);
13791
13796
 
13792
13797
  html += "<ul>";
13793
- //!!!
13794
- /*
13798
+
13795
13799
  html += this.getLink('mn6_igrefYes', 'Show Ig for Selection', undefined, 2);
13796
13800
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
13797
13801
  html += this.getLink('mn6_alignrefTpl', 'Align w/ Specified Template', undefined, 2);
13798
13802
  html += this.getLink('mn6_igrefNo', 'Reset Ig Ref. Number', undefined, 2);
13799
13803
 
13800
13804
  html += this.getMenuSep();
13801
- */
13802
-
13803
-
13804
13805
 
13805
13806
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
13806
13807
  html += "</ul>";
@@ -13890,6 +13891,7 @@ class SetMenu {
13890
13891
  html += this.getMenuUrl('faq_simialphapdb', me.htmlCls.baseUrl + "icn3d/icn3d.html#simifoldseek", "Similar AlphaFold/PDB", 1, 2);
13891
13892
  html += this.getMenuUrl('faq_alnstru', me.htmlCls.baseUrl + "icn3d/icn3d.html#alignmul", "Align Multiple Structures", 1, 2);
13892
13893
  html += this.getMenuUrl('faq_batchanal', me.htmlCls.baseUrl + "icn3d/icn3d.html#batchanalysis", "Batch Analysis", 1, 2);
13894
+ html += this.getMenuUrl('faq_batchanal', me.htmlCls.baseUrl + "icn3d/icn3d.html#igrefnum", "Assign Ig Ref. Numbers", 1, 2);
13893
13895
  html += this.getMenuUrl('faq_embedicn3d', me.htmlCls.baseUrl + "icn3d/icn3d.html#embedicn3d", "Embed iCn3D", 1, 2);
13894
13896
  html += "</ul>";
13895
13897
  html += "</li>";
@@ -14929,8 +14931,8 @@ class SetDialog {
14929
14931
  html += "</div>";
14930
14932
 
14931
14933
  html += me.htmlCls.divStr + "dl_mmciffile' class='" + dialogClass + "'>";
14932
- html += this.addNotebookTitle('dl_mmciffile', 'Please input an mmCIF file');
14933
- html += "mmCIF File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "mmciffile' value='1TUP' size=8> ";
14934
+ html += this.addNotebookTitle('dl_mmciffile', 'Please append mmCIF files');
14935
+ html += "Multiple mmCIF Files: <input type='file' multiple id='" + me.pre + "mmciffile' size=8> ";
14934
14936
  html += me.htmlCls.buttonStr + "reload_mmciffile'>Load</button>";
14935
14937
  html += "</div>";
14936
14938
 
@@ -16078,13 +16080,10 @@ class SetDialog {
16078
16080
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_interact'>Interactions" + me.htmlCls.space2 + "</span></td>";
16079
16081
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_crosslink'>Cross-Linkages" + me.htmlCls.space2 + "</span></td>";
16080
16082
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_transmem'>Transmembrane" + me.htmlCls.space2 + "</span></td>";
16081
- //!!!
16082
- /*
16083
+
16083
16084
  html += "<td></td>";
16084
16085
  html += "</tr><tr>";
16085
16086
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_ig'>Ig Domains" + me.htmlCls.space2 + "</span></td>";
16086
- */
16087
-
16088
16087
 
16089
16088
  html += "<td></td>";
16090
16089
  html += "</tr></table></div></div>";
@@ -16185,17 +16184,15 @@ class Events {
16185
16184
  }
16186
16185
  }
16187
16186
 
16188
- async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16187
+ async readFile(bAppend, files, index, dataStrAll, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16189
16188
  let file = files[index];
16190
16189
  let commandName = (bAppend) ? 'append': 'load';
16190
+ commandName += (bmmCIF) ? ' mmcif file ': ' pdb file ';
16191
16191
 
16192
16192
  let reader = new FileReader();
16193
16193
  reader.onload = async function(e) {
16194
- //++ic.loadedFileCnt;
16195
-
16196
16194
  let dataStr = e.target.result; // or = reader.result;
16197
- //thisClass.setLogCmd(commandName + ' pdb file ' + $("#" + me.pre + fileId).val(), false);
16198
- thisClass.setLogCmd(commandName + ' pdb file ' + file.name, false);
16195
+ thisClass.setLogCmd(commandName + file.name, false);
16199
16196
 
16200
16197
  if(!bAppend) {
16201
16198
  ic.init();
@@ -16209,7 +16206,7 @@ class Events {
16209
16206
  }
16210
16207
 
16211
16208
  ic.bInputfile = true;
16212
- ic.InputfileType = 'pdb';
16209
+ ic.InputfileType = (bmmCIF) ? 'mmcif' : 'pdb';
16213
16210
  ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + dataStr : dataStr;
16214
16211
 
16215
16212
  dataStrAll = (index > 0) ? dataStrAll + '\nENDMDL\n' + dataStr : dataStr;
@@ -16219,15 +16216,21 @@ class Events {
16219
16216
  ic.hAtoms = {};
16220
16217
  ic.dAtoms = {};
16221
16218
  }
16222
- await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
16219
+ if(bmmCIF) {
16220
+ await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend);
16221
+ }
16222
+ else {
16223
+ await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
16224
+ }
16225
+
16226
+ //ic.InputfileType = undefined; // reset
16223
16227
  }
16224
16228
  else {
16225
- await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
16229
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll, bmmCIF);
16226
16230
  }
16227
16231
 
16228
16232
  if(bAppend) {
16229
16233
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
16230
- //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
16231
16234
 
16232
16235
  ic.bResetAnno = true;
16233
16236
 
@@ -16244,9 +16247,7 @@ class Events {
16244
16247
  }
16245
16248
  }
16246
16249
 
16247
- async loadPdbFile(bAppend) { let me = this.icn3dui, ic = me.icn3d;
16248
- let fileId = (bAppend) ? 'pdbfile_app' : 'pdbfile';
16249
-
16250
+ async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d;
16250
16251
  //me = ic.setIcn3dui(this.id);
16251
16252
  ic.bInitial = true;
16252
16253
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -16270,7 +16271,7 @@ class Events {
16270
16271
 
16271
16272
  ic.dataStrAll = '';
16272
16273
 
16273
- await this.readFile(bAppend, files, 0, '');
16274
+ await this.readFile(bAppend, files, 0, '', bmmCIF);
16274
16275
  }
16275
16276
  }
16276
16277
 
@@ -17627,14 +17628,14 @@ class Events {
17627
17628
  e.preventDefault();
17628
17629
 
17629
17630
  let bAppend = false;
17630
- await thisClass.loadPdbFile(bAppend);
17631
+ await thisClass.loadPdbFile(bAppend, 'pdbfile');
17631
17632
  });
17632
17633
 
17633
17634
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", async function(e) { let ic = me.icn3d;
17634
17635
  e.preventDefault();
17635
17636
 
17636
17637
  ic.bAppend = true;
17637
- await thisClass.loadPdbFile(ic.bAppend);
17638
+ await thisClass.loadPdbFile(ic.bAppend, 'pdbfile_app');
17638
17639
  });
17639
17640
 
17640
17641
  me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
@@ -17818,49 +17819,13 @@ class Events {
17818
17819
  await ic.pdbParserCls.downloadUrl(url, type);
17819
17820
  });
17820
17821
 
17821
- me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", function(e) { let ic = me.icn3d;
17822
+ me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", async function(e) { let ic = me.icn3d;
17822
17823
  e.preventDefault();
17823
- ic.bInitial = true;
17824
- if(!me.cfg.notebook) dialog.dialog( "close" );
17825
- //close all dialog
17826
- if(!me.cfg.notebook) {
17827
- $(".ui-dialog-content").dialog("close");
17828
- }
17829
- else {
17830
- ic.resizeCanvasCls.closeDialogs();
17831
- }
17832
- let file = $("#" + me.pre + "mmciffile")[0].files[0];
17833
- if(!file) {
17834
- alert("Please select a file before clicking 'Load'");
17835
- }
17836
- else {
17837
- me.htmlCls.setHtmlCls.fileSupport();
17838
- let reader = new FileReader();
17839
- reader.onload = async function(e) {
17840
- let dataStr = e.target.result; // or = reader.result;
17841
- thisClass.setLogCmd('load mmcif file ' + $("#" + me.pre + "mmciffile").val(), false);
17842
- ic.molTitle = "";
17843
-
17844
- // let url = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi";
17845
- // //ic.bCid = undefined;
17846
17824
 
17847
- // let dataObj = {'mmciffile': dataStr};
17848
- // let data = await me.getAjaxPostPromise(url, dataObj, true);
17849
-
17850
- let bText = true;
17851
- // let bcifData = ic.bcifParserCls.getBcifJson(dataStr, undefined, bText);
17852
- // let data = JSON.parse(bcifData);
17853
-
17854
- //ic.initUI();
17855
- ic.init();
17856
- ic.bInputfile = true;
17857
- ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + data : dataStr;
17858
- ic.InputfileType = 'mmcif';
17859
- // await ic.mmcifParserCls.loadMmcifData(data);
17860
- await ic.opmParserCls.loadOpmData(dataStr, undefined, undefined, 'mmcif', undefined, bText);
17861
- };
17862
- reader.readAsText(file);
17863
- }
17825
+ ic.bAppend = true;
17826
+ let bmmCIF = true;
17827
+ let fileId = 'mmciffile';
17828
+ await thisClass.loadPdbFile(ic.bAppend, fileId, bmmCIF);
17864
17829
  });
17865
17830
 
17866
17831
  me.myEventCls.onIds("#" + me.pre + "applycustomcolor", "click", function(e) { let ic = me.icn3d;
@@ -35789,6 +35754,33 @@ class ResidueLabels {
35789
35754
  ic.hlObjectsCls.removeHlObjects();
35790
35755
  }
35791
35756
 
35757
+ //Add labels for each Ig domain
35758
+ addIgLabels(atoms) { let ic = this.icn3d, me = ic.icn3dui;
35759
+ if(me.bNode) return;
35760
+
35761
+ let size = 60; //18;
35762
+
35763
+ ic.labels['ig'] = [];
35764
+ let chainidHash = ic.firstAtomObjCls.getChainsFromAtoms(atoms);
35765
+
35766
+ for(let chainid in ic.igLabel2Pos) {
35767
+ if(!chainidHash.hasOwnProperty(chainid)) continue;
35768
+
35769
+ for(let text in ic.igLabel2Pos[chainid]) {
35770
+ let label = {}; // Each label contains 'position', 'text', 'color', 'background'
35771
+ label.position = ic.igLabel2Pos[chainid][text];
35772
+ label.text = text;
35773
+
35774
+ label.size = size;
35775
+ label.color = '#00FFFF';
35776
+
35777
+ ic.labels['ig'].push(label);
35778
+ }
35779
+ }
35780
+
35781
+ ic.hlObjectsCls.removeHlObjects();
35782
+ }
35783
+
35792
35784
  addNonCarbonAtomLabels(atoms) { let ic = this.icn3d, me = ic.icn3dui;
35793
35785
  if(me.bNode) return;
35794
35786
 
@@ -40850,9 +40842,24 @@ class AnnoCddSite {
40850
40842
  pssmid2toArray = {};
40851
40843
  }
40852
40844
 
40853
- let indexl =(domainArray !== undefined) ? domainArray.length : 0;
40845
+ if(domainArray === undefined) domainArray = [];
40846
+ let indexl = domainArray.length;
40854
40847
  let maxTextLen =(type == 'domain') ? 14 : 19;
40855
40848
  let titleSpace =(type == 'domain') ? 100 : 120;
40849
+
40850
+ // sort domainArray
40851
+ domainArray.sort(function(a, b) {
40852
+ let domainRepeatArray = a.locs;
40853
+ let segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
40854
+ let domainFrom1 = Math.round(segArray[0].from);
40855
+
40856
+ domainRepeatArray = b.locs;
40857
+ segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
40858
+ let domainFrom2 = Math.round(segArray[0].from);
40859
+
40860
+ return domainFrom1 - domainFrom2;
40861
+ });
40862
+
40856
40863
  for(let index = 0; index < indexl; ++index) {
40857
40864
  let pssmid = (type == 'domain') ? domainArray[index].pssmid : 0;
40858
40865
 
@@ -41721,6 +41728,7 @@ class AnnoIg {
41721
41728
  async showIg(chnid, template) { let ic = this.icn3d; ic.icn3dui;
41722
41729
  // if(!ic.bRunRefnum || Object.keys(ic.atoms).length > Object.keys(ic.hAtoms).length) {
41723
41730
  if(ic.bRunRefnumAgain) {
41731
+ // run for all chains
41724
41732
  await ic.refnumCls.showIgRefNum(template);
41725
41733
  // ic.bRunRefnum = true;
41726
41734
  }
@@ -42043,6 +42051,8 @@ class AnnoIg {
42043
42051
  let igCnt = ic.chain2igArray[chnid].length;
42044
42052
  let fromArray = [], toArray = [];
42045
42053
  let posindex2domainindex = {};
42054
+ if(!ic.igLabel2Pos) ic.igLabel2Pos = {};
42055
+ ic.igLabel2Pos[chnid] = {};
42046
42056
  for(let i = 0; i < igCnt; ++i) {
42047
42057
  let igElem = ic.chain2igArray[chnid][i];
42048
42058
  fromArray = fromArray.concat(igElem.startPosArray);
@@ -42052,6 +42062,18 @@ class AnnoIg {
42052
42062
  let pos = igElem.startPosArray[j];
42053
42063
  posindex2domainindex[pos] = i;
42054
42064
  }
42065
+
42066
+ let resi1 = ic.ParserUtilsCls.getResi(chnid, igElem.startPosArray[0]);
42067
+ let resid1 = chnid + "_" + resi1;
42068
+ let calpha1 = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid1]);
42069
+
42070
+ let resi2 = ic.ParserUtilsCls.getResi(chnid, igElem.endPosArray[igElem.endPosArray.length - 1]);
42071
+ let resid2 = chnid + "_" + resi2;
42072
+ let calpha2 = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid2]);
42073
+
42074
+ let label = chnid.substr(chnid.lastIndexOf('_') + 1) + '-Ig' + (i+1).toString();
42075
+
42076
+ ic.igLabel2Pos[chnid][label] = calpha1.coord.clone().add(calpha2.coord).multiplyScalar(0.5);
42055
42077
  }
42056
42078
 
42057
42079
  // let htmlCnt = '<span class="icn3d-residueNum" title="Ig domain count">' + igCnt.toString() + ' Igs</span>';
@@ -42102,6 +42124,7 @@ class AnnoIg {
42102
42124
  if(igArray.length == 0) return {html: html, html2: html2, html3: html3}
42103
42125
  let rangeArray = [], titleArray = [], fullTitleArray = [], domainArray = [];
42104
42126
 
42127
+ let chain = chnid.substr(chnid.lastIndexOf('_') + 1);
42105
42128
  for(let i = 0, il = igArray.length; i < il; ++i) {
42106
42129
  let domainid = igArray[i].domainid;
42107
42130
  if(!ic.domainid2info) continue;
@@ -42113,7 +42136,7 @@ class AnnoIg {
42113
42136
 
42114
42137
  let igType = (parseFloat(tmscore) < ic.refnumCls.TMThresholdIgType ) ? 'Ig' : ic.ref2igtype[info.refpdbname];
42115
42138
  titleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + ')');
42116
- fullTitleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + '), template: ' + info.refpdbname + ', type: ' + ic.ref2igtype[info.refpdbname] + ', Seq. identity: ' + parseFloat(info.seqid).toFixed(2) + ', aligned residues: ' + info.nresAlign);
42139
+ fullTitleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + '), template: ' + info.refpdbname + ', type: ' + ic.ref2igtype[info.refpdbname] + ', Seq. identity: ' + parseFloat(info.seqid).toFixed(2) + ', aligned residues: ' + info.nresAlign + ', label in 3D: ' + chain + '-Ig' + (i+1).toString());
42117
42140
 
42118
42141
  domainArray.push(igType);
42119
42142
 
@@ -42378,9 +42401,7 @@ class AnnoDomain {
42378
42401
 
42379
42402
  let result = ic.domain3dCls.c2b_NewSplitChain(atoms);
42380
42403
  let subdomains = result.subdomains;
42381
- let pos2resi = result.pos2resi;
42382
- //let substruct = result.substruct;
42383
- //let jsonStr = ic.domain3dCls.getDomainJsonForAlign(atoms);
42404
+ // let pos2resi = result.pos2resi;
42384
42405
 
42385
42406
  for(let i = 0, il = subdomains.length; i < il; ++i) {
42386
42407
  // domain item: {"sdid":1722375,"intervals":[[1,104],[269,323]]}
@@ -42394,7 +42415,7 @@ class AnnoDomain {
42394
42415
  data.domains[chainid].domains.push(domain);
42395
42416
  }
42396
42417
 
42397
- data.domains[chainid].pos2resi = pos2resi;
42418
+ // data.domains[chainid].pos2resi = pos2resi;
42398
42419
  }
42399
42420
  }
42400
42421
 
@@ -42427,11 +42448,26 @@ class AnnoDomain {
42427
42448
  this.showDomainPerStructure(i);
42428
42449
  }
42429
42450
  }
42451
+
42452
+ getResiFromNnbiresid(ncbiresid) { let ic = this.icn3d; ic.icn3dui;
42453
+ let resid = (ic.ncbi2resid[ncbiresid]) ? ic.ncbi2resid[ncbiresid] : ncbiresid;
42454
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
42455
+
42456
+ return resi;
42457
+ }
42458
+
42459
+ getNcbiresiFromResid(resid) { let ic = this.icn3d; ic.icn3dui;
42460
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
42461
+ let resi = ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1);
42462
+
42463
+ return resi;
42464
+ }
42465
+
42430
42466
  showDomainWithData(chnid, data, bCalcDirect) { let ic = this.icn3d, me = ic.icn3dui;
42431
42467
  let html = '<div id="' + ic.pre + chnid + '_domainseq_sequence" class="icn3d-dl_sequence">';
42432
42468
  let html2 = html;
42433
42469
  let html3 = html;
42434
- let domainArray, pos2resi, proteinname;
42470
+ let domainArray, proteinname;
42435
42471
  let pos = chnid.indexOf('_');
42436
42472
  let chain = chnid.substr(pos + 1);
42437
42473
  // MMDB symmetry chain has the form of 'A1'
@@ -42442,7 +42478,7 @@ class AnnoDomain {
42442
42478
  // if(bCalcDirect) {
42443
42479
  proteinname = chnid;
42444
42480
  domainArray = (data.domains[chnid]) ? data.domains[chnid].domains : [];
42445
- pos2resi = data.domains[chnid].pos2resi;
42481
+ // pos2resi = data.domains[chnid].pos2resi;
42446
42482
  /*
42447
42483
  }
42448
42484
  else {
@@ -42470,40 +42506,33 @@ class AnnoDomain {
42470
42506
  let title =(fulltitle.length > 17) ? fulltitle.substr(0,17) + '...' : fulltitle;
42471
42507
  let subdomainArray = domainArray[index].intervals;
42472
42508
  // remove duplicate, e.g., at https://www.ncbi.nlm.nih.gov/Structure/mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=1itw
42473
- let domainFromHash = {}, domainToHash = {};
42474
- let fromArray = [], toArray = [], posFromArray = [], posToArray = [];
42509
+ // let domainFromHash = {}, domainToHash = {};
42510
+ let fromArray = [], toArray = []; // posFromArray = [], posToArray = [];
42475
42511
  let resiHash = {};
42476
42512
  let resCnt = 0;
42477
42513
 
42514
+ // subdomainArray contains NCBI residue number
42478
42515
  for(let i = 0, il = subdomainArray.length; i < il; ++i) {
42479
- let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
42480
- let domainTo = Math.round(subdomainArray[i][1]) - 1;
42516
+ // let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
42517
+ // let domainTo = Math.round(subdomainArray[i][1]) - 1;
42481
42518
 
42482
- if(domainFromHash.hasOwnProperty(domainFrom) || domainToHash.hasOwnProperty(domainTo)) {
42483
- continue; // do nothing for duplicated "from" or "to", e.g, PDBID 1ITW, 5FWI
42484
- }
42485
- else {
42486
- domainFromHash[domainFrom] = 1;
42487
- domainToHash[domainTo] = 1;
42488
- }
42519
+ let domainFrom = parseInt(subdomainArray[i][0]);
42520
+ let domainTo = parseInt(subdomainArray[i][1]);
42489
42521
 
42490
- // use the NCBI residue number, and convert to PDB residue number during selection
42491
- // if(ic.bNCBI || bCalcDirect) {
42492
- fromArray.push(pos2resi[domainFrom]);
42493
- toArray.push(pos2resi[domainTo]);
42494
42522
 
42495
- posFromArray.push(domainFrom);
42496
- posToArray.push(domainTo);
42497
- // }
42498
- // else {
42499
- // fromArray.push(domainFrom + ic.baseResi[chnid]);
42500
- // toArray.push(domainTo + ic.baseResi[chnid]);
42501
- // }
42523
+ // fromArray.push(pos2resi[domainFrom]);
42524
+ // toArray.push(pos2resi[domainTo]);
42525
+
42526
+ fromArray.push(domainFrom);
42527
+ toArray.push(domainTo);
42528
+
42529
+ // posFromArray.push(domainFrom);
42530
+ // posToArray.push(domainTo);
42502
42531
 
42503
42532
  resCnt += domainTo - domainFrom + 1;
42504
42533
  for(let j = domainFrom; j <= domainTo; ++j) {
42505
- // resiHash[j+1] = 1;
42506
- let resi = pos2resi[j];
42534
+ // let resi = pos2resi[j];
42535
+ let resi = this.getResiFromNnbiresid(chnid + '_' + j);
42507
42536
  resiHash[resi] = 1;
42508
42537
  }
42509
42538
  }
@@ -42514,21 +42543,22 @@ class AnnoDomain {
42514
42543
 
42515
42544
  if(!ic.resid2domain) ic.resid2domain = {};
42516
42545
  if(!ic.resid2domain[chnid]) ic.resid2domain[chnid] = [];
42517
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
42518
- let from = parseInt(posFromArray[i]);
42519
- let to = parseInt(posToArray[i]);
42546
+ // for(let i = 0, il = posFromArray.length; i < il; ++i) {
42547
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
42548
+ let from = fromArray[i];
42549
+ let to = toArray[i];
42520
42550
  for(let j = from; j <= to; ++j) {
42521
42551
  // 0-based
42522
42552
  let obj = {};
42523
42553
  // let resi = ic.ParserUtilsCls.getResi(chnid, j);
42524
- let resi = pos2resi[j];
42525
- obj[chnid + '_' + resi] = domainName;
42554
+ let resid = ic.ncbi2resid(chnid + '_' + j);
42555
+ obj[resid] = domainName;
42526
42556
  ic.resid2domain[chnid].push(obj);
42527
42557
  }
42528
42558
  }
42529
42559
  }
42530
42560
 
42531
- let htmlTmp2 = '<div class="icn3d-seqTitle icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + posFromArray + '" to="' + posToArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
42561
+ let htmlTmp2 = '<div class="icn3d-seqTitle icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
42532
42562
  let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
42533
42563
  html3 += htmlTmp2 + htmlTmp3 + '<br>';
42534
42564
  let htmlTmp = '<span class="icn3d-seqLine">';
@@ -42568,12 +42598,12 @@ class AnnoDomain {
42568
42598
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
42569
42599
 
42570
42600
  if(me.cfg.blast_rep_id != chnid) { // regular
42571
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
42601
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
42572
42602
  // let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i] - ic.baseResi[chnid] - 1) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
42573
- let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
42603
+ let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
42574
42604
 
42575
42605
  html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
42576
- html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(posToArray[i] - posFromArray[i] + 1) / ic.maxAnnoLength) + 'px;" class="icn3d-seqTitle icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + posFromArray + '" to="' + posToArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" id="' + chnid + '_3d_domain_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">3D domain ' +(index+1).toString() + '</div>';
42606
+ 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 icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" id="' + chnid + '_3d_domain_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">3D domain ' +(index+1).toString() + '</div>';
42577
42607
  }
42578
42608
  }
42579
42609
  else { // with potential gaps
@@ -44085,6 +44115,7 @@ class Domain3d {
44085
44115
  //c2b_NewSplitChain(string asymId, let seqLen, let* x0, let* y0, let* z0) { let ic = this.icn3d, me = ic.icn3dui;
44086
44116
  // x0, y0, z0: array of x,y,z coordinates of C-alpha atoms
44087
44117
  //c2b_NewSplitChain(chnid, dcut) { let ic = this.icn3d, me = ic.icn3dui;
44118
+ // this function works for a single chain
44088
44119
  c2b_NewSplitChain(atoms, dcut) { let ic = this.icn3d; ic.icn3dui;
44089
44120
  this.init3ddomain();
44090
44121
 
@@ -44140,14 +44171,11 @@ class Domain3d {
44140
44171
  // pos2resi[i+1] = resi;
44141
44172
  pos2resi[i] = resi;
44142
44173
 
44143
- ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
44144
- // let residNCBI = ic.resid2ncbi[resid];
44145
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44146
- // pos2resi[pos] = resi;
44147
-
44174
+ // ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
44148
44175
  if(atom.ssend) {
44149
44176
  //substructItem.To = parseInt(resi);
44150
44177
  substructItem.To = i + 1;
44178
+ // substructItem.To = ic.annoDomainCls.getNcbiresiFromResid(resid);
44151
44179
  substructItem.x2 = atom.coord.x;
44152
44180
  substructItem.y2 = atom.coord.y;
44153
44181
  substructItem.z2 = atom.coord.z;
@@ -44162,6 +44190,7 @@ class Domain3d {
44162
44190
  if(atom.ssbegin) {
44163
44191
  //substructItem.From = parseInt(resi);
44164
44192
  substructItem.From = i + 1;
44193
+ // substructItem.From = ic.annoDomainCls.getNcbiresiFromResid(resid);
44165
44194
  substructItem.x1 = atom.coord.x;
44166
44195
  substructItem.y1 = atom.coord.y;
44167
44196
  substructItem.z1 = atom.coord.z;
@@ -44169,17 +44198,19 @@ class Domain3d {
44169
44198
  }
44170
44199
 
44171
44200
  let nsse = substruct.length;
44172
-
44173
- if (nsse <= 3)
44201
+
44202
+ if (nsse <= 3) {
44174
44203
  // too small, can't split or trim
44175
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44204
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44205
+ return {subdomains: subdomains, substruct: substruct};
44206
+ }
44176
44207
 
44177
44208
  if (nsse > this.MAX_SSE) {
44178
44209
  // we have a problem...
44179
-
44180
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44210
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44211
+ return {subdomains: subdomains, substruct: substruct};
44181
44212
  }
44182
-
44213
+
44183
44214
  let seqLen = residueArray.length; // + resiOffset;
44184
44215
  //let lastResi = resiArray[seqLen - 1];
44185
44216
  let lastResi = seqLen;
@@ -44500,7 +44531,8 @@ class Domain3d {
44500
44531
  let k = prts[i] - 1;
44501
44532
 
44502
44533
  if ((k < 0) || (k >= substruct.length)) {
44503
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44534
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44535
+ return {subdomains: subdomains, substruct: substruct};
44504
44536
  }
44505
44537
 
44506
44538
  //SSE_Rec sserec = substruct[k];
@@ -44587,16 +44619,23 @@ class Domain3d {
44587
44619
 
44588
44620
  if (inseg && (rf == 0)) {
44589
44621
  // segment ends
44590
- segments.push(startseg);
44591
- segments.push(i);
44622
+ // segments.push(startseg);
44623
+ // segments.push(i);
44624
+
44625
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, i, pos2resi);
44626
+ segments = segments.concat(resiRangeArray);
44627
+
44592
44628
  inseg = false;
44593
44629
  }
44594
44630
  }
44595
44631
 
44596
44632
  // check for the last segment
44597
44633
  if (inseg) {
44598
- segments.push(startseg);
44599
- segments.push(lastResi);
44634
+ // segments.push(startseg);
44635
+ // segments.push(lastResi);
44636
+
44637
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, lastResi, pos2resi);
44638
+ segments = segments.concat(resiRangeArray);
44600
44639
  }
44601
44640
 
44602
44641
  subdomains.push(segments);
@@ -44617,61 +44656,114 @@ class Domain3d {
44617
44656
  }
44618
44657
  }
44619
44658
 
44620
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi };
44659
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44660
+
44661
+ // return {subdomains: subdomains, substruct: substruct};
44662
+ //subdomains contains NCBI residue numbers
44663
+ return {subdomains: subdomains, substruct: substruct};
44621
44664
  } // end c2b_NewSplitChain
44622
44665
 
44623
- getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
44666
+ standardizeSubstruct(chnid, substruct, pos2resi) { let ic = this.icn3d; ic.icn3dui;
44667
+ // adjust substruct to use NCBI residue number
44668
+ for (let i = 0; i < substruct.length; i++) {
44669
+ //SSE_Rec sserec = substruct[i];
44670
+ let sserec = substruct[i];
44671
+ let FromPos = sserec.From;
44672
+ let ToPos = sserec.To;
44673
+
44674
+ let FromResi = pos2resi[FromPos - 1];
44675
+ let ToResi = pos2resi[ToPos - 1];
44676
+
44677
+ let FromNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + FromResi);
44678
+ let ToNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + ToResi);
44679
+
44680
+ substruct[i].From = FromNcbiResid.substr(FromNcbiResid.lastIndexOf('_') + 1);
44681
+ substruct[i].To = ToNcbiResid.substr(ToNcbiResid.lastIndexOf('_') + 1);
44682
+
44683
+ substruct[i].From = parseInt(substruct[i].From);
44684
+ substruct[i].To = parseInt(substruct[i].To);
44685
+ }
44686
+
44687
+ return substruct;
44688
+ }
44689
+
44690
+ getNcbiresiRangeFromPos(chnid, startPos, endPos, pos2resi) { let ic = this.icn3d; ic.icn3dui;
44691
+ let resiArray = [];
44692
+ for(let i = startPos; i <= endPos; ++i) {
44693
+ let resi = pos2resi[i - 1];
44694
+ let residNCBI = (ic.resid2ncbi[chnid + '_' + resi]) ? ic.resid2ncbi[chnid + '_' + resi] : chnid + '_' + resi;
44695
+ let ncbiresi = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44696
+ resiArray.push(parseInt(ncbiresi));
44697
+ }
44698
+
44699
+ let resiRangeArray = ic.resid2specCls.resi2range(resiArray);
44700
+
44701
+ return resiRangeArray;
44702
+ }
44703
+
44704
+ /*
44705
+ // this function works for atoms in a single chain
44706
+ // getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
44707
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
44624
44708
  let result = this.c2b_NewSplitChain(atoms);
44625
44709
 
44626
44710
  let subdomains = result.subdomains;
44627
44711
  let substruct = result.substruct;
44628
- let pos2resi = result.pos2resi;
44712
+ // let pos2resi = result.pos2resi;
44629
44713
 
44630
- let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44631
- let residueArray = Object.keys(residueHash);
44632
- let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44633
44714
 
44634
- if(bForceOneDomain) subdomains = [];
44715
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44716
+ // let residueArray = Object.keys(residueHash);
44717
+ // let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44635
44718
 
44636
- //the whole structure is also considered as a large domain
44637
- //if(subdomains.length == 0) {
44638
- //subdomains.push([parseInt(ic.chainsSeq[chnid][0].resi), parseInt(ic.chainsSeq[chnid][ic.chainsSeq[chnid].length - 1].resi)]);
44719
+ let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
44720
+ let chnid = firstAtom.structure + '_' + firstAtom.chain;
44639
44721
 
44640
- // subdomains.push([parseInt(residueArray[0].substr(residueArray[0].lastIndexOf('_') + 1)),
44641
- // parseInt(residueArray[residueArray.length-1].substr(residueArray[residueArray.length-1].lastIndexOf('_') + 1))]);
44722
+ // if(bForceOneDomain) subdomains = [];
44642
44723
 
44643
- // use position based
44644
- subdomains.push([1, residueArray.length]);
44645
-
44646
- //}
44724
+ //the whole structure is also considered as a large domain
44725
+ if(subdomains.length == 0) {
44726
+ let resid1 = residueArray[0];
44727
+ let resid2 = residueArray[residueArray.length - 1];
44728
+ let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
44729
+ let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
44730
+ subdomains.push([parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1)), parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1))]);
44731
+ }
44647
44732
 
44648
44733
  // m_domains1: {"data": [ {"ss": [[1,20,30,x,y,z,x,y,z], [2,50,60,x,y,z,x,y,z]], "domain": [[1,43,x,y,z],[2,58,x,y,z], ...]}, {"ss": [[1,20,30,x,y,z,x,y,z], [2,50,60,x,y,z,x,y,z]],"domain": [[1,43,x,y,z],[2,58,x,y,z], ...]} ] }
44649
44734
  let jsonStr = '{"data": [';
44735
+ //merge all subdomains into one domain
44736
+ jsonStr += '{"ss": ['; //secondary structure
44737
+
44738
+ let ssCnt = 0, startAll = 999, endAll = -999;
44650
44739
  for(let i = 0, il = subdomains.length; i < il; ++i) {
44651
- if(i > 0) jsonStr += ', ';
44652
- //secondary structure
44653
- jsonStr += '{"ss": [';
44654
- let ssCnt = 0;
44740
+ // if(i > 0) jsonStr += ', ';
44741
+ // jsonStr += '{"ss": ['; //secondary structure
44742
+
44655
44743
  for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
44656
44744
  let start = subdomains[i][j];
44657
44745
  let end = subdomains[i][j + 1];
44658
-
44746
+
44747
+ if(start < startAll) startAll = start;
44748
+ if(end > endAll) endAll = end;
44749
+
44659
44750
  for(let k = 0, kl = substruct.length; k < kl; ++k) {
44660
44751
  //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
44661
44752
  //sstype: 1 (helix), 2 (sheet)
44662
44753
  let sstype = (substruct[k].Sheet) ? 2 : 1;
44663
- let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
44664
- let to = pos2resi[substruct[k].To - 1];
44754
+ // let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
44755
+ // let to = pos2resi[substruct[k].To - 1];
44665
44756
 
44666
44757
  // 1-based residue numbers
44667
44758
  let fromPos = substruct[k].From;
44668
44759
  let toPos = substruct[k].To;
44669
44760
 
44670
- let residFrom = chnid + "_" + from;
44761
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
44671
44762
  let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
44763
+
44672
44764
  if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
44673
44765
 
44674
- let residTo = chnid + "_" + to;
44766
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
44675
44767
  let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
44676
44768
  if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
44677
44769
 
@@ -44683,45 +44775,170 @@ class Domain3d {
44683
44775
  }
44684
44776
  }
44685
44777
  }
44686
- jsonStr += ']';
44778
+ }
44779
+ jsonStr += ']';
44780
+
44781
+ // domain
44782
+ jsonStr += ', "domain": [';
44783
+ let domainCnt = 0;
44784
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
44687
44785
 
44688
- // domain
44689
- jsonStr += ', "domain": [';
44690
- let domainCnt = 0;
44691
- for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
44692
- let start = subdomains[i][j];
44693
- let end = subdomains[i][j + 1];
44786
+ // resi should be the continuous number starting from 1. make this correction in the backend
44787
+ for(let j = startAll; j <= endAll; ++j) {
44788
+ let ncbiResid = chnid + '_' + j;
44789
+ let resid = ic.ncbi2resid[ncbiResid];
44790
+
44791
+ let pos = j;
44694
44792
 
44695
- for(let k = 0, kl = residueArray.length; k < kl; ++k) {
44696
- let resid = residueArray[k];
44793
+ if(domainCnt > 0) jsonStr += ', ';
44794
+
44795
+ if(!residueHash.hasOwnProperty(resid)) {
44796
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
44797
+ }
44798
+ else {
44799
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44800
+
44801
+ //domain: resi, restype, x, y, z
44802
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
44803
+
44804
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44805
+ }
44806
+
44807
+ ++domainCnt;
44808
+ }
44809
+ jsonStr += ']}';
44697
44810
 
44698
- // let resi = resid.substr(resid.lastIndexOf('_') + 1);
44699
- // let residNCBI = ic.resid2ncbi[resid];
44700
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44701
- let pos = k + 1;
44811
+ jsonStr += ']}';
44812
+
44813
+ return jsonStr;
44814
+ }
44815
+ */
44816
+ // this function works for atoms in a single chain
44817
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
44818
+ // let result = this.c2b_NewSplitChain(atoms);
44819
+
44820
+ // let subdomains = result.subdomains;
44821
+ // let substruct = result.substruct;
44822
+
44823
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44824
+ let residueArray = Object.keys(residueHash);
44825
+ let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44826
+
44827
+ // let resid1 = residueArray[0];
44828
+ // let resid2 = residueArray[residueArray.length - 1];
44829
+ // let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
44830
+ // let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
44831
+ // let startAll = parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1));
44832
+ // let endAll = parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1));
44833
+
44834
+ let substruct = [];
44835
+ let substructItem = {};
44836
+ let pos2resi = {}; // 0-based
44837
+ let startAll = 999, endAll = -999;
44838
+ for(let i = 0; i < residueArray.length; ++i) {
44839
+ let resid = residueArray[i];
44840
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44841
+
44842
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
44843
+ pos2resi[i] = resi;
44844
+
44845
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
44846
+ let ncbiresi = parseInt(ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1));
44847
+
44848
+ if(ncbiresi < startAll) startAll = ncbiresi;
44849
+ if(ncbiresi > endAll) endAll = ncbiresi;
44850
+
44851
+ if(atom.ssend) {
44852
+ substructItem.To = i + 1;
44853
+ substructItem.x2 = atom.coord.x;
44854
+ substructItem.y2 = atom.coord.y;
44855
+ substructItem.z2 = atom.coord.z;
44856
+
44857
+ substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
44858
+
44859
+ substruct.push(substructItem);
44860
+ substructItem = {};
44861
+ }
44862
+
44863
+ // a residue could be both start and end. check ssend first, then check ssbegin
44864
+ if(atom.ssbegin) {
44865
+ substructItem.From = i + 1;
44866
+ substructItem.x1 = atom.coord.x;
44867
+ substructItem.y1 = atom.coord.y;
44868
+ substructItem.z1 = atom.coord.z;
44869
+ }
44870
+ }
44871
+
44872
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44873
+
44874
+ // m_domains1: {"data": [ {"ss": [[1,20,30,x,y,z,x,y,z], [2,50,60,x,y,z,x,y,z]], "domain": [[1,43,x,y,z],[2,58,x,y,z], ...]}, {"ss": [[1,20,30,x,y,z,x,y,z], [2,50,60,x,y,z,x,y,z]],"domain": [[1,43,x,y,z],[2,58,x,y,z], ...]} ] }
44875
+ let jsonStr = '{"data": [';
44876
+ //merge all subdomains into one domain
44877
+ jsonStr += '{"ss": ['; //secondary structure
44878
+
44879
+ let ssCnt = 0;
44880
+ for(let k = 0, kl = substruct.length; k < kl; ++k) {
44881
+ //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
44882
+ //sstype: 1 (helix), 2 (sheet)
44883
+ let sstype = (substruct[k].Sheet) ? 2 : 1;
44884
+
44885
+ // 1-based residue numbers
44886
+ let fromPos = substruct[k].From;
44887
+ let toPos = substruct[k].To;
44888
+
44889
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
44890
+ let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
44891
+ if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
44892
+
44893
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
44894
+ let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
44895
+ if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
44896
+
44897
+ // if(fromPos >= start && toPos <= end) {
44898
+ if(ssCnt > 0) jsonStr += ', ';
44899
+ jsonStr += '[' + sstype + ',' + fromPos + ',' + toPos + ',' + substruct[k].x1.toFixed(2) + ',' + substruct[k].y1.toFixed(2) + ','
44900
+ + substruct[k].z1.toFixed(2) + ',' + substruct[k].x2.toFixed(2) + ',' + substruct[k].y2.toFixed(2) + ',' + substruct[k].z2.toFixed(2) + ']';
44901
+ ++ssCnt;
44902
+ // }
44903
+ }
44904
+
44905
+ jsonStr += ']';
44702
44906
 
44703
- //let resid = chnid + "_" + resi;
44704
- let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44705
-
44706
- if(!atom) continue;
44707
- if(!ic.hAtoms.hasOwnProperty(atom.serial)) continue;
44708
-
44709
- //domain: resi, restype, x, y, z
44710
- let restype = me.parasCls.resn2restype[atom.resn];
44711
- if(restype !== undefined && pos >= start && pos <= end) {
44712
- if(domainCnt > 0) jsonStr += ', ';
44713
- jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ','
44714
- + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44715
- ++domainCnt;
44716
- }
44717
- }
44907
+ // domain
44908
+ jsonStr += ', "domain": [';
44909
+ let domainCnt = 0;
44910
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
44911
+
44912
+ // resi should be the continuous number starting from 1. make this correction in the backend
44913
+ for(let j = startAll; j <= endAll; ++j) {
44914
+ let ncbiResid = chnid + '_' + j;
44915
+ let resid = ic.ncbi2resid[ncbiResid];
44916
+
44917
+ let pos = j;
44918
+
44919
+ if(domainCnt > 0) jsonStr += ', ';
44920
+
44921
+ if(!residueHash.hasOwnProperty(resid)) {
44922
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
44923
+ }
44924
+ else {
44925
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44926
+
44927
+ //domain: resi, restype, x, y, z
44928
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
44929
+
44930
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44718
44931
  }
44719
- jsonStr += ']}';
44932
+
44933
+ ++domainCnt;
44720
44934
  }
44721
44935
  jsonStr += ']}';
44722
44936
 
44937
+ jsonStr += ']}';
44938
+
44723
44939
  return jsonStr;
44724
44940
  }
44941
+
44725
44942
  }
44726
44943
 
44727
44944
  /**
@@ -46827,7 +47044,6 @@ class Annotation {
46827
47044
  if($("#" + ic.pre + "anno_transmem").length) $("#" + ic.pre + "anno_transmem")[0].checked = false;
46828
47045
  }
46829
47046
  async setAnnoTabIg(bSelection, template) { let ic = this.icn3d; ic.icn3dui;
46830
-
46831
47047
  await this.updateIg(bSelection, template);
46832
47048
 
46833
47049
  $("[id^=" + ic.pre + "ig]").show();
@@ -47168,7 +47384,7 @@ class Annotation {
47168
47384
 
47169
47385
  async updateIg(bSelection, template) { let ic = this.icn3d, me = ic.icn3dui;
47170
47386
  ic.opts['color'] = 'ig strand';
47171
-
47387
+
47172
47388
  // if(!bSelection && !template) {
47173
47389
  if(!bSelection) {
47174
47390
  // select all protein chains
@@ -47187,11 +47403,13 @@ class Annotation {
47187
47403
  }
47188
47404
 
47189
47405
  ic.bRunRefnumAgain = true;
47190
- for(let chainid in ic.protein_chainid) {
47406
+ let chainidHash = (!bSelection) ? ic.protein_chainid : ic.firstAtomObjCls.getChainsFromAtoms(ic.hAtoms);
47407
+ for(let chainid in chainidHash) {
47408
+ // showIgRefNum() in showIg() runs for all chains
47191
47409
  await ic.annoIgCls.showIg(chainid, template);
47192
47410
  ic.bRunRefnumAgain = false; // run it once for all chains
47193
47411
  }
47194
-
47412
+
47195
47413
  if(ic.bShowRefnum) {
47196
47414
  ic.hlUpdateCls.updateHlAll();
47197
47415
  ic.drawCls.draw();
@@ -48938,8 +49156,9 @@ class HlSeq {
48938
49156
  residueid = ic.ncbi2resid[residNCBI];
48939
49157
  }
48940
49158
  else if($(that).attr('3ddomain') !== undefined) {
48941
- // the position of residues with coordinates
48942
- residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
49159
+ // NCBI residue numbers
49160
+ // residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
49161
+ residueid = ic.ncbi2resid[chainid + '_' + j];
48943
49162
  }
48944
49163
  else {
48945
49164
  residueid = chainid + '_' + (j+1).toString();
@@ -49187,7 +49406,7 @@ class HlUpdate {
49187
49406
  }
49188
49407
 
49189
49408
  //Remove the highlight in the 2D interaction diagram.
49190
- removeHl2D() { let ic = this.icn3d; ic.icn3dui;
49409
+ removeHl2D(bRemoveChainOnly) { let ic = this.icn3d; ic.icn3dui;
49191
49410
  // clear nodes in 2d dgm
49192
49411
  $("#" + ic.pre + "dl_2ddgm rect").attr('stroke', '#000000');
49193
49412
  $("#" + ic.pre + "dl_2ddgm circle").attr('stroke', '#000000');
@@ -49201,6 +49420,22 @@ class HlUpdate {
49201
49420
  $("#" + ic.pre + "dl_2ddgm svg line").attr('stroke', '#000000');
49202
49421
  $("#" + ic.pre + "dl_2ddgm line").attr('stroke-width', 1);
49203
49422
  }
49423
+
49424
+ if(!bRemoveChainOnly) {
49425
+ // clear nodes in 2d interaction network
49426
+ // $("#" + ic.pre + "dl_linegraph rect").attr('stroke', '#000000');
49427
+ $("#" + ic.pre + "dl_linegraph circle").attr('stroke', '#000000');
49428
+
49429
+ // $("#" + ic.pre + "dl_linegraph rect").attr('stroke-width', 1);
49430
+ $("#" + ic.pre + "dl_linegraph circle").attr('stroke-width', 1);
49431
+
49432
+ // clear nodes in 2d interaction graph
49433
+ $("#" + ic.pre + "dl_scatterplot rect").attr('stroke', '#000000');
49434
+ $("#" + ic.pre + "dl_scatterplot circle").attr('stroke', '#000000');
49435
+
49436
+ $("#" + ic.pre + "dl_scatterplot rect").attr('stroke-width', 1);
49437
+ $("#" + ic.pre + "dl_scatterplot circle").attr('stroke-width', 1);
49438
+ }
49204
49439
  }
49205
49440
 
49206
49441
  //Remove the selection in the menu of defined sets.
@@ -49298,7 +49533,7 @@ class HlUpdate {
49298
49533
  // update highlight in 2D window
49299
49534
  //Update the highlight of 2D interaction diagram according to the current highlighted atoms.
49300
49535
  updateHl2D(chainArray2d) { let ic = this.icn3d, me = ic.icn3dui;
49301
- this.removeHl2D();
49536
+ this.removeHl2D(true);
49302
49537
 
49303
49538
  if(ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length == Object.keys(ic.atoms).length) return;
49304
49539
 
@@ -49623,7 +49858,7 @@ class LineGraph {
49623
49858
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
49624
49859
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
49625
49860
  let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
49626
- let linkedNodeCnt = {}, linkedNodeInterDiff = {};
49861
+ let linkedNodeCnt = {}, linkedNodeInterDiff = {}, linkedNodeInterDiffBool = {};
49627
49862
 
49628
49863
  for(let i = 0, il = structureArray.length; i < il; ++i) {
49629
49864
  nodeArray1Split[i] = [];
@@ -49682,13 +49917,15 @@ class LineGraph {
49682
49917
  linkedNodeInterDiff[mappingid] = link.n;
49683
49918
  }
49684
49919
  else {
49685
- ++linkedNodeCnt[mappingid];
49686
- linkedNodeInterDiff[mappingid] -= link.n; // show difference
49920
+ ++linkedNodeCnt[mappingid];
49921
+ linkedNodeInterDiff[mappingid] += link.n;
49922
+
49923
+ linkedNodeInterDiffBool[mappingid] = (linkedNodeInterDiff[mappingid] / link.n == linkedNodeCnt[mappingid]) ? 0 : 1;
49687
49924
  }
49688
49925
  }
49689
49926
  }
49690
49927
  }
49691
-
49928
+
49692
49929
  // do not combine with the above section since linkedNodeCnt was pre-populated above
49693
49930
  // set linkArraySplitCommon and nameHashSplitCommon
49694
49931
  // set linkArraySplitDiff and nameHashSplitDiff
@@ -49723,6 +49960,8 @@ class LineGraph {
49723
49960
  && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
49724
49961
  mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
49725
49962
  mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
49963
+
49964
+ let bIgRef = (mapping1.length > 4 && !isNaN(parseInt(mapping1.substr(-4, 4)))) || (mapping2.length > 4 && !isNaN(parseInt(mapping2.substr(-4, 4))));
49726
49965
 
49727
49966
  let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
49728
49967
 
@@ -49734,7 +49973,7 @@ class LineGraph {
49734
49973
  linkDiff.source += separatorDiff + ic.chainsMapping[chainid1][resid1];
49735
49974
  linkDiff.target += separatorDiff + ic.chainsMapping[chainid2][resid2];
49736
49975
 
49737
- if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiff[mappingid] == 0) {
49976
+ if(linkedNodeCnt[mappingid] == structureArray.length && (bIgRef || linkedNodeInterDiffBool[mappingid] == 0)) {
49738
49977
  linkArraySplitCommon[index].push(linkCommon);
49739
49978
  }
49740
49979
  else {
@@ -50431,18 +50670,20 @@ class GetGraph {
50431
50670
  return lineGraphStr;
50432
50671
  }
50433
50672
 
50434
- updateGraphColor() { let ic = this.icn3d, me = ic.icn3dui;
50673
+ updateGraphColor() { let ic = this.icn3d; ic.icn3dui;
50435
50674
  // change graph color
50436
50675
 
50676
+ // do not update the graph for now
50677
+ /*
50437
50678
  if(ic.graphStr !== undefined) {
50438
50679
  let graphJson = JSON.parse(ic.graphStr);
50439
- let resid2color = {};
50680
+ let resid2color = {}
50440
50681
  for(let resid in ic.residues) {
50441
50682
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
50442
50683
  resid2color[resid] = atom.color.getHexString().toUpperCase();
50443
50684
  }
50444
50685
 
50445
- let target2resid = {};
50686
+ let target2resid = {}
50446
50687
  for(let i = 0, il = graphJson.nodes.length; i < il; ++i) {
50447
50688
  let node = graphJson.nodes[i];
50448
50689
  //node.r: 1_1_1KQ2_A_1
@@ -50471,6 +50712,7 @@ class GetGraph {
50471
50712
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
50472
50713
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
50473
50714
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
50715
+ */
50474
50716
  }
50475
50717
 
50476
50718
  handleForce() { let ic = this.icn3d, me = ic.icn3dui;
@@ -52634,7 +52876,7 @@ class ContactMap {
52634
52876
 
52635
52877
  let graphStr = '{\n';
52636
52878
 
52637
- let struc1 = (ic.structures.length > 0) ? ic.structures[0] : ic.defaultPdbId;
52879
+ let struc1 = (Object.keys(ic.structures).length > 0) ? ic.structures[0] : ic.defaultPdbId;
52638
52880
  let len1 = nodeArray1.length,
52639
52881
  len2 = nodeArray2.length;
52640
52882
  let factor = 1;
@@ -53168,6 +53410,7 @@ class ChainalignParser {
53168
53410
  let allPromise = Promise.allSettled(ajaxArray);
53169
53411
  // try {
53170
53412
  let dataArray = await allPromise;
53413
+
53171
53414
  await thisClass.downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray, indexArray, mmdbid_t, struArray);
53172
53415
  // }
53173
53416
  // catch(err) {
@@ -53771,13 +54014,13 @@ class ChainalignParser {
53771
54014
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
53772
54015
  && align !== undefined && JSON.stringify(align).indexOf('Oops there was a problem') === -1
53773
54016
  ) {
53774
- if((align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
54017
+ if((align === "error" || align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53775
54018
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
53776
54019
  ic.q_trans_sub[index] = {"x":0, "y":0, "z":0};
53777
54020
  ic.q_rotation[index] = {"x1":1, "y1":0, "z1":0, "x2":0, "y2":1, "z2":0, "x3":0, "y3":0, "z3":1};
53778
54021
  ic.qt_start_end[index] = undefined;
53779
54022
  }
53780
- else if(align === undefined || align.length == 0) {
54023
+ else if(align === "error" || align === undefined || align.length == 0) {
53781
54024
  if(!me.cfg.command && !bNoAlert) alert('These two chains can not align to each other. ' + 'Please select sequences from these two chains in the "Sequences & Annotations" window, ' + 'and click "Realign Selection" in the "File" menu to align your selection.');
53782
54025
 
53783
54026
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
@@ -53808,14 +54051,16 @@ class ChainalignParser {
53808
54051
  ic.qt_start_end[index] = align[0].segs;
53809
54052
 
53810
54053
  let rmsd = align[0].super_rmsd;
54054
+ let rmsdStr = (rmsd) ? rmsd.toPrecision(4) : rmsd;
54055
+ let scoreStr = (align[0].score) ? align[0].score.toPrecision(4) : align[0].score;
53811
54056
 
53812
- let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
53813
- if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
54057
+ let logStr = "alignment RMSD: " + rmsdStr;
54058
+ if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + scoreStr;
53814
54059
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
53815
- let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
54060
+ let html = "<br><b>Alignment RMSD</b>: " + rmsdStr + " &#8491;<br>";
53816
54061
  if(me.cfg.aligntool == 'tmalign') {
53817
- html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
53818
- ic.tmscore = align[0].score.toPrecision(4);
54062
+ html += "<b>TM-score</b>: " + scoreStr + "<br><br>";
54063
+ ic.tmscore = scoreStr;
53819
54064
  }
53820
54065
 
53821
54066
  $("#" + ic.pre + "dl_rmsd_html").html(html);
@@ -53962,6 +54207,7 @@ class ChainalignParser {
53962
54207
  let allPromise = Promise.allSettled(ajaxArray);
53963
54208
  // try {
53964
54209
  let dataArray = await allPromise;
54210
+
53965
54211
  await thisClass.parseMMdbAfData(dataArray, structArray, bQuery, vastplusAtype);
53966
54212
  if(vastplusAtype === undefined) ic.ParserUtilsCls.hideLoading();
53967
54213
  // }
@@ -53994,13 +54240,9 @@ class ChainalignParser {
53994
54240
 
53995
54241
  //if(!ic.bCommandLoad && !bQuery) ic.init(); // remove all previously loaded data
53996
54242
 
53997
- let hAtoms = {}, hAtomsTmp = {};
54243
+ let hAtoms = {};
53998
54244
  let bLastQuery = false;
53999
54245
 
54000
- let opts = {};
54001
-
54002
- opts['color'] = (structArray.length > 1) ? 'structure' : ((structArray[0].length > 5) ? 'confidence' : 'chain');
54003
-
54004
54246
  for(let i = 0, il = structArray.length; i < il; ++i) {
54005
54247
  if(i == structArray.length - 1) bLastQuery = true;
54006
54248
 
@@ -54015,24 +54257,30 @@ class ChainalignParser {
54015
54257
  targetOrQuery = 'query';
54016
54258
  bAppend = true;
54017
54259
  }
54018
-
54260
+
54019
54261
  //if(structArray[i].length > 4) {
54020
54262
  if(isNaN(structArray[i]) && structArray[i].length > 5) { // PDB ID plus postfix could be 5
54021
54263
  //let bNoDssp = true;
54022
54264
  let bNoDssp = false; // get secondary structure info
54023
- hAtomsTmp = await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
54265
+ await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
54024
54266
  }
54025
54267
  else {
54026
54268
  let bNoSeqalign = true;
54027
54269
  let pdbid = structArray[i];
54028
- hAtomsTmp = await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
54270
+
54271
+ //hAtomsTmp contains all atoms
54272
+ await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
54029
54273
  }
54030
54274
 
54031
- hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
54275
+ // hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
54032
54276
  }
54033
54277
 
54034
- // add color only for the newly loaded structures
54035
- ic.setColorCls.setColorByOptions(opts, hAtoms);
54278
+ let structArrayAll = Object.keys(ic.structures);
54279
+
54280
+ ic.opts['color'] = (structArrayAll.length > 1) ? 'structure' : ((structArrayAll[0].length > 5) ? 'confidence' : 'chain');
54281
+
54282
+ // add color for all structures
54283
+ ic.setColorCls.setColorByOptions(ic.opts, hAtoms);
54036
54284
 
54037
54285
  await ic.ParserUtilsCls.renderStructure();
54038
54286
 
@@ -54062,15 +54310,6 @@ class ChainalignParser {
54062
54310
  if(vastplusAtype == 2) me.cfg.aligntool = 'tmalign';
54063
54311
  await ic.vastplusCls.vastplusAlign(structArray, vastplusAtype);
54064
54312
  }
54065
-
54066
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
54067
-
54068
- // if(Object.keys(ic.structures).length == 1 && me.cfg.mmdbafid.length > 5) {
54069
- // ic.ParserUtilsCls.checkMemProtein(me.cfg.mmdbafid);
54070
- // }
54071
- // else {
54072
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
54073
- // }
54074
54313
  }
54075
54314
  }
54076
54315
 
@@ -55538,24 +55777,32 @@ class MmcifParser {
55538
55777
  if(data.emd !== undefined) ic.emd = data.emd;
55539
55778
  if(data.organism !== undefined) ic.organism = data.organism;
55540
55779
 
55541
- if(ic.emd !== undefined) {
55542
- $("#" + ic.pre + "mapWrapper1").hide();
55543
- $("#" + ic.pre + "mapWrapper2").hide();
55544
- $("#" + ic.pre + "mapWrapper3").hide();
55545
- }
55546
- else {
55547
- $("#" + ic.pre + "emmapWrapper1").hide();
55548
- $("#" + ic.pre + "emmapWrapper2").hide();
55549
- $("#" + ic.pre + "emmapWrapper3").hide();
55550
- }
55551
-
55552
55780
  await ic.opmParserCls.loadOpmData(data, mmcifid, undefined, 'mmcif');
55781
+
55782
+ ic.opmParserCls.modifyUIMapAssembly();
55553
55783
  }
55554
55784
  else {
55555
- //alert('invalid atoms data.');
55556
55785
  return false;
55557
55786
  }
55558
55787
  }
55788
+
55789
+ async loadMultipleMmcifData(data, mmcifid, bAppend) { let ic = this.icn3d; ic.icn3dui;
55790
+ let bText = true;
55791
+ ic.loadCIFCls.loadCIF(data, mmcifid, bText, bAppend);
55792
+
55793
+ if(Object.keys(ic.structures).length > 1) {
55794
+ ic.opts['color'] = 'structure';
55795
+ }
55796
+
55797
+ ic.opmParserCls.modifyUIMapAssembly();
55798
+
55799
+ ic.pdbParserCls.addSecondary(bAppend);
55800
+
55801
+ // ic.setStyleCls.setAtomStyleByOptions(ic.opts);
55802
+ // ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
55803
+
55804
+ // await ic.ParserUtilsCls.renderStructure();
55805
+ }
55559
55806
  }
55560
55807
 
55561
55808
  /**
@@ -56398,26 +56645,26 @@ class BcifParser {
56398
56645
  let molecueType;
56399
56646
  if(atom_hetatm == "ATOM") {
56400
56647
  if(resn.length == 3) {
56401
- molecueType = "p"; // protein
56648
+ molecueType = "protein"; //"p"; // protein
56402
56649
  }
56403
56650
  else {
56404
- molecueType = "n"; // nucleotide
56651
+ molecueType = "nucleotide"; //"n"; // nucleotide
56405
56652
  }
56406
56653
  }
56407
56654
  else {
56408
56655
  if(resn == "WAT" || resn == "HOH") {
56409
- molecueType = "s"; // solvent
56656
+ molecueType = "solvent"; //"s"; // solvent
56410
56657
  chain = 'Misc';
56411
56658
  }
56412
56659
  else {
56413
- molecueType = "l"; // ligands or ions
56660
+ molecueType = "ligand"; //"l"; // ligands or ions
56414
56661
  chain = resn;
56415
56662
  }
56416
56663
  }
56417
56664
 
56418
56665
  // C-alpha only for large structure
56419
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
56420
- || (molecueType == "n" && !(name == "P")) ) ) continue;
56666
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
56667
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
56421
56668
  // skip alternative atoms
56422
56669
  if(alt == "B") continue;
56423
56670
 
@@ -56440,7 +56687,7 @@ class BcifParser {
56440
56687
  // }
56441
56688
  }
56442
56689
 
56443
- if(molecueType == 's' || molecueType == "l") {
56690
+ if(molecueType == 'solvent' || molecueType == "ligand") {
56444
56691
  let seq = {};
56445
56692
  if(!ligSeqHash.hasOwnProperty(chain)) {
56446
56693
  ligSeqHash[chain] = [];
@@ -56578,26 +56825,26 @@ class BcifParser {
56578
56825
  let molecueType;
56579
56826
  if(atom_hetatm == "ATOM") {
56580
56827
  if(resn.length == 3) {
56581
- molecueType = "p"; // protein
56828
+ molecueType = "protein"; // protein
56582
56829
  }
56583
56830
  else {
56584
- molecueType = "n"; // nucleotide
56831
+ molecueType = "nucleotide"; // nucleotide
56585
56832
  }
56586
56833
  }
56587
56834
  else {
56588
56835
  if(resn == "WAT" || resn == "HOH") {
56589
- molecueType = "s"; // solvent
56836
+ molecueType = "solvent"; // solvent
56590
56837
  chain = 'Misc';
56591
56838
  }
56592
56839
  else {
56593
- molecueType = "l"; // ligands or ions
56840
+ molecueType = "ligand"; // ligands or ions
56594
56841
  chain = resn;
56595
56842
  }
56596
56843
  }
56597
56844
 
56598
56845
  // C-alpha only for large structure
56599
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
56600
- || (molecueType == "n" && !(name == "P")) ) ) continue;
56846
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
56847
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
56601
56848
  // skip alternative atoms
56602
56849
  if(alt == "B") continue;
56603
56850
 
@@ -57147,6 +57394,43 @@ class OpmParser {
57147
57394
  }
57148
57395
  }
57149
57396
 
57397
+ modifyUIMapAssembly() { let ic = this.icn3d, me = ic.icn3dui;
57398
+ if(!me.bNode) {
57399
+ if(ic.emd !== undefined) {
57400
+ $("#" + ic.pre + "mapWrapper1").hide();
57401
+ $("#" + ic.pre + "mapWrapper2").hide();
57402
+ $("#" + ic.pre + "mapWrapper3").hide();
57403
+ }
57404
+ else {
57405
+ $("#" + ic.pre + "emmapWrapper1").hide();
57406
+ $("#" + ic.pre + "emmapWrapper2").hide();
57407
+ $("#" + ic.pre + "emmapWrapper3").hide();
57408
+ }
57409
+
57410
+ if(Object.keys(ic.structures).length == 1) {
57411
+ $("#" + ic.pre + "alternateWrapper").hide();
57412
+ }
57413
+ /*
57414
+ // load assembly info
57415
+ if(type === 'mmcif') {
57416
+ let assembly =(data.assembly !== undefined) ? data.assembly : [];
57417
+ for(let i = 0, il = assembly.length; i < il; ++i) {
57418
+ if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
57419
+
57420
+ for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
57421
+ ic.biomtMatrices[i].elements[j] = assembly[i][j];
57422
+ }
57423
+ }
57424
+ }
57425
+ */
57426
+ if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
57427
+ $("#" + ic.pre + "assemblyWrapper").show();
57428
+
57429
+ ic.asuCnt = ic.biomtMatrices.length;
57430
+ }
57431
+ }
57432
+ }
57433
+
57150
57434
  async parseAtomData(data, pdbid, bFull, type, pdbid2, bText) { let ic = this.icn3d, me = ic.icn3dui;
57151
57435
  /*
57152
57436
  if(type === 'mmtf') {
@@ -57163,38 +57447,7 @@ class OpmParser {
57163
57447
  ic.loadCIFCls.loadCIF(data, pdbid, bText);
57164
57448
  // }
57165
57449
 
57166
- if(ic.emd !== undefined) {
57167
- $("#" + ic.pre + "mapWrapper1").hide();
57168
- $("#" + ic.pre + "mapWrapper2").hide();
57169
- $("#" + ic.pre + "mapWrapper3").hide();
57170
- }
57171
- else {
57172
- $("#" + ic.pre + "emmapWrapper1").hide();
57173
- $("#" + ic.pre + "emmapWrapper2").hide();
57174
- $("#" + ic.pre + "emmapWrapper3").hide();
57175
- }
57176
-
57177
- if(Object.keys(ic.structures).length == 1) {
57178
- $("#" + ic.pre + "alternateWrapper").hide();
57179
- }
57180
- /*
57181
- // load assembly info
57182
- if(type === 'mmcif') {
57183
- let assembly =(data.assembly !== undefined) ? data.assembly : [];
57184
- for(let i = 0, il = assembly.length; i < il; ++i) {
57185
- if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
57186
-
57187
- for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
57188
- ic.biomtMatrices[i].elements[j] = assembly[i][j];
57189
- }
57190
- }
57191
- }
57192
- */
57193
- if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
57194
- $("#" + ic.pre + "assemblyWrapper").show();
57195
-
57196
- ic.asuCnt = ic.biomtMatrices.length;
57197
- }
57450
+ this.modifyUIMapAssembly();
57198
57451
 
57199
57452
  ic.setStyleCls.setAtomStyleByOptions(ic.opts);
57200
57453
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
@@ -57388,6 +57641,12 @@ class PdbParser {
57388
57641
  }
57389
57642
  }
57390
57643
 
57644
+ await this.addSecondary(bAppend, bNoDssp);
57645
+
57646
+ return hAtoms;
57647
+ }
57648
+
57649
+ async addSecondary(bAppend, bNoDssp) { let ic = this.icn3d, me = ic.icn3dui;
57391
57650
  // calculate secondary structures if not available
57392
57651
  // DSSP only works for structures with all atoms. The Calpha only structures didn't work
57393
57652
  //if(!ic.bSecondaryStructure && !bCalphaOnly) {
@@ -57411,8 +57670,6 @@ class PdbParser {
57411
57670
 
57412
57671
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
57413
57672
  }
57414
-
57415
- return hAtoms;
57416
57673
  }
57417
57674
 
57418
57675
  async applyCommandDssp(bAppend) { let ic = this.icn3d, me = ic.icn3dui;
@@ -58250,23 +58507,27 @@ class RealignParser {
58250
58507
 
58251
58508
  for(let s = 0, sl = structArray.length; s < sl; ++s) {
58252
58509
  let struct1 = structArray[s];
58510
+
58253
58511
  let chainidArray1 = Object.keys(struct2domain[struct1]);
58254
58512
  if(chainidArray1.length == 0) continue;
58255
- for(let t = s+1, tl = structArray.length; t < tl; ++t) {
58256
- let struct2 = structArray[t];
58257
- let chainidArray2 = Object.keys(struct2domain[struct2]);
58258
- if(chainidArray2.length == 0) continue;
58259
-
58260
- for(let i = 0, il = chainidArray1.length; i < il; ++i) {
58261
- let chainid1 = chainidArray1[i];
58262
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
58513
+
58514
+ for(let i = 0, il = chainidArray1.length; i < il; ++i) {
58515
+ let chainid1 = chainidArray1[i];
58516
+ let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
58517
+
58518
+ for(let t = s+1, tl = structArray.length; t < tl; ++t) {
58519
+ let struct2 = structArray[t];
58520
+
58521
+ let chainidArray2 = Object.keys(struct2domain[struct2]);
58522
+ if(chainidArray2.length == 0) continue;
58523
+
58263
58524
  for(let j = 0, jl = chainidArray2.length; j < jl; ++j) {
58264
58525
  let chainid2 = chainidArray2[j];
58265
58526
 
58266
58527
  let alignAjax;
58267
58528
  if(me.cfg.aligntool != 'tmalign') {
58268
58529
  let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct2][chainid2]);
58269
-
58530
+
58270
58531
  let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
58271
58532
  alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
58272
58533
  }
@@ -58291,7 +58552,14 @@ class RealignParser {
58291
58552
 
58292
58553
  let allPromise = Promise.allSettled(ajaxArray);
58293
58554
  // try {
58555
+ // let dataArray = await allPromise;
58556
+
58557
+ let startDate = new Date();
58294
58558
  let dataArray = await allPromise;
58559
+ let endDate = new Date();
58560
+ let miliseconds = (endDate.getTime() - startDate.getTime());
58561
+ console.log("vastdyn time: " + miliseconds + " miliseconds");
58562
+
58295
58563
  ic.qt_start_end = []; // reset the alignment
58296
58564
  await ic.chainalignParserCls.downloadChainalignmentPart2bRealign(dataArray, chainidPairArray, bReverse);
58297
58565
  // }
@@ -60515,6 +60783,7 @@ class LoadAtomData {
60515
60783
 
60516
60784
  //This function was used to parse atom "data" to set up parameters for the 3D viewer. "type" is mmcifid or mmdbid.
60517
60785
  //"id" is the MMDB ID or mmCIF ID.
60786
+ // thi sfunction is NOT used for mmCIF loading any more
60518
60787
  loadAtomDataIn(data, id, type, seqalign, alignType, chainidInput, chainIndex, bLastQuery, bNoSeqalign) { let ic = this.icn3d, me = ic.icn3dui;
60519
60788
  //ic.init();
60520
60789
  ic.pmin = new THREE.Vector3( 9999, 9999, 9999);
@@ -60658,13 +60927,6 @@ class LoadAtomData {
60658
60927
  if(ic.pdbid_chain2title === undefined) ic.pdbid_chain2title = {};
60659
60928
  ic.pdbid_chain2title[chainid] = data.moleculeInfor[molid].name;
60660
60929
 
60661
- //if(alignType == 'query' && chain == ic.chain_q) {
60662
- // ic.alignmolid2color[0][molid] = molidCnt.toString();
60663
- //}
60664
- //else if(alignType == 'target' && chain == ic.chain_t) {
60665
- // ic.alignmolid2color[1][molid] = molidCnt.toString();
60666
- //}
60667
-
60668
60930
  if(chain == chainid.substr(chainid.lastIndexOf('_')) ) {
60669
60931
  let tmpHash = {};
60670
60932
  tmpHash[molid] = molidCnt.toString();
@@ -60856,17 +61118,15 @@ class LoadAtomData {
60856
61118
  ic.pmin.min(atm.coord);
60857
61119
  ic.pmax.max(atm.coord);
60858
61120
  ic.psum.add(atm.coord);
60859
-
60860
- let bNonMmcif = (me.cfg.mmcifid === undefined && me.cfg.mmtfid === undefined && me.cfg.bcifid === undefined && ic.InputfileType != 'mmcif');
60861
- let bProtein = (bNonMmcif) ? chainid2kind[chainNum] === 'protein' : atm.mt === 'p';
60862
- let bNucleotide = (bNonMmcif) ? chainid2kind[chainNum] === 'nucleotide' : atm.mt === 'n';
60863
- let bSolvent = (bNonMmcif) ? chainid2kind[chainNum] === 'solvent' : atm.mt === 's';
61121
+ let bProtein = chainid2kind[chainNum] === 'protein' ;
61122
+ let bNucleotide = chainid2kind[chainNum] === 'nucleotide' ;
61123
+ let bSolvent = chainid2kind[chainNum] === 'solvent' ;
60864
61124
  // in vastplus.cgi, ions arenotlisted in alignedStructures...molecules, thus chainid2kind[chainNum] === undefined is used.
60865
61125
  // ions will be separated from chemicals later.
60866
61126
  // here "ligand" is used in the cgi output
60867
61127
  //var bChemicalIons =(me.cfg.mmcifid === undefined) ?(chainid2kind[chainNum] === 'ligand' || chainid2kind[chainNum] === 'otherPolymer' || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
60868
61128
  // kind: other, otherPolymer, etc
60869
- let bChemicalIons = (bNonMmcif) ? (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
61129
+ let bChemicalIons = (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) ;
60870
61130
 
60871
61131
  if((atm.chain === 'Misc' || chainid2kind[chainNum] === 'other') && biopolymerChainsHash[chainNum] !== 'protein' && biopolymerChainsHash[chainNum] !== 'nucleotide') { // biopolymer, could be protein or nucleotide
60872
61132
  if(atm.name === 'CA' && atm.elem === 'C') {
@@ -61130,18 +61390,17 @@ class LoadAtomData {
61130
61390
 
61131
61391
  // update bonds info
61132
61392
  if(type !== 'mmcifid') {
61133
- //for(let i in ic.atoms) {
61134
- for(let i in atoms) {
61135
- let currSerial = atomid2serial[i];
61393
+ //for(let i in ic.atoms) {
61394
+ for(let i in atoms) {
61395
+ let currSerial = atomid2serial[i];
61136
61396
 
61137
- let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
61397
+ let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
61138
61398
 
61139
- for(let j = 0; j < bondLength; ++j) {
61140
- ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
61399
+ for(let j = 0; j < bondLength; ++j) {
61400
+ ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
61401
+ }
61141
61402
  }
61142
61403
  }
61143
- }
61144
-
61145
61404
  // remove the reference
61146
61405
  data.atoms = {};
61147
61406
 
@@ -61237,7 +61496,7 @@ class LoadAtomData {
61237
61496
  // display the structure right away. load the mns and sequences later
61238
61497
  // setTimeout(function(){
61239
61498
  let hAtoms = {};
61240
-
61499
+
61241
61500
  if(type === 'align' && seqalign !== undefined && ic.bFullUi) {
61242
61501
  ic.setSeqAlignCls.setSeqAlign(seqalign, data.alignedStructures);
61243
61502
  } // if(align
@@ -61260,7 +61519,7 @@ class LoadAtomData {
61260
61519
  hAtoms = ic.hAtoms;
61261
61520
  }
61262
61521
  }
61263
- else if(type === 'mmdbid' && alignType === 'target') {
61522
+ else { //if(type === 'mmdbid' && alignType === 'target') {
61264
61523
  hAtoms = ic.hAtoms;
61265
61524
  }
61266
61525
 
@@ -61594,13 +61853,19 @@ class SetSeqAlign {
61594
61853
  resi = pos;
61595
61854
  }
61596
61855
  else {
61597
- if(ic.posid2resid) {
61598
- let resid = ic.posid2resid[chainid + '_' + pos];
61599
- resi = resid.substr(resid.lastIndexOf('_') + 1);
61600
- }
61601
- else {
61856
+ // if(ic.posid2resid) {
61857
+ // let resid = ic.posid2resid[chainid + '_' + pos];
61858
+ // resi = resid.substr(resid.lastIndexOf('_') + 1);
61859
+ // }
61860
+ // else {
61861
+ // resi = (ic.chainsSeq[chainid][pos].resi) ? ic.chainsSeq[chainid][pos].resi : pos;
61862
+ if(pos > ic.chainsSeq[chainid].length - 1) {
61863
+ console.log("Error: the position " + pos + " exceeds the max index " + (ic.chainsSeq[chainid].length - 1));
61864
+ pos = ic.chainsSeq[chainid].length - 1;
61865
+ }
61866
+
61602
61867
  resi = ic.chainsSeq[chainid][pos].resi;
61603
- }
61868
+ // }
61604
61869
  }
61605
61870
 
61606
61871
  return resi;
@@ -63685,17 +63950,6 @@ class LoadCIF {
63685
63950
  loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
63686
63951
  let hAtoms = {};
63687
63952
 
63688
- // bcifData could be binary or text
63689
- let parsed = (bText) ? CIFTools.Text.parse(bcifData) : CIFTools.Binary.parse(bcifData);
63690
-
63691
- if (parsed.isError) {
63692
- // report error:
63693
- alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
63694
- return;
63695
- }
63696
-
63697
- let block = parsed.result.dataBlocks[0];
63698
-
63699
63953
  let bNMR = false;
63700
63954
  // let lines = src.split('\n');
63701
63955
 
@@ -63731,92 +63985,152 @@ class LoadCIF {
63731
63985
 
63732
63986
  let bFirstAtom = true;
63733
63987
 
63734
- if(block.getCategory("_entry")) {
63735
- id = block.getCategory("_entry").getColumn("id").getString(0);
63988
+ let cifArray = bcifData.split('ENDMDL\n');
63736
63989
 
63737
- if(id == '') {
63738
- if(bAppend) {
63739
- id = ic.defaultPdbId;
63740
- }
63741
- else {
63742
- //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
63743
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
63744
- }
63745
- }
63990
+ for(let index = 0, indexl = cifArray.length; index < indexl; ++index) {
63991
+ ++moleculeNum;
63992
+ id = ic.defaultPdbId;
63746
63993
 
63747
63994
  structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63748
63995
 
63749
- ic.molTitle = '';
63750
- ic.molTitleHash = {};
63751
- }
63752
-
63753
- if(block.getCategory("_struct")) {
63754
- let title = block.getCategory("_struct").getColumn("title").getString(0);
63755
- title = title.replace(/"/, "'");
63756
- let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
63757
- ic.molTitle += name.trim() + " ";
63758
- // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63996
+ // if(!bNMR) {
63997
+ sheetArray = [];
63998
+ sheetStart = [];
63999
+ sheetEnd = [];
64000
+ helixArray = [];
64001
+ helixStart = [];
64002
+ helixEnd = [];
63759
64003
 
63760
- if(!ic.molTitleHash) ic.molTitleHash = {};
63761
- ic.molTitleHash[structure] = ic.molTitle;
63762
64004
 
63763
- }
64005
+ // bcifData could be binary or text
64006
+ let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
63764
64007
 
63765
- if(block.getCategory("_entity_src_gen")) {
63766
- ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
63767
- }
63768
-
63769
- if(block.getCategory("_database_2")) {
63770
- let database_2 = block.getCategory("_database_2");
63771
-
63772
- // Iterate through every row in the table
63773
- let db2Size = database_2.rowCount ;
63774
- for (let i = 0; i < db2Size; ++i) {
63775
- let db_id = database_2.getColumn("database_id").getString(0);
63776
- let db_code = database_2.getColumn("database_code").getString(0);
64008
+ if (parsed.isError) {
64009
+ // report error:
64010
+ alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
64011
+ return;
64012
+ }
64013
+
64014
+ let block = parsed.result.dataBlocks[0];
63777
64015
 
63778
- if(db_id == "EMDB") {
63779
- ic.emd = db_code;
63780
- break;
64016
+ if(block.getCategory("_entry")) {
64017
+ id = block.getCategory("_entry").getColumn("id").getString(0);
64018
+
64019
+ if(id == '') {
64020
+ if(bAppend) {
64021
+ id = ic.defaultPdbId;
64022
+ }
64023
+ else {
64024
+ //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
64025
+ id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
64026
+ }
63781
64027
  }
64028
+
64029
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64030
+
64031
+ ic.molTitle = '';
64032
+ ic.molTitleHash = {};
63782
64033
  }
63783
- }
64034
+
64035
+ if(block.getCategory("_struct")) {
64036
+ let title = block.getCategory("_struct").getColumn("title").getString(0);
64037
+ title = title.replace(/"/, "'");
64038
+ let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
64039
+ ic.molTitle += name.trim() + " ";
64040
+ // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63784
64041
 
63785
- if(block.getCategory("_struct_conf")) {
63786
- ic.bSecondaryStructure = true;
64042
+ if(!ic.molTitleHash) ic.molTitleHash = {};
64043
+ ic.molTitleHash[structure] = ic.molTitle;
63787
64044
 
63788
- // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
63789
- let struct_conf = block.getCategory("_struct_conf");
63790
-
63791
- let conf_type_idArray = struct_conf.getColumn("conf_type_id");
63792
-
63793
- let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
63794
- // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
63795
- let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
63796
-
63797
- struct_conf.getColumn("end_auth_asym_id");
63798
- // let resi2Array = struct_conf.getColumn("end_label_seq_id");
63799
- let resi2Array = struct_conf.getColumn("end_auth_seq_id");
63800
-
63801
- // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
63802
- let confSize = struct_conf.rowCount;
63803
- for (let i = 0; i < confSize; ++i) {
63804
- let conf_type_id = conf_type_idArray.getString(i);
64045
+ }
64046
+
64047
+ if(block.getCategory("_entity_src_gen")) {
64048
+ ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
64049
+ }
63805
64050
 
63806
- let startChain = chain1Array.getString(i);
63807
- let startResi = parseInt(resi1Array.getString(i));
63808
- let endResi = parseInt(resi2Array.getString(i));
64051
+ if(block.getCategory("_database_2")) {
64052
+ let database_2 = block.getCategory("_database_2");
63809
64053
 
63810
- if(conf_type_id.substr(0, 4) == "HELX") {
63811
- for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
63812
- let resid = structure + "_" + startChain + "_" + j;
63813
- helixArray.push(resid);
63814
-
63815
- if(j == startResi) helixStart.push(resid);
63816
- if(j == endResi) helixEnd.push(resid);
63817
- }
64054
+ // Iterate through every row in the table
64055
+ let db2Size = database_2.rowCount ;
64056
+ for (let i = 0; i < db2Size; ++i) {
64057
+ let db_id = database_2.getColumn("database_id").getString(0);
64058
+ let db_code = database_2.getColumn("database_code").getString(0);
64059
+
64060
+ if(db_id == "EMDB") {
64061
+ ic.emd = db_code;
64062
+ break;
64063
+ }
63818
64064
  }
63819
- else if(conf_type_id.substr(0, 4) == "STRN") {
64065
+ }
64066
+
64067
+ if(block.getCategory("_struct_conf")) {
64068
+ ic.bSecondaryStructure = true;
64069
+
64070
+ // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
64071
+ let struct_conf = block.getCategory("_struct_conf");
64072
+
64073
+ let conf_type_idArray = struct_conf.getColumn("conf_type_id");
64074
+
64075
+ let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
64076
+ // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
64077
+ let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
64078
+
64079
+ struct_conf.getColumn("end_auth_asym_id");
64080
+ // let resi2Array = struct_conf.getColumn("end_label_seq_id");
64081
+ let resi2Array = struct_conf.getColumn("end_auth_seq_id");
64082
+
64083
+ // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
64084
+ let confSize = struct_conf.rowCount;
64085
+ for (let i = 0; i < confSize; ++i) {
64086
+ let conf_type_id = conf_type_idArray.getString(i);
64087
+
64088
+ let startChain = chain1Array.getString(i);
64089
+ let startResi = parseInt(resi1Array.getString(i));
64090
+ let endResi = parseInt(resi2Array.getString(i));
64091
+
64092
+ if(conf_type_id.substr(0, 4) == "HELX") {
64093
+ for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
64094
+ let resid = structure + "_" + startChain + "_" + j;
64095
+ helixArray.push(resid);
64096
+
64097
+ if(j == startResi) helixStart.push(resid);
64098
+ if(j == endResi) helixEnd.push(resid);
64099
+ }
64100
+ }
64101
+ else if(conf_type_id.substr(0, 4) == "STRN") {
64102
+ for(let j = startResi; j <= endResi; ++j) {
64103
+ let resid = structure + "_" + startChain + "_" + j;
64104
+ sheetArray.push(resid);
64105
+
64106
+ if(j == startResi) sheetStart.push(resid);
64107
+ if(j == endResi) sheetEnd.push(resid);
64108
+ }
64109
+ }
64110
+ }
64111
+
64112
+ conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
64113
+ }
64114
+
64115
+ if(block.getCategory("_struct_sheet_range")) {
64116
+ // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
64117
+ let struct_sheet_range = block.getCategory("_struct_sheet_range");
64118
+
64119
+ let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
64120
+ // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
64121
+ let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
64122
+
64123
+ struct_sheet_range.getColumn("end_auth_asym_id");
64124
+ // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
64125
+ let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
64126
+
64127
+ // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
64128
+ let sheetSize = struct_sheet_range.rowCount;
64129
+ for (let i = 0; i < sheetSize; ++i) {
64130
+ let startChain = chain1Array.getString(i);
64131
+ let startResi = parseInt(resi1Array.getString(i));
64132
+ let endResi = parseInt(resi2Array.getString(i));
64133
+
63820
64134
  for(let j = startResi; j <= endResi; ++j) {
63821
64135
  let resid = structure + "_" + startChain + "_" + j;
63822
64136
  sheetArray.push(resid);
@@ -63825,500 +64139,469 @@ class LoadCIF {
63825
64139
  if(j == endResi) sheetEnd.push(resid);
63826
64140
  }
63827
64141
  }
64142
+
64143
+ chain1Array = resi1Array = resi2Array = [];
63828
64144
  }
63829
-
63830
- conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
63831
- }
63832
-
63833
- if(block.getCategory("_struct_sheet_range")) {
63834
- // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
63835
- let struct_sheet_range = block.getCategory("_struct_sheet_range");
63836
-
63837
- let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
63838
- // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
63839
- let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
63840
-
63841
- struct_sheet_range.getColumn("end_auth_asym_id");
63842
- // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
63843
- let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
63844
-
63845
- // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
63846
- let sheetSize = struct_sheet_range.rowCount;
63847
- for (let i = 0; i < sheetSize; ++i) {
63848
- let startChain = chain1Array.getString(i);
63849
- let startResi = parseInt(resi1Array.getString(i));
63850
- let endResi = parseInt(resi2Array.getString(i));
63851
-
63852
- for(let j = startResi; j <= endResi; ++j) {
63853
- let resid = structure + "_" + startChain + "_" + j;
63854
- sheetArray.push(resid);
63855
-
63856
- if(j == startResi) sheetStart.push(resid);
63857
- if(j == endResi) sheetEnd.push(resid);
63858
- }
63859
- }
63860
-
63861
- chain1Array = resi1Array = resi2Array = [];
63862
- }
63863
64145
 
63864
- if(block.getCategory("_struct_conn")) {
63865
- ic.bSsbondProvided = true;
64146
+ if(block.getCategory("_struct_conn")) {
64147
+ ic.bSsbondProvided = true;
63866
64148
 
63867
- // Retrieve the table corresponding to the struct_conn category, which delineates connections1
63868
- let struct_conn = block.getCategory("_struct_conn");
63869
-
63870
- let conn_type_idArray = struct_conn.getColumn("conn_type_id");
63871
-
63872
- let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
63873
- let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
63874
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
63875
-
63876
- let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
63877
- let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
63878
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
63879
-
63880
- let connSize = struct_conn.rowCount;
63881
- for (let i = 0; i < connSize; ++i) {
63882
- let conn_type_id = conn_type_idArray.getString(i);
64149
+ // Retrieve the table corresponding to the struct_conn category, which delineates connections1
64150
+ let struct_conn = block.getCategory("_struct_conn");
63883
64151
 
63884
- let chain1 = chain1Array.getString(i);
63885
- name1Array.getString(i);
63886
- let resi1 = resi1Array.getString(i);
63887
- let id1 = structure + '_' + chain1 + "_" + resi1;
64152
+ let conn_type_idArray = struct_conn.getColumn("conn_type_id");
63888
64153
 
63889
- let chain2 = chain2Array.getString(i);
63890
- name2Array.getString(i);
63891
- let resi2 = resi2Array.getString(i);
63892
- let id2 = structure + '_' + chain2 + "_" + resi2;
64154
+ let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
64155
+ let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
64156
+ let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
63893
64157
 
63894
- // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
64158
+ let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
64159
+ let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
64160
+ let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
63895
64161
 
63896
- // if (conn_type_id == "covale") {
63897
- // vBonds.push(id1);
63898
- // vBonds.push(id2);
63899
- // }
64162
+ let connSize = struct_conn.rowCount;
64163
+ for (let i = 0; i < connSize; ++i) {
64164
+ let conn_type_id = conn_type_idArray.getString(i);
63900
64165
 
63901
- if(conn_type_id == "disulf") {
63902
- if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
64166
+ let chain1 = chain1Array.getString(i);
64167
+ name1Array.getString(i);
64168
+ let resi1 = resi1Array.getString(i);
64169
+ let id1 = structure + '_' + chain1 + "_" + resi1;
64170
+
64171
+ let chain2 = chain2Array.getString(i);
64172
+ name2Array.getString(i);
64173
+ let resi2 = resi2Array.getString(i);
64174
+ let id2 = structure + '_' + chain2 + "_" + resi2;
64175
+
64176
+ // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
64177
+
64178
+ // if (conn_type_id == "covale") {
64179
+ // vBonds.push(id1);
64180
+ // vBonds.push(id2);
64181
+ // }
64182
+
64183
+ if(conn_type_id == "disulf") {
64184
+ if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
63903
64185
 
63904
- ic.ssbondpnts[structure].push(id1);
63905
- ic.ssbondpnts[structure].push(id2);
64186
+ ic.ssbondpnts[structure].push(id1);
64187
+ ic.ssbondpnts[structure].push(id2);
64188
+ }
63906
64189
  }
64190
+
64191
+ conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63907
64192
  }
63908
-
63909
- conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63910
- }
63911
64193
 
63912
- if(block.getCategory("_exptl")) {
63913
- let method = block.getCategory("_exptl").getColumn("method").getString(0);
63914
- if(method.indexOf('NMR') != -1) {
63915
- bNMR = true;
64194
+ if(block.getCategory("_exptl")) {
64195
+ let method = block.getCategory("_exptl").getColumn("method").getString(0);
64196
+ if(method.indexOf('NMR') != -1) {
64197
+ bNMR = true;
64198
+ }
63916
64199
  }
63917
- }
63918
64200
 
63919
- if(block.getCategory("_pdbx_struct_oper_list")) {
63920
- // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
63921
- let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
63922
-
63923
- let struct_oper_idArray = struct_oper_list.getColumn("id");
63924
- let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63925
- let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63926
- let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63927
- let m14Array = struct_oper_list.getColumn("vector[1]");
63928
-
63929
- let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63930
- let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63931
- let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63932
- let m24Array = struct_oper_list.getColumn("vector[2]");
63933
-
63934
- let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63935
- let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63936
- let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63937
- let m34Array = struct_oper_list.getColumn("vector[3]");
63938
-
63939
- let assemblySize = struct_oper_list.rowCount;
63940
- for (let i = 0; i < assemblySize; ++i) {
63941
- let struct_oper_id = struct_oper_idArray.getString(i);
63942
- if(struct_oper_id == "X0") continue;
64201
+ if(block.getCategory("_pdbx_struct_oper_list")) {
64202
+ // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
64203
+ let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
64204
+
64205
+ let struct_oper_idArray = struct_oper_list.getColumn("id");
64206
+ let m11Array = struct_oper_list.getColumn("matrix[1][1]");
64207
+ let m12Array = struct_oper_list.getColumn("matrix[1][2]");
64208
+ let m13Array = struct_oper_list.getColumn("matrix[1][3]");
64209
+ let m14Array = struct_oper_list.getColumn("vector[1]");
64210
+
64211
+ let m21Array = struct_oper_list.getColumn("matrix[2][1]");
64212
+ let m22Array = struct_oper_list.getColumn("matrix[2][2]");
64213
+ let m23Array = struct_oper_list.getColumn("matrix[2][3]");
64214
+ let m24Array = struct_oper_list.getColumn("vector[2]");
64215
+
64216
+ let m31Array = struct_oper_list.getColumn("matrix[3][1]");
64217
+ let m32Array = struct_oper_list.getColumn("matrix[3][2]");
64218
+ let m33Array = struct_oper_list.getColumn("matrix[3][3]");
64219
+ let m34Array = struct_oper_list.getColumn("vector[3]");
64220
+
64221
+ let assemblySize = struct_oper_list.rowCount;
64222
+ for (let i = 0; i < assemblySize; ++i) {
64223
+ let struct_oper_id = struct_oper_idArray.getString(i);
64224
+ if(struct_oper_id == "X0") continue;
63943
64225
 
63944
- if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63945
- ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63946
- m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63947
- m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63948
- 0, 0, 0, 1);
64226
+ if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
64227
+ ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
64228
+ m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
64229
+ m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
64230
+ 0, 0, 0, 1);
64231
+ }
64232
+
64233
+ struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
64234
+ = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63949
64235
  }
63950
-
63951
- struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63952
- = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63953
- }
63954
64236
 
63955
- // if (record === 'ENDMDL') {
63956
- // ++moleculeNum;
63957
- // id = ic.defaultPdbId;
64237
+ // if (record === 'ENDMDL') {
64238
+ // ++moleculeNum;
64239
+ // id = ic.defaultPdbId;
63958
64240
 
63959
- // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64241
+ // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63960
64242
 
63961
- // //helices = [];
63962
- // //sheets = [];
63963
- // if(!bNMR) {
63964
- // sheetArray = [];
63965
- // sheetStart = [];
63966
- // sheetEnd = [];
63967
- // helixArray = [];
63968
- // helixStart = [];
63969
- // helixEnd = [];
63970
- // }
64243
+ // //helices = [];
64244
+ // //sheets = [];
64245
+ // if(!bNMR) {
64246
+ // sheetArray = [];
64247
+ // sheetStart = [];
64248
+ // sheetEnd = [];
64249
+ // helixArray = [];
64250
+ // helixStart = [];
64251
+ // helixEnd = [];
64252
+ // }
63971
64253
 
63972
- // bHeader = false; // reinitialize to read structure name from the header
63973
- // }
64254
+ // bHeader = false; // reinitialize to read structure name from the header
64255
+ // }
63974
64256
 
63975
- if(block.getCategory("_citation")) {
63976
- ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63977
- }
64257
+ if(block.getCategory("_citation")) {
64258
+ ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
64259
+ }
63978
64260
 
63979
- // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63980
- let atom_site = block.getCategory("_atom_site");
63981
- let atomSize = atom_site.rowCount;
63982
- // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63983
- let bFull = (atomSize > ic.maxatomcnt) ? false : true;
64261
+ // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
64262
+ let atom_site = block.getCategory("_atom_site");
64263
+ let atomSize = atom_site.rowCount;
64264
+ // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
64265
+ let bFull = (atomSize > ic.maxatomcnt) ? false : true;
63984
64266
 
63985
- if(!bFull) {
63986
- ic.opts['proteins'] = 'c alpha trace'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, b factor tube, lines, stick, ball and stick, sphere, nothing
63987
- ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63988
- }
64267
+ if(!bFull) {
64268
+ ic.opts['proteins'] = 'c alpha trace'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, b factor tube, lines, stick, ball and stick, sphere, nothing
64269
+ ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
64270
+ }
63989
64271
 
63990
- let atom_hetatmArray = atom_site.getColumn("group_PDB");
63991
- let resnArray = atom_site.getColumn("label_comp_id");
63992
- let elemArray = atom_site.getColumn("type_symbol");
63993
- let nameArray = atom_site.getColumn("label_atom_id");
64272
+ let atom_hetatmArray = atom_site.getColumn("group_PDB");
64273
+ let resnArray = atom_site.getColumn("label_comp_id");
64274
+ let elemArray = atom_site.getColumn("type_symbol");
64275
+ let nameArray = atom_site.getColumn("label_atom_id");
63994
64276
 
63995
- let chainArray = atom_site.getColumn("auth_asym_id");
64277
+ let chainArray = atom_site.getColumn("auth_asym_id");
63996
64278
 
63997
- let resiArray = atom_site.getColumn("label_seq_id");
63998
- let resiOriArray = atom_site.getColumn("auth_seq_id");
63999
- let altArray = atom_site.getColumn("label_alt_id");
64279
+ let resiArray = atom_site.getColumn("label_seq_id");
64280
+ let resiOriArray = atom_site.getColumn("auth_seq_id");
64281
+ let altArray = atom_site.getColumn("label_alt_id");
64000
64282
 
64001
- let bArray = atom_site.getColumn("B_iso_or_equiv");
64283
+ let bArray = atom_site.getColumn("B_iso_or_equiv");
64002
64284
 
64003
- let xArray = atom_site.getColumn("Cartn_x");
64004
- let yArray = atom_site.getColumn("Cartn_y");
64005
- let zArray = atom_site.getColumn("Cartn_z");
64285
+ let xArray = atom_site.getColumn("Cartn_x");
64286
+ let yArray = atom_site.getColumn("Cartn_y");
64287
+ let zArray = atom_site.getColumn("Cartn_z");
64006
64288
 
64007
- let autochainArray = atom_site.getColumn("label_asym_id");
64289
+ let autochainArray = atom_site.getColumn("label_asym_id");
64008
64290
 
64009
- // get the bond info
64010
- let ligSeqHash = {}, prevAutochain = '';
64011
- let prevResn;
64012
- let sChain = {};
64013
- for (let i = 0; i < atomSize; ++i) {
64014
- let atom_hetatm = atom_hetatmArray.getString(i);
64015
- let resn = resnArray.getString(i);
64016
- let elem = elemArray.getString(i);
64017
- let atom = nameArray.getString(i);
64018
- let chain = chainArray.getString(i);
64019
- let resi = resiArray.getString(i);
64020
- let oriResi = resiOriArray.getString(i);
64021
- let alt = altArray.getString(i);
64022
- let bFactor = bArray.getString(i);
64291
+ // get the bond info
64292
+ let ligSeqHash = {}, prevAutochain = '';
64293
+ let prevResn;
64294
+ let sChain = {};
64295
+ for (let i = 0; i < atomSize; ++i) {
64296
+ let atom_hetatm = atom_hetatmArray.getString(i);
64297
+ let resn = resnArray.getString(i);
64298
+ let elem = elemArray.getString(i);
64299
+ let atom = nameArray.getString(i);
64300
+ let chain = chainArray.getString(i);
64301
+ let resi = resiArray.getString(i);
64302
+ let oriResi = resiOriArray.getString(i);
64303
+ let alt = altArray.getString(i);
64304
+ let bFactor = bArray.getString(i);
64023
64305
 
64024
- let autochain = autochainArray.getString(i);
64306
+ let autochain = autochainArray.getString(i);
64025
64307
 
64026
64308
 
64027
- resi = oriResi;
64309
+ resi = oriResi;
64028
64310
 
64029
- let molecueType;
64030
- if(atom_hetatm == "ATOM") {
64031
- if(resn.length == 3) {
64032
- molecueType = "p"; // protein
64033
- }
64034
- else {
64035
- molecueType = "n"; // nucleotide
64036
- }
64037
- }
64038
- else {
64039
- if(resn == "WAT" || resn == "HOH") {
64040
- molecueType = "s"; // solvent
64041
- chain = 'Misc';
64311
+ let molecueType;
64312
+ if(atom_hetatm == "ATOM") {
64313
+ if(resn.length == 3) {
64314
+ molecueType = "protein"; // protein
64315
+ }
64316
+ else {
64317
+ molecueType = "nucleotide"; // nucleotide
64318
+ }
64042
64319
  }
64043
64320
  else {
64044
- molecueType = "l"; // ligands or ions
64045
- chain = resn;
64321
+ if(resn == "WAT" || resn == "HOH") {
64322
+ molecueType = "solvent"; // solvent
64323
+ chain = 'Misc';
64324
+ }
64325
+ else {
64326
+ molecueType = "ligand"; // ligands or ions
64327
+ chain = resn;
64328
+ }
64046
64329
  }
64047
- }
64048
- if(chain === '') chain = 'A';
64049
-
64050
- // C-alpha only for large structure
64051
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && atom == 'CA')) || (molecueType == "n" && !(atom == "P")) ) ) continue;
64052
-
64053
- // skip alternative atoms
64054
- if(alt == "B") continue;
64055
-
64056
- sChain[chain] = 1;
64330
+ if(chain === '') chain = 'A';
64057
64331
 
64058
- if(bFirstAtom) {
64059
- structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64332
+ // C-alpha only for large structure
64333
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && atom == 'CA')) || (molecueType == "nucleotide" && !(atom == "P")) ) ) continue;
64334
+
64335
+ // skip alternative atoms
64336
+ if(alt == "B") continue;
64060
64337
 
64061
- bFirstAtom = false;
64062
- }
64338
+ sChain[chain] = 1;
64063
64339
 
64064
- // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
64065
- // Concatenation of two pdbs will have several atoms for the same serial
64066
- ++serial;
64340
+ if(bFirstAtom) {
64341
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64067
64342
 
64068
- // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
64069
- // bModifyResi = true;
64070
- // }
64343
+ bFirstAtom = false;
64344
+ }
64071
64345
 
64072
- if(resi == "?" || resi == "." || resi == "0") {
64073
- resi = oriResi;
64346
+ // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
64347
+ // Concatenation of two pdbs will have several atoms for the same serial
64348
+ ++serial;
64074
64349
 
64075
- // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64076
- // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64077
- // resi = (++tmpResi).toString();
64078
- // }
64079
- // }
64080
- // else {
64081
- // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64082
- // resi = (++tmpResi).toString();
64083
- // }
64084
- // else {
64085
- // resi = (tmpResi).toString();
64086
- // }
64350
+ // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
64351
+ // bModifyResi = true;
64087
64352
  // }
64088
- }
64089
64353
 
64090
- if(molecueType == 's' || molecueType == "l") {
64091
- let seq = {};
64092
- if(!ligSeqHash.hasOwnProperty(chain)) {
64093
- ligSeqHash[chain] = [];
64354
+ if(resi == "?" || resi == "." || resi == "0") {
64355
+ resi = oriResi;
64356
+
64357
+ // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64358
+ // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64359
+ // resi = (++tmpResi).toString();
64360
+ // }
64361
+ // }
64362
+ // else {
64363
+ // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64364
+ // resi = (++tmpResi).toString();
64365
+ // }
64366
+ // else {
64367
+ // resi = (tmpResi).toString();
64368
+ // }
64369
+ // }
64094
64370
  }
64095
64371
 
64096
- if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64097
- if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64098
- seq.resi = resi;
64099
- seq.name = me.utilsCls.residueName2Abbr(resn);
64100
- ligSeqHash[chain].push(seq);
64372
+ if(molecueType == 'solvent' || molecueType == "ligand") {
64373
+ let seq = {};
64374
+ if(!ligSeqHash.hasOwnProperty(chain)) {
64375
+ ligSeqHash[chain] = [];
64101
64376
  }
64102
- }
64103
- else {
64104
- if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64105
- seq.resi = resi;
64106
- seq.name = me.utilsCls.residueName2Abbr(resn);
64107
- ligSeqHash[chain].push(seq);
64377
+
64378
+ if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64379
+ if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64380
+ seq.resi = resi;
64381
+ seq.name = me.utilsCls.residueName2Abbr(resn);
64382
+ ligSeqHash[chain].push(seq);
64383
+ }
64384
+ }
64385
+ else {
64386
+ if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64387
+ seq.resi = resi;
64388
+ seq.name = me.utilsCls.residueName2Abbr(resn);
64389
+ ligSeqHash[chain].push(seq);
64390
+ }
64108
64391
  }
64109
64392
  }
64110
- }
64111
64393
 
64112
- // if(bOpm && resn === 'DUM') {
64113
- // elem = atom;
64114
- // chain = 'MEM';
64115
- // resi = 1;
64116
- // oriResi = 1;
64117
- // }
64394
+ // if(bOpm && resn === 'DUM') {
64395
+ // elem = atom;
64396
+ // chain = 'MEM';
64397
+ // resi = 1;
64398
+ // oriResi = 1;
64399
+ // }
64118
64400
 
64119
- // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
64401
+ // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
64120
64402
 
64121
- chainNum = structure + "_" + chain;
64122
- oriResidueNum = chainNum + "_" + oriResi;
64403
+ chainNum = structure + "_" + chain;
64404
+ oriResidueNum = chainNum + "_" + oriResi;
64123
64405
 
64124
- residueNum = chainNum + "_" + resi;
64406
+ residueNum = chainNum + "_" + resi;
64125
64407
 
64126
- //let chain_resi = chain + "_" + resi;
64408
+ //let chain_resi = chain + "_" + resi;
64127
64409
 
64128
- let x = xArray.getFloat(i);
64129
- let y = yArray.getFloat(i);
64130
- let z = zArray.getFloat(i);
64131
- let coord = new THREE.Vector3(x, y, z);
64410
+ let x = xArray.getFloat(i);
64411
+ let y = yArray.getFloat(i);
64412
+ let z = zArray.getFloat(i);
64413
+ let coord = new THREE.Vector3(x, y, z);
64132
64414
 
64133
- let atomDetails = {
64134
- het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
64135
- serial: serial, // required, unique atom id
64136
- name: atom, // required, atom name
64137
- alt: alt, // optional, some alternative coordinates
64138
- resn: resn, // optional, used to determine protein or nucleotide
64139
- structure: structure, // optional, used to identify structure
64140
- chain: chain, // optional, used to identify chain
64141
- resi: resi, // optional, used to identify residue ID
64142
- //insc: line.substr(26, 1),
64143
- coord: coord, // required, used to draw 3D shape
64144
- b: bFactor, // optional, used to draw B-factor tube
64145
- elem: elem, // optional, used to determine hydrogen bond
64146
- bonds: [], // required, used to connect atoms
64147
- ss: 'coil', // optional, used to show secondary structures
64148
- ssbegin: false, // optional, used to show the beginning of secondary structures
64149
- ssend: false // optional, used to show the end of secondary structures
64150
- };
64415
+ let atomDetails = {
64416
+ het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
64417
+ serial: serial, // required, unique atom id
64418
+ name: atom, // required, atom name
64419
+ alt: alt, // optional, some alternative coordinates
64420
+ resn: resn, // optional, used to determine protein or nucleotide
64421
+ structure: structure, // optional, used to identify structure
64422
+ chain: chain, // optional, used to identify chain
64423
+ resi: resi, // optional, used to identify residue ID
64424
+ //insc: line.substr(26, 1),
64425
+ coord: coord, // required, used to draw 3D shape
64426
+ b: bFactor, // optional, used to draw B-factor tube
64427
+ elem: elem, // optional, used to determine hydrogen bond
64428
+ bonds: [], // required, used to connect atoms
64429
+ ss: 'coil', // optional, used to show secondary structures
64430
+ ssbegin: false, // optional, used to show the beginning of secondary structures
64431
+ ssend: false // optional, used to show the end of secondary structures
64432
+ };
64151
64433
 
64152
- if(!atomDetails.het && atomDetails.name === 'C') ;
64153
- if(!atomDetails.het && atomDetails.name === 'O') ;
64434
+ if(!atomDetails.het && atomDetails.name === 'C') ;
64435
+ if(!atomDetails.het && atomDetails.name === 'O') ;
64154
64436
 
64155
- // from DSSP C++ code
64156
- // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
64157
- // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
64437
+ // from DSSP C++ code
64438
+ // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
64439
+ // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
64158
64440
 
64159
- // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
64160
- // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
64161
- // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
64441
+ // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
64442
+ // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
64443
+ // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
64162
64444
 
64163
- // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
64164
- // }
64445
+ // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
64446
+ // }
64165
64447
 
64166
- ic.atoms[serial] = atomDetails;
64448
+ ic.atoms[serial] = atomDetails;
64167
64449
 
64168
- ic.dAtoms[serial] = 1;
64169
- ic.hAtoms[serial] = 1;
64170
- hAtoms[serial] = 1;
64450
+ ic.dAtoms[serial] = 1;
64451
+ ic.hAtoms[serial] = 1;
64452
+ hAtoms[serial] = 1;
64171
64453
 
64172
- // Assign secondary structures from the input
64173
- // if a residue is assigned both sheet and helix, it is assigned as sheet
64174
- if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
64175
- ic.atoms[serial].ss = 'sheet';
64176
- if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
64177
- ic.atoms[serial].ssbegin = true;
64178
- }
64454
+ // Assign secondary structures from the input
64455
+ // if a residue is assigned both sheet and helix, it is assigned as sheet
64456
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
64457
+ ic.atoms[serial].ss = 'sheet';
64458
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
64459
+ ic.atoms[serial].ssbegin = true;
64460
+ }
64179
64461
 
64180
- // do not use else if. Some residues are both start and end of secondary structure
64181
- if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
64182
- ic.atoms[serial].ssend = true;
64462
+ // do not use else if. Some residues are both start and end of secondary structure
64463
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
64464
+ ic.atoms[serial].ssend = true;
64465
+ }
64183
64466
  }
64184
- }
64185
- else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
64186
- ic.atoms[serial].ss = 'helix';
64467
+ else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
64468
+ ic.atoms[serial].ss = 'helix';
64187
64469
 
64188
- if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
64189
- ic.atoms[serial].ssbegin = true;
64470
+ if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
64471
+ ic.atoms[serial].ssbegin = true;
64472
+ }
64473
+
64474
+ // do not use else if. Some residues are both start and end of secondary structure
64475
+ if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
64476
+ ic.atoms[serial].ssend = true;
64477
+ }
64190
64478
  }
64191
64479
 
64192
- // do not use else if. Some residues are both start and end of secondary structure
64193
- if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
64194
- ic.atoms[serial].ssend = true;
64480
+ let secondaries = '-';
64481
+ if(ic.atoms[serial].ss === 'helix') {
64482
+ secondaries = 'H';
64483
+ }
64484
+ else if(ic.atoms[serial].ss === 'sheet') {
64485
+ secondaries = 'E';
64486
+ }
64487
+ //else if(ic.atoms[serial].ss === 'coil') {
64488
+ // secondaries = 'c';
64489
+ //}
64490
+ else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
64491
+ secondaries = 'c';
64492
+ }
64493
+ else {
64494
+ secondaries = 'o';
64195
64495
  }
64196
- }
64197
64496
 
64198
- let secondaries = '-';
64199
- if(ic.atoms[serial].ss === 'helix') {
64200
- secondaries = 'H';
64201
- }
64202
- else if(ic.atoms[serial].ss === 'sheet') {
64203
- secondaries = 'E';
64204
- }
64205
- //else if(ic.atoms[serial].ss === 'coil') {
64206
- // secondaries = 'c';
64207
- //}
64208
- else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
64209
- secondaries = 'c';
64210
- }
64211
- else {
64212
- secondaries = 'o';
64213
- }
64497
+ ic.secondaries[residueNum] = secondaries;
64214
64498
 
64215
- ic.secondaries[residueNum] = secondaries;
64499
+ // different residue
64500
+ //if(residueNum !== prevResidueNum) {
64501
+
64502
+ // if(oriResidueNum !== prevOriResidueNum) {
64503
+ if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
64504
+ let residue = me.utilsCls.residueName2Abbr(resn);
64505
+
64506
+ ic.residueId2Name[residueNum] = residue;
64216
64507
 
64217
- // different residue
64218
- //if(residueNum !== prevResidueNum) {
64219
-
64220
- // if(oriResidueNum !== prevOriResidueNum) {
64221
- if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
64222
- let residue = me.utilsCls.residueName2Abbr(resn);
64223
-
64224
- ic.residueId2Name[residueNum] = residue;
64508
+ if(serial !== 1 && prevResidueNum !== '') {
64509
+ ic.residues[prevResidueNum] = residuesTmp;
64510
+ }
64225
64511
 
64226
- if(serial !== 1 && prevResidueNum !== '') {
64227
- ic.residues[prevResidueNum] = residuesTmp;
64228
- }
64512
+ if(residueNum !== prevResidueNum) {
64513
+ residuesTmp = {};
64514
+ }
64229
64515
 
64230
- if(residueNum !== prevResidueNum) {
64231
- residuesTmp = {};
64232
- }
64516
+ // different chain
64517
+ if(chainNum !== prevChainNum) {
64233
64518
 
64234
- // different chain
64235
- if(chainNum !== prevChainNum) {
64519
+ // a chain could be separated in two sections
64520
+ if(serial !== 1 && prevChainNum !== '') {
64521
+ if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
64522
+ ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
64523
+ }
64236
64524
 
64237
- // a chain could be separated in two sections
64238
- if(serial !== 1 && prevChainNum !== '') {
64239
- if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
64240
- ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
64241
- }
64525
+ chainsTmp = {};
64242
64526
 
64243
- chainsTmp = {};
64527
+ if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
64528
+ if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
64244
64529
 
64245
- if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
64246
- if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
64530
+ if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
64247
64531
 
64248
- if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
64532
+ let resObject = {};
64533
+ resObject.resi = resi;
64534
+ resObject.name = residue;
64249
64535
 
64250
- let resObject = {};
64251
- resObject.resi = resi;
64252
- resObject.name = residue;
64536
+ ic.chainsSeq[chainNum].push(resObject);
64537
+ }
64538
+ else {
64539
+
64540
+ let resObject = {};
64541
+ resObject.resi = resi;
64542
+ resObject.name = residue;
64253
64543
 
64254
- ic.chainsSeq[chainNum].push(resObject);
64544
+ ic.chainsSeq[chainNum].push(resObject);
64545
+ }
64255
64546
  }
64256
- else {
64257
64547
 
64258
- let resObject = {};
64259
- resObject.resi = resi;
64260
- resObject.name = residue;
64548
+ chainsTmp[serial] = 1;
64549
+ residuesTmp[serial] = 1;
64261
64550
 
64262
- ic.chainsSeq[chainNum].push(resObject);
64263
- }
64264
- }
64551
+ prevChainNum = chainNum;
64552
+ prevResidueNum = residueNum;
64553
+ prevOriResidueNum = oriResidueNum;
64265
64554
 
64266
- chainsTmp[serial] = 1;
64267
- residuesTmp[serial] = 1;
64555
+ prevResn = chain + "_" + resn;
64556
+ prevAutochain = autochain;
64557
+ }
64268
64558
 
64269
- prevChainNum = chainNum;
64270
- prevResidueNum = residueNum;
64271
- prevOriResidueNum = oriResidueNum;
64559
+ // add the last residue set
64560
+ ic.residues[residueNum] = residuesTmp;
64561
+ if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
64562
+ ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
64272
64563
 
64273
- prevResn = chain + "_" + resn;
64274
- prevAutochain = autochain;
64275
- }
64564
+ // clear memory
64565
+ atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
64566
+ = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
64276
64567
 
64277
- // add the last residue set
64278
- ic.residues[residueNum] = residuesTmp;
64279
- if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
64280
- ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
64568
+ let mChainSeq = {};
64569
+ if(block.getCategory("_pdbx_poly_seq_scheme")) {
64570
+ let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
64281
64571
 
64282
- // clear memory
64283
- atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
64284
- = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
64572
+ let resiArray = poly_seq_scheme.getColumn("seq_id");
64573
+ let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
64574
+ let resnArray = poly_seq_scheme.getColumn("mon_id");
64575
+ let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
64285
64576
 
64286
- let mChainSeq = {};
64287
- if(block.getCategory("_pdbx_poly_seq_scheme")) {
64288
- let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
64577
+ let seqSize = poly_seq_scheme.rowCount;
64578
+ let prevChain = "";
64579
+ let seqArray = [];
64580
+ for (let i = 0; i < seqSize; ++i) {
64581
+ resiArray.getString(i);
64582
+ let oriResi = oriResiArray.getString(i);
64583
+ let resn = resnArray.getString(i);
64584
+ let chain = chainArray.getString(i);
64289
64585
 
64290
- let resiArray = poly_seq_scheme.getColumn("seq_id");
64291
- let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
64292
- let resnArray = poly_seq_scheme.getColumn("mon_id");
64293
- let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
64586
+ if(chain != prevChain && i > 0) {
64587
+ mChainSeq[prevChain] = seqArray;
64294
64588
 
64295
- let seqSize = poly_seq_scheme.rowCount;
64296
- let prevChain = "";
64297
- let seqArray = [];
64298
- for (let i = 0; i < seqSize; ++i) {
64299
- resiArray.getString(i);
64300
- let oriResi = oriResiArray.getString(i);
64301
- let resn = resnArray.getString(i);
64302
- let chain = chainArray.getString(i);
64589
+ seqArray = [];
64590
+ }
64303
64591
 
64304
- if(chain != prevChain && i > 0) {
64305
- mChainSeq[prevChain] = seqArray;
64592
+ // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
64593
+ seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
64306
64594
 
64307
- seqArray = [];
64595
+ prevChain = chain;
64308
64596
  }
64309
64597
 
64310
- // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
64311
- seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
64598
+ mChainSeq[prevChain] = seqArray;
64312
64599
 
64313
- prevChain = chain;
64600
+ resiArray = oriResiArray = resnArray = chainArray = [];
64314
64601
  }
64315
-
64316
- mChainSeq[prevChain] = seqArray;
64317
-
64318
- resiArray = oriResiArray = resnArray = chainArray = [];
64602
+
64603
+ this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
64319
64604
  }
64320
-
64321
- this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
64322
64605
 
64323
64606
  // copy disulfide bonds
64324
64607
  let structureArray = Object.keys(ic.structures);
@@ -64613,7 +64896,7 @@ class Vastplus {
64613
64896
  let chainid = chainidArray[i];
64614
64897
  let atoms = me.hashUtilsCls.intHash(ic.hAtoms, ic.chains[chainid]);
64615
64898
  let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
64616
- structHash[firstAtom.structure] = 1;
64899
+ if(firstAtom) structHash[firstAtom.structure] = 1;
64617
64900
  }
64618
64901
  }
64619
64902
 
@@ -65635,6 +65918,11 @@ class ApplyCommand {
65635
65918
 
65636
65919
  ic.drawCls.draw();
65637
65920
  }
65921
+ else if(command == 'add ig labels') {
65922
+ ic.residueLabelsCls.addIgLabels(ic.hAtoms);
65923
+
65924
+ ic.drawCls.draw();
65925
+ }
65638
65926
  else if(command == 'add atom labels') {
65639
65927
  ic.residueLabelsCls.addAtomLabels(ic.hAtoms);
65640
65928
 
@@ -66961,6 +67249,7 @@ class ApplyCommand {
66961
67249
  else if(cmd.indexOf('hide annotation') == 0) return seqAnnoStr + ': checkboxes off';
66962
67250
  else if(cmd == 'add residue labels') return labelStr + 'per Residue';
66963
67251
  else if(cmd == 'add residue number labels') return labelStr + 'per Residue & Number';
67252
+ else if(cmd == 'add Ig domain labels') return labelStr + 'per Ig Domain';
66964
67253
  else if(cmd == 'add atom labels') return labelStr + 'per Atom';
66965
67254
  else if(cmd == 'add chain labels') return labelStr + 'per Chain';
66966
67255
  else if(cmd == 'add terminal labels') return labelStr + 'N- & C- Termini';
@@ -70225,6 +70514,34 @@ class Resid2spec {
70225
70514
  return spec;
70226
70515
  }
70227
70516
 
70517
+ resi2range(resiArray) {var ic = this.icn3d; ic.icn3dui;
70518
+ let range = [];
70519
+
70520
+ let resiArraySorted = resiArray.sort(function(a, b) {
70521
+ return parseInt(a) - parseInt(b);
70522
+ });
70523
+
70524
+ let startResi = resiArraySorted[0];
70525
+ let prevResi, resi;
70526
+ for(let j = 0, jl = resiArraySorted.length; j < jl; ++j) {
70527
+ resi = resiArraySorted[j];
70528
+
70529
+ if(j != 0 && resi != prevResi + 1) {
70530
+ range.push(startResi);
70531
+ range.push(prevResi);
70532
+ startResi = resi;
70533
+ }
70534
+
70535
+ prevResi = resi;
70536
+ }
70537
+
70538
+ // last residue
70539
+ range.push(startResi);
70540
+ range.push(prevResi);
70541
+
70542
+ return range;
70543
+ }
70544
+
70228
70545
  atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
70229
70546
  let spec = "";
70230
70547
  let i = 0;
@@ -71687,8 +72004,6 @@ class Dssp {
71687
72004
  bNoMoreIg = false;
71688
72005
 
71689
72006
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
71690
- //let bForceOneDomain = true;
71691
- //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
71692
72007
 
71693
72008
  // ig strand for any subset will have the same k, use the number of residue to separate them
71694
72009
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
@@ -71848,20 +72163,24 @@ class Dssp {
71848
72163
  // assign ref numbers to selected residues
71849
72164
  let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
71850
72165
  let subdomains = result.subdomains;
71851
- let pos2resi = result.pos2resi;
72166
+ // let pos2resi = result.pos2resi;
71852
72167
 
71853
72168
  if(subdomains.length >= 1) {
71854
72169
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
71855
72170
  let domainAtoms = {};
71856
72171
  let segArray = subdomains[k];
71857
72172
 
71858
- let resCnt = 0;
72173
+ let resCnt = 0; // minResi = 999, maxResi = -999;
71859
72174
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
71860
72175
  let startResi = parseInt(segArray[m]);
71861
72176
  let endResi = parseInt(segArray[m+1]);
71862
72177
 
72178
+ // if(startResi < minResi) minResi = startResi;
72179
+ // if(endResi > maxResi) maxResi = endResi;
72180
+
71863
72181
  for(let n = startResi; n <= endResi; ++n) {
71864
- let resid = chainid + '_' + pos2resi[n - 1];
72182
+ // let resid = chainid + '_' + pos2resi[n - 1];
72183
+ let resid = ic.ncbi2resid[chainid + '_' + n];
71865
72184
  ++resCnt;
71866
72185
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
71867
72186
 
@@ -71877,6 +72196,9 @@ class Dssp {
71877
72196
  domainAtomsArray.push(domainAtoms);
71878
72197
  }
71879
72198
  }
72199
+ // else { // no domain
72200
+ // domainAtomsArray = [currAtoms];
72201
+ // }
71880
72202
 
71881
72203
  return domainAtomsArray;
71882
72204
  }
@@ -72000,8 +72322,6 @@ class Dssp {
72000
72322
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
72001
72323
  }
72002
72324
 
72003
- console.log("### " + bBstrand + bCstrand + bEstrand + bFstrand);
72004
-
72005
72325
  // if(refpdbname != 'CD19_6al5A_human-n1') { // relax for CD19
72006
72326
  if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
72007
72327
  // if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
@@ -81434,7 +81754,7 @@ class iCn3DUI {
81434
81754
  //even when multiple iCn3D viewers are shown together.
81435
81755
  this.pre = this.cfg.divid + "_";
81436
81756
 
81437
- this.REVISION = '3.31.4';
81757
+ this.REVISION = '3.33.0';
81438
81758
 
81439
81759
  // In nodejs, iCn3D defines "window = {navigator: {}}"
81440
81760
  this.bNode = (Object.keys(window).length < 2) ? true : false;