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.module.js CHANGED
@@ -9919,7 +9919,7 @@ class ClickMenu {
9919
9919
  });
9920
9920
 
9921
9921
  me.myEventCls.onIds("#" + me.pre + "mn1_mmciffile", "click", function(e) { me.icn3d; //e.preventDefault();
9922
- me.htmlCls.dialogCls.openDlg('dl_mmciffile', 'Please input mmCIF File');
9922
+ me.htmlCls.dialogCls.openDlg('dl_mmciffile', 'Please append mmCIF File');
9923
9923
  });
9924
9924
 
9925
9925
  me.myEventCls.onIds("#" + me.pre + "mn1_mmcifid", "click", function(e) { me.icn3d; //e.preventDefault();
@@ -12585,7 +12585,7 @@ class SetMenu {
12585
12585
  // html += this.getLink('mn1_pdbfile', 'PDB File');
12586
12586
  // html += this.getLink('mn1_pdbfile_app', 'PDB File (append)');
12587
12587
  html += this.getLink('mn1_pdbfile_app', 'PDB Files (appendable)', 1, 2);
12588
- html += this.getLink('mn1_mmciffile', 'mmCIF File', undefined, 2);
12588
+ html += this.getLink('mn1_mmciffile', 'mmCIF File (appendable)', undefined, 2);
12589
12589
  html += this.getLink('mn1_mol2file', 'Mol2 File', undefined, 2);
12590
12590
  html += this.getLink('mn1_sdffile', 'SDF File', undefined, 2);
12591
12591
  html += this.getLink('mn1_xyzfile', 'XYZ File', undefined, 2);
@@ -14929,8 +14929,8 @@ class SetDialog {
14929
14929
  html += "</div>";
14930
14930
 
14931
14931
  html += me.htmlCls.divStr + "dl_mmciffile' class='" + dialogClass + "'>";
14932
- html += this.addNotebookTitle('dl_mmciffile', 'Please input an mmCIF file');
14933
- html += "mmCIF File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "mmciffile' value='1TUP' size=8> ";
14932
+ html += this.addNotebookTitle('dl_mmciffile', 'Please append mmCIF files');
14933
+ html += "Multiple mmCIF Files: <input type='file' multiple id='" + me.pre + "mmciffile' size=8> ";
14934
14934
  html += me.htmlCls.buttonStr + "reload_mmciffile'>Load</button>";
14935
14935
  html += "</div>";
14936
14936
 
@@ -16185,17 +16185,15 @@ class Events {
16185
16185
  }
16186
16186
  }
16187
16187
 
16188
- async readFile(bAppend, files, index, dataStrAll) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16188
+ async readFile(bAppend, files, index, dataStrAll, bmmCIF) { let me = this.icn3dui, ic = me.icn3d, thisClass = this;
16189
16189
  let file = files[index];
16190
16190
  let commandName = (bAppend) ? 'append': 'load';
16191
+ commandName += (bmmCIF) ? ' mmcif file ': ' pdb file ';
16191
16192
 
16192
16193
  let reader = new FileReader();
16193
16194
  reader.onload = async function(e) {
16194
- //++ic.loadedFileCnt;
16195
-
16196
16195
  let dataStr = e.target.result; // or = reader.result;
16197
- //thisClass.setLogCmd(commandName + ' pdb file ' + $("#" + me.pre + fileId).val(), false);
16198
- thisClass.setLogCmd(commandName + ' pdb file ' + file.name, false);
16196
+ thisClass.setLogCmd(commandName + file.name, false);
16199
16197
 
16200
16198
  if(!bAppend) {
16201
16199
  ic.init();
@@ -16209,7 +16207,7 @@ class Events {
16209
16207
  }
16210
16208
 
16211
16209
  ic.bInputfile = true;
16212
- ic.InputfileType = 'pdb';
16210
+ ic.InputfileType = (bmmCIF) ? 'mmcif' : 'pdb';
16213
16211
  ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + dataStr : dataStr;
16214
16212
 
16215
16213
  dataStrAll = (index > 0) ? dataStrAll + '\nENDMDL\n' + dataStr : dataStr;
@@ -16219,15 +16217,21 @@ class Events {
16219
16217
  ic.hAtoms = {};
16220
16218
  ic.dAtoms = {};
16221
16219
  }
16222
- await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
16220
+ if(bmmCIF) {
16221
+ await ic.mmcifParserCls.loadMultipleMmcifData(dataStrAll, undefined, bAppend);
16222
+ }
16223
+ else {
16224
+ await ic.pdbParserCls.loadPdbData(dataStrAll, undefined, undefined, bAppend);
16225
+ }
16226
+
16227
+ //ic.InputfileType = undefined; // reset
16223
16228
  }
16224
16229
  else {
16225
- await thisClass.readFile(bAppend, files, index + 1, dataStrAll);
16230
+ await thisClass.readFile(bAppend, files, index + 1, dataStrAll, bmmCIF);
16226
16231
  }
16227
16232
 
16228
16233
  if(bAppend) {
16229
16234
  if(ic.bSetChainsAdvancedMenu) ic.definedSetsCls.showSets();
16230
- //if(ic.bSetChainsAdvancedMenu) ic.legendTableCls.showSets();
16231
16235
 
16232
16236
  ic.bResetAnno = true;
16233
16237
 
@@ -16244,9 +16248,7 @@ class Events {
16244
16248
  }
16245
16249
  }
16246
16250
 
16247
- async loadPdbFile(bAppend) { let me = this.icn3dui, ic = me.icn3d;
16248
- let fileId = (bAppend) ? 'pdbfile_app' : 'pdbfile';
16249
-
16251
+ async loadPdbFile(bAppend, fileId, bmmCIF) { let me = this.icn3dui, ic = me.icn3d;
16250
16252
  //me = ic.setIcn3dui(this.id);
16251
16253
  ic.bInitial = true;
16252
16254
  if(!me.cfg.notebook) dialog.dialog( "close" );
@@ -16270,7 +16272,7 @@ class Events {
16270
16272
 
16271
16273
  ic.dataStrAll = '';
16272
16274
 
16273
- await this.readFile(bAppend, files, 0, '');
16275
+ await this.readFile(bAppend, files, 0, '', bmmCIF);
16274
16276
  }
16275
16277
  }
16276
16278
 
@@ -17627,14 +17629,14 @@ class Events {
17627
17629
  e.preventDefault();
17628
17630
 
17629
17631
  let bAppend = false;
17630
- await thisClass.loadPdbFile(bAppend);
17632
+ await thisClass.loadPdbFile(bAppend, 'pdbfile');
17631
17633
  });
17632
17634
 
17633
17635
  me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", async function(e) { let ic = me.icn3d;
17634
17636
  e.preventDefault();
17635
17637
 
17636
17638
  ic.bAppend = true;
17637
- await thisClass.loadPdbFile(ic.bAppend);
17639
+ await thisClass.loadPdbFile(ic.bAppend, 'pdbfile_app');
17638
17640
  });
17639
17641
 
17640
17642
  me.myEventCls.onIds("#" + me.pre + "reload_mol2file", "click", function(e) { let ic = me.icn3d;
@@ -17818,49 +17820,13 @@ class Events {
17818
17820
  await ic.pdbParserCls.downloadUrl(url, type);
17819
17821
  });
17820
17822
 
17821
- me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", function(e) { let ic = me.icn3d;
17823
+ me.myEventCls.onIds("#" + me.pre + "reload_mmciffile", "click", async function(e) { let ic = me.icn3d;
17822
17824
  e.preventDefault();
17823
- ic.bInitial = true;
17824
- if(!me.cfg.notebook) dialog.dialog( "close" );
17825
- //close all dialog
17826
- if(!me.cfg.notebook) {
17827
- $(".ui-dialog-content").dialog("close");
17828
- }
17829
- else {
17830
- ic.resizeCanvasCls.closeDialogs();
17831
- }
17832
- let file = $("#" + me.pre + "mmciffile")[0].files[0];
17833
- if(!file) {
17834
- alert("Please select a file before clicking 'Load'");
17835
- }
17836
- else {
17837
- me.htmlCls.setHtmlCls.fileSupport();
17838
- let reader = new FileReader();
17839
- reader.onload = async function(e) {
17840
- let dataStr = e.target.result; // or = reader.result;
17841
- thisClass.setLogCmd('load mmcif file ' + $("#" + me.pre + "mmciffile").val(), false);
17842
- ic.molTitle = "";
17843
-
17844
- // let url = me.htmlCls.baseUrl + "mmcifparser/mmcifparser.cgi";
17845
- // //ic.bCid = undefined;
17846
-
17847
- // let dataObj = {'mmciffile': dataStr};
17848
- // let data = await me.getAjaxPostPromise(url, dataObj, true);
17849
-
17850
- let bText = true;
17851
- // let bcifData = ic.bcifParserCls.getBcifJson(dataStr, undefined, bText);
17852
- // let data = JSON.parse(bcifData);
17853
17825
 
17854
- //ic.initUI();
17855
- ic.init();
17856
- ic.bInputfile = true;
17857
- ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + data : data;
17858
- ic.InputfileType = 'mmcif';
17859
- // await ic.mmcifParserCls.loadMmcifData(data);
17860
- await ic.opmParserCls.loadOpmData(dataStr, undefined, undefined, 'mmcif', undefined, bText);
17861
- };
17862
- reader.readAsText(file);
17863
- }
17826
+ ic.bAppend = true;
17827
+ let bmmCIF = true;
17828
+ let fileId = 'mmciffile';
17829
+ await thisClass.loadPdbFile(ic.bAppend, fileId, bmmCIF);
17864
17830
  });
17865
17831
 
17866
17832
  me.myEventCls.onIds("#" + me.pre + "applycustomcolor", "click", function(e) { let ic = me.icn3d;
@@ -18509,11 +18475,13 @@ class Events {
18509
18475
  let command;
18510
18476
  if(shape == 'Sphere') {
18511
18477
  ic.sphereCls.createSphereBase(pos1, color, radius, undefined, undefined, undefined, opacity);
18512
- command = 'add sphere | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
18478
+ // command = 'add sphere | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
18479
+ command = 'add sphere | ' + nameArray + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
18513
18480
  }
18514
18481
  else {
18515
18482
  ic.boxCls.createBox_base(pos1, radius, color, undefined, undefined, undefined, opacity);
18516
- command = 'add cube | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
18483
+ // command = 'add cube | x1 ' + pos1.x.toPrecision(4) + ' y1 ' + pos1.y.toPrecision(4) + ' z1 ' + pos1.z.toPrecision(4) + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
18484
+ command = 'add cube | ' + nameArray + ' | color ' + colorStr + ' | opacity ' + opacity + ' | radius ' + radius;
18517
18485
  }
18518
18486
 
18519
18487
  thisClass.setLogCmd(command, true);
@@ -29047,14 +29015,14 @@ class Strand {
29047
29015
  // include the whole sheet or helix when highlighting
29048
29016
  let atomsAdjust = {};
29049
29017
 
29050
- //if( (bHighlight === 1 || bHighlight === 2) && !ic.bAllAtoms) {
29051
- //if( !ic.bAllAtoms) {
29052
- if( Object.keys(atoms).length < Object.keys(ic.atoms).length) {
29053
- atomsAdjust = this.getSSExpandedAtoms(atoms);
29054
- }
29055
- else {
29056
- atomsAdjust = atoms;
29057
- }
29018
+ // if( Object.keys(atoms).length < Object.keys(ic.atoms).length) {
29019
+ // atomsAdjust = this.getSSExpandedAtoms(atoms);
29020
+ // }
29021
+ // else {
29022
+ // atomsAdjust = atoms;
29023
+ // }
29024
+
29025
+ atomsAdjust = atoms;
29058
29026
 
29059
29027
  if(bHighlight === 2) {
29060
29028
  if(fill) {
@@ -29112,9 +29080,16 @@ class Strand {
29112
29080
 
29113
29081
  let maxDist = 6.0;
29114
29082
 
29083
+ //get the last residue
29084
+ let atomArray = Object.keys(atoms);
29085
+ let lastAtomSerial = atomArray[atomArray.length - 1];
29086
+ let lastAtom = atoms[lastAtomSerial];
29087
+ let lastResid = lastAtom.structure + '_' + lastAtom.chain + '_' + lastAtom.resi;
29088
+
29115
29089
  for (let i in atomsAdjust) {
29116
29090
  atom = atomsAdjust[i];
29117
29091
  let chainid = atom.structure + '_' + atom.chain;
29092
+ let resid = atom.structure + '_' + atom.chain + '_' + atom.resi;
29118
29093
  if ((atom.name === 'O' || atom.name === 'CA') && !atom.het) {
29119
29094
  // "CA" has to appear before "O"
29120
29095
 
@@ -29151,7 +29126,7 @@ class Strand {
29151
29126
  if(atom.ssend && atom.ss === 'sheet') {
29152
29127
  bSheetSegment = true;
29153
29128
  }
29154
- else if(atom.ssend && atom.ss === 'helix') {
29129
+ else if( (atom.ssend && atom.ss === 'helix') || resid == lastResid) { // partial sheet will draw as helix
29155
29130
  bHelixSegment = true;
29156
29131
  }
29157
29132
 
@@ -29258,7 +29233,7 @@ class Strand {
29258
29233
  // }
29259
29234
 
29260
29235
  //if ((atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs) && pnts[0].length > 0 && bSameChain) {
29261
- if ((currentChain !== atom.chain || atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs) && pnts[0].length > 0) {
29236
+ if ((currentChain !== atom.chain || atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs || resid == lastResid) && pnts[0].length > 0) {
29262
29237
  let atomName = 'CA';
29263
29238
 
29264
29239
  let prevone = [], nexttwo = [];
@@ -29401,8 +29376,11 @@ class Strand {
29401
29376
  bHelixSegment = false;
29402
29377
  } // end if (atom.ssbegin || atom.ssend)
29403
29378
 
29404
- // end of a chain
29405
- if ((currentChain !== atom.chain || ic.ParserUtilsCls.getResiNCBI(atom.structure + '_' + currentChain, currentResi) + 1 !== ic.ParserUtilsCls.getResiNCBI(chainid, atom.resi)) && pnts[0].length > 0) {
29379
+ // end of a chain, or end of selection
29380
+ if ((currentChain !== atom.chain
29381
+ || ic.ParserUtilsCls.getResiNCBI(atom.structure + '_' + currentChain, currentResi) + 1 !== ic.ParserUtilsCls.getResiNCBI(chainid, atom.resi)
29382
+ || resid == lastResid
29383
+ ) && pnts[0].length > 0) {
29406
29384
  //if ((currentChain !== atom.chain) && pnts[0].length > 0) {
29407
29385
 
29408
29386
  let atomName = 'CA';
@@ -40838,9 +40816,24 @@ class AnnoCddSite {
40838
40816
  pssmid2toArray = {};
40839
40817
  }
40840
40818
 
40841
- let indexl =(domainArray !== undefined) ? domainArray.length : 0;
40819
+ if(domainArray === undefined) domainArray = [];
40820
+ let indexl = domainArray.length;
40842
40821
  let maxTextLen =(type == 'domain') ? 14 : 19;
40843
40822
  let titleSpace =(type == 'domain') ? 100 : 120;
40823
+
40824
+ // sort domainArray
40825
+ domainArray.sort(function(a, b) {
40826
+ let domainRepeatArray = a.locs;
40827
+ let segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
40828
+ let domainFrom1 = Math.round(segArray[0].from);
40829
+
40830
+ domainRepeatArray = b.locs;
40831
+ segArray = (type == 'domain' || type == 'ig') ? domainRepeatArray[0].segs : [domainRepeatArray[0]];
40832
+ let domainFrom2 = Math.round(segArray[0].from);
40833
+
40834
+ return domainFrom1 - domainFrom2;
40835
+ });
40836
+
40844
40837
  for(let index = 0; index < indexl; ++index) {
40845
40838
  let pssmid = (type == 'domain') ? domainArray[index].pssmid : 0;
40846
40839
 
@@ -40904,6 +40897,9 @@ class AnnoCddSite {
40904
40897
  // if(type != 'domain') setname += "_" + index + "_" + r;
40905
40898
  if(type != 'domain') setname = chnid + "_" + index + "_" + r + "_" + domain;
40906
40899
 
40900
+ //remove space in setname
40901
+ setname = setname.replace(/\s+/g, '');
40902
+
40907
40903
  if(type == 'domain') pssmid2fromArray[pssmid] = fromArray;
40908
40904
  if(type == 'domain') pssmid2toArray[pssmid] = toArray;
40909
40905
 
@@ -41706,6 +41702,7 @@ class AnnoIg {
41706
41702
  async showIg(chnid, template) { let ic = this.icn3d; ic.icn3dui;
41707
41703
  // if(!ic.bRunRefnum || Object.keys(ic.atoms).length > Object.keys(ic.hAtoms).length) {
41708
41704
  if(ic.bRunRefnumAgain) {
41705
+ // run for all chains
41709
41706
  await ic.refnumCls.showIgRefNum(template);
41710
41707
  // ic.bRunRefnum = true;
41711
41708
  }
@@ -42363,9 +42360,7 @@ class AnnoDomain {
42363
42360
 
42364
42361
  let result = ic.domain3dCls.c2b_NewSplitChain(atoms);
42365
42362
  let subdomains = result.subdomains;
42366
- let pos2resi = result.pos2resi;
42367
- //let substruct = result.substruct;
42368
- //let jsonStr = ic.domain3dCls.getDomainJsonForAlign(atoms);
42363
+ // let pos2resi = result.pos2resi;
42369
42364
 
42370
42365
  for(let i = 0, il = subdomains.length; i < il; ++i) {
42371
42366
  // domain item: {"sdid":1722375,"intervals":[[1,104],[269,323]]}
@@ -42379,7 +42374,7 @@ class AnnoDomain {
42379
42374
  data.domains[chainid].domains.push(domain);
42380
42375
  }
42381
42376
 
42382
- data.domains[chainid].pos2resi = pos2resi;
42377
+ // data.domains[chainid].pos2resi = pos2resi;
42383
42378
  }
42384
42379
  }
42385
42380
 
@@ -42412,11 +42407,26 @@ class AnnoDomain {
42412
42407
  this.showDomainPerStructure(i);
42413
42408
  }
42414
42409
  }
42410
+
42411
+ getResiFromNnbiresid(ncbiresid) { let ic = this.icn3d; ic.icn3dui;
42412
+ let resid = (ic.ncbi2resid[ncbiresid]) ? ic.ncbi2resid[ncbiresid] : ncbiresid;
42413
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
42414
+
42415
+ return resi;
42416
+ }
42417
+
42418
+ getNcbiresiFromResid(resid) { let ic = this.icn3d; ic.icn3dui;
42419
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
42420
+ let resi = ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1);
42421
+
42422
+ return resi;
42423
+ }
42424
+
42415
42425
  showDomainWithData(chnid, data, bCalcDirect) { let ic = this.icn3d, me = ic.icn3dui;
42416
42426
  let html = '<div id="' + ic.pre + chnid + '_domainseq_sequence" class="icn3d-dl_sequence">';
42417
42427
  let html2 = html;
42418
42428
  let html3 = html;
42419
- let domainArray, pos2resi, proteinname;
42429
+ let domainArray, proteinname;
42420
42430
  let pos = chnid.indexOf('_');
42421
42431
  let chain = chnid.substr(pos + 1);
42422
42432
  // MMDB symmetry chain has the form of 'A1'
@@ -42427,7 +42437,7 @@ class AnnoDomain {
42427
42437
  // if(bCalcDirect) {
42428
42438
  proteinname = chnid;
42429
42439
  domainArray = (data.domains[chnid]) ? data.domains[chnid].domains : [];
42430
- pos2resi = data.domains[chnid].pos2resi;
42440
+ // pos2resi = data.domains[chnid].pos2resi;
42431
42441
  /*
42432
42442
  }
42433
42443
  else {
@@ -42455,40 +42465,33 @@ class AnnoDomain {
42455
42465
  let title =(fulltitle.length > 17) ? fulltitle.substr(0,17) + '...' : fulltitle;
42456
42466
  let subdomainArray = domainArray[index].intervals;
42457
42467
  // remove duplicate, e.g., at https://www.ncbi.nlm.nih.gov/Structure/mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=1itw
42458
- let domainFromHash = {}, domainToHash = {};
42459
- let fromArray = [], toArray = [], posFromArray = [], posToArray = [];
42468
+ // let domainFromHash = {}, domainToHash = {};
42469
+ let fromArray = [], toArray = []; // posFromArray = [], posToArray = [];
42460
42470
  let resiHash = {};
42461
42471
  let resCnt = 0;
42462
42472
 
42473
+ // subdomainArray contains NCBI residue number
42463
42474
  for(let i = 0, il = subdomainArray.length; i < il; ++i) {
42464
- let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
42465
- let domainTo = Math.round(subdomainArray[i][1]) - 1;
42475
+ // let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
42476
+ // let domainTo = Math.round(subdomainArray[i][1]) - 1;
42466
42477
 
42467
- if(domainFromHash.hasOwnProperty(domainFrom) || domainToHash.hasOwnProperty(domainTo)) {
42468
- continue; // do nothing for duplicated "from" or "to", e.g, PDBID 1ITW, 5FWI
42469
- }
42470
- else {
42471
- domainFromHash[domainFrom] = 1;
42472
- domainToHash[domainTo] = 1;
42473
- }
42478
+ let domainFrom = parseInt(subdomainArray[i][0]);
42479
+ let domainTo = parseInt(subdomainArray[i][1]);
42474
42480
 
42475
- // use the NCBI residue number, and convert to PDB residue number during selection
42476
- // if(ic.bNCBI || bCalcDirect) {
42477
- fromArray.push(pos2resi[domainFrom]);
42478
- toArray.push(pos2resi[domainTo]);
42479
42481
 
42480
- posFromArray.push(domainFrom);
42481
- posToArray.push(domainTo);
42482
- // }
42483
- // else {
42484
- // fromArray.push(domainFrom + ic.baseResi[chnid]);
42485
- // toArray.push(domainTo + ic.baseResi[chnid]);
42486
- // }
42482
+ // fromArray.push(pos2resi[domainFrom]);
42483
+ // toArray.push(pos2resi[domainTo]);
42484
+
42485
+ fromArray.push(domainFrom);
42486
+ toArray.push(domainTo);
42487
+
42488
+ // posFromArray.push(domainFrom);
42489
+ // posToArray.push(domainTo);
42487
42490
 
42488
42491
  resCnt += domainTo - domainFrom + 1;
42489
42492
  for(let j = domainFrom; j <= domainTo; ++j) {
42490
- // resiHash[j+1] = 1;
42491
- let resi = pos2resi[j];
42493
+ // let resi = pos2resi[j];
42494
+ let resi = this.getResiFromNnbiresid(chnid + '_' + j);
42492
42495
  resiHash[resi] = 1;
42493
42496
  }
42494
42497
  }
@@ -42499,21 +42502,22 @@ class AnnoDomain {
42499
42502
 
42500
42503
  if(!ic.resid2domain) ic.resid2domain = {};
42501
42504
  if(!ic.resid2domain[chnid]) ic.resid2domain[chnid] = [];
42502
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
42503
- let from = parseInt(posFromArray[i]);
42504
- let to = parseInt(posToArray[i]);
42505
+ // for(let i = 0, il = posFromArray.length; i < il; ++i) {
42506
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
42507
+ let from = fromArray[i];
42508
+ let to = toArray[i];
42505
42509
  for(let j = from; j <= to; ++j) {
42506
42510
  // 0-based
42507
42511
  let obj = {};
42508
42512
  // let resi = ic.ParserUtilsCls.getResi(chnid, j);
42509
- let resi = pos2resi[j];
42510
- obj[chnid + '_' + resi] = domainName;
42513
+ let resid = ic.ncbi2resid(chnid + '_' + j);
42514
+ obj[resid] = domainName;
42511
42515
  ic.resid2domain[chnid].push(obj);
42512
42516
  }
42513
42517
  }
42514
42518
  }
42515
42519
 
42516
- 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>';
42520
+ 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>';
42517
42521
  let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
42518
42522
  html3 += htmlTmp2 + htmlTmp3 + '<br>';
42519
42523
  let htmlTmp = '<span class="icn3d-seqLine">';
@@ -42553,12 +42557,12 @@ class AnnoDomain {
42553
42557
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
42554
42558
 
42555
42559
  if(me.cfg.blast_rep_id != chnid) { // regular
42556
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
42560
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
42557
42561
  // 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);
42558
- let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
42562
+ let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(fromArray[i] - toArray[i-1] - 1) / ic.maxAnnoLength);
42559
42563
 
42560
42564
  html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
42561
- 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>';
42565
+ 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>';
42562
42566
  }
42563
42567
  }
42564
42568
  else { // with potential gaps
@@ -44070,6 +44074,7 @@ class Domain3d {
44070
44074
  //c2b_NewSplitChain(string asymId, let seqLen, let* x0, let* y0, let* z0) { let ic = this.icn3d, me = ic.icn3dui;
44071
44075
  // x0, y0, z0: array of x,y,z coordinates of C-alpha atoms
44072
44076
  //c2b_NewSplitChain(chnid, dcut) { let ic = this.icn3d, me = ic.icn3dui;
44077
+ // this function works for a single chain
44073
44078
  c2b_NewSplitChain(atoms, dcut) { let ic = this.icn3d; ic.icn3dui;
44074
44079
  this.init3ddomain();
44075
44080
 
@@ -44125,14 +44130,11 @@ class Domain3d {
44125
44130
  // pos2resi[i+1] = resi;
44126
44131
  pos2resi[i] = resi;
44127
44132
 
44128
- ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
44129
- // let residNCBI = ic.resid2ncbi[resid];
44130
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44131
- // pos2resi[pos] = resi;
44132
-
44133
+ // ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
44133
44134
  if(atom.ssend) {
44134
44135
  //substructItem.To = parseInt(resi);
44135
44136
  substructItem.To = i + 1;
44137
+ // substructItem.To = ic.annoDomainCls.getNcbiresiFromResid(resid);
44136
44138
  substructItem.x2 = atom.coord.x;
44137
44139
  substructItem.y2 = atom.coord.y;
44138
44140
  substructItem.z2 = atom.coord.z;
@@ -44147,6 +44149,7 @@ class Domain3d {
44147
44149
  if(atom.ssbegin) {
44148
44150
  //substructItem.From = parseInt(resi);
44149
44151
  substructItem.From = i + 1;
44152
+ // substructItem.From = ic.annoDomainCls.getNcbiresiFromResid(resid);
44150
44153
  substructItem.x1 = atom.coord.x;
44151
44154
  substructItem.y1 = atom.coord.y;
44152
44155
  substructItem.z1 = atom.coord.z;
@@ -44154,17 +44157,19 @@ class Domain3d {
44154
44157
  }
44155
44158
 
44156
44159
  let nsse = substruct.length;
44157
-
44158
- if (nsse <= 3)
44160
+
44161
+ if (nsse <= 3) {
44159
44162
  // too small, can't split or trim
44160
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44163
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44164
+ return {subdomains: subdomains, substruct: substruct};
44165
+ }
44161
44166
 
44162
44167
  if (nsse > this.MAX_SSE) {
44163
44168
  // we have a problem...
44164
-
44165
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44169
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44170
+ return {subdomains: subdomains, substruct: substruct};
44166
44171
  }
44167
-
44172
+
44168
44173
  let seqLen = residueArray.length; // + resiOffset;
44169
44174
  //let lastResi = resiArray[seqLen - 1];
44170
44175
  let lastResi = seqLen;
@@ -44485,7 +44490,8 @@ class Domain3d {
44485
44490
  let k = prts[i] - 1;
44486
44491
 
44487
44492
  if ((k < 0) || (k >= substruct.length)) {
44488
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44493
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44494
+ return {subdomains: subdomains, substruct: substruct};
44489
44495
  }
44490
44496
 
44491
44497
  //SSE_Rec sserec = substruct[k];
@@ -44572,16 +44578,23 @@ class Domain3d {
44572
44578
 
44573
44579
  if (inseg && (rf == 0)) {
44574
44580
  // segment ends
44575
- segments.push(startseg);
44576
- segments.push(i);
44581
+ // segments.push(startseg);
44582
+ // segments.push(i);
44583
+
44584
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, i, pos2resi);
44585
+ segments = segments.concat(resiRangeArray);
44586
+
44577
44587
  inseg = false;
44578
44588
  }
44579
44589
  }
44580
44590
 
44581
44591
  // check for the last segment
44582
44592
  if (inseg) {
44583
- segments.push(startseg);
44584
- segments.push(lastResi);
44593
+ // segments.push(startseg);
44594
+ // segments.push(lastResi);
44595
+
44596
+ let resiRangeArray = this.getNcbiresiRangeFromPos(chnid, startseg, lastResi, pos2resi);
44597
+ segments = segments.concat(resiRangeArray);
44585
44598
  }
44586
44599
 
44587
44600
  subdomains.push(segments);
@@ -44602,61 +44615,114 @@ class Domain3d {
44602
44615
  }
44603
44616
  }
44604
44617
 
44605
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi };
44618
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44619
+
44620
+ // return {subdomains: subdomains, substruct: substruct};
44621
+ //subdomains contains NCBI residue numbers
44622
+ return {subdomains: subdomains, substruct: substruct};
44606
44623
  } // end c2b_NewSplitChain
44607
44624
 
44608
- getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
44625
+ standardizeSubstruct(chnid, substruct, pos2resi) { let ic = this.icn3d; ic.icn3dui;
44626
+ // adjust substruct to use NCBI residue number
44627
+ for (let i = 0; i < substruct.length; i++) {
44628
+ //SSE_Rec sserec = substruct[i];
44629
+ let sserec = substruct[i];
44630
+ let FromPos = sserec.From;
44631
+ let ToPos = sserec.To;
44632
+
44633
+ let FromResi = pos2resi[FromPos - 1];
44634
+ let ToResi = pos2resi[ToPos - 1];
44635
+
44636
+ let FromNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + FromResi);
44637
+ let ToNcbiResid = ic.annoDomainCls.getNcbiresiFromResid(chnid + '_' + ToResi);
44638
+
44639
+ substruct[i].From = FromNcbiResid.substr(FromNcbiResid.lastIndexOf('_') + 1);
44640
+ substruct[i].To = ToNcbiResid.substr(ToNcbiResid.lastIndexOf('_') + 1);
44641
+
44642
+ substruct[i].From = parseInt(substruct[i].From);
44643
+ substruct[i].To = parseInt(substruct[i].To);
44644
+ }
44645
+
44646
+ return substruct;
44647
+ }
44648
+
44649
+ getNcbiresiRangeFromPos(chnid, startPos, endPos, pos2resi) { let ic = this.icn3d; ic.icn3dui;
44650
+ let resiArray = [];
44651
+ for(let i = startPos; i <= endPos; ++i) {
44652
+ let resi = pos2resi[i - 1];
44653
+ let residNCBI = (ic.resid2ncbi[chnid + '_' + resi]) ? ic.resid2ncbi[chnid + '_' + resi] : chnid + '_' + resi;
44654
+ let ncbiresi = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44655
+ resiArray.push(parseInt(ncbiresi));
44656
+ }
44657
+
44658
+ let resiRangeArray = ic.resid2specCls.resi2range(resiArray);
44659
+
44660
+ return resiRangeArray;
44661
+ }
44662
+
44663
+ /*
44664
+ // this function works for atoms in a single chain
44665
+ // getDomainJsonForAlign(atoms, bForceOneDomain) { let ic = this.icn3d, me = ic.icn3dui;
44666
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
44609
44667
  let result = this.c2b_NewSplitChain(atoms);
44610
44668
 
44611
44669
  let subdomains = result.subdomains;
44612
44670
  let substruct = result.substruct;
44613
- let pos2resi = result.pos2resi;
44671
+ // let pos2resi = result.pos2resi;
44614
44672
 
44615
- let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44616
- let residueArray = Object.keys(residueHash);
44617
- let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44618
44673
 
44619
- if(bForceOneDomain) subdomains = [];
44674
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44675
+ // let residueArray = Object.keys(residueHash);
44676
+ // let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44620
44677
 
44621
- //the whole structure is also considered as a large domain
44622
- //if(subdomains.length == 0) {
44623
- //subdomains.push([parseInt(ic.chainsSeq[chnid][0].resi), parseInt(ic.chainsSeq[chnid][ic.chainsSeq[chnid].length - 1].resi)]);
44678
+ let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
44679
+ let chnid = firstAtom.structure + '_' + firstAtom.chain;
44624
44680
 
44625
- // subdomains.push([parseInt(residueArray[0].substr(residueArray[0].lastIndexOf('_') + 1)),
44626
- // parseInt(residueArray[residueArray.length-1].substr(residueArray[residueArray.length-1].lastIndexOf('_') + 1))]);
44681
+ // if(bForceOneDomain) subdomains = [];
44627
44682
 
44628
- // use position based
44629
- subdomains.push([1, residueArray.length]);
44630
-
44631
- //}
44683
+ //the whole structure is also considered as a large domain
44684
+ if(subdomains.length == 0) {
44685
+ let resid1 = residueArray[0];
44686
+ let resid2 = residueArray[residueArray.length - 1];
44687
+ let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
44688
+ let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
44689
+ subdomains.push([parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1)), parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1))]);
44690
+ }
44632
44691
 
44633
44692
  // 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], ...]} ] }
44634
44693
  let jsonStr = '{"data": [';
44694
+ //merge all subdomains into one domain
44695
+ jsonStr += '{"ss": ['; //secondary structure
44696
+
44697
+ let ssCnt = 0, startAll = 999, endAll = -999;
44635
44698
  for(let i = 0, il = subdomains.length; i < il; ++i) {
44636
- if(i > 0) jsonStr += ', ';
44637
- //secondary structure
44638
- jsonStr += '{"ss": [';
44639
- let ssCnt = 0;
44699
+ // if(i > 0) jsonStr += ', ';
44700
+ // jsonStr += '{"ss": ['; //secondary structure
44701
+
44640
44702
  for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
44641
44703
  let start = subdomains[i][j];
44642
44704
  let end = subdomains[i][j + 1];
44643
-
44705
+
44706
+ if(start < startAll) startAll = start;
44707
+ if(end > endAll) endAll = end;
44708
+
44644
44709
  for(let k = 0, kl = substruct.length; k < kl; ++k) {
44645
44710
  //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
44646
44711
  //sstype: 1 (helix), 2 (sheet)
44647
44712
  let sstype = (substruct[k].Sheet) ? 2 : 1;
44648
- let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
44649
- let to = pos2resi[substruct[k].To - 1];
44713
+ // let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
44714
+ // let to = pos2resi[substruct[k].To - 1];
44650
44715
 
44651
44716
  // 1-based residue numbers
44652
44717
  let fromPos = substruct[k].From;
44653
44718
  let toPos = substruct[k].To;
44654
44719
 
44655
- let residFrom = chnid + "_" + from;
44720
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
44656
44721
  let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
44722
+
44657
44723
  if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
44658
44724
 
44659
- let residTo = chnid + "_" + to;
44725
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
44660
44726
  let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
44661
44727
  if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
44662
44728
 
@@ -44668,45 +44734,170 @@ class Domain3d {
44668
44734
  }
44669
44735
  }
44670
44736
  }
44671
- jsonStr += ']';
44737
+ }
44738
+ jsonStr += ']';
44739
+
44740
+ // domain
44741
+ jsonStr += ', "domain": [';
44742
+ let domainCnt = 0;
44743
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
44672
44744
 
44673
- // domain
44674
- jsonStr += ', "domain": [';
44675
- let domainCnt = 0;
44676
- for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
44677
- let start = subdomains[i][j];
44678
- let end = subdomains[i][j + 1];
44745
+ // resi should be the continuous number starting from 1. make this correction in the backend
44746
+ for(let j = startAll; j <= endAll; ++j) {
44747
+ let ncbiResid = chnid + '_' + j;
44748
+ let resid = ic.ncbi2resid[ncbiResid];
44749
+
44750
+ let pos = j;
44751
+
44752
+ if(domainCnt > 0) jsonStr += ', ';
44753
+
44754
+ if(!residueHash.hasOwnProperty(resid)) {
44755
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
44756
+ }
44757
+ else {
44758
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44759
+
44760
+ //domain: resi, restype, x, y, z
44761
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
44762
+
44763
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44764
+ }
44765
+
44766
+ ++domainCnt;
44767
+ }
44768
+ jsonStr += ']}';
44769
+
44770
+ jsonStr += ']}';
44771
+
44772
+ return jsonStr;
44773
+ }
44774
+ */
44775
+ // this function works for atoms in a single chain
44776
+ getDomainJsonForAlign(atoms) { let ic = this.icn3d, me = ic.icn3dui;
44777
+ // let result = this.c2b_NewSplitChain(atoms);
44778
+
44779
+ // let subdomains = result.subdomains;
44780
+ // let substruct = result.substruct;
44781
+
44782
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44783
+ let residueArray = Object.keys(residueHash);
44784
+ let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44785
+
44786
+ // let resid1 = residueArray[0];
44787
+ // let resid2 = residueArray[residueArray.length - 1];
44788
+ // let ncbiresid1 = (ic.resid2ncbi[resid1]) ? ic.resid2ncbi[resid1] : resid1;
44789
+ // let ncbiresid2 = (ic.resid2ncbi[resid2]) ? ic.resid2ncbi[resid2] : resid2;
44790
+ // let startAll = parseInt(ncbiresid1.substr(ncbiresid1.lastIndexOf('_') + 1));
44791
+ // let endAll = parseInt(ncbiresid2.substr(ncbiresid2.lastIndexOf('_') + 1));
44792
+
44793
+ let substruct = [];
44794
+ let substructItem = {};
44795
+ let pos2resi = {}; // 0-based
44796
+ let startAll = 999, endAll = -999;
44797
+ for(let i = 0; i < residueArray.length; ++i) {
44798
+ let resid = residueArray[i];
44799
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44679
44800
 
44680
- for(let k = 0, kl = residueArray.length; k < kl; ++k) {
44681
- let resid = residueArray[k];
44801
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
44802
+ pos2resi[i] = resi;
44803
+
44804
+ let ncbiresid = (ic.resid2ncbi[resid]) ? ic.resid2ncbi[resid] : resid;
44805
+ let ncbiresi = parseInt(ncbiresid.substr(ncbiresid.lastIndexOf('_') + 1));
44806
+
44807
+ if(ncbiresi < startAll) startAll = ncbiresi;
44808
+ if(ncbiresi > endAll) endAll = ncbiresi;
44809
+
44810
+ if(atom.ssend) {
44811
+ substructItem.To = i + 1;
44812
+ substructItem.x2 = atom.coord.x;
44813
+ substructItem.y2 = atom.coord.y;
44814
+ substructItem.z2 = atom.coord.z;
44682
44815
 
44683
- // let resi = resid.substr(resid.lastIndexOf('_') + 1);
44684
- // let residNCBI = ic.resid2ncbi[resid];
44685
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44686
- let pos = k + 1;
44816
+ substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
44817
+
44818
+ substruct.push(substructItem);
44819
+ substructItem = {};
44820
+ }
44821
+
44822
+ // a residue could be both start and end. check ssend first, then check ssbegin
44823
+ if(atom.ssbegin) {
44824
+ substructItem.From = i + 1;
44825
+ substructItem.x1 = atom.coord.x;
44826
+ substructItem.y1 = atom.coord.y;
44827
+ substructItem.z1 = atom.coord.z;
44828
+ }
44829
+ }
44830
+
44831
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44832
+
44833
+ // 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], ...]} ] }
44834
+ let jsonStr = '{"data": [';
44835
+ //merge all subdomains into one domain
44836
+ jsonStr += '{"ss": ['; //secondary structure
44837
+
44838
+ let ssCnt = 0;
44839
+ for(let k = 0, kl = substruct.length; k < kl; ++k) {
44840
+ //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
44841
+ //sstype: 1 (helix), 2 (sheet)
44842
+ let sstype = (substruct[k].Sheet) ? 2 : 1;
44843
+
44844
+ // 1-based residue numbers
44845
+ let fromPos = substruct[k].From;
44846
+ let toPos = substruct[k].To;
44847
+
44848
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
44849
+ let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
44850
+ if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
44851
+
44852
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
44853
+ let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
44854
+ if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
44855
+
44856
+ // if(fromPos >= start && toPos <= end) {
44857
+ if(ssCnt > 0) jsonStr += ', ';
44858
+ jsonStr += '[' + sstype + ',' + fromPos + ',' + toPos + ',' + substruct[k].x1.toFixed(2) + ',' + substruct[k].y1.toFixed(2) + ','
44859
+ + substruct[k].z1.toFixed(2) + ',' + substruct[k].x2.toFixed(2) + ',' + substruct[k].y2.toFixed(2) + ',' + substruct[k].z2.toFixed(2) + ']';
44860
+ ++ssCnt;
44861
+ // }
44862
+ }
44863
+
44864
+ jsonStr += ']';
44687
44865
 
44688
- //let resid = chnid + "_" + resi;
44689
- let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44690
-
44691
- if(!atom) continue;
44692
- if(!ic.hAtoms.hasOwnProperty(atom.serial)) continue;
44693
-
44694
- //domain: resi, restype, x, y, z
44695
- let restype = me.parasCls.resn2restype[atom.resn];
44696
- if(restype !== undefined && pos >= start && pos <= end) {
44697
- if(domainCnt > 0) jsonStr += ', ';
44698
- jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ','
44699
- + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44700
- ++domainCnt;
44701
- }
44702
- }
44866
+ // domain
44867
+ jsonStr += ', "domain": [';
44868
+ let domainCnt = 0;
44869
+ let fakeCoord = 0; //-100000; // the fake corrd is not read anyway
44870
+
44871
+ // resi should be the continuous number starting from 1. make this correction in the backend
44872
+ for(let j = startAll; j <= endAll; ++j) {
44873
+ let ncbiResid = chnid + '_' + j;
44874
+ let resid = ic.ncbi2resid[ncbiResid];
44875
+
44876
+ let pos = j;
44877
+
44878
+ if(domainCnt > 0) jsonStr += ', ';
44879
+
44880
+ if(!residueHash.hasOwnProperty(resid)) {
44881
+ jsonStr += '[' + pos + ',' + 0 + ',' + fakeCoord + ',' + fakeCoord + ',' + fakeCoord + ']';
44882
+ }
44883
+ else {
44884
+ let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44885
+
44886
+ //domain: resi, restype, x, y, z
44887
+ let restype = (me.parasCls.resn2restype[atom.resn]) ? me.parasCls.resn2restype[atom.resn] : 0;
44888
+
44889
+ jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ',' + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44703
44890
  }
44704
- jsonStr += ']}';
44891
+
44892
+ ++domainCnt;
44705
44893
  }
44706
44894
  jsonStr += ']}';
44707
44895
 
44896
+ jsonStr += ']}';
44897
+
44708
44898
  return jsonStr;
44709
44899
  }
44900
+
44710
44901
  }
44711
44902
 
44712
44903
  /**
@@ -44804,27 +44995,12 @@ class AddTrack {
44804
44995
  });
44805
44996
 
44806
44997
  // Isoform Alignment
44807
- me.myEventCls.onIds("#" + ic.pre + "addtrack_button2c", "click", async function(e) { let ic = thisClass.icn3d;
44998
+ me.myEventCls.onIds("#" + ic.pre + "addtrack_button2c", "click", async function(e) { thisClass.icn3d;
44808
44999
  e.stopImmediatePropagation();
44809
45000
  //e.preventDefault();
44810
45001
  dialog.dialog( "close" );
44811
45002
 
44812
- let chainid = $("#" + ic.pre + "track_chainid").val();
44813
- let geneid = $("#" + ic.pre + "track_geneid").val();
44814
- if(!geneid) {
44815
- alert("Please fill in the Gene ID...");
44816
- return;
44817
- }
44818
-
44819
- let startpos = $("#" + ic.pre + "fasta_startpos2").val();
44820
- if(!startpos) startpos = 1;
44821
-
44822
- //let colorseqby = $("#" + ic.pre + "colorseqby2").val();
44823
- //let type =(colorseqby == 'identity') ? 'identity' : 'custom';
44824
-
44825
- let type = 'identity';
44826
-
44827
- await thisClass.addExonTracks(chainid, geneid, startpos, type);
45003
+ await thisClass.addExonTracksWrap();
44828
45004
  });
44829
45005
 
44830
45006
  // BED file
@@ -46415,6 +46591,25 @@ class AddTrack {
46415
46591
  return acclistTmp;
46416
46592
  }
46417
46593
 
46594
+ async addExonTracksWrap() { let ic = this.icn3d; ic.icn3dui;
46595
+ let chainid = $("#" + ic.pre + "track_chainid").val();
46596
+ let geneid = $("#" + ic.pre + "track_geneid").val();
46597
+ if(!geneid) {
46598
+ alert("Please fill in the Gene ID...");
46599
+ return;
46600
+ }
46601
+
46602
+ let startpos = $("#" + ic.pre + "fasta_startpos2").val();
46603
+ if(!startpos) startpos = 1;
46604
+
46605
+ //let colorseqby = $("#" + ic.pre + "colorseqby2").val();
46606
+ //let type =(colorseqby == 'identity') ? 'identity' : 'custom';
46607
+
46608
+ let type = 'identity';
46609
+
46610
+ await thisClass.addExonTracks(chainid, geneid, startpos, type);
46611
+ }
46612
+
46418
46613
  async addExonTracks(chainid, geneid, startpos, type) { let ic = this.icn3d, me = ic.icn3dui;
46419
46614
  let thisClass = this;
46420
46615
 
@@ -46808,7 +47003,6 @@ class Annotation {
46808
47003
  if($("#" + ic.pre + "anno_transmem").length) $("#" + ic.pre + "anno_transmem")[0].checked = false;
46809
47004
  }
46810
47005
  async setAnnoTabIg(bSelection, template) { let ic = this.icn3d; ic.icn3dui;
46811
-
46812
47006
  await this.updateIg(bSelection, template);
46813
47007
 
46814
47008
  $("[id^=" + ic.pre + "ig]").show();
@@ -47149,7 +47343,7 @@ class Annotation {
47149
47343
 
47150
47344
  async updateIg(bSelection, template) { let ic = this.icn3d, me = ic.icn3dui;
47151
47345
  ic.opts['color'] = 'ig strand';
47152
-
47346
+
47153
47347
  // if(!bSelection && !template) {
47154
47348
  if(!bSelection) {
47155
47349
  // select all protein chains
@@ -47168,11 +47362,13 @@ class Annotation {
47168
47362
  }
47169
47363
 
47170
47364
  ic.bRunRefnumAgain = true;
47171
- for(let chainid in ic.protein_chainid) {
47365
+ let chainidHash = (!bSelection) ? ic.protein_chainid : ic.firstAtomObjCls.getChainsFromAtoms(ic.hAtoms);
47366
+ for(let chainid in chainidHash) {
47367
+ // showIgRefNum() in showIg() runs for all chains
47172
47368
  await ic.annoIgCls.showIg(chainid, template);
47173
47369
  ic.bRunRefnumAgain = false; // run it once for all chains
47174
47370
  }
47175
-
47371
+
47176
47372
  if(ic.bShowRefnum) {
47177
47373
  ic.hlUpdateCls.updateHlAll();
47178
47374
  ic.drawCls.draw();
@@ -48609,11 +48805,12 @@ class HlSeq {
48609
48805
  ic.bAlignSeq = false;
48610
48806
  ic.bAnnotations = true;
48611
48807
  }
48612
-
48808
+
48613
48809
  if(ic.bSelectResidue === false && !ic.bShift && !ic.bCtrl) {
48810
+ // if(!ic.bShift && !ic.bCtrl) {
48614
48811
  ic.selectionCls.removeSelection();
48615
48812
  }
48616
-
48813
+
48617
48814
  // select residues
48618
48815
  $("span.ui-selected", this).each(function() {
48619
48816
  let id = $(this).attr('id');
@@ -48624,11 +48821,12 @@ class HlSeq {
48624
48821
  });
48625
48822
 
48626
48823
  ic.selectionCls.saveSelectionPrep(true);
48627
- ic.selectionCls.saveSelection(undefined, undefined, true);
48824
+ //ic.selectionCls.saveSelection(undefined, undefined, true);
48825
+ // do not use selected residues, use ic.hAtoms instead
48826
+ ic.selectionCls.saveSelection(undefined, undefined, false);
48628
48827
 
48629
48828
  //ic.residueLabelsCls.addResidueLabels(ic.hAtoms, false, 0.5);
48630
48829
  ic.hlObjectsCls.addHlObjects(); // render() is called
48631
-
48632
48830
  // get all chainid in the selected residues
48633
48831
  let chainHash = {};
48634
48832
  for(let residueid in ic.selectedResidues) {
@@ -48711,7 +48909,9 @@ class HlSeq {
48711
48909
  thisClass.selectResidues(id, this);
48712
48910
 
48713
48911
  ic.selectionCls.saveSelectionPrep(true);
48714
- ic.selectionCls.saveSelection(undefined, undefined, true);
48912
+ //ic.selectionCls.saveSelection(undefined, undefined, true);
48913
+ // do not use selected residues, use ic.hAtoms instead
48914
+ ic.selectionCls.saveSelection(undefined, undefined, false);
48715
48915
  }
48716
48916
  //});
48717
48917
 
@@ -48915,8 +49115,9 @@ class HlSeq {
48915
49115
  residueid = ic.ncbi2resid[residNCBI];
48916
49116
  }
48917
49117
  else if($(that).attr('3ddomain') !== undefined) {
48918
- // the position of residues with coordinates
48919
- residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
49118
+ // NCBI residue numbers
49119
+ // residueid = ic.posid2resid[chainid + '_' + (j+1).toString()];
49120
+ residueid = ic.ncbi2resid[chainid + '_' + j];
48920
49121
  }
48921
49122
  else {
48922
49123
  residueid = chainid + '_' + (j+1).toString();
@@ -49036,9 +49237,10 @@ class HlSeq {
49036
49237
  if(me.bNode) return;
49037
49238
 
49038
49239
  if(ic.bSelectResidue === false && !ic.bShift && !ic.bCtrl) {
49240
+ // if(!ic.bShift && !ic.bCtrl) {
49039
49241
  ic.selectionCls.removeSelection();
49040
49242
  }
49041
-
49243
+
49042
49244
  if(id !== undefined && id !== '') {
49043
49245
  // add "align_" in front of id so that full sequence and aligned sequence will not conflict
49044
49246
  //if(id.substr(0, 5) === 'align') id = id.substr(5);
@@ -49599,7 +49801,7 @@ class LineGraph {
49599
49801
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
49600
49802
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
49601
49803
  let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
49602
- let linkedNodeCnt = {}, linkedNodeInterDiff = {};
49804
+ let linkedNodeCnt = {}, linkedNodeInterDiff = {}, linkedNodeInterDiffBool = {};
49603
49805
 
49604
49806
  for(let i = 0, il = structureArray.length; i < il; ++i) {
49605
49807
  nodeArray1Split[i] = [];
@@ -49658,13 +49860,15 @@ class LineGraph {
49658
49860
  linkedNodeInterDiff[mappingid] = link.n;
49659
49861
  }
49660
49862
  else {
49661
- ++linkedNodeCnt[mappingid];
49662
- linkedNodeInterDiff[mappingid] -= link.n; // show difference
49863
+ ++linkedNodeCnt[mappingid];
49864
+ linkedNodeInterDiff[mappingid] += link.n;
49865
+
49866
+ linkedNodeInterDiffBool[mappingid] = (linkedNodeInterDiff[mappingid] / link.n == linkedNodeCnt[mappingid]) ? 0 : 1;
49663
49867
  }
49664
49868
  }
49665
49869
  }
49666
49870
  }
49667
-
49871
+
49668
49872
  // do not combine with the above section since linkedNodeCnt was pre-populated above
49669
49873
  // set linkArraySplitCommon and nameHashSplitCommon
49670
49874
  // set linkArraySplitDiff and nameHashSplitDiff
@@ -49710,7 +49914,7 @@ class LineGraph {
49710
49914
  linkDiff.source += separatorDiff + ic.chainsMapping[chainid1][resid1];
49711
49915
  linkDiff.target += separatorDiff + ic.chainsMapping[chainid2][resid2];
49712
49916
 
49713
- if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiff[mappingid] == 0) {
49917
+ if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiffBool[mappingid] == 0) {
49714
49918
  linkArraySplitCommon[index].push(linkCommon);
49715
49919
  }
49716
49920
  else {
@@ -50407,18 +50611,20 @@ class GetGraph {
50407
50611
  return lineGraphStr;
50408
50612
  }
50409
50613
 
50410
- updateGraphColor() { let ic = this.icn3d, me = ic.icn3dui;
50614
+ updateGraphColor() { let ic = this.icn3d; ic.icn3dui;
50411
50615
  // change graph color
50412
50616
 
50617
+ // do not update the graph for now
50618
+ /*
50413
50619
  if(ic.graphStr !== undefined) {
50414
50620
  let graphJson = JSON.parse(ic.graphStr);
50415
- let resid2color = {};
50621
+ let resid2color = {}
50416
50622
  for(let resid in ic.residues) {
50417
50623
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
50418
50624
  resid2color[resid] = atom.color.getHexString().toUpperCase();
50419
50625
  }
50420
50626
 
50421
- let target2resid = {};
50627
+ let target2resid = {}
50422
50628
  for(let i = 0, il = graphJson.nodes.length; i < il; ++i) {
50423
50629
  let node = graphJson.nodes[i];
50424
50630
  //node.r: 1_1_1KQ2_A_1
@@ -50447,6 +50653,7 @@ class GetGraph {
50447
50653
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
50448
50654
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
50449
50655
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
50656
+ */
50450
50657
  }
50451
50658
 
50452
50659
  handleForce() { let ic = this.icn3d, me = ic.icn3dui;
@@ -52610,7 +52817,7 @@ class ContactMap {
52610
52817
 
52611
52818
  let graphStr = '{\n';
52612
52819
 
52613
- let struc1 = (ic.structures.length > 0) ? ic.structures[0] : ic.defaultPdbId;
52820
+ let struc1 = (Object.keys(ic.structures).length > 0) ? ic.structures[0] : ic.defaultPdbId;
52614
52821
  let len1 = nodeArray1.length,
52615
52822
  len2 = nodeArray2.length;
52616
52823
  let factor = 1;
@@ -53144,6 +53351,7 @@ class ChainalignParser {
53144
53351
  let allPromise = Promise.allSettled(ajaxArray);
53145
53352
  // try {
53146
53353
  let dataArray = await allPromise;
53354
+
53147
53355
  await thisClass.downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray, indexArray, mmdbid_t, struArray);
53148
53356
  // }
53149
53357
  // catch(err) {
@@ -53747,13 +53955,13 @@ class ChainalignParser {
53747
53955
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
53748
53956
  && align !== undefined && JSON.stringify(align).indexOf('Oops there was a problem') === -1
53749
53957
  ) {
53750
- if((align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53958
+ if((align === "error" || align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53751
53959
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
53752
53960
  ic.q_trans_sub[index] = {"x":0, "y":0, "z":0};
53753
53961
  ic.q_rotation[index] = {"x1":1, "y1":0, "z1":0, "x2":0, "y2":1, "z2":0, "x3":0, "y3":0, "z3":1};
53754
53962
  ic.qt_start_end[index] = undefined;
53755
53963
  }
53756
- else if(align === undefined || align.length == 0) {
53964
+ else if(align === "error" || align === undefined || align.length == 0) {
53757
53965
  if(!me.cfg.command && !bNoAlert) alert('These two chains can not align to each other. ' + 'Please select sequences from these two chains in the "Sequences & Annotations" window, ' + 'and click "Realign Selection" in the "File" menu to align your selection.');
53758
53966
 
53759
53967
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
@@ -53784,14 +53992,16 @@ class ChainalignParser {
53784
53992
  ic.qt_start_end[index] = align[0].segs;
53785
53993
 
53786
53994
  let rmsd = align[0].super_rmsd;
53995
+ let rmsdStr = (rmsd) ? rmsd.toPrecision(4) : rmsd;
53996
+ let scoreStr = (align[0].score) ? align[0].score.toPrecision(4) : align[0].score;
53787
53997
 
53788
- let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
53789
- if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + align[0].score.toPrecision(4);
53998
+ let logStr = "alignment RMSD: " + rmsdStr;
53999
+ if(me.cfg.aligntool == 'tmalign') logStr += "; TM-score: " + scoreStr;
53790
54000
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
53791
- let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
54001
+ let html = "<br><b>Alignment RMSD</b>: " + rmsdStr + " &#8491;<br>";
53792
54002
  if(me.cfg.aligntool == 'tmalign') {
53793
- html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
53794
- ic.tmscore = align[0].score.toPrecision(4);
54003
+ html += "<b>TM-score</b>: " + scoreStr + "<br><br>";
54004
+ ic.tmscore = scoreStr;
53795
54005
  }
53796
54006
 
53797
54007
  $("#" + ic.pre + "dl_rmsd_html").html(html);
@@ -53938,6 +54148,7 @@ class ChainalignParser {
53938
54148
  let allPromise = Promise.allSettled(ajaxArray);
53939
54149
  // try {
53940
54150
  let dataArray = await allPromise;
54151
+
53941
54152
  await thisClass.parseMMdbAfData(dataArray, structArray, bQuery, vastplusAtype);
53942
54153
  if(vastplusAtype === undefined) ic.ParserUtilsCls.hideLoading();
53943
54154
  // }
@@ -53970,13 +54181,9 @@ class ChainalignParser {
53970
54181
 
53971
54182
  //if(!ic.bCommandLoad && !bQuery) ic.init(); // remove all previously loaded data
53972
54183
 
53973
- let hAtoms = {}, hAtomsTmp = {};
54184
+ let hAtoms = {};
53974
54185
  let bLastQuery = false;
53975
54186
 
53976
- let opts = {};
53977
-
53978
- opts['color'] = (structArray.length > 1) ? 'structure' : ((structArray[0].length > 5) ? 'confidence' : 'chain');
53979
-
53980
54187
  for(let i = 0, il = structArray.length; i < il; ++i) {
53981
54188
  if(i == structArray.length - 1) bLastQuery = true;
53982
54189
 
@@ -53991,24 +54198,30 @@ class ChainalignParser {
53991
54198
  targetOrQuery = 'query';
53992
54199
  bAppend = true;
53993
54200
  }
53994
-
54201
+
53995
54202
  //if(structArray[i].length > 4) {
53996
54203
  if(isNaN(structArray[i]) && structArray[i].length > 5) { // PDB ID plus postfix could be 5
53997
54204
  //let bNoDssp = true;
53998
54205
  let bNoDssp = false; // get secondary structure info
53999
- hAtomsTmp = await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
54206
+ await ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
54000
54207
  }
54001
54208
  else {
54002
54209
  let bNoSeqalign = true;
54003
54210
  let pdbid = structArray[i];
54004
- hAtomsTmp = await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
54211
+
54212
+ //hAtomsTmp contains all atoms
54213
+ await ic.mmdbParserCls.parseMmdbData(queryDataArray[i], targetOrQuery, undefined, undefined, bLastQuery, bNoSeqalign, pdbid);
54005
54214
  }
54006
54215
 
54007
- hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
54216
+ // hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
54008
54217
  }
54009
54218
 
54010
- // add color only for the newly loaded structures
54011
- ic.setColorCls.setColorByOptions(opts, hAtoms);
54219
+ let structArrayAll = Object.keys(ic.structures);
54220
+
54221
+ ic.opts['color'] = (structArrayAll.length > 1) ? 'structure' : ((structArrayAll[0].length > 5) ? 'confidence' : 'chain');
54222
+
54223
+ // add color for all structures
54224
+ ic.setColorCls.setColorByOptions(ic.opts, hAtoms);
54012
54225
 
54013
54226
  await ic.ParserUtilsCls.renderStructure();
54014
54227
 
@@ -54038,15 +54251,6 @@ class ChainalignParser {
54038
54251
  if(vastplusAtype == 2) me.cfg.aligntool = 'tmalign';
54039
54252
  await ic.vastplusCls.vastplusAlign(structArray, vastplusAtype);
54040
54253
  }
54041
-
54042
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
54043
-
54044
- // if(Object.keys(ic.structures).length == 1 && me.cfg.mmdbafid.length > 5) {
54045
- // ic.ParserUtilsCls.checkMemProtein(me.cfg.mmdbafid);
54046
- // }
54047
- // else {
54048
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
54049
- // }
54050
54254
  }
54051
54255
  }
54052
54256
 
@@ -55514,24 +55718,32 @@ class MmcifParser {
55514
55718
  if(data.emd !== undefined) ic.emd = data.emd;
55515
55719
  if(data.organism !== undefined) ic.organism = data.organism;
55516
55720
 
55517
- if(ic.emd !== undefined) {
55518
- $("#" + ic.pre + "mapWrapper1").hide();
55519
- $("#" + ic.pre + "mapWrapper2").hide();
55520
- $("#" + ic.pre + "mapWrapper3").hide();
55521
- }
55522
- else {
55523
- $("#" + ic.pre + "emmapWrapper1").hide();
55524
- $("#" + ic.pre + "emmapWrapper2").hide();
55525
- $("#" + ic.pre + "emmapWrapper3").hide();
55526
- }
55527
-
55528
55721
  await ic.opmParserCls.loadOpmData(data, mmcifid, undefined, 'mmcif');
55722
+
55723
+ ic.opmParserCls.modifyUIMapAssembly();
55529
55724
  }
55530
55725
  else {
55531
- //alert('invalid atoms data.');
55532
55726
  return false;
55533
55727
  }
55534
55728
  }
55729
+
55730
+ async loadMultipleMmcifData(data, mmcifid, bAppend) { let ic = this.icn3d; ic.icn3dui;
55731
+ let bText = true;
55732
+ ic.loadCIFCls.loadCIF(data, mmcifid, bText, bAppend);
55733
+
55734
+ if(Object.keys(ic.structures).length > 1) {
55735
+ ic.opts['color'] = 'structure';
55736
+ }
55737
+
55738
+ ic.opmParserCls.modifyUIMapAssembly();
55739
+
55740
+ ic.pdbParserCls.addSecondary(bAppend);
55741
+
55742
+ // ic.setStyleCls.setAtomStyleByOptions(ic.opts);
55743
+ // ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
55744
+
55745
+ // await ic.ParserUtilsCls.renderStructure();
55746
+ }
55535
55747
  }
55536
55748
 
55537
55749
  /**
@@ -56374,26 +56586,26 @@ class BcifParser {
56374
56586
  let molecueType;
56375
56587
  if(atom_hetatm == "ATOM") {
56376
56588
  if(resn.length == 3) {
56377
- molecueType = "p"; // protein
56589
+ molecueType = "protein"; //"p"; // protein
56378
56590
  }
56379
56591
  else {
56380
- molecueType = "n"; // nucleotide
56592
+ molecueType = "nucleotide"; //"n"; // nucleotide
56381
56593
  }
56382
56594
  }
56383
56595
  else {
56384
56596
  if(resn == "WAT" || resn == "HOH") {
56385
- molecueType = "s"; // solvent
56597
+ molecueType = "solvent"; //"s"; // solvent
56386
56598
  chain = 'Misc';
56387
56599
  }
56388
56600
  else {
56389
- molecueType = "l"; // ligands or ions
56601
+ molecueType = "ligand"; //"l"; // ligands or ions
56390
56602
  chain = resn;
56391
56603
  }
56392
56604
  }
56393
56605
 
56394
56606
  // C-alpha only for large structure
56395
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
56396
- || (molecueType == "n" && !(name == "P")) ) ) continue;
56607
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
56608
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
56397
56609
  // skip alternative atoms
56398
56610
  if(alt == "B") continue;
56399
56611
 
@@ -56416,7 +56628,7 @@ class BcifParser {
56416
56628
  // }
56417
56629
  }
56418
56630
 
56419
- if(molecueType == 's' || molecueType == "l") {
56631
+ if(molecueType == 'solvent' || molecueType == "ligand") {
56420
56632
  let seq = {};
56421
56633
  if(!ligSeqHash.hasOwnProperty(chain)) {
56422
56634
  ligSeqHash[chain] = [];
@@ -56554,26 +56766,26 @@ class BcifParser {
56554
56766
  let molecueType;
56555
56767
  if(atom_hetatm == "ATOM") {
56556
56768
  if(resn.length == 3) {
56557
- molecueType = "p"; // protein
56769
+ molecueType = "protein"; // protein
56558
56770
  }
56559
56771
  else {
56560
- molecueType = "n"; // nucleotide
56772
+ molecueType = "nucleotide"; // nucleotide
56561
56773
  }
56562
56774
  }
56563
56775
  else {
56564
56776
  if(resn == "WAT" || resn == "HOH") {
56565
- molecueType = "s"; // solvent
56777
+ molecueType = "solvent"; // solvent
56566
56778
  chain = 'Misc';
56567
56779
  }
56568
56780
  else {
56569
- molecueType = "l"; // ligands or ions
56781
+ molecueType = "ligand"; // ligands or ions
56570
56782
  chain = resn;
56571
56783
  }
56572
56784
  }
56573
56785
 
56574
56786
  // C-alpha only for large structure
56575
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
56576
- || (molecueType == "n" && !(name == "P")) ) ) continue;
56787
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
56788
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
56577
56789
  // skip alternative atoms
56578
56790
  if(alt == "B") continue;
56579
56791
 
@@ -57123,6 +57335,43 @@ class OpmParser {
57123
57335
  }
57124
57336
  }
57125
57337
 
57338
+ modifyUIMapAssembly() { let ic = this.icn3d, me = ic.icn3dui;
57339
+ if(!me.bNode) {
57340
+ if(ic.emd !== undefined) {
57341
+ $("#" + ic.pre + "mapWrapper1").hide();
57342
+ $("#" + ic.pre + "mapWrapper2").hide();
57343
+ $("#" + ic.pre + "mapWrapper3").hide();
57344
+ }
57345
+ else {
57346
+ $("#" + ic.pre + "emmapWrapper1").hide();
57347
+ $("#" + ic.pre + "emmapWrapper2").hide();
57348
+ $("#" + ic.pre + "emmapWrapper3").hide();
57349
+ }
57350
+
57351
+ if(Object.keys(ic.structures).length == 1) {
57352
+ $("#" + ic.pre + "alternateWrapper").hide();
57353
+ }
57354
+ /*
57355
+ // load assembly info
57356
+ if(type === 'mmcif') {
57357
+ let assembly =(data.assembly !== undefined) ? data.assembly : [];
57358
+ for(let i = 0, il = assembly.length; i < il; ++i) {
57359
+ if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
57360
+
57361
+ for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
57362
+ ic.biomtMatrices[i].elements[j] = assembly[i][j];
57363
+ }
57364
+ }
57365
+ }
57366
+ */
57367
+ if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
57368
+ $("#" + ic.pre + "assemblyWrapper").show();
57369
+
57370
+ ic.asuCnt = ic.biomtMatrices.length;
57371
+ }
57372
+ }
57373
+ }
57374
+
57126
57375
  async parseAtomData(data, pdbid, bFull, type, pdbid2, bText) { let ic = this.icn3d, me = ic.icn3dui;
57127
57376
  /*
57128
57377
  if(type === 'mmtf') {
@@ -57139,38 +57388,7 @@ class OpmParser {
57139
57388
  ic.loadCIFCls.loadCIF(data, pdbid, bText);
57140
57389
  // }
57141
57390
 
57142
- if(ic.emd !== undefined) {
57143
- $("#" + ic.pre + "mapWrapper1").hide();
57144
- $("#" + ic.pre + "mapWrapper2").hide();
57145
- $("#" + ic.pre + "mapWrapper3").hide();
57146
- }
57147
- else {
57148
- $("#" + ic.pre + "emmapWrapper1").hide();
57149
- $("#" + ic.pre + "emmapWrapper2").hide();
57150
- $("#" + ic.pre + "emmapWrapper3").hide();
57151
- }
57152
-
57153
- if(Object.keys(ic.structures).length == 1) {
57154
- $("#" + ic.pre + "alternateWrapper").hide();
57155
- }
57156
- /*
57157
- // load assembly info
57158
- if(type === 'mmcif') {
57159
- let assembly =(data.assembly !== undefined) ? data.assembly : [];
57160
- for(let i = 0, il = assembly.length; i < il; ++i) {
57161
- if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
57162
-
57163
- for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
57164
- ic.biomtMatrices[i].elements[j] = assembly[i][j];
57165
- }
57166
- }
57167
- }
57168
- */
57169
- if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
57170
- $("#" + ic.pre + "assemblyWrapper").show();
57171
-
57172
- ic.asuCnt = ic.biomtMatrices.length;
57173
- }
57391
+ this.modifyUIMapAssembly();
57174
57392
 
57175
57393
  ic.setStyleCls.setAtomStyleByOptions(ic.opts);
57176
57394
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
@@ -57364,6 +57582,12 @@ class PdbParser {
57364
57582
  }
57365
57583
  }
57366
57584
 
57585
+ await this.addSecondary(bAppend, bNoDssp);
57586
+
57587
+ return hAtoms;
57588
+ }
57589
+
57590
+ async addSecondary(bAppend, bNoDssp) { let ic = this.icn3d, me = ic.icn3dui;
57367
57591
  // calculate secondary structures if not available
57368
57592
  // DSSP only works for structures with all atoms. The Calpha only structures didn't work
57369
57593
  //if(!ic.bSecondaryStructure && !bCalphaOnly) {
@@ -57387,8 +57611,6 @@ class PdbParser {
57387
57611
 
57388
57612
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
57389
57613
  }
57390
-
57391
- return hAtoms;
57392
57614
  }
57393
57615
 
57394
57616
  async applyCommandDssp(bAppend) { let ic = this.icn3d, me = ic.icn3dui;
@@ -58226,23 +58448,27 @@ class RealignParser {
58226
58448
 
58227
58449
  for(let s = 0, sl = structArray.length; s < sl; ++s) {
58228
58450
  let struct1 = structArray[s];
58451
+
58229
58452
  let chainidArray1 = Object.keys(struct2domain[struct1]);
58230
58453
  if(chainidArray1.length == 0) continue;
58231
- for(let t = s+1, tl = structArray.length; t < tl; ++t) {
58232
- let struct2 = structArray[t];
58233
- let chainidArray2 = Object.keys(struct2domain[struct2]);
58234
- if(chainidArray2.length == 0) continue;
58235
-
58236
- for(let i = 0, il = chainidArray1.length; i < il; ++i) {
58237
- let chainid1 = chainidArray1[i];
58238
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
58454
+
58455
+ for(let i = 0, il = chainidArray1.length; i < il; ++i) {
58456
+ let chainid1 = chainidArray1[i];
58457
+ let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
58458
+
58459
+ for(let t = s+1, tl = structArray.length; t < tl; ++t) {
58460
+ let struct2 = structArray[t];
58461
+
58462
+ let chainidArray2 = Object.keys(struct2domain[struct2]);
58463
+ if(chainidArray2.length == 0) continue;
58464
+
58239
58465
  for(let j = 0, jl = chainidArray2.length; j < jl; ++j) {
58240
58466
  let chainid2 = chainidArray2[j];
58241
58467
 
58242
58468
  let alignAjax;
58243
58469
  if(me.cfg.aligntool != 'tmalign') {
58244
58470
  let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct2][chainid2]);
58245
-
58471
+
58246
58472
  let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
58247
58473
  alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
58248
58474
  }
@@ -58267,7 +58493,14 @@ class RealignParser {
58267
58493
 
58268
58494
  let allPromise = Promise.allSettled(ajaxArray);
58269
58495
  // try {
58496
+ // let dataArray = await allPromise;
58497
+
58498
+ let startDate = new Date();
58270
58499
  let dataArray = await allPromise;
58500
+ let endDate = new Date();
58501
+ let miliseconds = (endDate.getTime() - startDate.getTime());
58502
+ console.log("vastdyn time: " + miliseconds + " miliseconds");
58503
+
58271
58504
  ic.qt_start_end = []; // reset the alignment
58272
58505
  await ic.chainalignParserCls.downloadChainalignmentPart2bRealign(dataArray, chainidPairArray, bReverse);
58273
58506
  // }
@@ -60491,6 +60724,7 @@ class LoadAtomData {
60491
60724
 
60492
60725
  //This function was used to parse atom "data" to set up parameters for the 3D viewer. "type" is mmcifid or mmdbid.
60493
60726
  //"id" is the MMDB ID or mmCIF ID.
60727
+ // thi sfunction is NOT used for mmCIF loading any more
60494
60728
  loadAtomDataIn(data, id, type, seqalign, alignType, chainidInput, chainIndex, bLastQuery, bNoSeqalign) { let ic = this.icn3d, me = ic.icn3dui;
60495
60729
  //ic.init();
60496
60730
  ic.pmin = new THREE.Vector3( 9999, 9999, 9999);
@@ -60634,13 +60868,6 @@ class LoadAtomData {
60634
60868
  if(ic.pdbid_chain2title === undefined) ic.pdbid_chain2title = {};
60635
60869
  ic.pdbid_chain2title[chainid] = data.moleculeInfor[molid].name;
60636
60870
 
60637
- //if(alignType == 'query' && chain == ic.chain_q) {
60638
- // ic.alignmolid2color[0][molid] = molidCnt.toString();
60639
- //}
60640
- //else if(alignType == 'target' && chain == ic.chain_t) {
60641
- // ic.alignmolid2color[1][molid] = molidCnt.toString();
60642
- //}
60643
-
60644
60871
  if(chain == chainid.substr(chainid.lastIndexOf('_')) ) {
60645
60872
  let tmpHash = {};
60646
60873
  tmpHash[molid] = molidCnt.toString();
@@ -60832,17 +61059,15 @@ class LoadAtomData {
60832
61059
  ic.pmin.min(atm.coord);
60833
61060
  ic.pmax.max(atm.coord);
60834
61061
  ic.psum.add(atm.coord);
60835
-
60836
- let bNonMmcif = (me.cfg.mmcifid === undefined && me.cfg.mmtfid === undefined && me.cfg.bcifid === undefined && ic.InputfileType != 'mmcif');
60837
- let bProtein = (bNonMmcif) ? chainid2kind[chainNum] === 'protein' : atm.mt === 'p';
60838
- let bNucleotide = (bNonMmcif) ? chainid2kind[chainNum] === 'nucleotide' : atm.mt === 'n';
60839
- let bSolvent = (bNonMmcif) ? chainid2kind[chainNum] === 'solvent' : atm.mt === 's';
61062
+ let bProtein = chainid2kind[chainNum] === 'protein' ;
61063
+ let bNucleotide = chainid2kind[chainNum] === 'nucleotide' ;
61064
+ let bSolvent = chainid2kind[chainNum] === 'solvent' ;
60840
61065
  // in vastplus.cgi, ions arenotlisted in alignedStructures...molecules, thus chainid2kind[chainNum] === undefined is used.
60841
61066
  // ions will be separated from chemicals later.
60842
61067
  // here "ligand" is used in the cgi output
60843
61068
  //var bChemicalIons =(me.cfg.mmcifid === undefined) ?(chainid2kind[chainNum] === 'ligand' || chainid2kind[chainNum] === 'otherPolymer' || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
60844
61069
  // kind: other, otherPolymer, etc
60845
- let bChemicalIons = (bNonMmcif) ? (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
61070
+ let bChemicalIons = (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) ;
60846
61071
 
60847
61072
  if((atm.chain === 'Misc' || chainid2kind[chainNum] === 'other') && biopolymerChainsHash[chainNum] !== 'protein' && biopolymerChainsHash[chainNum] !== 'nucleotide') { // biopolymer, could be protein or nucleotide
60848
61073
  if(atm.name === 'CA' && atm.elem === 'C') {
@@ -61106,18 +61331,17 @@ class LoadAtomData {
61106
61331
 
61107
61332
  // update bonds info
61108
61333
  if(type !== 'mmcifid') {
61109
- //for(let i in ic.atoms) {
61110
- for(let i in atoms) {
61111
- let currSerial = atomid2serial[i];
61334
+ //for(let i in ic.atoms) {
61335
+ for(let i in atoms) {
61336
+ let currSerial = atomid2serial[i];
61112
61337
 
61113
- let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
61338
+ let bondLength =(ic.atoms[currSerial].bonds === undefined) ? 0 : ic.atoms[currSerial].bonds.length;
61114
61339
 
61115
- for(let j = 0; j < bondLength; ++j) {
61116
- ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
61340
+ for(let j = 0; j < bondLength; ++j) {
61341
+ ic.atoms[currSerial].bonds[j] = atomid2serial[ic.atoms[currSerial].bonds[j]];
61342
+ }
61117
61343
  }
61118
61344
  }
61119
- }
61120
-
61121
61345
  // remove the reference
61122
61346
  data.atoms = {};
61123
61347
 
@@ -61213,7 +61437,7 @@ class LoadAtomData {
61213
61437
  // display the structure right away. load the mns and sequences later
61214
61438
  // setTimeout(function(){
61215
61439
  let hAtoms = {};
61216
-
61440
+
61217
61441
  if(type === 'align' && seqalign !== undefined && ic.bFullUi) {
61218
61442
  ic.setSeqAlignCls.setSeqAlign(seqalign, data.alignedStructures);
61219
61443
  } // if(align
@@ -61236,7 +61460,7 @@ class LoadAtomData {
61236
61460
  hAtoms = ic.hAtoms;
61237
61461
  }
61238
61462
  }
61239
- else if(type === 'mmdbid' && alignType === 'target') {
61463
+ else { //if(type === 'mmdbid' && alignType === 'target') {
61240
61464
  hAtoms = ic.hAtoms;
61241
61465
  }
61242
61466
 
@@ -61570,13 +61794,19 @@ class SetSeqAlign {
61570
61794
  resi = pos;
61571
61795
  }
61572
61796
  else {
61573
- if(ic.posid2resid) {
61574
- let resid = ic.posid2resid[chainid + '_' + pos];
61575
- resi = resid.substr(resid.lastIndexOf('_') + 1);
61576
- }
61577
- else {
61797
+ // if(ic.posid2resid) {
61798
+ // let resid = ic.posid2resid[chainid + '_' + pos];
61799
+ // resi = resid.substr(resid.lastIndexOf('_') + 1);
61800
+ // }
61801
+ // else {
61802
+ // resi = (ic.chainsSeq[chainid][pos].resi) ? ic.chainsSeq[chainid][pos].resi : pos;
61803
+ if(pos > ic.chainsSeq[chainid].length - 1) {
61804
+ console.log("Error: the position " + pos + " exceeds the max index " + (ic.chainsSeq[chainid].length - 1));
61805
+ pos = ic.chainsSeq[chainid].length - 1;
61806
+ }
61807
+
61578
61808
  resi = ic.chainsSeq[chainid][pos].resi;
61579
- }
61809
+ // }
61580
61810
  }
61581
61811
 
61582
61812
  return resi;
@@ -63661,17 +63891,6 @@ class LoadCIF {
63661
63891
  loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
63662
63892
  let hAtoms = {};
63663
63893
 
63664
- // bcifData could be binary or text
63665
- let parsed = (bText) ? CIFTools.Text.parse(bcifData) : CIFTools.Binary.parse(bcifData);
63666
-
63667
- if (parsed.isError) {
63668
- // report error:
63669
- alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
63670
- return;
63671
- }
63672
-
63673
- let block = parsed.result.dataBlocks[0];
63674
-
63675
63894
  let bNMR = false;
63676
63895
  // let lines = src.split('\n');
63677
63896
 
@@ -63707,92 +63926,152 @@ class LoadCIF {
63707
63926
 
63708
63927
  let bFirstAtom = true;
63709
63928
 
63710
- if(block.getCategory("_entry")) {
63711
- id = block.getCategory("_entry").getColumn("id").getString(0);
63929
+ let cifArray = bcifData.split('ENDMDL\n');
63712
63930
 
63713
- if(id == '') {
63714
- if(bAppend) {
63715
- id = ic.defaultPdbId;
63716
- }
63717
- else {
63718
- //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
63719
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
63720
- }
63721
- }
63931
+ for(let index = 0, indexl = cifArray.length; index < indexl; ++index) {
63932
+ ++moleculeNum;
63933
+ id = ic.defaultPdbId;
63722
63934
 
63723
63935
  structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63724
63936
 
63725
- ic.molTitle = '';
63726
- ic.molTitleHash = {};
63727
- }
63728
-
63729
- if(block.getCategory("_struct")) {
63730
- let title = block.getCategory("_struct").getColumn("title").getString(0);
63731
- title = title.replace(/"/, "'");
63732
- let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
63733
- ic.molTitle += name.trim() + " ";
63734
- // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63937
+ // if(!bNMR) {
63938
+ sheetArray = [];
63939
+ sheetStart = [];
63940
+ sheetEnd = [];
63941
+ helixArray = [];
63942
+ helixStart = [];
63943
+ helixEnd = [];
63735
63944
 
63736
- if(!ic.molTitleHash) ic.molTitleHash = {};
63737
- ic.molTitleHash[structure] = ic.molTitle;
63738
63945
 
63739
- }
63946
+ // bcifData could be binary or text
63947
+ let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
63740
63948
 
63741
- if(block.getCategory("_entity_src_gen")) {
63742
- ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
63743
- }
63744
-
63745
- if(block.getCategory("_database_2")) {
63746
- let database_2 = block.getCategory("_database_2");
63747
-
63748
- // Iterate through every row in the table
63749
- let db2Size = database_2.rowCount ;
63750
- for (let i = 0; i < db2Size; ++i) {
63751
- let db_id = database_2.getColumn("database_id").getString(0);
63752
- let db_code = database_2.getColumn("database_code").getString(0);
63949
+ if (parsed.isError) {
63950
+ // report error:
63951
+ alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
63952
+ return;
63953
+ }
63954
+
63955
+ let block = parsed.result.dataBlocks[0];
63753
63956
 
63754
- if(db_id == "EMDB") {
63755
- ic.emd = db_code;
63756
- break;
63957
+ if(block.getCategory("_entry")) {
63958
+ id = block.getCategory("_entry").getColumn("id").getString(0);
63959
+
63960
+ if(id == '') {
63961
+ if(bAppend) {
63962
+ id = ic.defaultPdbId;
63963
+ }
63964
+ else {
63965
+ //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
63966
+ id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
63967
+ }
63757
63968
  }
63969
+
63970
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63971
+
63972
+ ic.molTitle = '';
63973
+ ic.molTitleHash = {};
63758
63974
  }
63759
- }
63975
+
63976
+ if(block.getCategory("_struct")) {
63977
+ let title = block.getCategory("_struct").getColumn("title").getString(0);
63978
+ title = title.replace(/"/, "'");
63979
+ let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
63980
+ ic.molTitle += name.trim() + " ";
63981
+ // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63760
63982
 
63761
- if(block.getCategory("_struct_conf")) {
63762
- ic.bSecondaryStructure = true;
63983
+ if(!ic.molTitleHash) ic.molTitleHash = {};
63984
+ ic.molTitleHash[structure] = ic.molTitle;
63763
63985
 
63764
- // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
63765
- let struct_conf = block.getCategory("_struct_conf");
63766
-
63767
- let conf_type_idArray = struct_conf.getColumn("conf_type_id");
63768
-
63769
- let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
63770
- // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
63771
- let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
63772
-
63773
- struct_conf.getColumn("end_auth_asym_id");
63774
- // let resi2Array = struct_conf.getColumn("end_label_seq_id");
63775
- let resi2Array = struct_conf.getColumn("end_auth_seq_id");
63776
-
63777
- // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
63778
- let confSize = struct_conf.rowCount;
63779
- for (let i = 0; i < confSize; ++i) {
63780
- let conf_type_id = conf_type_idArray.getString(i);
63986
+ }
63987
+
63988
+ if(block.getCategory("_entity_src_gen")) {
63989
+ ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
63990
+ }
63781
63991
 
63782
- let startChain = chain1Array.getString(i);
63783
- let startResi = parseInt(resi1Array.getString(i));
63784
- let endResi = parseInt(resi2Array.getString(i));
63992
+ if(block.getCategory("_database_2")) {
63993
+ let database_2 = block.getCategory("_database_2");
63785
63994
 
63786
- if(conf_type_id.substr(0, 4) == "HELX") {
63787
- for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
63788
- let resid = structure + "_" + startChain + "_" + j;
63789
- helixArray.push(resid);
63790
-
63791
- if(j == startResi) helixStart.push(resid);
63792
- if(j == endResi) helixEnd.push(resid);
63793
- }
63995
+ // Iterate through every row in the table
63996
+ let db2Size = database_2.rowCount ;
63997
+ for (let i = 0; i < db2Size; ++i) {
63998
+ let db_id = database_2.getColumn("database_id").getString(0);
63999
+ let db_code = database_2.getColumn("database_code").getString(0);
64000
+
64001
+ if(db_id == "EMDB") {
64002
+ ic.emd = db_code;
64003
+ break;
64004
+ }
63794
64005
  }
63795
- else if(conf_type_id.substr(0, 4) == "STRN") {
64006
+ }
64007
+
64008
+ if(block.getCategory("_struct_conf")) {
64009
+ ic.bSecondaryStructure = true;
64010
+
64011
+ // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
64012
+ let struct_conf = block.getCategory("_struct_conf");
64013
+
64014
+ let conf_type_idArray = struct_conf.getColumn("conf_type_id");
64015
+
64016
+ let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
64017
+ // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
64018
+ let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
64019
+
64020
+ struct_conf.getColumn("end_auth_asym_id");
64021
+ // let resi2Array = struct_conf.getColumn("end_label_seq_id");
64022
+ let resi2Array = struct_conf.getColumn("end_auth_seq_id");
64023
+
64024
+ // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
64025
+ let confSize = struct_conf.rowCount;
64026
+ for (let i = 0; i < confSize; ++i) {
64027
+ let conf_type_id = conf_type_idArray.getString(i);
64028
+
64029
+ let startChain = chain1Array.getString(i);
64030
+ let startResi = parseInt(resi1Array.getString(i));
64031
+ let endResi = parseInt(resi2Array.getString(i));
64032
+
64033
+ if(conf_type_id.substr(0, 4) == "HELX") {
64034
+ for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
64035
+ let resid = structure + "_" + startChain + "_" + j;
64036
+ helixArray.push(resid);
64037
+
64038
+ if(j == startResi) helixStart.push(resid);
64039
+ if(j == endResi) helixEnd.push(resid);
64040
+ }
64041
+ }
64042
+ else if(conf_type_id.substr(0, 4) == "STRN") {
64043
+ for(let j = startResi; j <= endResi; ++j) {
64044
+ let resid = structure + "_" + startChain + "_" + j;
64045
+ sheetArray.push(resid);
64046
+
64047
+ if(j == startResi) sheetStart.push(resid);
64048
+ if(j == endResi) sheetEnd.push(resid);
64049
+ }
64050
+ }
64051
+ }
64052
+
64053
+ conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
64054
+ }
64055
+
64056
+ if(block.getCategory("_struct_sheet_range")) {
64057
+ // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
64058
+ let struct_sheet_range = block.getCategory("_struct_sheet_range");
64059
+
64060
+ let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
64061
+ // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
64062
+ let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
64063
+
64064
+ struct_sheet_range.getColumn("end_auth_asym_id");
64065
+ // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
64066
+ let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
64067
+
64068
+ // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
64069
+ let sheetSize = struct_sheet_range.rowCount;
64070
+ for (let i = 0; i < sheetSize; ++i) {
64071
+ let startChain = chain1Array.getString(i);
64072
+ let startResi = parseInt(resi1Array.getString(i));
64073
+ let endResi = parseInt(resi2Array.getString(i));
64074
+
63796
64075
  for(let j = startResi; j <= endResi; ++j) {
63797
64076
  let resid = structure + "_" + startChain + "_" + j;
63798
64077
  sheetArray.push(resid);
@@ -63801,500 +64080,469 @@ class LoadCIF {
63801
64080
  if(j == endResi) sheetEnd.push(resid);
63802
64081
  }
63803
64082
  }
64083
+
64084
+ chain1Array = resi1Array = resi2Array = [];
63804
64085
  }
63805
-
63806
- conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
63807
- }
63808
-
63809
- if(block.getCategory("_struct_sheet_range")) {
63810
- // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
63811
- let struct_sheet_range = block.getCategory("_struct_sheet_range");
63812
-
63813
- let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
63814
- // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
63815
- let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
63816
-
63817
- struct_sheet_range.getColumn("end_auth_asym_id");
63818
- // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
63819
- let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
63820
-
63821
- // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
63822
- let sheetSize = struct_sheet_range.rowCount;
63823
- for (let i = 0; i < sheetSize; ++i) {
63824
- let startChain = chain1Array.getString(i);
63825
- let startResi = parseInt(resi1Array.getString(i));
63826
- let endResi = parseInt(resi2Array.getString(i));
63827
-
63828
- for(let j = startResi; j <= endResi; ++j) {
63829
- let resid = structure + "_" + startChain + "_" + j;
63830
- sheetArray.push(resid);
63831
-
63832
- if(j == startResi) sheetStart.push(resid);
63833
- if(j == endResi) sheetEnd.push(resid);
63834
- }
63835
- }
63836
-
63837
- chain1Array = resi1Array = resi2Array = [];
63838
- }
63839
64086
 
63840
- if(block.getCategory("_struct_conn")) {
63841
- ic.bSsbondProvided = true;
64087
+ if(block.getCategory("_struct_conn")) {
64088
+ ic.bSsbondProvided = true;
63842
64089
 
63843
- // Retrieve the table corresponding to the struct_conn category, which delineates connections1
63844
- let struct_conn = block.getCategory("_struct_conn");
63845
-
63846
- let conn_type_idArray = struct_conn.getColumn("conn_type_id");
63847
-
63848
- let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
63849
- let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
63850
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
63851
-
63852
- let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
63853
- let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
63854
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
63855
-
63856
- let connSize = struct_conn.rowCount;
63857
- for (let i = 0; i < connSize; ++i) {
63858
- let conn_type_id = conn_type_idArray.getString(i);
64090
+ // Retrieve the table corresponding to the struct_conn category, which delineates connections1
64091
+ let struct_conn = block.getCategory("_struct_conn");
63859
64092
 
63860
- let chain1 = chain1Array.getString(i);
63861
- name1Array.getString(i);
63862
- let resi1 = resi1Array.getString(i);
63863
- let id1 = structure + '_' + chain1 + "_" + resi1;
64093
+ let conn_type_idArray = struct_conn.getColumn("conn_type_id");
63864
64094
 
63865
- let chain2 = chain2Array.getString(i);
63866
- name2Array.getString(i);
63867
- let resi2 = resi2Array.getString(i);
63868
- let id2 = structure + '_' + chain2 + "_" + resi2;
64095
+ let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
64096
+ let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
64097
+ let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
63869
64098
 
63870
- // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
64099
+ let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
64100
+ let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
64101
+ let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
63871
64102
 
63872
- // if (conn_type_id == "covale") {
63873
- // vBonds.push(id1);
63874
- // vBonds.push(id2);
63875
- // }
64103
+ let connSize = struct_conn.rowCount;
64104
+ for (let i = 0; i < connSize; ++i) {
64105
+ let conn_type_id = conn_type_idArray.getString(i);
63876
64106
 
63877
- if(conn_type_id == "disulf") {
63878
- if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
64107
+ let chain1 = chain1Array.getString(i);
64108
+ name1Array.getString(i);
64109
+ let resi1 = resi1Array.getString(i);
64110
+ let id1 = structure + '_' + chain1 + "_" + resi1;
64111
+
64112
+ let chain2 = chain2Array.getString(i);
64113
+ name2Array.getString(i);
64114
+ let resi2 = resi2Array.getString(i);
64115
+ let id2 = structure + '_' + chain2 + "_" + resi2;
64116
+
64117
+ // Verify that the linkage is covalent, as indicated by the conn_type_id attribute2
64118
+
64119
+ // if (conn_type_id == "covale") {
64120
+ // vBonds.push(id1);
64121
+ // vBonds.push(id2);
64122
+ // }
64123
+
64124
+ if(conn_type_id == "disulf") {
64125
+ if(ic.ssbondpnts[structure] === undefined) ic.ssbondpnts[structure] = [];
63879
64126
 
63880
- ic.ssbondpnts[structure].push(id1);
63881
- ic.ssbondpnts[structure].push(id2);
64127
+ ic.ssbondpnts[structure].push(id1);
64128
+ ic.ssbondpnts[structure].push(id2);
64129
+ }
63882
64130
  }
64131
+
64132
+ conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63883
64133
  }
63884
-
63885
- conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63886
- }
63887
64134
 
63888
- if(block.getCategory("_exptl")) {
63889
- let method = block.getCategory("_exptl").getColumn("method").getString(0);
63890
- if(method.indexOf('NMR') != -1) {
63891
- bNMR = true;
64135
+ if(block.getCategory("_exptl")) {
64136
+ let method = block.getCategory("_exptl").getColumn("method").getString(0);
64137
+ if(method.indexOf('NMR') != -1) {
64138
+ bNMR = true;
64139
+ }
63892
64140
  }
63893
- }
63894
64141
 
63895
- if(block.getCategory("_pdbx_struct_oper_list")) {
63896
- // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
63897
- let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
63898
-
63899
- let struct_oper_idArray = struct_oper_list.getColumn("id");
63900
- let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63901
- let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63902
- let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63903
- let m14Array = struct_oper_list.getColumn("vector[1]");
63904
-
63905
- let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63906
- let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63907
- let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63908
- let m24Array = struct_oper_list.getColumn("vector[2]");
63909
-
63910
- let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63911
- let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63912
- let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63913
- let m34Array = struct_oper_list.getColumn("vector[3]");
63914
-
63915
- let assemblySize = struct_oper_list.rowCount;
63916
- for (let i = 0; i < assemblySize; ++i) {
63917
- let struct_oper_id = struct_oper_idArray.getString(i);
63918
- if(struct_oper_id == "X0") continue;
64142
+ if(block.getCategory("_pdbx_struct_oper_list")) {
64143
+ // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
64144
+ let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
64145
+
64146
+ let struct_oper_idArray = struct_oper_list.getColumn("id");
64147
+ let m11Array = struct_oper_list.getColumn("matrix[1][1]");
64148
+ let m12Array = struct_oper_list.getColumn("matrix[1][2]");
64149
+ let m13Array = struct_oper_list.getColumn("matrix[1][3]");
64150
+ let m14Array = struct_oper_list.getColumn("vector[1]");
64151
+
64152
+ let m21Array = struct_oper_list.getColumn("matrix[2][1]");
64153
+ let m22Array = struct_oper_list.getColumn("matrix[2][2]");
64154
+ let m23Array = struct_oper_list.getColumn("matrix[2][3]");
64155
+ let m24Array = struct_oper_list.getColumn("vector[2]");
64156
+
64157
+ let m31Array = struct_oper_list.getColumn("matrix[3][1]");
64158
+ let m32Array = struct_oper_list.getColumn("matrix[3][2]");
64159
+ let m33Array = struct_oper_list.getColumn("matrix[3][3]");
64160
+ let m34Array = struct_oper_list.getColumn("vector[3]");
64161
+
64162
+ let assemblySize = struct_oper_list.rowCount;
64163
+ for (let i = 0; i < assemblySize; ++i) {
64164
+ let struct_oper_id = struct_oper_idArray.getString(i);
64165
+ if(struct_oper_id == "X0") continue;
63919
64166
 
63920
- if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63921
- ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63922
- m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63923
- m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63924
- 0, 0, 0, 1);
64167
+ if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
64168
+ ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
64169
+ m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
64170
+ m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
64171
+ 0, 0, 0, 1);
64172
+ }
64173
+
64174
+ struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
64175
+ = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63925
64176
  }
63926
-
63927
- struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63928
- = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63929
- }
63930
64177
 
63931
- // if (record === 'ENDMDL') {
63932
- // ++moleculeNum;
63933
- // id = ic.defaultPdbId;
64178
+ // if (record === 'ENDMDL') {
64179
+ // ++moleculeNum;
64180
+ // id = ic.defaultPdbId;
63934
64181
 
63935
- // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64182
+ // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63936
64183
 
63937
- // //helices = [];
63938
- // //sheets = [];
63939
- // if(!bNMR) {
63940
- // sheetArray = [];
63941
- // sheetStart = [];
63942
- // sheetEnd = [];
63943
- // helixArray = [];
63944
- // helixStart = [];
63945
- // helixEnd = [];
63946
- // }
64184
+ // //helices = [];
64185
+ // //sheets = [];
64186
+ // if(!bNMR) {
64187
+ // sheetArray = [];
64188
+ // sheetStart = [];
64189
+ // sheetEnd = [];
64190
+ // helixArray = [];
64191
+ // helixStart = [];
64192
+ // helixEnd = [];
64193
+ // }
63947
64194
 
63948
- // bHeader = false; // reinitialize to read structure name from the header
63949
- // }
64195
+ // bHeader = false; // reinitialize to read structure name from the header
64196
+ // }
63950
64197
 
63951
- if(block.getCategory("_citation")) {
63952
- ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63953
- }
64198
+ if(block.getCategory("_citation")) {
64199
+ ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
64200
+ }
63954
64201
 
63955
- // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63956
- let atom_site = block.getCategory("_atom_site");
63957
- let atomSize = atom_site.rowCount;
63958
- // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63959
- let bFull = (atomSize > ic.maxatomcnt) ? false : true;
64202
+ // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
64203
+ let atom_site = block.getCategory("_atom_site");
64204
+ let atomSize = atom_site.rowCount;
64205
+ // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
64206
+ let bFull = (atomSize > ic.maxatomcnt) ? false : true;
63960
64207
 
63961
- if(!bFull) {
63962
- 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
63963
- ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63964
- }
64208
+ if(!bFull) {
64209
+ 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
64210
+ ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
64211
+ }
63965
64212
 
63966
- let atom_hetatmArray = atom_site.getColumn("group_PDB");
63967
- let resnArray = atom_site.getColumn("label_comp_id");
63968
- let elemArray = atom_site.getColumn("type_symbol");
63969
- let nameArray = atom_site.getColumn("label_atom_id");
64213
+ let atom_hetatmArray = atom_site.getColumn("group_PDB");
64214
+ let resnArray = atom_site.getColumn("label_comp_id");
64215
+ let elemArray = atom_site.getColumn("type_symbol");
64216
+ let nameArray = atom_site.getColumn("label_atom_id");
63970
64217
 
63971
- let chainArray = atom_site.getColumn("auth_asym_id");
64218
+ let chainArray = atom_site.getColumn("auth_asym_id");
63972
64219
 
63973
- let resiArray = atom_site.getColumn("label_seq_id");
63974
- let resiOriArray = atom_site.getColumn("auth_seq_id");
63975
- let altArray = atom_site.getColumn("label_alt_id");
64220
+ let resiArray = atom_site.getColumn("label_seq_id");
64221
+ let resiOriArray = atom_site.getColumn("auth_seq_id");
64222
+ let altArray = atom_site.getColumn("label_alt_id");
63976
64223
 
63977
- let bArray = atom_site.getColumn("B_iso_or_equiv");
64224
+ let bArray = atom_site.getColumn("B_iso_or_equiv");
63978
64225
 
63979
- let xArray = atom_site.getColumn("Cartn_x");
63980
- let yArray = atom_site.getColumn("Cartn_y");
63981
- let zArray = atom_site.getColumn("Cartn_z");
64226
+ let xArray = atom_site.getColumn("Cartn_x");
64227
+ let yArray = atom_site.getColumn("Cartn_y");
64228
+ let zArray = atom_site.getColumn("Cartn_z");
63982
64229
 
63983
- let autochainArray = atom_site.getColumn("label_asym_id");
64230
+ let autochainArray = atom_site.getColumn("label_asym_id");
63984
64231
 
63985
- // get the bond info
63986
- let ligSeqHash = {}, prevAutochain = '';
63987
- let prevResn;
63988
- let sChain = {};
63989
- for (let i = 0; i < atomSize; ++i) {
63990
- let atom_hetatm = atom_hetatmArray.getString(i);
63991
- let resn = resnArray.getString(i);
63992
- let elem = elemArray.getString(i);
63993
- let atom = nameArray.getString(i);
63994
- let chain = chainArray.getString(i);
63995
- let resi = resiArray.getString(i);
63996
- let oriResi = resiOriArray.getString(i);
63997
- let alt = altArray.getString(i);
63998
- let bFactor = bArray.getString(i);
64232
+ // get the bond info
64233
+ let ligSeqHash = {}, prevAutochain = '';
64234
+ let prevResn;
64235
+ let sChain = {};
64236
+ for (let i = 0; i < atomSize; ++i) {
64237
+ let atom_hetatm = atom_hetatmArray.getString(i);
64238
+ let resn = resnArray.getString(i);
64239
+ let elem = elemArray.getString(i);
64240
+ let atom = nameArray.getString(i);
64241
+ let chain = chainArray.getString(i);
64242
+ let resi = resiArray.getString(i);
64243
+ let oriResi = resiOriArray.getString(i);
64244
+ let alt = altArray.getString(i);
64245
+ let bFactor = bArray.getString(i);
63999
64246
 
64000
- let autochain = autochainArray.getString(i);
64247
+ let autochain = autochainArray.getString(i);
64001
64248
 
64002
64249
 
64003
- resi = oriResi;
64250
+ resi = oriResi;
64004
64251
 
64005
- let molecueType;
64006
- if(atom_hetatm == "ATOM") {
64007
- if(resn.length == 3) {
64008
- molecueType = "p"; // protein
64009
- }
64010
- else {
64011
- molecueType = "n"; // nucleotide
64012
- }
64013
- }
64014
- else {
64015
- if(resn == "WAT" || resn == "HOH") {
64016
- molecueType = "s"; // solvent
64017
- chain = 'Misc';
64252
+ let molecueType;
64253
+ if(atom_hetatm == "ATOM") {
64254
+ if(resn.length == 3) {
64255
+ molecueType = "protein"; // protein
64256
+ }
64257
+ else {
64258
+ molecueType = "nucleotide"; // nucleotide
64259
+ }
64018
64260
  }
64019
64261
  else {
64020
- molecueType = "l"; // ligands or ions
64021
- chain = resn;
64262
+ if(resn == "WAT" || resn == "HOH") {
64263
+ molecueType = "solvent"; // solvent
64264
+ chain = 'Misc';
64265
+ }
64266
+ else {
64267
+ molecueType = "ligand"; // ligands or ions
64268
+ chain = resn;
64269
+ }
64022
64270
  }
64023
- }
64024
- if(chain === '') chain = 'A';
64025
-
64026
- // C-alpha only for large structure
64027
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && atom == 'CA')) || (molecueType == "n" && !(atom == "P")) ) ) continue;
64028
-
64029
- // skip alternative atoms
64030
- if(alt == "B") continue;
64031
-
64032
- sChain[chain] = 1;
64271
+ if(chain === '') chain = 'A';
64033
64272
 
64034
- if(bFirstAtom) {
64035
- structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64273
+ // C-alpha only for large structure
64274
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && atom == 'CA')) || (molecueType == "nucleotide" && !(atom == "P")) ) ) continue;
64275
+
64276
+ // skip alternative atoms
64277
+ if(alt == "B") continue;
64036
64278
 
64037
- bFirstAtom = false;
64038
- }
64279
+ sChain[chain] = 1;
64039
64280
 
64040
- // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
64041
- // Concatenation of two pdbs will have several atoms for the same serial
64042
- ++serial;
64281
+ if(bFirstAtom) {
64282
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64043
64283
 
64044
- // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
64045
- // bModifyResi = true;
64046
- // }
64284
+ bFirstAtom = false;
64285
+ }
64047
64286
 
64048
- if(resi == "?" || resi == "." || resi == "0") {
64049
- resi = oriResi;
64287
+ // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
64288
+ // Concatenation of two pdbs will have several atoms for the same serial
64289
+ ++serial;
64050
64290
 
64051
- // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64052
- // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64053
- // resi = (++tmpResi).toString();
64054
- // }
64055
- // }
64056
- // else {
64057
- // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64058
- // resi = (++tmpResi).toString();
64059
- // }
64060
- // else {
64061
- // resi = (tmpResi).toString();
64062
- // }
64291
+ // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
64292
+ // bModifyResi = true;
64063
64293
  // }
64064
- }
64065
64294
 
64066
- if(molecueType == 's' || molecueType == "l") {
64067
- let seq = {};
64068
- if(!ligSeqHash.hasOwnProperty(chain)) {
64069
- ligSeqHash[chain] = [];
64295
+ if(resi == "?" || resi == "." || resi == "0") {
64296
+ resi = oriResi;
64297
+
64298
+ // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64299
+ // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64300
+ // resi = (++tmpResi).toString();
64301
+ // }
64302
+ // }
64303
+ // else {
64304
+ // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64305
+ // resi = (++tmpResi).toString();
64306
+ // }
64307
+ // else {
64308
+ // resi = (tmpResi).toString();
64309
+ // }
64310
+ // }
64070
64311
  }
64071
64312
 
64072
- if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64073
- if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64074
- seq.resi = resi;
64075
- seq.name = me.utilsCls.residueName2Abbr(resn);
64076
- ligSeqHash[chain].push(seq);
64313
+ if(molecueType == 'solvent' || molecueType == "ligand") {
64314
+ let seq = {};
64315
+ if(!ligSeqHash.hasOwnProperty(chain)) {
64316
+ ligSeqHash[chain] = [];
64077
64317
  }
64078
- }
64079
- else {
64080
- if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64081
- seq.resi = resi;
64082
- seq.name = me.utilsCls.residueName2Abbr(resn);
64083
- ligSeqHash[chain].push(seq);
64318
+
64319
+ if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64320
+ if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64321
+ seq.resi = resi;
64322
+ seq.name = me.utilsCls.residueName2Abbr(resn);
64323
+ ligSeqHash[chain].push(seq);
64324
+ }
64325
+ }
64326
+ else {
64327
+ if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64328
+ seq.resi = resi;
64329
+ seq.name = me.utilsCls.residueName2Abbr(resn);
64330
+ ligSeqHash[chain].push(seq);
64331
+ }
64084
64332
  }
64085
64333
  }
64086
- }
64087
64334
 
64088
- // if(bOpm && resn === 'DUM') {
64089
- // elem = atom;
64090
- // chain = 'MEM';
64091
- // resi = 1;
64092
- // oriResi = 1;
64093
- // }
64335
+ // if(bOpm && resn === 'DUM') {
64336
+ // elem = atom;
64337
+ // chain = 'MEM';
64338
+ // resi = 1;
64339
+ // oriResi = 1;
64340
+ // }
64094
64341
 
64095
- // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
64342
+ // if(bVector && resn === 'DUM') break; // just need to get the vector of the largest chain
64096
64343
 
64097
- chainNum = structure + "_" + chain;
64098
- oriResidueNum = chainNum + "_" + oriResi;
64344
+ chainNum = structure + "_" + chain;
64345
+ oriResidueNum = chainNum + "_" + oriResi;
64099
64346
 
64100
- residueNum = chainNum + "_" + resi;
64347
+ residueNum = chainNum + "_" + resi;
64101
64348
 
64102
- //let chain_resi = chain + "_" + resi;
64349
+ //let chain_resi = chain + "_" + resi;
64103
64350
 
64104
- let x = xArray.getFloat(i);
64105
- let y = yArray.getFloat(i);
64106
- let z = zArray.getFloat(i);
64107
- let coord = new THREE.Vector3(x, y, z);
64351
+ let x = xArray.getFloat(i);
64352
+ let y = yArray.getFloat(i);
64353
+ let z = zArray.getFloat(i);
64354
+ let coord = new THREE.Vector3(x, y, z);
64108
64355
 
64109
- let atomDetails = {
64110
- het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
64111
- serial: serial, // required, unique atom id
64112
- name: atom, // required, atom name
64113
- alt: alt, // optional, some alternative coordinates
64114
- resn: resn, // optional, used to determine protein or nucleotide
64115
- structure: structure, // optional, used to identify structure
64116
- chain: chain, // optional, used to identify chain
64117
- resi: resi, // optional, used to identify residue ID
64118
- //insc: line.substr(26, 1),
64119
- coord: coord, // required, used to draw 3D shape
64120
- b: bFactor, // optional, used to draw B-factor tube
64121
- elem: elem, // optional, used to determine hydrogen bond
64122
- bonds: [], // required, used to connect atoms
64123
- ss: 'coil', // optional, used to show secondary structures
64124
- ssbegin: false, // optional, used to show the beginning of secondary structures
64125
- ssend: false // optional, used to show the end of secondary structures
64126
- };
64356
+ let atomDetails = {
64357
+ het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
64358
+ serial: serial, // required, unique atom id
64359
+ name: atom, // required, atom name
64360
+ alt: alt, // optional, some alternative coordinates
64361
+ resn: resn, // optional, used to determine protein or nucleotide
64362
+ structure: structure, // optional, used to identify structure
64363
+ chain: chain, // optional, used to identify chain
64364
+ resi: resi, // optional, used to identify residue ID
64365
+ //insc: line.substr(26, 1),
64366
+ coord: coord, // required, used to draw 3D shape
64367
+ b: bFactor, // optional, used to draw B-factor tube
64368
+ elem: elem, // optional, used to determine hydrogen bond
64369
+ bonds: [], // required, used to connect atoms
64370
+ ss: 'coil', // optional, used to show secondary structures
64371
+ ssbegin: false, // optional, used to show the beginning of secondary structures
64372
+ ssend: false // optional, used to show the end of secondary structures
64373
+ };
64127
64374
 
64128
- if(!atomDetails.het && atomDetails.name === 'C') ;
64129
- if(!atomDetails.het && atomDetails.name === 'O') ;
64375
+ if(!atomDetails.het && atomDetails.name === 'C') ;
64376
+ if(!atomDetails.het && atomDetails.name === 'O') ;
64130
64377
 
64131
- // from DSSP C++ code
64132
- // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
64133
- // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
64378
+ // from DSSP C++ code
64379
+ // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
64380
+ // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
64134
64381
 
64135
- // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
64136
- // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
64137
- // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
64382
+ // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
64383
+ // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
64384
+ // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
64138
64385
 
64139
- // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
64140
- // }
64386
+ // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
64387
+ // }
64141
64388
 
64142
- ic.atoms[serial] = atomDetails;
64389
+ ic.atoms[serial] = atomDetails;
64143
64390
 
64144
- ic.dAtoms[serial] = 1;
64145
- ic.hAtoms[serial] = 1;
64146
- hAtoms[serial] = 1;
64391
+ ic.dAtoms[serial] = 1;
64392
+ ic.hAtoms[serial] = 1;
64393
+ hAtoms[serial] = 1;
64147
64394
 
64148
- // Assign secondary structures from the input
64149
- // if a residue is assigned both sheet and helix, it is assigned as sheet
64150
- if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
64151
- ic.atoms[serial].ss = 'sheet';
64152
- if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
64153
- ic.atoms[serial].ssbegin = true;
64154
- }
64395
+ // Assign secondary structures from the input
64396
+ // if a residue is assigned both sheet and helix, it is assigned as sheet
64397
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
64398
+ ic.atoms[serial].ss = 'sheet';
64399
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
64400
+ ic.atoms[serial].ssbegin = true;
64401
+ }
64155
64402
 
64156
- // do not use else if. Some residues are both start and end of secondary structure
64157
- if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
64158
- ic.atoms[serial].ssend = true;
64403
+ // do not use else if. Some residues are both start and end of secondary structure
64404
+ if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
64405
+ ic.atoms[serial].ssend = true;
64406
+ }
64159
64407
  }
64160
- }
64161
- else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
64162
- ic.atoms[serial].ss = 'helix';
64408
+ else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
64409
+ ic.atoms[serial].ss = 'helix';
64163
64410
 
64164
- if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
64165
- ic.atoms[serial].ssbegin = true;
64411
+ if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
64412
+ ic.atoms[serial].ssbegin = true;
64413
+ }
64414
+
64415
+ // do not use else if. Some residues are both start and end of secondary structure
64416
+ if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
64417
+ ic.atoms[serial].ssend = true;
64418
+ }
64166
64419
  }
64167
64420
 
64168
- // do not use else if. Some residues are both start and end of secondary structure
64169
- if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
64170
- ic.atoms[serial].ssend = true;
64421
+ let secondaries = '-';
64422
+ if(ic.atoms[serial].ss === 'helix') {
64423
+ secondaries = 'H';
64424
+ }
64425
+ else if(ic.atoms[serial].ss === 'sheet') {
64426
+ secondaries = 'E';
64427
+ }
64428
+ //else if(ic.atoms[serial].ss === 'coil') {
64429
+ // secondaries = 'c';
64430
+ //}
64431
+ else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
64432
+ secondaries = 'c';
64433
+ }
64434
+ else {
64435
+ secondaries = 'o';
64171
64436
  }
64172
- }
64173
64437
 
64174
- let secondaries = '-';
64175
- if(ic.atoms[serial].ss === 'helix') {
64176
- secondaries = 'H';
64177
- }
64178
- else if(ic.atoms[serial].ss === 'sheet') {
64179
- secondaries = 'E';
64180
- }
64181
- //else if(ic.atoms[serial].ss === 'coil') {
64182
- // secondaries = 'c';
64183
- //}
64184
- else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
64185
- secondaries = 'c';
64186
- }
64187
- else {
64188
- secondaries = 'o';
64189
- }
64438
+ ic.secondaries[residueNum] = secondaries;
64190
64439
 
64191
- ic.secondaries[residueNum] = secondaries;
64440
+ // different residue
64441
+ //if(residueNum !== prevResidueNum) {
64442
+
64443
+ // if(oriResidueNum !== prevOriResidueNum) {
64444
+ if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
64445
+ let residue = me.utilsCls.residueName2Abbr(resn);
64446
+
64447
+ ic.residueId2Name[residueNum] = residue;
64192
64448
 
64193
- // different residue
64194
- //if(residueNum !== prevResidueNum) {
64195
-
64196
- // if(oriResidueNum !== prevOriResidueNum) {
64197
- if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
64198
- let residue = me.utilsCls.residueName2Abbr(resn);
64199
-
64200
- ic.residueId2Name[residueNum] = residue;
64449
+ if(serial !== 1 && prevResidueNum !== '') {
64450
+ ic.residues[prevResidueNum] = residuesTmp;
64451
+ }
64201
64452
 
64202
- if(serial !== 1 && prevResidueNum !== '') {
64203
- ic.residues[prevResidueNum] = residuesTmp;
64204
- }
64453
+ if(residueNum !== prevResidueNum) {
64454
+ residuesTmp = {};
64455
+ }
64205
64456
 
64206
- if(residueNum !== prevResidueNum) {
64207
- residuesTmp = {};
64208
- }
64457
+ // different chain
64458
+ if(chainNum !== prevChainNum) {
64209
64459
 
64210
- // different chain
64211
- if(chainNum !== prevChainNum) {
64460
+ // a chain could be separated in two sections
64461
+ if(serial !== 1 && prevChainNum !== '') {
64462
+ if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
64463
+ ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
64464
+ }
64212
64465
 
64213
- // a chain could be separated in two sections
64214
- if(serial !== 1 && prevChainNum !== '') {
64215
- if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
64216
- ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
64217
- }
64466
+ chainsTmp = {};
64218
64467
 
64219
- chainsTmp = {};
64468
+ if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
64469
+ if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
64220
64470
 
64221
- if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
64222
- if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
64471
+ if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
64223
64472
 
64224
- if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
64473
+ let resObject = {};
64474
+ resObject.resi = resi;
64475
+ resObject.name = residue;
64225
64476
 
64226
- let resObject = {};
64227
- resObject.resi = resi;
64228
- resObject.name = residue;
64477
+ ic.chainsSeq[chainNum].push(resObject);
64478
+ }
64479
+ else {
64480
+
64481
+ let resObject = {};
64482
+ resObject.resi = resi;
64483
+ resObject.name = residue;
64229
64484
 
64230
- ic.chainsSeq[chainNum].push(resObject);
64485
+ ic.chainsSeq[chainNum].push(resObject);
64486
+ }
64231
64487
  }
64232
- else {
64233
64488
 
64234
- let resObject = {};
64235
- resObject.resi = resi;
64236
- resObject.name = residue;
64489
+ chainsTmp[serial] = 1;
64490
+ residuesTmp[serial] = 1;
64237
64491
 
64238
- ic.chainsSeq[chainNum].push(resObject);
64239
- }
64240
- }
64492
+ prevChainNum = chainNum;
64493
+ prevResidueNum = residueNum;
64494
+ prevOriResidueNum = oriResidueNum;
64241
64495
 
64242
- chainsTmp[serial] = 1;
64243
- residuesTmp[serial] = 1;
64496
+ prevResn = chain + "_" + resn;
64497
+ prevAutochain = autochain;
64498
+ }
64244
64499
 
64245
- prevChainNum = chainNum;
64246
- prevResidueNum = residueNum;
64247
- prevOriResidueNum = oriResidueNum;
64500
+ // add the last residue set
64501
+ ic.residues[residueNum] = residuesTmp;
64502
+ if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
64503
+ ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
64248
64504
 
64249
- prevResn = chain + "_" + resn;
64250
- prevAutochain = autochain;
64251
- }
64505
+ // clear memory
64506
+ atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
64507
+ = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
64252
64508
 
64253
- // add the last residue set
64254
- ic.residues[residueNum] = residuesTmp;
64255
- if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
64256
- ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
64509
+ let mChainSeq = {};
64510
+ if(block.getCategory("_pdbx_poly_seq_scheme")) {
64511
+ let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
64257
64512
 
64258
- // clear memory
64259
- atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
64260
- = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
64513
+ let resiArray = poly_seq_scheme.getColumn("seq_id");
64514
+ let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
64515
+ let resnArray = poly_seq_scheme.getColumn("mon_id");
64516
+ let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
64261
64517
 
64262
- let mChainSeq = {};
64263
- if(block.getCategory("_pdbx_poly_seq_scheme")) {
64264
- let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
64518
+ let seqSize = poly_seq_scheme.rowCount;
64519
+ let prevChain = "";
64520
+ let seqArray = [];
64521
+ for (let i = 0; i < seqSize; ++i) {
64522
+ resiArray.getString(i);
64523
+ let oriResi = oriResiArray.getString(i);
64524
+ let resn = resnArray.getString(i);
64525
+ let chain = chainArray.getString(i);
64265
64526
 
64266
- let resiArray = poly_seq_scheme.getColumn("seq_id");
64267
- let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
64268
- let resnArray = poly_seq_scheme.getColumn("mon_id");
64269
- let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
64527
+ if(chain != prevChain && i > 0) {
64528
+ mChainSeq[prevChain] = seqArray;
64270
64529
 
64271
- let seqSize = poly_seq_scheme.rowCount;
64272
- let prevChain = "";
64273
- let seqArray = [];
64274
- for (let i = 0; i < seqSize; ++i) {
64275
- resiArray.getString(i);
64276
- let oriResi = oriResiArray.getString(i);
64277
- let resn = resnArray.getString(i);
64278
- let chain = chainArray.getString(i);
64530
+ seqArray = [];
64531
+ }
64279
64532
 
64280
- if(chain != prevChain && i > 0) {
64281
- mChainSeq[prevChain] = seqArray;
64533
+ // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
64534
+ seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
64282
64535
 
64283
- seqArray = [];
64536
+ prevChain = chain;
64284
64537
  }
64285
64538
 
64286
- // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
64287
- seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
64539
+ mChainSeq[prevChain] = seqArray;
64288
64540
 
64289
- prevChain = chain;
64541
+ resiArray = oriResiArray = resnArray = chainArray = [];
64290
64542
  }
64291
-
64292
- mChainSeq[prevChain] = seqArray;
64293
-
64294
- resiArray = oriResiArray = resnArray = chainArray = [];
64543
+
64544
+ this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
64295
64545
  }
64296
-
64297
- this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
64298
64546
 
64299
64547
  // copy disulfide bonds
64300
64548
  let structureArray = Object.keys(ic.structures);
@@ -66069,11 +66317,13 @@ class ApplyCommand {
66069
66317
  ic.drawCls.draw();
66070
66318
  }
66071
66319
  else if(command.indexOf('add sphere') == 0) {
66072
- this.addShape(command, 'sphere');
66320
+ this.addShape(commandOri, 'sphere');
66321
+ ic.shapeCmdHash[commandOri] = 1;
66073
66322
  //ic.drawCls.draw();
66074
66323
  }
66075
66324
  else if(command.indexOf('add cube') == 0) {
66076
- this.addShape(command, 'cube');
66325
+ this.addShape(commandOri, 'cube');
66326
+ ic.shapeCmdHash[commandOri] = 1;
66077
66327
  //ic.drawCls.draw();
66078
66328
  }
66079
66329
  else if(command.indexOf('clear shape') == 0) {
@@ -66529,8 +66779,8 @@ class ApplyCommand {
66529
66779
 
66530
66780
  ic.hlUpdateCls.updateHlAll();
66531
66781
 
66532
- // change graph color
66533
- ic.getGraphCls.updateGraphColor();
66782
+ // change graph color, was done in color command
66783
+ //ic.getGraphCls.updateGraphColor();
66534
66784
  }
66535
66785
  else if(commandOri.indexOf('remove legend') == 0) {
66536
66786
  $("#" + me.pre + "legend").hide();
@@ -66816,7 +67066,7 @@ class ApplyCommand {
66816
67066
  }
66817
67067
 
66818
67068
  addShape(command, shape) { let ic = this.icn3d, me = ic.icn3dui;
66819
- ic.shapeCmdHash[command] = 1;
67069
+ // ic.shapeCmdHash[command] = 1;
66820
67070
 
66821
67071
  let paraArray = command.split(' | ');
66822
67072
  let p1Array = paraArray[1].split(' ');
@@ -66827,7 +67077,17 @@ class ApplyCommand {
66827
67077
  colorStr = '#' + colorStr.replace(/\#/g, '');
66828
67078
  let color = me.parasCls.thr(colorStr);
66829
67079
 
66830
- let pos1 = new THREE.Vector3(parseFloat(p1Array[1]), parseFloat(p1Array[3]), parseFloat(p1Array[5]));
67080
+ let pos1;
67081
+
67082
+ if(p1Array[0] == 'x1') { // input position
67083
+ pos1 = new THREE.Vector3(parseFloat(p1Array[1]), parseFloat(p1Array[3]), parseFloat(p1Array[5]));
67084
+ }
67085
+ else { // input sets
67086
+ let nameArray = paraArray[1].split(',');
67087
+ let atomSet1 = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
67088
+ let posArray1 = ic.contactCls.getExtent(atomSet1);
67089
+ pos1 = new THREE.Vector3(posArray1[2][0], posArray1[2][1], posArray1[2][2]);
67090
+ }
66831
67091
 
66832
67092
  if(shape == 'sphere') {
66833
67093
  ic.sphereCls.createSphereBase(pos1, color, parseFloat(radius), undefined, undefined, undefined, parseFloat(opacity));
@@ -67807,7 +68067,7 @@ class SelectCollections {
67807
68067
 
67808
68068
  ic.ssbondpnts = {};
67809
68069
 
67810
- ic.bShowHighlight = false;
68070
+ ic.bShowHighlight = undefined;
67811
68071
  ic.bResetSets = true;
67812
68072
  }
67813
68073
 
@@ -67938,8 +68198,8 @@ class SelectCollections {
67938
68198
  ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
67939
68199
  }
67940
68200
 
67941
- ic.opts["color"] = "structure";
67942
- ic.setStyleCls.setAtomStyleByOptions();
68201
+ ic.opts["color"] = (Object.keys(ic.structures).length == 1) ? "chain" : "structure";
68202
+ // ic.setStyleCls.setAtomStyleByOptions();
67943
68203
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
67944
68204
 
67945
68205
  ic.transformCls.zoominSelection();
@@ -70189,6 +70449,34 @@ class Resid2spec {
70189
70449
  return spec;
70190
70450
  }
70191
70451
 
70452
+ resi2range(resiArray) {var ic = this.icn3d; ic.icn3dui;
70453
+ let range = [];
70454
+
70455
+ let resiArraySorted = resiArray.sort(function(a, b) {
70456
+ return parseInt(a) - parseInt(b);
70457
+ });
70458
+
70459
+ let startResi = resiArraySorted[0];
70460
+ let prevResi, resi;
70461
+ for(let j = 0, jl = resiArraySorted.length; j < jl; ++j) {
70462
+ resi = resiArraySorted[j];
70463
+
70464
+ if(j != 0 && resi != prevResi + 1) {
70465
+ range.push(startResi);
70466
+ range.push(prevResi);
70467
+ startResi = resi;
70468
+ }
70469
+
70470
+ prevResi = resi;
70471
+ }
70472
+
70473
+ // last residue
70474
+ range.push(startResi);
70475
+ range.push(prevResi);
70476
+
70477
+ return range;
70478
+ }
70479
+
70192
70480
  atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
70193
70481
  let spec = "";
70194
70482
  let i = 0;
@@ -71651,8 +71939,6 @@ class Dssp {
71651
71939
  bNoMoreIg = false;
71652
71940
 
71653
71941
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
71654
- //let bForceOneDomain = true;
71655
- //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
71656
71942
 
71657
71943
  // ig strand for any subset will have the same k, use the number of residue to separate them
71658
71944
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
@@ -71812,20 +72098,24 @@ class Dssp {
71812
72098
  // assign ref numbers to selected residues
71813
72099
  let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
71814
72100
  let subdomains = result.subdomains;
71815
- let pos2resi = result.pos2resi;
72101
+ // let pos2resi = result.pos2resi;
71816
72102
 
71817
72103
  if(subdomains.length >= 1) {
71818
72104
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
71819
72105
  let domainAtoms = {};
71820
72106
  let segArray = subdomains[k];
71821
72107
 
71822
- let resCnt = 0;
72108
+ let resCnt = 0; // minResi = 999, maxResi = -999;
71823
72109
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
71824
72110
  let startResi = parseInt(segArray[m]);
71825
72111
  let endResi = parseInt(segArray[m+1]);
71826
72112
 
72113
+ // if(startResi < minResi) minResi = startResi;
72114
+ // if(endResi > maxResi) maxResi = endResi;
72115
+
71827
72116
  for(let n = startResi; n <= endResi; ++n) {
71828
- let resid = chainid + '_' + pos2resi[n - 1];
72117
+ // let resid = chainid + '_' + pos2resi[n - 1];
72118
+ let resid = ic.ncbi2resid[chainid + '_' + n];
71829
72119
  ++resCnt;
71830
72120
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
71831
72121
 
@@ -71841,6 +72131,9 @@ class Dssp {
71841
72131
  domainAtomsArray.push(domainAtoms);
71842
72132
  }
71843
72133
  }
72134
+ // else { // no domain
72135
+ // domainAtomsArray = [currAtoms];
72136
+ // }
71844
72137
 
71845
72138
  return domainAtomsArray;
71846
72139
  }
@@ -71977,7 +72270,6 @@ class Dssp {
71977
72270
  continue;
71978
72271
  }
71979
72272
  // }
71980
-
71981
72273
  }
71982
72274
 
71983
72275
  if(!bRound1) {
@@ -72525,15 +72817,21 @@ class Dssp {
72525
72817
 
72526
72818
  let resi = refAA[i][j].trim();
72527
72819
  let refnum = refAA[refI][j].trim();
72820
+
72821
+ if(!ic.chainsMapping.hasOwnProperty(chainid)) {
72822
+ ic.chainsMapping[chainid] = {};
72823
+ }
72824
+
72825
+ let resid = chainid + '_' + resi;
72826
+
72528
72827
  if(resi && refnum) {
72529
- let resid = chainid + '_' + resi;
72530
72828
  ic.resid2refnum[resid] = refnum;
72531
72829
 
72532
- if(!ic.chainsMapping.hasOwnProperty(chainid)) {
72533
- ic.chainsMapping[chainid] = {};
72534
- }
72535
72830
  ic.chainsMapping[chainid][resid] = refnum;
72536
72831
  }
72832
+ else {
72833
+ ic.chainsMapping[chainid][resid] = resi;
72834
+ }
72537
72835
  }
72538
72836
  }
72539
72837
 
@@ -73009,17 +73307,18 @@ class Dssp {
73009
73307
  }
73010
73308
 
73011
73309
  // assign before removing
73012
- let resid = chnid + '_' + strandArray[i].startResi;
73310
+ chnid + '_' + strandArray[i].startResi;
73013
73311
 
73014
73312
  strandArray.splice(i, 1);
73015
73313
 
73016
- if(strandTmp == 'B' || strandTmp == 'C' || strandTmp == 'E' || strandTmp == 'F') {
73017
- if(!me.bNode) console.log("Ig strand " + strandTmp + " is removed since it is too short...");
73314
+ // do not remove BCEF strands even though they are short
73315
+ // if(strandTmp == 'B' || strandTmp == 'C' || strandTmp == 'E' || strandTmp == 'F') {
73316
+ // if(!me.bNode) console.log("Ig strand " + strandTmp + " is removed since it is too short...");
73018
73317
 
73019
- let domainid = ic.resid2domainid[resid];
73020
- removeDomainidHash[domainid] = 1;
73021
- continue;
73022
- }
73318
+ // let domainid = ic.resid2domainid[resid];
73319
+ // removeDomainidHash[domainid] = 1;
73320
+ // continue;
73321
+ // }
73023
73322
  }
73024
73323
  }
73025
73324
 
@@ -73237,7 +73536,7 @@ class Dssp {
73237
73536
 
73238
73537
  // remove the postfix when comparing interactions
73239
73538
  //ic.chainsMapping[chnid][residueid] = refnumLabel;
73240
- ic.chainsMapping[chnid][residueid] = refnumLabelNoPostfix;
73539
+ ic.chainsMapping[chnid][residueid] = (refnumLabelNoPostfix) ? refnumLabelNoPostfix : currResi;
73241
73540
  }
73242
73541
  }
73243
73542
 
@@ -81390,7 +81689,7 @@ class iCn3DUI {
81390
81689
  //even when multiple iCn3D viewers are shown together.
81391
81690
  this.pre = this.cfg.divid + "_";
81392
81691
 
81393
- this.REVISION = '3.31.3';
81692
+ this.REVISION = '3.32.0';
81394
81693
 
81395
81694
  // In nodejs, iCn3D defines "window = {navigator: {}}"
81396
81695
  this.bNode = (Object.keys(window).length < 2) ? true : false;