icn3d 3.31.13 → 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 +1048 -793
  2. package/icn3d.min.js +5 -5
  3. package/icn3d.module.js +1048 -793
  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
17825
 
17847
- // let dataObj = {'mmciffile': dataStr};
17848
- // let data = await me.getAjaxPostPromise(url, dataObj, true);
17849
-
17850
- let bText = true;
17851
- // let bcifData = ic.bcifParserCls.getBcifJson(dataStr, undefined, bText);
17852
- // let data = JSON.parse(bcifData);
17853
-
17854
- //ic.initUI();
17855
- ic.init();
17856
- ic.bInputfile = true;
17857
- ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + data : dataStr;
17858
- ic.InputfileType = 'mmcif';
17859
- // await ic.mmcifParserCls.loadMmcifData(data);
17860
- await ic.opmParserCls.loadOpmData(dataStr, undefined, undefined, 'mmcif', undefined, bText);
17861
- };
17862
- reader.readAsText(file);
17863
- }
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;
@@ -40850,9 +40816,24 @@ class AnnoCddSite {
40850
40816
  pssmid2toArray = {};
40851
40817
  }
40852
40818
 
40853
- let indexl =(domainArray !== undefined) ? domainArray.length : 0;
40819
+ if(domainArray === undefined) domainArray = [];
40820
+ let indexl = domainArray.length;
40854
40821
  let maxTextLen =(type == 'domain') ? 14 : 19;
40855
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
+
40856
40837
  for(let index = 0; index < indexl; ++index) {
40857
40838
  let pssmid = (type == 'domain') ? domainArray[index].pssmid : 0;
40858
40839
 
@@ -41721,6 +41702,7 @@ class AnnoIg {
41721
41702
  async showIg(chnid, template) { let ic = this.icn3d; ic.icn3dui;
41722
41703
  // if(!ic.bRunRefnum || Object.keys(ic.atoms).length > Object.keys(ic.hAtoms).length) {
41723
41704
  if(ic.bRunRefnumAgain) {
41705
+ // run for all chains
41724
41706
  await ic.refnumCls.showIgRefNum(template);
41725
41707
  // ic.bRunRefnum = true;
41726
41708
  }
@@ -42378,9 +42360,7 @@ class AnnoDomain {
42378
42360
 
42379
42361
  let result = ic.domain3dCls.c2b_NewSplitChain(atoms);
42380
42362
  let subdomains = result.subdomains;
42381
- let pos2resi = result.pos2resi;
42382
- //let substruct = result.substruct;
42383
- //let jsonStr = ic.domain3dCls.getDomainJsonForAlign(atoms);
42363
+ // let pos2resi = result.pos2resi;
42384
42364
 
42385
42365
  for(let i = 0, il = subdomains.length; i < il; ++i) {
42386
42366
  // domain item: {"sdid":1722375,"intervals":[[1,104],[269,323]]}
@@ -42394,7 +42374,7 @@ class AnnoDomain {
42394
42374
  data.domains[chainid].domains.push(domain);
42395
42375
  }
42396
42376
 
42397
- data.domains[chainid].pos2resi = pos2resi;
42377
+ // data.domains[chainid].pos2resi = pos2resi;
42398
42378
  }
42399
42379
  }
42400
42380
 
@@ -42427,11 +42407,26 @@ class AnnoDomain {
42427
42407
  this.showDomainPerStructure(i);
42428
42408
  }
42429
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
+
42430
42425
  showDomainWithData(chnid, data, bCalcDirect) { let ic = this.icn3d, me = ic.icn3dui;
42431
42426
  let html = '<div id="' + ic.pre + chnid + '_domainseq_sequence" class="icn3d-dl_sequence">';
42432
42427
  let html2 = html;
42433
42428
  let html3 = html;
42434
- let domainArray, pos2resi, proteinname;
42429
+ let domainArray, proteinname;
42435
42430
  let pos = chnid.indexOf('_');
42436
42431
  let chain = chnid.substr(pos + 1);
42437
42432
  // MMDB symmetry chain has the form of 'A1'
@@ -42442,7 +42437,7 @@ class AnnoDomain {
42442
42437
  // if(bCalcDirect) {
42443
42438
  proteinname = chnid;
42444
42439
  domainArray = (data.domains[chnid]) ? data.domains[chnid].domains : [];
42445
- pos2resi = data.domains[chnid].pos2resi;
42440
+ // pos2resi = data.domains[chnid].pos2resi;
42446
42441
  /*
42447
42442
  }
42448
42443
  else {
@@ -42470,40 +42465,33 @@ class AnnoDomain {
42470
42465
  let title =(fulltitle.length > 17) ? fulltitle.substr(0,17) + '...' : fulltitle;
42471
42466
  let subdomainArray = domainArray[index].intervals;
42472
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
42473
- let domainFromHash = {}, domainToHash = {};
42474
- let fromArray = [], toArray = [], posFromArray = [], posToArray = [];
42468
+ // let domainFromHash = {}, domainToHash = {};
42469
+ let fromArray = [], toArray = []; // posFromArray = [], posToArray = [];
42475
42470
  let resiHash = {};
42476
42471
  let resCnt = 0;
42477
42472
 
42473
+ // subdomainArray contains NCBI residue number
42478
42474
  for(let i = 0, il = subdomainArray.length; i < il; ++i) {
42479
- let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
42480
- let domainTo = Math.round(subdomainArray[i][1]) - 1;
42475
+ // let domainFrom = Math.round(subdomainArray[i][0]) - 1; // convert 1-based to 0-based
42476
+ // let domainTo = Math.round(subdomainArray[i][1]) - 1;
42481
42477
 
42482
- if(domainFromHash.hasOwnProperty(domainFrom) || domainToHash.hasOwnProperty(domainTo)) {
42483
- continue; // do nothing for duplicated "from" or "to", e.g, PDBID 1ITW, 5FWI
42484
- }
42485
- else {
42486
- domainFromHash[domainFrom] = 1;
42487
- domainToHash[domainTo] = 1;
42488
- }
42478
+ let domainFrom = parseInt(subdomainArray[i][0]);
42479
+ let domainTo = parseInt(subdomainArray[i][1]);
42489
42480
 
42490
- // use the NCBI residue number, and convert to PDB residue number during selection
42491
- // if(ic.bNCBI || bCalcDirect) {
42492
- fromArray.push(pos2resi[domainFrom]);
42493
- toArray.push(pos2resi[domainTo]);
42494
42481
 
42495
- posFromArray.push(domainFrom);
42496
- posToArray.push(domainTo);
42497
- // }
42498
- // else {
42499
- // fromArray.push(domainFrom + ic.baseResi[chnid]);
42500
- // toArray.push(domainTo + ic.baseResi[chnid]);
42501
- // }
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);
42502
42490
 
42503
42491
  resCnt += domainTo - domainFrom + 1;
42504
42492
  for(let j = domainFrom; j <= domainTo; ++j) {
42505
- // resiHash[j+1] = 1;
42506
- let resi = pos2resi[j];
42493
+ // let resi = pos2resi[j];
42494
+ let resi = this.getResiFromNnbiresid(chnid + '_' + j);
42507
42495
  resiHash[resi] = 1;
42508
42496
  }
42509
42497
  }
@@ -42514,21 +42502,22 @@ class AnnoDomain {
42514
42502
 
42515
42503
  if(!ic.resid2domain) ic.resid2domain = {};
42516
42504
  if(!ic.resid2domain[chnid]) ic.resid2domain[chnid] = [];
42517
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
42518
- let from = parseInt(posFromArray[i]);
42519
- let to = parseInt(posToArray[i]);
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];
42520
42509
  for(let j = from; j <= to; ++j) {
42521
42510
  // 0-based
42522
42511
  let obj = {};
42523
42512
  // let resi = ic.ParserUtilsCls.getResi(chnid, j);
42524
- let resi = pos2resi[j];
42525
- obj[chnid + '_' + resi] = domainName;
42513
+ let resid = ic.ncbi2resid(chnid + '_' + j);
42514
+ obj[resid] = domainName;
42526
42515
  ic.resid2domain[chnid].push(obj);
42527
42516
  }
42528
42517
  }
42529
42518
  }
42530
42519
 
42531
- let htmlTmp2 = '<div class="icn3d-seqTitle icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + posFromArray + '" to="' + posToArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
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>';
42532
42521
  let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
42533
42522
  html3 += htmlTmp2 + htmlTmp3 + '<br>';
42534
42523
  let htmlTmp = '<span class="icn3d-seqLine">';
@@ -42568,12 +42557,12 @@ class AnnoDomain {
42568
42557
  if(ic.seqStartLen && ic.seqStartLen[chnid]) html2 += ic.showSeqCls.insertMulGapOverview(chnid, ic.seqStartLen[chnid]);
42569
42558
 
42570
42559
  if(me.cfg.blast_rep_id != chnid) { // regular
42571
- for(let i = 0, il = posFromArray.length; i < il; ++i) {
42560
+ for(let i = 0, il = fromArray.length; i < il; ++i) {
42572
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);
42573
- let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(posFromArray[i]) / ic.maxAnnoLength) : Math.round(ic.seqAnnWidth *(posFromArray[i] - posToArray[i-1] - 1) / ic.maxAnnoLength);
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);
42574
42563
 
42575
42564
  html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;">&nbsp;</div>';
42576
- html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(posToArray[i] - posFromArray[i] + 1) / ic.maxAnnoLength) + 'px;" class="icn3d-seqTitle icn3d-link icn3d-blue" 3ddomain="' +(index+1).toString() + '" from="' + posFromArray + '" to="' + posToArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + chnid + '_3d_domain_' +(index+1).toString() + '" id="' + chnid + '_3d_domain_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">3D domain ' +(index+1).toString() + '</div>';
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>';
42577
42566
  }
42578
42567
  }
42579
42568
  else { // with potential gaps
@@ -44085,6 +44074,7 @@ class Domain3d {
44085
44074
  //c2b_NewSplitChain(string asymId, let seqLen, let* x0, let* y0, let* z0) { let ic = this.icn3d, me = ic.icn3dui;
44086
44075
  // x0, y0, z0: array of x,y,z coordinates of C-alpha atoms
44087
44076
  //c2b_NewSplitChain(chnid, dcut) { let ic = this.icn3d, me = ic.icn3dui;
44077
+ // this function works for a single chain
44088
44078
  c2b_NewSplitChain(atoms, dcut) { let ic = this.icn3d; ic.icn3dui;
44089
44079
  this.init3ddomain();
44090
44080
 
@@ -44140,14 +44130,11 @@ class Domain3d {
44140
44130
  // pos2resi[i+1] = resi;
44141
44131
  pos2resi[i] = resi;
44142
44132
 
44143
- ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
44144
- // let residNCBI = ic.resid2ncbi[resid];
44145
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44146
- // pos2resi[pos] = resi;
44147
-
44133
+ // ic.posid2resid[atom.structure + '_' + atom.chain + '_' + (i+1).toString()] = resid;
44148
44134
  if(atom.ssend) {
44149
44135
  //substructItem.To = parseInt(resi);
44150
44136
  substructItem.To = i + 1;
44137
+ // substructItem.To = ic.annoDomainCls.getNcbiresiFromResid(resid);
44151
44138
  substructItem.x2 = atom.coord.x;
44152
44139
  substructItem.y2 = atom.coord.y;
44153
44140
  substructItem.z2 = atom.coord.z;
@@ -44162,6 +44149,7 @@ class Domain3d {
44162
44149
  if(atom.ssbegin) {
44163
44150
  //substructItem.From = parseInt(resi);
44164
44151
  substructItem.From = i + 1;
44152
+ // substructItem.From = ic.annoDomainCls.getNcbiresiFromResid(resid);
44165
44153
  substructItem.x1 = atom.coord.x;
44166
44154
  substructItem.y1 = atom.coord.y;
44167
44155
  substructItem.z1 = atom.coord.z;
@@ -44169,17 +44157,19 @@ class Domain3d {
44169
44157
  }
44170
44158
 
44171
44159
  let nsse = substruct.length;
44172
-
44173
- if (nsse <= 3)
44160
+
44161
+ if (nsse <= 3) {
44174
44162
  // too small, can't split or trim
44175
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44163
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44164
+ return {subdomains: subdomains, substruct: substruct};
44165
+ }
44176
44166
 
44177
44167
  if (nsse > this.MAX_SSE) {
44178
44168
  // we have a problem...
44179
-
44180
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44169
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44170
+ return {subdomains: subdomains, substruct: substruct};
44181
44171
  }
44182
-
44172
+
44183
44173
  let seqLen = residueArray.length; // + resiOffset;
44184
44174
  //let lastResi = resiArray[seqLen - 1];
44185
44175
  let lastResi = seqLen;
@@ -44500,7 +44490,8 @@ class Domain3d {
44500
44490
  let k = prts[i] - 1;
44501
44491
 
44502
44492
  if ((k < 0) || (k >= substruct.length)) {
44503
- return {subdomains: subdomains, substruct: substruct, pos2resi: pos2resi};
44493
+ substruct = this.standardizeSubstruct(chnid, substruct, pos2resi);
44494
+ return {subdomains: subdomains, substruct: substruct};
44504
44495
  }
44505
44496
 
44506
44497
  //SSE_Rec sserec = substruct[k];
@@ -44587,16 +44578,23 @@ class Domain3d {
44587
44578
 
44588
44579
  if (inseg && (rf == 0)) {
44589
44580
  // segment ends
44590
- segments.push(startseg);
44591
- 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
+
44592
44587
  inseg = false;
44593
44588
  }
44594
44589
  }
44595
44590
 
44596
44591
  // check for the last segment
44597
44592
  if (inseg) {
44598
- segments.push(startseg);
44599
- 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);
44600
44598
  }
44601
44599
 
44602
44600
  subdomains.push(segments);
@@ -44617,61 +44615,114 @@ class Domain3d {
44617
44615
  }
44618
44616
  }
44619
44617
 
44620
- 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};
44621
44623
  } // end c2b_NewSplitChain
44622
44624
 
44623
- 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;
44624
44667
  let result = this.c2b_NewSplitChain(atoms);
44625
44668
 
44626
44669
  let subdomains = result.subdomains;
44627
44670
  let substruct = result.substruct;
44628
- let pos2resi = result.pos2resi;
44671
+ // let pos2resi = result.pos2resi;
44629
44672
 
44630
- let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
44631
- let residueArray = Object.keys(residueHash);
44632
- let chnid = residueArray[0].substr(0, residueArray[0].lastIndexOf('_'));
44633
44673
 
44634
- 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('_'));
44635
44677
 
44636
- //the whole structure is also considered as a large domain
44637
- //if(subdomains.length == 0) {
44638
- //subdomains.push([parseInt(ic.chainsSeq[chnid][0].resi), parseInt(ic.chainsSeq[chnid][ic.chainsSeq[chnid].length - 1].resi)]);
44678
+ let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(atoms);
44679
+ let chnid = firstAtom.structure + '_' + firstAtom.chain;
44639
44680
 
44640
- // subdomains.push([parseInt(residueArray[0].substr(residueArray[0].lastIndexOf('_') + 1)),
44641
- // parseInt(residueArray[residueArray.length-1].substr(residueArray[residueArray.length-1].lastIndexOf('_') + 1))]);
44681
+ // if(bForceOneDomain) subdomains = [];
44642
44682
 
44643
- // use position based
44644
- subdomains.push([1, residueArray.length]);
44645
-
44646
- //}
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
+ }
44647
44691
 
44648
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], ...]} ] }
44649
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;
44650
44698
  for(let i = 0, il = subdomains.length; i < il; ++i) {
44651
- if(i > 0) jsonStr += ', ';
44652
- //secondary structure
44653
- jsonStr += '{"ss": [';
44654
- let ssCnt = 0;
44699
+ // if(i > 0) jsonStr += ', ';
44700
+ // jsonStr += '{"ss": ['; //secondary structure
44701
+
44655
44702
  for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
44656
44703
  let start = subdomains[i][j];
44657
44704
  let end = subdomains[i][j + 1];
44658
-
44705
+
44706
+ if(start < startAll) startAll = start;
44707
+ if(end > endAll) endAll = end;
44708
+
44659
44709
  for(let k = 0, kl = substruct.length; k < kl; ++k) {
44660
44710
  //ss: sstype ss_start ss_end x1 y1 z1 x2 y2 z2
44661
44711
  //sstype: 1 (helix), 2 (sheet)
44662
44712
  let sstype = (substruct[k].Sheet) ? 2 : 1;
44663
- let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
44664
- let to = pos2resi[substruct[k].To - 1];
44713
+ // let from = pos2resi[substruct[k].From - 1]; // 1-based to 0-based
44714
+ // let to = pos2resi[substruct[k].To - 1];
44665
44715
 
44666
44716
  // 1-based residue numbers
44667
44717
  let fromPos = substruct[k].From;
44668
44718
  let toPos = substruct[k].To;
44669
44719
 
44670
- let residFrom = chnid + "_" + from;
44720
+ let residFrom = ic.ncbi2resid[chnid + "_" + fromPos];
44671
44721
  let atomFrom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residFrom]);
44722
+
44672
44723
  if(!atomFrom || !ic.hAtoms.hasOwnProperty(atomFrom.serial)) continue;
44673
44724
 
44674
- let residTo = chnid + "_" + to;
44725
+ let residTo = ic.ncbi2resid[chnid + "_" + toPos];
44675
44726
  let atomTo = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[residTo]);
44676
44727
  if(!atomTo || !ic.hAtoms.hasOwnProperty(atomTo.serial)) continue;
44677
44728
 
@@ -44683,45 +44734,170 @@ class Domain3d {
44683
44734
  }
44684
44735
  }
44685
44736
  }
44686
- 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
44687
44744
 
44688
- // domain
44689
- jsonStr += ', "domain": [';
44690
- let domainCnt = 0;
44691
- for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
44692
- let start = subdomains[i][j];
44693
- let end = subdomains[i][j + 1];
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;
44694
44751
 
44695
- for(let k = 0, kl = residueArray.length; k < kl; ++k) {
44696
- let resid = residueArray[k];
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]);
44800
+
44801
+ let resi = resid.substr(resid.lastIndexOf('_') + 1);
44802
+ pos2resi[i] = resi;
44697
44803
 
44698
- // let resi = resid.substr(resid.lastIndexOf('_') + 1);
44699
- // let residNCBI = ic.resid2ncbi[resid];
44700
- // let pos = residNCBI.substr(residNCBI.lastIndexOf('_') + 1);
44701
- let pos = k + 1;
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;
44815
+
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 += ']';
44702
44865
 
44703
- //let resid = chnid + "_" + resi;
44704
- let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
44705
-
44706
- if(!atom) continue;
44707
- if(!ic.hAtoms.hasOwnProperty(atom.serial)) continue;
44708
-
44709
- //domain: resi, restype, x, y, z
44710
- let restype = me.parasCls.resn2restype[atom.resn];
44711
- if(restype !== undefined && pos >= start && pos <= end) {
44712
- if(domainCnt > 0) jsonStr += ', ';
44713
- jsonStr += '[' + pos + ',' + restype + ',' + atom.coord.x.toFixed(2) + ','
44714
- + atom.coord.y.toFixed(2) + ',' + atom.coord.z.toFixed(2) + ']';
44715
- ++domainCnt;
44716
- }
44717
- }
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 + ']';
44718
44882
  }
44719
- jsonStr += ']}';
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) + ']';
44890
+ }
44891
+
44892
+ ++domainCnt;
44720
44893
  }
44721
44894
  jsonStr += ']}';
44722
44895
 
44896
+ jsonStr += ']}';
44897
+
44723
44898
  return jsonStr;
44724
44899
  }
44900
+
44725
44901
  }
44726
44902
 
44727
44903
  /**
@@ -46827,7 +47003,6 @@ class Annotation {
46827
47003
  if($("#" + ic.pre + "anno_transmem").length) $("#" + ic.pre + "anno_transmem")[0].checked = false;
46828
47004
  }
46829
47005
  async setAnnoTabIg(bSelection, template) { let ic = this.icn3d; ic.icn3dui;
46830
-
46831
47006
  await this.updateIg(bSelection, template);
46832
47007
 
46833
47008
  $("[id^=" + ic.pre + "ig]").show();
@@ -47168,7 +47343,7 @@ class Annotation {
47168
47343
 
47169
47344
  async updateIg(bSelection, template) { let ic = this.icn3d, me = ic.icn3dui;
47170
47345
  ic.opts['color'] = 'ig strand';
47171
-
47346
+
47172
47347
  // if(!bSelection && !template) {
47173
47348
  if(!bSelection) {
47174
47349
  // select all protein chains
@@ -47187,11 +47362,13 @@ class Annotation {
47187
47362
  }
47188
47363
 
47189
47364
  ic.bRunRefnumAgain = true;
47190
- 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
47191
47368
  await ic.annoIgCls.showIg(chainid, template);
47192
47369
  ic.bRunRefnumAgain = false; // run it once for all chains
47193
47370
  }
47194
-
47371
+
47195
47372
  if(ic.bShowRefnum) {
47196
47373
  ic.hlUpdateCls.updateHlAll();
47197
47374
  ic.drawCls.draw();
@@ -48938,8 +49115,9 @@ class HlSeq {
48938
49115
  residueid = ic.ncbi2resid[residNCBI];
48939
49116
  }
48940
49117
  else if($(that).attr('3ddomain') !== undefined) {
48941
- // the position of residues with coordinates
48942
- 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];
48943
49121
  }
48944
49122
  else {
48945
49123
  residueid = chainid + '_' + (j+1).toString();
@@ -49623,7 +49801,7 @@ class LineGraph {
49623
49801
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
49624
49802
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
49625
49803
  let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
49626
- let linkedNodeCnt = {}, linkedNodeInterDiff = {};
49804
+ let linkedNodeCnt = {}, linkedNodeInterDiff = {}, linkedNodeInterDiffBool = {};
49627
49805
 
49628
49806
  for(let i = 0, il = structureArray.length; i < il; ++i) {
49629
49807
  nodeArray1Split[i] = [];
@@ -49682,13 +49860,15 @@ class LineGraph {
49682
49860
  linkedNodeInterDiff[mappingid] = link.n;
49683
49861
  }
49684
49862
  else {
49685
- ++linkedNodeCnt[mappingid];
49686
- 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;
49687
49867
  }
49688
49868
  }
49689
49869
  }
49690
49870
  }
49691
-
49871
+
49692
49872
  // do not combine with the above section since linkedNodeCnt was pre-populated above
49693
49873
  // set linkArraySplitCommon and nameHashSplitCommon
49694
49874
  // set linkArraySplitDiff and nameHashSplitDiff
@@ -49734,7 +49914,7 @@ class LineGraph {
49734
49914
  linkDiff.source += separatorDiff + ic.chainsMapping[chainid1][resid1];
49735
49915
  linkDiff.target += separatorDiff + ic.chainsMapping[chainid2][resid2];
49736
49916
 
49737
- if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiff[mappingid] == 0) {
49917
+ if(linkedNodeCnt[mappingid] == structureArray.length && linkedNodeInterDiffBool[mappingid] == 0) {
49738
49918
  linkArraySplitCommon[index].push(linkCommon);
49739
49919
  }
49740
49920
  else {
@@ -50431,18 +50611,20 @@ class GetGraph {
50431
50611
  return lineGraphStr;
50432
50612
  }
50433
50613
 
50434
- updateGraphColor() { let ic = this.icn3d, me = ic.icn3dui;
50614
+ updateGraphColor() { let ic = this.icn3d; ic.icn3dui;
50435
50615
  // change graph color
50436
50616
 
50617
+ // do not update the graph for now
50618
+ /*
50437
50619
  if(ic.graphStr !== undefined) {
50438
50620
  let graphJson = JSON.parse(ic.graphStr);
50439
- let resid2color = {};
50621
+ let resid2color = {}
50440
50622
  for(let resid in ic.residues) {
50441
50623
  let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
50442
50624
  resid2color[resid] = atom.color.getHexString().toUpperCase();
50443
50625
  }
50444
50626
 
50445
- let target2resid = {};
50627
+ let target2resid = {}
50446
50628
  for(let i = 0, il = graphJson.nodes.length; i < il; ++i) {
50447
50629
  let node = graphJson.nodes[i];
50448
50630
  //node.r: 1_1_1KQ2_A_1
@@ -50471,6 +50653,7 @@ class GetGraph {
50471
50653
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
50472
50654
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
50473
50655
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
50656
+ */
50474
50657
  }
50475
50658
 
50476
50659
  handleForce() { let ic = this.icn3d, me = ic.icn3dui;
@@ -52634,7 +52817,7 @@ class ContactMap {
52634
52817
 
52635
52818
  let graphStr = '{\n';
52636
52819
 
52637
- 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;
52638
52821
  let len1 = nodeArray1.length,
52639
52822
  len2 = nodeArray2.length;
52640
52823
  let factor = 1;
@@ -53168,6 +53351,7 @@ class ChainalignParser {
53168
53351
  let allPromise = Promise.allSettled(ajaxArray);
53169
53352
  // try {
53170
53353
  let dataArray = await allPromise;
53354
+
53171
53355
  await thisClass.downloadChainalignmentPart2b(chainresiCalphaHash2, chainidArray, hAtoms, dataArray, indexArray, mmdbid_t, struArray);
53172
53356
  // }
53173
53357
  // catch(err) {
@@ -53771,13 +53955,13 @@ class ChainalignParser {
53771
53955
  if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
53772
53956
  && align !== undefined && JSON.stringify(align).indexOf('Oops there was a problem') === -1
53773
53957
  ) {
53774
- if((align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53958
+ if((align === "error" || align === undefined || align.length == 0) && bEqualMmdbid && bEqualChain) {
53775
53959
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
53776
53960
  ic.q_trans_sub[index] = {"x":0, "y":0, "z":0};
53777
53961
  ic.q_rotation[index] = {"x1":1, "y1":0, "z1":0, "x2":0, "y2":1, "z2":0, "x3":0, "y3":0, "z3":1};
53778
53962
  ic.qt_start_end[index] = undefined;
53779
53963
  }
53780
- else if(align === undefined || align.length == 0) {
53964
+ else if(align === "error" || align === undefined || align.length == 0) {
53781
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.');
53782
53966
 
53783
53967
  ic.t_trans_add[index] = {"x":0, "y":0, "z":0};
@@ -53808,14 +53992,16 @@ class ChainalignParser {
53808
53992
  ic.qt_start_end[index] = align[0].segs;
53809
53993
 
53810
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;
53811
53997
 
53812
- let logStr = "alignment RMSD: " + rmsd.toPrecision(4);
53813
- 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;
53814
54000
  me.htmlCls.clickMenuCls.setLogCmd(logStr, false);
53815
- let html = "<br><b>Alignment RMSD</b>: " + rmsd.toPrecision(4) + " &#8491;<br>";
54001
+ let html = "<br><b>Alignment RMSD</b>: " + rmsdStr + " &#8491;<br>";
53816
54002
  if(me.cfg.aligntool == 'tmalign') {
53817
- html += "<b>TM-score</b>: " + align[0].score.toPrecision(4) + "<br><br>";
53818
- ic.tmscore = align[0].score.toPrecision(4);
54003
+ html += "<b>TM-score</b>: " + scoreStr + "<br><br>";
54004
+ ic.tmscore = scoreStr;
53819
54005
  }
53820
54006
 
53821
54007
  $("#" + ic.pre + "dl_rmsd_html").html(html);
@@ -53962,6 +54148,7 @@ class ChainalignParser {
53962
54148
  let allPromise = Promise.allSettled(ajaxArray);
53963
54149
  // try {
53964
54150
  let dataArray = await allPromise;
54151
+
53965
54152
  await thisClass.parseMMdbAfData(dataArray, structArray, bQuery, vastplusAtype);
53966
54153
  if(vastplusAtype === undefined) ic.ParserUtilsCls.hideLoading();
53967
54154
  // }
@@ -53994,13 +54181,9 @@ class ChainalignParser {
53994
54181
 
53995
54182
  //if(!ic.bCommandLoad && !bQuery) ic.init(); // remove all previously loaded data
53996
54183
 
53997
- let hAtoms = {}, hAtomsTmp = {};
54184
+ let hAtoms = {};
53998
54185
  let bLastQuery = false;
53999
54186
 
54000
- let opts = {};
54001
-
54002
- opts['color'] = (structArray.length > 1) ? 'structure' : ((structArray[0].length > 5) ? 'confidence' : 'chain');
54003
-
54004
54187
  for(let i = 0, il = structArray.length; i < il; ++i) {
54005
54188
  if(i == structArray.length - 1) bLastQuery = true;
54006
54189
 
@@ -54015,24 +54198,30 @@ class ChainalignParser {
54015
54198
  targetOrQuery = 'query';
54016
54199
  bAppend = true;
54017
54200
  }
54018
-
54201
+
54019
54202
  //if(structArray[i].length > 4) {
54020
54203
  if(isNaN(structArray[i]) && structArray[i].length > 5) { // PDB ID plus postfix could be 5
54021
54204
  //let bNoDssp = true;
54022
54205
  let bNoDssp = false; // get secondary structure info
54023
- 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);
54024
54207
  }
54025
54208
  else {
54026
54209
  let bNoSeqalign = true;
54027
54210
  let pdbid = structArray[i];
54028
- 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);
54029
54214
  }
54030
54215
 
54031
- hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
54216
+ // hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
54032
54217
  }
54033
54218
 
54034
- // add color only for the newly loaded structures
54035
- 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);
54036
54225
 
54037
54226
  await ic.ParserUtilsCls.renderStructure();
54038
54227
 
@@ -54062,15 +54251,6 @@ class ChainalignParser {
54062
54251
  if(vastplusAtype == 2) me.cfg.aligntool = 'tmalign';
54063
54252
  await ic.vastplusCls.vastplusAlign(structArray, vastplusAtype);
54064
54253
  }
54065
-
54066
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
54067
-
54068
- // if(Object.keys(ic.structures).length == 1 && me.cfg.mmdbafid.length > 5) {
54069
- // ic.ParserUtilsCls.checkMemProtein(me.cfg.mmdbafid);
54070
- // }
54071
- // else {
54072
- // /// if(ic.deferredMmdbaf !== undefined) ic.deferredMmdbaf.resolve();
54073
- // }
54074
54254
  }
54075
54255
  }
54076
54256
 
@@ -55538,24 +55718,32 @@ class MmcifParser {
55538
55718
  if(data.emd !== undefined) ic.emd = data.emd;
55539
55719
  if(data.organism !== undefined) ic.organism = data.organism;
55540
55720
 
55541
- if(ic.emd !== undefined) {
55542
- $("#" + ic.pre + "mapWrapper1").hide();
55543
- $("#" + ic.pre + "mapWrapper2").hide();
55544
- $("#" + ic.pre + "mapWrapper3").hide();
55545
- }
55546
- else {
55547
- $("#" + ic.pre + "emmapWrapper1").hide();
55548
- $("#" + ic.pre + "emmapWrapper2").hide();
55549
- $("#" + ic.pre + "emmapWrapper3").hide();
55550
- }
55551
-
55552
55721
  await ic.opmParserCls.loadOpmData(data, mmcifid, undefined, 'mmcif');
55722
+
55723
+ ic.opmParserCls.modifyUIMapAssembly();
55553
55724
  }
55554
55725
  else {
55555
- //alert('invalid atoms data.');
55556
55726
  return false;
55557
55727
  }
55558
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
+ }
55559
55747
  }
55560
55748
 
55561
55749
  /**
@@ -56398,26 +56586,26 @@ class BcifParser {
56398
56586
  let molecueType;
56399
56587
  if(atom_hetatm == "ATOM") {
56400
56588
  if(resn.length == 3) {
56401
- molecueType = "p"; // protein
56589
+ molecueType = "protein"; //"p"; // protein
56402
56590
  }
56403
56591
  else {
56404
- molecueType = "n"; // nucleotide
56592
+ molecueType = "nucleotide"; //"n"; // nucleotide
56405
56593
  }
56406
56594
  }
56407
56595
  else {
56408
56596
  if(resn == "WAT" || resn == "HOH") {
56409
- molecueType = "s"; // solvent
56597
+ molecueType = "solvent"; //"s"; // solvent
56410
56598
  chain = 'Misc';
56411
56599
  }
56412
56600
  else {
56413
- molecueType = "l"; // ligands or ions
56601
+ molecueType = "ligand"; //"l"; // ligands or ions
56414
56602
  chain = resn;
56415
56603
  }
56416
56604
  }
56417
56605
 
56418
56606
  // C-alpha only for large structure
56419
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
56420
- || (molecueType == "n" && !(name == "P")) ) ) continue;
56607
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
56608
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
56421
56609
  // skip alternative atoms
56422
56610
  if(alt == "B") continue;
56423
56611
 
@@ -56440,7 +56628,7 @@ class BcifParser {
56440
56628
  // }
56441
56629
  }
56442
56630
 
56443
- if(molecueType == 's' || molecueType == "l") {
56631
+ if(molecueType == 'solvent' || molecueType == "ligand") {
56444
56632
  let seq = {};
56445
56633
  if(!ligSeqHash.hasOwnProperty(chain)) {
56446
56634
  ligSeqHash[chain] = [];
@@ -56578,26 +56766,26 @@ class BcifParser {
56578
56766
  let molecueType;
56579
56767
  if(atom_hetatm == "ATOM") {
56580
56768
  if(resn.length == 3) {
56581
- molecueType = "p"; // protein
56769
+ molecueType = "protein"; // protein
56582
56770
  }
56583
56771
  else {
56584
- molecueType = "n"; // nucleotide
56772
+ molecueType = "nucleotide"; // nucleotide
56585
56773
  }
56586
56774
  }
56587
56775
  else {
56588
56776
  if(resn == "WAT" || resn == "HOH") {
56589
- molecueType = "s"; // solvent
56777
+ molecueType = "solvent"; // solvent
56590
56778
  chain = 'Misc';
56591
56779
  }
56592
56780
  else {
56593
- molecueType = "l"; // ligands or ions
56781
+ molecueType = "ligand"; // ligands or ions
56594
56782
  chain = resn;
56595
56783
  }
56596
56784
  }
56597
56785
 
56598
56786
  // C-alpha only for large structure
56599
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && name == 'CA'))
56600
- || (molecueType == "n" && !(name == "P")) ) ) continue;
56787
+ if(!bFull && ((molecueType == "protein" && !(elem == 'C' && name == 'CA'))
56788
+ || (molecueType == "nucleotide" && !(name == "P")) ) ) continue;
56601
56789
  // skip alternative atoms
56602
56790
  if(alt == "B") continue;
56603
56791
 
@@ -57147,6 +57335,43 @@ class OpmParser {
57147
57335
  }
57148
57336
  }
57149
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
+
57150
57375
  async parseAtomData(data, pdbid, bFull, type, pdbid2, bText) { let ic = this.icn3d, me = ic.icn3dui;
57151
57376
  /*
57152
57377
  if(type === 'mmtf') {
@@ -57163,38 +57388,7 @@ class OpmParser {
57163
57388
  ic.loadCIFCls.loadCIF(data, pdbid, bText);
57164
57389
  // }
57165
57390
 
57166
- if(ic.emd !== undefined) {
57167
- $("#" + ic.pre + "mapWrapper1").hide();
57168
- $("#" + ic.pre + "mapWrapper2").hide();
57169
- $("#" + ic.pre + "mapWrapper3").hide();
57170
- }
57171
- else {
57172
- $("#" + ic.pre + "emmapWrapper1").hide();
57173
- $("#" + ic.pre + "emmapWrapper2").hide();
57174
- $("#" + ic.pre + "emmapWrapper3").hide();
57175
- }
57176
-
57177
- if(Object.keys(ic.structures).length == 1) {
57178
- $("#" + ic.pre + "alternateWrapper").hide();
57179
- }
57180
- /*
57181
- // load assembly info
57182
- if(type === 'mmcif') {
57183
- let assembly =(data.assembly !== undefined) ? data.assembly : [];
57184
- for(let i = 0, il = assembly.length; i < il; ++i) {
57185
- if(ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
57186
-
57187
- for(let j = 0, jl = assembly[i].length; j < jl; ++j) {
57188
- ic.biomtMatrices[i].elements[j] = assembly[i][j];
57189
- }
57190
- }
57191
- }
57192
- */
57193
- if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
57194
- $("#" + ic.pre + "assemblyWrapper").show();
57195
-
57196
- ic.asuCnt = ic.biomtMatrices.length;
57197
- }
57391
+ this.modifyUIMapAssembly();
57198
57392
 
57199
57393
  ic.setStyleCls.setAtomStyleByOptions(ic.opts);
57200
57394
  ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
@@ -57388,6 +57582,12 @@ class PdbParser {
57388
57582
  }
57389
57583
  }
57390
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;
57391
57591
  // calculate secondary structures if not available
57392
57592
  // DSSP only works for structures with all atoms. The Calpha only structures didn't work
57393
57593
  //if(!ic.bSecondaryStructure && !bCalphaOnly) {
@@ -57411,8 +57611,6 @@ class PdbParser {
57411
57611
 
57412
57612
  /// if(ic.deferredOpm !== undefined) ic.deferredOpm.resolve();
57413
57613
  }
57414
-
57415
- return hAtoms;
57416
57614
  }
57417
57615
 
57418
57616
  async applyCommandDssp(bAppend) { let ic = this.icn3d, me = ic.icn3dui;
@@ -58250,23 +58448,27 @@ class RealignParser {
58250
58448
 
58251
58449
  for(let s = 0, sl = structArray.length; s < sl; ++s) {
58252
58450
  let struct1 = structArray[s];
58451
+
58253
58452
  let chainidArray1 = Object.keys(struct2domain[struct1]);
58254
58453
  if(chainidArray1.length == 0) continue;
58255
- for(let t = s+1, tl = structArray.length; t < tl; ++t) {
58256
- let struct2 = structArray[t];
58257
- let chainidArray2 = Object.keys(struct2domain[struct2]);
58258
- if(chainidArray2.length == 0) continue;
58259
-
58260
- for(let i = 0, il = chainidArray1.length; i < il; ++i) {
58261
- let chainid1 = chainidArray1[i];
58262
- let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct1][chainid1]);
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
+
58263
58465
  for(let j = 0, jl = chainidArray2.length; j < jl; ++j) {
58264
58466
  let chainid2 = chainidArray2[j];
58265
58467
 
58266
58468
  let alignAjax;
58267
58469
  if(me.cfg.aligntool != 'tmalign') {
58268
58470
  let jsonStr_q = ic.domain3dCls.getDomainJsonForAlign(struct2domain[struct2][chainid2]);
58269
-
58471
+
58270
58472
  let dataObj = {'domains1': jsonStr_q, 'domains2': jsonStr_t};
58271
58473
  alignAjax = me.getAjaxPostPromise(urlalign, dataObj);
58272
58474
  }
@@ -58291,7 +58493,14 @@ class RealignParser {
58291
58493
 
58292
58494
  let allPromise = Promise.allSettled(ajaxArray);
58293
58495
  // try {
58496
+ // let dataArray = await allPromise;
58497
+
58498
+ let startDate = new Date();
58294
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
+
58295
58504
  ic.qt_start_end = []; // reset the alignment
58296
58505
  await ic.chainalignParserCls.downloadChainalignmentPart2bRealign(dataArray, chainidPairArray, bReverse);
58297
58506
  // }
@@ -60515,6 +60724,7 @@ class LoadAtomData {
60515
60724
 
60516
60725
  //This function was used to parse atom "data" to set up parameters for the 3D viewer. "type" is mmcifid or mmdbid.
60517
60726
  //"id" is the MMDB ID or mmCIF ID.
60727
+ // thi sfunction is NOT used for mmCIF loading any more
60518
60728
  loadAtomDataIn(data, id, type, seqalign, alignType, chainidInput, chainIndex, bLastQuery, bNoSeqalign) { let ic = this.icn3d, me = ic.icn3dui;
60519
60729
  //ic.init();
60520
60730
  ic.pmin = new THREE.Vector3( 9999, 9999, 9999);
@@ -60658,13 +60868,6 @@ class LoadAtomData {
60658
60868
  if(ic.pdbid_chain2title === undefined) ic.pdbid_chain2title = {};
60659
60869
  ic.pdbid_chain2title[chainid] = data.moleculeInfor[molid].name;
60660
60870
 
60661
- //if(alignType == 'query' && chain == ic.chain_q) {
60662
- // ic.alignmolid2color[0][molid] = molidCnt.toString();
60663
- //}
60664
- //else if(alignType == 'target' && chain == ic.chain_t) {
60665
- // ic.alignmolid2color[1][molid] = molidCnt.toString();
60666
- //}
60667
-
60668
60871
  if(chain == chainid.substr(chainid.lastIndexOf('_')) ) {
60669
60872
  let tmpHash = {};
60670
60873
  tmpHash[molid] = molidCnt.toString();
@@ -60856,17 +61059,15 @@ class LoadAtomData {
60856
61059
  ic.pmin.min(atm.coord);
60857
61060
  ic.pmax.max(atm.coord);
60858
61061
  ic.psum.add(atm.coord);
60859
-
60860
- let bNonMmcif = (me.cfg.mmcifid === undefined && me.cfg.mmtfid === undefined && me.cfg.bcifid === undefined && ic.InputfileType != 'mmcif');
60861
- let bProtein = (bNonMmcif) ? chainid2kind[chainNum] === 'protein' : atm.mt === 'p';
60862
- let bNucleotide = (bNonMmcif) ? chainid2kind[chainNum] === 'nucleotide' : atm.mt === 'n';
60863
- let bSolvent = (bNonMmcif) ? chainid2kind[chainNum] === 'solvent' : atm.mt === 's';
61062
+ let bProtein = chainid2kind[chainNum] === 'protein' ;
61063
+ let bNucleotide = chainid2kind[chainNum] === 'nucleotide' ;
61064
+ let bSolvent = chainid2kind[chainNum] === 'solvent' ;
60864
61065
  // in vastplus.cgi, ions arenotlisted in alignedStructures...molecules, thus chainid2kind[chainNum] === undefined is used.
60865
61066
  // ions will be separated from chemicals later.
60866
61067
  // here "ligand" is used in the cgi output
60867
61068
  //var bChemicalIons =(me.cfg.mmcifid === undefined) ?(chainid2kind[chainNum] === 'ligand' || chainid2kind[chainNum] === 'otherPolymer' || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
60868
61069
  // kind: other, otherPolymer, etc
60869
- let bChemicalIons = (bNonMmcif) ? (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) : atm.mt === 'l';
61070
+ let bChemicalIons = (chainid2kind[chainNum] === 'ligand' ||(chainid2kind[chainNum] !== undefined && chainid2kind[chainNum].indexOf('other') !== -1) || chainid2kind[chainNum] === undefined) ;
60870
61071
 
60871
61072
  if((atm.chain === 'Misc' || chainid2kind[chainNum] === 'other') && biopolymerChainsHash[chainNum] !== 'protein' && biopolymerChainsHash[chainNum] !== 'nucleotide') { // biopolymer, could be protein or nucleotide
60872
61073
  if(atm.name === 'CA' && atm.elem === 'C') {
@@ -61130,18 +61331,17 @@ class LoadAtomData {
61130
61331
 
61131
61332
  // update bonds info
61132
61333
  if(type !== 'mmcifid') {
61133
- //for(let i in ic.atoms) {
61134
- for(let i in atoms) {
61135
- let currSerial = atomid2serial[i];
61334
+ //for(let i in ic.atoms) {
61335
+ for(let i in atoms) {
61336
+ let currSerial = atomid2serial[i];
61136
61337
 
61137
- 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;
61138
61339
 
61139
- for(let j = 0; j < bondLength; ++j) {
61140
- 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
+ }
61141
61343
  }
61142
61344
  }
61143
- }
61144
-
61145
61345
  // remove the reference
61146
61346
  data.atoms = {};
61147
61347
 
@@ -61237,7 +61437,7 @@ class LoadAtomData {
61237
61437
  // display the structure right away. load the mns and sequences later
61238
61438
  // setTimeout(function(){
61239
61439
  let hAtoms = {};
61240
-
61440
+
61241
61441
  if(type === 'align' && seqalign !== undefined && ic.bFullUi) {
61242
61442
  ic.setSeqAlignCls.setSeqAlign(seqalign, data.alignedStructures);
61243
61443
  } // if(align
@@ -61260,7 +61460,7 @@ class LoadAtomData {
61260
61460
  hAtoms = ic.hAtoms;
61261
61461
  }
61262
61462
  }
61263
- else if(type === 'mmdbid' && alignType === 'target') {
61463
+ else { //if(type === 'mmdbid' && alignType === 'target') {
61264
61464
  hAtoms = ic.hAtoms;
61265
61465
  }
61266
61466
 
@@ -61594,13 +61794,19 @@ class SetSeqAlign {
61594
61794
  resi = pos;
61595
61795
  }
61596
61796
  else {
61597
- if(ic.posid2resid) {
61598
- let resid = ic.posid2resid[chainid + '_' + pos];
61599
- resi = resid.substr(resid.lastIndexOf('_') + 1);
61600
- }
61601
- 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
+
61602
61808
  resi = ic.chainsSeq[chainid][pos].resi;
61603
- }
61809
+ // }
61604
61810
  }
61605
61811
 
61606
61812
  return resi;
@@ -63685,17 +63891,6 @@ class LoadCIF {
63685
63891
  loadCIF(bcifData, bcifid, bText, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
63686
63892
  let hAtoms = {};
63687
63893
 
63688
- // bcifData could be binary or text
63689
- let parsed = (bText) ? CIFTools.Text.parse(bcifData) : CIFTools.Binary.parse(bcifData);
63690
-
63691
- if (parsed.isError) {
63692
- // report error:
63693
- alert("The Binary CIF data can NOT be parsed: " + parsed.toString());
63694
- return;
63695
- }
63696
-
63697
- let block = parsed.result.dataBlocks[0];
63698
-
63699
63894
  let bNMR = false;
63700
63895
  // let lines = src.split('\n');
63701
63896
 
@@ -63731,92 +63926,152 @@ class LoadCIF {
63731
63926
 
63732
63927
  let bFirstAtom = true;
63733
63928
 
63734
- if(block.getCategory("_entry")) {
63735
- id = block.getCategory("_entry").getColumn("id").getString(0);
63929
+ let cifArray = bcifData.split('ENDMDL\n');
63736
63930
 
63737
- if(id == '') {
63738
- if(bAppend) {
63739
- id = ic.defaultPdbId;
63740
- }
63741
- else {
63742
- //if(!ic.inputid) ic.inputid = ic.defaultPdbId;
63743
- id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : ic.defaultPdbId; //ic.filename.substr(0, 4);
63744
- }
63745
- }
63931
+ for(let index = 0, indexl = cifArray.length; index < indexl; ++index) {
63932
+ ++moleculeNum;
63933
+ id = ic.defaultPdbId;
63746
63934
 
63747
63935
  structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63748
63936
 
63749
- ic.molTitle = '';
63750
- ic.molTitleHash = {};
63751
- }
63752
-
63753
- if(block.getCategory("_struct")) {
63754
- let title = block.getCategory("_struct").getColumn("title").getString(0);
63755
- title = title.replace(/"/, "'");
63756
- let name = title.replace(/ALPHAFOLD MONOMER V2.0 PREDICTION FOR /gi, '');
63757
- ic.molTitle += name.trim() + " ";
63758
- // if(bEsmfold && ic.esmTitle) ic.molTitle = ic.esmTitle;
63937
+ // if(!bNMR) {
63938
+ sheetArray = [];
63939
+ sheetStart = [];
63940
+ sheetEnd = [];
63941
+ helixArray = [];
63942
+ helixStart = [];
63943
+ helixEnd = [];
63759
63944
 
63760
- if(!ic.molTitleHash) ic.molTitleHash = {};
63761
- ic.molTitleHash[structure] = ic.molTitle;
63762
63945
 
63763
- }
63946
+ // bcifData could be binary or text
63947
+ let parsed = (bText) ? CIFTools.Text.parse(cifArray[index]) : CIFTools.Binary.parse(cifArray[index]);
63764
63948
 
63765
- if(block.getCategory("_entity_src_gen")) {
63766
- ic.organism = block.getCategory("_entity_src_gen").getColumn("gene_src_common_name").getString(0);
63767
- }
63768
-
63769
- if(block.getCategory("_database_2")) {
63770
- let database_2 = block.getCategory("_database_2");
63771
-
63772
- // Iterate through every row in the table
63773
- let db2Size = database_2.rowCount ;
63774
- for (let i = 0; i < db2Size; ++i) {
63775
- let db_id = database_2.getColumn("database_id").getString(0);
63776
- let db_code = database_2.getColumn("database_code").getString(0);
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];
63777
63956
 
63778
- if(db_id == "EMDB") {
63779
- ic.emd = db_code;
63780
- 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
+ }
63781
63968
  }
63969
+
63970
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63971
+
63972
+ ic.molTitle = '';
63973
+ ic.molTitleHash = {};
63782
63974
  }
63783
- }
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;
63784
63982
 
63785
- if(block.getCategory("_struct_conf")) {
63786
- ic.bSecondaryStructure = true;
63983
+ if(!ic.molTitleHash) ic.molTitleHash = {};
63984
+ ic.molTitleHash[structure] = ic.molTitle;
63787
63985
 
63788
- // Retrieve the table corresponding to the struct_conf category, which delineates mainly helix
63789
- let struct_conf = block.getCategory("_struct_conf");
63790
-
63791
- let conf_type_idArray = struct_conf.getColumn("conf_type_id");
63792
-
63793
- let chain1Array = struct_conf.getColumn("beg_auth_asym_id");
63794
- // let resi1Array = struct_conf.getColumn("beg_label_seq_id");
63795
- let resi1Array = struct_conf.getColumn("beg_auth_seq_id");
63796
-
63797
- struct_conf.getColumn("end_auth_asym_id");
63798
- // let resi2Array = struct_conf.getColumn("end_label_seq_id");
63799
- let resi2Array = struct_conf.getColumn("end_auth_seq_id");
63800
-
63801
- // Iterate through every row in the struct_conf category table, where each row delineates an interatomic connection
63802
- let confSize = struct_conf.rowCount;
63803
- for (let i = 0; i < confSize; ++i) {
63804
- let conf_type_id = conf_type_idArray.getString(i);
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
+ }
63805
63991
 
63806
- let startChain = chain1Array.getString(i);
63807
- let startResi = parseInt(resi1Array.getString(i));
63808
- let endResi = parseInt(resi2Array.getString(i));
63992
+ if(block.getCategory("_database_2")) {
63993
+ let database_2 = block.getCategory("_database_2");
63809
63994
 
63810
- if(conf_type_id.substr(0, 4) == "HELX") {
63811
- for(let j = parseInt(startResi); j <= parseInt(endResi); ++j) {
63812
- let resid = structure + "_" + startChain + "_" + j;
63813
- helixArray.push(resid);
63814
-
63815
- if(j == startResi) helixStart.push(resid);
63816
- if(j == endResi) helixEnd.push(resid);
63817
- }
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
+ }
63818
64005
  }
63819
- 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
+
63820
64075
  for(let j = startResi; j <= endResi; ++j) {
63821
64076
  let resid = structure + "_" + startChain + "_" + j;
63822
64077
  sheetArray.push(resid);
@@ -63825,500 +64080,469 @@ class LoadCIF {
63825
64080
  if(j == endResi) sheetEnd.push(resid);
63826
64081
  }
63827
64082
  }
64083
+
64084
+ chain1Array = resi1Array = resi2Array = [];
63828
64085
  }
63829
-
63830
- conf_type_idArray = chain1Array = resi1Array = resi2Array = [];
63831
- }
63832
-
63833
- if(block.getCategory("_struct_sheet_range")) {
63834
- // Retrieve the table corresponding to the struct_sheet_range category, which delineates mainly beta sheet
63835
- let struct_sheet_range = block.getCategory("_struct_sheet_range");
63836
-
63837
- let chain1Array = struct_sheet_range.getColumn("beg_auth_asym_id");
63838
- // let resi1Array = struct_sheet_range.getColumn("beg_label_seq_id");
63839
- let resi1Array = struct_sheet_range.getColumn("beg_auth_seq_id");
63840
-
63841
- struct_sheet_range.getColumn("end_auth_asym_id");
63842
- // let resi2Array = struct_sheet_range.getColumn("end_label_seq_id");
63843
- let resi2Array = struct_sheet_range.getColumn("end_auth_seq_id");
63844
-
63845
- // Iterate through every row in the struct_sheet_range category table, where each row delineates an interatomic connection
63846
- let sheetSize = struct_sheet_range.rowCount;
63847
- for (let i = 0; i < sheetSize; ++i) {
63848
- let startChain = chain1Array.getString(i);
63849
- let startResi = parseInt(resi1Array.getString(i));
63850
- let endResi = parseInt(resi2Array.getString(i));
63851
-
63852
- for(let j = startResi; j <= endResi; ++j) {
63853
- let resid = structure + "_" + startChain + "_" + j;
63854
- sheetArray.push(resid);
63855
-
63856
- if(j == startResi) sheetStart.push(resid);
63857
- if(j == endResi) sheetEnd.push(resid);
63858
- }
63859
- }
63860
-
63861
- chain1Array = resi1Array = resi2Array = [];
63862
- }
63863
64086
 
63864
- if(block.getCategory("_struct_conn")) {
63865
- ic.bSsbondProvided = true;
64087
+ if(block.getCategory("_struct_conn")) {
64088
+ ic.bSsbondProvided = true;
63866
64089
 
63867
- // Retrieve the table corresponding to the struct_conn category, which delineates connections1
63868
- let struct_conn = block.getCategory("_struct_conn");
63869
-
63870
- let conn_type_idArray = struct_conn.getColumn("conn_type_id");
63871
-
63872
- let chain1Array = struct_conn.getColumn("ptnr1_auth_asym_id");
63873
- let name1Array = struct_conn.getColumn("ptnr1_label_atom_id");
63874
- let resi1Array = struct_conn.getColumn("ptnr1_label_seq_id");
63875
-
63876
- let chain2Array = struct_conn.getColumn("ptnr2_auth_asym_id");
63877
- let name2Array = struct_conn.getColumn("ptnr2_label_atom_id");
63878
- let resi2Array = struct_conn.getColumn("ptnr2_label_seq_id");
63879
-
63880
- let connSize = struct_conn.rowCount;
63881
- for (let i = 0; i < connSize; ++i) {
63882
- let conn_type_id = conn_type_idArray.getString(i);
64090
+ // Retrieve the table corresponding to the struct_conn category, which delineates connections1
64091
+ let struct_conn = block.getCategory("_struct_conn");
63883
64092
 
63884
- let chain1 = chain1Array.getString(i);
63885
- name1Array.getString(i);
63886
- let resi1 = resi1Array.getString(i);
63887
- let id1 = structure + '_' + chain1 + "_" + resi1;
64093
+ let conn_type_idArray = struct_conn.getColumn("conn_type_id");
63888
64094
 
63889
- let chain2 = chain2Array.getString(i);
63890
- name2Array.getString(i);
63891
- let resi2 = resi2Array.getString(i);
63892
- 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");
63893
64098
 
63894
- // 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");
63895
64102
 
63896
- // if (conn_type_id == "covale") {
63897
- // vBonds.push(id1);
63898
- // vBonds.push(id2);
63899
- // }
64103
+ let connSize = struct_conn.rowCount;
64104
+ for (let i = 0; i < connSize; ++i) {
64105
+ let conn_type_id = conn_type_idArray.getString(i);
63900
64106
 
63901
- if(conn_type_id == "disulf") {
63902
- 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] = [];
63903
64126
 
63904
- ic.ssbondpnts[structure].push(id1);
63905
- ic.ssbondpnts[structure].push(id2);
64127
+ ic.ssbondpnts[structure].push(id1);
64128
+ ic.ssbondpnts[structure].push(id2);
64129
+ }
63906
64130
  }
64131
+
64132
+ conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63907
64133
  }
63908
-
63909
- conn_type_idArray = chain1Array = name1Array = resi1Array = chain2Array = name2Array = resi2Array = [];
63910
- }
63911
64134
 
63912
- if(block.getCategory("_exptl")) {
63913
- let method = block.getCategory("_exptl").getColumn("method").getString(0);
63914
- if(method.indexOf('NMR') != -1) {
63915
- 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
+ }
63916
64140
  }
63917
- }
63918
64141
 
63919
- if(block.getCategory("_pdbx_struct_oper_list")) {
63920
- // Retrieve the table corresponding to the struct_oper_list category, which delineates assembly
63921
- let struct_oper_list = block.getCategory("_pdbx_struct_oper_list");
63922
-
63923
- let struct_oper_idArray = struct_oper_list.getColumn("id");
63924
- let m11Array = struct_oper_list.getColumn("matrix[1][1]");
63925
- let m12Array = struct_oper_list.getColumn("matrix[1][2]");
63926
- let m13Array = struct_oper_list.getColumn("matrix[1][3]");
63927
- let m14Array = struct_oper_list.getColumn("vector[1]");
63928
-
63929
- let m21Array = struct_oper_list.getColumn("matrix[2][1]");
63930
- let m22Array = struct_oper_list.getColumn("matrix[2][2]");
63931
- let m23Array = struct_oper_list.getColumn("matrix[2][3]");
63932
- let m24Array = struct_oper_list.getColumn("vector[2]");
63933
-
63934
- let m31Array = struct_oper_list.getColumn("matrix[3][1]");
63935
- let m32Array = struct_oper_list.getColumn("matrix[3][2]");
63936
- let m33Array = struct_oper_list.getColumn("matrix[3][3]");
63937
- let m34Array = struct_oper_list.getColumn("vector[3]");
63938
-
63939
- let assemblySize = struct_oper_list.rowCount;
63940
- for (let i = 0; i < assemblySize; ++i) {
63941
- let struct_oper_id = struct_oper_idArray.getString(i);
63942
- if(struct_oper_id == "X0") continue;
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;
63943
64166
 
63944
- if (ic.biomtMatrices[i] == undefined) ic.biomtMatrices[i] = new THREE.Matrix4().identity();
63945
- ic.biomtMatrices[i].set(m11Array.getString(i), m12Array.getString(i), m13Array.getString(i), m14Array.getString(i),
63946
- m21Array.getString(i), m22Array.getString(i), m23Array.getString(i), m24Array.getString(i),
63947
- m31Array.getString(i), m32Array.getString(i), m33Array.getString(i), m34Array.getString(i),
63948
- 0, 0, 0, 1);
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 = [];
63949
64176
  }
63950
-
63951
- struct_oper_idArray = m11Array = m12Array = m13Array = m14Array = m21Array = m22Array = m23Array
63952
- = m24Array = m31Array = m32Array = m33Array = m34Array = [];
63953
- }
63954
64177
 
63955
- // if (record === 'ENDMDL') {
63956
- // ++moleculeNum;
63957
- // id = ic.defaultPdbId;
64178
+ // if (record === 'ENDMDL') {
64179
+ // ++moleculeNum;
64180
+ // id = ic.defaultPdbId;
63958
64181
 
63959
- // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64182
+ // structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
63960
64183
 
63961
- // //helices = [];
63962
- // //sheets = [];
63963
- // if(!bNMR) {
63964
- // sheetArray = [];
63965
- // sheetStart = [];
63966
- // sheetEnd = [];
63967
- // helixArray = [];
63968
- // helixStart = [];
63969
- // helixEnd = [];
63970
- // }
64184
+ // //helices = [];
64185
+ // //sheets = [];
64186
+ // if(!bNMR) {
64187
+ // sheetArray = [];
64188
+ // sheetStart = [];
64189
+ // sheetEnd = [];
64190
+ // helixArray = [];
64191
+ // helixStart = [];
64192
+ // helixEnd = [];
64193
+ // }
63971
64194
 
63972
- // bHeader = false; // reinitialize to read structure name from the header
63973
- // }
64195
+ // bHeader = false; // reinitialize to read structure name from the header
64196
+ // }
63974
64197
 
63975
- if(block.getCategory("_citation")) {
63976
- ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
63977
- }
64198
+ if(block.getCategory("_citation")) {
64199
+ ic.pmid = block.getCategory("_citation").getColumn("pdbx_database_id_PubMed").getString(0);
64200
+ }
63978
64201
 
63979
- // Retrieve the table corresponding to the atom_site category, which delineates atomic constituents
63980
- let atom_site = block.getCategory("_atom_site");
63981
- let atomSize = atom_site.rowCount;
63982
- // let bFull = (atomSize * 10 > ic.maxatomcnt) ? false : true;
63983
- let bFull = (atomSize > ic.maxatomcnt) ? false : true;
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;
63984
64207
 
63985
- if(!bFull) {
63986
- ic.opts['proteins'] = 'c alpha trace'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, b factor tube, lines, stick, ball and stick, sphere, nothing
63987
- ic.opts['nucleotides'] = 'o3 trace'; //nucleotide cartoon, o3 trace, schematic, lines, stick,
63988
- }
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
+ }
63989
64212
 
63990
- let atom_hetatmArray = atom_site.getColumn("group_PDB");
63991
- let resnArray = atom_site.getColumn("label_comp_id");
63992
- let elemArray = atom_site.getColumn("type_symbol");
63993
- let nameArray = atom_site.getColumn("label_atom_id");
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");
63994
64217
 
63995
- let chainArray = atom_site.getColumn("auth_asym_id");
64218
+ let chainArray = atom_site.getColumn("auth_asym_id");
63996
64219
 
63997
- let resiArray = atom_site.getColumn("label_seq_id");
63998
- let resiOriArray = atom_site.getColumn("auth_seq_id");
63999
- let altArray = atom_site.getColumn("label_alt_id");
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");
64000
64223
 
64001
- let bArray = atom_site.getColumn("B_iso_or_equiv");
64224
+ let bArray = atom_site.getColumn("B_iso_or_equiv");
64002
64225
 
64003
- let xArray = atom_site.getColumn("Cartn_x");
64004
- let yArray = atom_site.getColumn("Cartn_y");
64005
- 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");
64006
64229
 
64007
- let autochainArray = atom_site.getColumn("label_asym_id");
64230
+ let autochainArray = atom_site.getColumn("label_asym_id");
64008
64231
 
64009
- // get the bond info
64010
- let ligSeqHash = {}, prevAutochain = '';
64011
- let prevResn;
64012
- let sChain = {};
64013
- for (let i = 0; i < atomSize; ++i) {
64014
- let atom_hetatm = atom_hetatmArray.getString(i);
64015
- let resn = resnArray.getString(i);
64016
- let elem = elemArray.getString(i);
64017
- let atom = nameArray.getString(i);
64018
- let chain = chainArray.getString(i);
64019
- let resi = resiArray.getString(i);
64020
- let oriResi = resiOriArray.getString(i);
64021
- let alt = altArray.getString(i);
64022
- let bFactor = bArray.getString(i);
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);
64023
64246
 
64024
- let autochain = autochainArray.getString(i);
64247
+ let autochain = autochainArray.getString(i);
64025
64248
 
64026
64249
 
64027
- resi = oriResi;
64250
+ resi = oriResi;
64028
64251
 
64029
- let molecueType;
64030
- if(atom_hetatm == "ATOM") {
64031
- if(resn.length == 3) {
64032
- molecueType = "p"; // protein
64033
- }
64034
- else {
64035
- molecueType = "n"; // nucleotide
64036
- }
64037
- }
64038
- else {
64039
- if(resn == "WAT" || resn == "HOH") {
64040
- molecueType = "s"; // solvent
64041
- chain = 'Misc';
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
+ }
64042
64260
  }
64043
64261
  else {
64044
- molecueType = "l"; // ligands or ions
64045
- 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
+ }
64046
64270
  }
64047
- }
64048
- if(chain === '') chain = 'A';
64049
-
64050
- // C-alpha only for large structure
64051
- if(!bFull && ((molecueType == "p" && !(elem == 'C' && atom == 'CA')) || (molecueType == "n" && !(atom == "P")) ) ) continue;
64052
-
64053
- // skip alternative atoms
64054
- if(alt == "B") continue;
64055
-
64056
- sChain[chain] = 1;
64271
+ if(chain === '') chain = 'A';
64057
64272
 
64058
- if(bFirstAtom) {
64059
- 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;
64060
64278
 
64061
- bFirstAtom = false;
64062
- }
64279
+ sChain[chain] = 1;
64063
64280
 
64064
- // "CA" has to appear before "O". Otherwise the cartoon of secondary structure will have breaks
64065
- // Concatenation of two pdbs will have several atoms for the same serial
64066
- ++serial;
64281
+ if(bFirstAtom) {
64282
+ structure = ic.loadPDBCls.getStructureId(id, moleculeNum);
64067
64283
 
64068
- // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
64069
- // bModifyResi = true;
64070
- // }
64284
+ bFirstAtom = false;
64285
+ }
64071
64286
 
64072
- if(resi == "?" || resi == "." || resi == "0") {
64073
- 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;
64074
64290
 
64075
- // if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64076
- // if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64077
- // resi = (++tmpResi).toString();
64078
- // }
64079
- // }
64080
- // else {
64081
- // if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64082
- // resi = (++tmpResi).toString();
64083
- // }
64084
- // else {
64085
- // resi = (tmpResi).toString();
64086
- // }
64291
+ // if(oriResi != resi || bModifyResi) { // e.g., 99A and 99
64292
+ // bModifyResi = true;
64087
64293
  // }
64088
- }
64089
64294
 
64090
- if(molecueType == 's' || molecueType == "l") {
64091
- let seq = {};
64092
- if(!ligSeqHash.hasOwnProperty(chain)) {
64093
- 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
+ // }
64094
64311
  }
64095
64312
 
64096
- if(resn.length != 3 || resn == "HOH" || resn == "WAT") {
64097
- if(resn.length != 3 || (elem == 'O' && (resn == "HOH" || resn == "WAT"))) {
64098
- seq.resi = resi;
64099
- seq.name = me.utilsCls.residueName2Abbr(resn);
64100
- ligSeqHash[chain].push(seq);
64313
+ if(molecueType == 'solvent' || molecueType == "ligand") {
64314
+ let seq = {};
64315
+ if(!ligSeqHash.hasOwnProperty(chain)) {
64316
+ ligSeqHash[chain] = [];
64101
64317
  }
64102
- }
64103
- else {
64104
- if(chain + "_" + resn != prevResn || prevAutochain != autochain) {
64105
- seq.resi = resi;
64106
- seq.name = me.utilsCls.residueName2Abbr(resn);
64107
- ligSeqHash[chain].push(seq);
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
+ }
64108
64332
  }
64109
64333
  }
64110
- }
64111
64334
 
64112
- // if(bOpm && resn === 'DUM') {
64113
- // elem = atom;
64114
- // chain = 'MEM';
64115
- // resi = 1;
64116
- // oriResi = 1;
64117
- // }
64335
+ // if(bOpm && resn === 'DUM') {
64336
+ // elem = atom;
64337
+ // chain = 'MEM';
64338
+ // resi = 1;
64339
+ // oriResi = 1;
64340
+ // }
64118
64341
 
64119
- // 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
64120
64343
 
64121
- chainNum = structure + "_" + chain;
64122
- oriResidueNum = chainNum + "_" + oriResi;
64344
+ chainNum = structure + "_" + chain;
64345
+ oriResidueNum = chainNum + "_" + oriResi;
64123
64346
 
64124
- residueNum = chainNum + "_" + resi;
64347
+ residueNum = chainNum + "_" + resi;
64125
64348
 
64126
- //let chain_resi = chain + "_" + resi;
64349
+ //let chain_resi = chain + "_" + resi;
64127
64350
 
64128
- let x = xArray.getFloat(i);
64129
- let y = yArray.getFloat(i);
64130
- let z = zArray.getFloat(i);
64131
- let coord = new THREE.Vector3(x, y, z);
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);
64132
64355
 
64133
- let atomDetails = {
64134
- het: (atom_hetatm == "HETATM"), // optional, used to determine chemicals, water, ions, etc
64135
- serial: serial, // required, unique atom id
64136
- name: atom, // required, atom name
64137
- alt: alt, // optional, some alternative coordinates
64138
- resn: resn, // optional, used to determine protein or nucleotide
64139
- structure: structure, // optional, used to identify structure
64140
- chain: chain, // optional, used to identify chain
64141
- resi: resi, // optional, used to identify residue ID
64142
- //insc: line.substr(26, 1),
64143
- coord: coord, // required, used to draw 3D shape
64144
- b: bFactor, // optional, used to draw B-factor tube
64145
- elem: elem, // optional, used to determine hydrogen bond
64146
- bonds: [], // required, used to connect atoms
64147
- ss: 'coil', // optional, used to show secondary structures
64148
- ssbegin: false, // optional, used to show the beginning of secondary structures
64149
- ssend: false // optional, used to show the end of secondary structures
64150
- };
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
+ };
64151
64374
 
64152
- if(!atomDetails.het && atomDetails.name === 'C') ;
64153
- if(!atomDetails.het && atomDetails.name === 'O') ;
64375
+ if(!atomDetails.het && atomDetails.name === 'C') ;
64376
+ if(!atomDetails.het && atomDetails.name === 'O') ;
64154
64377
 
64155
- // from DSSP C++ code
64156
- // if(!atomDetails.het && atomDetails.name === 'N' && prevCSerial !== undefined && prevOSerial !== undefined) {
64157
- // let dist = ic.atoms[prevCSerial].coord.distanceTo(ic.atoms[prevOSerial].coord);
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);
64158
64381
 
64159
- // let x2 = atomDetails.coord.x + (ic.atoms[prevCSerial].coord.x - ic.atoms[prevOSerial].coord.x) / dist;
64160
- // let y2 = atomDetails.coord.y + (ic.atoms[prevCSerial].coord.y - ic.atoms[prevOSerial].coord.y) / dist;
64161
- // let z2 = atomDetails.coord.z + (ic.atoms[prevCSerial].coord.z - ic.atoms[prevOSerial].coord.z) / dist;
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;
64162
64385
 
64163
- // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
64164
- // }
64386
+ // atomDetails.hcoord = new THREE.Vector3(x2, y2, z2);
64387
+ // }
64165
64388
 
64166
- ic.atoms[serial] = atomDetails;
64389
+ ic.atoms[serial] = atomDetails;
64167
64390
 
64168
- ic.dAtoms[serial] = 1;
64169
- ic.hAtoms[serial] = 1;
64170
- hAtoms[serial] = 1;
64391
+ ic.dAtoms[serial] = 1;
64392
+ ic.hAtoms[serial] = 1;
64393
+ hAtoms[serial] = 1;
64171
64394
 
64172
- // Assign secondary structures from the input
64173
- // if a residue is assigned both sheet and helix, it is assigned as sheet
64174
- if(ic.loadPDBCls.isSecondary(residueNum, sheetArray, bNMR, !bFull)) {
64175
- ic.atoms[serial].ss = 'sheet';
64176
- if(ic.loadPDBCls.isSecondary(residueNum, sheetStart, bNMR, !bFull)) {
64177
- ic.atoms[serial].ssbegin = true;
64178
- }
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
+ }
64179
64402
 
64180
- // do not use else if. Some residues are both start and end of secondary structure
64181
- if(ic.loadPDBCls.isSecondary(residueNum, sheetEnd, bNMR, !bFull)) {
64182
- ic.atoms[serial].ssend = true;
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
+ }
64183
64407
  }
64184
- }
64185
- else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
64186
- ic.atoms[serial].ss = 'helix';
64408
+ else if(ic.loadPDBCls.isSecondary(residueNum, helixArray, bNMR, !bFull)) {
64409
+ ic.atoms[serial].ss = 'helix';
64410
+
64411
+ if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
64412
+ ic.atoms[serial].ssbegin = true;
64413
+ }
64187
64414
 
64188
- if(ic.loadPDBCls.isSecondary(residueNum, helixStart, bNMR, !bFull)) {
64189
- ic.atoms[serial].ssbegin = true;
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
+ }
64190
64419
  }
64191
64420
 
64192
- // do not use else if. Some residues are both start and end of secondary structure
64193
- if(ic.loadPDBCls.isSecondary(residueNum, helixEnd, bNMR, !bFull)) {
64194
- ic.atoms[serial].ssend = true;
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';
64195
64436
  }
64196
- }
64197
64437
 
64198
- let secondaries = '-';
64199
- if(ic.atoms[serial].ss === 'helix') {
64200
- secondaries = 'H';
64201
- }
64202
- else if(ic.atoms[serial].ss === 'sheet') {
64203
- secondaries = 'E';
64204
- }
64205
- //else if(ic.atoms[serial].ss === 'coil') {
64206
- // secondaries = 'c';
64207
- //}
64208
- else if(!ic.atoms[serial].het && me.parasCls.residueColors.hasOwnProperty(ic.atoms[serial].resn.toUpperCase()) ) {
64209
- secondaries = 'c';
64210
- }
64211
- else {
64212
- secondaries = 'o';
64213
- }
64438
+ ic.secondaries[residueNum] = secondaries;
64214
64439
 
64215
- 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;
64216
64448
 
64217
- // different residue
64218
- //if(residueNum !== prevResidueNum) {
64219
-
64220
- // if(oriResidueNum !== prevOriResidueNum) {
64221
- if(oriResidueNum !== prevOriResidueNum || chain + "_" + resn != prevResn || prevAutochain != autochain) {
64222
- let residue = me.utilsCls.residueName2Abbr(resn);
64223
-
64224
- ic.residueId2Name[residueNum] = residue;
64449
+ if(serial !== 1 && prevResidueNum !== '') {
64450
+ ic.residues[prevResidueNum] = residuesTmp;
64451
+ }
64225
64452
 
64226
- if(serial !== 1 && prevResidueNum !== '') {
64227
- ic.residues[prevResidueNum] = residuesTmp;
64228
- }
64453
+ if(residueNum !== prevResidueNum) {
64454
+ residuesTmp = {};
64455
+ }
64229
64456
 
64230
- if(residueNum !== prevResidueNum) {
64231
- residuesTmp = {};
64232
- }
64457
+ // different chain
64458
+ if(chainNum !== prevChainNum) {
64233
64459
 
64234
- // different chain
64235
- 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
+ }
64236
64465
 
64237
- // a chain could be separated in two sections
64238
- if(serial !== 1 && prevChainNum !== '') {
64239
- if(ic.chains[prevChainNum] === undefined) ic.chains[prevChainNum] = {};
64240
- ic.chains[prevChainNum] = me.hashUtilsCls.unionHash(ic.chains[prevChainNum], chainsTmp);
64241
- }
64466
+ chainsTmp = {};
64467
+
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);
64242
64470
 
64243
- chainsTmp = {};
64471
+ if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
64244
64472
 
64245
- if(ic.structures[structure.toString()] === undefined) ic.structures[structure.toString()] = [];
64246
- if(!ic.structures[structure.toString()].includes(chainNum)) ic.structures[structure.toString()].push(chainNum);
64473
+ let resObject = {};
64474
+ resObject.resi = resi;
64475
+ resObject.name = residue;
64247
64476
 
64248
- if(ic.chainsSeq[chainNum] === undefined) ic.chainsSeq[chainNum] = [];
64477
+ ic.chainsSeq[chainNum].push(resObject);
64478
+ }
64479
+ else {
64249
64480
 
64250
- let resObject = {};
64251
- resObject.resi = resi;
64252
- resObject.name = residue;
64481
+ let resObject = {};
64482
+ resObject.resi = resi;
64483
+ resObject.name = residue;
64253
64484
 
64254
- ic.chainsSeq[chainNum].push(resObject);
64485
+ ic.chainsSeq[chainNum].push(resObject);
64486
+ }
64255
64487
  }
64256
- else {
64257
64488
 
64258
- let resObject = {};
64259
- resObject.resi = resi;
64260
- resObject.name = residue;
64489
+ chainsTmp[serial] = 1;
64490
+ residuesTmp[serial] = 1;
64261
64491
 
64262
- ic.chainsSeq[chainNum].push(resObject);
64263
- }
64264
- }
64492
+ prevChainNum = chainNum;
64493
+ prevResidueNum = residueNum;
64494
+ prevOriResidueNum = oriResidueNum;
64265
64495
 
64266
- chainsTmp[serial] = 1;
64267
- residuesTmp[serial] = 1;
64496
+ prevResn = chain + "_" + resn;
64497
+ prevAutochain = autochain;
64498
+ }
64268
64499
 
64269
- prevChainNum = chainNum;
64270
- prevResidueNum = residueNum;
64271
- 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);
64272
64504
 
64273
- prevResn = chain + "_" + resn;
64274
- prevAutochain = autochain;
64275
- }
64505
+ // clear memory
64506
+ atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
64507
+ = altArray = bArray = xArray = yArray = zArray = autochainArray = [];
64276
64508
 
64277
- // add the last residue set
64278
- ic.residues[residueNum] = residuesTmp;
64279
- if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
64280
- ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
64509
+ let mChainSeq = {};
64510
+ if(block.getCategory("_pdbx_poly_seq_scheme")) {
64511
+ let poly_seq_scheme = block.getCategory("_pdbx_poly_seq_scheme");
64281
64512
 
64282
- // clear memory
64283
- atom_hetatmArray = resnArray = elemArray = nameArray = chainArray = resiArray = resiOriArray
64284
- = 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");
64285
64517
 
64286
- let mChainSeq = {};
64287
- if(block.getCategory("_pdbx_poly_seq_scheme")) {
64288
- 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);
64289
64526
 
64290
- let resiArray = poly_seq_scheme.getColumn("seq_id");
64291
- let oriResiArray = poly_seq_scheme.getColumn("pdb_seq_num");
64292
- let resnArray = poly_seq_scheme.getColumn("mon_id");
64293
- let chainArray = poly_seq_scheme.getColumn("pdb_strand_id");
64527
+ if(chain != prevChain && i > 0) {
64528
+ mChainSeq[prevChain] = seqArray;
64294
64529
 
64295
- let seqSize = poly_seq_scheme.rowCount;
64296
- let prevChain = "";
64297
- let seqArray = [];
64298
- for (let i = 0; i < seqSize; ++i) {
64299
- resiArray.getString(i);
64300
- let oriResi = oriResiArray.getString(i);
64301
- let resn = resnArray.getString(i);
64302
- let chain = chainArray.getString(i);
64530
+ seqArray = [];
64531
+ }
64303
64532
 
64304
- if(chain != prevChain && i > 0) {
64305
- mChainSeq[prevChain] = seqArray;
64533
+ // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
64534
+ seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
64306
64535
 
64307
- seqArray = [];
64536
+ prevChain = chain;
64308
64537
  }
64309
64538
 
64310
- // seqArray.push({"resi": resi, "name": me.utilsCls.residueName2Abbr(resn)});
64311
- seqArray.push({"resi": oriResi, "name": me.utilsCls.residueName2Abbr(resn)});
64539
+ mChainSeq[prevChain] = seqArray;
64312
64540
 
64313
- prevChain = chain;
64541
+ resiArray = oriResiArray = resnArray = chainArray = [];
64314
64542
  }
64315
-
64316
- mChainSeq[prevChain] = seqArray;
64317
-
64318
- resiArray = oriResiArray = resnArray = chainArray = [];
64543
+
64544
+ this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
64319
64545
  }
64320
-
64321
- this.setSeq(structure, sChain, mChainSeq, ligSeqHash);
64322
64546
 
64323
64547
  // copy disulfide bonds
64324
64548
  let structureArray = Object.keys(ic.structures);
@@ -70225,6 +70449,34 @@ class Resid2spec {
70225
70449
  return spec;
70226
70450
  }
70227
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
+
70228
70480
  atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
70229
70481
  let spec = "";
70230
70482
  let i = 0;
@@ -71687,8 +71939,6 @@ class Dssp {
71687
71939
  bNoMoreIg = false;
71688
71940
 
71689
71941
  let pdb_target = ic.saveFileCls.getAtomPDB(domainAtomsArray[k], undefined, undefined, undefined, undefined, struct);
71690
- //let bForceOneDomain = true;
71691
- //let jsonStr_t = ic.domain3dCls.getDomainJsonForAlign(domainAtomsArray[k], bForceOneDomain);
71692
71942
 
71693
71943
  // ig strand for any subset will have the same k, use the number of residue to separate them
71694
71944
  let atomFirst = ic.firstAtomObjCls.getFirstAtomObj(domainAtomsArray[k]);
@@ -71848,20 +72098,24 @@ class Dssp {
71848
72098
  // assign ref numbers to selected residues
71849
72099
  let result = ic.domain3dCls.c2b_NewSplitChain(currAtoms, undefined);
71850
72100
  let subdomains = result.subdomains;
71851
- let pos2resi = result.pos2resi;
72101
+ // let pos2resi = result.pos2resi;
71852
72102
 
71853
72103
  if(subdomains.length >= 1) {
71854
72104
  for(let k = 0, kl = subdomains.length; k < kl; ++k) {
71855
72105
  let domainAtoms = {};
71856
72106
  let segArray = subdomains[k];
71857
72107
 
71858
- let resCnt = 0;
72108
+ let resCnt = 0; // minResi = 999, maxResi = -999;
71859
72109
  for(let m = 0, ml = segArray.length; m < ml; m += 2) {
71860
72110
  let startResi = parseInt(segArray[m]);
71861
72111
  let endResi = parseInt(segArray[m+1]);
71862
72112
 
72113
+ // if(startResi < minResi) minResi = startResi;
72114
+ // if(endResi > maxResi) maxResi = endResi;
72115
+
71863
72116
  for(let n = startResi; n <= endResi; ++n) {
71864
- let resid = chainid + '_' + pos2resi[n - 1];
72117
+ // let resid = chainid + '_' + pos2resi[n - 1];
72118
+ let resid = ic.ncbi2resid[chainid + '_' + n];
71865
72119
  ++resCnt;
71866
72120
  domainAtoms = me.hashUtilsCls.unionHash(domainAtoms, ic.residues[resid]);
71867
72121
 
@@ -71877,6 +72131,9 @@ class Dssp {
71877
72131
  domainAtomsArray.push(domainAtoms);
71878
72132
  }
71879
72133
  }
72134
+ // else { // no domain
72135
+ // domainAtomsArray = [currAtoms];
72136
+ // }
71880
72137
 
71881
72138
  return domainAtomsArray;
71882
72139
  }
@@ -72000,8 +72257,6 @@ class Dssp {
72000
72257
  if(bBstrand && bCstrand && bEstrand && bFstrand) break;
72001
72258
  }
72002
72259
 
72003
- console.log("### " + bBstrand + bCstrand + bEstrand + bFstrand);
72004
-
72005
72260
  // if(refpdbname != 'CD19_6al5A_human-n1') { // relax for CD19
72006
72261
  if(!(bBstrand && bCstrand && bEstrand && bFstrand) || !(bBSheet && bCSheet && bESheet && bFSheet)) {
72007
72262
  // if(!(bBstrand && bCstrand && bEstrand && bFstrand)) {
@@ -81434,7 +81689,7 @@ class iCn3DUI {
81434
81689
  //even when multiple iCn3D viewers are shown together.
81435
81690
  this.pre = this.cfg.divid + "_";
81436
81691
 
81437
- this.REVISION = '3.31.4';
81692
+ this.REVISION = '3.32.0';
81438
81693
 
81439
81694
  // In nodejs, iCn3D defines "window = {navigator: {}}"
81440
81695
  this.bNode = (Object.keys(window).length < 2) ? true : false;