icn3d 3.31.12 → 3.32.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 +1149 -850
  2. package/icn3d.min.js +5 -5
  3. package/icn3d.module.js +1149 -850
  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();
@@ -11684,7 +11684,7 @@ class SetMenu {
11684
11684
  // html += this.getLink('mn1_pdbfile', 'PDB File');
11685
11685
  // html += this.getLink('mn1_pdbfile_app', 'PDB File (append)');
11686
11686
  html += this.getLink('mn1_pdbfile_app', 'PDB Files (appendable)', 1, 2);
11687
- html += this.getLink('mn1_mmciffile', 'mmCIF File', undefined, 2);
11687
+ html += this.getLink('mn1_mmciffile', 'mmCIF File (appendable)', undefined, 2);
11688
11688
  html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
11689
11689
  html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
11690
11690
  html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
@@ -14028,8 +14028,8 @@ class SetDialog {
14028
14028
  html += "</div>";
14029
14029
 
14030
14030
  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> ";
14031
+ html += this.addNotebookTitle('dl_mmciffile', 'Please append mmCIF files');
14032
+ html += "Multiple mmCIF Files: <input type='file' multiple id='" + me.pre + "mmciffile' size=8> ";
14033
14033
  html += me.htmlCls.buttonStr + "reload_mmciffile'>Load</button>";
14034
14034
  html += "</div>";
14035
14035
 
@@ -15284,17 +15284,15 @@ class Events {
15284
15284
  }
15285
15285
  }
15286
15286
 
15287
- async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
15287
+ async readFile(bAppend, files, index, dataStrAll, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
15288
15288
  let file = files[index];
15289
15289
  let commandName = (bAppend) ? 'append': 'load';
15290
+ commandName += (bmmCIF) ? ' mmcif file ': ' pdb file ';
15290
15291
 
15291
15292
  let reader = new FileReader();
15292
15293
  reader.onload = async function(e) {
15293
- //++ic.loadedFileCnt;
15294
-
15295
15294
  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);
15295
+ thisClass.setLogCmd(commandName + file.name, false);
15298
15296
 
15299
15297
  if(!bAppend) {
15300
15298
  ic.init();
@@ -15308,7 +15306,7 @@ class Events {
15308
15306
  }
15309
15307
 
15310
15308
  ic.bInputfile = true;
15311
- ic.InputfileType = 'pdb';
15309
+ ic.InputfileType = (bmmCIF) ? 'mmcif' : 'pdb';
15312
15310
  ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + dataStr : dataStr;
15313
15311
 
15314
15312
  dataStrAll = (index > 0) ? dataStrAll + '\nENDMDL\n' + dataStr : dataStr;
@@ -15318,15 +15316,21 @@ class Events {
15318
15316
  ic.hAtoms = {};
15319
15317
  ic.dAtoms = {};
15320
15318
  }
15321
- await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
15319
+ if(bmmCIF) {
15320
+ await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend);
15321
+ }
15322
+ else {
15323
+ await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
15324
+ }
15325
+
15326
+ //ic.InputfileType = undefined; // reset
15322
15327
  }
15323
15328
  else {
15324
- await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
15329
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll, bmmCIF);
15325
15330
  }
15326
15331
 
15327
15332
  if(bAppend) {
15328
15333
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
15329
- //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
15330
15334
 
15331
15335
  ic.bResetAnno = true;
15332
15336
 
@@ -15343,9 +15347,7 @@ class Events {
15343
15347
  }
15344
15348
  }
15345
15349
 
15346
- async loadPdbFile(bAppend) { let me = this.icn3dui, ic = me.icn3d;
15347
- let fileId = (bAppend) ? 'pdbfile_app' : 'pdbfile';
15348
-
15350
+ async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d;
15349
15351
  //me = ic.setIcn3dui(this.id);
15350
15352
  ic.bInitial = true;
15351
15353
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -15369,7 +15371,7 @@ class Events {
15369
15371
 
15370
15372
  ic.dataStrAll = '';
15371
15373
 
15372
- await this.readFile(bAppend, files, 0, '');
15374
+ await this.readFile(bAppend, files, 0, '', bmmCIF);
15373
15375
  }
15374
15376
  }
15375
15377
 
@@ -16726,14 +16728,14 @@ class Events {
16726
16728
  e.preventDefault();
16727
16729
 
16728
16730
  let bAppend = false;
16729
- await thisClass.loadPdbFile(bAppend);
16731
+ await thisClass.loadPdbFile(bAppend, 'pdbfile');
16730
16732
  });
16731
16733
 
16732
16734
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", async function(e) { let ic = me.icn3d;
16733
16735
  e.preventDefault();
16734
16736
 
16735
16737
  ic.bAppend = true;
16736
- await thisClass.loadPdbFile(ic.bAppend);
16738
+ await thisClass.loadPdbFile(ic.bAppend, 'pdbfile_app');
16737
16739
  });
16738
16740
 
16739
16741
  me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
@@ -16917,49 +16919,13 @@ class Events {
16917
16919
  await ic.pdbParserCls.downloadUrl(url, type);
16918
16920
  });
16919
16921
 
16920
- me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", function(e) { let ic = me.icn3d;
16922
+ me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", async function(e) { let ic = me.icn3d;
16921
16923
  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
-
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
16924
 
16953
- //ic.initUI();
16954
- ic.init();
16955
- ic.bInputfile = true;
16956
- ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + data : data;
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
- }
16925
+ ic.bAppend = true;
16926
+ let bmmCIF = true;
16927
+ let fileId = 'mmciffile';
16928
+ await thisClass.loadPdbFile(ic.bAppend, fileId, bmmCIF);
16963
16929
  });
16964
16930
 
16965
16931
  me.myEventCls.onIds("#" + me.pre + "applycustomcolor", "click", function(e) { let ic = me.icn3d;
@@ -17608,11 +17574,13 @@ class Events {
17608
17574
  let command;
17609
17575
  if(shape == 'Sphere') {
17610
17576
  ic.sphereCls.createSphereBase(pos1, color, radius, undefined, undefined, undefined, opacity);
17611
- command = 'add sphere | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
17577
+ // command = 'add sphere | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
17578
+ command = 'add sphere | ' + nameArray + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
17612
17579
  }
17613
17580
  else {
17614
17581
  ic.boxCls.createBox_base(pos1, radius, color, undefined, undefined, undefined, opacity);
17615
- command = 'add cube | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
17582
+ // command = 'add cube | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
17583
+ command = 'add cube | ' + nameArray + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
17616
17584
  }
17617
17585
 
17618
17586
  thisClass.setLogCmd(command, true);
@@ -28146,14 +28114,14 @@ class Strand {
28146
28114
  // include the whole sheet or helix when highlighting
28147
28115
  let atomsAdjust = {};
28148
28116
 
28149
- //if( (bHighlight === 1 || bHighlight === 2) && !ic.bAllAtoms) {
28150
- //if( !ic.bAllAtoms) {
28151
- if( Object.keys(atoms).length < Object.keys(ic.atoms).length) {
28152
- atomsAdjust = this.getSSExpandedAtoms(atoms);
28153
- }
28154
- else {
28155
- atomsAdjust = atoms;
28156
- }
28117
+ // if( Object.keys(atoms).length < Object.keys(ic.atoms).length) {
28118
+ // atomsAdjust = this.getSSExpandedAtoms(atoms);
28119
+ // }
28120
+ // else {
28121
+ // atomsAdjust = atoms;
28122
+ // }
28123
+
28124
+ atomsAdjust = atoms;
28157
28125
 
28158
28126
  if(bHighlight === 2) {
28159
28127
  if(fill) {
@@ -28211,9 +28179,16 @@ class Strand {
28211
28179
 
28212
28180
  let maxDist = 6.0;
28213
28181
 
28182
+ //get the last residue
28183
+ let atomArray = Object.keys(atoms);
28184
+ let lastAtomSerial = atomArray[atomArray.length - 1];
28185
+ let lastAtom = atoms[lastAtomSerial];
28186
+ let lastResid = lastAtom.structure + '_' + lastAtom.chain + '_' + lastAtom.resi;
28187
+
28214
28188
  for (let i in atomsAdjust) {
28215
28189
  atom = atomsAdjust[i];
28216
28190
  let chainid = atom.structure + '_' + atom.chain;
28191
+ let resid = atom.structure + '_' + atom.chain + '_' + atom.resi;
28217
28192
  if ((atom.name === 'O' || atom.name === 'CA') && !atom.het) {
28218
28193
  // "CA" has to appear before "O"
28219
28194
 
@@ -28250,7 +28225,7 @@ class Strand {
28250
28225
  if(atom.ssend && atom.ss === 'sheet') {
28251
28226
  bSheetSegment = true;
28252
28227
  }
28253
- else if(atom.ssend && atom.ss === 'helix') {
28228
+ else if( (atom.ssend && atom.ss === 'helix') || resid == lastResid) { // partial sheet will draw as helix
28254
28229
  bHelixSegment = true;
28255
28230
  }
28256
28231
 
@@ -28357,7 +28332,7 @@ class Strand {
28357
28332
  // }
28358
28333
 
28359
28334
  //if ((atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs) && pnts[0].length > 0 && bSameChain) {
28360
- if ((currentChain !== atom.chain || atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs) && pnts[0].length > 0) {
28335
+ if ((currentChain !== atom.chain || atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs || resid == lastResid) && pnts[0].length > 0) {
28361
28336
  let atomName = 'CA';
28362
28337
 
28363
28338
  let prevone = [], nexttwo = [];
@@ -28500,8 +28475,11 @@ class Strand {
28500
28475
  bHelixSegment = false;
28501
28476
  } // end if (atom.ssbegin || atom.ssend)
28502
28477
 
28503
- // end of a chain
28504
- if ((currentChain !== atom.chain || ic.ParserUtilsCls.getResiNCBI(atom.structure + '_' + currentChain, currentResi) + 1 !== ic.ParserUtilsCls.getResiNCBI(chainid, atom.resi)) && pnts[0].length > 0) {
28478
+ // end of a chain, or end of selection
28479
+ if ((currentChain !== atom.chain
28480
+ || ic.ParserUtilsCls.getResiNCBI(atom.structure + '_' + currentChain, currentResi) + 1 !== ic.ParserUtilsCls.getResiNCBI(chainid, atom.resi)
28481
+ || resid == lastResid
28482
+ ) && pnts[0].length > 0) {
28505
28483
  //if ((currentChain !== atom.chain) && pnts[0].length > 0) {
28506
28484
 
28507
28485
  let atomName = 'CA';
@@ -39937,9 +39915,24 @@ class AnnoCddSite {
39937
39915
  pssmid2toArray = {};
39938
39916
  }
39939
39917
 
39940
- let indexl =(domainArray !== undefined) ? domainArray.length : 0;
39918
+ if(domainArray === undefined) domainArray = [];
39919
+ let indexl = domainArray.length;
39941
39920
  let maxTextLen =(type == 'domain') ? 14 : 19;
39942
39921
  let titleSpace =(type == 'domain') ? 100 : 120;
39922
+
39923
+ // sort domainArray
39924
+ domainArray.sort(function(a, b) {
39925
+ let domainRepeatArray = a.locs;
39926
+ let segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
39927
+ let domainFrom1 = Math.round(segArray[0].from);
39928
+
39929
+ domainRepeatArray = b.locs;
39930
+ segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
39931
+ let domainFrom2 = Math.round(segArray[0].from);
39932
+
39933
+ return domainFrom1 - domainFrom2;
39934
+ });
39935
+
39943
39936
  for(let index = 0; index < indexl; ++index) {
39944
39937
  let pssmid = (type == 'domain') ? domainArray[index].pssmid : 0;
39945
39938
 
@@ -40003,6 +39996,9 @@ class AnnoCddSite {
40003
39996
  // if(type != 'domain') setname += "_" + index + "_" + r;
40004
39997
  if(type != 'domain') setname = chnid + "_" + index + "_" + r + "_" + domain;
40005
39998
 
39999
+ //remove space in setname
40000
+ setname = setname.replace(/\s+/g, '');
40001
+
40006
40002
  if(type == 'domain') pssmid2fromArray[pssmid] = fromArray;
40007
40003
  if(type == 'domain') pssmid2toArray[pssmid] = toArray;
40008
40004
 
@@ -40805,6 +40801,7 @@ class AnnoIg {
40805
40801
  async showIg(chnid, template) { let ic = this.icn3d; ic.icn3dui;
40806
40802
  // if(!ic.bRunRefnum || Object.keys(ic.atoms).length > Object.keys(ic.hAtoms).length) {
40807
40803
  if(ic.bRunRefnumAgain) {
40804
+ // run for all chains
40808
40805
  await ic.refnumCls.showIgRefNum(template);
40809
40806
  // ic.bRunRefnum = true;
40810
40807
  }
@@ -41462,9 +41459,7 @@ class AnnoDomain {
41462
41459
 
41463
41460
  let result = ic.domain3dCls.c2b_NewSplitChain(atoms);
41464
41461
  let subdomains = result.subdomains;
41465
- let pos2resi = result.pos2resi;
41466
- //let substruct = result.substruct;
41467
- //let jsonStr = ic.domain3dCls.getDomainJsonForAlign(atoms);
41462
+ // let pos2resi = result.pos2resi;
41468
41463
 
41469
41464
  for(let i = 0, il = subdomains.length; i < il; ++i) {
41470
41465
  // domain item: {"sdid":1722375,"intervals":[[1,104],[269,323]]}
@@ -41478,7 +41473,7 @@ class AnnoDomain {
41478
41473
  data.domains[chainid].domains.push(domain);
41479
41474
  }
41480
41475
 
41481
- data.domains[chainid].pos2resi = pos2resi;
41476
+ // data.domains[chainid].pos2resi = pos2resi;
41482
41477
  }
41483
41478
  }
41484
41479
 
@@ -41511,11 +41506,26 @@ class AnnoDomain {
41511
41506
  this.showDomainPerStructure(i);
41512
41507
  }
41513
41508
  }
41509
+
41510
+ getResiFromNnbiresid(ncbiresid) { let ic = this.icn3d; ic.icn3dui;
41511
+ let resid = (ic.ncbi2resid[ncbiresid]) ? ic.ncbi2resid[ncbiresid] : ncbiresid;
41512
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
41513
+
41514
+ return resi;
41515
+ }
41516
+
41517
+ getNcbiresiFromResid(resid) { let ic = this.icn3d; ic.icn3dui;
41518
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
41519
+ let resi = ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1);
41520
+
41521
+ return resi;
41522
+ }
41523
+
41514
41524
  showDomainWithData(chnid, data, bCalcDirect) { let ic = this.icn3d, me = ic.icn3dui;
41515
41525
  let html = '<div id="' + ic.pre + chnid + '_domainseq_sequence" class="icn3d-dl_sequence">';
41516
41526
  let html2 = html;
41517
41527
  let html3 = html;
41518
- let domainArray, pos2resi, proteinname;
41528
+ let domainArray, proteinname;
41519
41529
  let pos = chnid.indexOf('_');
41520
41530
  let chain = chnid.substr(pos + 1);
41521
41531
  // MMDB symmetry chain has the form of 'A1'
@@ -41526,7 +41536,7 @@ class AnnoDomain {
41526
41536
  // if(bCalcDirect) {
41527
41537
  proteinname = chnid;
41528
41538
  domainArray = (data.domains[chnid]) ? data.domains[chnid].domains : [];
41529
- pos2resi = data.domains[chnid].pos2resi;
41539
+ // pos2resi = data.domains[chnid].pos2resi;
41530
41540
  /*
41531
41541
  }
41532
41542
  else {
@@ -41554,40 +41564,33 @@ class AnnoDomain {
41554
41564
  let title =(fulltitle.length > 17) ? fulltitle.substr(0,17) + '...' : fulltitle;
41555
41565
  let subdomainArray = domainArray[index].intervals;
41556
41566
  // remove duplicate, e.g., at https://www.ncbi.nlm.nih.gov/Structure/mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=1itw
41557
- let domainFromHash = {}, domainToHash = {};
41558
- let fromArray = [], toArray = [], posFromArray = [], posToArray = [];
41567
+ // let domainFromHash = {}, domainToHash = {};
41568
+ let fromArray = [], toArray = []; // posFromArray = [], posToArray = [];
41559
41569
  let resiHash = {};
41560
41570
  let resCnt = 0;
41561
41571
 
41572
+ // subdomainArray contains NCBI residue number
41562
41573
  for(let i = 0, il = subdomainArray.length; i < il; ++i) {
41563
- let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
41564
- let domainTo = Math.round(subdomainArray[i][1]) - 1;
41574
+ // let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
41575
+ // let domainTo = Math.round(subdomainArray[i][1]) - 1;
41565
41576
 
41566
- if(domainFromHash.hasOwnProperty(domainFrom) || domainToHash.hasOwnProperty(domainTo)) {
41567
- continue; // do nothing for duplicated "from" or "to", e.g, PDBID 1ITW, 5FWI
41568
- }
41569
- else {
41570
- domainFromHash[domainFrom] = 1;
41571
- domainToHash[domainTo] = 1;
41572
- }
41577
+ let domainFrom = parseInt(subdomainArray[i][0]);
41578
+ let domainTo = parseInt(subdomainArray[i][1]);
41573
41579
 
41574
- // use the NCBI residue number, and convert to PDB residue number during selection
41575
- // if(ic.bNCBI || bCalcDirect) {
41576
- fromArray.push(pos2resi[domainFrom]);
41577
- toArray.push(pos2resi[domainTo]);
41578
41580
 
41579
- posFromArray.push(domainFrom);
41580
- posToArray.push(domainTo);
41581
- // }
41582
- // else {
41583
- // fromArray.push(domainFrom + ic.baseResi[chnid]);
41584
- // toArray.push(domainTo + ic.baseResi[chnid]);
41585
- // }
41581
+ // fromArray.push(pos2resi[domainFrom]);
41582
+ // toArray.push(pos2resi[domainTo]);
41583
+
41584
+ fromArray.push(domainFrom);
41585
+ toArray.push(domainTo);
41586
+
41587
+ // posFromArray.push(domainFrom);
41588
+ // posToArray.push(domainTo);
41586
41589
 
41587
41590
  resCnt += domainTo - domainFrom + 1;
41588
41591
  for(let j = domainFrom; j <= domainTo; ++j) {
41589
- // resiHash[j+1] = 1;
41590
- let resi = pos2resi[j];
41592
+ // let resi = pos2resi[j];
41593
+ let resi = this.getResiFromNnbiresid(chnid + '_' + j);
41591
41594
  resiHash[resi] = 1;
41592
41595
  }
41593
41596
  }
@@ -41598,21 +41601,22 @@ class AnnoDomain {
41598
41601
 
41599
41602
  if(!ic.resid2domain) ic.resid2domain = {};
41600
41603
  if(!ic.resid2domain[chnid]) ic.resid2domain[chnid] = [];
41601
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
41602
- let from = parseInt(posFromArray[i]);
41603
- let to = parseInt(posToArray[i]);
41604
+ // for(let i = 0, il = posFromArray.length; i < il; ++i) {
41605
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
41606
+ let from = fromArray[i];
41607
+ let to = toArray[i];
41604
41608
  for(let j = from; j <= to; ++j) {
41605
41609
  // 0-based
41606
41610
  let obj = {};
41607
41611
  // let resi = ic.ParserUtilsCls.getResi(chnid, j);
41608
- let resi = pos2resi[j];
41609
- obj[chnid + '_' + resi] = domainName;
41612
+ let resid = ic.ncbi2resid(chnid + '_' + j);
41613
+ obj[resid] = domainName;
41610
41614
  ic.resid2domain[chnid].push(obj);
41611
41615
  }
41612
41616
  }
41613
41617
  }
41614
41618
 
41615
- 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>';
41619
+ 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>';
41616
41620
  let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
41617
41621
  html3 += htmlTmp2 + htmlTmp3 + '<br>';
41618
41622
  let htmlTmp = '<span class="icn3d-seqLine">';
@@ -41652,12 +41656,12 @@ class AnnoDomain {
41652
41656
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
41653
41657
 
41654
41658
  if(me.cfg.blast_rep_id != chnid) { // regular
41655
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
41659
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
41656
41660
  // 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);
41657
- let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
41661
+ let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
41658
41662
 
41659
41663
  html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
41660
- 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>';
41664
+ 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>';
41661
41665
  }
41662
41666
  }
41663
41667
  else { // with potential gaps
@@ -43169,6 +43173,7 @@ class Domain3d {
43169
43173
  //c2b_NewSplitChain(string asymId, let seqLen, let* x0, let* y0, let* z0) { let ic = this.icn3d, me = ic.icn3dui;
43170
43174
  // x0, y0, z0: array of x,y,z coordinates of C-alpha atoms
43171
43175
  //c2b_NewSplitChain(chnid, dcut) { let ic = this.icn3d, me = ic.icn3dui;
43176
+ // this function works for a single chain
43172
43177
  c2b_NewSplitChain(atoms, dcut) { let ic = this.icn3d; ic.icn3dui;
43173
43178
  this.init3ddomain();
43174
43179
 
@@ -43224,14 +43229,11 @@ class Domain3d {
43224
43229
  // pos2resi[i+1] = resi;
43225
43230
  pos2resi[i] = resi;
43226
43231
 
43227
- ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
43228
- // let residNCBI = ic.resid2ncbi[resid];
43229
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
43230
- // pos2resi[pos] = resi;
43231
-
43232
+ // ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
43232
43233
  if(atom.ssend) {
43233
43234
  //substructItem.To = parseInt(resi);
43234
43235
  substructItem.To = i + 1;
43236
+ // substructItem.To = ic.annoDomainCls.getNcbiresiFromResid(resid);
43235
43237
  substructItem.x2 = atom.coord.x;
43236
43238
  substructItem.y2 = atom.coord.y;
43237
43239
  substructItem.z2 = atom.coord.z;
@@ -43246,6 +43248,7 @@ class Domain3d {
43246
43248
  if(atom.ssbegin) {
43247
43249
  //substructItem.From = parseInt(resi);
43248
43250
  substructItem.From = i + 1;
43251
+ // substructItem.From = ic.annoDomainCls.getNcbiresiFromResid(resid);
43249
43252
  substructItem.x1 = atom.coord.x;
43250
43253
  substructItem.y1 = atom.coord.y;
43251
43254
  substructItem.z1 = atom.coord.z;
@@ -43253,17 +43256,19 @@ class Domain3d {
43253
43256
  }
43254
43257
 
43255
43258
  let nsse = substruct.length;
43256
-
43257
- if (nsse <= 3)
43259
+
43260
+ if (nsse <= 3) {
43258
43261
  // too small, can't split or trim
43259
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
43262
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43263
+ return {subdomains: subdomains, substruct: substruct};
43264
+ }
43260
43265
 
43261
43266
  if (nsse > this.MAX_SSE) {
43262
43267
  // we have a problem...
43263
-
43264
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
43268
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43269
+ return {subdomains: subdomains, substruct: substruct};
43265
43270
  }
43266
-
43271
+
43267
43272
  let seqLen = residueArray.length; // + resiOffset;
43268
43273
  //let lastResi = resiArray[seqLen - 1];
43269
43274
  let lastResi = seqLen;
@@ -43584,7 +43589,8 @@ class Domain3d {
43584
43589
  let k = prts[i] - 1;
43585
43590
 
43586
43591
  if ((k < 0) || (k >= substruct.length)) {
43587
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
43592
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43593
+ return {subdomains: subdomains, substruct: substruct};
43588
43594
  }
43589
43595
 
43590
43596
  //SSE_Rec sserec = substruct[k];
@@ -43671,16 +43677,23 @@ class Domain3d {
43671
43677
 
43672
43678
  if (inseg && (rf == 0)) {
43673
43679
  // segment ends
43674
- segments.push(startseg);
43675
- segments.push(i);
43680
+ // segments.push(startseg);
43681
+ // segments.push(i);
43682
+
43683
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, i, pos2resi);
43684
+ segments = segments.concat(resiRangeArray);
43685
+
43676
43686
  inseg = false;
43677
43687
  }
43678
43688
  }
43679
43689
 
43680
43690
  // check for the last segment
43681
43691
  if (inseg) {
43682
- segments.push(startseg);
43683
- segments.push(lastResi);
43692
+ // segments.push(startseg);
43693
+ // segments.push(lastResi);
43694
+
43695
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, lastResi, pos2resi);
43696
+ segments = segments.concat(resiRangeArray);
43684
43697
  }
43685
43698
 
43686
43699
  subdomains.push(segments);
@@ -43701,61 +43714,114 @@ class Domain3d {
43701
43714
  }
43702
43715
  }
43703
43716
 
43704
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi };
43717
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43718
+
43719
+ // return {subdomains: subdomains, substruct: substruct};
43720
+ //subdomains contains NCBI residue numbers
43721
+ return {subdomains: subdomains, substruct: substruct};
43705
43722
  } // end c2b_NewSplitChain
43706
43723
 
43707
- getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
43724
+ standardizeSubstruct(chnid, substruct, pos2resi) { let ic = this.icn3d; ic.icn3dui;
43725
+ // adjust substruct to use NCBI residue number
43726
+ for (let i = 0; i < substruct.length; i++) {
43727
+ //SSE_Rec sserec = substruct[i];
43728
+ let sserec = substruct[i];
43729
+ let FromPos = sserec.From;
43730
+ let ToPos = sserec.To;
43731
+
43732
+ let FromResi = pos2resi[FromPos - 1];
43733
+ let ToResi = pos2resi[ToPos - 1];
43734
+
43735
+ let FromNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + FromResi);
43736
+ let ToNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + ToResi);
43737
+
43738
+ substruct[i].From = FromNcbiResid.substr(FromNcbiResid.lastIndexOf('_') + 1);
43739
+ substruct[i].To = ToNcbiResid.substr(ToNcbiResid.lastIndexOf('_') + 1);
43740
+
43741
+ substruct[i].From = parseInt(substruct[i].From);
43742
+ substruct[i].To = parseInt(substruct[i].To);
43743
+ }
43744
+
43745
+ return substruct;
43746
+ }
43747
+
43748
+ getNcbiresiRangeFromPos(chnid, startPos, endPos, pos2resi) { let ic = this.icn3d; ic.icn3dui;
43749
+ let resiArray = [];
43750
+ for(let i = startPos; i <= endPos; ++i) {
43751
+ let resi = pos2resi[i - 1];
43752
+ let residNCBI = (ic.resid2ncbi[chnid + '_' + resi]) ? ic.resid2ncbi[chnid + '_' + resi] : chnid + '_' + resi;
43753
+ let ncbiresi = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
43754
+ resiArray.push(parseInt(ncbiresi));
43755
+ }
43756
+
43757
+ let resiRangeArray = ic.resid2specCls.resi2range(resiArray);
43758
+
43759
+ return resiRangeArray;
43760
+ }
43761
+
43762
+ /*
43763
+ // this function works for atoms in a single chain
43764
+ // getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
43765
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
43708
43766
  let result = this.c2b_NewSplitChain(atoms);
43709
43767
 
43710
43768
  let subdomains = result.subdomains;
43711
43769
  let substruct = result.substruct;
43712
- let pos2resi = result.pos2resi;
43770
+ // let pos2resi = result.pos2resi;
43713
43771
 
43714
- let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
43715
- let residueArray = Object.keys(residueHash);
43716
- let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
43717
43772
 
43718
- if(bForceOneDomain) subdomains = [];
43773
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
43774
+ // let residueArray = Object.keys(residueHash);
43775
+ // let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
43719
43776
 
43720
- //the whole structure is also considered as a large domain
43721
- //if(subdomains.length == 0) {
43722
- //subdomains.push([parseInt(ic.chainsSeq[chnid][0].resi), parseInt(ic.chainsSeq[chnid][ic.chainsSeq[chnid].length - 1].resi)]);
43777
+ let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
43778
+ let chnid = firstAtom.structure + '_' + firstAtom.chain;
43723
43779
 
43724
- // subdomains.push([parseInt(residueArray[0].substr(residueArray[0].lastIndexOf('_') + 1)),
43725
- // parseInt(residueArray[residueArray.length-1].substr(residueArray[residueArray.length-1].lastIndexOf('_') + 1))]);
43780
+ // if(bForceOneDomain) subdomains = [];
43726
43781
 
43727
- // use position based
43728
- subdomains.push([1, residueArray.length]);
43729
-
43730
- //}
43782
+ //the whole structure is also considered as a large domain
43783
+ if(subdomains.length == 0) {
43784
+ let resid1 = residueArray[0];
43785
+ let resid2 = residueArray[residueArray.length - 1];
43786
+ let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
43787
+ let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
43788
+ subdomains.push([parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1)), parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1))]);
43789
+ }
43731
43790
 
43732
43791
  // 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], ...]} ] }
43733
43792
  let jsonStr = '{"data": [';
43793
+ //merge all subdomains into one domain
43794
+ jsonStr += '{"ss": ['; //secondary structure
43795
+
43796
+ let ssCnt = 0, startAll = 999, endAll = -999;
43734
43797
  for(let i = 0, il = subdomains.length; i < il; ++i) {
43735
- if(i > 0) jsonStr += ', ';
43736
- //secondary structure
43737
- jsonStr += '{"ss": [';
43738
- let ssCnt = 0;
43798
+ // if(i > 0) jsonStr += ', ';
43799
+ // jsonStr += '{"ss": ['; //secondary structure
43800
+
43739
43801
  for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
43740
43802
  let start = subdomains[i][j];
43741
43803
  let end = subdomains[i][j + 1];
43742
-
43804
+
43805
+ if(start < startAll) startAll = start;
43806
+ if(end > endAll) endAll = end;
43807
+
43743
43808
  for(let k = 0, kl = substruct.length; k < kl; ++k) {
43744
43809
  //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
43745
43810
  //sstype: 1 (helix), 2 (sheet)
43746
43811
  let sstype = (substruct[k].Sheet) ? 2 : 1;
43747
- let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
43748
- let to = pos2resi[substruct[k].To - 1];
43812
+ // let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
43813
+ // let to = pos2resi[substruct[k].To - 1];
43749
43814
 
43750
43815
  // 1-based residue numbers
43751
43816
  let fromPos = substruct[k].From;
43752
43817
  let toPos = substruct[k].To;
43753
43818
 
43754
- let residFrom = chnid + "_" + from;
43819
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
43755
43820
  let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
43821
+
43756
43822
  if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
43757
43823
 
43758
- let residTo = chnid + "_" + to;
43824
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
43759
43825
  let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
43760
43826
  if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
43761
43827
 
@@ -43767,45 +43833,170 @@ class Domain3d {
43767
43833
  }
43768
43834
  }
43769
43835
  }
43770
- jsonStr += ']';
43836
+ }
43837
+ jsonStr += ']';
43838
+
43839
+ // domain
43840
+ jsonStr += ', "domain": [';
43841
+ let domainCnt = 0;
43842
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
43771
43843
 
43772
- // domain
43773
- jsonStr += ', "domain": [';
43774
- let domainCnt = 0;
43775
- for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
43776
- let start = subdomains[i][j];
43777
- let end = subdomains[i][j + 1];
43844
+ // resi should be the continuous number starting from 1. make this correction in the backend
43845
+ for(let j = startAll; j <= endAll; ++j) {
43846
+ let ncbiResid = chnid + '_' + j;
43847
+ let resid = ic.ncbi2resid[ncbiResid];
43848
+
43849
+ let pos = j;
43850
+
43851
+ if(domainCnt > 0) jsonStr += ', ';
43852
+
43853
+ if(!residueHash.hasOwnProperty(resid)) {
43854
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
43855
+ }
43856
+ else {
43857
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43858
+
43859
+ //domain: resi, restype, x, y, z
43860
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
43861
+
43862
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
43863
+ }
43864
+
43865
+ ++domainCnt;
43866
+ }
43867
+ jsonStr += ']}';
43868
+
43869
+ jsonStr += ']}';
43870
+
43871
+ return jsonStr;
43872
+ }
43873
+ */
43874
+ // this function works for atoms in a single chain
43875
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
43876
+ // let result = this.c2b_NewSplitChain(atoms);
43877
+
43878
+ // let subdomains = result.subdomains;
43879
+ // let substruct = result.substruct;
43880
+
43881
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
43882
+ let residueArray = Object.keys(residueHash);
43883
+ let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
43884
+
43885
+ // let resid1 = residueArray[0];
43886
+ // let resid2 = residueArray[residueArray.length - 1];
43887
+ // let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
43888
+ // let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
43889
+ // let startAll = parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1));
43890
+ // let endAll = parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1));
43891
+
43892
+ let substruct = [];
43893
+ let substructItem = {};
43894
+ let pos2resi = {}; // 0-based
43895
+ let startAll = 999, endAll = -999;
43896
+ for(let i = 0; i < residueArray.length; ++i) {
43897
+ let resid = residueArray[i];
43898
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43778
43899
 
43779
- for(let k = 0, kl = residueArray.length; k < kl; ++k) {
43780
- let resid = residueArray[k];
43900
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
43901
+ pos2resi[i] = resi;
43902
+
43903
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
43904
+ let ncbiresi = parseInt(ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1));
43905
+
43906
+ if(ncbiresi < startAll) startAll = ncbiresi;
43907
+ if(ncbiresi > endAll) endAll = ncbiresi;
43908
+
43909
+ if(atom.ssend) {
43910
+ substructItem.To = i + 1;
43911
+ substructItem.x2 = atom.coord.x;
43912
+ substructItem.y2 = atom.coord.y;
43913
+ substructItem.z2 = atom.coord.z;
43781
43914
 
43782
- // let resi = resid.substr(resid.lastIndexOf('_') + 1);
43783
- // let residNCBI = ic.resid2ncbi[resid];
43784
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
43785
- let pos = k + 1;
43915
+ substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
43916
+
43917
+ substruct.push(substructItem);
43918
+ substructItem = {};
43919
+ }
43920
+
43921
+ // a residue could be both start and end. check ssend first, then check ssbegin
43922
+ if(atom.ssbegin) {
43923
+ substructItem.From = i + 1;
43924
+ substructItem.x1 = atom.coord.x;
43925
+ substructItem.y1 = atom.coord.y;
43926
+ substructItem.z1 = atom.coord.z;
43927
+ }
43928
+ }
43929
+
43930
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
43931
+
43932
+ // 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], ...]} ] }
43933
+ let jsonStr = '{"data": [';
43934
+ //merge all subdomains into one domain
43935
+ jsonStr += '{"ss": ['; //secondary structure
43936
+
43937
+ let ssCnt = 0;
43938
+ for(let k = 0, kl = substruct.length; k < kl; ++k) {
43939
+ //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
43940
+ //sstype: 1 (helix), 2 (sheet)
43941
+ let sstype = (substruct[k].Sheet) ? 2 : 1;
43942
+
43943
+ // 1-based residue numbers
43944
+ let fromPos = substruct[k].From;
43945
+ let toPos = substruct[k].To;
43946
+
43947
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
43948
+ let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
43949
+ if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
43950
+
43951
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
43952
+ let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
43953
+ if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
43954
+
43955
+ // if(fromPos >= start && toPos <= end) {
43956
+ if(ssCnt > 0) jsonStr += ', ';
43957
+ jsonStr += '[' + sstype + ',' + fromPos + ',' + toPos + ',' + substruct[k].x1.toFixed(2) + ',' + substruct[k].y1.toFixed(2) + ','
43958
+ + substruct[k].z1.toFixed(2) + ',' + substruct[k].x2.toFixed(2) + ',' + substruct[k].y2.toFixed(2) + ',' + substruct[k].z2.toFixed(2) + ']';
43959
+ ++ssCnt;
43960
+ // }
43961
+ }
43962
+
43963
+ jsonStr += ']';
43786
43964
 
43787
- //let resid = chnid + "_" + resi;
43788
- let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43789
-
43790
- if(!atom) continue;
43791
- if(!ic.hAtoms.hasOwnProperty(atom.serial)) continue;
43792
-
43793
- //domain: resi, restype, x, y, z
43794
- let restype = me.parasCls.resn2restype[atom.resn];
43795
- if(restype !== undefined && pos >= start && pos <= end) {
43796
- if(domainCnt > 0) jsonStr += ', ';
43797
- jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ','
43798
- + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
43799
- ++domainCnt;
43800
- }
43801
- }
43965
+ // domain
43966
+ jsonStr += ', "domain": [';
43967
+ let domainCnt = 0;
43968
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
43969
+
43970
+ // resi should be the continuous number starting from 1. make this correction in the backend
43971
+ for(let j = startAll; j <= endAll; ++j) {
43972
+ let ncbiResid = chnid + '_' + j;
43973
+ let resid = ic.ncbi2resid[ncbiResid];
43974
+
43975
+ let pos = j;
43976
+
43977
+ if(domainCnt > 0) jsonStr += ', ';
43978
+
43979
+ if(!residueHash.hasOwnProperty(resid)) {
43980
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
43981
+ }
43982
+ else {
43983
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
43984
+
43985
+ //domain: resi, restype, x, y, z
43986
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
43987
+
43988
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
43802
43989
  }
43803
- jsonStr += ']}';
43990
+
43991
+ ++domainCnt;
43804
43992
  }
43805
43993
  jsonStr += ']}';
43806
43994
 
43995
+ jsonStr += ']}';
43996
+
43807
43997
  return jsonStr;
43808
43998
  }
43999
+
43809
44000
  }
43810
44001
 
43811
44002
  /**
@@ -43903,27 +44094,12 @@ class AddTrack {
43903
44094
  });
43904
44095
 
43905
44096
  // Isoform Alignment
43906
- me.myEventCls.onIds("#" + ic.pre + "addtrack_button2c", "click", async function(e) { let ic = thisClass.icn3d;
44097
+ me.myEventCls.onIds("#" + ic.pre + "addtrack_button2c", "click", async function(e) { thisClass.icn3d;
43907
44098
  e.stopImmediatePropagation();
43908
44099
  //e.preventDefault();
43909
44100
  dialog.dialog( "close" );
43910
44101
 
43911
- let chainid = $("#" + ic.pre + "track_chainid").val();
43912
- let geneid = $("#" + ic.pre + "track_geneid").val();
43913
- if(!geneid) {
43914
- var aaa = 1; //alert("Please fill in the Gene ID...");
43915
- return;
43916
- }
43917
-
43918
- let startpos = $("#" + ic.pre + "fasta_startpos2").val();
43919
- if(!startpos) startpos = 1;
43920
-
43921
- //let colorseqby = $("#" + ic.pre + "colorseqby2").val();
43922
- //let type =(colorseqby == 'identity') ? 'identity' : 'custom';
43923
-
43924
- let type = 'identity';
43925
-
43926
- await thisClass.addExonTracks(chainid, geneid, startpos, type);
44102
+ await thisClass.addExonTracksWrap();
43927
44103
  });
43928
44104
 
43929
44105
  // BED file
@@ -45514,6 +45690,25 @@ class AddTrack {
45514
45690
  return acclistTmp;
45515
45691
  }
45516
45692
 
45693
+ async addExonTracksWrap() { let ic = this.icn3d; ic.icn3dui;
45694
+ let chainid = $("#" + ic.pre + "track_chainid").val();
45695
+ let geneid = $("#" + ic.pre + "track_geneid").val();
45696
+ if(!geneid) {
45697
+ var aaa = 1; //alert("Please fill in the Gene ID...");
45698
+ return;
45699
+ }
45700
+
45701
+ let startpos = $("#" + ic.pre + "fasta_startpos2").val();
45702
+ if(!startpos) startpos = 1;
45703
+
45704
+ //let colorseqby = $("#" + ic.pre + "colorseqby2").val();
45705
+ //let type =(colorseqby == 'identity') ? 'identity' : 'custom';
45706
+
45707
+ let type = 'identity';
45708
+
45709
+ await thisClass.addExonTracks(chainid, geneid, startpos, type);
45710
+ }
45711
+
45517
45712
  async addExonTracks(chainid, geneid, startpos, type) { let ic = this.icn3d, me = ic.icn3dui;
45518
45713
  let thisClass = this;
45519
45714
 
@@ -45907,7 +46102,6 @@ class Annotation {
45907
46102
  if($("#" + ic.pre + "anno_transmem").length) $("#" + ic.pre + "anno_transmem")[0].checked = false;
45908
46103
  }
45909
46104
  async setAnnoTabIg(bSelection, template) { let ic = this.icn3d; ic.icn3dui;
45910
-
45911
46105
  await this.updateIg(bSelection, template);
45912
46106
 
45913
46107
  $("[id^=" + ic.pre + "ig]").show();
@@ -46248,7 +46442,7 @@ class Annotation {
46248
46442
 
46249
46443
  async updateIg(bSelection, template) { let ic = this.icn3d, me = ic.icn3dui;
46250
46444
  ic.opts['color'] = 'ig strand';
46251
-
46445
+
46252
46446
  // if(!bSelection && !template) {
46253
46447
  if(!bSelection) {
46254
46448
  // select all protein chains
@@ -46267,11 +46461,13 @@ class Annotation {
46267
46461
  }
46268
46462
 
46269
46463
  ic.bRunRefnumAgain = true;
46270
- for(let chainid in ic.protein_chainid) {
46464
+ let chainidHash = (!bSelection) ? ic.protein_chainid : ic.firstAtomObjCls.getChainsFromAtoms(ic.hAtoms);
46465
+ for(let chainid in chainidHash) {
46466
+ // showIgRefNum() in showIg() runs for all chains
46271
46467
  await ic.annoIgCls.showIg(chainid, template);
46272
46468
  ic.bRunRefnumAgain = false; // run it once for all chains
46273
46469
  }
46274
-
46470
+
46275
46471
  if(ic.bShowRefnum) {
46276
46472
  ic.hlUpdateCls.updateHlAll();
46277
46473
  ic.drawCls.draw();
@@ -47708,11 +47904,12 @@ class HlSeq {
47708
47904
  ic.bAlignSeq = false;
47709
47905
  ic.bAnnotations = true;
47710
47906
  }
47711
-
47907
+
47712
47908
  if(ic.bSelectResidue === false && !ic.bShift && !ic.bCtrl) {
47909
+ // if(!ic.bShift && !ic.bCtrl) {
47713
47910
  ic.selectionCls.removeSelection();
47714
47911
  }
47715
-
47912
+
47716
47913
  // select residues
47717
47914
  $("span.ui-selected", this).each(function() {
47718
47915
  let id = $(this).attr('id');
@@ -47723,11 +47920,12 @@ class HlSeq {
47723
47920
  });
47724
47921
 
47725
47922
  ic.selectionCls.saveSelectionPrep(true);
47726
- ic.selectionCls.saveSelection(undefined, undefined, true);
47923
+ //ic.selectionCls.saveSelection(undefined, undefined, true);
47924
+ // do not use selected residues, use ic.hAtoms instead
47925
+ ic.selectionCls.saveSelection(undefined, undefined, false);
47727
47926
 
47728
47927
  //ic.residueLabelsCls.addResidueLabels(ic.hAtoms, false, 0.5);
47729
47928
  ic.hlObjectsCls.addHlObjects(); // render() is called
47730
-
47731
47929
  // get all chainid in the selected residues
47732
47930
  let chainHash = {};
47733
47931
  for(let residueid in ic.selectedResidues) {
@@ -47810,7 +48008,9 @@ class HlSeq {
47810
48008
  thisClass.selectResidues(id, this);
47811
48009
 
47812
48010
  ic.selectionCls.saveSelectionPrep(true);
47813
- ic.selectionCls.saveSelection(undefined, undefined, true);
48011
+ //ic.selectionCls.saveSelection(undefined, undefined, true);
48012
+ // do not use selected residues, use ic.hAtoms instead
48013
+ ic.selectionCls.saveSelection(undefined, undefined, false);
47814
48014
  }
47815
48015
  //});
47816
48016
 
@@ -48014,8 +48214,9 @@ class HlSeq {
48014
48214
  residueid = ic.ncbi2resid[residNCBI];
48015
48215
  }
48016
48216
  else if($(that).attr('3ddomain') !== undefined) {
48017
- // the position of residues with coordinates
48018
- residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
48217
+ // NCBI residue numbers
48218
+ // residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
48219
+ residueid = ic.ncbi2resid[chainid + '_' + j];
48019
48220
  }
48020
48221
  else {
48021
48222
  residueid = chainid + '_' + (j+1).toString();
@@ -48135,9 +48336,10 @@ class HlSeq {
48135
48336
  if(me.bNode) return;
48136
48337
 
48137
48338
  if(ic.bSelectResidue === false && !ic.bShift && !ic.bCtrl) {
48339
+ // if(!ic.bShift && !ic.bCtrl) {
48138
48340
  ic.selectionCls.removeSelection();
48139
48341
  }
48140
-
48342
+
48141
48343
  if(id !== undefined && id !== '') {
48142
48344
  // add "align_" in front of id so that full sequence and aligned sequence will not conflict
48143
48345
  //if(id.substr(0, 5) === 'align') id = id.substr(5);
@@ -48698,7 +48900,7 @@ class LineGraph {
48698
48900
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
48699
48901
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
48700
48902
  let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
48701
- let linkedNodeCnt = {}, linkedNodeInterDiff = {};
48903
+ let linkedNodeCnt = {}, linkedNodeInterDiff = {}, linkedNodeInterDiffBool = {};
48702
48904
 
48703
48905
  for(let i = 0, il = structureArray.length; i < il; ++i) {
48704
48906
  nodeArray1Split[i] = [];
@@ -48757,13 +48959,15 @@ class LineGraph {
48757
48959
  linkedNodeInterDiff[mappingid] = link.n;
48758
48960
  }
48759
48961
  else {
48760
- ++linkedNodeCnt[mappingid];
48761
- linkedNodeInterDiff[mappingid] -= link.n; // show difference
48962
+ ++linkedNodeCnt[mappingid];
48963
+ linkedNodeInterDiff[mappingid] += link.n;
48964
+
48965
+ linkedNodeInterDiffBool[mappingid] = (linkedNodeInterDiff[mappingid] / link.n == linkedNodeCnt[mappingid]) ? 0 : 1;
48762
48966
  }
48763
48967
  }
48764
48968
  }
48765
48969
  }
48766
-
48970
+
48767
48971
  // do not combine with the above section since linkedNodeCnt was pre-populated above
48768
48972
  // set linkArraySplitCommon and nameHashSplitCommon
48769
48973
  // set linkArraySplitDiff and nameHashSplitDiff
@@ -48809,7 +49013,7 @@ class LineGraph {
48809
49013
  linkDiff.source += separatorDiff + ic.chainsMapping[chainid1][resid1];
48810
49014
  linkDiff.target += separatorDiff + ic.chainsMapping[chainid2][resid2];
48811
49015
 
48812
- if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiff[mappingid] == 0) {
49016
+ if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiffBool[mappingid] == 0) {
48813
49017
  linkArraySplitCommon[index].push(linkCommon);
48814
49018
  }
48815
49019
  else {
@@ -49506,18 +49710,20 @@ class GetGraph {
49506
49710
  return lineGraphStr;
49507
49711
  }
49508
49712
 
49509
- updateGraphColor() { let ic = this.icn3d, me = ic.icn3dui;
49713
+ updateGraphColor() { let ic = this.icn3d; ic.icn3dui;
49510
49714
  // change graph color
49511
49715
 
49716
+ // do not update the graph for now
49717
+ /*
49512
49718
  if(ic.graphStr !== undefined) {
49513
49719
  let graphJson = JSON.parse(ic.graphStr);
49514
- let resid2color = {};
49720
+ let resid2color = {}
49515
49721
  for(let resid in ic.residues) {
49516
49722
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
49517
49723
  resid2color[resid] = atom.color.getHexString().toUpperCase();
49518
49724
  }
49519
49725
 
49520
- let target2resid = {};
49726
+ let target2resid = {}
49521
49727
  for(let i = 0, il = graphJson.nodes.length; i < il; ++i) {
49522
49728
  let node = graphJson.nodes[i];
49523
49729
  //node.r: 1_1_1KQ2_A_1
@@ -49546,6 +49752,7 @@ class GetGraph {
49546
49752
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
49547
49753
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
49548
49754
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
49755
+ */
49549
49756
  }
49550
49757
 
49551
49758
  handleForce() { let ic = this.icn3d, me = ic.icn3dui;
@@ -51709,7 +51916,7 @@ class ContactMap {
51709
51916
 
51710
51917
  let graphStr = '{\n';
51711
51918
 
51712
- let struc1 = (ic.structures.length > 0) ? ic.structures[0] : ic.defaultPdbId;
51919
+ let struc1 = (Object.keys(ic.structures).length > 0) ? ic.structures[0] : ic.defaultPdbId;
51713
51920
  let len1 = nodeArray1.length,
51714
51921
  len2 = nodeArray2.length;
51715
51922
  let factor = 1;
@@ -52243,6 +52450,7 @@ class ChainalignParser {
52243
52450
  let allPromise = Promise.allSettled(ajaxArray);
52244
52451
  // try {
52245
52452
  let dataArray = await allPromise;
52453
+
52246
52454
  await thisClass.downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray, indexArray, mmdbid_t, struArray);
52247
52455
  // }
52248
52456
  // catch(err) {
@@ -52846,13 +53054,13 @@ class ChainalignParser {
52846
53054
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
52847
53055
  && align !== undefined && JSON.stringify(align).indexOf('Oops there was a problem') === -1
52848
53056
  ) {
52849
- if((align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53057
+ if((align === "error" || align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
52850
53058
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
52851
53059
  ic.q_trans_sub[index] = {"x":0, "y":0, "z":0};
52852
53060
  ic.q_rotation[index] = {"x1":1, "y1":0, "z1":0, "x2":0, "y2":1, "z2":0, "x3":0, "y3":0, "z3":1};
52853
53061
  ic.qt_start_end[index] = undefined;
52854
53062
  }
52855
- else if(align === undefined || align.length == 0) {
53063
+ else if(align === "error" || align === undefined || align.length == 0) {
52856
53064
  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.');
52857
53065
 
52858
53066
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
@@ -52883,14 +53091,16 @@ class ChainalignParser {
52883
53091
  ic.qt_start_end[index] = align[0].segs;
52884
53092
 
52885
53093
  let rmsd = align[0].super_rmsd;
53094
+ let rmsdStr = (rmsd) ? rmsd.toPrecision(4) : rmsd;
53095
+ let scoreStr = (align[0].score) ? align[0].score.toPrecision(4) : align[0].score;
52886
53096
 
52887
- let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
52888
- if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
53097
+ let logStr = "alignment RMSD: " + rmsdStr;
53098
+ if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + scoreStr;
52889
53099
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
52890
- let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
53100
+ let html = "<br><b>Alignment RMSD</b>: " + rmsdStr + " &#8491;<br>";
52891
53101
  if(me.cfg.aligntool == 'tmalign') {
52892
- html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
52893
- ic.tmscore = align[0].score.toPrecision(4);
53102
+ html += "<b>TM-score</b>: " + scoreStr + "<br><br>";
53103
+ ic.tmscore = scoreStr;
52894
53104
  }
52895
53105
 
52896
53106
  $("#" + ic.pre + "dl_rmsd_html").html(html);
@@ -53037,6 +53247,7 @@ class ChainalignParser {
53037
53247
  let allPromise = Promise.allSettled(ajaxArray);
53038
53248
  // try {
53039
53249
  let dataArray = await allPromise;
53250
+
53040
53251
  await thisClass.parseMMdbAfData(dataArray, structArray, bQuery, vastplusAtype);
53041
53252
  if(vastplusAtype === undefined) ic.ParserUtilsCls.hideLoading();
53042
53253
  // }
@@ -53069,13 +53280,9 @@ class ChainalignParser {
53069
53280
 
53070
53281
  //if(!ic.bCommandLoad && !bQuery) ic.init(); // remove all previously loaded data
53071
53282
 
53072
- let hAtoms = {}, hAtomsTmp = {};
53283
+ let hAtoms = {};
53073
53284
  let bLastQuery = false;
53074
53285
 
53075
- let opts = {};
53076
-
53077
- opts['color'] = (structArray.length > 1) ? 'structure' : ((structArray[0].length > 5) ? 'confidence' : 'chain');
53078
-
53079
53286
  for(let i = 0, il = structArray.length; i < il; ++i) {
53080
53287
  if(i == structArray.length - 1) bLastQuery = true;
53081
53288
 
@@ -53090,24 +53297,30 @@ class ChainalignParser {
53090
53297
  targetOrQuery = 'query';
53091
53298
  bAppend = true;
53092
53299
  }
53093
-
53300
+
53094
53301
  //if(structArray[i].length > 4) {
53095
53302
  if(isNaN(structArray[i]) && structArray[i].length > 5) { // PDB ID plus postfix could be 5
53096
53303
  //let bNoDssp = true;
53097
53304
  let bNoDssp = false; // get secondary structure info
53098
- hAtomsTmp = await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
53305
+ await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
53099
53306
  }
53100
53307
  else {
53101
53308
  let bNoSeqalign = true;
53102
53309
  let pdbid = structArray[i];
53103
- hAtomsTmp = await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
53310
+
53311
+ //hAtomsTmp contains all atoms
53312
+ await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
53104
53313
  }
53105
53314
 
53106
- hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
53315
+ // hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
53107
53316
  }
53108
53317
 
53109
- // add color only for the newly loaded structures
53110
- ic.setColorCls.setColorByOptions(opts, hAtoms);
53318
+ let structArrayAll = Object.keys(ic.structures);
53319
+
53320
+ ic.opts['color'] = (structArrayAll.length > 1) ? 'structure' : ((structArrayAll[0].length > 5) ? 'confidence' : 'chain');
53321
+
53322
+ // add color for all structures
53323
+ ic.setColorCls.setColorByOptions(ic.opts, hAtoms);
53111
53324
 
53112
53325
  await ic.ParserUtilsCls.renderStructure();
53113
53326
 
@@ -53137,15 +53350,6 @@ class ChainalignParser {
53137
53350
  if(vastplusAtype == 2) me.cfg.aligntool = 'tmalign';
53138
53351
  await ic.vastplusCls.vastplusAlign(structArray, vastplusAtype);
53139
53352
  }
53140
-
53141
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
53142
-
53143
- // if(Object.keys(ic.structures).length == 1 && me.cfg.mmdbafid.length > 5) {
53144
- // ic.ParserUtilsCls.checkMemProtein(me.cfg.mmdbafid);
53145
- // }
53146
- // else {
53147
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
53148
- // }
53149
53353
  }
53150
53354
  }
53151
53355
 
@@ -54613,24 +54817,32 @@ class MmcifParser {
54613
54817
  if(data.emd !== undefined) ic.emd = data.emd;
54614
54818
  if(data.organism !== undefined) ic.organism = data.organism;
54615
54819
 
54616
- if(ic.emd !== undefined) {
54617
- $("#" + ic.pre + "mapWrapper1").hide();
54618
- $("#" + ic.pre + "mapWrapper2").hide();
54619
- $("#" + ic.pre + "mapWrapper3").hide();
54620
- }
54621
- else {
54622
- $("#" + ic.pre + "emmapWrapper1").hide();
54623
- $("#" + ic.pre + "emmapWrapper2").hide();
54624
- $("#" + ic.pre + "emmapWrapper3").hide();
54625
- }
54626
-
54627
54820
  await ic.opmParserCls.loadOpmData(data, mmcifid, undefined, 'mmcif');
54821
+
54822
+ ic.opmParserCls.modifyUIMapAssembly();
54628
54823
  }
54629
54824
  else {
54630
- //var aaa = 1; //alert('invalid atoms data.');
54631
54825
  return false;
54632
54826
  }
54633
54827
  }
54828
+
54829
+ async loadMultipleMmcifData(data, mmcifid, bAppend) { let ic = this.icn3d; ic.icn3dui;
54830
+ let bText = true;
54831
+ ic.loadCIFCls.loadCIF(data, mmcifid, bText, bAppend);
54832
+
54833
+ if(Object.keys(ic.structures).length > 1) {
54834
+ ic.opts['color'] = 'structure';
54835
+ }
54836
+
54837
+ ic.opmParserCls.modifyUIMapAssembly();
54838
+
54839
+ ic.pdbParserCls.addSecondary(bAppend);
54840
+
54841
+ // ic.setStyleCls.setAtomStyleByOptions(ic.opts);
54842
+ // ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
54843
+
54844
+ // await ic.ParserUtilsCls.renderStructure();
54845
+ }
54634
54846
  }
54635
54847
 
54636
54848
  /**
@@ -55473,26 +55685,26 @@ class BcifParser {
55473
55685
  let molecueType;
55474
55686
  if(atom_hetatm == "ATOM") {
55475
55687
  if(resn.length == 3) {
55476
- molecueType = "p"; // protein
55688
+ molecueType = "protein"; //"p"; // protein
55477
55689
  }
55478
55690
  else {
55479
- molecueType = "n"; // nucleotide
55691
+ molecueType = "nucleotide"; //"n"; // nucleotide
55480
55692
  }
55481
55693
  }
55482
55694
  else {
55483
55695
  if(resn == "WAT" || resn == "HOH") {
55484
- molecueType = "s"; // solvent
55696
+ molecueType = "solvent"; //"s"; // solvent
55485
55697
  chain = 'Misc';
55486
55698
  }
55487
55699
  else {
55488
- molecueType = "l"; // ligands or ions
55700
+ molecueType = "ligand"; //"l"; // ligands or ions
55489
55701
  chain = resn;
55490
55702
  }
55491
55703
  }
55492
55704
 
55493
55705
  // C-alpha only for large structure
55494
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
55495
- || (molecueType == "n" && !(name == "P")) ) ) continue;
55706
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
55707
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
55496
55708
  // skip alternative atoms
55497
55709
  if(alt == "B") continue;
55498
55710
 
@@ -55515,7 +55727,7 @@ class BcifParser {
55515
55727
  // }
55516
55728
  }
55517
55729
 
55518
- if(molecueType == 's' || molecueType == "l") {
55730
+ if(molecueType == 'solvent' || molecueType == "ligand") {
55519
55731
  let seq = {};
55520
55732
  if(!ligSeqHash.hasOwnProperty(chain)) {
55521
55733
  ligSeqHash[chain] = [];
@@ -55653,26 +55865,26 @@ class BcifParser {
55653
55865
  let molecueType;
55654
55866
  if(atom_hetatm == "ATOM") {
55655
55867
  if(resn.length == 3) {
55656
- molecueType = "p"; // protein
55868
+ molecueType = "protein"; // protein
55657
55869
  }
55658
55870
  else {
55659
- molecueType = "n"; // nucleotide
55871
+ molecueType = "nucleotide"; // nucleotide
55660
55872
  }
55661
55873
  }
55662
55874
  else {
55663
55875
  if(resn == "WAT" || resn == "HOH") {
55664
- molecueType = "s"; // solvent
55876
+ molecueType = "solvent"; // solvent
55665
55877
  chain = 'Misc';
55666
55878
  }
55667
55879
  else {
55668
- molecueType = "l"; // ligands or ions
55880
+ molecueType = "ligand"; // ligands or ions
55669
55881
  chain = resn;
55670
55882
  }
55671
55883
  }
55672
55884
 
55673
55885
  // C-alpha only for large structure
55674
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
55675
- || (molecueType == "n" && !(name == "P")) ) ) continue;
55886
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
55887
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
55676
55888
  // skip alternative atoms
55677
55889
  if(alt == "B") continue;
55678
55890
 
@@ -56222,6 +56434,43 @@ class OpmParser {
56222
56434
  }
56223
56435
  }
56224
56436
 
56437
+ modifyUIMapAssembly() { let ic = this.icn3d, me = ic.icn3dui;
56438
+ if(!me.bNode) {
56439
+ if(ic.emd !== undefined) {
56440
+ $("#" + ic.pre + "mapWrapper1").hide();
56441
+ $("#" + ic.pre + "mapWrapper2").hide();
56442
+ $("#" + ic.pre + "mapWrapper3").hide();
56443
+ }
56444
+ else {
56445
+ $("#" + ic.pre + "emmapWrapper1").hide();
56446
+ $("#" + ic.pre + "emmapWrapper2").hide();
56447
+ $("#" + ic.pre + "emmapWrapper3").hide();
56448
+ }
56449
+
56450
+ if(Object.keys(ic.structures).length == 1) {
56451
+ $("#" + ic.pre + "alternateWrapper").hide();
56452
+ }
56453
+ /*
56454
+ // load assembly info
56455
+ if(type === 'mmcif') {
56456
+ let assembly =(data.assembly !== undefined) ? data.assembly : [];
56457
+ for(let i = 0, il = assembly.length; i < il; ++i) {
56458
+ if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
56459
+
56460
+ for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
56461
+ ic.biomtMatrices[i].elements[j] = assembly[i][j];
56462
+ }
56463
+ }
56464
+ }
56465
+ */
56466
+ if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
56467
+ $("#" + ic.pre + "assemblyWrapper").show();
56468
+
56469
+ ic.asuCnt = ic.biomtMatrices.length;
56470
+ }
56471
+ }
56472
+ }
56473
+
56225
56474
  async parseAtomData(data, pdbid, bFull, type, pdbid2, bText) { let ic = this.icn3d, me = ic.icn3dui;
56226
56475
  /*
56227
56476
  if(type === 'mmtf') {
@@ -56238,38 +56487,7 @@ class OpmParser {
56238
56487
  ic.loadCIFCls.loadCIF(data, pdbid, bText);
56239
56488
  // }
56240
56489
 
56241
- if(ic.emd !== undefined) {
56242
- $("#" + ic.pre + "mapWrapper1").hide();
56243
- $("#" + ic.pre + "mapWrapper2").hide();
56244
- $("#" + ic.pre + "mapWrapper3").hide();
56245
- }
56246
- else {
56247
- $("#" + ic.pre + "emmapWrapper1").hide();
56248
- $("#" + ic.pre + "emmapWrapper2").hide();
56249
- $("#" + ic.pre + "emmapWrapper3").hide();
56250
- }
56251
-
56252
- if(Object.keys(ic.structures).length == 1) {
56253
- $("#" + ic.pre + "alternateWrapper").hide();
56254
- }
56255
- /*
56256
- // load assembly info
56257
- if(type === 'mmcif') {
56258
- let assembly =(data.assembly !== undefined) ? data.assembly : [];
56259
- for(let i = 0, il = assembly.length; i < il; ++i) {
56260
- if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
56261
-
56262
- for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
56263
- ic.biomtMatrices[i].elements[j] = assembly[i][j];
56264
- }
56265
- }
56266
- }
56267
- */
56268
- if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
56269
- $("#" + ic.pre + "assemblyWrapper").show();
56270
-
56271
- ic.asuCnt = ic.biomtMatrices.length;
56272
- }
56490
+ this.modifyUIMapAssembly();
56273
56491
 
56274
56492
  ic.setStyleCls.setAtomStyleByOptions(ic.opts);
56275
56493
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
@@ -56463,6 +56681,12 @@ class PdbParser {
56463
56681
  }
56464
56682
  }
56465
56683
 
56684
+ await this.addSecondary(bAppend, bNoDssp);
56685
+
56686
+ return hAtoms;
56687
+ }
56688
+
56689
+ async addSecondary(bAppend, bNoDssp) { let ic = this.icn3d, me = ic.icn3dui;
56466
56690
  // calculate secondary structures if not available
56467
56691
  // DSSP only works for structures with all atoms. The Calpha only structures didn't work
56468
56692
  //if(!ic.bSecondaryStructure && !bCalphaOnly) {
@@ -56486,8 +56710,6 @@ class PdbParser {
56486
56710
 
56487
56711
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
56488
56712
  }
56489
-
56490
- return hAtoms;
56491
56713
  }
56492
56714
 
56493
56715
  async applyCommandDssp(bAppend) { let ic = this.icn3d, me = ic.icn3dui;
@@ -57325,23 +57547,27 @@ class RealignParser {
57325
57547
 
57326
57548
  for(let s = 0, sl = structArray.length; s < sl; ++s) {
57327
57549
  let struct1 = structArray[s];
57550
+
57328
57551
  let chainidArray1 = Object.keys(struct2domain[struct1]);
57329
57552
  if(chainidArray1.length == 0) continue;
57330
- for(let t = s+1, tl = structArray.length; t < tl; ++t) {
57331
- let struct2 = structArray[t];
57332
- let chainidArray2 = Object.keys(struct2domain[struct2]);
57333
- if(chainidArray2.length == 0) continue;
57334
-
57335
- for(let i = 0, il = chainidArray1.length; i < il; ++i) {
57336
- let chainid1 = chainidArray1[i];
57337
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
57553
+
57554
+ for(let i = 0, il = chainidArray1.length; i < il; ++i) {
57555
+ let chainid1 = chainidArray1[i];
57556
+ let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
57557
+
57558
+ for(let t = s+1, tl = structArray.length; t < tl; ++t) {
57559
+ let struct2 = structArray[t];
57560
+
57561
+ let chainidArray2 = Object.keys(struct2domain[struct2]);
57562
+ if(chainidArray2.length == 0) continue;
57563
+
57338
57564
  for(let j = 0, jl = chainidArray2.length; j < jl; ++j) {
57339
57565
  let chainid2 = chainidArray2[j];
57340
57566
 
57341
57567
  let alignAjax;
57342
57568
  if(me.cfg.aligntool != 'tmalign') {
57343
57569
  let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct2][chainid2]);
57344
-
57570
+
57345
57571
  let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
57346
57572
  alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
57347
57573
  }
@@ -57366,7 +57592,14 @@ class RealignParser {
57366
57592
 
57367
57593
  let allPromise = Promise.allSettled(ajaxArray);
57368
57594
  // try {
57595
+ // let dataArray = await allPromise;
57596
+
57597
+ let startDate = new Date();
57369
57598
  let dataArray = await allPromise;
57599
+ let endDate = new Date();
57600
+ let miliseconds = (endDate.getTime() - startDate.getTime());
57601
+ console.log("vastdyn time: " + miliseconds + " miliseconds");
57602
+
57370
57603
  ic.qt_start_end = []; // reset the alignment
57371
57604
  await ic.chainalignParserCls.downloadChainalignmentPart2bRealign(dataArray, chainidPairArray, bReverse);
57372
57605
  // }
@@ -59590,6 +59823,7 @@ class LoadAtomData {
59590
59823
 
59591
59824
  //This function was used to parse atom "data" to set up parameters for the 3D viewer. "type" is mmcifid or mmdbid.
59592
59825
  //"id" is the MMDB ID or mmCIF ID.
59826
+ // thi sfunction is NOT used for mmCIF loading any more
59593
59827
  loadAtomDataIn(data, id, type, seqalign, alignType, chainidInput, chainIndex, bLastQuery, bNoSeqalign) { let ic = this.icn3d, me = ic.icn3dui;
59594
59828
  //ic.init();
59595
59829
  ic.pmin = new THREE.Vector3( 9999, 9999, 9999);
@@ -59733,13 +59967,6 @@ class LoadAtomData {
59733
59967
  if(ic.pdbid_chain2title === undefined) ic.pdbid_chain2title = {};
59734
59968
  ic.pdbid_chain2title[chainid] = data.moleculeInfor[molid].name;
59735
59969
 
59736
- //if(alignType == 'query' && chain == ic.chain_q) {
59737
- // ic.alignmolid2color[0][molid] = molidCnt.toString();
59738
- //}
59739
- //else if(alignType == 'target' && chain == ic.chain_t) {
59740
- // ic.alignmolid2color[1][molid] = molidCnt.toString();
59741
- //}
59742
-
59743
59970
  if(chain == chainid.substr(chainid.lastIndexOf('_')) ) {
59744
59971
  let tmpHash = {};
59745
59972
  tmpHash[molid] = molidCnt.toString();
@@ -59931,17 +60158,15 @@ class LoadAtomData {
59931
60158
  ic.pmin.min(atm.coord);
59932
60159
  ic.pmax.max(atm.coord);
59933
60160
  ic.psum.add(atm.coord);
59934
-
59935
- let bNonMmcif = (me.cfg.mmcifid === undefined && me.cfg.mmtfid === undefined && me.cfg.bcifid === undefined && ic.InputfileType != 'mmcif');
59936
- let bProtein = (bNonMmcif) ? chainid2kind[chainNum] === 'protein' : atm.mt === 'p';
59937
- let bNucleotide = (bNonMmcif) ? chainid2kind[chainNum] === 'nucleotide' : atm.mt === 'n';
59938
- let bSolvent = (bNonMmcif) ? chainid2kind[chainNum] === 'solvent' : atm.mt === 's';
60161
+ let bProtein = chainid2kind[chainNum] === 'protein' ;
60162
+ let bNucleotide = chainid2kind[chainNum] === 'nucleotide' ;
60163
+ let bSolvent = chainid2kind[chainNum] === 'solvent' ;
59939
60164
  // in vastplus.cgi, ions arenotlisted in alignedStructures...molecules, thus chainid2kind[chainNum] === undefined is used.
59940
60165
  // ions will be separated from chemicals later.
59941
60166
  // here "ligand" is used in the cgi output
59942
60167
  //var bChemicalIons =(me.cfg.mmcifid === undefined) ?(chainid2kind[chainNum] === 'ligand' || chainid2kind[chainNum] === 'otherPolymer' || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
59943
60168
  // kind: other, otherPolymer, etc
59944
- let bChemicalIons = (bNonMmcif) ? (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
60169
+ let bChemicalIons = (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) ;
59945
60170
 
59946
60171
  if((atm.chain === 'Misc' || chainid2kind[chainNum] === 'other') && biopolymerChainsHash[chainNum] !== 'protein' && biopolymerChainsHash[chainNum] !== 'nucleotide') { // biopolymer, could be protein or nucleotide
59947
60172
  if(atm.name === 'CA' && atm.elem === 'C') {
@@ -60205,18 +60430,17 @@ class LoadAtomData {
60205
60430
 
60206
60431
  // update bonds info
60207
60432
  if(type !== 'mmcifid') {
60208
- //for(let i in ic.atoms) {
60209
- for(let i in atoms) {
60210
- let currSerial = atomid2serial[i];
60433
+ //for(let i in ic.atoms) {
60434
+ for(let i in atoms) {
60435
+ let currSerial = atomid2serial[i];
60211
60436
 
60212
- let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
60437
+ let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
60213
60438
 
60214
- for(let j = 0; j < bondLength; ++j) {
60215
- ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
60439
+ for(let j = 0; j < bondLength; ++j) {
60440
+ ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
60441
+ }
60216
60442
  }
60217
60443
  }
60218
- }
60219
-
60220
60444
  // remove the reference
60221
60445
  data.atoms = {};
60222
60446
 
@@ -60312,7 +60536,7 @@ class LoadAtomData {
60312
60536
  // display the structure right away. load the mns and sequences later
60313
60537
  // setTimeout(function(){
60314
60538
  let hAtoms = {};
60315
-
60539
+
60316
60540
  if(type === 'align' && seqalign !== undefined && ic.bFullUi) {
60317
60541
  ic.setSeqAlignCls.setSeqAlign(seqalign, data.alignedStructures);
60318
60542
  } // if(align
@@ -60335,7 +60559,7 @@ class LoadAtomData {
60335
60559
  hAtoms = ic.hAtoms;
60336
60560
  }
60337
60561
  }
60338
- else if(type === 'mmdbid' && alignType === 'target') {
60562
+ else { //if(type === 'mmdbid' && alignType === 'target') {
60339
60563
  hAtoms = ic.hAtoms;
60340
60564
  }
60341
60565
 
@@ -60669,13 +60893,19 @@ class SetSeqAlign {
60669
60893
  resi = pos;
60670
60894
  }
60671
60895
  else {
60672
- if(ic.posid2resid) {
60673
- let resid = ic.posid2resid[chainid + '_' + pos];
60674
- resi = resid.substr(resid.lastIndexOf('_') + 1);
60675
- }
60676
- else {
60896
+ // if(ic.posid2resid) {
60897
+ // let resid = ic.posid2resid[chainid + '_' + pos];
60898
+ // resi = resid.substr(resid.lastIndexOf('_') + 1);
60899
+ // }
60900
+ // else {
60901
+ // resi = (ic.chainsSeq[chainid][pos].resi) ? ic.chainsSeq[chainid][pos].resi : pos;
60902
+ if(pos > ic.chainsSeq[chainid].length - 1) {
60903
+ console.log("Error: the position " + pos + " exceeds the max index " + (ic.chainsSeq[chainid].length - 1));
60904
+ pos = ic.chainsSeq[chainid].length - 1;
60905
+ }
60906
+
60677
60907
  resi = ic.chainsSeq[chainid][pos].resi;
60678
- }
60908
+ // }
60679
60909
  }
60680
60910
 
60681
60911
  return resi;
@@ -62760,17 +62990,6 @@ class LoadCIF {
62760
62990
  loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
62761
62991
  let hAtoms = {};
62762
62992
 
62763
- // bcifData could be binary or text
62764
- let parsed = (bText) ? CIFTools.Text.parse(bcifData) : CIFTools.Binary.parse(bcifData);
62765
-
62766
- if (parsed.isError) {
62767
- // report error:
62768
- var aaa = 1; //alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
62769
- return;
62770
- }
62771
-
62772
- let block = parsed.result.dataBlocks[0];
62773
-
62774
62993
  let bNMR = false;
62775
62994
  // let lines = src.split('\n');
62776
62995
 
@@ -62806,92 +63025,152 @@ class LoadCIF {
62806
63025
 
62807
63026
  let bFirstAtom = true;
62808
63027
 
62809
- if(block.getCategory("_entry")) {
62810
- id = block.getCategory("_entry").getColumn("id").getString(0);
63028
+ let cifArray = bcifData.split('ENDMDL\n');
62811
63029
 
62812
- if(id == '') {
62813
- if(bAppend) {
62814
- id = ic.defaultPdbId;
62815
- }
62816
- else {
62817
- //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
62818
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
62819
- }
62820
- }
63030
+ for(let index = 0, indexl = cifArray.length; index < indexl; ++index) {
63031
+ ++moleculeNum;
63032
+ id = ic.defaultPdbId;
62821
63033
 
62822
63034
  structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
62823
63035
 
62824
- ic.molTitle = '';
62825
- ic.molTitleHash = {};
62826
- }
62827
-
62828
- if(block.getCategory("_struct")) {
62829
- let title = block.getCategory("_struct").getColumn("title").getString(0);
62830
- title = title.replace(/"/, "'");
62831
- let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
62832
- ic.molTitle += name.trim() + " ";
62833
- // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63036
+ // if(!bNMR) {
63037
+ sheetArray = [];
63038
+ sheetStart = [];
63039
+ sheetEnd = [];
63040
+ helixArray = [];
63041
+ helixStart = [];
63042
+ helixEnd = [];
62834
63043
 
62835
- if(!ic.molTitleHash) ic.molTitleHash = {};
62836
- ic.molTitleHash[structure] = ic.molTitle;
62837
63044
 
62838
- }
63045
+ // bcifData could be binary or text
63046
+ let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
62839
63047
 
62840
- if(block.getCategory("_entity_src_gen")) {
62841
- ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
62842
- }
62843
-
62844
- if(block.getCategory("_database_2")) {
62845
- let database_2 = block.getCategory("_database_2");
62846
-
62847
- // Iterate through every row in the table
62848
- let db2Size = database_2.rowCount ;
62849
- for (let i = 0; i < db2Size; ++i) {
62850
- let db_id = database_2.getColumn("database_id").getString(0);
62851
- let db_code = database_2.getColumn("database_code").getString(0);
63048
+ if (parsed.isError) {
63049
+ // report error:
63050
+ var aaa = 1; //alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
63051
+ return;
63052
+ }
63053
+
63054
+ let block = parsed.result.dataBlocks[0];
62852
63055
 
62853
- if(db_id == "EMDB") {
62854
- ic.emd = db_code;
62855
- break;
63056
+ if(block.getCategory("_entry")) {
63057
+ id = block.getCategory("_entry").getColumn("id").getString(0);
63058
+
63059
+ if(id == '') {
63060
+ if(bAppend) {
63061
+ id = ic.defaultPdbId;
63062
+ }
63063
+ else {
63064
+ //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
63065
+ id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
63066
+ }
62856
63067
  }
63068
+
63069
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63070
+
63071
+ ic.molTitle = '';
63072
+ ic.molTitleHash = {};
62857
63073
  }
62858
- }
63074
+
63075
+ if(block.getCategory("_struct")) {
63076
+ let title = block.getCategory("_struct").getColumn("title").getString(0);
63077
+ title = title.replace(/"/, "'");
63078
+ let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
63079
+ ic.molTitle += name.trim() + " ";
63080
+ // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
62859
63081
 
62860
- if(block.getCategory("_struct_conf")) {
62861
- ic.bSecondaryStructure = true;
63082
+ if(!ic.molTitleHash) ic.molTitleHash = {};
63083
+ ic.molTitleHash[structure] = ic.molTitle;
62862
63084
 
62863
- // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
62864
- let struct_conf = block.getCategory("_struct_conf");
62865
-
62866
- let conf_type_idArray = struct_conf.getColumn("conf_type_id");
62867
-
62868
- let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
62869
- // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
62870
- let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
62871
-
62872
- struct_conf.getColumn("end_auth_asym_id");
62873
- // let resi2Array = struct_conf.getColumn("end_label_seq_id");
62874
- let resi2Array = struct_conf.getColumn("end_auth_seq_id");
62875
-
62876
- // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
62877
- let confSize = struct_conf.rowCount;
62878
- for (let i = 0; i < confSize; ++i) {
62879
- let conf_type_id = conf_type_idArray.getString(i);
63085
+ }
63086
+
63087
+ if(block.getCategory("_entity_src_gen")) {
63088
+ ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
63089
+ }
62880
63090
 
62881
- let startChain = chain1Array.getString(i);
62882
- let startResi = parseInt(resi1Array.getString(i));
62883
- let endResi = parseInt(resi2Array.getString(i));
63091
+ if(block.getCategory("_database_2")) {
63092
+ let database_2 = block.getCategory("_database_2");
62884
63093
 
62885
- if(conf_type_id.substr(0, 4) == "HELX") {
62886
- for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
62887
- let resid = structure + "_" + startChain + "_" + j;
62888
- helixArray.push(resid);
62889
-
62890
- if(j == startResi) helixStart.push(resid);
62891
- if(j == endResi) helixEnd.push(resid);
62892
- }
63094
+ // Iterate through every row in the table
63095
+ let db2Size = database_2.rowCount ;
63096
+ for (let i = 0; i < db2Size; ++i) {
63097
+ let db_id = database_2.getColumn("database_id").getString(0);
63098
+ let db_code = database_2.getColumn("database_code").getString(0);
63099
+
63100
+ if(db_id == "EMDB") {
63101
+ ic.emd = db_code;
63102
+ break;
63103
+ }
62893
63104
  }
62894
- else if(conf_type_id.substr(0, 4) == "STRN") {
63105
+ }
63106
+
63107
+ if(block.getCategory("_struct_conf")) {
63108
+ ic.bSecondaryStructure = true;
63109
+
63110
+ // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
63111
+ let struct_conf = block.getCategory("_struct_conf");
63112
+
63113
+ let conf_type_idArray = struct_conf.getColumn("conf_type_id");
63114
+
63115
+ let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
63116
+ // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
63117
+ let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
63118
+
63119
+ struct_conf.getColumn("end_auth_asym_id");
63120
+ // let resi2Array = struct_conf.getColumn("end_label_seq_id");
63121
+ let resi2Array = struct_conf.getColumn("end_auth_seq_id");
63122
+
63123
+ // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
63124
+ let confSize = struct_conf.rowCount;
63125
+ for (let i = 0; i < confSize; ++i) {
63126
+ let conf_type_id = conf_type_idArray.getString(i);
63127
+
63128
+ let startChain = chain1Array.getString(i);
63129
+ let startResi = parseInt(resi1Array.getString(i));
63130
+ let endResi = parseInt(resi2Array.getString(i));
63131
+
63132
+ if(conf_type_id.substr(0, 4) == "HELX") {
63133
+ for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
63134
+ let resid = structure + "_" + startChain + "_" + j;
63135
+ helixArray.push(resid);
63136
+
63137
+ if(j == startResi) helixStart.push(resid);
63138
+ if(j == endResi) helixEnd.push(resid);
63139
+ }
63140
+ }
63141
+ else if(conf_type_id.substr(0, 4) == "STRN") {
63142
+ for(let j = startResi; j <= endResi; ++j) {
63143
+ let resid = structure + "_" + startChain + "_" + j;
63144
+ sheetArray.push(resid);
63145
+
63146
+ if(j == startResi) sheetStart.push(resid);
63147
+ if(j == endResi) sheetEnd.push(resid);
63148
+ }
63149
+ }
63150
+ }
63151
+
63152
+ conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
63153
+ }
63154
+
63155
+ if(block.getCategory("_struct_sheet_range")) {
63156
+ // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
63157
+ let struct_sheet_range = block.getCategory("_struct_sheet_range");
63158
+
63159
+ let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
63160
+ // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
63161
+ let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
63162
+
63163
+ struct_sheet_range.getColumn("end_auth_asym_id");
63164
+ // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
63165
+ let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
63166
+
63167
+ // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
63168
+ let sheetSize = struct_sheet_range.rowCount;
63169
+ for (let i = 0; i < sheetSize; ++i) {
63170
+ let startChain = chain1Array.getString(i);
63171
+ let startResi = parseInt(resi1Array.getString(i));
63172
+ let endResi = parseInt(resi2Array.getString(i));
63173
+
62895
63174
  for(let j = startResi; j <= endResi; ++j) {
62896
63175
  let resid = structure + "_" + startChain + "_" + j;
62897
63176
  sheetArray.push(resid);
@@ -62900,500 +63179,469 @@ class LoadCIF {
62900
63179
  if(j == endResi) sheetEnd.push(resid);
62901
63180
  }
62902
63181
  }
63182
+
63183
+ chain1Array = resi1Array = resi2Array = [];
62903
63184
  }
62904
-
62905
- conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
62906
- }
62907
-
62908
- if(block.getCategory("_struct_sheet_range")) {
62909
- // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
62910
- let struct_sheet_range = block.getCategory("_struct_sheet_range");
62911
-
62912
- let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
62913
- // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
62914
- let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
62915
-
62916
- struct_sheet_range.getColumn("end_auth_asym_id");
62917
- // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
62918
- let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
62919
-
62920
- // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
62921
- let sheetSize = struct_sheet_range.rowCount;
62922
- for (let i = 0; i < sheetSize; ++i) {
62923
- let startChain = chain1Array.getString(i);
62924
- let startResi = parseInt(resi1Array.getString(i));
62925
- let endResi = parseInt(resi2Array.getString(i));
62926
-
62927
- for(let j = startResi; j <= endResi; ++j) {
62928
- let resid = structure + "_" + startChain + "_" + j;
62929
- sheetArray.push(resid);
62930
-
62931
- if(j == startResi) sheetStart.push(resid);
62932
- if(j == endResi) sheetEnd.push(resid);
62933
- }
62934
- }
62935
-
62936
- chain1Array = resi1Array = resi2Array = [];
62937
- }
62938
63185
 
62939
- if(block.getCategory("_struct_conn")) {
62940
- ic.bSsbondProvided = true;
63186
+ if(block.getCategory("_struct_conn")) {
63187
+ ic.bSsbondProvided = true;
62941
63188
 
62942
- // Retrieve the table corresponding to the struct_conn category, which delineates connections1
62943
- let struct_conn = block.getCategory("_struct_conn");
62944
-
62945
- let conn_type_idArray = struct_conn.getColumn("conn_type_id");
62946
-
62947
- let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
62948
- let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
62949
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
62950
-
62951
- let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
62952
- let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
62953
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
62954
-
62955
- let connSize = struct_conn.rowCount;
62956
- for (let i = 0; i < connSize; ++i) {
62957
- let conn_type_id = conn_type_idArray.getString(i);
63189
+ // Retrieve the table corresponding to the struct_conn category, which delineates connections1
63190
+ let struct_conn = block.getCategory("_struct_conn");
62958
63191
 
62959
- let chain1 = chain1Array.getString(i);
62960
- name1Array.getString(i);
62961
- let resi1 = resi1Array.getString(i);
62962
- let id1 = structure + '_' + chain1 + "_" + resi1;
63192
+ let conn_type_idArray = struct_conn.getColumn("conn_type_id");
62963
63193
 
62964
- let chain2 = chain2Array.getString(i);
62965
- name2Array.getString(i);
62966
- let resi2 = resi2Array.getString(i);
62967
- let id2 = structure + '_' + chain2 + "_" + resi2;
63194
+ let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
63195
+ let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
63196
+ let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
62968
63197
 
62969
- // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
63198
+ let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
63199
+ let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
63200
+ let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
62970
63201
 
62971
- // if (conn_type_id == "covale") {
62972
- // vBonds.push(id1);
62973
- // vBonds.push(id2);
62974
- // }
63202
+ let connSize = struct_conn.rowCount;
63203
+ for (let i = 0; i < connSize; ++i) {
63204
+ let conn_type_id = conn_type_idArray.getString(i);
62975
63205
 
62976
- if(conn_type_id == "disulf") {
62977
- if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
63206
+ let chain1 = chain1Array.getString(i);
63207
+ name1Array.getString(i);
63208
+ let resi1 = resi1Array.getString(i);
63209
+ let id1 = structure + '_' + chain1 + "_" + resi1;
63210
+
63211
+ let chain2 = chain2Array.getString(i);
63212
+ name2Array.getString(i);
63213
+ let resi2 = resi2Array.getString(i);
63214
+ let id2 = structure + '_' + chain2 + "_" + resi2;
63215
+
63216
+ // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
63217
+
63218
+ // if (conn_type_id == "covale") {
63219
+ // vBonds.push(id1);
63220
+ // vBonds.push(id2);
63221
+ // }
63222
+
63223
+ if(conn_type_id == "disulf") {
63224
+ if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
62978
63225
 
62979
- ic.ssbondpnts[structure].push(id1);
62980
- ic.ssbondpnts[structure].push(id2);
63226
+ ic.ssbondpnts[structure].push(id1);
63227
+ ic.ssbondpnts[structure].push(id2);
63228
+ }
62981
63229
  }
63230
+
63231
+ conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
62982
63232
  }
62983
-
62984
- conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
62985
- }
62986
63233
 
62987
- if(block.getCategory("_exptl")) {
62988
- let method = block.getCategory("_exptl").getColumn("method").getString(0);
62989
- if(method.indexOf('NMR') != -1) {
62990
- bNMR = true;
63234
+ if(block.getCategory("_exptl")) {
63235
+ let method = block.getCategory("_exptl").getColumn("method").getString(0);
63236
+ if(method.indexOf('NMR') != -1) {
63237
+ bNMR = true;
63238
+ }
62991
63239
  }
62992
- }
62993
63240
 
62994
- if(block.getCategory("_pdbx_struct_oper_list")) {
62995
- // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
62996
- let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
62997
-
62998
- let struct_oper_idArray = struct_oper_list.getColumn("id");
62999
- let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63000
- let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63001
- let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63002
- let m14Array = struct_oper_list.getColumn("vector[1]");
63003
-
63004
- let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63005
- let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63006
- let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63007
- let m24Array = struct_oper_list.getColumn("vector[2]");
63008
-
63009
- let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63010
- let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63011
- let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63012
- let m34Array = struct_oper_list.getColumn("vector[3]");
63013
-
63014
- let assemblySize = struct_oper_list.rowCount;
63015
- for (let i = 0; i < assemblySize; ++i) {
63016
- let struct_oper_id = struct_oper_idArray.getString(i);
63017
- if(struct_oper_id == "X0") continue;
63241
+ if(block.getCategory("_pdbx_struct_oper_list")) {
63242
+ // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
63243
+ let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
63244
+
63245
+ let struct_oper_idArray = struct_oper_list.getColumn("id");
63246
+ let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63247
+ let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63248
+ let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63249
+ let m14Array = struct_oper_list.getColumn("vector[1]");
63250
+
63251
+ let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63252
+ let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63253
+ let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63254
+ let m24Array = struct_oper_list.getColumn("vector[2]");
63255
+
63256
+ let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63257
+ let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63258
+ let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63259
+ let m34Array = struct_oper_list.getColumn("vector[3]");
63260
+
63261
+ let assemblySize = struct_oper_list.rowCount;
63262
+ for (let i = 0; i < assemblySize; ++i) {
63263
+ let struct_oper_id = struct_oper_idArray.getString(i);
63264
+ if(struct_oper_id == "X0") continue;
63018
63265
 
63019
- if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63020
- ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63021
- m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63022
- m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63023
- 0, 0, 0, 1);
63266
+ if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63267
+ ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63268
+ m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63269
+ m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63270
+ 0, 0, 0, 1);
63271
+ }
63272
+
63273
+ struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63274
+ = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63024
63275
  }
63025
-
63026
- struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63027
- = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63028
- }
63029
63276
 
63030
- // if (record === 'ENDMDL') {
63031
- // ++moleculeNum;
63032
- // id = ic.defaultPdbId;
63277
+ // if (record === 'ENDMDL') {
63278
+ // ++moleculeNum;
63279
+ // id = ic.defaultPdbId;
63033
63280
 
63034
- // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63281
+ // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63035
63282
 
63036
- // //helices = [];
63037
- // //sheets = [];
63038
- // if(!bNMR) {
63039
- // sheetArray = [];
63040
- // sheetStart = [];
63041
- // sheetEnd = [];
63042
- // helixArray = [];
63043
- // helixStart = [];
63044
- // helixEnd = [];
63045
- // }
63283
+ // //helices = [];
63284
+ // //sheets = [];
63285
+ // if(!bNMR) {
63286
+ // sheetArray = [];
63287
+ // sheetStart = [];
63288
+ // sheetEnd = [];
63289
+ // helixArray = [];
63290
+ // helixStart = [];
63291
+ // helixEnd = [];
63292
+ // }
63046
63293
 
63047
- // bHeader = false; // reinitialize to read structure name from the header
63048
- // }
63294
+ // bHeader = false; // reinitialize to read structure name from the header
63295
+ // }
63049
63296
 
63050
- if(block.getCategory("_citation")) {
63051
- ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63052
- }
63297
+ if(block.getCategory("_citation")) {
63298
+ ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63299
+ }
63053
63300
 
63054
- // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63055
- let atom_site = block.getCategory("_atom_site");
63056
- let atomSize = atom_site.rowCount;
63057
- // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63058
- let bFull = (atomSize > ic.maxatomcnt) ? false : true;
63301
+ // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63302
+ let atom_site = block.getCategory("_atom_site");
63303
+ let atomSize = atom_site.rowCount;
63304
+ // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63305
+ let bFull = (atomSize > ic.maxatomcnt) ? false : true;
63059
63306
 
63060
- if(!bFull) {
63061
- 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
63062
- ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63063
- }
63307
+ if(!bFull) {
63308
+ 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
63309
+ ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63310
+ }
63064
63311
 
63065
- let atom_hetatmArray = atom_site.getColumn("group_PDB");
63066
- let resnArray = atom_site.getColumn("label_comp_id");
63067
- let elemArray = atom_site.getColumn("type_symbol");
63068
- let nameArray = atom_site.getColumn("label_atom_id");
63312
+ let atom_hetatmArray = atom_site.getColumn("group_PDB");
63313
+ let resnArray = atom_site.getColumn("label_comp_id");
63314
+ let elemArray = atom_site.getColumn("type_symbol");
63315
+ let nameArray = atom_site.getColumn("label_atom_id");
63069
63316
 
63070
- let chainArray = atom_site.getColumn("auth_asym_id");
63317
+ let chainArray = atom_site.getColumn("auth_asym_id");
63071
63318
 
63072
- let resiArray = atom_site.getColumn("label_seq_id");
63073
- let resiOriArray = atom_site.getColumn("auth_seq_id");
63074
- let altArray = atom_site.getColumn("label_alt_id");
63319
+ let resiArray = atom_site.getColumn("label_seq_id");
63320
+ let resiOriArray = atom_site.getColumn("auth_seq_id");
63321
+ let altArray = atom_site.getColumn("label_alt_id");
63075
63322
 
63076
- let bArray = atom_site.getColumn("B_iso_or_equiv");
63323
+ let bArray = atom_site.getColumn("B_iso_or_equiv");
63077
63324
 
63078
- let xArray = atom_site.getColumn("Cartn_x");
63079
- let yArray = atom_site.getColumn("Cartn_y");
63080
- let zArray = atom_site.getColumn("Cartn_z");
63325
+ let xArray = atom_site.getColumn("Cartn_x");
63326
+ let yArray = atom_site.getColumn("Cartn_y");
63327
+ let zArray = atom_site.getColumn("Cartn_z");
63081
63328
 
63082
- let autochainArray = atom_site.getColumn("label_asym_id");
63329
+ let autochainArray = atom_site.getColumn("label_asym_id");
63083
63330
 
63084
- // get the bond info
63085
- let ligSeqHash = {}, prevAutochain = '';
63086
- let prevResn;
63087
- let sChain = {};
63088
- for (let i = 0; i < atomSize; ++i) {
63089
- let atom_hetatm = atom_hetatmArray.getString(i);
63090
- let resn = resnArray.getString(i);
63091
- let elem = elemArray.getString(i);
63092
- let atom = nameArray.getString(i);
63093
- let chain = chainArray.getString(i);
63094
- let resi = resiArray.getString(i);
63095
- let oriResi = resiOriArray.getString(i);
63096
- let alt = altArray.getString(i);
63097
- let bFactor = bArray.getString(i);
63331
+ // get the bond info
63332
+ let ligSeqHash = {}, prevAutochain = '';
63333
+ let prevResn;
63334
+ let sChain = {};
63335
+ for (let i = 0; i < atomSize; ++i) {
63336
+ let atom_hetatm = atom_hetatmArray.getString(i);
63337
+ let resn = resnArray.getString(i);
63338
+ let elem = elemArray.getString(i);
63339
+ let atom = nameArray.getString(i);
63340
+ let chain = chainArray.getString(i);
63341
+ let resi = resiArray.getString(i);
63342
+ let oriResi = resiOriArray.getString(i);
63343
+ let alt = altArray.getString(i);
63344
+ let bFactor = bArray.getString(i);
63098
63345
 
63099
- let autochain = autochainArray.getString(i);
63346
+ let autochain = autochainArray.getString(i);
63100
63347
 
63101
63348
 
63102
- resi = oriResi;
63349
+ resi = oriResi;
63103
63350
 
63104
- let molecueType;
63105
- if(atom_hetatm == "ATOM") {
63106
- if(resn.length == 3) {
63107
- molecueType = "p"; // protein
63108
- }
63109
- else {
63110
- molecueType = "n"; // nucleotide
63111
- }
63112
- }
63113
- else {
63114
- if(resn == "WAT" || resn == "HOH") {
63115
- molecueType = "s"; // solvent
63116
- chain = 'Misc';
63351
+ let molecueType;
63352
+ if(atom_hetatm == "ATOM") {
63353
+ if(resn.length == 3) {
63354
+ molecueType = "protein"; // protein
63355
+ }
63356
+ else {
63357
+ molecueType = "nucleotide"; // nucleotide
63358
+ }
63117
63359
  }
63118
63360
  else {
63119
- molecueType = "l"; // ligands or ions
63120
- chain = resn;
63361
+ if(resn == "WAT" || resn == "HOH") {
63362
+ molecueType = "solvent"; // solvent
63363
+ chain = 'Misc';
63364
+ }
63365
+ else {
63366
+ molecueType = "ligand"; // ligands or ions
63367
+ chain = resn;
63368
+ }
63121
63369
  }
63122
- }
63123
- if(chain === '') chain = 'A';
63124
-
63125
- // C-alpha only for large structure
63126
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && atom == 'CA')) || (molecueType == "n" && !(atom == "P")) ) ) continue;
63127
-
63128
- // skip alternative atoms
63129
- if(alt == "B") continue;
63130
-
63131
- sChain[chain] = 1;
63370
+ if(chain === '') chain = 'A';
63132
63371
 
63133
- if(bFirstAtom) {
63134
- structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63372
+ // C-alpha only for large structure
63373
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && atom == 'CA')) || (molecueType == "nucleotide" && !(atom == "P")) ) ) continue;
63374
+
63375
+ // skip alternative atoms
63376
+ if(alt == "B") continue;
63135
63377
 
63136
- bFirstAtom = false;
63137
- }
63378
+ sChain[chain] = 1;
63138
63379
 
63139
- // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
63140
- // Concatenation of two pdbs will have several atoms for the same serial
63141
- ++serial;
63380
+ if(bFirstAtom) {
63381
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63142
63382
 
63143
- // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
63144
- // bModifyResi = true;
63145
- // }
63383
+ bFirstAtom = false;
63384
+ }
63146
63385
 
63147
- if(resi == "?" || resi == "." || resi == "0") {
63148
- resi = oriResi;
63386
+ // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
63387
+ // Concatenation of two pdbs will have several atoms for the same serial
63388
+ ++serial;
63149
63389
 
63150
- // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63151
- // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63152
- // resi = (++tmpResi).toString();
63153
- // }
63154
- // }
63155
- // else {
63156
- // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63157
- // resi = (++tmpResi).toString();
63158
- // }
63159
- // else {
63160
- // resi = (tmpResi).toString();
63161
- // }
63390
+ // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
63391
+ // bModifyResi = true;
63162
63392
  // }
63163
- }
63164
63393
 
63165
- if(molecueType == 's' || molecueType == "l") {
63166
- let seq = {};
63167
- if(!ligSeqHash.hasOwnProperty(chain)) {
63168
- ligSeqHash[chain] = [];
63394
+ if(resi == "?" || resi == "." || resi == "0") {
63395
+ resi = oriResi;
63396
+
63397
+ // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63398
+ // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63399
+ // resi = (++tmpResi).toString();
63400
+ // }
63401
+ // }
63402
+ // else {
63403
+ // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63404
+ // resi = (++tmpResi).toString();
63405
+ // }
63406
+ // else {
63407
+ // resi = (tmpResi).toString();
63408
+ // }
63409
+ // }
63169
63410
  }
63170
63411
 
63171
- if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63172
- if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63173
- seq.resi = resi;
63174
- seq.name = me.utilsCls.residueName2Abbr(resn);
63175
- ligSeqHash[chain].push(seq);
63412
+ if(molecueType == 'solvent' || molecueType == "ligand") {
63413
+ let seq = {};
63414
+ if(!ligSeqHash.hasOwnProperty(chain)) {
63415
+ ligSeqHash[chain] = [];
63176
63416
  }
63177
- }
63178
- else {
63179
- if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63180
- seq.resi = resi;
63181
- seq.name = me.utilsCls.residueName2Abbr(resn);
63182
- ligSeqHash[chain].push(seq);
63417
+
63418
+ if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
63419
+ if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
63420
+ seq.resi = resi;
63421
+ seq.name = me.utilsCls.residueName2Abbr(resn);
63422
+ ligSeqHash[chain].push(seq);
63423
+ }
63424
+ }
63425
+ else {
63426
+ if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
63427
+ seq.resi = resi;
63428
+ seq.name = me.utilsCls.residueName2Abbr(resn);
63429
+ ligSeqHash[chain].push(seq);
63430
+ }
63183
63431
  }
63184
63432
  }
63185
- }
63186
63433
 
63187
- // if(bOpm && resn === 'DUM') {
63188
- // elem = atom;
63189
- // chain = 'MEM';
63190
- // resi = 1;
63191
- // oriResi = 1;
63192
- // }
63434
+ // if(bOpm && resn === 'DUM') {
63435
+ // elem = atom;
63436
+ // chain = 'MEM';
63437
+ // resi = 1;
63438
+ // oriResi = 1;
63439
+ // }
63193
63440
 
63194
- // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
63441
+ // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
63195
63442
 
63196
- chainNum = structure + "_" + chain;
63197
- oriResidueNum = chainNum + "_" + oriResi;
63443
+ chainNum = structure + "_" + chain;
63444
+ oriResidueNum = chainNum + "_" + oriResi;
63198
63445
 
63199
- residueNum = chainNum + "_" + resi;
63446
+ residueNum = chainNum + "_" + resi;
63200
63447
 
63201
- //let chain_resi = chain + "_" + resi;
63448
+ //let chain_resi = chain + "_" + resi;
63202
63449
 
63203
- let x = xArray.getFloat(i);
63204
- let y = yArray.getFloat(i);
63205
- let z = zArray.getFloat(i);
63206
- let coord = new THREE.Vector3(x, y, z);
63450
+ let x = xArray.getFloat(i);
63451
+ let y = yArray.getFloat(i);
63452
+ let z = zArray.getFloat(i);
63453
+ let coord = new THREE.Vector3(x, y, z);
63207
63454
 
63208
- let atomDetails = {
63209
- het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
63210
- serial: serial, // required, unique atom id
63211
- name: atom, // required, atom name
63212
- alt: alt, // optional, some alternative coordinates
63213
- resn: resn, // optional, used to determine protein or nucleotide
63214
- structure: structure, // optional, used to identify structure
63215
- chain: chain, // optional, used to identify chain
63216
- resi: resi, // optional, used to identify residue ID
63217
- //insc: line.substr(26, 1),
63218
- coord: coord, // required, used to draw 3D shape
63219
- b: bFactor, // optional, used to draw B-factor tube
63220
- elem: elem, // optional, used to determine hydrogen bond
63221
- bonds: [], // required, used to connect atoms
63222
- ss: 'coil', // optional, used to show secondary structures
63223
- ssbegin: false, // optional, used to show the beginning of secondary structures
63224
- ssend: false // optional, used to show the end of secondary structures
63225
- };
63455
+ let atomDetails = {
63456
+ het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
63457
+ serial: serial, // required, unique atom id
63458
+ name: atom, // required, atom name
63459
+ alt: alt, // optional, some alternative coordinates
63460
+ resn: resn, // optional, used to determine protein or nucleotide
63461
+ structure: structure, // optional, used to identify structure
63462
+ chain: chain, // optional, used to identify chain
63463
+ resi: resi, // optional, used to identify residue ID
63464
+ //insc: line.substr(26, 1),
63465
+ coord: coord, // required, used to draw 3D shape
63466
+ b: bFactor, // optional, used to draw B-factor tube
63467
+ elem: elem, // optional, used to determine hydrogen bond
63468
+ bonds: [], // required, used to connect atoms
63469
+ ss: 'coil', // optional, used to show secondary structures
63470
+ ssbegin: false, // optional, used to show the beginning of secondary structures
63471
+ ssend: false // optional, used to show the end of secondary structures
63472
+ };
63226
63473
 
63227
- if(!atomDetails.het && atomDetails.name === 'C') ;
63228
- if(!atomDetails.het && atomDetails.name === 'O') ;
63474
+ if(!atomDetails.het && atomDetails.name === 'C') ;
63475
+ if(!atomDetails.het && atomDetails.name === 'O') ;
63229
63476
 
63230
- // from DSSP C++ code
63231
- // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
63232
- // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
63477
+ // from DSSP C++ code
63478
+ // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
63479
+ // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
63233
63480
 
63234
- // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
63235
- // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
63236
- // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
63481
+ // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
63482
+ // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
63483
+ // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
63237
63484
 
63238
- // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
63239
- // }
63485
+ // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
63486
+ // }
63240
63487
 
63241
- ic.atoms[serial] = atomDetails;
63488
+ ic.atoms[serial] = atomDetails;
63242
63489
 
63243
- ic.dAtoms[serial] = 1;
63244
- ic.hAtoms[serial] = 1;
63245
- hAtoms[serial] = 1;
63490
+ ic.dAtoms[serial] = 1;
63491
+ ic.hAtoms[serial] = 1;
63492
+ hAtoms[serial] = 1;
63246
63493
 
63247
- // Assign secondary structures from the input
63248
- // if a residue is assigned both sheet and helix, it is assigned as sheet
63249
- if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
63250
- ic.atoms[serial].ss = 'sheet';
63251
- if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
63252
- ic.atoms[serial].ssbegin = true;
63253
- }
63494
+ // Assign secondary structures from the input
63495
+ // if a residue is assigned both sheet and helix, it is assigned as sheet
63496
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
63497
+ ic.atoms[serial].ss = 'sheet';
63498
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
63499
+ ic.atoms[serial].ssbegin = true;
63500
+ }
63254
63501
 
63255
- // do not use else if. Some residues are both start and end of secondary structure
63256
- if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
63257
- ic.atoms[serial].ssend = true;
63502
+ // do not use else if. Some residues are both start and end of secondary structure
63503
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
63504
+ ic.atoms[serial].ssend = true;
63505
+ }
63258
63506
  }
63259
- }
63260
- else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
63261
- ic.atoms[serial].ss = 'helix';
63507
+ else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
63508
+ ic.atoms[serial].ss = 'helix';
63262
63509
 
63263
- if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
63264
- ic.atoms[serial].ssbegin = true;
63510
+ if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
63511
+ ic.atoms[serial].ssbegin = true;
63512
+ }
63513
+
63514
+ // do not use else if. Some residues are both start and end of secondary structure
63515
+ if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
63516
+ ic.atoms[serial].ssend = true;
63517
+ }
63265
63518
  }
63266
63519
 
63267
- // do not use else if. Some residues are both start and end of secondary structure
63268
- if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
63269
- ic.atoms[serial].ssend = true;
63520
+ let secondaries = '-';
63521
+ if(ic.atoms[serial].ss === 'helix') {
63522
+ secondaries = 'H';
63523
+ }
63524
+ else if(ic.atoms[serial].ss === 'sheet') {
63525
+ secondaries = 'E';
63526
+ }
63527
+ //else if(ic.atoms[serial].ss === 'coil') {
63528
+ // secondaries = 'c';
63529
+ //}
63530
+ else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
63531
+ secondaries = 'c';
63532
+ }
63533
+ else {
63534
+ secondaries = 'o';
63270
63535
  }
63271
- }
63272
63536
 
63273
- let secondaries = '-';
63274
- if(ic.atoms[serial].ss === 'helix') {
63275
- secondaries = 'H';
63276
- }
63277
- else if(ic.atoms[serial].ss === 'sheet') {
63278
- secondaries = 'E';
63279
- }
63280
- //else if(ic.atoms[serial].ss === 'coil') {
63281
- // secondaries = 'c';
63282
- //}
63283
- else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
63284
- secondaries = 'c';
63285
- }
63286
- else {
63287
- secondaries = 'o';
63288
- }
63537
+ ic.secondaries[residueNum] = secondaries;
63289
63538
 
63290
- ic.secondaries[residueNum] = secondaries;
63539
+ // different residue
63540
+ //if(residueNum !== prevResidueNum) {
63541
+
63542
+ // if(oriResidueNum !== prevOriResidueNum) {
63543
+ if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
63544
+ let residue = me.utilsCls.residueName2Abbr(resn);
63545
+
63546
+ ic.residueId2Name[residueNum] = residue;
63291
63547
 
63292
- // different residue
63293
- //if(residueNum !== prevResidueNum) {
63294
-
63295
- // if(oriResidueNum !== prevOriResidueNum) {
63296
- if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
63297
- let residue = me.utilsCls.residueName2Abbr(resn);
63298
-
63299
- ic.residueId2Name[residueNum] = residue;
63548
+ if(serial !== 1 && prevResidueNum !== '') {
63549
+ ic.residues[prevResidueNum] = residuesTmp;
63550
+ }
63300
63551
 
63301
- if(serial !== 1 && prevResidueNum !== '') {
63302
- ic.residues[prevResidueNum] = residuesTmp;
63303
- }
63552
+ if(residueNum !== prevResidueNum) {
63553
+ residuesTmp = {};
63554
+ }
63304
63555
 
63305
- if(residueNum !== prevResidueNum) {
63306
- residuesTmp = {};
63307
- }
63556
+ // different chain
63557
+ if(chainNum !== prevChainNum) {
63308
63558
 
63309
- // different chain
63310
- if(chainNum !== prevChainNum) {
63559
+ // a chain could be separated in two sections
63560
+ if(serial !== 1 && prevChainNum !== '') {
63561
+ if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
63562
+ ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
63563
+ }
63311
63564
 
63312
- // a chain could be separated in two sections
63313
- if(serial !== 1 && prevChainNum !== '') {
63314
- if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
63315
- ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
63316
- }
63565
+ chainsTmp = {};
63317
63566
 
63318
- chainsTmp = {};
63567
+ if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
63568
+ if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
63319
63569
 
63320
- if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
63321
- if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
63570
+ if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
63322
63571
 
63323
- if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
63572
+ let resObject = {};
63573
+ resObject.resi = resi;
63574
+ resObject.name = residue;
63324
63575
 
63325
- let resObject = {};
63326
- resObject.resi = resi;
63327
- resObject.name = residue;
63576
+ ic.chainsSeq[chainNum].push(resObject);
63577
+ }
63578
+ else {
63579
+
63580
+ let resObject = {};
63581
+ resObject.resi = resi;
63582
+ resObject.name = residue;
63328
63583
 
63329
- ic.chainsSeq[chainNum].push(resObject);
63584
+ ic.chainsSeq[chainNum].push(resObject);
63585
+ }
63330
63586
  }
63331
- else {
63332
63587
 
63333
- let resObject = {};
63334
- resObject.resi = resi;
63335
- resObject.name = residue;
63588
+ chainsTmp[serial] = 1;
63589
+ residuesTmp[serial] = 1;
63336
63590
 
63337
- ic.chainsSeq[chainNum].push(resObject);
63338
- }
63339
- }
63591
+ prevChainNum = chainNum;
63592
+ prevResidueNum = residueNum;
63593
+ prevOriResidueNum = oriResidueNum;
63340
63594
 
63341
- chainsTmp[serial] = 1;
63342
- residuesTmp[serial] = 1;
63595
+ prevResn = chain + "_" + resn;
63596
+ prevAutochain = autochain;
63597
+ }
63343
63598
 
63344
- prevChainNum = chainNum;
63345
- prevResidueNum = residueNum;
63346
- prevOriResidueNum = oriResidueNum;
63599
+ // add the last residue set
63600
+ ic.residues[residueNum] = residuesTmp;
63601
+ if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
63602
+ ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
63347
63603
 
63348
- prevResn = chain + "_" + resn;
63349
- prevAutochain = autochain;
63350
- }
63604
+ // clear memory
63605
+ atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
63606
+ = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
63351
63607
 
63352
- // add the last residue set
63353
- ic.residues[residueNum] = residuesTmp;
63354
- if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
63355
- ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
63608
+ let mChainSeq = {};
63609
+ if(block.getCategory("_pdbx_poly_seq_scheme")) {
63610
+ let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
63356
63611
 
63357
- // clear memory
63358
- atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
63359
- = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
63612
+ let resiArray = poly_seq_scheme.getColumn("seq_id");
63613
+ let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
63614
+ let resnArray = poly_seq_scheme.getColumn("mon_id");
63615
+ let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
63360
63616
 
63361
- let mChainSeq = {};
63362
- if(block.getCategory("_pdbx_poly_seq_scheme")) {
63363
- let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
63617
+ let seqSize = poly_seq_scheme.rowCount;
63618
+ let prevChain = "";
63619
+ let seqArray = [];
63620
+ for (let i = 0; i < seqSize; ++i) {
63621
+ resiArray.getString(i);
63622
+ let oriResi = oriResiArray.getString(i);
63623
+ let resn = resnArray.getString(i);
63624
+ let chain = chainArray.getString(i);
63364
63625
 
63365
- let resiArray = poly_seq_scheme.getColumn("seq_id");
63366
- let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
63367
- let resnArray = poly_seq_scheme.getColumn("mon_id");
63368
- let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
63626
+ if(chain != prevChain && i > 0) {
63627
+ mChainSeq[prevChain] = seqArray;
63369
63628
 
63370
- let seqSize = poly_seq_scheme.rowCount;
63371
- let prevChain = "";
63372
- let seqArray = [];
63373
- for (let i = 0; i < seqSize; ++i) {
63374
- resiArray.getString(i);
63375
- let oriResi = oriResiArray.getString(i);
63376
- let resn = resnArray.getString(i);
63377
- let chain = chainArray.getString(i);
63629
+ seqArray = [];
63630
+ }
63378
63631
 
63379
- if(chain != prevChain && i > 0) {
63380
- mChainSeq[prevChain] = seqArray;
63632
+ // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
63633
+ seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
63381
63634
 
63382
- seqArray = [];
63635
+ prevChain = chain;
63383
63636
  }
63384
63637
 
63385
- // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
63386
- seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
63638
+ mChainSeq[prevChain] = seqArray;
63387
63639
 
63388
- prevChain = chain;
63640
+ resiArray = oriResiArray = resnArray = chainArray = [];
63389
63641
  }
63390
-
63391
- mChainSeq[prevChain] = seqArray;
63392
-
63393
- resiArray = oriResiArray = resnArray = chainArray = [];
63642
+
63643
+ this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
63394
63644
  }
63395
-
63396
- this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
63397
63645
 
63398
63646
  // copy disulfide bonds
63399
63647
  let structureArray = Object.keys(ic.structures);
@@ -65168,11 +65416,13 @@ class ApplyCommand {
65168
65416
  ic.drawCls.draw();
65169
65417
  }
65170
65418
  else if(command.indexOf('add sphere') == 0) {
65171
- this.addShape(command, 'sphere');
65419
+ this.addShape(commandOri, 'sphere');
65420
+ ic.shapeCmdHash[commandOri] = 1;
65172
65421
  //ic.drawCls.draw();
65173
65422
  }
65174
65423
  else if(command.indexOf('add cube') == 0) {
65175
- this.addShape(command, 'cube');
65424
+ this.addShape(commandOri, 'cube');
65425
+ ic.shapeCmdHash[commandOri] = 1;
65176
65426
  //ic.drawCls.draw();
65177
65427
  }
65178
65428
  else if(command.indexOf('clear shape') == 0) {
@@ -65628,8 +65878,8 @@ class ApplyCommand {
65628
65878
 
65629
65879
  ic.hlUpdateCls.updateHlAll();
65630
65880
 
65631
- // change graph color
65632
- ic.getGraphCls.updateGraphColor();
65881
+ // change graph color, was done in color command
65882
+ //ic.getGraphCls.updateGraphColor();
65633
65883
  }
65634
65884
  else if(commandOri.indexOf('remove legend') == 0) {
65635
65885
  $("#" + me.pre + "legend").hide();
@@ -65915,7 +66165,7 @@ class ApplyCommand {
65915
66165
  }
65916
66166
 
65917
66167
  addShape(command, shape) { let ic = this.icn3d, me = ic.icn3dui;
65918
- ic.shapeCmdHash[command] = 1;
66168
+ // ic.shapeCmdHash[command] = 1;
65919
66169
 
65920
66170
  let paraArray = command.split(' | ');
65921
66171
  let p1Array = paraArray[1].split(' ');
@@ -65926,7 +66176,17 @@ class ApplyCommand {
65926
66176
  colorStr = '#' + colorStr.replace(/\#/g, '');
65927
66177
  let color = me.parasCls.thr(colorStr);
65928
66178
 
65929
- let pos1 = new THREE.Vector3(parseFloat(p1Array[1]), parseFloat(p1Array[3]), parseFloat(p1Array[5]));
66179
+ let pos1;
66180
+
66181
+ if(p1Array[0] == 'x1') { // input position
66182
+ pos1 = new THREE.Vector3(parseFloat(p1Array[1]), parseFloat(p1Array[3]), parseFloat(p1Array[5]));
66183
+ }
66184
+ else { // input sets
66185
+ let nameArray = paraArray[1].split(',');
66186
+ let atomSet1 = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
66187
+ let posArray1 = ic.contactCls.getExtent(atomSet1);
66188
+ pos1 = new THREE.Vector3(posArray1[2][0], posArray1[2][1], posArray1[2][2]);
66189
+ }
65930
66190
 
65931
66191
  if(shape == 'sphere') {
65932
66192
  ic.sphereCls.createSphereBase(pos1, color, parseFloat(radius), undefined, undefined, undefined, parseFloat(opacity));
@@ -66906,7 +67166,7 @@ class SelectCollections {
66906
67166
 
66907
67167
  ic.ssbondpnts = {};
66908
67168
 
66909
- ic.bShowHighlight = false;
67169
+ ic.bShowHighlight = undefined;
66910
67170
  ic.bResetSets = true;
66911
67171
  }
66912
67172
 
@@ -67037,8 +67297,8 @@ class SelectCollections {
67037
67297
  ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
67038
67298
  }
67039
67299
 
67040
- ic.opts["color"] = "structure";
67041
- ic.setStyleCls.setAtomStyleByOptions();
67300
+ ic.opts["color"] = (Object.keys(ic.structures).length == 1) ? "chain" : "structure";
67301
+ // ic.setStyleCls.setAtomStyleByOptions();
67042
67302
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
67043
67303
 
67044
67304
  ic.transformCls.zoominSelection();
@@ -69288,6 +69548,34 @@ class Resid2spec {
69288
69548
  return spec;
69289
69549
  }
69290
69550
 
69551
+ resi2range(resiArray) {var ic = this.icn3d; ic.icn3dui;
69552
+ let range = [];
69553
+
69554
+ let resiArraySorted = resiArray.sort(function(a, b) {
69555
+ return parseInt(a) - parseInt(b);
69556
+ });
69557
+
69558
+ let startResi = resiArraySorted[0];
69559
+ let prevResi, resi;
69560
+ for(let j = 0, jl = resiArraySorted.length; j < jl; ++j) {
69561
+ resi = resiArraySorted[j];
69562
+
69563
+ if(j != 0 && resi != prevResi + 1) {
69564
+ range.push(startResi);
69565
+ range.push(prevResi);
69566
+ startResi = resi;
69567
+ }
69568
+
69569
+ prevResi = resi;
69570
+ }
69571
+
69572
+ // last residue
69573
+ range.push(startResi);
69574
+ range.push(prevResi);
69575
+
69576
+ return range;
69577
+ }
69578
+
69291
69579
  atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
69292
69580
  let spec = "";
69293
69581
  let i = 0;
@@ -70750,8 +71038,6 @@ class Dssp {
70750
71038
  bNoMoreIg = false;
70751
71039
 
70752
71040
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
70753
- //let bForceOneDomain = true;
70754
- //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
70755
71041
 
70756
71042
  // ig strand for any subset will have the same k, use the number of residue to separate them
70757
71043
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
@@ -70911,20 +71197,24 @@ class Dssp {
70911
71197
  // assign ref numbers to selected residues
70912
71198
  let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
70913
71199
  let subdomains = result.subdomains;
70914
- let pos2resi = result.pos2resi;
71200
+ // let pos2resi = result.pos2resi;
70915
71201
 
70916
71202
  if(subdomains.length >= 1) {
70917
71203
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
70918
71204
  let domainAtoms = {};
70919
71205
  let segArray = subdomains[k];
70920
71206
 
70921
- let resCnt = 0;
71207
+ let resCnt = 0; // minResi = 999, maxResi = -999;
70922
71208
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
70923
71209
  let startResi = parseInt(segArray[m]);
70924
71210
  let endResi = parseInt(segArray[m+1]);
70925
71211
 
71212
+ // if(startResi < minResi) minResi = startResi;
71213
+ // if(endResi > maxResi) maxResi = endResi;
71214
+
70926
71215
  for(let n = startResi; n <= endResi; ++n) {
70927
- let resid = chainid + '_' + pos2resi[n - 1];
71216
+ // let resid = chainid + '_' + pos2resi[n - 1];
71217
+ let resid = ic.ncbi2resid[chainid + '_' + n];
70928
71218
  ++resCnt;
70929
71219
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
70930
71220
 
@@ -70940,6 +71230,9 @@ class Dssp {
70940
71230
  domainAtomsArray.push(domainAtoms);
70941
71231
  }
70942
71232
  }
71233
+ // else { // no domain
71234
+ // domainAtomsArray = [currAtoms];
71235
+ // }
70943
71236
 
70944
71237
  return domainAtomsArray;
70945
71238
  }
@@ -71076,7 +71369,6 @@ class Dssp {
71076
71369
  continue;
71077
71370
  }
71078
71371
  // }
71079
-
71080
71372
  }
71081
71373
 
71082
71374
  if(!bRound1) {
@@ -71624,15 +71916,21 @@ class Dssp {
71624
71916
 
71625
71917
  let resi = refAA[i][j].trim();
71626
71918
  let refnum = refAA[refI][j].trim();
71919
+
71920
+ if(!ic.chainsMapping.hasOwnProperty(chainid)) {
71921
+ ic.chainsMapping[chainid] = {};
71922
+ }
71923
+
71924
+ let resid = chainid + '_' + resi;
71925
+
71627
71926
  if(resi && refnum) {
71628
- let resid = chainid + '_' + resi;
71629
71927
  ic.resid2refnum[resid] = refnum;
71630
71928
 
71631
- if(!ic.chainsMapping.hasOwnProperty(chainid)) {
71632
- ic.chainsMapping[chainid] = {};
71633
- }
71634
71929
  ic.chainsMapping[chainid][resid] = refnum;
71635
71930
  }
71931
+ else {
71932
+ ic.chainsMapping[chainid][resid] = resi;
71933
+ }
71636
71934
  }
71637
71935
  }
71638
71936
 
@@ -72108,17 +72406,18 @@ class Dssp {
72108
72406
  }
72109
72407
 
72110
72408
  // assign before removing
72111
- let resid = chnid + '_' + strandArray[i].startResi;
72409
+ chnid + '_' + strandArray[i].startResi;
72112
72410
 
72113
72411
  strandArray.splice(i, 1);
72114
72412
 
72115
- if(strandTmp == 'B' || strandTmp == 'C' || strandTmp == 'E' || strandTmp == 'F') {
72116
- if(!me.bNode) console.log("Ig strand " + strandTmp + " is removed since it is too short...");
72413
+ // do not remove BCEF strands even though they are short
72414
+ // if(strandTmp == 'B' || strandTmp == 'C' || strandTmp == 'E' || strandTmp == 'F') {
72415
+ // if(!me.bNode) console.log("Ig strand " + strandTmp + " is removed since it is too short...");
72117
72416
 
72118
- let domainid = ic.resid2domainid[resid];
72119
- removeDomainidHash[domainid] = 1;
72120
- continue;
72121
- }
72417
+ // let domainid = ic.resid2domainid[resid];
72418
+ // removeDomainidHash[domainid] = 1;
72419
+ // continue;
72420
+ // }
72122
72421
  }
72123
72422
  }
72124
72423
 
@@ -72336,7 +72635,7 @@ class Dssp {
72336
72635
 
72337
72636
  // remove the postfix when comparing interactions
72338
72637
  //ic.chainsMapping[chnid][residueid] = refnumLabel;
72339
- ic.chainsMapping[chnid][residueid] = refnumLabelNoPostfix;
72638
+ ic.chainsMapping[chnid][residueid] = (refnumLabelNoPostfix) ? refnumLabelNoPostfix : currResi;
72340
72639
  }
72341
72640
  }
72342
72641
 
@@ -80489,7 +80788,7 @@ class iCn3DUI {
80489
80788
  //even when multiple iCn3D viewers are shown together.
80490
80789
  this.pre = this.cfg.divid + "_";
80491
80790
 
80492
- this.REVISION = '3.31.3';
80791
+ this.REVISION = '3.32.0';
80493
80792
 
80494
80793
  // In nodejs, iCn3D defines "window = {navigator: {}}"
80495
80794
  this.bNode = (Object.keys(window).length < 2) ? true : false;