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.js CHANGED
@@ -9018,7 +9018,7 @@ class ClickMenu {
9018
9018
  });
9019
9019
 
9020
9020
  me.myEventCls.onIds("#" + me.pre + "mn1_mmciffile", "click", function(e) { me.icn3d; //e.preventDefault();
9021
- me.htmlCls.dialogCls.openDlg('dl_mmciffile', 'Please input mmCIF File');
9021
+ me.htmlCls.dialogCls.openDlg('dl_mmciffile', 'Please append mmCIF File');
9022
9022
  });
9023
9023
 
9024
9024
  me.myEventCls.onIds("#" + me.pre + "mn1_mmcifid", "click", function(e) { me.icn3d; //e.preventDefault();
@@ -10588,6 +10588,13 @@ class ClickMenu {
10588
10588
  ic.drawCls.draw();
10589
10589
  });
10590
10590
 
10591
+ me.myEventCls.onIds("#" + me.pre + "mn6_addlabelIg", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
10592
+ ic.residueLabelsCls.addIgLabels(ic.hAtoms);
10593
+ ic.selectionCls.saveSelectionIfSelected();
10594
+ thisClass.setLogCmd('add ig labels', true);
10595
+ ic.drawCls.draw();
10596
+ });
10597
+
10591
10598
  me.myEventCls.onIds("#" + me.pre + "mn6_addlabelChains", "click", function(e) { let ic = me.icn3d; //e.preventDefault();
10592
10599
  ic.analysisCls.addChainLabels(ic.hAtoms);
10593
10600
  ic.selectionCls.saveSelectionIfSelected();
@@ -11684,7 +11691,7 @@ class SetMenu {
11684
11691
  // html += this.getLink('mn1_pdbfile', 'PDB File');
11685
11692
  // html += this.getLink('mn1_pdbfile_app', 'PDB File (append)');
11686
11693
  html += this.getLink('mn1_pdbfile_app', 'PDB Files (appendable)', 1, 2);
11687
- html += this.getLink('mn1_mmciffile', 'mmCIF File', undefined, 2);
11694
+ html += this.getLink('mn1_mmciffile', 'mmCIF Files (appendable)', undefined, 2);
11688
11695
  html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
11689
11696
  html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
11690
11697
  html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
@@ -11812,15 +11819,12 @@ class SetMenu {
11812
11819
  html += this.getLink('mn1_exportSecondary', 'Secondary Structure', undefined, 2);
11813
11820
  }
11814
11821
 
11815
- //!!!
11816
- /*
11817
11822
  html += this.getMenuText('m1_exportrefnum', 'Reference Numbers', undefined, undefined, 2);
11818
11823
  html += "<ul>";
11819
11824
  html += this.getLink('mn1_exportIgstrand', 'Ig Strand', undefined, 3);
11820
11825
  html += this.getLink('mn1_exportKabat', 'Kabat', undefined, 3);
11821
11826
  html += this.getLink('mn1_exportImgt', 'IMGT', undefined, 3);
11822
11827
  html += "</ul>";
11823
- */
11824
11828
 
11825
11829
  html += "<li><br/></li>";
11826
11830
 
@@ -12663,9 +12667,8 @@ class SetMenu {
12663
12667
  html += this.getRadio('mn4_clr', 'mn4_clrConfidence', 'pLDDT', undefined, 1, 1);
12664
12668
  //}
12665
12669
 
12666
- //!!!
12667
- // html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
12668
- // html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
12670
+ html += this.getRadio('mn4_clr', 'mn4_clrIgstrand', 'Ig Strand', undefined, undefined, 2);
12671
+ html += this.getRadio('mn4_clr', 'mn4_clrIgproto', 'Ig Protodomain', undefined, undefined, 2);
12669
12672
  }
12670
12673
  else {
12671
12674
  //if(!me.cfg.hidelicense) html += this.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
@@ -12795,8 +12798,10 @@ class SetMenu {
12795
12798
  if(me.cfg.cid === undefined) {
12796
12799
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResidues', 'per Residue', undefined, 1, 2);
12797
12800
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelResnum', 'per Residue & Number', undefined, 1, 2);
12798
- //!!!
12799
- // html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
12801
+
12802
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelRefnum', 'per Reference Number', undefined, 1, 2);
12803
+ html += this.getRadio('mn6_addlabel', 'mn6_addlabelIg', 'per Ig Domain', undefined, 1, 2);
12804
+
12800
12805
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelChains', 'per Chain', undefined, undefined, 2);
12801
12806
  html += this.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini', undefined, 1, 2);
12802
12807
  }
@@ -12889,17 +12894,13 @@ class SetMenu {
12889
12894
  html += this.getMenuText('mn6_igrefwrap', 'Ref. Number', undefined, undefined, 1);
12890
12895
 
12891
12896
  html += "<ul>";
12892
- //!!!
12893
- /*
12897
+
12894
12898
  html += this.getLink('mn6_igrefYes', 'Show Ig for Selection', undefined, 2);
12895
12899
  html += this.getLink('mn6_igrefTpl', 'Ig w/ Specified Template', undefined, 2);
12896
12900
  html += this.getLink('mn6_alignrefTpl', 'Align w/ Specified Template', undefined, 2);
12897
12901
  html += this.getLink('mn6_igrefNo', 'Reset Ig Ref. Number', undefined, 2);
12898
12902
 
12899
12903
  html += this.getMenuSep();
12900
- */
12901
-
12902
-
12903
12904
 
12904
12905
  html += this.getLink('mn6_customref', 'Custom Ref. Number', undefined, 2);
12905
12906
  html += "</ul>";
@@ -12989,6 +12990,7 @@ class SetMenu {
12989
12990
  html += this.getMenuUrl('faq_simialphapdb', me.htmlCls.baseUrl + "icn3d/icn3d.html#simifoldseek", "Similar AlphaFold/PDB", 1, 2);
12990
12991
  html += this.getMenuUrl('faq_alnstru', me.htmlCls.baseUrl + "icn3d/icn3d.html#alignmul", "Align Multiple Structures", 1, 2);
12991
12992
  html += this.getMenuUrl('faq_batchanal', me.htmlCls.baseUrl + "icn3d/icn3d.html#batchanalysis", "Batch Analysis", 1, 2);
12993
+ html += this.getMenuUrl('faq_batchanal', me.htmlCls.baseUrl + "icn3d/icn3d.html#igrefnum", "Assign Ig Ref. Numbers", 1, 2);
12992
12994
  html += this.getMenuUrl('faq_embedicn3d', me.htmlCls.baseUrl + "icn3d/icn3d.html#embedicn3d", "Embed iCn3D", 1, 2);
12993
12995
  html += "</ul>";
12994
12996
  html += "</li>";
@@ -14028,8 +14030,8 @@ class SetDialog {
14028
14030
  html += "</div>";
14029
14031
 
14030
14032
  html += me.htmlCls.divStr + "dl_mmciffile' class='" + dialogClass + "'>";
14031
- html += this.addNotebookTitle('dl_mmciffile', 'Please input an mmCIF file');
14032
- html += "mmCIF File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "mmciffile' value='1TUP' size=8> ";
14033
+ html += this.addNotebookTitle('dl_mmciffile', 'Please append mmCIF files');
14034
+ html += "Multiple mmCIF Files: <input type='file' multiple id='" + me.pre + "mmciffile' size=8> ";
14033
14035
  html += me.htmlCls.buttonStr + "reload_mmciffile'>Load</button>";
14034
14036
  html += "</div>";
14035
14037
 
@@ -15177,13 +15179,10 @@ class SetDialog {
15177
15179
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_interact'>Interactions" + me.htmlCls.space2 + "</span></td>";
15178
15180
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_crosslink'>Cross-Linkages" + me.htmlCls.space2 + "</span></td>";
15179
15181
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_transmem'>Transmembrane" + me.htmlCls.space2 + "</span></td>";
15180
- //!!!
15181
- /*
15182
+
15182
15183
  html += "<td></td>";
15183
15184
  html += "</tr><tr>";
15184
15185
  html += tmpStr1 + me.htmlCls.inputCheckStr + "id='" + me.pre + "anno_ig'>Ig Domains" + me.htmlCls.space2 + "</span></td>";
15185
- */
15186
-
15187
15186
 
15188
15187
  html += "<td></td>";
15189
15188
  html += "</tr></table></div></div>";
@@ -15284,17 +15283,15 @@ class Events {
15284
15283
  }
15285
15284
  }
15286
15285
 
15287
- async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
15286
+ async readFile(bAppend, files, index, dataStrAll, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
15288
15287
  let file = files[index];
15289
15288
  let commandName = (bAppend) ? 'append': 'load';
15289
+ commandName += (bmmCIF) ? ' mmcif file ': ' pdb file ';
15290
15290
 
15291
15291
  let reader = new FileReader();
15292
15292
  reader.onload = async function(e) {
15293
- //++ic.loadedFileCnt;
15294
-
15295
15293
  let dataStr = e.target.result; // or = reader.result;
15296
- //thisClass.setLogCmd(commandName + ' pdb file ' + $("#" + me.pre + fileId).val(), false);
15297
- thisClass.setLogCmd(commandName + ' pdb file ' + file.name, false);
15294
+ thisClass.setLogCmd(commandName + file.name, false);
15298
15295
 
15299
15296
  if(!bAppend) {
15300
15297
  ic.init();
@@ -15308,7 +15305,7 @@ class Events {
15308
15305
  }
15309
15306
 
15310
15307
  ic.bInputfile = true;
15311
- ic.InputfileType = 'pdb';
15308
+ ic.InputfileType = (bmmCIF) ? 'mmcif' : 'pdb';
15312
15309
  ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + dataStr : dataStr;
15313
15310
 
15314
15311
  dataStrAll = (index > 0) ? dataStrAll + '\nENDMDL\n' + dataStr : dataStr;
@@ -15318,15 +15315,21 @@ class Events {
15318
15315
  ic.hAtoms = {};
15319
15316
  ic.dAtoms = {};
15320
15317
  }
15321
- await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
15318
+ if(bmmCIF) {
15319
+ await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend);
15320
+ }
15321
+ else {
15322
+ await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
15323
+ }
15324
+
15325
+ //ic.InputfileType = undefined; // reset
15322
15326
  }
15323
15327
  else {
15324
- await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
15328
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll, bmmCIF);
15325
15329
  }
15326
15330
 
15327
15331
  if(bAppend) {
15328
15332
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
15329
- //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
15330
15333
 
15331
15334
  ic.bResetAnno = true;
15332
15335
 
@@ -15343,9 +15346,7 @@ class Events {
15343
15346
  }
15344
15347
  }
15345
15348
 
15346
- async loadPdbFile(bAppend) { let me = this.icn3dui, ic = me.icn3d;
15347
- let fileId = (bAppend) ? 'pdbfile_app' : 'pdbfile';
15348
-
15349
+ async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d;
15349
15350
  //me = ic.setIcn3dui(this.id);
15350
15351
  ic.bInitial = true;
15351
15352
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -15369,7 +15370,7 @@ class Events {
15369
15370
 
15370
15371
  ic.dataStrAll = '';
15371
15372
 
15372
- await this.readFile(bAppend, files, 0, '');
15373
+ await this.readFile(bAppend, files, 0, '', bmmCIF);
15373
15374
  }
15374
15375
  }
15375
15376
 
@@ -16726,14 +16727,14 @@ class Events {
16726
16727
  e.preventDefault();
16727
16728
 
16728
16729
  let bAppend = false;
16729
- await thisClass.loadPdbFile(bAppend);
16730
+ await thisClass.loadPdbFile(bAppend, 'pdbfile');
16730
16731
  });
16731
16732
 
16732
16733
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", async function(e) { let ic = me.icn3d;
16733
16734
  e.preventDefault();
16734
16735
 
16735
16736
  ic.bAppend = true;
16736
- await thisClass.loadPdbFile(ic.bAppend);
16737
+ await thisClass.loadPdbFile(ic.bAppend, 'pdbfile_app');
16737
16738
  });
16738
16739
 
16739
16740
  me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
@@ -16917,49 +16918,13 @@ class Events {
16917
16918
  await ic.pdbParserCls.downloadUrl(url, type);
16918
16919
  });
16919
16920
 
16920
- me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", function(e) { let ic = me.icn3d;
16921
+ me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", async function(e) { let ic = me.icn3d;
16921
16922
  e.preventDefault();
16922
- ic.bInitial = true;
16923
- if(!me.cfg.notebook) dialog.dialog( "close" );
16924
- //close all dialog
16925
- if(!me.cfg.notebook) {
16926
- $(".ui-dialog-content").dialog("close");
16927
- }
16928
- else {
16929
- ic.resizeCanvasCls.closeDialogs();
16930
- }
16931
- let file = $("#" + me.pre + "mmciffile")[0].files[0];
16932
- if(!file) {
16933
- var aaa = 1; //alert("Please select a file before clicking 'Load'");
16934
- }
16935
- else {
16936
- me.htmlCls.setHtmlCls.fileSupport();
16937
- let reader = new FileReader();
16938
- reader.onload = async function(e) {
16939
- let dataStr = e.target.result; // or = reader.result;
16940
- thisClass.setLogCmd('load mmcif file ' + $("#" + me.pre + "mmciffile").val(), false);
16941
- ic.molTitle = "";
16942
-
16943
- // let url = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi";
16944
- // //ic.bCid = undefined;
16945
16923
 
16946
- // let dataObj = {'mmciffile': dataStr};
16947
- // let data = await me.getAjaxPostPromise(url, dataObj, true);
16948
-
16949
- let bText = true;
16950
- // let bcifData = ic.bcifParserCls.getBcifJson(dataStr, undefined, bText);
16951
- // let data = JSON.parse(bcifData);
16952
-
16953
- //ic.initUI();
16954
- ic.init();
16955
- ic.bInputfile = true;
16956
- ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + data : dataStr;
16957
- ic.InputfileType = 'mmcif';
16958
- // await ic.mmcifParserCls.loadMmcifData(data);
16959
- await ic.opmParserCls.loadOpmData(dataStr, undefined, undefined, 'mmcif', undefined, bText);
16960
- };
16961
- reader.readAsText(file);
16962
- }
16924
+ ic.bAppend = true;
16925
+ let bmmCIF = true;
16926
+ let fileId = 'mmciffile';
16927
+ await thisClass.loadPdbFile(ic.bAppend, fileId, bmmCIF);
16963
16928
  });
16964
16929
 
16965
16930
  me.myEventCls.onIds("#" + me.pre + "applycustomcolor", "click", function(e) { let ic = me.icn3d;
@@ -34888,6 +34853,33 @@ class ResidueLabels {
34888
34853
  ic.hlObjectsCls.removeHlObjects();
34889
34854
  }
34890
34855
 
34856
+ //Add labels for each Ig domain
34857
+ addIgLabels(atoms) { let ic = this.icn3d, me = ic.icn3dui;
34858
+ if(me.bNode) return;
34859
+
34860
+ let size = 60; //18;
34861
+
34862
+ ic.labels['ig'] = [];
34863
+ let chainidHash = ic.firstAtomObjCls.getChainsFromAtoms(atoms);
34864
+
34865
+ for(let chainid in ic.igLabel2Pos) {
34866
+ if(!chainidHash.hasOwnProperty(chainid)) continue;
34867
+
34868
+ for(let text in ic.igLabel2Pos[chainid]) {
34869
+ let label = {}; // Each label contains 'position', 'text', 'color', 'background'
34870
+ label.position = ic.igLabel2Pos[chainid][text];
34871
+ label.text = text;
34872
+
34873
+ label.size = size;
34874
+ label.color = '#00FFFF';
34875
+
34876
+ ic.labels['ig'].push(label);
34877
+ }
34878
+ }
34879
+
34880
+ ic.hlObjectsCls.removeHlObjects();
34881
+ }
34882
+
34891
34883
  addNonCarbonAtomLabels(atoms) { let ic = this.icn3d, me = ic.icn3dui;
34892
34884
  if(me.bNode) return;
34893
34885
 
@@ -39949,9 +39941,24 @@ class AnnoCddSite {
39949
39941
  pssmid2toArray = {};
39950
39942
  }
39951
39943
 
39952
- let indexl =(domainArray !== undefined) ? domainArray.length : 0;
39944
+ if(domainArray === undefined) domainArray = [];
39945
+ let indexl = domainArray.length;
39953
39946
  let maxTextLen =(type == 'domain') ? 14 : 19;
39954
39947
  let titleSpace =(type == 'domain') ? 100 : 120;
39948
+
39949
+ // sort domainArray
39950
+ domainArray.sort(function(a, b) {
39951
+ let domainRepeatArray = a.locs;
39952
+ let segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
39953
+ let domainFrom1 = Math.round(segArray[0].from);
39954
+
39955
+ domainRepeatArray = b.locs;
39956
+ segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
39957
+ let domainFrom2 = Math.round(segArray[0].from);
39958
+
39959
+ return domainFrom1 - domainFrom2;
39960
+ });
39961
+
39955
39962
  for(let index = 0; index < indexl; ++index) {
39956
39963
  let pssmid = (type == 'domain') ? domainArray[index].pssmid : 0;
39957
39964
 
@@ -40820,6 +40827,7 @@ class AnnoIg {
40820
40827
  async showIg(chnid, template) { let ic = this.icn3d; ic.icn3dui;
40821
40828
  // if(!ic.bRunRefnum || Object.keys(ic.atoms).length > Object.keys(ic.hAtoms).length) {
40822
40829
  if(ic.bRunRefnumAgain) {
40830
+ // run for all chains
40823
40831
  await ic.refnumCls.showIgRefNum(template);
40824
40832
  // ic.bRunRefnum = true;
40825
40833
  }
@@ -41142,6 +41150,8 @@ class AnnoIg {
41142
41150
  let igCnt = ic.chain2igArray[chnid].length;
41143
41151
  let fromArray = [], toArray = [];
41144
41152
  let posindex2domainindex = {};
41153
+ if(!ic.igLabel2Pos) ic.igLabel2Pos = {};
41154
+ ic.igLabel2Pos[chnid] = {};
41145
41155
  for(let i = 0; i < igCnt; ++i) {
41146
41156
  let igElem = ic.chain2igArray[chnid][i];
41147
41157
  fromArray = fromArray.concat(igElem.startPosArray);
@@ -41151,6 +41161,18 @@ class AnnoIg {
41151
41161
  let pos = igElem.startPosArray[j];
41152
41162
  posindex2domainindex[pos] = i;
41153
41163
  }
41164
+
41165
+ let resi1 = ic.ParserUtilsCls.getResi(chnid, igElem.startPosArray[0]);
41166
+ let resid1 = chnid + "_" + resi1;
41167
+ let calpha1 = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid1]);
41168
+
41169
+ let resi2 = ic.ParserUtilsCls.getResi(chnid, igElem.endPosArray[igElem.endPosArray.length - 1]);
41170
+ let resid2 = chnid + "_" + resi2;
41171
+ let calpha2 = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid2]);
41172
+
41173
+ let label = chnid.substr(chnid.lastIndexOf('_') + 1) + '-Ig' + (i+1).toString();
41174
+
41175
+ ic.igLabel2Pos[chnid][label] = calpha1.coord.clone().add(calpha2.coord).multiplyScalar(0.5);
41154
41176
  }
41155
41177
 
41156
41178
  // let htmlCnt = '<span class="icn3d-residueNum" title="Ig domain count">' + igCnt.toString() + ' Igs</span>';
@@ -41201,6 +41223,7 @@ class AnnoIg {
41201
41223
  if(igArray.length == 0) return {html: html, html2: html2, html3: html3}
41202
41224
  let rangeArray = [], titleArray = [], fullTitleArray = [], domainArray = [];
41203
41225
 
41226
+ let chain = chnid.substr(chnid.lastIndexOf('_') + 1);
41204
41227
  for(let i = 0, il = igArray.length; i < il; ++i) {
41205
41228
  let domainid = igArray[i].domainid;
41206
41229
  if(!ic.domainid2info) continue;
@@ -41212,7 +41235,7 @@ class AnnoIg {
41212
41235
 
41213
41236
  let igType = (parseFloat(tmscore) < ic.refnumCls.TMThresholdIgType ) ? 'Ig' : ic.ref2igtype[info.refpdbname];
41214
41237
  titleArray.push(igType + ' (TM:' + parseFloat(tmscore).toFixed(2) + ')');
41215
- 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);
41238
+ 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());
41216
41239
 
41217
41240
  domainArray.push(igType);
41218
41241
 
@@ -41477,9 +41500,7 @@ class AnnoDomain {
41477
41500
 
41478
41501
  let result = ic.domain3dCls.c2b_NewSplitChain(atoms);
41479
41502
  let subdomains = result.subdomains;
41480
- let pos2resi = result.pos2resi;
41481
- //let substruct = result.substruct;
41482
- //let jsonStr = ic.domain3dCls.getDomainJsonForAlign(atoms);
41503
+ // let pos2resi = result.pos2resi;
41483
41504
 
41484
41505
  for(let i = 0, il = subdomains.length; i < il; ++i) {
41485
41506
  // domain item: {"sdid":1722375,"intervals":[[1,104],[269,323]]}
@@ -41493,7 +41514,7 @@ class AnnoDomain {
41493
41514
  data.domains[chainid].domains.push(domain);
41494
41515
  }
41495
41516
 
41496
- data.domains[chainid].pos2resi = pos2resi;
41517
+ // data.domains[chainid].pos2resi = pos2resi;
41497
41518
  }
41498
41519
  }
41499
41520
 
@@ -41526,11 +41547,26 @@ class AnnoDomain {
41526
41547
  this.showDomainPerStructure(i);
41527
41548
  }
41528
41549
  }
41550
+
41551
+ getResiFromNnbiresid(ncbiresid) { let ic = this.icn3d; ic.icn3dui;
41552
+ let resid = (ic.ncbi2resid[ncbiresid]) ? ic.ncbi2resid[ncbiresid] : ncbiresid;
41553
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
41554
+
41555
+ return resi;
41556
+ }
41557
+
41558
+ getNcbiresiFromResid(resid) { let ic = this.icn3d; ic.icn3dui;
41559
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
41560
+ let resi = ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1);
41561
+
41562
+ return resi;
41563
+ }
41564
+
41529
41565
  showDomainWithData(chnid, data, bCalcDirect) { let ic = this.icn3d, me = ic.icn3dui;
41530
41566
  let html = '<div id="' + ic.pre + chnid + '_domainseq_sequence" class="icn3d-dl_sequence">';
41531
41567
  let html2 = html;
41532
41568
  let html3 = html;
41533
- let domainArray, pos2resi, proteinname;
41569
+ let domainArray, proteinname;
41534
41570
  let pos = chnid.indexOf('_');
41535
41571
  let chain = chnid.substr(pos + 1);
41536
41572
  // MMDB symmetry chain has the form of 'A1'
@@ -41541,7 +41577,7 @@ class AnnoDomain {
41541
41577
  // if(bCalcDirect) {
41542
41578
  proteinname = chnid;
41543
41579
  domainArray = (data.domains[chnid]) ? data.domains[chnid].domains : [];
41544
- pos2resi = data.domains[chnid].pos2resi;
41580
+ // pos2resi = data.domains[chnid].pos2resi;
41545
41581
  /*
41546
41582
  }
41547
41583
  else {
@@ -41569,40 +41605,33 @@ class AnnoDomain {
41569
41605
  let title =(fulltitle.length > 17) ? fulltitle.substr(0,17) + '...' : fulltitle;
41570
41606
  let subdomainArray = domainArray[index].intervals;
41571
41607
  // remove duplicate, e.g., at https://www.ncbi.nlm.nih.gov/Structure/mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=1itw
41572
- let domainFromHash = {}, domainToHash = {};
41573
- let fromArray = [], toArray = [], posFromArray = [], posToArray = [];
41608
+ // let domainFromHash = {}, domainToHash = {};
41609
+ let fromArray = [], toArray = []; // posFromArray = [], posToArray = [];
41574
41610
  let resiHash = {};
41575
41611
  let resCnt = 0;
41576
41612
 
41613
+ // subdomainArray contains NCBI residue number
41577
41614
  for(let i = 0, il = subdomainArray.length; i < il; ++i) {
41578
- let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
41579
- let domainTo = Math.round(subdomainArray[i][1]) - 1;
41615
+ // let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
41616
+ // let domainTo = Math.round(subdomainArray[i][1]) - 1;
41580
41617
 
41581
- if(domainFromHash.hasOwnProperty(domainFrom) || domainToHash.hasOwnProperty(domainTo)) {
41582
- continue; // do nothing for duplicated "from" or "to", e.g, PDBID 1ITW, 5FWI
41583
- }
41584
- else {
41585
- domainFromHash[domainFrom] = 1;
41586
- domainToHash[domainTo] = 1;
41587
- }
41618
+ let domainFrom = parseInt(subdomainArray[i][0]);
41619
+ let domainTo = parseInt(subdomainArray[i][1]);
41588
41620
 
41589
- // use the NCBI residue number, and convert to PDB residue number during selection
41590
- // if(ic.bNCBI || bCalcDirect) {
41591
- fromArray.push(pos2resi[domainFrom]);
41592
- toArray.push(pos2resi[domainTo]);
41593
41621
 
41594
- posFromArray.push(domainFrom);
41595
- posToArray.push(domainTo);
41596
- // }
41597
- // else {
41598
- // fromArray.push(domainFrom + ic.baseResi[chnid]);
41599
- // toArray.push(domainTo + ic.baseResi[chnid]);
41600
- // }
41622
+ // fromArray.push(pos2resi[domainFrom]);
41623
+ // toArray.push(pos2resi[domainTo]);
41624
+
41625
+ fromArray.push(domainFrom);
41626
+ toArray.push(domainTo);
41627
+
41628
+ // posFromArray.push(domainFrom);
41629
+ // posToArray.push(domainTo);
41601
41630
 
41602
41631
  resCnt += domainTo - domainFrom + 1;
41603
41632
  for(let j = domainFrom; j <= domainTo; ++j) {
41604
- // resiHash[j+1] = 1;
41605
- let resi = pos2resi[j];
41633
+ // let resi = pos2resi[j];
41634
+ let resi = this.getResiFromNnbiresid(chnid + '_' + j);
41606
41635
  resiHash[resi] = 1;
41607
41636
  }
41608
41637
  }
@@ -41613,21 +41642,22 @@ class AnnoDomain {
41613
41642
 
41614
41643
  if(!ic.resid2domain) ic.resid2domain = {};
41615
41644
  if(!ic.resid2domain[chnid]) ic.resid2domain[chnid] = [];
41616
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
41617
- let from = parseInt(posFromArray[i]);
41618
- let to = parseInt(posToArray[i]);
41645
+ // for(let i = 0, il = posFromArray.length; i < il; ++i) {
41646
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
41647
+ let from = fromArray[i];
41648
+ let to = toArray[i];
41619
41649
  for(let j = from; j <= to; ++j) {
41620
41650
  // 0-based
41621
41651
  let obj = {};
41622
41652
  // let resi = ic.ParserUtilsCls.getResi(chnid, j);
41623
- let resi = pos2resi[j];
41624
- obj[chnid + '_' + resi] = domainName;
41653
+ let resid = ic.ncbi2resid(chnid + '_' + j);
41654
+ obj[resid] = domainName;
41625
41655
  ic.resid2domain[chnid].push(obj);
41626
41656
  }
41627
41657
  }
41628
41658
  }
41629
41659
 
41630
- 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>';
41660
+ 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>';
41631
41661
  let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
41632
41662
  html3 += htmlTmp2 + htmlTmp3 + '<br>';
41633
41663
  let htmlTmp = '<span class="icn3d-seqLine">';
@@ -41667,12 +41697,12 @@ class AnnoDomain {
41667
41697
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
41668
41698
 
41669
41699
  if(me.cfg.blast_rep_id != chnid) { // regular
41670
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
41700
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
41671
41701
  // 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);
41672
- let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
41702
+ let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
41673
41703
 
41674
41704
  html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
41675
- 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>';
41705
+ 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>';
41676
41706
  }
41677
41707
  }
41678
41708
  else { // with potential gaps
@@ -43184,6 +43214,7 @@ class Domain3d {
43184
43214
  //c2b_NewSplitChain(string asymId, let seqLen, let* x0, let* y0, let* z0) { let ic = this.icn3d, me = ic.icn3dui;
43185
43215
  // x0, y0, z0: array of x,y,z coordinates of C-alpha atoms
43186
43216
  //c2b_NewSplitChain(chnid, dcut) { let ic = this.icn3d, me = ic.icn3dui;
43217
+ // this function works for a single chain
43187
43218
  c2b_NewSplitChain(atoms, dcut) { let ic = this.icn3d; ic.icn3dui;
43188
43219
  this.init3ddomain();
43189
43220
 
@@ -43239,14 +43270,11 @@ class Domain3d {
43239
43270
  // pos2resi[i+1] = resi;
43240
43271
  pos2resi[i] = resi;
43241
43272
 
43242
- ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
43243
- // let residNCBI = ic.resid2ncbi[resid];
43244
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
43245
- // pos2resi[pos] = resi;
43246
-
43273
+ // ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
43247
43274
  if(atom.ssend) {
43248
43275
  //substructItem.To = parseInt(resi);
43249
43276
  substructItem.To = i + 1;
43277
+ // substructItem.To = ic.annoDomainCls.getNcbiresiFromResid(resid);
43250
43278
  substructItem.x2 = atom.coord.x;
43251
43279
  substructItem.y2 = atom.coord.y;
43252
43280
  substructItem.z2 = atom.coord.z;
@@ -43261,6 +43289,7 @@ class Domain3d {
43261
43289
  if(atom.ssbegin) {
43262
43290
  //substructItem.From = parseInt(resi);
43263
43291
  substructItem.From = i + 1;
43292
+ // substructItem.From = ic.annoDomainCls.getNcbiresiFromResid(resid);
43264
43293
  substructItem.x1 = atom.coord.x;
43265
43294
  substructItem.y1 = atom.coord.y;
43266
43295
  substructItem.z1 = atom.coord.z;
@@ -43268,17 +43297,19 @@ class Domain3d {
43268
43297
  }
43269
43298
 
43270
43299
  let nsse = substruct.length;
43271
-
43272
- if (nsse <= 3)
43300
+
43301
+ if (nsse <= 3) {
43273
43302
  // too small, can't split or trim
43274
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
43303
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43304
+ return {subdomains: subdomains, substruct: substruct};
43305
+ }
43275
43306
 
43276
43307
  if (nsse > this.MAX_SSE) {
43277
43308
  // we have a problem...
43278
-
43279
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
43309
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43310
+ return {subdomains: subdomains, substruct: substruct};
43280
43311
  }
43281
-
43312
+
43282
43313
  let seqLen = residueArray.length; // + resiOffset;
43283
43314
  //let lastResi = resiArray[seqLen - 1];
43284
43315
  let lastResi = seqLen;
@@ -43599,7 +43630,8 @@ class Domain3d {
43599
43630
  let k = prts[i] - 1;
43600
43631
 
43601
43632
  if ((k < 0) || (k >= substruct.length)) {
43602
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
43633
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43634
+ return {subdomains: subdomains, substruct: substruct};
43603
43635
  }
43604
43636
 
43605
43637
  //SSE_Rec sserec = substruct[k];
@@ -43686,16 +43718,23 @@ class Domain3d {
43686
43718
 
43687
43719
  if (inseg && (rf == 0)) {
43688
43720
  // segment ends
43689
- segments.push(startseg);
43690
- segments.push(i);
43721
+ // segments.push(startseg);
43722
+ // segments.push(i);
43723
+
43724
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, i, pos2resi);
43725
+ segments = segments.concat(resiRangeArray);
43726
+
43691
43727
  inseg = false;
43692
43728
  }
43693
43729
  }
43694
43730
 
43695
43731
  // check for the last segment
43696
43732
  if (inseg) {
43697
- segments.push(startseg);
43698
- segments.push(lastResi);
43733
+ // segments.push(startseg);
43734
+ // segments.push(lastResi);
43735
+
43736
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, lastResi, pos2resi);
43737
+ segments = segments.concat(resiRangeArray);
43699
43738
  }
43700
43739
 
43701
43740
  subdomains.push(segments);
@@ -43716,61 +43755,114 @@ class Domain3d {
43716
43755
  }
43717
43756
  }
43718
43757
 
43719
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi };
43758
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43759
+
43760
+ // return {subdomains: subdomains, substruct: substruct};
43761
+ //subdomains contains NCBI residue numbers
43762
+ return {subdomains: subdomains, substruct: substruct};
43720
43763
  } // end c2b_NewSplitChain
43721
43764
 
43722
- getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
43765
+ standardizeSubstruct(chnid, substruct, pos2resi) { let ic = this.icn3d; ic.icn3dui;
43766
+ // adjust substruct to use NCBI residue number
43767
+ for (let i = 0; i < substruct.length; i++) {
43768
+ //SSE_Rec sserec = substruct[i];
43769
+ let sserec = substruct[i];
43770
+ let FromPos = sserec.From;
43771
+ let ToPos = sserec.To;
43772
+
43773
+ let FromResi = pos2resi[FromPos - 1];
43774
+ let ToResi = pos2resi[ToPos - 1];
43775
+
43776
+ let FromNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + FromResi);
43777
+ let ToNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + ToResi);
43778
+
43779
+ substruct[i].From = FromNcbiResid.substr(FromNcbiResid.lastIndexOf('_') + 1);
43780
+ substruct[i].To = ToNcbiResid.substr(ToNcbiResid.lastIndexOf('_') + 1);
43781
+
43782
+ substruct[i].From = parseInt(substruct[i].From);
43783
+ substruct[i].To = parseInt(substruct[i].To);
43784
+ }
43785
+
43786
+ return substruct;
43787
+ }
43788
+
43789
+ getNcbiresiRangeFromPos(chnid, startPos, endPos, pos2resi) { let ic = this.icn3d; ic.icn3dui;
43790
+ let resiArray = [];
43791
+ for(let i = startPos; i <= endPos; ++i) {
43792
+ let resi = pos2resi[i - 1];
43793
+ let residNCBI = (ic.resid2ncbi[chnid + '_' + resi]) ? ic.resid2ncbi[chnid + '_' + resi] : chnid + '_' + resi;
43794
+ let ncbiresi = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
43795
+ resiArray.push(parseInt(ncbiresi));
43796
+ }
43797
+
43798
+ let resiRangeArray = ic.resid2specCls.resi2range(resiArray);
43799
+
43800
+ return resiRangeArray;
43801
+ }
43802
+
43803
+ /*
43804
+ // this function works for atoms in a single chain
43805
+ // getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
43806
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
43723
43807
  let result = this.c2b_NewSplitChain(atoms);
43724
43808
 
43725
43809
  let subdomains = result.subdomains;
43726
43810
  let substruct = result.substruct;
43727
- let pos2resi = result.pos2resi;
43811
+ // let pos2resi = result.pos2resi;
43728
43812
 
43729
- let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
43730
- let residueArray = Object.keys(residueHash);
43731
- let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
43732
43813
 
43733
- if(bForceOneDomain) subdomains = [];
43814
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
43815
+ // let residueArray = Object.keys(residueHash);
43816
+ // let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
43734
43817
 
43735
- //the whole structure is also considered as a large domain
43736
- //if(subdomains.length == 0) {
43737
- //subdomains.push([parseInt(ic.chainsSeq[chnid][0].resi), parseInt(ic.chainsSeq[chnid][ic.chainsSeq[chnid].length - 1].resi)]);
43818
+ let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
43819
+ let chnid = firstAtom.structure + '_' + firstAtom.chain;
43738
43820
 
43739
- // subdomains.push([parseInt(residueArray[0].substr(residueArray[0].lastIndexOf('_') + 1)),
43740
- // parseInt(residueArray[residueArray.length-1].substr(residueArray[residueArray.length-1].lastIndexOf('_') + 1))]);
43821
+ // if(bForceOneDomain) subdomains = [];
43741
43822
 
43742
- // use position based
43743
- subdomains.push([1, residueArray.length]);
43744
-
43745
- //}
43823
+ //the whole structure is also considered as a large domain
43824
+ if(subdomains.length == 0) {
43825
+ let resid1 = residueArray[0];
43826
+ let resid2 = residueArray[residueArray.length - 1];
43827
+ let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
43828
+ let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
43829
+ subdomains.push([parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1)), parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1))]);
43830
+ }
43746
43831
 
43747
43832
  // 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], ...]} ] }
43748
43833
  let jsonStr = '{"data": [';
43834
+ //merge all subdomains into one domain
43835
+ jsonStr += '{"ss": ['; //secondary structure
43836
+
43837
+ let ssCnt = 0, startAll = 999, endAll = -999;
43749
43838
  for(let i = 0, il = subdomains.length; i < il; ++i) {
43750
- if(i > 0) jsonStr += ', ';
43751
- //secondary structure
43752
- jsonStr += '{"ss": [';
43753
- let ssCnt = 0;
43839
+ // if(i > 0) jsonStr += ', ';
43840
+ // jsonStr += '{"ss": ['; //secondary structure
43841
+
43754
43842
  for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
43755
43843
  let start = subdomains[i][j];
43756
43844
  let end = subdomains[i][j + 1];
43757
-
43845
+
43846
+ if(start < startAll) startAll = start;
43847
+ if(end > endAll) endAll = end;
43848
+
43758
43849
  for(let k = 0, kl = substruct.length; k < kl; ++k) {
43759
43850
  //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
43760
43851
  //sstype: 1 (helix), 2 (sheet)
43761
43852
  let sstype = (substruct[k].Sheet) ? 2 : 1;
43762
- let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
43763
- let to = pos2resi[substruct[k].To - 1];
43853
+ // let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
43854
+ // let to = pos2resi[substruct[k].To - 1];
43764
43855
 
43765
43856
  // 1-based residue numbers
43766
43857
  let fromPos = substruct[k].From;
43767
43858
  let toPos = substruct[k].To;
43768
43859
 
43769
- let residFrom = chnid + "_" + from;
43860
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
43770
43861
  let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
43862
+
43771
43863
  if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
43772
43864
 
43773
- let residTo = chnid + "_" + to;
43865
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
43774
43866
  let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
43775
43867
  if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
43776
43868
 
@@ -43782,45 +43874,170 @@ class Domain3d {
43782
43874
  }
43783
43875
  }
43784
43876
  }
43785
- jsonStr += ']';
43877
+ }
43878
+ jsonStr += ']';
43879
+
43880
+ // domain
43881
+ jsonStr += ', "domain": [';
43882
+ let domainCnt = 0;
43883
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
43786
43884
 
43787
- // domain
43788
- jsonStr += ', "domain": [';
43789
- let domainCnt = 0;
43790
- for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
43791
- let start = subdomains[i][j];
43792
- let end = subdomains[i][j + 1];
43885
+ // resi should be the continuous number starting from 1. make this correction in the backend
43886
+ for(let j = startAll; j <= endAll; ++j) {
43887
+ let ncbiResid = chnid + '_' + j;
43888
+ let resid = ic.ncbi2resid[ncbiResid];
43889
+
43890
+ let pos = j;
43793
43891
 
43794
- for(let k = 0, kl = residueArray.length; k < kl; ++k) {
43795
- let resid = residueArray[k];
43892
+ if(domainCnt > 0) jsonStr += ', ';
43893
+
43894
+ if(!residueHash.hasOwnProperty(resid)) {
43895
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
43896
+ }
43897
+ else {
43898
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43899
+
43900
+ //domain: resi, restype, x, y, z
43901
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
43902
+
43903
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
43904
+ }
43905
+
43906
+ ++domainCnt;
43907
+ }
43908
+ jsonStr += ']}';
43796
43909
 
43797
- // let resi = resid.substr(resid.lastIndexOf('_') + 1);
43798
- // let residNCBI = ic.resid2ncbi[resid];
43799
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
43800
- let pos = k + 1;
43910
+ jsonStr += ']}';
43911
+
43912
+ return jsonStr;
43913
+ }
43914
+ */
43915
+ // this function works for atoms in a single chain
43916
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
43917
+ // let result = this.c2b_NewSplitChain(atoms);
43918
+
43919
+ // let subdomains = result.subdomains;
43920
+ // let substruct = result.substruct;
43921
+
43922
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
43923
+ let residueArray = Object.keys(residueHash);
43924
+ let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
43925
+
43926
+ // let resid1 = residueArray[0];
43927
+ // let resid2 = residueArray[residueArray.length - 1];
43928
+ // let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
43929
+ // let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
43930
+ // let startAll = parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1));
43931
+ // let endAll = parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1));
43932
+
43933
+ let substruct = [];
43934
+ let substructItem = {};
43935
+ let pos2resi = {}; // 0-based
43936
+ let startAll = 999, endAll = -999;
43937
+ for(let i = 0; i < residueArray.length; ++i) {
43938
+ let resid = residueArray[i];
43939
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43940
+
43941
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
43942
+ pos2resi[i] = resi;
43943
+
43944
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
43945
+ let ncbiresi = parseInt(ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1));
43946
+
43947
+ if(ncbiresi < startAll) startAll = ncbiresi;
43948
+ if(ncbiresi > endAll) endAll = ncbiresi;
43949
+
43950
+ if(atom.ssend) {
43951
+ substructItem.To = i + 1;
43952
+ substructItem.x2 = atom.coord.x;
43953
+ substructItem.y2 = atom.coord.y;
43954
+ substructItem.z2 = atom.coord.z;
43955
+
43956
+ substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
43957
+
43958
+ substruct.push(substructItem);
43959
+ substructItem = {};
43960
+ }
43961
+
43962
+ // a residue could be both start and end. check ssend first, then check ssbegin
43963
+ if(atom.ssbegin) {
43964
+ substructItem.From = i + 1;
43965
+ substructItem.x1 = atom.coord.x;
43966
+ substructItem.y1 = atom.coord.y;
43967
+ substructItem.z1 = atom.coord.z;
43968
+ }
43969
+ }
43970
+
43971
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43972
+
43973
+ // 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], ...]} ] }
43974
+ let jsonStr = '{"data": [';
43975
+ //merge all subdomains into one domain
43976
+ jsonStr += '{"ss": ['; //secondary structure
43977
+
43978
+ let ssCnt = 0;
43979
+ for(let k = 0, kl = substruct.length; k < kl; ++k) {
43980
+ //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
43981
+ //sstype: 1 (helix), 2 (sheet)
43982
+ let sstype = (substruct[k].Sheet) ? 2 : 1;
43983
+
43984
+ // 1-based residue numbers
43985
+ let fromPos = substruct[k].From;
43986
+ let toPos = substruct[k].To;
43987
+
43988
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
43989
+ let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
43990
+ if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
43991
+
43992
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
43993
+ let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
43994
+ if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
43995
+
43996
+ // if(fromPos >= start && toPos <= end) {
43997
+ if(ssCnt > 0) jsonStr += ', ';
43998
+ jsonStr += '[' + sstype + ',' + fromPos + ',' + toPos + ',' + substruct[k].x1.toFixed(2) + ',' + substruct[k].y1.toFixed(2) + ','
43999
+ + substruct[k].z1.toFixed(2) + ',' + substruct[k].x2.toFixed(2) + ',' + substruct[k].y2.toFixed(2) + ',' + substruct[k].z2.toFixed(2) + ']';
44000
+ ++ssCnt;
44001
+ // }
44002
+ }
44003
+
44004
+ jsonStr += ']';
43801
44005
 
43802
- //let resid = chnid + "_" + resi;
43803
- let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43804
-
43805
- if(!atom) continue;
43806
- if(!ic.hAtoms.hasOwnProperty(atom.serial)) continue;
43807
-
43808
- //domain: resi, restype, x, y, z
43809
- let restype = me.parasCls.resn2restype[atom.resn];
43810
- if(restype !== undefined && pos >= start && pos <= end) {
43811
- if(domainCnt > 0) jsonStr += ', ';
43812
- jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ','
43813
- + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
43814
- ++domainCnt;
43815
- }
43816
- }
44006
+ // domain
44007
+ jsonStr += ', "domain": [';
44008
+ let domainCnt = 0;
44009
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
44010
+
44011
+ // resi should be the continuous number starting from 1. make this correction in the backend
44012
+ for(let j = startAll; j <= endAll; ++j) {
44013
+ let ncbiResid = chnid + '_' + j;
44014
+ let resid = ic.ncbi2resid[ncbiResid];
44015
+
44016
+ let pos = j;
44017
+
44018
+ if(domainCnt > 0) jsonStr += ', ';
44019
+
44020
+ if(!residueHash.hasOwnProperty(resid)) {
44021
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
44022
+ }
44023
+ else {
44024
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44025
+
44026
+ //domain: resi, restype, x, y, z
44027
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
44028
+
44029
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
43817
44030
  }
43818
- jsonStr += ']}';
44031
+
44032
+ ++domainCnt;
43819
44033
  }
43820
44034
  jsonStr += ']}';
43821
44035
 
44036
+ jsonStr += ']}';
44037
+
43822
44038
  return jsonStr;
43823
44039
  }
44040
+
43824
44041
  }
43825
44042
 
43826
44043
  /**
@@ -45926,7 +46143,6 @@ class Annotation {
45926
46143
  if($("#" + ic.pre + "anno_transmem").length) $("#" + ic.pre + "anno_transmem")[0].checked = false;
45927
46144
  }
45928
46145
  async setAnnoTabIg(bSelection, template) { let ic = this.icn3d; ic.icn3dui;
45929
-
45930
46146
  await this.updateIg(bSelection, template);
45931
46147
 
45932
46148
  $("[id^=" + ic.pre + "ig]").show();
@@ -46267,7 +46483,7 @@ class Annotation {
46267
46483
 
46268
46484
  async updateIg(bSelection, template) { let ic = this.icn3d, me = ic.icn3dui;
46269
46485
  ic.opts['color'] = 'ig strand';
46270
-
46486
+
46271
46487
  // if(!bSelection && !template) {
46272
46488
  if(!bSelection) {
46273
46489
  // select all protein chains
@@ -46286,11 +46502,13 @@ class Annotation {
46286
46502
  }
46287
46503
 
46288
46504
  ic.bRunRefnumAgain = true;
46289
- for(let chainid in ic.protein_chainid) {
46505
+ let chainidHash = (!bSelection) ? ic.protein_chainid : ic.firstAtomObjCls.getChainsFromAtoms(ic.hAtoms);
46506
+ for(let chainid in chainidHash) {
46507
+ // showIgRefNum() in showIg() runs for all chains
46290
46508
  await ic.annoIgCls.showIg(chainid, template);
46291
46509
  ic.bRunRefnumAgain = false; // run it once for all chains
46292
46510
  }
46293
-
46511
+
46294
46512
  if(ic.bShowRefnum) {
46295
46513
  ic.hlUpdateCls.updateHlAll();
46296
46514
  ic.drawCls.draw();
@@ -48037,8 +48255,9 @@ class HlSeq {
48037
48255
  residueid = ic.ncbi2resid[residNCBI];
48038
48256
  }
48039
48257
  else if($(that).attr('3ddomain') !== undefined) {
48040
- // the position of residues with coordinates
48041
- residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
48258
+ // NCBI residue numbers
48259
+ // residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
48260
+ residueid = ic.ncbi2resid[chainid + '_' + j];
48042
48261
  }
48043
48262
  else {
48044
48263
  residueid = chainid + '_' + (j+1).toString();
@@ -48286,7 +48505,7 @@ class HlUpdate {
48286
48505
  }
48287
48506
 
48288
48507
  //Remove the highlight in the 2D interaction diagram.
48289
- removeHl2D() { let ic = this.icn3d; ic.icn3dui;
48508
+ removeHl2D(bRemoveChainOnly) { let ic = this.icn3d; ic.icn3dui;
48290
48509
  // clear nodes in 2d dgm
48291
48510
  $("#" + ic.pre + "dl_2ddgm rect").attr('stroke', '#000000');
48292
48511
  $("#" + ic.pre + "dl_2ddgm circle").attr('stroke', '#000000');
@@ -48300,6 +48519,22 @@ class HlUpdate {
48300
48519
  $("#" + ic.pre + "dl_2ddgm svg line").attr('stroke', '#000000');
48301
48520
  $("#" + ic.pre + "dl_2ddgm line").attr('stroke-width', 1);
48302
48521
  }
48522
+
48523
+ if(!bRemoveChainOnly) {
48524
+ // clear nodes in 2d interaction network
48525
+ // $("#" + ic.pre + "dl_linegraph rect").attr('stroke', '#000000');
48526
+ $("#" + ic.pre + "dl_linegraph circle").attr('stroke', '#000000');
48527
+
48528
+ // $("#" + ic.pre + "dl_linegraph rect").attr('stroke-width', 1);
48529
+ $("#" + ic.pre + "dl_linegraph circle").attr('stroke-width', 1);
48530
+
48531
+ // clear nodes in 2d interaction graph
48532
+ $("#" + ic.pre + "dl_scatterplot rect").attr('stroke', '#000000');
48533
+ $("#" + ic.pre + "dl_scatterplot circle").attr('stroke', '#000000');
48534
+
48535
+ $("#" + ic.pre + "dl_scatterplot rect").attr('stroke-width', 1);
48536
+ $("#" + ic.pre + "dl_scatterplot circle").attr('stroke-width', 1);
48537
+ }
48303
48538
  }
48304
48539
 
48305
48540
  //Remove the selection in the menu of defined sets.
@@ -48397,7 +48632,7 @@ class HlUpdate {
48397
48632
  // update highlight in 2D window
48398
48633
  //Update the highlight of 2D interaction diagram according to the current highlighted atoms.
48399
48634
  updateHl2D(chainArray2d) { let ic = this.icn3d, me = ic.icn3dui;
48400
- this.removeHl2D();
48635
+ this.removeHl2D(true);
48401
48636
 
48402
48637
  if(ic.hAtoms && ic.atoms && Object.keys(ic.hAtoms).length == Object.keys(ic.atoms).length) return;
48403
48638
 
@@ -48722,7 +48957,7 @@ class LineGraph {
48722
48957
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
48723
48958
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
48724
48959
  let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
48725
- let linkedNodeCnt = {}, linkedNodeInterDiff = {};
48960
+ let linkedNodeCnt = {}, linkedNodeInterDiff = {}, linkedNodeInterDiffBool = {};
48726
48961
 
48727
48962
  for(let i = 0, il = structureArray.length; i < il; ++i) {
48728
48963
  nodeArray1Split[i] = [];
@@ -48781,13 +49016,15 @@ class LineGraph {
48781
49016
  linkedNodeInterDiff[mappingid] = link.n;
48782
49017
  }
48783
49018
  else {
48784
- ++linkedNodeCnt[mappingid];
48785
- linkedNodeInterDiff[mappingid] -= link.n; // show difference
49019
+ ++linkedNodeCnt[mappingid];
49020
+ linkedNodeInterDiff[mappingid] += link.n;
49021
+
49022
+ linkedNodeInterDiffBool[mappingid] = (linkedNodeInterDiff[mappingid] / link.n == linkedNodeCnt[mappingid]) ? 0 : 1;
48786
49023
  }
48787
49024
  }
48788
49025
  }
48789
49026
  }
48790
-
49027
+
48791
49028
  // do not combine with the above section since linkedNodeCnt was pre-populated above
48792
49029
  // set linkArraySplitCommon and nameHashSplitCommon
48793
49030
  // set linkArraySplitDiff and nameHashSplitDiff
@@ -48822,6 +49059,8 @@ class LineGraph {
48822
49059
  && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
48823
49060
  mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
48824
49061
  mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
49062
+
49063
+ let bIgRef = (mapping1.length > 4 && !isNaN(parseInt(mapping1.substr(-4, 4)))) || (mapping2.length > 4 && !isNaN(parseInt(mapping2.substr(-4, 4))));
48825
49064
 
48826
49065
  let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
48827
49066
 
@@ -48833,7 +49072,7 @@ class LineGraph {
48833
49072
  linkDiff.source += separatorDiff + ic.chainsMapping[chainid1][resid1];
48834
49073
  linkDiff.target += separatorDiff + ic.chainsMapping[chainid2][resid2];
48835
49074
 
48836
- if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiff[mappingid] == 0) {
49075
+ if(linkedNodeCnt[mappingid] == structureArray.length && (bIgRef || linkedNodeInterDiffBool[mappingid] == 0)) {
48837
49076
  linkArraySplitCommon[index].push(linkCommon);
48838
49077
  }
48839
49078
  else {
@@ -49530,18 +49769,20 @@ class GetGraph {
49530
49769
  return lineGraphStr;
49531
49770
  }
49532
49771
 
49533
- updateGraphColor() { let ic = this.icn3d, me = ic.icn3dui;
49772
+ updateGraphColor() { let ic = this.icn3d; ic.icn3dui;
49534
49773
  // change graph color
49535
49774
 
49775
+ // do not update the graph for now
49776
+ /*
49536
49777
  if(ic.graphStr !== undefined) {
49537
49778
  let graphJson = JSON.parse(ic.graphStr);
49538
- let resid2color = {};
49779
+ let resid2color = {}
49539
49780
  for(let resid in ic.residues) {
49540
49781
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
49541
49782
  resid2color[resid] = atom.color.getHexString().toUpperCase();
49542
49783
  }
49543
49784
 
49544
- let target2resid = {};
49785
+ let target2resid = {}
49545
49786
  for(let i = 0, il = graphJson.nodes.length; i < il; ++i) {
49546
49787
  let node = graphJson.nodes[i];
49547
49788
  //node.r: 1_1_1KQ2_A_1
@@ -49570,6 +49811,7 @@ class GetGraph {
49570
49811
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
49571
49812
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
49572
49813
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
49814
+ */
49573
49815
  }
49574
49816
 
49575
49817
  handleForce() { let ic = this.icn3d, me = ic.icn3dui;
@@ -51733,7 +51975,7 @@ class ContactMap {
51733
51975
 
51734
51976
  let graphStr = '{\n';
51735
51977
 
51736
- let struc1 = (ic.structures.length > 0) ? ic.structures[0] : ic.defaultPdbId;
51978
+ let struc1 = (Object.keys(ic.structures).length > 0) ? ic.structures[0] : ic.defaultPdbId;
51737
51979
  let len1 = nodeArray1.length,
51738
51980
  len2 = nodeArray2.length;
51739
51981
  let factor = 1;
@@ -52267,6 +52509,7 @@ class ChainalignParser {
52267
52509
  let allPromise = Promise.allSettled(ajaxArray);
52268
52510
  // try {
52269
52511
  let dataArray = await allPromise;
52512
+
52270
52513
  await thisClass.downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray, indexArray, mmdbid_t, struArray);
52271
52514
  // }
52272
52515
  // catch(err) {
@@ -52870,13 +53113,13 @@ class ChainalignParser {
52870
53113
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
52871
53114
  && align !== undefined && JSON.stringify(align).indexOf('Oops there was a problem') === -1
52872
53115
  ) {
52873
- if((align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53116
+ if((align === "error" || align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
52874
53117
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
52875
53118
  ic.q_trans_sub[index] = {"x":0, "y":0, "z":0};
52876
53119
  ic.q_rotation[index] = {"x1":1, "y1":0, "z1":0, "x2":0, "y2":1, "z2":0, "x3":0, "y3":0, "z3":1};
52877
53120
  ic.qt_start_end[index] = undefined;
52878
53121
  }
52879
- else if(align === undefined || align.length == 0) {
53122
+ else if(align === "error" || align === undefined || align.length == 0) {
52880
53123
  if(!me.cfg.command && !bNoAlert) var aaa = 1; //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.');
52881
53124
 
52882
53125
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
@@ -52907,14 +53150,16 @@ class ChainalignParser {
52907
53150
  ic.qt_start_end[index] = align[0].segs;
52908
53151
 
52909
53152
  let rmsd = align[0].super_rmsd;
53153
+ let rmsdStr = (rmsd) ? rmsd.toPrecision(4) : rmsd;
53154
+ let scoreStr = (align[0].score) ? align[0].score.toPrecision(4) : align[0].score;
52910
53155
 
52911
- let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
52912
- if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
53156
+ let logStr = "alignment RMSD: " + rmsdStr;
53157
+ if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + scoreStr;
52913
53158
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
52914
- let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
53159
+ let html = "<br><b>Alignment RMSD</b>: " + rmsdStr + " &#8491;<br>";
52915
53160
  if(me.cfg.aligntool == 'tmalign') {
52916
- html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
52917
- ic.tmscore = align[0].score.toPrecision(4);
53161
+ html += "<b>TM-score</b>: " + scoreStr + "<br><br>";
53162
+ ic.tmscore = scoreStr;
52918
53163
  }
52919
53164
 
52920
53165
  $("#" + ic.pre + "dl_rmsd_html").html(html);
@@ -53061,6 +53306,7 @@ class ChainalignParser {
53061
53306
  let allPromise = Promise.allSettled(ajaxArray);
53062
53307
  // try {
53063
53308
  let dataArray = await allPromise;
53309
+
53064
53310
  await thisClass.parseMMdbAfData(dataArray, structArray, bQuery, vastplusAtype);
53065
53311
  if(vastplusAtype === undefined) ic.ParserUtilsCls.hideLoading();
53066
53312
  // }
@@ -53093,13 +53339,9 @@ class ChainalignParser {
53093
53339
 
53094
53340
  //if(!ic.bCommandLoad && !bQuery) ic.init(); // remove all previously loaded data
53095
53341
 
53096
- let hAtoms = {}, hAtomsTmp = {};
53342
+ let hAtoms = {};
53097
53343
  let bLastQuery = false;
53098
53344
 
53099
- let opts = {};
53100
-
53101
- opts['color'] = (structArray.length > 1) ? 'structure' : ((structArray[0].length > 5) ? 'confidence' : 'chain');
53102
-
53103
53345
  for(let i = 0, il = structArray.length; i < il; ++i) {
53104
53346
  if(i == structArray.length - 1) bLastQuery = true;
53105
53347
 
@@ -53114,24 +53356,30 @@ class ChainalignParser {
53114
53356
  targetOrQuery = 'query';
53115
53357
  bAppend = true;
53116
53358
  }
53117
-
53359
+
53118
53360
  //if(structArray[i].length > 4) {
53119
53361
  if(isNaN(structArray[i]) && structArray[i].length > 5) { // PDB ID plus postfix could be 5
53120
53362
  //let bNoDssp = true;
53121
53363
  let bNoDssp = false; // get secondary structure info
53122
- hAtomsTmp = await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
53364
+ await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
53123
53365
  }
53124
53366
  else {
53125
53367
  let bNoSeqalign = true;
53126
53368
  let pdbid = structArray[i];
53127
- hAtomsTmp = await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
53369
+
53370
+ //hAtomsTmp contains all atoms
53371
+ await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
53128
53372
  }
53129
53373
 
53130
- hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
53374
+ // hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
53131
53375
  }
53132
53376
 
53133
- // add color only for the newly loaded structures
53134
- ic.setColorCls.setColorByOptions(opts, hAtoms);
53377
+ let structArrayAll = Object.keys(ic.structures);
53378
+
53379
+ ic.opts['color'] = (structArrayAll.length > 1) ? 'structure' : ((structArrayAll[0].length > 5) ? 'confidence' : 'chain');
53380
+
53381
+ // add color for all structures
53382
+ ic.setColorCls.setColorByOptions(ic.opts, hAtoms);
53135
53383
 
53136
53384
  await ic.ParserUtilsCls.renderStructure();
53137
53385
 
@@ -53161,15 +53409,6 @@ class ChainalignParser {
53161
53409
  if(vastplusAtype == 2) me.cfg.aligntool = 'tmalign';
53162
53410
  await ic.vastplusCls.vastplusAlign(structArray, vastplusAtype);
53163
53411
  }
53164
-
53165
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
53166
-
53167
- // if(Object.keys(ic.structures).length == 1 && me.cfg.mmdbafid.length > 5) {
53168
- // ic.ParserUtilsCls.checkMemProtein(me.cfg.mmdbafid);
53169
- // }
53170
- // else {
53171
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
53172
- // }
53173
53412
  }
53174
53413
  }
53175
53414
 
@@ -54637,24 +54876,32 @@ class MmcifParser {
54637
54876
  if(data.emd !== undefined) ic.emd = data.emd;
54638
54877
  if(data.organism !== undefined) ic.organism = data.organism;
54639
54878
 
54640
- if(ic.emd !== undefined) {
54641
- $("#" + ic.pre + "mapWrapper1").hide();
54642
- $("#" + ic.pre + "mapWrapper2").hide();
54643
- $("#" + ic.pre + "mapWrapper3").hide();
54644
- }
54645
- else {
54646
- $("#" + ic.pre + "emmapWrapper1").hide();
54647
- $("#" + ic.pre + "emmapWrapper2").hide();
54648
- $("#" + ic.pre + "emmapWrapper3").hide();
54649
- }
54650
-
54651
54879
  await ic.opmParserCls.loadOpmData(data, mmcifid, undefined, 'mmcif');
54880
+
54881
+ ic.opmParserCls.modifyUIMapAssembly();
54652
54882
  }
54653
54883
  else {
54654
- //var aaa = 1; //alert('invalid atoms data.');
54655
54884
  return false;
54656
54885
  }
54657
54886
  }
54887
+
54888
+ async loadMultipleMmcifData(data, mmcifid, bAppend) { let ic = this.icn3d; ic.icn3dui;
54889
+ let bText = true;
54890
+ ic.loadCIFCls.loadCIF(data, mmcifid, bText, bAppend);
54891
+
54892
+ if(Object.keys(ic.structures).length > 1) {
54893
+ ic.opts['color'] = 'structure';
54894
+ }
54895
+
54896
+ ic.opmParserCls.modifyUIMapAssembly();
54897
+
54898
+ ic.pdbParserCls.addSecondary(bAppend);
54899
+
54900
+ // ic.setStyleCls.setAtomStyleByOptions(ic.opts);
54901
+ // ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
54902
+
54903
+ // await ic.ParserUtilsCls.renderStructure();
54904
+ }
54658
54905
  }
54659
54906
 
54660
54907
  /**
@@ -55497,26 +55744,26 @@ class BcifParser {
55497
55744
  let molecueType;
55498
55745
  if(atom_hetatm == "ATOM") {
55499
55746
  if(resn.length == 3) {
55500
- molecueType = "p"; // protein
55747
+ molecueType = "protein"; //"p"; // protein
55501
55748
  }
55502
55749
  else {
55503
- molecueType = "n"; // nucleotide
55750
+ molecueType = "nucleotide"; //"n"; // nucleotide
55504
55751
  }
55505
55752
  }
55506
55753
  else {
55507
55754
  if(resn == "WAT" || resn == "HOH") {
55508
- molecueType = "s"; // solvent
55755
+ molecueType = "solvent"; //"s"; // solvent
55509
55756
  chain = 'Misc';
55510
55757
  }
55511
55758
  else {
55512
- molecueType = "l"; // ligands or ions
55759
+ molecueType = "ligand"; //"l"; // ligands or ions
55513
55760
  chain = resn;
55514
55761
  }
55515
55762
  }
55516
55763
 
55517
55764
  // C-alpha only for large structure
55518
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
55519
- || (molecueType == "n" && !(name == "P")) ) ) continue;
55765
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
55766
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
55520
55767
  // skip alternative atoms
55521
55768
  if(alt == "B") continue;
55522
55769
 
@@ -55539,7 +55786,7 @@ class BcifParser {
55539
55786
  // }
55540
55787
  }
55541
55788
 
55542
- if(molecueType == 's' || molecueType == "l") {
55789
+ if(molecueType == 'solvent' || molecueType == "ligand") {
55543
55790
  let seq = {};
55544
55791
  if(!ligSeqHash.hasOwnProperty(chain)) {
55545
55792
  ligSeqHash[chain] = [];
@@ -55677,26 +55924,26 @@ class BcifParser {
55677
55924
  let molecueType;
55678
55925
  if(atom_hetatm == "ATOM") {
55679
55926
  if(resn.length == 3) {
55680
- molecueType = "p"; // protein
55927
+ molecueType = "protein"; // protein
55681
55928
  }
55682
55929
  else {
55683
- molecueType = "n"; // nucleotide
55930
+ molecueType = "nucleotide"; // nucleotide
55684
55931
  }
55685
55932
  }
55686
55933
  else {
55687
55934
  if(resn == "WAT" || resn == "HOH") {
55688
- molecueType = "s"; // solvent
55935
+ molecueType = "solvent"; // solvent
55689
55936
  chain = 'Misc';
55690
55937
  }
55691
55938
  else {
55692
- molecueType = "l"; // ligands or ions
55939
+ molecueType = "ligand"; // ligands or ions
55693
55940
  chain = resn;
55694
55941
  }
55695
55942
  }
55696
55943
 
55697
55944
  // C-alpha only for large structure
55698
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
55699
- || (molecueType == "n" && !(name == "P")) ) ) continue;
55945
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
55946
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
55700
55947
  // skip alternative atoms
55701
55948
  if(alt == "B") continue;
55702
55949
 
@@ -56246,6 +56493,43 @@ class OpmParser {
56246
56493
  }
56247
56494
  }
56248
56495
 
56496
+ modifyUIMapAssembly() { let ic = this.icn3d, me = ic.icn3dui;
56497
+ if(!me.bNode) {
56498
+ if(ic.emd !== undefined) {
56499
+ $("#" + ic.pre + "mapWrapper1").hide();
56500
+ $("#" + ic.pre + "mapWrapper2").hide();
56501
+ $("#" + ic.pre + "mapWrapper3").hide();
56502
+ }
56503
+ else {
56504
+ $("#" + ic.pre + "emmapWrapper1").hide();
56505
+ $("#" + ic.pre + "emmapWrapper2").hide();
56506
+ $("#" + ic.pre + "emmapWrapper3").hide();
56507
+ }
56508
+
56509
+ if(Object.keys(ic.structures).length == 1) {
56510
+ $("#" + ic.pre + "alternateWrapper").hide();
56511
+ }
56512
+ /*
56513
+ // load assembly info
56514
+ if(type === 'mmcif') {
56515
+ let assembly =(data.assembly !== undefined) ? data.assembly : [];
56516
+ for(let i = 0, il = assembly.length; i < il; ++i) {
56517
+ if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
56518
+
56519
+ for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
56520
+ ic.biomtMatrices[i].elements[j] = assembly[i][j];
56521
+ }
56522
+ }
56523
+ }
56524
+ */
56525
+ if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
56526
+ $("#" + ic.pre + "assemblyWrapper").show();
56527
+
56528
+ ic.asuCnt = ic.biomtMatrices.length;
56529
+ }
56530
+ }
56531
+ }
56532
+
56249
56533
  async parseAtomData(data, pdbid, bFull, type, pdbid2, bText) { let ic = this.icn3d, me = ic.icn3dui;
56250
56534
  /*
56251
56535
  if(type === 'mmtf') {
@@ -56262,38 +56546,7 @@ class OpmParser {
56262
56546
  ic.loadCIFCls.loadCIF(data, pdbid, bText);
56263
56547
  // }
56264
56548
 
56265
- if(ic.emd !== undefined) {
56266
- $("#" + ic.pre + "mapWrapper1").hide();
56267
- $("#" + ic.pre + "mapWrapper2").hide();
56268
- $("#" + ic.pre + "mapWrapper3").hide();
56269
- }
56270
- else {
56271
- $("#" + ic.pre + "emmapWrapper1").hide();
56272
- $("#" + ic.pre + "emmapWrapper2").hide();
56273
- $("#" + ic.pre + "emmapWrapper3").hide();
56274
- }
56275
-
56276
- if(Object.keys(ic.structures).length == 1) {
56277
- $("#" + ic.pre + "alternateWrapper").hide();
56278
- }
56279
- /*
56280
- // load assembly info
56281
- if(type === 'mmcif') {
56282
- let assembly =(data.assembly !== undefined) ? data.assembly : [];
56283
- for(let i = 0, il = assembly.length; i < il; ++i) {
56284
- if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
56285
-
56286
- for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
56287
- ic.biomtMatrices[i].elements[j] = assembly[i][j];
56288
- }
56289
- }
56290
- }
56291
- */
56292
- if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
56293
- $("#" + ic.pre + "assemblyWrapper").show();
56294
-
56295
- ic.asuCnt = ic.biomtMatrices.length;
56296
- }
56549
+ this.modifyUIMapAssembly();
56297
56550
 
56298
56551
  ic.setStyleCls.setAtomStyleByOptions(ic.opts);
56299
56552
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
@@ -56487,6 +56740,12 @@ class PdbParser {
56487
56740
  }
56488
56741
  }
56489
56742
 
56743
+ await this.addSecondary(bAppend, bNoDssp);
56744
+
56745
+ return hAtoms;
56746
+ }
56747
+
56748
+ async addSecondary(bAppend, bNoDssp) { let ic = this.icn3d, me = ic.icn3dui;
56490
56749
  // calculate secondary structures if not available
56491
56750
  // DSSP only works for structures with all atoms. The Calpha only structures didn't work
56492
56751
  //if(!ic.bSecondaryStructure && !bCalphaOnly) {
@@ -56510,8 +56769,6 @@ class PdbParser {
56510
56769
 
56511
56770
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
56512
56771
  }
56513
-
56514
- return hAtoms;
56515
56772
  }
56516
56773
 
56517
56774
  async applyCommandDssp(bAppend) { let ic = this.icn3d, me = ic.icn3dui;
@@ -57349,23 +57606,27 @@ class RealignParser {
57349
57606
 
57350
57607
  for(let s = 0, sl = structArray.length; s < sl; ++s) {
57351
57608
  let struct1 = structArray[s];
57609
+
57352
57610
  let chainidArray1 = Object.keys(struct2domain[struct1]);
57353
57611
  if(chainidArray1.length == 0) continue;
57354
- for(let t = s+1, tl = structArray.length; t < tl; ++t) {
57355
- let struct2 = structArray[t];
57356
- let chainidArray2 = Object.keys(struct2domain[struct2]);
57357
- if(chainidArray2.length == 0) continue;
57358
-
57359
- for(let i = 0, il = chainidArray1.length; i < il; ++i) {
57360
- let chainid1 = chainidArray1[i];
57361
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
57612
+
57613
+ for(let i = 0, il = chainidArray1.length; i < il; ++i) {
57614
+ let chainid1 = chainidArray1[i];
57615
+ let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
57616
+
57617
+ for(let t = s+1, tl = structArray.length; t < tl; ++t) {
57618
+ let struct2 = structArray[t];
57619
+
57620
+ let chainidArray2 = Object.keys(struct2domain[struct2]);
57621
+ if(chainidArray2.length == 0) continue;
57622
+
57362
57623
  for(let j = 0, jl = chainidArray2.length; j < jl; ++j) {
57363
57624
  let chainid2 = chainidArray2[j];
57364
57625
 
57365
57626
  let alignAjax;
57366
57627
  if(me.cfg.aligntool != 'tmalign') {
57367
57628
  let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct2][chainid2]);
57368
-
57629
+
57369
57630
  let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
57370
57631
  alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
57371
57632
  }
@@ -57390,7 +57651,14 @@ class RealignParser {
57390
57651
 
57391
57652
  let allPromise = Promise.allSettled(ajaxArray);
57392
57653
  // try {
57654
+ // let dataArray = await allPromise;
57655
+
57656
+ let startDate = new Date();
57393
57657
  let dataArray = await allPromise;
57658
+ let endDate = new Date();
57659
+ let miliseconds = (endDate.getTime() - startDate.getTime());
57660
+ console.log("vastdyn time: " + miliseconds + " miliseconds");
57661
+
57394
57662
  ic.qt_start_end = []; // reset the alignment
57395
57663
  await ic.chainalignParserCls.downloadChainalignmentPart2bRealign(dataArray, chainidPairArray, bReverse);
57396
57664
  // }
@@ -59614,6 +59882,7 @@ class LoadAtomData {
59614
59882
 
59615
59883
  //This function was used to parse atom "data" to set up parameters for the 3D viewer. "type" is mmcifid or mmdbid.
59616
59884
  //"id" is the MMDB ID or mmCIF ID.
59885
+ // thi sfunction is NOT used for mmCIF loading any more
59617
59886
  loadAtomDataIn(data, id, type, seqalign, alignType, chainidInput, chainIndex, bLastQuery, bNoSeqalign) { let ic = this.icn3d, me = ic.icn3dui;
59618
59887
  //ic.init();
59619
59888
  ic.pmin = new THREE.Vector3( 9999, 9999, 9999);
@@ -59757,13 +60026,6 @@ class LoadAtomData {
59757
60026
  if(ic.pdbid_chain2title === undefined) ic.pdbid_chain2title = {};
59758
60027
  ic.pdbid_chain2title[chainid] = data.moleculeInfor[molid].name;
59759
60028
 
59760
- //if(alignType == 'query' && chain == ic.chain_q) {
59761
- // ic.alignmolid2color[0][molid] = molidCnt.toString();
59762
- //}
59763
- //else if(alignType == 'target' && chain == ic.chain_t) {
59764
- // ic.alignmolid2color[1][molid] = molidCnt.toString();
59765
- //}
59766
-
59767
60029
  if(chain == chainid.substr(chainid.lastIndexOf('_')) ) {
59768
60030
  let tmpHash = {};
59769
60031
  tmpHash[molid] = molidCnt.toString();
@@ -59955,17 +60217,15 @@ class LoadAtomData {
59955
60217
  ic.pmin.min(atm.coord);
59956
60218
  ic.pmax.max(atm.coord);
59957
60219
  ic.psum.add(atm.coord);
59958
-
59959
- let bNonMmcif = (me.cfg.mmcifid === undefined && me.cfg.mmtfid === undefined && me.cfg.bcifid === undefined && ic.InputfileType != 'mmcif');
59960
- let bProtein = (bNonMmcif) ? chainid2kind[chainNum] === 'protein' : atm.mt === 'p';
59961
- let bNucleotide = (bNonMmcif) ? chainid2kind[chainNum] === 'nucleotide' : atm.mt === 'n';
59962
- let bSolvent = (bNonMmcif) ? chainid2kind[chainNum] === 'solvent' : atm.mt === 's';
60220
+ let bProtein = chainid2kind[chainNum] === 'protein' ;
60221
+ let bNucleotide = chainid2kind[chainNum] === 'nucleotide' ;
60222
+ let bSolvent = chainid2kind[chainNum] === 'solvent' ;
59963
60223
  // in vastplus.cgi, ions arenotlisted in alignedStructures...molecules, thus chainid2kind[chainNum] === undefined is used.
59964
60224
  // ions will be separated from chemicals later.
59965
60225
  // here "ligand" is used in the cgi output
59966
60226
  //var bChemicalIons =(me.cfg.mmcifid === undefined) ?(chainid2kind[chainNum] === 'ligand' || chainid2kind[chainNum] === 'otherPolymer' || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
59967
60227
  // kind: other, otherPolymer, etc
59968
- let bChemicalIons = (bNonMmcif) ? (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
60228
+ let bChemicalIons = (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) ;
59969
60229
 
59970
60230
  if((atm.chain === 'Misc' || chainid2kind[chainNum] === 'other') && biopolymerChainsHash[chainNum] !== 'protein' && biopolymerChainsHash[chainNum] !== 'nucleotide') { // biopolymer, could be protein or nucleotide
59971
60231
  if(atm.name === 'CA' && atm.elem === 'C') {
@@ -60229,18 +60489,17 @@ class LoadAtomData {
60229
60489
 
60230
60490
  // update bonds info
60231
60491
  if(type !== 'mmcifid') {
60232
- //for(let i in ic.atoms) {
60233
- for(let i in atoms) {
60234
- let currSerial = atomid2serial[i];
60492
+ //for(let i in ic.atoms) {
60493
+ for(let i in atoms) {
60494
+ let currSerial = atomid2serial[i];
60235
60495
 
60236
- let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
60496
+ let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
60237
60497
 
60238
- for(let j = 0; j < bondLength; ++j) {
60239
- ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
60498
+ for(let j = 0; j < bondLength; ++j) {
60499
+ ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
60500
+ }
60240
60501
  }
60241
60502
  }
60242
- }
60243
-
60244
60503
  // remove the reference
60245
60504
  data.atoms = {};
60246
60505
 
@@ -60336,7 +60595,7 @@ class LoadAtomData {
60336
60595
  // display the structure right away. load the mns and sequences later
60337
60596
  // setTimeout(function(){
60338
60597
  let hAtoms = {};
60339
-
60598
+
60340
60599
  if(type === 'align' && seqalign !== undefined && ic.bFullUi) {
60341
60600
  ic.setSeqAlignCls.setSeqAlign(seqalign, data.alignedStructures);
60342
60601
  } // if(align
@@ -60359,7 +60618,7 @@ class LoadAtomData {
60359
60618
  hAtoms = ic.hAtoms;
60360
60619
  }
60361
60620
  }
60362
- else if(type === 'mmdbid' && alignType === 'target') {
60621
+ else { //if(type === 'mmdbid' && alignType === 'target') {
60363
60622
  hAtoms = ic.hAtoms;
60364
60623
  }
60365
60624
 
@@ -60693,13 +60952,19 @@ class SetSeqAlign {
60693
60952
  resi = pos;
60694
60953
  }
60695
60954
  else {
60696
- if(ic.posid2resid) {
60697
- let resid = ic.posid2resid[chainid + '_' + pos];
60698
- resi = resid.substr(resid.lastIndexOf('_') + 1);
60699
- }
60700
- else {
60955
+ // if(ic.posid2resid) {
60956
+ // let resid = ic.posid2resid[chainid + '_' + pos];
60957
+ // resi = resid.substr(resid.lastIndexOf('_') + 1);
60958
+ // }
60959
+ // else {
60960
+ // resi = (ic.chainsSeq[chainid][pos].resi) ? ic.chainsSeq[chainid][pos].resi : pos;
60961
+ if(pos > ic.chainsSeq[chainid].length - 1) {
60962
+ console.log("Error: the position " + pos + " exceeds the max index " + (ic.chainsSeq[chainid].length - 1));
60963
+ pos = ic.chainsSeq[chainid].length - 1;
60964
+ }
60965
+
60701
60966
  resi = ic.chainsSeq[chainid][pos].resi;
60702
- }
60967
+ // }
60703
60968
  }
60704
60969
 
60705
60970
  return resi;
@@ -62784,17 +63049,6 @@ class LoadCIF {
62784
63049
  loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
62785
63050
  let hAtoms = {};
62786
63051
 
62787
- // bcifData could be binary or text
62788
- let parsed = (bText) ? CIFTools.Text.parse(bcifData) : CIFTools.Binary.parse(bcifData);
62789
-
62790
- if (parsed.isError) {
62791
- // report error:
62792
- var aaa = 1; //alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
62793
- return;
62794
- }
62795
-
62796
- let block = parsed.result.dataBlocks[0];
62797
-
62798
63052
  let bNMR = false;
62799
63053
  // let lines = src.split('\n');
62800
63054
 
@@ -62830,92 +63084,152 @@ class LoadCIF {
62830
63084
 
62831
63085
  let bFirstAtom = true;
62832
63086
 
62833
- if(block.getCategory("_entry")) {
62834
- id = block.getCategory("_entry").getColumn("id").getString(0);
63087
+ let cifArray = bcifData.split('ENDMDL\n');
62835
63088
 
62836
- if(id == '') {
62837
- if(bAppend) {
62838
- id = ic.defaultPdbId;
62839
- }
62840
- else {
62841
- //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
62842
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
62843
- }
62844
- }
63089
+ for(let index = 0, indexl = cifArray.length; index < indexl; ++index) {
63090
+ ++moleculeNum;
63091
+ id = ic.defaultPdbId;
62845
63092
 
62846
63093
  structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
62847
63094
 
62848
- ic.molTitle = '';
62849
- ic.molTitleHash = {};
62850
- }
62851
-
62852
- if(block.getCategory("_struct")) {
62853
- let title = block.getCategory("_struct").getColumn("title").getString(0);
62854
- title = title.replace(/"/, "'");
62855
- let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
62856
- ic.molTitle += name.trim() + " ";
62857
- // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63095
+ // if(!bNMR) {
63096
+ sheetArray = [];
63097
+ sheetStart = [];
63098
+ sheetEnd = [];
63099
+ helixArray = [];
63100
+ helixStart = [];
63101
+ helixEnd = [];
62858
63102
 
62859
- if(!ic.molTitleHash) ic.molTitleHash = {};
62860
- ic.molTitleHash[structure] = ic.molTitle;
62861
63103
 
62862
- }
63104
+ // bcifData could be binary or text
63105
+ let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
62863
63106
 
62864
- if(block.getCategory("_entity_src_gen")) {
62865
- ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
62866
- }
62867
-
62868
- if(block.getCategory("_database_2")) {
62869
- let database_2 = block.getCategory("_database_2");
62870
-
62871
- // Iterate through every row in the table
62872
- let db2Size = database_2.rowCount ;
62873
- for (let i = 0; i < db2Size; ++i) {
62874
- let db_id = database_2.getColumn("database_id").getString(0);
62875
- let db_code = database_2.getColumn("database_code").getString(0);
63107
+ if (parsed.isError) {
63108
+ // report error:
63109
+ var aaa = 1; //alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
63110
+ return;
63111
+ }
63112
+
63113
+ let block = parsed.result.dataBlocks[0];
62876
63114
 
62877
- if(db_id == "EMDB") {
62878
- ic.emd = db_code;
62879
- break;
63115
+ if(block.getCategory("_entry")) {
63116
+ id = block.getCategory("_entry").getColumn("id").getString(0);
63117
+
63118
+ if(id == '') {
63119
+ if(bAppend) {
63120
+ id = ic.defaultPdbId;
63121
+ }
63122
+ else {
63123
+ //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
63124
+ id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
63125
+ }
62880
63126
  }
63127
+
63128
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63129
+
63130
+ ic.molTitle = '';
63131
+ ic.molTitleHash = {};
62881
63132
  }
62882
- }
63133
+
63134
+ if(block.getCategory("_struct")) {
63135
+ let title = block.getCategory("_struct").getColumn("title").getString(0);
63136
+ title = title.replace(/"/, "'");
63137
+ let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
63138
+ ic.molTitle += name.trim() + " ";
63139
+ // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
62883
63140
 
62884
- if(block.getCategory("_struct_conf")) {
62885
- ic.bSecondaryStructure = true;
63141
+ if(!ic.molTitleHash) ic.molTitleHash = {};
63142
+ ic.molTitleHash[structure] = ic.molTitle;
62886
63143
 
62887
- // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
62888
- let struct_conf = block.getCategory("_struct_conf");
62889
-
62890
- let conf_type_idArray = struct_conf.getColumn("conf_type_id");
62891
-
62892
- let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
62893
- // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
62894
- let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
62895
-
62896
- struct_conf.getColumn("end_auth_asym_id");
62897
- // let resi2Array = struct_conf.getColumn("end_label_seq_id");
62898
- let resi2Array = struct_conf.getColumn("end_auth_seq_id");
62899
-
62900
- // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
62901
- let confSize = struct_conf.rowCount;
62902
- for (let i = 0; i < confSize; ++i) {
62903
- let conf_type_id = conf_type_idArray.getString(i);
63144
+ }
63145
+
63146
+ if(block.getCategory("_entity_src_gen")) {
63147
+ ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
63148
+ }
62904
63149
 
62905
- let startChain = chain1Array.getString(i);
62906
- let startResi = parseInt(resi1Array.getString(i));
62907
- let endResi = parseInt(resi2Array.getString(i));
63150
+ if(block.getCategory("_database_2")) {
63151
+ let database_2 = block.getCategory("_database_2");
62908
63152
 
62909
- if(conf_type_id.substr(0, 4) == "HELX") {
62910
- for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
62911
- let resid = structure + "_" + startChain + "_" + j;
62912
- helixArray.push(resid);
62913
-
62914
- if(j == startResi) helixStart.push(resid);
62915
- if(j == endResi) helixEnd.push(resid);
62916
- }
63153
+ // Iterate through every row in the table
63154
+ let db2Size = database_2.rowCount ;
63155
+ for (let i = 0; i < db2Size; ++i) {
63156
+ let db_id = database_2.getColumn("database_id").getString(0);
63157
+ let db_code = database_2.getColumn("database_code").getString(0);
63158
+
63159
+ if(db_id == "EMDB") {
63160
+ ic.emd = db_code;
63161
+ break;
63162
+ }
62917
63163
  }
62918
- else if(conf_type_id.substr(0, 4) == "STRN") {
63164
+ }
63165
+
63166
+ if(block.getCategory("_struct_conf")) {
63167
+ ic.bSecondaryStructure = true;
63168
+
63169
+ // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
63170
+ let struct_conf = block.getCategory("_struct_conf");
63171
+
63172
+ let conf_type_idArray = struct_conf.getColumn("conf_type_id");
63173
+
63174
+ let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
63175
+ // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
63176
+ let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
63177
+
63178
+ struct_conf.getColumn("end_auth_asym_id");
63179
+ // let resi2Array = struct_conf.getColumn("end_label_seq_id");
63180
+ let resi2Array = struct_conf.getColumn("end_auth_seq_id");
63181
+
63182
+ // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
63183
+ let confSize = struct_conf.rowCount;
63184
+ for (let i = 0; i < confSize; ++i) {
63185
+ let conf_type_id = conf_type_idArray.getString(i);
63186
+
63187
+ let startChain = chain1Array.getString(i);
63188
+ let startResi = parseInt(resi1Array.getString(i));
63189
+ let endResi = parseInt(resi2Array.getString(i));
63190
+
63191
+ if(conf_type_id.substr(0, 4) == "HELX") {
63192
+ for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
63193
+ let resid = structure + "_" + startChain + "_" + j;
63194
+ helixArray.push(resid);
63195
+
63196
+ if(j == startResi) helixStart.push(resid);
63197
+ if(j == endResi) helixEnd.push(resid);
63198
+ }
63199
+ }
63200
+ else if(conf_type_id.substr(0, 4) == "STRN") {
63201
+ for(let j = startResi; j <= endResi; ++j) {
63202
+ let resid = structure + "_" + startChain + "_" + j;
63203
+ sheetArray.push(resid);
63204
+
63205
+ if(j == startResi) sheetStart.push(resid);
63206
+ if(j == endResi) sheetEnd.push(resid);
63207
+ }
63208
+ }
63209
+ }
63210
+
63211
+ conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
63212
+ }
63213
+
63214
+ if(block.getCategory("_struct_sheet_range")) {
63215
+ // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
63216
+ let struct_sheet_range = block.getCategory("_struct_sheet_range");
63217
+
63218
+ let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
63219
+ // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
63220
+ let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
63221
+
63222
+ struct_sheet_range.getColumn("end_auth_asym_id");
63223
+ // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
63224
+ let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
63225
+
63226
+ // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
63227
+ let sheetSize = struct_sheet_range.rowCount;
63228
+ for (let i = 0; i < sheetSize; ++i) {
63229
+ let startChain = chain1Array.getString(i);
63230
+ let startResi = parseInt(resi1Array.getString(i));
63231
+ let endResi = parseInt(resi2Array.getString(i));
63232
+
62919
63233
  for(let j = startResi; j <= endResi; ++j) {
62920
63234
  let resid = structure + "_" + startChain + "_" + j;
62921
63235
  sheetArray.push(resid);
@@ -62924,500 +63238,469 @@ class LoadCIF {
62924
63238
  if(j == endResi) sheetEnd.push(resid);
62925
63239
  }
62926
63240
  }
63241
+
63242
+ chain1Array = resi1Array = resi2Array = [];
62927
63243
  }
62928
-
62929
- conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
62930
- }
62931
-
62932
- if(block.getCategory("_struct_sheet_range")) {
62933
- // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
62934
- let struct_sheet_range = block.getCategory("_struct_sheet_range");
62935
-
62936
- let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
62937
- // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
62938
- let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
62939
-
62940
- struct_sheet_range.getColumn("end_auth_asym_id");
62941
- // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
62942
- let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
62943
-
62944
- // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
62945
- let sheetSize = struct_sheet_range.rowCount;
62946
- for (let i = 0; i < sheetSize; ++i) {
62947
- let startChain = chain1Array.getString(i);
62948
- let startResi = parseInt(resi1Array.getString(i));
62949
- let endResi = parseInt(resi2Array.getString(i));
62950
-
62951
- for(let j = startResi; j <= endResi; ++j) {
62952
- let resid = structure + "_" + startChain + "_" + j;
62953
- sheetArray.push(resid);
62954
-
62955
- if(j == startResi) sheetStart.push(resid);
62956
- if(j == endResi) sheetEnd.push(resid);
62957
- }
62958
- }
62959
-
62960
- chain1Array = resi1Array = resi2Array = [];
62961
- }
62962
63244
 
62963
- if(block.getCategory("_struct_conn")) {
62964
- ic.bSsbondProvided = true;
63245
+ if(block.getCategory("_struct_conn")) {
63246
+ ic.bSsbondProvided = true;
62965
63247
 
62966
- // Retrieve the table corresponding to the struct_conn category, which delineates connections1
62967
- let struct_conn = block.getCategory("_struct_conn");
62968
-
62969
- let conn_type_idArray = struct_conn.getColumn("conn_type_id");
62970
-
62971
- let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
62972
- let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
62973
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
62974
-
62975
- let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
62976
- let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
62977
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
62978
-
62979
- let connSize = struct_conn.rowCount;
62980
- for (let i = 0; i < connSize; ++i) {
62981
- let conn_type_id = conn_type_idArray.getString(i);
63248
+ // Retrieve the table corresponding to the struct_conn category, which delineates connections1
63249
+ let struct_conn = block.getCategory("_struct_conn");
62982
63250
 
62983
- let chain1 = chain1Array.getString(i);
62984
- name1Array.getString(i);
62985
- let resi1 = resi1Array.getString(i);
62986
- let id1 = structure + '_' + chain1 + "_" + resi1;
63251
+ let conn_type_idArray = struct_conn.getColumn("conn_type_id");
62987
63252
 
62988
- let chain2 = chain2Array.getString(i);
62989
- name2Array.getString(i);
62990
- let resi2 = resi2Array.getString(i);
62991
- let id2 = structure + '_' + chain2 + "_" + resi2;
63253
+ let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
63254
+ let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
63255
+ let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
62992
63256
 
62993
- // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
63257
+ let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
63258
+ let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
63259
+ let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
62994
63260
 
62995
- // if (conn_type_id == "covale") {
62996
- // vBonds.push(id1);
62997
- // vBonds.push(id2);
62998
- // }
63261
+ let connSize = struct_conn.rowCount;
63262
+ for (let i = 0; i < connSize; ++i) {
63263
+ let conn_type_id = conn_type_idArray.getString(i);
62999
63264
 
63000
- if(conn_type_id == "disulf") {
63001
- if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
63265
+ let chain1 = chain1Array.getString(i);
63266
+ name1Array.getString(i);
63267
+ let resi1 = resi1Array.getString(i);
63268
+ let id1 = structure + '_' + chain1 + "_" + resi1;
63269
+
63270
+ let chain2 = chain2Array.getString(i);
63271
+ name2Array.getString(i);
63272
+ let resi2 = resi2Array.getString(i);
63273
+ let id2 = structure + '_' + chain2 + "_" + resi2;
63274
+
63275
+ // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
63276
+
63277
+ // if (conn_type_id == "covale") {
63278
+ // vBonds.push(id1);
63279
+ // vBonds.push(id2);
63280
+ // }
63281
+
63282
+ if(conn_type_id == "disulf") {
63283
+ if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
63002
63284
 
63003
- ic.ssbondpnts[structure].push(id1);
63004
- ic.ssbondpnts[structure].push(id2);
63285
+ ic.ssbondpnts[structure].push(id1);
63286
+ ic.ssbondpnts[structure].push(id2);
63287
+ }
63005
63288
  }
63289
+
63290
+ conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63006
63291
  }
63007
-
63008
- conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63009
- }
63010
63292
 
63011
- if(block.getCategory("_exptl")) {
63012
- let method = block.getCategory("_exptl").getColumn("method").getString(0);
63013
- if(method.indexOf('NMR') != -1) {
63014
- bNMR = true;
63293
+ if(block.getCategory("_exptl")) {
63294
+ let method = block.getCategory("_exptl").getColumn("method").getString(0);
63295
+ if(method.indexOf('NMR') != -1) {
63296
+ bNMR = true;
63297
+ }
63015
63298
  }
63016
- }
63017
63299
 
63018
- if(block.getCategory("_pdbx_struct_oper_list")) {
63019
- // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
63020
- let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
63021
-
63022
- let struct_oper_idArray = struct_oper_list.getColumn("id");
63023
- let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63024
- let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63025
- let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63026
- let m14Array = struct_oper_list.getColumn("vector[1]");
63027
-
63028
- let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63029
- let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63030
- let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63031
- let m24Array = struct_oper_list.getColumn("vector[2]");
63032
-
63033
- let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63034
- let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63035
- let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63036
- let m34Array = struct_oper_list.getColumn("vector[3]");
63037
-
63038
- let assemblySize = struct_oper_list.rowCount;
63039
- for (let i = 0; i < assemblySize; ++i) {
63040
- let struct_oper_id = struct_oper_idArray.getString(i);
63041
- if(struct_oper_id == "X0") continue;
63300
+ if(block.getCategory("_pdbx_struct_oper_list")) {
63301
+ // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
63302
+ let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
63303
+
63304
+ let struct_oper_idArray = struct_oper_list.getColumn("id");
63305
+ let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63306
+ let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63307
+ let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63308
+ let m14Array = struct_oper_list.getColumn("vector[1]");
63309
+
63310
+ let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63311
+ let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63312
+ let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63313
+ let m24Array = struct_oper_list.getColumn("vector[2]");
63314
+
63315
+ let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63316
+ let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63317
+ let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63318
+ let m34Array = struct_oper_list.getColumn("vector[3]");
63319
+
63320
+ let assemblySize = struct_oper_list.rowCount;
63321
+ for (let i = 0; i < assemblySize; ++i) {
63322
+ let struct_oper_id = struct_oper_idArray.getString(i);
63323
+ if(struct_oper_id == "X0") continue;
63042
63324
 
63043
- if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63044
- ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63045
- m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63046
- m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63047
- 0, 0, 0, 1);
63325
+ if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63326
+ ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63327
+ m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63328
+ m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63329
+ 0, 0, 0, 1);
63330
+ }
63331
+
63332
+ struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63333
+ = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63048
63334
  }
63049
-
63050
- struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63051
- = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63052
- }
63053
63335
 
63054
- // if (record === 'ENDMDL') {
63055
- // ++moleculeNum;
63056
- // id = ic.defaultPdbId;
63336
+ // if (record === 'ENDMDL') {
63337
+ // ++moleculeNum;
63338
+ // id = ic.defaultPdbId;
63057
63339
 
63058
- // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63340
+ // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63059
63341
 
63060
- // //helices = [];
63061
- // //sheets = [];
63062
- // if(!bNMR) {
63063
- // sheetArray = [];
63064
- // sheetStart = [];
63065
- // sheetEnd = [];
63066
- // helixArray = [];
63067
- // helixStart = [];
63068
- // helixEnd = [];
63069
- // }
63342
+ // //helices = [];
63343
+ // //sheets = [];
63344
+ // if(!bNMR) {
63345
+ // sheetArray = [];
63346
+ // sheetStart = [];
63347
+ // sheetEnd = [];
63348
+ // helixArray = [];
63349
+ // helixStart = [];
63350
+ // helixEnd = [];
63351
+ // }
63070
63352
 
63071
- // bHeader = false; // reinitialize to read structure name from the header
63072
- // }
63353
+ // bHeader = false; // reinitialize to read structure name from the header
63354
+ // }
63073
63355
 
63074
- if(block.getCategory("_citation")) {
63075
- ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63076
- }
63356
+ if(block.getCategory("_citation")) {
63357
+ ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63358
+ }
63077
63359
 
63078
- // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63079
- let atom_site = block.getCategory("_atom_site");
63080
- let atomSize = atom_site.rowCount;
63081
- // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63082
- let bFull = (atomSize > ic.maxatomcnt) ? false : true;
63360
+ // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63361
+ let atom_site = block.getCategory("_atom_site");
63362
+ let atomSize = atom_site.rowCount;
63363
+ // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63364
+ let bFull = (atomSize > ic.maxatomcnt) ? false : true;
63083
63365
 
63084
- if(!bFull) {
63085
- 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
63086
- ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63087
- }
63366
+ if(!bFull) {
63367
+ 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
63368
+ ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63369
+ }
63088
63370
 
63089
- let atom_hetatmArray = atom_site.getColumn("group_PDB");
63090
- let resnArray = atom_site.getColumn("label_comp_id");
63091
- let elemArray = atom_site.getColumn("type_symbol");
63092
- let nameArray = atom_site.getColumn("label_atom_id");
63371
+ let atom_hetatmArray = atom_site.getColumn("group_PDB");
63372
+ let resnArray = atom_site.getColumn("label_comp_id");
63373
+ let elemArray = atom_site.getColumn("type_symbol");
63374
+ let nameArray = atom_site.getColumn("label_atom_id");
63093
63375
 
63094
- let chainArray = atom_site.getColumn("auth_asym_id");
63376
+ let chainArray = atom_site.getColumn("auth_asym_id");
63095
63377
 
63096
- let resiArray = atom_site.getColumn("label_seq_id");
63097
- let resiOriArray = atom_site.getColumn("auth_seq_id");
63098
- let altArray = atom_site.getColumn("label_alt_id");
63378
+ let resiArray = atom_site.getColumn("label_seq_id");
63379
+ let resiOriArray = atom_site.getColumn("auth_seq_id");
63380
+ let altArray = atom_site.getColumn("label_alt_id");
63099
63381
 
63100
- let bArray = atom_site.getColumn("B_iso_or_equiv");
63382
+ let bArray = atom_site.getColumn("B_iso_or_equiv");
63101
63383
 
63102
- let xArray = atom_site.getColumn("Cartn_x");
63103
- let yArray = atom_site.getColumn("Cartn_y");
63104
- let zArray = atom_site.getColumn("Cartn_z");
63384
+ let xArray = atom_site.getColumn("Cartn_x");
63385
+ let yArray = atom_site.getColumn("Cartn_y");
63386
+ let zArray = atom_site.getColumn("Cartn_z");
63105
63387
 
63106
- let autochainArray = atom_site.getColumn("label_asym_id");
63388
+ let autochainArray = atom_site.getColumn("label_asym_id");
63107
63389
 
63108
- // get the bond info
63109
- let ligSeqHash = {}, prevAutochain = '';
63110
- let prevResn;
63111
- let sChain = {};
63112
- for (let i = 0; i < atomSize; ++i) {
63113
- let atom_hetatm = atom_hetatmArray.getString(i);
63114
- let resn = resnArray.getString(i);
63115
- let elem = elemArray.getString(i);
63116
- let atom = nameArray.getString(i);
63117
- let chain = chainArray.getString(i);
63118
- let resi = resiArray.getString(i);
63119
- let oriResi = resiOriArray.getString(i);
63120
- let alt = altArray.getString(i);
63121
- let bFactor = bArray.getString(i);
63390
+ // get the bond info
63391
+ let ligSeqHash = {}, prevAutochain = '';
63392
+ let prevResn;
63393
+ let sChain = {};
63394
+ for (let i = 0; i < atomSize; ++i) {
63395
+ let atom_hetatm = atom_hetatmArray.getString(i);
63396
+ let resn = resnArray.getString(i);
63397
+ let elem = elemArray.getString(i);
63398
+ let atom = nameArray.getString(i);
63399
+ let chain = chainArray.getString(i);
63400
+ let resi = resiArray.getString(i);
63401
+ let oriResi = resiOriArray.getString(i);
63402
+ let alt = altArray.getString(i);
63403
+ let bFactor = bArray.getString(i);
63122
63404
 
63123
- let autochain = autochainArray.getString(i);
63405
+ let autochain = autochainArray.getString(i);
63124
63406
 
63125
63407
 
63126
- resi = oriResi;
63408
+ resi = oriResi;
63127
63409
 
63128
- let molecueType;
63129
- if(atom_hetatm == "ATOM") {
63130
- if(resn.length == 3) {
63131
- molecueType = "p"; // protein
63132
- }
63133
- else {
63134
- molecueType = "n"; // nucleotide
63135
- }
63136
- }
63137
- else {
63138
- if(resn == "WAT" || resn == "HOH") {
63139
- molecueType = "s"; // solvent
63140
- chain = 'Misc';
63410
+ let molecueType;
63411
+ if(atom_hetatm == "ATOM") {
63412
+ if(resn.length == 3) {
63413
+ molecueType = "protein"; // protein
63414
+ }
63415
+ else {
63416
+ molecueType = "nucleotide"; // nucleotide
63417
+ }
63141
63418
  }
63142
63419
  else {
63143
- molecueType = "l"; // ligands or ions
63144
- chain = resn;
63420
+ if(resn == "WAT" || resn == "HOH") {
63421
+ molecueType = "solvent"; // solvent
63422
+ chain = 'Misc';
63423
+ }
63424
+ else {
63425
+ molecueType = "ligand"; // ligands or ions
63426
+ chain = resn;
63427
+ }
63145
63428
  }
63146
- }
63147
- if(chain === '') chain = 'A';
63148
-
63149
- // C-alpha only for large structure
63150
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && atom == 'CA')) || (molecueType == "n" && !(atom == "P")) ) ) continue;
63151
-
63152
- // skip alternative atoms
63153
- if(alt == "B") continue;
63154
-
63155
- sChain[chain] = 1;
63429
+ if(chain === '') chain = 'A';
63156
63430
 
63157
- if(bFirstAtom) {
63158
- structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63431
+ // C-alpha only for large structure
63432
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && atom == 'CA')) || (molecueType == "nucleotide" && !(atom == "P")) ) ) continue;
63433
+
63434
+ // skip alternative atoms
63435
+ if(alt == "B") continue;
63159
63436
 
63160
- bFirstAtom = false;
63161
- }
63437
+ sChain[chain] = 1;
63162
63438
 
63163
- // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
63164
- // Concatenation of two pdbs will have several atoms for the same serial
63165
- ++serial;
63439
+ if(bFirstAtom) {
63440
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63166
63441
 
63167
- // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
63168
- // bModifyResi = true;
63169
- // }
63442
+ bFirstAtom = false;
63443
+ }
63170
63444
 
63171
- if(resi == "?" || resi == "." || resi == "0") {
63172
- resi = oriResi;
63445
+ // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
63446
+ // Concatenation of two pdbs will have several atoms for the same serial
63447
+ ++serial;
63173
63448
 
63174
- // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63175
- // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63176
- // resi = (++tmpResi).toString();
63177
- // }
63178
- // }
63179
- // else {
63180
- // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63181
- // resi = (++tmpResi).toString();
63182
- // }
63183
- // else {
63184
- // resi = (tmpResi).toString();
63185
- // }
63449
+ // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
63450
+ // bModifyResi = true;
63186
63451
  // }
63187
- }
63188
63452
 
63189
- if(molecueType == 's' || molecueType == "l") {
63190
- let seq = {};
63191
- if(!ligSeqHash.hasOwnProperty(chain)) {
63192
- ligSeqHash[chain] = [];
63453
+ if(resi == "?" || resi == "." || resi == "0") {
63454
+ resi = oriResi;
63455
+
63456
+ // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63457
+ // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63458
+ // resi = (++tmpResi).toString();
63459
+ // }
63460
+ // }
63461
+ // else {
63462
+ // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63463
+ // resi = (++tmpResi).toString();
63464
+ // }
63465
+ // else {
63466
+ // resi = (tmpResi).toString();
63467
+ // }
63468
+ // }
63193
63469
  }
63194
63470
 
63195
- if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63196
- if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63197
- seq.resi = resi;
63198
- seq.name = me.utilsCls.residueName2Abbr(resn);
63199
- ligSeqHash[chain].push(seq);
63471
+ if(molecueType == 'solvent' || molecueType == "ligand") {
63472
+ let seq = {};
63473
+ if(!ligSeqHash.hasOwnProperty(chain)) {
63474
+ ligSeqHash[chain] = [];
63200
63475
  }
63201
- }
63202
- else {
63203
- if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63204
- seq.resi = resi;
63205
- seq.name = me.utilsCls.residueName2Abbr(resn);
63206
- ligSeqHash[chain].push(seq);
63476
+
63477
+ if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63478
+ if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63479
+ seq.resi = resi;
63480
+ seq.name = me.utilsCls.residueName2Abbr(resn);
63481
+ ligSeqHash[chain].push(seq);
63482
+ }
63483
+ }
63484
+ else {
63485
+ if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63486
+ seq.resi = resi;
63487
+ seq.name = me.utilsCls.residueName2Abbr(resn);
63488
+ ligSeqHash[chain].push(seq);
63489
+ }
63207
63490
  }
63208
63491
  }
63209
- }
63210
63492
 
63211
- // if(bOpm && resn === 'DUM') {
63212
- // elem = atom;
63213
- // chain = 'MEM';
63214
- // resi = 1;
63215
- // oriResi = 1;
63216
- // }
63493
+ // if(bOpm && resn === 'DUM') {
63494
+ // elem = atom;
63495
+ // chain = 'MEM';
63496
+ // resi = 1;
63497
+ // oriResi = 1;
63498
+ // }
63217
63499
 
63218
- // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
63500
+ // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
63219
63501
 
63220
- chainNum = structure + "_" + chain;
63221
- oriResidueNum = chainNum + "_" + oriResi;
63502
+ chainNum = structure + "_" + chain;
63503
+ oriResidueNum = chainNum + "_" + oriResi;
63222
63504
 
63223
- residueNum = chainNum + "_" + resi;
63505
+ residueNum = chainNum + "_" + resi;
63224
63506
 
63225
- //let chain_resi = chain + "_" + resi;
63507
+ //let chain_resi = chain + "_" + resi;
63226
63508
 
63227
- let x = xArray.getFloat(i);
63228
- let y = yArray.getFloat(i);
63229
- let z = zArray.getFloat(i);
63230
- let coord = new THREE.Vector3(x, y, z);
63509
+ let x = xArray.getFloat(i);
63510
+ let y = yArray.getFloat(i);
63511
+ let z = zArray.getFloat(i);
63512
+ let coord = new THREE.Vector3(x, y, z);
63231
63513
 
63232
- let atomDetails = {
63233
- het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
63234
- serial: serial, // required, unique atom id
63235
- name: atom, // required, atom name
63236
- alt: alt, // optional, some alternative coordinates
63237
- resn: resn, // optional, used to determine protein or nucleotide
63238
- structure: structure, // optional, used to identify structure
63239
- chain: chain, // optional, used to identify chain
63240
- resi: resi, // optional, used to identify residue ID
63241
- //insc: line.substr(26, 1),
63242
- coord: coord, // required, used to draw 3D shape
63243
- b: bFactor, // optional, used to draw B-factor tube
63244
- elem: elem, // optional, used to determine hydrogen bond
63245
- bonds: [], // required, used to connect atoms
63246
- ss: 'coil', // optional, used to show secondary structures
63247
- ssbegin: false, // optional, used to show the beginning of secondary structures
63248
- ssend: false // optional, used to show the end of secondary structures
63249
- };
63514
+ let atomDetails = {
63515
+ het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
63516
+ serial: serial, // required, unique atom id
63517
+ name: atom, // required, atom name
63518
+ alt: alt, // optional, some alternative coordinates
63519
+ resn: resn, // optional, used to determine protein or nucleotide
63520
+ structure: structure, // optional, used to identify structure
63521
+ chain: chain, // optional, used to identify chain
63522
+ resi: resi, // optional, used to identify residue ID
63523
+ //insc: line.substr(26, 1),
63524
+ coord: coord, // required, used to draw 3D shape
63525
+ b: bFactor, // optional, used to draw B-factor tube
63526
+ elem: elem, // optional, used to determine hydrogen bond
63527
+ bonds: [], // required, used to connect atoms
63528
+ ss: 'coil', // optional, used to show secondary structures
63529
+ ssbegin: false, // optional, used to show the beginning of secondary structures
63530
+ ssend: false // optional, used to show the end of secondary structures
63531
+ };
63250
63532
 
63251
- if(!atomDetails.het && atomDetails.name === 'C') ;
63252
- if(!atomDetails.het && atomDetails.name === 'O') ;
63533
+ if(!atomDetails.het && atomDetails.name === 'C') ;
63534
+ if(!atomDetails.het && atomDetails.name === 'O') ;
63253
63535
 
63254
- // from DSSP C++ code
63255
- // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
63256
- // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
63536
+ // from DSSP C++ code
63537
+ // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
63538
+ // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
63257
63539
 
63258
- // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
63259
- // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
63260
- // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
63540
+ // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
63541
+ // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
63542
+ // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
63261
63543
 
63262
- // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
63263
- // }
63544
+ // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
63545
+ // }
63264
63546
 
63265
- ic.atoms[serial] = atomDetails;
63547
+ ic.atoms[serial] = atomDetails;
63266
63548
 
63267
- ic.dAtoms[serial] = 1;
63268
- ic.hAtoms[serial] = 1;
63269
- hAtoms[serial] = 1;
63549
+ ic.dAtoms[serial] = 1;
63550
+ ic.hAtoms[serial] = 1;
63551
+ hAtoms[serial] = 1;
63270
63552
 
63271
- // Assign secondary structures from the input
63272
- // if a residue is assigned both sheet and helix, it is assigned as sheet
63273
- if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
63274
- ic.atoms[serial].ss = 'sheet';
63275
- if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
63276
- ic.atoms[serial].ssbegin = true;
63277
- }
63553
+ // Assign secondary structures from the input
63554
+ // if a residue is assigned both sheet and helix, it is assigned as sheet
63555
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
63556
+ ic.atoms[serial].ss = 'sheet';
63557
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
63558
+ ic.atoms[serial].ssbegin = true;
63559
+ }
63278
63560
 
63279
- // do not use else if. Some residues are both start and end of secondary structure
63280
- if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
63281
- ic.atoms[serial].ssend = true;
63561
+ // do not use else if. Some residues are both start and end of secondary structure
63562
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
63563
+ ic.atoms[serial].ssend = true;
63564
+ }
63282
63565
  }
63283
- }
63284
- else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
63285
- ic.atoms[serial].ss = 'helix';
63566
+ else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
63567
+ ic.atoms[serial].ss = 'helix';
63286
63568
 
63287
- if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
63288
- ic.atoms[serial].ssbegin = true;
63569
+ if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
63570
+ ic.atoms[serial].ssbegin = true;
63571
+ }
63572
+
63573
+ // do not use else if. Some residues are both start and end of secondary structure
63574
+ if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
63575
+ ic.atoms[serial].ssend = true;
63576
+ }
63289
63577
  }
63290
63578
 
63291
- // do not use else if. Some residues are both start and end of secondary structure
63292
- if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
63293
- ic.atoms[serial].ssend = true;
63579
+ let secondaries = '-';
63580
+ if(ic.atoms[serial].ss === 'helix') {
63581
+ secondaries = 'H';
63582
+ }
63583
+ else if(ic.atoms[serial].ss === 'sheet') {
63584
+ secondaries = 'E';
63585
+ }
63586
+ //else if(ic.atoms[serial].ss === 'coil') {
63587
+ // secondaries = 'c';
63588
+ //}
63589
+ else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
63590
+ secondaries = 'c';
63591
+ }
63592
+ else {
63593
+ secondaries = 'o';
63294
63594
  }
63295
- }
63296
63595
 
63297
- let secondaries = '-';
63298
- if(ic.atoms[serial].ss === 'helix') {
63299
- secondaries = 'H';
63300
- }
63301
- else if(ic.atoms[serial].ss === 'sheet') {
63302
- secondaries = 'E';
63303
- }
63304
- //else if(ic.atoms[serial].ss === 'coil') {
63305
- // secondaries = 'c';
63306
- //}
63307
- else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
63308
- secondaries = 'c';
63309
- }
63310
- else {
63311
- secondaries = 'o';
63312
- }
63596
+ ic.secondaries[residueNum] = secondaries;
63313
63597
 
63314
- ic.secondaries[residueNum] = secondaries;
63598
+ // different residue
63599
+ //if(residueNum !== prevResidueNum) {
63600
+
63601
+ // if(oriResidueNum !== prevOriResidueNum) {
63602
+ if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
63603
+ let residue = me.utilsCls.residueName2Abbr(resn);
63604
+
63605
+ ic.residueId2Name[residueNum] = residue;
63315
63606
 
63316
- // different residue
63317
- //if(residueNum !== prevResidueNum) {
63318
-
63319
- // if(oriResidueNum !== prevOriResidueNum) {
63320
- if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
63321
- let residue = me.utilsCls.residueName2Abbr(resn);
63322
-
63323
- ic.residueId2Name[residueNum] = residue;
63607
+ if(serial !== 1 && prevResidueNum !== '') {
63608
+ ic.residues[prevResidueNum] = residuesTmp;
63609
+ }
63324
63610
 
63325
- if(serial !== 1 && prevResidueNum !== '') {
63326
- ic.residues[prevResidueNum] = residuesTmp;
63327
- }
63611
+ if(residueNum !== prevResidueNum) {
63612
+ residuesTmp = {};
63613
+ }
63328
63614
 
63329
- if(residueNum !== prevResidueNum) {
63330
- residuesTmp = {};
63331
- }
63615
+ // different chain
63616
+ if(chainNum !== prevChainNum) {
63332
63617
 
63333
- // different chain
63334
- if(chainNum !== prevChainNum) {
63618
+ // a chain could be separated in two sections
63619
+ if(serial !== 1 && prevChainNum !== '') {
63620
+ if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
63621
+ ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
63622
+ }
63335
63623
 
63336
- // a chain could be separated in two sections
63337
- if(serial !== 1 && prevChainNum !== '') {
63338
- if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
63339
- ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
63340
- }
63624
+ chainsTmp = {};
63341
63625
 
63342
- chainsTmp = {};
63626
+ if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
63627
+ if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
63343
63628
 
63344
- if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
63345
- if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
63629
+ if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
63346
63630
 
63347
- if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
63631
+ let resObject = {};
63632
+ resObject.resi = resi;
63633
+ resObject.name = residue;
63348
63634
 
63349
- let resObject = {};
63350
- resObject.resi = resi;
63351
- resObject.name = residue;
63635
+ ic.chainsSeq[chainNum].push(resObject);
63636
+ }
63637
+ else {
63638
+
63639
+ let resObject = {};
63640
+ resObject.resi = resi;
63641
+ resObject.name = residue;
63352
63642
 
63353
- ic.chainsSeq[chainNum].push(resObject);
63643
+ ic.chainsSeq[chainNum].push(resObject);
63644
+ }
63354
63645
  }
63355
- else {
63356
63646
 
63357
- let resObject = {};
63358
- resObject.resi = resi;
63359
- resObject.name = residue;
63647
+ chainsTmp[serial] = 1;
63648
+ residuesTmp[serial] = 1;
63360
63649
 
63361
- ic.chainsSeq[chainNum].push(resObject);
63362
- }
63363
- }
63650
+ prevChainNum = chainNum;
63651
+ prevResidueNum = residueNum;
63652
+ prevOriResidueNum = oriResidueNum;
63364
63653
 
63365
- chainsTmp[serial] = 1;
63366
- residuesTmp[serial] = 1;
63654
+ prevResn = chain + "_" + resn;
63655
+ prevAutochain = autochain;
63656
+ }
63367
63657
 
63368
- prevChainNum = chainNum;
63369
- prevResidueNum = residueNum;
63370
- prevOriResidueNum = oriResidueNum;
63658
+ // add the last residue set
63659
+ ic.residues[residueNum] = residuesTmp;
63660
+ if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
63661
+ ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
63371
63662
 
63372
- prevResn = chain + "_" + resn;
63373
- prevAutochain = autochain;
63374
- }
63663
+ // clear memory
63664
+ atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
63665
+ = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
63375
63666
 
63376
- // add the last residue set
63377
- ic.residues[residueNum] = residuesTmp;
63378
- if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
63379
- ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
63667
+ let mChainSeq = {};
63668
+ if(block.getCategory("_pdbx_poly_seq_scheme")) {
63669
+ let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
63380
63670
 
63381
- // clear memory
63382
- atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
63383
- = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
63671
+ let resiArray = poly_seq_scheme.getColumn("seq_id");
63672
+ let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
63673
+ let resnArray = poly_seq_scheme.getColumn("mon_id");
63674
+ let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
63384
63675
 
63385
- let mChainSeq = {};
63386
- if(block.getCategory("_pdbx_poly_seq_scheme")) {
63387
- let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
63676
+ let seqSize = poly_seq_scheme.rowCount;
63677
+ let prevChain = "";
63678
+ let seqArray = [];
63679
+ for (let i = 0; i < seqSize; ++i) {
63680
+ resiArray.getString(i);
63681
+ let oriResi = oriResiArray.getString(i);
63682
+ let resn = resnArray.getString(i);
63683
+ let chain = chainArray.getString(i);
63388
63684
 
63389
- let resiArray = poly_seq_scheme.getColumn("seq_id");
63390
- let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
63391
- let resnArray = poly_seq_scheme.getColumn("mon_id");
63392
- let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
63685
+ if(chain != prevChain && i > 0) {
63686
+ mChainSeq[prevChain] = seqArray;
63393
63687
 
63394
- let seqSize = poly_seq_scheme.rowCount;
63395
- let prevChain = "";
63396
- let seqArray = [];
63397
- for (let i = 0; i < seqSize; ++i) {
63398
- resiArray.getString(i);
63399
- let oriResi = oriResiArray.getString(i);
63400
- let resn = resnArray.getString(i);
63401
- let chain = chainArray.getString(i);
63688
+ seqArray = [];
63689
+ }
63402
63690
 
63403
- if(chain != prevChain && i > 0) {
63404
- mChainSeq[prevChain] = seqArray;
63691
+ // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
63692
+ seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
63405
63693
 
63406
- seqArray = [];
63694
+ prevChain = chain;
63407
63695
  }
63408
63696
 
63409
- // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
63410
- seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
63697
+ mChainSeq[prevChain] = seqArray;
63411
63698
 
63412
- prevChain = chain;
63699
+ resiArray = oriResiArray = resnArray = chainArray = [];
63413
63700
  }
63414
-
63415
- mChainSeq[prevChain] = seqArray;
63416
-
63417
- resiArray = oriResiArray = resnArray = chainArray = [];
63701
+
63702
+ this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
63418
63703
  }
63419
-
63420
- this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
63421
63704
 
63422
63705
  // copy disulfide bonds
63423
63706
  let structureArray = Object.keys(ic.structures);
@@ -63712,7 +63995,7 @@ class Vastplus {
63712
63995
  let chainid = chainidArray[i];
63713
63996
  let atoms = me.hashUtilsCls.intHash(ic.hAtoms, ic.chains[chainid]);
63714
63997
  let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
63715
- structHash[firstAtom.structure] = 1;
63998
+ if(firstAtom) structHash[firstAtom.structure] = 1;
63716
63999
  }
63717
64000
  }
63718
64001
 
@@ -64734,6 +65017,11 @@ class ApplyCommand {
64734
65017
 
64735
65018
  ic.drawCls.draw();
64736
65019
  }
65020
+ else if(command == 'add ig labels') {
65021
+ ic.residueLabelsCls.addIgLabels(ic.hAtoms);
65022
+
65023
+ ic.drawCls.draw();
65024
+ }
64737
65025
  else if(command == 'add atom labels') {
64738
65026
  ic.residueLabelsCls.addAtomLabels(ic.hAtoms);
64739
65027
 
@@ -66060,6 +66348,7 @@ class ApplyCommand {
66060
66348
  else if(cmd.indexOf('hide annotation') == 0) return seqAnnoStr + ': checkboxes off';
66061
66349
  else if(cmd == 'add residue labels') return labelStr + 'per Residue';
66062
66350
  else if(cmd == 'add residue number labels') return labelStr + 'per Residue & Number';
66351
+ else if(cmd == 'add Ig domain labels') return labelStr + 'per Ig Domain';
66063
66352
  else if(cmd == 'add atom labels') return labelStr + 'per Atom';
66064
66353
  else if(cmd == 'add chain labels') return labelStr + 'per Chain';
66065
66354
  else if(cmd == 'add terminal labels') return labelStr + 'N- & C- Termini';
@@ -69324,6 +69613,34 @@ class Resid2spec {
69324
69613
  return spec;
69325
69614
  }
69326
69615
 
69616
+ resi2range(resiArray) {var ic = this.icn3d; ic.icn3dui;
69617
+ let range = [];
69618
+
69619
+ let resiArraySorted = resiArray.sort(function(a, b) {
69620
+ return parseInt(a) - parseInt(b);
69621
+ });
69622
+
69623
+ let startResi = resiArraySorted[0];
69624
+ let prevResi, resi;
69625
+ for(let j = 0, jl = resiArraySorted.length; j < jl; ++j) {
69626
+ resi = resiArraySorted[j];
69627
+
69628
+ if(j != 0 && resi != prevResi + 1) {
69629
+ range.push(startResi);
69630
+ range.push(prevResi);
69631
+ startResi = resi;
69632
+ }
69633
+
69634
+ prevResi = resi;
69635
+ }
69636
+
69637
+ // last residue
69638
+ range.push(startResi);
69639
+ range.push(prevResi);
69640
+
69641
+ return range;
69642
+ }
69643
+
69327
69644
  atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
69328
69645
  let spec = "";
69329
69646
  let i = 0;
@@ -70786,8 +71103,6 @@ class Dssp {
70786
71103
  bNoMoreIg = false;
70787
71104
 
70788
71105
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
70789
- //let bForceOneDomain = true;
70790
- //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
70791
71106
 
70792
71107
  // ig strand for any subset will have the same k, use the number of residue to separate them
70793
71108
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
@@ -70947,20 +71262,24 @@ class Dssp {
70947
71262
  // assign ref numbers to selected residues
70948
71263
  let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
70949
71264
  let subdomains = result.subdomains;
70950
- let pos2resi = result.pos2resi;
71265
+ // let pos2resi = result.pos2resi;
70951
71266
 
70952
71267
  if(subdomains.length >= 1) {
70953
71268
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
70954
71269
  let domainAtoms = {};
70955
71270
  let segArray = subdomains[k];
70956
71271
 
70957
- let resCnt = 0;
71272
+ let resCnt = 0; // minResi = 999, maxResi = -999;
70958
71273
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
70959
71274
  let startResi = parseInt(segArray[m]);
70960
71275
  let endResi = parseInt(segArray[m+1]);
70961
71276
 
71277
+ // if(startResi < minResi) minResi = startResi;
71278
+ // if(endResi > maxResi) maxResi = endResi;
71279
+
70962
71280
  for(let n = startResi; n <= endResi; ++n) {
70963
- let resid = chainid + '_' + pos2resi[n - 1];
71281
+ // let resid = chainid + '_' + pos2resi[n - 1];
71282
+ let resid = ic.ncbi2resid[chainid + '_' + n];
70964
71283
  ++resCnt;
70965
71284
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
70966
71285
 
@@ -70976,6 +71295,9 @@ class Dssp {
70976
71295
  domainAtomsArray.push(domainAtoms);
70977
71296
  }
70978
71297
  }
71298
+ // else { // no domain
71299
+ // domainAtomsArray = [currAtoms];
71300
+ // }
70979
71301
 
70980
71302
  return domainAtomsArray;
70981
71303
  }
@@ -71099,8 +71421,6 @@ class Dssp {
71099
71421
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
71100
71422
  }
71101
71423
 
71102
- console.log("### " + bBstrand + bCstrand + bEstrand + bFstrand);
71103
-
71104
71424
  // if(refpdbname != 'CD19_6al5A_human-n1') { // relax for CD19
71105
71425
  if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
71106
71426
  // if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
@@ -80533,7 +80853,7 @@ class iCn3DUI {
80533
80853
  //even when multiple iCn3D viewers are shown together.
80534
80854
  this.pre = this.cfg.divid + "_";
80535
80855
 
80536
- this.REVISION = '3.31.4';
80856
+ this.REVISION = '3.33.0';
80537
80857
 
80538
80858
  // In nodejs, iCn3D defines "window = {navigator: {}}"
80539
80859
  this.bNode = (Object.keys(window).length < 2) ? true : false;