icn3d 3.8.3 → 3.9.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.
- package/icn3d.js +1246 -80
- package/package.json +1 -1
package/icn3d.js
CHANGED
|
@@ -7460,7 +7460,15 @@ class Strand {
|
|
|
7460
7460
|
}
|
|
7461
7461
|
|
|
7462
7462
|
let maxDist = 6.0;
|
|
7463
|
-
let bBrokenSs = (prevCoorCA && Math.abs(currentCA.x - prevCoorCA.x) > maxDist) || (prevCoorCA && Math.abs(currentCA.y - prevCoorCA.y) > maxDist) || (prevCoorCA && Math.abs(currentCA.z - prevCoorCA.z) > maxDist);
|
|
7463
|
+
//let bBrokenSs = (prevCoorCA && Math.abs(currentCA.x - prevCoorCA.x) > maxDist) || (prevCoorCA && Math.abs(currentCA.y - prevCoorCA.y) > maxDist) || (prevCoorCA && Math.abs(currentCA.z - prevCoorCA.z) > maxDist);
|
|
7464
|
+
let bBrokenSs = !atoms.hasOwnProperty(atom.serial) || (prevCoorCA && Math.abs(currentCA.x - prevCoorCA.x) > maxDist) || (prevCoorCA && Math.abs(currentCA.y - prevCoorCA.y) > maxDist) || (prevCoorCA && Math.abs(currentCA.z - prevCoorCA.z) > maxDist);
|
|
7465
|
+
|
|
7466
|
+
if(bBrokenSs && atom.ss === 'sheet') {
|
|
7467
|
+
bSheetSegment = true;
|
|
7468
|
+
}
|
|
7469
|
+
else if(bBrokenSs && atom.ss === 'helix') {
|
|
7470
|
+
bHelixSegment = true;
|
|
7471
|
+
}
|
|
7464
7472
|
|
|
7465
7473
|
if ((atom.ssbegin || atom.ssend || (drawnResidueCount === totalResidueCount - 1) || bBrokenSs) && pnts[0].length > 0 && bSameChain) {
|
|
7466
7474
|
let atomName = 'CA';
|
|
@@ -11461,17 +11469,32 @@ class Surface {
|
|
|
11461
11469
|
//vertexColors.push(ic.atoms[verts[vb].atomid].color);
|
|
11462
11470
|
//vertexColors.push(ic.atoms[verts[vc].atomid].color);
|
|
11463
11471
|
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11472
|
+
if(type == 21 || type == 22 || type == 23) { // potential on surface
|
|
11473
|
+
colorArray[offset2++] = verts[va].color.r;
|
|
11474
|
+
colorArray[offset2++] = verts[va].color.g;
|
|
11475
|
+
colorArray[offset2++] = verts[va].color.b;
|
|
11467
11476
|
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11477
|
+
colorArray[offset2++] = verts[vb].color.r;
|
|
11478
|
+
colorArray[offset2++] = verts[vb].color.g;
|
|
11479
|
+
colorArray[offset2++] = verts[vb].color.b;
|
|
11471
11480
|
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11481
|
+
colorArray[offset2++] = verts[vc].color.r;
|
|
11482
|
+
colorArray[offset2++] = verts[vc].color.g;
|
|
11483
|
+
colorArray[offset2++] = verts[vc].color.b;
|
|
11484
|
+
}
|
|
11485
|
+
else {
|
|
11486
|
+
colorArray[offset2++] = ic.atoms[verts[va].atomid].color.r;
|
|
11487
|
+
colorArray[offset2++] = ic.atoms[verts[va].atomid].color.g;
|
|
11488
|
+
colorArray[offset2++] = ic.atoms[verts[va].atomid].color.b;
|
|
11489
|
+
|
|
11490
|
+
colorArray[offset2++] = ic.atoms[verts[vb].atomid].color.r;
|
|
11491
|
+
colorArray[offset2++] = ic.atoms[verts[vb].atomid].color.g;
|
|
11492
|
+
colorArray[offset2++] = ic.atoms[verts[vb].atomid].color.b;
|
|
11493
|
+
|
|
11494
|
+
colorArray[offset2++] = ic.atoms[verts[vc].atomid].color.r;
|
|
11495
|
+
colorArray[offset2++] = ic.atoms[verts[vc].atomid].color.g;
|
|
11496
|
+
colorArray[offset2++] = ic.atoms[verts[vc].atomid].color.b;
|
|
11497
|
+
}
|
|
11475
11498
|
|
|
11476
11499
|
//var normals = [];
|
|
11477
11500
|
//normals.push(normalArrayIn[va]);
|
|
@@ -11723,7 +11746,7 @@ class ShareLink {
|
|
|
11723
11746
|
|
|
11724
11747
|
if(!bPngHtml) {
|
|
11725
11748
|
if(ic.bInputfile && !ic.bInputUrlfile) {
|
|
11726
|
-
var aaa = 1; //alert("Share Link does NOT work when the data
|
|
11749
|
+
var aaa = 1; //alert("Share Link does NOT work when the data are from custom files. Please save 'iCn3D PNG Image' in the File menu and open it in iCn3D.");
|
|
11727
11750
|
return;
|
|
11728
11751
|
}
|
|
11729
11752
|
if(bTooLong) {
|
|
@@ -15589,6 +15612,7 @@ class GetGraph {
|
|
|
15589
15612
|
let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
|
|
15590
15613
|
resid2color[resid] = atom.color.getHexString().toUpperCase();
|
|
15591
15614
|
}
|
|
15615
|
+
|
|
15592
15616
|
let target2resid = {};
|
|
15593
15617
|
for(let i = 0, il = graphJson.nodes.length; i < il; ++i) {
|
|
15594
15618
|
let node = graphJson.nodes[i];
|
|
@@ -15615,11 +15639,9 @@ class GetGraph {
|
|
|
15615
15639
|
ic.graphStr = JSON.stringify(graphJson);
|
|
15616
15640
|
}
|
|
15617
15641
|
|
|
15618
|
-
/*
|
|
15619
15642
|
if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
|
|
15620
15643
|
if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
|
|
15621
15644
|
if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
|
|
15622
|
-
*/
|
|
15623
15645
|
}
|
|
15624
15646
|
|
|
15625
15647
|
handleForce() { let ic = this.icn3d, me = ic.icn3dui;
|
|
@@ -26491,9 +26513,10 @@ class LoadScript {
|
|
|
26491
26513
|
let strArray = ic.commands[i].split("|||");
|
|
26492
26514
|
|
|
26493
26515
|
if(Object.keys(ic.proteins).length > 0 && ic.mmdb_data === undefined &&(ic.bAjax3ddomain === undefined || !ic.bAjax3ddomain)) {
|
|
26494
|
-
|
|
26495
|
-
|
|
26496
|
-
|
|
26516
|
+
//$.when(thisClass.applyCommand3ddomain(strArray[0].trim())).then(function() {
|
|
26517
|
+
thisClass.applyCommand3ddomain(strArray[0].trim());
|
|
26518
|
+
thisClass.execCommandsBase(i + 1, end, steps);
|
|
26519
|
+
//});
|
|
26497
26520
|
}
|
|
26498
26521
|
else {
|
|
26499
26522
|
if(Object.keys(ic.proteins).length > 0) {
|
|
@@ -26515,8 +26538,9 @@ class LoadScript {
|
|
|
26515
26538
|
&&(ic.bAjax3ddomain === undefined || !ic.bAjax3ddomain || ic.mmdb_data === undefined) ) {
|
|
26516
26539
|
$.when(thisClass.applyCommandClinvar(strArray[0].trim()))
|
|
26517
26540
|
.then(thisClass.applyCommandSnp(strArray[0].trim()))
|
|
26518
|
-
|
|
26541
|
+
//.then(thisClass.applyCommand3ddomain(strArray[0].trim()))
|
|
26519
26542
|
.then(function() {
|
|
26543
|
+
thisClass.applyCommand3ddomain(strArray[0].trim());
|
|
26520
26544
|
ic.annotationCls.setAnnoTabAll();
|
|
26521
26545
|
|
|
26522
26546
|
thisClass.execCommandsBase(i + 1, end, steps);
|
|
@@ -26535,8 +26559,9 @@ class LoadScript {
|
|
|
26535
26559
|
else if(Object.keys(ic.proteins).length > 0 &&(ic.bAjaxClinvar === undefined || !ic.bAjaxClinvar)
|
|
26536
26560
|
&&(ic.bAjax3ddomain === undefined || !ic.bAjax3ddomain || ic.mmdb_data === undefined)) {
|
|
26537
26561
|
$.when(thisClass.applyCommandClinvar(strArray[0].trim()))
|
|
26538
|
-
|
|
26562
|
+
//.then(thisClass.applyCommand3ddomain(strArray[0].trim()))
|
|
26539
26563
|
.then(function() {
|
|
26564
|
+
thisClass.applyCommand3ddomain(strArray[0].trim());
|
|
26540
26565
|
ic.annotationCls.setAnnoTabAll();
|
|
26541
26566
|
|
|
26542
26567
|
thisClass.execCommandsBase(i + 1, end, steps);
|
|
@@ -26544,10 +26569,11 @@ class LoadScript {
|
|
|
26544
26569
|
}
|
|
26545
26570
|
else if(Object.keys(ic.proteins).length > 0 &&(ic.bAjax3ddomain === undefined || !ic.bAjax3ddomain || ic.mmdb_data === undefined)
|
|
26546
26571
|
&&(ic.bAjaxSnp === undefined || !ic.bAjaxSnp)) {
|
|
26547
|
-
|
|
26548
|
-
|
|
26572
|
+
//$.when(thisClass.applyCommand3ddomain(strArray[0].trim()))
|
|
26573
|
+
$.when(thisClass.applyCommandSnp(strArray[0].trim()))
|
|
26549
26574
|
.then(function() {
|
|
26550
|
-
|
|
26575
|
+
thisClass.applyCommand3ddomain(strArray[0].trim());
|
|
26576
|
+
ic.annotationCls.setAnnoTabAll();
|
|
26551
26577
|
|
|
26552
26578
|
thisClass.execCommandsBase(i + 1, end, steps);
|
|
26553
26579
|
});
|
|
@@ -26569,12 +26595,14 @@ class LoadScript {
|
|
|
26569
26595
|
});
|
|
26570
26596
|
}
|
|
26571
26597
|
else if(Object.keys(ic.proteins).length > 0 &&(ic.bAjax3ddomain === undefined || !ic.bAjax3ddomain || ic.mmdb_data === undefined) ) {
|
|
26572
|
-
|
|
26573
|
-
|
|
26598
|
+
//$.when(thisClass.applyCommand3ddomain(strArray[0].trim()))
|
|
26599
|
+
// .then(function() {
|
|
26600
|
+
thisClass.applyCommand3ddomain(strArray[0].trim());
|
|
26601
|
+
|
|
26574
26602
|
ic.annotationCls.setAnnoTabAll();
|
|
26575
26603
|
|
|
26576
26604
|
thisClass.execCommandsBase(i + 1, end, steps);
|
|
26577
|
-
});
|
|
26605
|
+
//});
|
|
26578
26606
|
}
|
|
26579
26607
|
else {
|
|
26580
26608
|
if(Object.keys(ic.proteins).length > 0) {
|
|
@@ -26841,12 +26869,13 @@ class LoadScript {
|
|
|
26841
26869
|
thisClass.applyCommand3ddomain(lastCommand);
|
|
26842
26870
|
}
|
|
26843
26871
|
else if(lastCommand.indexOf('set annotation all') == 0) {
|
|
26844
|
-
//$.when(thisClass.applyCommandAnnotationsAndCddSite(lastCommand))
|
|
26845
|
-
// .then(thisClass.applyCommandSnpClinvar(lastCommand))
|
|
26846
26872
|
$.when(thisClass.applyCommandClinvar(lastCommand))
|
|
26847
26873
|
.then(thisClass.applyCommandSnp(lastCommand))
|
|
26848
|
-
|
|
26849
|
-
|
|
26874
|
+
//.then(thisClass.applyCommand3ddomain(lastCommand));
|
|
26875
|
+
.then(function() {
|
|
26876
|
+
thisClass.applyCommand3ddomain(lastCommand);
|
|
26877
|
+
ic.annotationCls.setAnnoTabAll();
|
|
26878
|
+
});
|
|
26850
26879
|
}
|
|
26851
26880
|
else if(lastCommand.indexOf('view interactions') == 0 && me.cfg.align !== undefined) {
|
|
26852
26881
|
thisClass.applyCommandViewinteraction(lastCommand);
|
|
@@ -27238,11 +27267,11 @@ class LoadScript {
|
|
|
27238
27267
|
let thisClass = this;
|
|
27239
27268
|
|
|
27240
27269
|
// chain functions together
|
|
27241
|
-
ic.deferred3ddomain = $.Deferred(function() {
|
|
27270
|
+
//ic.deferred3ddomain = $.Deferred(function() {
|
|
27242
27271
|
thisClass.applyCommand3ddomainBase(command);
|
|
27243
|
-
}); // end of me.deferred = $.Deferred(function() {
|
|
27272
|
+
//}); // end of me.deferred = $.Deferred(function() {
|
|
27244
27273
|
|
|
27245
|
-
return ic.deferred3ddomain.promise();
|
|
27274
|
+
//return ic.deferred3ddomain.promise();
|
|
27246
27275
|
}
|
|
27247
27276
|
|
|
27248
27277
|
applyCommandViewinteractionBase(command) { let ic = this.icn3d, me = ic.icn3dui;
|
|
@@ -27581,6 +27610,1037 @@ class ResizeCanvas {
|
|
|
27581
27610
|
}
|
|
27582
27611
|
}
|
|
27583
27612
|
|
|
27613
|
+
/*
|
|
27614
|
+
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
27615
|
+
* Modified from Tom Madej's C++ code
|
|
27616
|
+
*/
|
|
27617
|
+
|
|
27618
|
+
//import * as THREE from 'three';
|
|
27619
|
+
|
|
27620
|
+
class Domain3d {
|
|
27621
|
+
constructor(icn3d) {
|
|
27622
|
+
this.icn3d = icn3d;
|
|
27623
|
+
|
|
27624
|
+
this.dcut = 8; // threshold for C-alpha interactions
|
|
27625
|
+
|
|
27626
|
+
this.MAX_SSE = 512;
|
|
27627
|
+
|
|
27628
|
+
//let this.ctc_cnt[this.MAX_SSE][this.MAX_SSE]; // contact count matrix
|
|
27629
|
+
this.ctc_cnt = [];
|
|
27630
|
+
for(let i = 0; i < this.MAX_SSE; ++i) {
|
|
27631
|
+
this.ctc_cnt[i] = [];
|
|
27632
|
+
}
|
|
27633
|
+
|
|
27634
|
+
//let this.elt_size[this.MAX_SSE]; // element sizes in residues
|
|
27635
|
+
this.elt_size = [];
|
|
27636
|
+
this.elt_size.length = this.MAX_SSE;
|
|
27637
|
+
|
|
27638
|
+
//let this.group_num[this.MAX_SSE]; // indicates required element groupings
|
|
27639
|
+
this.group_num = [];
|
|
27640
|
+
this.group_num.length = this.MAX_SSE;
|
|
27641
|
+
|
|
27642
|
+
this.split_ratio = 0.0; //let // splitting ratio
|
|
27643
|
+
this.min_size = 0; // min required size of a domain
|
|
27644
|
+
this.min_sse = 0; // min number of SSEs required in a domain
|
|
27645
|
+
this.max_csz = 0; // max size of a cut, i.e. number of points
|
|
27646
|
+
this.mean_cts = 0.0; // mean number of contacts in a domain
|
|
27647
|
+
this.c_delta = 0; // cut set parameter
|
|
27648
|
+
this.nc_fact = 0.0; // size factor for internal contacts
|
|
27649
|
+
//let this.elements[2*this.MAX_SSE]; // sets of this.elements to be split
|
|
27650
|
+
this.elements = [];
|
|
27651
|
+
this.elements.length = 2*this.MAX_SSE;
|
|
27652
|
+
|
|
27653
|
+
//let this.stack[this.MAX_SSE]; // this.stack of sets (subdomains) to split
|
|
27654
|
+
this.stack = [];
|
|
27655
|
+
this.stack.length = this.MAX_SSE;
|
|
27656
|
+
|
|
27657
|
+
this.top = 0; // this.top of this.stack
|
|
27658
|
+
//let this.curr_prt0[this.MAX_SSE]; // current part 0 this.elements
|
|
27659
|
+
this.curr_prt0 = [];
|
|
27660
|
+
this.curr_prt0.length = this.MAX_SSE;
|
|
27661
|
+
|
|
27662
|
+
//let this.curr_prt1[this.MAX_SSE]; // current part 1 this.elements
|
|
27663
|
+
this.curr_prt1 = [];
|
|
27664
|
+
this.curr_prt1.length = this.MAX_SSE;
|
|
27665
|
+
|
|
27666
|
+
this.curr_ne0 = 0; // no. of this.elements in current part 0
|
|
27667
|
+
this.curr_ne1 = 0; // no. of this.elements in current part 1
|
|
27668
|
+
this.curr_ratio = 0.0; // current splitting ratio
|
|
27669
|
+
this.curr_msize = 0; // min of current part sizes
|
|
27670
|
+
//let this.parts[2*this.MAX_SSE]; // final partition into domains
|
|
27671
|
+
this.parts = [];
|
|
27672
|
+
this.parts.length = 2*this.MAX_SSE;
|
|
27673
|
+
|
|
27674
|
+
this.np = 0; // next free location in this.parts[]
|
|
27675
|
+
this.n_doms = 0; // number of domains
|
|
27676
|
+
//let this.save_ratios[this.MAX_SSE]; // this.saved splitting ratios
|
|
27677
|
+
this.save_ratios = [];
|
|
27678
|
+
this.save_ratios.length = this.MAX_SSE;
|
|
27679
|
+
|
|
27680
|
+
this.saved = 0; // number of this.saved ratios
|
|
27681
|
+
}
|
|
27682
|
+
|
|
27683
|
+
// Partition the set of this.elements on this.top of the this.stack based on the input cut.
|
|
27684
|
+
// If the partition is valid and the ratio is smaller than the current one, then
|
|
27685
|
+
// save it as the best partition so far encountered. Various criteria are
|
|
27686
|
+
// employed for valid partitions, as described below.
|
|
27687
|
+
//
|
|
27688
|
+
|
|
27689
|
+
//update_partition(int* cut, let k, let n) { let ic = this.icn3d, me = ic.icn3dui;
|
|
27690
|
+
update_partition(cut, k, n) { let ic = this.icn3d; ic.icn3dui;
|
|
27691
|
+
let i, il, j, t, nc0, nc1, ncx, ne, ne0, ne1, elts = [], prt = []; //int
|
|
27692
|
+
let size0, size1, prt0 = [], prt1 = []; // int
|
|
27693
|
+
prt0.length = this.MAX_SSE;
|
|
27694
|
+
prt1.length = this.MAX_SSE;
|
|
27695
|
+
let f, r0; //let
|
|
27696
|
+
|
|
27697
|
+
// this.elements from the this.top of the this.stack
|
|
27698
|
+
//elts = &this.elements[this.stack[this.top - 1]];
|
|
27699
|
+
for(i = this.stack[this.top - 1], il = this.elements.length; i < il; ++i) {
|
|
27700
|
+
elts.push(this.elements[i]);
|
|
27701
|
+
}
|
|
27702
|
+
|
|
27703
|
+
// generate the partition based on the cut //
|
|
27704
|
+
for (i = ne = ne0 = ne1 = 0, prt = prt0, t = -1; i < k; i++) {
|
|
27705
|
+
// write the this.elements into prt //
|
|
27706
|
+
for (j = t + 1; j <= cut[i]; j++)
|
|
27707
|
+
prt[ne++] = elts[j];
|
|
27708
|
+
|
|
27709
|
+
t = cut[i];
|
|
27710
|
+
|
|
27711
|
+
// switch the partition //
|
|
27712
|
+
if (prt == prt0) {
|
|
27713
|
+
ne0 = ne;
|
|
27714
|
+
prt = prt1;
|
|
27715
|
+
ne = ne1;
|
|
27716
|
+
}
|
|
27717
|
+
else {
|
|
27718
|
+
ne1 = ne;
|
|
27719
|
+
prt = prt0;
|
|
27720
|
+
ne = ne0;
|
|
27721
|
+
}
|
|
27722
|
+
}
|
|
27723
|
+
|
|
27724
|
+
// finish with the last part //
|
|
27725
|
+
for (j = t + 1; j < n; j++)
|
|
27726
|
+
prt[ne++] = elts[j];
|
|
27727
|
+
|
|
27728
|
+
if (prt == prt0)
|
|
27729
|
+
ne0 = ne;
|
|
27730
|
+
else
|
|
27731
|
+
ne1 = ne;
|
|
27732
|
+
|
|
27733
|
+
// don't split into two teeny this.parts! //
|
|
27734
|
+
if ((ne0 < this.min_sse) && (ne1 < this.min_sse))
|
|
27735
|
+
return cut;
|
|
27736
|
+
|
|
27737
|
+
// check to see if the partition splits any required groups //
|
|
27738
|
+
for (i = 0; i < ne0; i++) {
|
|
27739
|
+
t = this.group_num[prt0[i]];
|
|
27740
|
+
|
|
27741
|
+
for (j = 0; j < ne1; j++) {
|
|
27742
|
+
if (t == this.group_num[prt1[j]])
|
|
27743
|
+
return cut;
|
|
27744
|
+
}
|
|
27745
|
+
}
|
|
27746
|
+
|
|
27747
|
+
// compute the sizes of the this.parts //
|
|
27748
|
+
for (i = size0 = 0; i < ne0; i++)
|
|
27749
|
+
size0 += this.elt_size[prt0[i]];
|
|
27750
|
+
|
|
27751
|
+
for (i = size1 = 0; i < ne1; i++)
|
|
27752
|
+
size1 += this.elt_size[prt1[i]];
|
|
27753
|
+
|
|
27754
|
+
// count internal contacts for part 0 //
|
|
27755
|
+
for (i = nc0 = 0; i < ne0; i++) {
|
|
27756
|
+
for (j = i; j < ne0; j++)
|
|
27757
|
+
nc0 += this.ctc_cnt[prt0[i]][prt0[j]];
|
|
27758
|
+
}
|
|
27759
|
+
|
|
27760
|
+
// count internal contacts for part 1 //
|
|
27761
|
+
for (i = nc1 = 0; i < ne1; i++) {
|
|
27762
|
+
for (j = i; j < ne1; j++)
|
|
27763
|
+
nc1 += this.ctc_cnt[prt1[i]][prt1[j]];
|
|
27764
|
+
}
|
|
27765
|
+
|
|
27766
|
+
// check globularity condition //
|
|
27767
|
+
if ((1.0 * nc0 / size0 < this.mean_cts) ||
|
|
27768
|
+
(1.0 * nc1 / size1 < this.mean_cts))
|
|
27769
|
+
return cut;
|
|
27770
|
+
|
|
27771
|
+
// to handle non-globular pieces make sure nc0, nc1, are large enough //
|
|
27772
|
+
nc0 = Math.max(nc0, this.nc_fact*size0);
|
|
27773
|
+
nc1 = Math.max(nc1, this.nc_fact*size1);
|
|
27774
|
+
|
|
27775
|
+
// count inter-part contacts //
|
|
27776
|
+
for (i = ncx = 0; i < ne0; i++) {
|
|
27777
|
+
t = prt0[i];
|
|
27778
|
+
|
|
27779
|
+
for (j = 0; j < ne1; j++)
|
|
27780
|
+
ncx += this.ctc_cnt[t][prt1[j]];
|
|
27781
|
+
}
|
|
27782
|
+
|
|
27783
|
+
// compute the splitting ratio //
|
|
27784
|
+
f = Math.min(nc0, nc1);
|
|
27785
|
+
r0 = 1.0 * ncx / (f + 1.0);
|
|
27786
|
+
|
|
27787
|
+
if ((r0 >= this.curr_ratio + 0.01) || (r0 > this.split_ratio))
|
|
27788
|
+
return cut;
|
|
27789
|
+
|
|
27790
|
+
// If the difference in the ratios is insignificant then take the split
|
|
27791
|
+
// that most evenly partitions the domain.
|
|
27792
|
+
|
|
27793
|
+
if ((r0 > this.curr_ratio - 0.01) && (Math.min(size0, size1) < this.curr_msize))
|
|
27794
|
+
return cut;
|
|
27795
|
+
|
|
27796
|
+
// if we get to here then keep this split //
|
|
27797
|
+
for (i = 0; i < ne0; i++)
|
|
27798
|
+
this.curr_prt0[i] = prt0[i];
|
|
27799
|
+
|
|
27800
|
+
for (i = 0; i < ne1; i++)
|
|
27801
|
+
this.curr_prt1[i] = prt1[i];
|
|
27802
|
+
|
|
27803
|
+
this.curr_ne0 = ne0;
|
|
27804
|
+
this.curr_ne1 = ne1;
|
|
27805
|
+
this.curr_ratio = r0;
|
|
27806
|
+
this.curr_msize = Math.min(size0, size1);
|
|
27807
|
+
|
|
27808
|
+
return cut;
|
|
27809
|
+
|
|
27810
|
+
} // end update_partition //
|
|
27811
|
+
|
|
27812
|
+
|
|
27813
|
+
|
|
27814
|
+
// // Run through the possible cuts of size k for a set of this.elements of size n.
|
|
27815
|
+
// *
|
|
27816
|
+
// * To avoid small protrusions, no blocks of consecutive this.elements of length <= this.c_delta
|
|
27817
|
+
// * are allowed. An example where this is desirable is as follows. Let's say you
|
|
27818
|
+
// * have a protein with 2 subdomains, one of them an alpha-beta-alpha sandwich. It
|
|
27819
|
+
// * could then happen that one of the helices in the sandwich domain might make more
|
|
27820
|
+
// * contacts with the other subdomain than with the sandwich. The correct thing to
|
|
27821
|
+
// * do is to keep the helix with the rest of the sandwich, and the "this.c_delta rule"
|
|
27822
|
+
// * enforces this.
|
|
27823
|
+
// //
|
|
27824
|
+
|
|
27825
|
+
cut_size(k, n) { let ic = this.icn3d; ic.icn3dui;
|
|
27826
|
+
let i, j, cok, cut0 = []; //int
|
|
27827
|
+
cut0.length = this.MAX_SSE;
|
|
27828
|
+
|
|
27829
|
+
for (i = 0; i < k; i++)
|
|
27830
|
+
cut0[i] = i;
|
|
27831
|
+
|
|
27832
|
+
// enumerate cuts of length k //
|
|
27833
|
+
while (1) {
|
|
27834
|
+
// check block sizes in the cut //
|
|
27835
|
+
for (i = cok = 1; i < k; i++) {
|
|
27836
|
+
if (cut0[i] - cut0[i - 1] <= this.c_delta) {
|
|
27837
|
+
cok = 0;
|
|
27838
|
+
break;
|
|
27839
|
+
}
|
|
27840
|
+
}
|
|
27841
|
+
if (cok && (cut0[k - 1] < n - 1))
|
|
27842
|
+
cut0 = this.update_partition(cut0, k, n);
|
|
27843
|
+
|
|
27844
|
+
// generate the next k-tuple of positions //
|
|
27845
|
+
for (j = k - 1; (j >= 0) && (cut0[j] == n - k + j); j--);
|
|
27846
|
+
|
|
27847
|
+
if (j < 0) break;
|
|
27848
|
+
|
|
27849
|
+
cut0[j]++;
|
|
27850
|
+
|
|
27851
|
+
for (i = j + 1; i < k; i++)
|
|
27852
|
+
cut0[i] = cut0[i - 1] + 1;
|
|
27853
|
+
}
|
|
27854
|
+
|
|
27855
|
+
} // end cut_size //
|
|
27856
|
+
|
|
27857
|
+
|
|
27858
|
+
|
|
27859
|
+
// // Process the set of this.elements on this.top of the this.stack. We generate cut sets in
|
|
27860
|
+
// * a limited size range, generally from 1 to 5. For each cut the induced
|
|
27861
|
+
// * partition is considered and its splitting parameters computed. The cut
|
|
27862
|
+
// * that yields the smallest splitting ratio is chosen as the correct one, if
|
|
27863
|
+
// * the ratio is low enough. The subdomains are then placed on the this.stack for
|
|
27864
|
+
// * further consideration.
|
|
27865
|
+
// *
|
|
27866
|
+
// * Subdomains with < this.min_sse SSEs are not allowed to split further, however,
|
|
27867
|
+
// * it is possible to trim fewer than this.min_sse SSEs from a larger domain. E.g.
|
|
27868
|
+
// * a chain with 7 SSEs can be split into a subdomain with 5 SSEs and another
|
|
27869
|
+
// * with 2 SSEs, but the one with 2 SSEs cannot be split further.
|
|
27870
|
+
// *
|
|
27871
|
+
// * Note that the invariant is, that this.stack[top] always points to the next free
|
|
27872
|
+
// * location in this.elements[].
|
|
27873
|
+
// //
|
|
27874
|
+
|
|
27875
|
+
process_set() { let ic = this.icn3d; ic.icn3dui;
|
|
27876
|
+
let i, il, k, n, t, k0, elts = []; //int
|
|
27877
|
+
|
|
27878
|
+
// count the this.elements //
|
|
27879
|
+
//elts = &this.elements[this.stack[this.top - 1]];
|
|
27880
|
+
for(i = this.stack[this.top - 1], il = this.elements.length; i < il; ++i) {
|
|
27881
|
+
elts.push(this.elements[i]);
|
|
27882
|
+
}
|
|
27883
|
+
|
|
27884
|
+
//for (n = 0; *elts > -1; n++, elts++);
|
|
27885
|
+
for (n = 0; n < elts.length && elts[n] > -1; n++);
|
|
27886
|
+
|
|
27887
|
+
// try various cut sizes //
|
|
27888
|
+
k0 = Math.min(n - 1, this.max_csz);
|
|
27889
|
+
this.curr_ne0 = this.curr_ne1 = 0;
|
|
27890
|
+
this.curr_ratio = 100.0;
|
|
27891
|
+
|
|
27892
|
+
for (k = 1; k <= k0; k++)
|
|
27893
|
+
this.cut_size(k, n);
|
|
27894
|
+
|
|
27895
|
+
// pop this.stack //
|
|
27896
|
+
this.top--;
|
|
27897
|
+
|
|
27898
|
+
if (this.curr_ne0 == 0) {
|
|
27899
|
+
// no split took place, save part //
|
|
27900
|
+
t = this.stack[this.top];
|
|
27901
|
+
|
|
27902
|
+
//for (elts = &this.elements[t]; *elts > -1; elts++)
|
|
27903
|
+
// parts[np++] = *elts;
|
|
27904
|
+
|
|
27905
|
+
for (i = t; i < this.elements.length && this.elements[i] > -1; i++)
|
|
27906
|
+
this.parts[this.np++] = this.elements[i];
|
|
27907
|
+
|
|
27908
|
+
this.parts[this.np++] = -1;
|
|
27909
|
+
this.n_doms++;
|
|
27910
|
+
}
|
|
27911
|
+
else {
|
|
27912
|
+
this.save_ratios[this.saved++] = this.curr_ratio;
|
|
27913
|
+
|
|
27914
|
+
if (this.curr_ne0 > this.min_sse) {
|
|
27915
|
+
// push on part 0 //
|
|
27916
|
+
t = this.stack[this.top];
|
|
27917
|
+
|
|
27918
|
+
for (i = 0; i < this.curr_ne0; i++)
|
|
27919
|
+
this.elements[t++] = this.curr_prt0[i];
|
|
27920
|
+
|
|
27921
|
+
this.elements[t++] = -1;
|
|
27922
|
+
this.stack[++this.top] = t;
|
|
27923
|
+
}
|
|
27924
|
+
else {
|
|
27925
|
+
// save part 0 //
|
|
27926
|
+
for (i = 0; i < this.curr_ne0; i++)
|
|
27927
|
+
this.parts[this.np++] = this.curr_prt0[i];
|
|
27928
|
+
|
|
27929
|
+
this.parts[this.np++] = -1;
|
|
27930
|
+
this.n_doms++;
|
|
27931
|
+
}
|
|
27932
|
+
|
|
27933
|
+
if (this.curr_ne1 > this.min_sse) {
|
|
27934
|
+
// push on part 1 //
|
|
27935
|
+
t = this.stack[this.top];
|
|
27936
|
+
|
|
27937
|
+
for (i = 0; i < this.curr_ne1; i++)
|
|
27938
|
+
this.elements[t++] = this.curr_prt1[i];
|
|
27939
|
+
|
|
27940
|
+
this.elements[t++] = -1;
|
|
27941
|
+
this.stack[++this.top] = t;
|
|
27942
|
+
}
|
|
27943
|
+
else {
|
|
27944
|
+
// save part 1 //
|
|
27945
|
+
for (i = 0; i < this.curr_ne1; i++)
|
|
27946
|
+
this.parts[this.np++] = this.curr_prt1[i];
|
|
27947
|
+
|
|
27948
|
+
this.parts[this.np++] = -1;
|
|
27949
|
+
this.n_doms++;
|
|
27950
|
+
}
|
|
27951
|
+
}
|
|
27952
|
+
} // end process_set //
|
|
27953
|
+
|
|
27954
|
+
|
|
27955
|
+
|
|
27956
|
+
// Main driver for chain splitting. //
|
|
27957
|
+
//process_all(let n) { let ic = this.icn3d, me = ic.icn3dui;
|
|
27958
|
+
process_all(n) { let ic = this.icn3d; ic.icn3dui;
|
|
27959
|
+
let i; //int
|
|
27960
|
+
|
|
27961
|
+
// initialize the this.stack //
|
|
27962
|
+
this.top = 1;
|
|
27963
|
+
this.stack[0] = this.np = this.n_doms = 0;
|
|
27964
|
+
this.saved = 0;
|
|
27965
|
+
|
|
27966
|
+
for (i = 0; i < n; i++)
|
|
27967
|
+
this.elements[i] = i;
|
|
27968
|
+
|
|
27969
|
+
this.elements[n] = -1;
|
|
27970
|
+
|
|
27971
|
+
// recursively split the chain into domains //
|
|
27972
|
+
while (this.top > 0) {
|
|
27973
|
+
this.process_set();
|
|
27974
|
+
}
|
|
27975
|
+
} // end process_all //
|
|
27976
|
+
|
|
27977
|
+
// Output the domains. For S we number the this.elements 1, 2, ..., n. //
|
|
27978
|
+
//output(let n, int* prts) { let ic = this.icn3d, me = ic.icn3dui;
|
|
27979
|
+
output(n) { let ic = this.icn3d; ic.icn3dui;
|
|
27980
|
+
let i, k; //int
|
|
27981
|
+
|
|
27982
|
+
let prts = [];
|
|
27983
|
+
|
|
27984
|
+
// zap the output array //
|
|
27985
|
+
for (i = 0; i < 2*n; i++)
|
|
27986
|
+
prts.push(0);
|
|
27987
|
+
|
|
27988
|
+
// now write out the subdomains //
|
|
27989
|
+
for (i = k = 0; k < this.n_doms; i++) {
|
|
27990
|
+
prts[i] = this.parts[i] + 1;
|
|
27991
|
+
|
|
27992
|
+
if (this.parts[i] < 0)
|
|
27993
|
+
k++;
|
|
27994
|
+
}
|
|
27995
|
+
|
|
27996
|
+
return prts;
|
|
27997
|
+
} // end output //
|
|
27998
|
+
|
|
27999
|
+
|
|
28000
|
+
|
|
28001
|
+
// // S-interface to the chain-splitting program.
|
|
28002
|
+
// *
|
|
28003
|
+
// * Explanation of parameters:
|
|
28004
|
+
// *
|
|
28005
|
+
// * ne - number of secondary structure this.elements (SSEs)
|
|
28006
|
+
// * cts - contact count matrix
|
|
28007
|
+
// * elt_sz - sizes of SSEs
|
|
28008
|
+
// * grps - element group indicators
|
|
28009
|
+
// * sratio - splitting ratio
|
|
28010
|
+
// * msize - min size of a split domain
|
|
28011
|
+
// * m_sse - min number of SSEs required in a split part
|
|
28012
|
+
// * mcsz - max cut size, i.e. max number of split points
|
|
28013
|
+
// * avg_cts - mean number of internal contacts for a domain
|
|
28014
|
+
// * c_delt - cut set parameter
|
|
28015
|
+
// * ncf0 - size factor for number of internal contacts
|
|
28016
|
+
// * prts - output listing of domains
|
|
28017
|
+
// * n_saved - number of this.saved splitting ratios
|
|
28018
|
+
// * ratios - splitting ratios
|
|
28019
|
+
// * ret - success/failure indicator
|
|
28020
|
+
// * verb - flag to turn off/on splitting information
|
|
28021
|
+
// //
|
|
28022
|
+
|
|
28023
|
+
//new_split_chain(let ne, let sratio, let msize, let m_sse, let mcsz, let avg_cts,
|
|
28024
|
+
// let c_delt, let ncf0, int* prts, int* n_saved, let* ratios) { let ic = this.icn3d, me = ic.icn3dui;
|
|
28025
|
+
new_split_chain(ne, sratio, msize, m_sse, mcsz, avg_cts,
|
|
28026
|
+
c_delt, ncf0, prts, n_saved, ratios) { let ic = this.icn3d; ic.icn3dui;
|
|
28027
|
+
let i; //int
|
|
28028
|
+
|
|
28029
|
+
this.split_ratio = sratio;
|
|
28030
|
+
this.min_size = msize;
|
|
28031
|
+
this.min_sse = m_sse;
|
|
28032
|
+
this.max_csz = mcsz;
|
|
28033
|
+
this.mean_cts = avg_cts;
|
|
28034
|
+
this.c_delta = c_delt;
|
|
28035
|
+
this.nc_fact = ncf0;
|
|
28036
|
+
|
|
28037
|
+
this.process_all(ne);
|
|
28038
|
+
//this.output(ne, prts);
|
|
28039
|
+
this.parts = this.output(ne);
|
|
28040
|
+
n_saved = this.saved;
|
|
28041
|
+
for (i = 0; i < this.saved; i++)
|
|
28042
|
+
ratios[i] = this.save_ratios[i];
|
|
28043
|
+
|
|
28044
|
+
return n_saved;
|
|
28045
|
+
|
|
28046
|
+
} // end new_split_chain //
|
|
28047
|
+
|
|
28048
|
+
//
|
|
28049
|
+
// Actually, here is a better method that is also simple!
|
|
28050
|
+
//
|
|
28051
|
+
// If there are N atoms (residues) this algorithm should usually run in
|
|
28052
|
+
// time O(N^4/3), and usually even much faster! In very unusual cases
|
|
28053
|
+
// it could take quadratic time. The key idea is that atoms are not
|
|
28054
|
+
// infinitely compressible, i.e. only a fixed number will fit in a given
|
|
28055
|
+
// region of space. So if the protein is roughly spherical, there will
|
|
28056
|
+
// only be O(N^1/3) atoms close to any given diameter. Therefore, a
|
|
28057
|
+
// bound on the number of iterations of the inner loop is O(N^1/3).
|
|
28058
|
+
//
|
|
28059
|
+
// For an elongated protein that happens to have the x-axis normal to
|
|
28060
|
+
// the long axis, then it is possible for the inner loop to take time
|
|
28061
|
+
// O(N), in which case the whole takes O(N^2). But this should rarely,
|
|
28062
|
+
// if ever, occur in practice. It would also be possible beforehand to
|
|
28063
|
+
// choose the axis with the largest variance.
|
|
28064
|
+
//
|
|
28065
|
+
|
|
28066
|
+
// typedef struct res_struct {
|
|
28067
|
+
// let rnum;
|
|
28068
|
+
// let x, y, z;
|
|
28069
|
+
// } ResRec;
|
|
28070
|
+
|
|
28071
|
+
//list< pair< pair< int, let >, let > >
|
|
28072
|
+
//c2b_AlphaContacts(let n0, let* x0, let* y0, let* z0,
|
|
28073
|
+
// const let incr = 4, const let dcut = 8.0) { let ic = this.icn3d, me = ic.icn3dui;
|
|
28074
|
+
c2b_AlphaContacts(n0, x0, y0, z0, dcut) { let ic = this.icn3d; ic.icn3dui;
|
|
28075
|
+
//if(!incr) incr = 4;
|
|
28076
|
+
if(!dcut) dcut = this.dcut;
|
|
28077
|
+
|
|
28078
|
+
let list_cts = [], list_rr = [];
|
|
28079
|
+
|
|
28080
|
+
for (let i = 0; i < n0; i++) {
|
|
28081
|
+
// don't include residues with missing coordinates
|
|
28082
|
+
//if ((x0[i] == MissingCoord) || (y0[i] == MissingCoord) || (z0[i] == MissingCoord))
|
|
28083
|
+
if (!x0[i]|| !y0[i] || !z0[i])
|
|
28084
|
+
continue;
|
|
28085
|
+
|
|
28086
|
+
//ResRec rr0;
|
|
28087
|
+
let rr0 = {};
|
|
28088
|
+
rr0.rnum = i + 1;
|
|
28089
|
+
rr0.x = x0[i];
|
|
28090
|
+
rr0.y = y0[i];
|
|
28091
|
+
rr0.z = z0[i];
|
|
28092
|
+
list_rr.push(rr0);
|
|
28093
|
+
}
|
|
28094
|
+
|
|
28095
|
+
list_rr.sort(function(rr1, rr2) {
|
|
28096
|
+
return rr1.x - rr2.x;
|
|
28097
|
+
});
|
|
28098
|
+
|
|
28099
|
+
//let rrit1, rrit2, rrbeg;
|
|
28100
|
+
let i, j, len = list_rr.length;
|
|
28101
|
+
|
|
28102
|
+
//for (rrit1 = list_rr.begin(); rrit1 != list_rr.end(); rrit1++) {
|
|
28103
|
+
for (i = 0; i < len; ++i) {
|
|
28104
|
+
//ResRec rr1 = *rrit1;
|
|
28105
|
+
let rr1 = list_rr[i];
|
|
28106
|
+
let x1 = rr1.x;
|
|
28107
|
+
let y1 = rr1.y;
|
|
28108
|
+
let z1 = rr1.z;
|
|
28109
|
+
//rrbeg = rrit1;
|
|
28110
|
+
//rrbeg++;
|
|
28111
|
+
|
|
28112
|
+
//for (rrit2 = rrbeg; rrit2 != list_rr.end(); rrit2++) {
|
|
28113
|
+
for (j = i + 1; j < len; ++j) {
|
|
28114
|
+
//ResRec rr2 = *rrit2;
|
|
28115
|
+
let rr2 = list_rr[j];
|
|
28116
|
+
if ((rr1.rnum - rr2.rnum <= 3) && (rr2.rnum - rr1.rnum <= 3)) continue;
|
|
28117
|
+
let x2 = rr2.x;
|
|
28118
|
+
let y2 = rr2.y;
|
|
28119
|
+
let z2 = rr2.z;
|
|
28120
|
+
|
|
28121
|
+
if (x2 > x1 + dcut)
|
|
28122
|
+
break;
|
|
28123
|
+
|
|
28124
|
+
// x1 <= x2 <= x1 + dcut so compare
|
|
28125
|
+
let sum = (x1 - x2)*(x1 - x2);
|
|
28126
|
+
sum += (y1 - y2)*(y1 - y2);
|
|
28127
|
+
sum += (z1 - z2)*(z1 - z2);
|
|
28128
|
+
let d0 = Math.sqrt(sum);
|
|
28129
|
+
if (d0 > dcut) continue;
|
|
28130
|
+
//pair< pair< int, let >, let > lpair;
|
|
28131
|
+
//pair< int, let > rpair;
|
|
28132
|
+
let lpair = {}, rpair = {};
|
|
28133
|
+
|
|
28134
|
+
if (rr1.rnum < rr2.rnum) {
|
|
28135
|
+
rpair.first = rr1.rnum;
|
|
28136
|
+
rpair.second = rr2.rnum;
|
|
28137
|
+
}
|
|
28138
|
+
else {
|
|
28139
|
+
rpair.first = rr2.rnum;
|
|
28140
|
+
rpair.second = rr1.rnum;
|
|
28141
|
+
}
|
|
28142
|
+
|
|
28143
|
+
lpair.first = rpair;
|
|
28144
|
+
lpair.second = d0;
|
|
28145
|
+
list_cts.push(lpair);
|
|
28146
|
+
}
|
|
28147
|
+
}
|
|
28148
|
+
|
|
28149
|
+
return list_cts;
|
|
28150
|
+
|
|
28151
|
+
} // end c2b_AlphaContacts
|
|
28152
|
+
|
|
28153
|
+
|
|
28154
|
+
|
|
28155
|
+
//
|
|
28156
|
+
// Creates a table, actually a graph, of the contacts between SSEs.
|
|
28157
|
+
//
|
|
28158
|
+
|
|
28159
|
+
//static map< pair< int, let >, let >
|
|
28160
|
+
//c2b_ContactTable(vector<int>& v1, vector<int>& v2) { let ic = this.icn3d, me = ic.icn3dui;
|
|
28161
|
+
c2b_ContactTable(v1, v2) { let ic = this.icn3d; ic.icn3dui;
|
|
28162
|
+
let cmap = {};
|
|
28163
|
+
let n0 = v1.length; //unsigned int
|
|
28164
|
+
|
|
28165
|
+
if (n0 != v2.length) {
|
|
28166
|
+
// problem!
|
|
28167
|
+
|
|
28168
|
+
return cmap;
|
|
28169
|
+
}
|
|
28170
|
+
|
|
28171
|
+
for (let i = 0; i < n0; i++) {
|
|
28172
|
+
let e1 = v1[i];
|
|
28173
|
+
let e2 = v2[i];
|
|
28174
|
+
//pair<int, int> epr;
|
|
28175
|
+
//let epr = {};
|
|
28176
|
+
//epr.first = e1;
|
|
28177
|
+
//epr.second = e2;
|
|
28178
|
+
let epr = e1 + '_' + e2;
|
|
28179
|
+
|
|
28180
|
+
//if (cmap.count(epr) == 0) {
|
|
28181
|
+
if (!cmap[epr]) {
|
|
28182
|
+
cmap[epr] = 1;
|
|
28183
|
+
}
|
|
28184
|
+
else
|
|
28185
|
+
cmap[epr]++;
|
|
28186
|
+
}
|
|
28187
|
+
|
|
28188
|
+
return cmap;
|
|
28189
|
+
|
|
28190
|
+
} // end c2b_ContactTable
|
|
28191
|
+
|
|
28192
|
+
|
|
28193
|
+
//https://www.geeksforgeeks.org/number-groups-formed-graph-friends/
|
|
28194
|
+
countUtil(ss1, sheetNeighbor, existing_groups) {
|
|
28195
|
+
this.visited[ss1] = true;
|
|
28196
|
+
if(!this.groupnum2sheet[existing_groups]) this.groupnum2sheet[existing_groups] = [];
|
|
28197
|
+
this.groupnum2sheet[existing_groups].push(parseInt(ss1));
|
|
28198
|
+
|
|
28199
|
+
for(let ss2 in sheetNeighbor[ss1]) {
|
|
28200
|
+
if (!this.visited[ss2]) {
|
|
28201
|
+
this.countUtil(ss2, sheetNeighbor, existing_groups);
|
|
28202
|
+
}
|
|
28203
|
+
}
|
|
28204
|
+
}
|
|
28205
|
+
|
|
28206
|
+
//
|
|
28207
|
+
// Residue ranges of the Vast domains, per protein chain.
|
|
28208
|
+
//
|
|
28209
|
+
|
|
28210
|
+
//
|
|
28211
|
+
// Subdomain definition rules are as follows; let m0 = minSSE:
|
|
28212
|
+
//
|
|
28213
|
+
// 1. A subdomain with <= m0 SSEs cannot be split.
|
|
28214
|
+
//
|
|
28215
|
+
// 2. A subdomain cannot be split into two this.parts, both with < m0 SSEs.
|
|
28216
|
+
//
|
|
28217
|
+
// 3. However, a subdomain can be trimmed, i.e. split into two this.parts,
|
|
28218
|
+
// one with < m0 SSEs.
|
|
28219
|
+
//
|
|
28220
|
+
//c2b_NewSplitChain(string asymId, let seqLen, let* x0, let* y0, let* z0) { let ic = this.icn3d, me = ic.icn3dui;
|
|
28221
|
+
// x0, y0, z0: array of x,y,z coordinates of C-alpha atoms
|
|
28222
|
+
c2b_NewSplitChain(chnid, dcut) { let ic = this.icn3d; ic.icn3dui;
|
|
28223
|
+
let x0 = [], y0 = [], z0 = [];
|
|
28224
|
+
|
|
28225
|
+
//substruct: array of secondary structures, each of which has the keys: From (1-based), To (1-based), Sheet (0 or 1)
|
|
28226
|
+
let substruct = [];
|
|
28227
|
+
// sheets: array of sheets, each of which has the key: sheet_num (beta sandwich has two sheets, e.g., 0 and 1), adj_strand1 (not used), adj_strand2
|
|
28228
|
+
let sheets = [];
|
|
28229
|
+
|
|
28230
|
+
let substructItem = {};
|
|
28231
|
+
let resiOffset = 0;
|
|
28232
|
+
for(let i = 0; i < ic.chainsSeq[chnid].length; ++i) {
|
|
28233
|
+
let resi = ic.chainsSeq[chnid][i].resi;
|
|
28234
|
+
if(i == 0) {
|
|
28235
|
+
resiOffset = resi - 1;
|
|
28236
|
+
|
|
28237
|
+
for(let j = 0; j < resiOffset; ++j) {
|
|
28238
|
+
x0.push(undefined);
|
|
28239
|
+
y0.push(undefined);
|
|
28240
|
+
z0.push(undefined);
|
|
28241
|
+
}
|
|
28242
|
+
}
|
|
28243
|
+
|
|
28244
|
+
let resid = chnid + "_" + resi;
|
|
28245
|
+
let atom = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]);
|
|
28246
|
+
|
|
28247
|
+
if(atom) {
|
|
28248
|
+
x0.push(atom.coord.x);
|
|
28249
|
+
y0.push(atom.coord.y);
|
|
28250
|
+
z0.push(atom.coord.z);
|
|
28251
|
+
}
|
|
28252
|
+
else {
|
|
28253
|
+
x0.push(undefined);
|
|
28254
|
+
y0.push(undefined);
|
|
28255
|
+
z0.push(undefined);
|
|
28256
|
+
}
|
|
28257
|
+
|
|
28258
|
+
if(!atom) continue;
|
|
28259
|
+
|
|
28260
|
+
if(atom.ssend) {
|
|
28261
|
+
substructItem.To = parseInt(resi);
|
|
28262
|
+
substructItem.Sheet = (atom.ss == 'sheet') ? true : false;
|
|
28263
|
+
substruct.push(substructItem);
|
|
28264
|
+
substructItem = {};
|
|
28265
|
+
}
|
|
28266
|
+
|
|
28267
|
+
// a residue could be both start and end. check ssend first, then check ssbegin
|
|
28268
|
+
if(atom.ssbegin) {
|
|
28269
|
+
substructItem.From = parseInt(resi);
|
|
28270
|
+
}
|
|
28271
|
+
}
|
|
28272
|
+
|
|
28273
|
+
let nsse = substruct.length;
|
|
28274
|
+
|
|
28275
|
+
if (nsse <= 3)
|
|
28276
|
+
// too small, can't split or trim
|
|
28277
|
+
return;
|
|
28278
|
+
|
|
28279
|
+
if (nsse > this.MAX_SSE) {
|
|
28280
|
+
// we have a problem...
|
|
28281
|
+
|
|
28282
|
+
return;
|
|
28283
|
+
}
|
|
28284
|
+
|
|
28285
|
+
let seqLen = ic.chainsSeq[chnid].length + resiOffset;
|
|
28286
|
+
|
|
28287
|
+
// get a list of Calpha-Calpha contacts
|
|
28288
|
+
///list< pair< pair< int, let >, let > >
|
|
28289
|
+
let cts = this.c2b_AlphaContacts(seqLen, x0, y0, z0, dcut);
|
|
28290
|
+
|
|
28291
|
+
//
|
|
28292
|
+
// Produce a "map" of the SSEs, i.e. vec_sse[i] = 0 means residue i + 1
|
|
28293
|
+
// is in a loop, and vec_sse[i] = k means residue i + 1 belongs to SSE
|
|
28294
|
+
// number k.
|
|
28295
|
+
//
|
|
28296
|
+
let vec_sse = []; //vector<int>
|
|
28297
|
+
|
|
28298
|
+
for (let i = 0; i < seqLen; i++)
|
|
28299
|
+
vec_sse.push(0);
|
|
28300
|
+
|
|
28301
|
+
let hasSheets = false;
|
|
28302
|
+
|
|
28303
|
+
//substruct: array of secondary structures, each of which has the keys: From, To, Sheet (0, 1)
|
|
28304
|
+
for (let i = 0; i < substruct.length; i++) {
|
|
28305
|
+
//SSE_Rec sserec = substruct[i];
|
|
28306
|
+
let sserec = substruct[i];
|
|
28307
|
+
let From = sserec.From;
|
|
28308
|
+
let To = sserec.To;
|
|
28309
|
+
this.elt_size[i] = To - From + 1;
|
|
28310
|
+
|
|
28311
|
+
// double-check indexing OK???
|
|
28312
|
+
for (let j = From; j <= To; j++)
|
|
28313
|
+
vec_sse[j - 1] = i + 1;
|
|
28314
|
+
|
|
28315
|
+
//if (sserec.Sheet > 0)
|
|
28316
|
+
if (sserec.Sheet)
|
|
28317
|
+
hasSheets = true;
|
|
28318
|
+
}
|
|
28319
|
+
|
|
28320
|
+
// produce the SSE contact lists
|
|
28321
|
+
let vec_cts1 = [], vec_cts2 = [], vec_cts1a = [], vec_cts2a = [];
|
|
28322
|
+
|
|
28323
|
+
//for (ctsit = cts.begin(); ctsit != cts.end(); ctsit++) {
|
|
28324
|
+
for (let i = 0, il = cts.length; i < il; ++i) {
|
|
28325
|
+
//pair< pair< int, let >, let > epr = *ctsit;
|
|
28326
|
+
//pair< int, let > respair = epr.first;
|
|
28327
|
+
let epr = cts[i];
|
|
28328
|
+
let respair = epr.first;
|
|
28329
|
+
let sse1 = vec_sse[respair.first - 1];
|
|
28330
|
+
let sse2 = vec_sse[respair.second - 1];
|
|
28331
|
+
// could be 0 or null
|
|
28332
|
+
if ((sse1 <= 0) || (sse2 <= 0) || !sse1 || !sse2) continue;
|
|
28333
|
+
vec_cts1.push(sse1);
|
|
28334
|
+
vec_cts2.push(sse2);
|
|
28335
|
+
if (sse1 == sse2) continue;
|
|
28336
|
+
vec_cts1a.push(sse1);
|
|
28337
|
+
vec_cts2a.push(sse2);
|
|
28338
|
+
}
|
|
28339
|
+
|
|
28340
|
+
// this symmetrizes the contact data
|
|
28341
|
+
for (let i = 0; i < vec_cts1a.length; i++) {
|
|
28342
|
+
vec_cts1.push(vec_cts2a[i]);
|
|
28343
|
+
vec_cts2.push(vec_cts1a[i]);
|
|
28344
|
+
}
|
|
28345
|
+
|
|
28346
|
+
// add dummy contacts
|
|
28347
|
+
for (let i = 0; i < nsse; i++) {
|
|
28348
|
+
vec_cts1.push(i + 1);
|
|
28349
|
+
vec_cts2.push(i + 1);
|
|
28350
|
+
}
|
|
28351
|
+
|
|
28352
|
+
// create contact counts from the contacts/interactions
|
|
28353
|
+
//map< pair< int, let >, let > ctable = this.c2b_ContactTable(vec_cts1, vec_cts2);
|
|
28354
|
+
let ctable = this.c2b_ContactTable(vec_cts1, vec_cts2);
|
|
28355
|
+
|
|
28356
|
+
// neighbor list of each sheet
|
|
28357
|
+
let sheetNeighbor = {};
|
|
28358
|
+
for(let pair in ctable) {
|
|
28359
|
+
let ssPair = pair.split('_'); // 1-based
|
|
28360
|
+
let ss1 = parseInt(ssPair[0]);
|
|
28361
|
+
let ss2 = parseInt(ssPair[1]);
|
|
28362
|
+
|
|
28363
|
+
// both are sheets
|
|
28364
|
+
if(substruct[ss1 - 1].Sheet && substruct[ss2 - 1].Sheet) {
|
|
28365
|
+
if(!sheetNeighbor[ss1]) sheetNeighbor[ss1] = {};
|
|
28366
|
+
if(!sheetNeighbor[ss2]) sheetNeighbor[ss2] = {};
|
|
28367
|
+
|
|
28368
|
+
sheetNeighbor[ss1][ss2] = 1;
|
|
28369
|
+
sheetNeighbor[ss2][ss1] = 1;
|
|
28370
|
+
}
|
|
28371
|
+
}
|
|
28372
|
+
|
|
28373
|
+
//https://www.geeksforgeeks.org/number-groups-formed-graph-friends/
|
|
28374
|
+
let existing_groups = 0;
|
|
28375
|
+
let sheet2sheetnum = {};
|
|
28376
|
+
this.groupnum2sheet = {};
|
|
28377
|
+
this.visited = {};
|
|
28378
|
+
for (let ss1 in sheetNeighbor) {
|
|
28379
|
+
this.visited[ss1] = false;
|
|
28380
|
+
}
|
|
28381
|
+
|
|
28382
|
+
// get this.groupnum2sheet
|
|
28383
|
+
for (let ss1 in sheetNeighbor) {
|
|
28384
|
+
// If not in any group.
|
|
28385
|
+
if (this.visited[ss1] == false) {
|
|
28386
|
+
existing_groups++;
|
|
28387
|
+
|
|
28388
|
+
this.countUtil(ss1, sheetNeighbor, existing_groups);
|
|
28389
|
+
}
|
|
28390
|
+
}
|
|
28391
|
+
|
|
28392
|
+
// get sheet2sheetnum
|
|
28393
|
+
// each neighboring sheet willbe represented by the sheet with the smallest sse
|
|
28394
|
+
for(let groupnum in this.groupnum2sheet) {
|
|
28395
|
+
let ssArray = this.groupnum2sheet[groupnum].sort();
|
|
28396
|
+
for(let i = 0, il = ssArray.length; i < il; ++i) {
|
|
28397
|
+
sheet2sheetnum[ssArray[i]] = ssArray[0];
|
|
28398
|
+
}
|
|
28399
|
+
}
|
|
28400
|
+
|
|
28401
|
+
for (let i = 0; i < nsse; i++) {
|
|
28402
|
+
if(substruct[i].Sheet) {
|
|
28403
|
+
let sheetsItem = {};
|
|
28404
|
+
if(sheet2sheetnum[i+1]) {
|
|
28405
|
+
sheetsItem.sheet_num = sheet2sheetnum[i+1];
|
|
28406
|
+
sheetsItem.adj_strand2 = 1;
|
|
28407
|
+
sheetsItem.sse = i + 1;
|
|
28408
|
+
}
|
|
28409
|
+
else {
|
|
28410
|
+
sheetsItem.sheet_num = 0;
|
|
28411
|
+
sheetsItem.adj_strand2 = 0;
|
|
28412
|
+
sheetsItem.sse = i + 1;
|
|
28413
|
+
}
|
|
28414
|
+
|
|
28415
|
+
sheets.push(sheetsItem);
|
|
28416
|
+
}
|
|
28417
|
+
}
|
|
28418
|
+
|
|
28419
|
+
//
|
|
28420
|
+
// Correct for dummy contacts; they're present to ensure that the
|
|
28421
|
+
// table gives the right result in the possible case there is an
|
|
28422
|
+
// element with no contacts.
|
|
28423
|
+
//
|
|
28424
|
+
for (let i = 0; i < nsse; i++) {
|
|
28425
|
+
for (let j = 0; j < nsse; j++) {
|
|
28426
|
+
//pair<int, int> epr;
|
|
28427
|
+
//let epr = {};
|
|
28428
|
+
//epr.first = i + 1;
|
|
28429
|
+
//epr.second = j + 1;
|
|
28430
|
+
let epr = (i+1).toString() + '_' + (j+1).toString();
|
|
28431
|
+
|
|
28432
|
+
//if (ctable.count(epr) == 0)
|
|
28433
|
+
if (!ctable[epr])
|
|
28434
|
+
this.ctc_cnt[i][j] = 0;
|
|
28435
|
+
else {
|
|
28436
|
+
let cnt = ctable[epr];
|
|
28437
|
+
if (i == j) cnt--; // subtract dummy contact
|
|
28438
|
+
this.ctc_cnt[i][j] = cnt;
|
|
28439
|
+
this.ctc_cnt[j][i] = cnt;
|
|
28440
|
+
}
|
|
28441
|
+
}
|
|
28442
|
+
}
|
|
28443
|
+
|
|
28444
|
+
let minStrand = 6;
|
|
28445
|
+
|
|
28446
|
+
if (hasSheets) {
|
|
28447
|
+
//sheets: array of sheets, each of which has the key: sheet_num (number of strands), adj_strand1, adj_strand2
|
|
28448
|
+
|
|
28449
|
+
let cnt = 0;
|
|
28450
|
+
|
|
28451
|
+
for (let i = 0; i < sheets.length; i++) {
|
|
28452
|
+
//BetaSheet_Rec bsrec = sheets[i];
|
|
28453
|
+
let bsrec = sheets[i];
|
|
28454
|
+
|
|
28455
|
+
//if ((bsrec.sheet_num > 0) && (this.elt_size[i] >= minStrand) && (bsrec.adj_strand2 != 0))
|
|
28456
|
+
if ((bsrec.sheet_num > 0) && (this.elt_size[bsrec.sse - 1] >= minStrand) && (bsrec.adj_strand2 != 0))
|
|
28457
|
+
cnt++;
|
|
28458
|
+
}
|
|
28459
|
+
|
|
28460
|
+
for (let i = 0; i < nsse; i++) {
|
|
28461
|
+
//this.group_num[i] = (cnt == 0) ? i + 1 : 0;
|
|
28462
|
+
this.group_num[i] = i + 1;
|
|
28463
|
+
}
|
|
28464
|
+
|
|
28465
|
+
if (cnt> 0) {
|
|
28466
|
+
for (let i = 0; i < sheets.length; i++) {
|
|
28467
|
+
let bsrec = sheets[i];
|
|
28468
|
+
this.group_num[bsrec.sse - 1] = bsrec.sheet_num;
|
|
28469
|
+
}
|
|
28470
|
+
}
|
|
28471
|
+
}
|
|
28472
|
+
else {
|
|
28473
|
+
for (let i = 0; i < nsse; i++)
|
|
28474
|
+
this.group_num[i] = i + 1;
|
|
28475
|
+
}
|
|
28476
|
+
|
|
28477
|
+
let sratio = 0.25;
|
|
28478
|
+
let minSize = 25;
|
|
28479
|
+
let maxCsz = 4;
|
|
28480
|
+
let avgCts = 0.0;
|
|
28481
|
+
let ncFact = 0.0;
|
|
28482
|
+
let cDelta = 3;
|
|
28483
|
+
let minSSE = 3;
|
|
28484
|
+
|
|
28485
|
+
// call the domain splitter
|
|
28486
|
+
this.parts = [];
|
|
28487
|
+
this.parts.length = 2*this.MAX_SSE;
|
|
28488
|
+
let ratios = [];
|
|
28489
|
+
ratios.length = this.MAX_SSE;
|
|
28490
|
+
let n_saved = 0;
|
|
28491
|
+
|
|
28492
|
+
for (let i = 0; i < nsse; i++) {
|
|
28493
|
+
this.parts[2*i] = this.parts[2*i + 1] = 0;
|
|
28494
|
+
ratios[i] = 0.0;
|
|
28495
|
+
}
|
|
28496
|
+
|
|
28497
|
+
n_saved = this.new_split_chain(nsse, sratio, minSize, minSSE, maxCsz, avgCts, cDelta, ncFact, this.parts, n_saved, ratios);
|
|
28498
|
+
|
|
28499
|
+
// save domain data
|
|
28500
|
+
//list< vector< let > > list_parts;
|
|
28501
|
+
let list_parts = [];
|
|
28502
|
+
|
|
28503
|
+
if (n_saved > 0) {
|
|
28504
|
+
// splits occurred...
|
|
28505
|
+
let j = 0;
|
|
28506
|
+
|
|
28507
|
+
for (let i = 0; i <= n_saved; i++) {
|
|
28508
|
+
//vector<int> sselst;
|
|
28509
|
+
let sselst = [];
|
|
28510
|
+
//sselst.clear();
|
|
28511
|
+
|
|
28512
|
+
while (j < 2*nsse) {
|
|
28513
|
+
let sse0 = this.parts[j++];
|
|
28514
|
+
|
|
28515
|
+
if (sse0 == 0) {
|
|
28516
|
+
list_parts.push(sselst);
|
|
28517
|
+
break;
|
|
28518
|
+
}
|
|
28519
|
+
else
|
|
28520
|
+
sselst.push(sse0);
|
|
28521
|
+
}
|
|
28522
|
+
}
|
|
28523
|
+
}
|
|
28524
|
+
|
|
28525
|
+
list_parts.sort(function(v1, v2) {
|
|
28526
|
+
return v1[0] - v2[0];
|
|
28527
|
+
});
|
|
28528
|
+
|
|
28529
|
+
// determine residue ranges for each subdomain
|
|
28530
|
+
let subdomains = [];
|
|
28531
|
+
|
|
28532
|
+
//for (lplet = list_parts.begin(); lplet != list_parts.end(); lpint++) {
|
|
28533
|
+
for (let index = 0, indexl = list_parts.length; index < indexl; ++index) {
|
|
28534
|
+
//vector<int> prts = *lpint;
|
|
28535
|
+
let prts = list_parts[index];
|
|
28536
|
+
//vector<int> resflags;
|
|
28537
|
+
//resflags.clear();
|
|
28538
|
+
let resflags = [];
|
|
28539
|
+
|
|
28540
|
+
// a domain must have at least 3 SSEs...
|
|
28541
|
+
if (prts.length <= 2) continue;
|
|
28542
|
+
|
|
28543
|
+
for (let i = 0; i < seqLen; i++)
|
|
28544
|
+
resflags.push(0);
|
|
28545
|
+
|
|
28546
|
+
for (let i = 0; i < prts.length; i++) {
|
|
28547
|
+
let k = prts[i] - 1;
|
|
28548
|
+
|
|
28549
|
+
if ((k < 0) || (k >= substruct.length)) {
|
|
28550
|
+
return;
|
|
28551
|
+
}
|
|
28552
|
+
|
|
28553
|
+
//SSE_Rec sserec = substruct[k];
|
|
28554
|
+
let sserec = substruct[k];
|
|
28555
|
+
let From = sserec.From;
|
|
28556
|
+
let To = sserec.To;
|
|
28557
|
+
|
|
28558
|
+
for (let j = From; j <= To; j++)
|
|
28559
|
+
resflags[j - 1] = 1;
|
|
28560
|
+
|
|
28561
|
+
if ((k == 0) && (From > 1)) {
|
|
28562
|
+
// residues with negative residue numbers will not be included
|
|
28563
|
+
for (let j = 1; j < From; j++)
|
|
28564
|
+
resflags[j - 1] = 1;
|
|
28565
|
+
}
|
|
28566
|
+
|
|
28567
|
+
if ((k == substruct.length - 1) && (To < seqLen)) {
|
|
28568
|
+
for (let j = To + 1; j <= seqLen; j++)
|
|
28569
|
+
resflags[j - 1] = 1;
|
|
28570
|
+
}
|
|
28571
|
+
|
|
28572
|
+
// left side
|
|
28573
|
+
if (k > 0) {
|
|
28574
|
+
//SSE_Rec sserec1 = substruct[k - 1];
|
|
28575
|
+
let sserec1 = substruct[k - 1];
|
|
28576
|
+
let To1 = sserec1.To;
|
|
28577
|
+
//let ll = (int) floor(0.5*((let) (From - To1 - 1)));
|
|
28578
|
+
let ll = parseInt(0.5 * (From - To1 - 1));
|
|
28579
|
+
|
|
28580
|
+
if (ll > 0) {
|
|
28581
|
+
for (let j = From - ll; j <= From - 1; j++)
|
|
28582
|
+
resflags[j - 1] = 1;
|
|
28583
|
+
}
|
|
28584
|
+
}
|
|
28585
|
+
|
|
28586
|
+
// right side
|
|
28587
|
+
if (k < substruct.length - 1) {
|
|
28588
|
+
//SSE_Rec sserec1 = substruct[k + 1];
|
|
28589
|
+
let sserec1 = substruct[k + 1];
|
|
28590
|
+
let From1 = sserec1.From;
|
|
28591
|
+
//let ll = (int) ceil(0.5*((let) (From1 - To - 1)));
|
|
28592
|
+
// let ft = From1 - To - 1;
|
|
28593
|
+
// let ll = parseInt(ft/2);
|
|
28594
|
+
// if (ft % 2 == 1) ll++;
|
|
28595
|
+
let ll = parseInt(0.5 * (From1 - To - 1) + 0.5);
|
|
28596
|
+
|
|
28597
|
+
if (ll > 0) {
|
|
28598
|
+
for (let j = To + 1; j <= To + ll; j++)
|
|
28599
|
+
resflags[j - 1] = 1;
|
|
28600
|
+
}
|
|
28601
|
+
}
|
|
28602
|
+
}
|
|
28603
|
+
|
|
28604
|
+
// extract the continguous segments
|
|
28605
|
+
let inseg = false;
|
|
28606
|
+
let startseg;
|
|
28607
|
+
//vector<int> segments;
|
|
28608
|
+
//segments.clear();
|
|
28609
|
+
let segments = [];
|
|
28610
|
+
|
|
28611
|
+
for (let i = 0; i < seqLen; i++) {
|
|
28612
|
+
let rf = resflags[i];
|
|
28613
|
+
|
|
28614
|
+
if (!inseg && (rf == 1)) {
|
|
28615
|
+
// new segment starts here
|
|
28616
|
+
startseg = i + 1;
|
|
28617
|
+
inseg = true;
|
|
28618
|
+
continue;
|
|
28619
|
+
}
|
|
28620
|
+
|
|
28621
|
+
if (inseg && (rf == 0)) {
|
|
28622
|
+
// segment ends
|
|
28623
|
+
segments.push(startseg);
|
|
28624
|
+
segments.push(i);
|
|
28625
|
+
inseg = false;
|
|
28626
|
+
}
|
|
28627
|
+
}
|
|
28628
|
+
|
|
28629
|
+
// check for the last segment
|
|
28630
|
+
if (inseg) {
|
|
28631
|
+
segments.push(startseg);
|
|
28632
|
+
segments.push(seqLen);
|
|
28633
|
+
}
|
|
28634
|
+
|
|
28635
|
+
subdomains.push(segments);
|
|
28636
|
+
}
|
|
28637
|
+
|
|
28638
|
+
//console.log("subdomains: " + JSON.stringify(subdomains));
|
|
28639
|
+
|
|
28640
|
+
return subdomains;
|
|
28641
|
+
} // end c2b_NewSplitChain
|
|
28642
|
+
}
|
|
28643
|
+
|
|
27584
28644
|
/**
|
|
27585
28645
|
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
27586
28646
|
*/
|
|
@@ -29902,6 +30962,8 @@ class Picking {
|
|
|
29902
30962
|
transformation.quaternion._y = parseFloat(ic.quaternion._y).toPrecision(5);
|
|
29903
30963
|
transformation.quaternion._z = parseFloat(ic.quaternion._z).toPrecision(5);
|
|
29904
30964
|
transformation.quaternion._w = parseFloat(ic.quaternion._w).toPrecision(5);
|
|
30965
|
+
|
|
30966
|
+
/*
|
|
29905
30967
|
if(ic.bAddCommands) {
|
|
29906
30968
|
ic.commands.push('pickatom ' + atom.serial + '|||' + ic.transformCls.getTransformationStr(transformation));
|
|
29907
30969
|
ic.optsHistory.push(me.hashUtilsCls.cloneHash(ic.opts));
|
|
@@ -29913,6 +30975,9 @@ class Picking {
|
|
|
29913
30975
|
if( $( "#" + ic.pre + "logtext" ).length ) {
|
|
29914
30976
|
$("#" + ic.pre + "logtext").val("> " + ic.logs.join("\n> ") + "\n> ").scrollTop($("#" + ic.pre + "logtext")[0].scrollHeight);
|
|
29915
30977
|
}
|
|
30978
|
+
*/
|
|
30979
|
+
me.htmlCls.clickMenuCls.setLogCmd('pickatom ' + atom.serial, true);
|
|
30980
|
+
|
|
29916
30981
|
// update the interaction flag
|
|
29917
30982
|
ic.bSphereCalc = false;
|
|
29918
30983
|
//me.htmlCls.clickMenuCls.setLogCmd('set calculate sphere false', true);
|
|
@@ -31289,11 +32354,16 @@ class ApplyCommand {
|
|
|
31289
32354
|
ic.bGlycansCartoon = false;
|
|
31290
32355
|
}
|
|
31291
32356
|
}
|
|
32357
|
+
else if(command.indexOf('save html') == 0) {
|
|
32358
|
+
let id = command.substr(command.lastIndexOf(' ') + 1);
|
|
32359
|
+
me.htmlCls.eventsCls.saveHtml(id);
|
|
32360
|
+
}
|
|
31292
32361
|
|
|
31293
32362
|
// special, select ==========
|
|
31294
32363
|
|
|
31295
32364
|
else if(command.indexOf('select displayed set') !== -1) {
|
|
31296
|
-
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
32365
|
+
//ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
32366
|
+
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.viewSelectionAtoms);
|
|
31297
32367
|
ic.hlUpdateCls.updateHlAll();
|
|
31298
32368
|
}
|
|
31299
32369
|
else if(command.indexOf('select prop') !== -1) {
|
|
@@ -32140,11 +33210,12 @@ class Resid2spec {
|
|
|
32140
33210
|
|
|
32141
33211
|
atoms2spec(atomHash) {var ic = this.icn3d; ic.icn3dui;
|
|
32142
33212
|
let spec = "";
|
|
32143
|
-
|
|
32144
33213
|
let i = 0;
|
|
32145
33214
|
let structureHash = {}, chainHash = {}, resiHash = {};
|
|
33215
|
+
|
|
33216
|
+
let atom;
|
|
32146
33217
|
for(let serial in atomHash) {
|
|
32147
|
-
|
|
33218
|
+
atom = ic.atoms[serial];
|
|
32148
33219
|
if(i > 0) {
|
|
32149
33220
|
spec += ' or ';
|
|
32150
33221
|
}
|
|
@@ -35203,7 +36274,7 @@ class ShowAnno {
|
|
|
35203
36274
|
// the missing residues at the end of the seq will be filled up in the API showNewTrack()
|
|
35204
36275
|
let nGap = 0;
|
|
35205
36276
|
ic.alnChainsSeq[chnid] = [];
|
|
35206
|
-
let offset =(ic.chainid2offset[chnid]) ? ic.chainid2offset[chnid] : 0;
|
|
36277
|
+
let offset =(ic.chainid2offset[chnid]) ? ic.chainid2offset[chnid] : 0;
|
|
35207
36278
|
for(let i = 0, il = targetSeq.length; i < il; ++i) {
|
|
35208
36279
|
//text += ic.showSeqCls.insertGap(chnid, i, '-', true);
|
|
35209
36280
|
if(ic.targetGapHash.hasOwnProperty(i)) {
|
|
@@ -35576,7 +36647,8 @@ class AnnoDomain {
|
|
|
35576
36647
|
let pdbArray = Object.keys(ic.structures);
|
|
35577
36648
|
// show 3D domains
|
|
35578
36649
|
let pdbid = pdbArray[index];
|
|
35579
|
-
|
|
36650
|
+
me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&domain&molinfor&uid=" + pdbid;
|
|
36651
|
+
|
|
35580
36652
|
if(index == 0 && ic.mmdb_data !== undefined) {
|
|
35581
36653
|
for(let chnid in ic.protein_chainid) {
|
|
35582
36654
|
if(chnid.indexOf(pdbid) !== -1) {
|
|
@@ -35592,6 +36664,43 @@ class AnnoDomain {
|
|
|
35592
36664
|
}
|
|
35593
36665
|
}
|
|
35594
36666
|
else {
|
|
36667
|
+
// calculate 3D domains on-the-fly
|
|
36668
|
+
//ic.protein_chainid[chainArray[i]]
|
|
36669
|
+
let data = {};
|
|
36670
|
+
data.domains = {};
|
|
36671
|
+
for(let chainid in ic.chains) {
|
|
36672
|
+
let structure = chainid.substr(0, chainid.indexOf('_'));
|
|
36673
|
+
if(pdbid == structure && ic.protein_chainid.hasOwnProperty(chainid)) {
|
|
36674
|
+
data.domains[chainid] = {};
|
|
36675
|
+
data.domains[chainid].domains = [];
|
|
36676
|
+
|
|
36677
|
+
let subdomains = ic.domain3dCls.c2b_NewSplitChain(chainid);
|
|
36678
|
+
for(let i = 0, il = subdomains.length; i < il; ++i) {
|
|
36679
|
+
// domain item: {"sdid":1722375,"intervals":[[1,104],[269,323]]}
|
|
36680
|
+
let domain = {};
|
|
36681
|
+
domain.intervals = [];
|
|
36682
|
+
|
|
36683
|
+
for(let j = 0, jl = subdomains[i].length; j < jl; j += 2) {
|
|
36684
|
+
domain.intervals.push([subdomains[i][j], subdomains[i][j+1]]);
|
|
36685
|
+
}
|
|
36686
|
+
|
|
36687
|
+
data.domains[chainid].domains.push(domain);
|
|
36688
|
+
}
|
|
36689
|
+
}
|
|
36690
|
+
}
|
|
36691
|
+
|
|
36692
|
+
ic.mmdb_dataArray[index] = data;
|
|
36693
|
+
let bCalcDirect = true;
|
|
36694
|
+
for(let chnid in ic.protein_chainid) {
|
|
36695
|
+
if(chnid.indexOf(pdbid) !== -1) {
|
|
36696
|
+
thisClass.showDomainWithData(chnid, ic.mmdb_dataArray[index], bCalcDirect);
|
|
36697
|
+
}
|
|
36698
|
+
}
|
|
36699
|
+
|
|
36700
|
+
ic.bAjax3ddomain = true;
|
|
36701
|
+
ic.bAjaxDoneArray[index] = true;
|
|
36702
|
+
|
|
36703
|
+
/*
|
|
35595
36704
|
$.ajax({
|
|
35596
36705
|
url: url,
|
|
35597
36706
|
dataType: 'json',
|
|
@@ -35655,6 +36764,7 @@ class AnnoDomain {
|
|
|
35655
36764
|
return;
|
|
35656
36765
|
}
|
|
35657
36766
|
});
|
|
36767
|
+
*/
|
|
35658
36768
|
}
|
|
35659
36769
|
}
|
|
35660
36770
|
|
|
@@ -35673,28 +36783,36 @@ class AnnoDomain {
|
|
|
35673
36783
|
this.showDomainPerStructure(i);
|
|
35674
36784
|
}
|
|
35675
36785
|
}
|
|
35676
|
-
showDomainWithData(chnid, data) { let ic = this.icn3d, me = ic.icn3dui;
|
|
36786
|
+
showDomainWithData(chnid, data, bCalcDirect) { let ic = this.icn3d, me = ic.icn3dui;
|
|
35677
36787
|
let html = '<div id="' + ic.pre + chnid + '_domainseq_sequence" class="icn3d-dl_sequence">';
|
|
35678
36788
|
let html2 = html;
|
|
35679
36789
|
let html3 = html;
|
|
35680
36790
|
let domainArray, proteinname;
|
|
35681
36791
|
let pos = chnid.indexOf('_');
|
|
35682
36792
|
let chain = chnid.substr(pos + 1);
|
|
35683
|
-
|
|
35684
|
-
|
|
35685
|
-
|
|
35686
|
-
|
|
35687
|
-
currMolid = molid;
|
|
35688
|
-
proteinname = molinfo[molid].name;
|
|
35689
|
-
break;
|
|
35690
|
-
}
|
|
35691
|
-
}
|
|
35692
|
-
if(currMolid !== undefined && data.domains[currMolid] !== undefined) {
|
|
35693
|
-
domainArray = data.domains[currMolid].domains;
|
|
36793
|
+
|
|
36794
|
+
if(bCalcDirect) {
|
|
36795
|
+
proteinname = chnid;
|
|
36796
|
+
domainArray = data.domains[chnid].domains;
|
|
35694
36797
|
}
|
|
35695
|
-
|
|
35696
|
-
|
|
36798
|
+
else {
|
|
36799
|
+
let molinfo = data.moleculeInfor;
|
|
36800
|
+
let currMolid;
|
|
36801
|
+
for(let molid in molinfo) {
|
|
36802
|
+
if(molinfo[molid].chain === chain) {
|
|
36803
|
+
currMolid = molid;
|
|
36804
|
+
proteinname = molinfo[molid].name;
|
|
36805
|
+
break;
|
|
36806
|
+
}
|
|
36807
|
+
}
|
|
36808
|
+
if(currMolid !== undefined && data.domains[currMolid] !== undefined) {
|
|
36809
|
+
domainArray = data.domains[currMolid].domains;
|
|
36810
|
+
}
|
|
36811
|
+
if(domainArray === undefined) {
|
|
36812
|
+
domainArray = [];
|
|
36813
|
+
}
|
|
35697
36814
|
}
|
|
36815
|
+
|
|
35698
36816
|
for(let index = 0, indexl = domainArray.length; index < indexl; ++index) {
|
|
35699
36817
|
//var fulltitle = '3D domain ' +(index+1).toString() + ' of ' + proteinname + '(PDB ID: ' + data.pdbId + ')';
|
|
35700
36818
|
let fulltitle = '3D domain ' +(index+1).toString() + ' of ' + proteinname;
|
|
@@ -35717,7 +36835,7 @@ class AnnoDomain {
|
|
|
35717
36835
|
}
|
|
35718
36836
|
|
|
35719
36837
|
// use the NCBI residue number, and convert to PDB residue number during selection
|
|
35720
|
-
if(ic.bNCBI) {
|
|
36838
|
+
if(ic.bNCBI || bCalcDirect) {
|
|
35721
36839
|
fromArray.push(domainFrom);
|
|
35722
36840
|
toArray.push(domainTo);
|
|
35723
36841
|
}
|
|
@@ -38507,8 +39625,11 @@ class Selection {
|
|
|
38507
39625
|
|
|
38508
39626
|
for(let i in ic.chains) {
|
|
38509
39627
|
ic.hAtoms = me.hashUtilsCls.unionHash(ic.hAtoms, ic.chains[i]);
|
|
38510
|
-
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chains[i]);
|
|
39628
|
+
//ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chains[i]);
|
|
38511
39629
|
}
|
|
39630
|
+
|
|
39631
|
+
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
39632
|
+
ic.viewSelectionAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
38512
39633
|
}
|
|
38513
39634
|
|
|
38514
39635
|
//Select a chain with the chain id "chainid" in the sequence dialog and save it as a custom selection with the name "commandname".
|
|
@@ -38743,6 +39864,7 @@ class Selection {
|
|
|
38743
39864
|
if(Object.keys(ic.hAtoms).length == 0) this.selectAll_base();
|
|
38744
39865
|
|
|
38745
39866
|
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
39867
|
+
ic.viewSelectionAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
38746
39868
|
|
|
38747
39869
|
let centerAtomsResults = ic.applyCenterCls.centerAtoms(me.hashUtilsCls.hash2Atoms(ic.dAtoms, ic.atoms));
|
|
38748
39870
|
ic.maxD = centerAtomsResults.maxD;
|
|
@@ -40999,8 +42121,9 @@ class ApplySsbonds {
|
|
|
40999
42121
|
let start, end;
|
|
41000
42122
|
|
|
41001
42123
|
if(ic.bAlternate) {
|
|
41002
|
-
|
|
41003
|
-
|
|
42124
|
+
let nStructures = structureArray.length;
|
|
42125
|
+
start = ic.ALTERNATE_STRUCTURE % nStructures;
|
|
42126
|
+
end = ic.ALTERNATE_STRUCTURE % nStructures + 1;
|
|
41004
42127
|
}
|
|
41005
42128
|
else {
|
|
41006
42129
|
start = 0;
|
|
@@ -44291,7 +45414,8 @@ class ClickMenu {
|
|
|
44291
45414
|
// clkMn2_selectdisplayed: function() {
|
|
44292
45415
|
me.myEventCls.onIds("#" + me.pre + "mn2_selectdisplayed", "click", function(e) { let ic = me.icn3d;
|
|
44293
45416
|
thisClass.setLogCmd("select displayed set", true);
|
|
44294
|
-
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
45417
|
+
//ic.hAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
45418
|
+
ic.hAtoms = me.hashUtilsCls.cloneHash(ic.viewSelectionAtoms);
|
|
44295
45419
|
ic.hlUpdateCls.updateHlAll();
|
|
44296
45420
|
//ic.drawCls.draw();
|
|
44297
45421
|
});
|
|
@@ -45412,6 +46536,10 @@ class ClickMenu {
|
|
|
45412
46536
|
// },
|
|
45413
46537
|
// clkMn6_sidebyside: function() {
|
|
45414
46538
|
me.myEventCls.onIds("#" + me.pre + "mn6_sidebyside", "click", function(e) { let ic = me.icn3d;
|
|
46539
|
+
if(ic.bInputfile) {
|
|
46540
|
+
var aaa = 1; //alert("Side-by-Side does NOT work when the input is from a local file.");
|
|
46541
|
+
return;
|
|
46542
|
+
}
|
|
45415
46543
|
let url = ic.shareLinkCls.shareLinkUrl(undefined);
|
|
45416
46544
|
//if(url.indexOf('http') !== 0) {
|
|
45417
46545
|
// var aaa = 1; //alert("The url is more than 4000 characters and may not work.");
|
|
@@ -46019,6 +47147,8 @@ class SetMenu {
|
|
|
46019
47147
|
// show title at the top left corner
|
|
46020
47148
|
html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:block; margin: 12px 0px 0px 40px; color:" + titleColor + "; width:" +(me.htmlCls.WIDTH - 40).toString() + "px'></div>";
|
|
46021
47149
|
html += me.htmlCls.divStr + "viewer' style='position:relative; width:100%; height:100%; background-color: " + me.htmlCls.GREYD + ";'>";
|
|
47150
|
+
// don't show legend in mobile
|
|
47151
|
+
//html += me.htmlCls.divStr + "legend' class='icn3d-text icn3d-legend'></div>";
|
|
46022
47152
|
html += me.htmlCls.divStr + "mnLogSection'>";
|
|
46023
47153
|
html += "<div style='height: " + me.htmlCls.MENU_HEIGHT + "px;'></div>";
|
|
46024
47154
|
html += "</div>";
|
|
@@ -49176,6 +50306,18 @@ class Events {
|
|
|
49176
50306
|
}
|
|
49177
50307
|
}
|
|
49178
50308
|
|
|
50309
|
+
saveHtml(id) { let me = this.icn3dui, ic = me.icn3d;
|
|
50310
|
+
let html = '';
|
|
50311
|
+
html += '<link rel="stylesheet" href="https:///structure.ncbi.nlm.nih.gov/icn3d/lib/jquery-ui-1.12.1.min.css">\n';
|
|
50312
|
+
html += '<link rel="stylesheet" href="https:///structure.ncbi.nlm.nih.gov/icn3d/icn3d_full_ui.css">\n';
|
|
50313
|
+
html += $("#" + id).html();
|
|
50314
|
+
let idArray = id.split('_');
|
|
50315
|
+
let idStr =(idArray.length > 2) ? idArray[2] : id;
|
|
50316
|
+
let structureStr = Object.keys(ic.structures)[0];
|
|
50317
|
+
if(Object.keys(ic.structures).length > 1) structureStr += '-' + Object.keys(ic.structures)[1];
|
|
50318
|
+
ic.saveFileCls.saveFile(structureStr + '-' + idStr + '.html', 'html', encodeURIComponent(html));
|
|
50319
|
+
}
|
|
50320
|
+
|
|
49179
50321
|
//Hold all functions related to click events.
|
|
49180
50322
|
allEventFunctions() { let me = this.icn3dui, ic = me.icn3d;
|
|
49181
50323
|
let thisClass = this;
|
|
@@ -50837,18 +51979,12 @@ class Events {
|
|
|
50837
51979
|
});
|
|
50838
51980
|
// },
|
|
50839
51981
|
// clickSaveDialog: function() {
|
|
50840
|
-
$(document).on("click", ".icn3d-saveicon", function(e) {
|
|
51982
|
+
$(document).on("click", ".icn3d-saveicon", function(e) { me.icn3d;
|
|
50841
51983
|
e.stopImmediatePropagation();
|
|
50842
51984
|
let id = $(this).attr('pid');
|
|
50843
|
-
|
|
50844
|
-
|
|
50845
|
-
html
|
|
50846
|
-
html += $("#" + id).html();
|
|
50847
|
-
let idArray = id.split('_');
|
|
50848
|
-
let idStr =(idArray.length > 2) ? idArray[2] : id;
|
|
50849
|
-
let structureStr = Object.keys(ic.structures)[0];
|
|
50850
|
-
if(Object.keys(ic.structures).length > 1) structureStr += '-' + Object.keys(ic.structures)[1];
|
|
50851
|
-
ic.saveFileCls.saveFile(structureStr + '-' + idStr + '.html', 'html', encodeURIComponent(html));
|
|
51985
|
+
|
|
51986
|
+
thisClass.saveHtml(id);
|
|
51987
|
+
me.htmlCls.clickMenuCls.setLogCmd("save html " + id, true);
|
|
50852
51988
|
});
|
|
50853
51989
|
// },
|
|
50854
51990
|
// clickHideDialog: function() {
|
|
@@ -52363,38 +53499,66 @@ class Alternate {
|
|
|
52363
53499
|
// change the display atom when alternating
|
|
52364
53500
|
//Show structures one by one.
|
|
52365
53501
|
alternateStructures() { let ic = this.icn3d, me = ic.icn3dui;
|
|
52366
|
-
|
|
53502
|
+
if(!ic.viewSelectionAtoms) {
|
|
53503
|
+
ic.viewSelectionAtoms = me.hashUtilsCls.cloneHash(ic.dAtoms);
|
|
53504
|
+
}
|
|
53505
|
+
|
|
53506
|
+
let viewSelectionAtomsCount = Object.keys(ic.viewSelectionAtoms).length;
|
|
52367
53507
|
let allAtomsCount = Object.keys(ic.atoms).length;
|
|
52368
53508
|
|
|
52369
53509
|
ic.dAtoms = {};
|
|
52370
53510
|
|
|
53511
|
+
// alternate all displayed structures
|
|
53512
|
+
let moleculeArray = Object.keys(ic.structures);
|
|
52371
53513
|
// only alternate selected structures
|
|
52372
|
-
//let
|
|
52373
|
-
let
|
|
52374
|
-
|
|
52375
|
-
|
|
52376
|
-
|
|
52377
|
-
|
|
52378
|
-
let moleculeArray = Object.keys(structureHash);
|
|
53514
|
+
// let structureHash = {};
|
|
53515
|
+
// for(let i in ic.hAtoms) {
|
|
53516
|
+
// let structure = ic.atoms[i].structure;
|
|
53517
|
+
// structureHash[structure] = 1;
|
|
53518
|
+
// }
|
|
53519
|
+
// let moleculeArray = Object.keys(structureHash);
|
|
52379
53520
|
|
|
52380
53521
|
for(let i = 0, il = moleculeArray.length; i < il; ++i) {
|
|
52381
53522
|
let structure = moleculeArray[i];
|
|
52382
|
-
if(i > ic.ALTERNATE_STRUCTURE || (ic.ALTERNATE_STRUCTURE === il - 1 && i === 0) ) {
|
|
53523
|
+
//if(i > ic.ALTERNATE_STRUCTURE || (ic.ALTERNATE_STRUCTURE === il - 1 && i === 0) ) {
|
|
53524
|
+
let bChoose;
|
|
53525
|
+
if(ic.bShift) {
|
|
53526
|
+
// default ic.ALTERNATE_STRUCTURE = -1
|
|
53527
|
+
if(ic.ALTERNATE_STRUCTURE < 0) ic.ALTERNATE_STRUCTURE = 1;
|
|
53528
|
+
|
|
53529
|
+
bChoose = (i == ic.ALTERNATE_STRUCTURE % il - 1)
|
|
53530
|
+
|| (ic.ALTERNATE_STRUCTURE % il === 0 && i === il - 1);
|
|
53531
|
+
}
|
|
53532
|
+
else {
|
|
53533
|
+
bChoose = (i == ic.ALTERNATE_STRUCTURE % il + 1)
|
|
53534
|
+
|| (ic.ALTERNATE_STRUCTURE % il === il - 1 && i === 0);
|
|
53535
|
+
}
|
|
53536
|
+
|
|
53537
|
+
if(bChoose) {
|
|
52383
53538
|
for(let k in ic.structures[structure]) {
|
|
52384
53539
|
let chain = ic.structures[structure][k];
|
|
52385
53540
|
ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, ic.chains[chain]);
|
|
52386
53541
|
}
|
|
52387
53542
|
|
|
52388
|
-
ic.ALTERNATE_STRUCTURE = i;
|
|
53543
|
+
//ic.ALTERNATE_STRUCTURE = i;
|
|
53544
|
+
if(ic.bShift) {
|
|
53545
|
+
--ic.ALTERNATE_STRUCTURE;
|
|
53546
|
+
}
|
|
53547
|
+
else {
|
|
53548
|
+
++ic.ALTERNATE_STRUCTURE;
|
|
53549
|
+
}
|
|
53550
|
+
|
|
53551
|
+
if(ic.ALTERNATE_STRUCTURE < 0) ic.ALTERNATE_STRUCTURE += il;
|
|
52389
53552
|
|
|
52390
53553
|
$("#" + ic.pre + "title").html(structure);
|
|
52391
53554
|
|
|
52392
53555
|
break;
|
|
52393
53556
|
}
|
|
52394
|
-
}
|
|
53557
|
+
}
|
|
52395
53558
|
|
|
52396
|
-
if(
|
|
52397
|
-
ic.dAtoms = me.hashUtilsCls.intHash(ic.dAtoms, ic.hAtoms);
|
|
53559
|
+
if(viewSelectionAtomsCount < allAtomsCount) {
|
|
53560
|
+
//ic.dAtoms = me.hashUtilsCls.intHash(ic.dAtoms, ic.hAtoms);
|
|
53561
|
+
ic.dAtoms = me.hashUtilsCls.intHash(ic.dAtoms, ic.viewSelectionAtoms);
|
|
52398
53562
|
|
|
52399
53563
|
ic.bShowHighlight = false;
|
|
52400
53564
|
ic.opts['rotationcenter'] = 'highlight center';
|
|
@@ -54927,7 +56091,7 @@ class Control {
|
|
|
54927
56091
|
|
|
54928
56092
|
else if(e.keyCode === 65 ) { // A, alternate
|
|
54929
56093
|
if(Object.keys(ic.structures).length > 1) {
|
|
54930
|
-
|
|
56094
|
+
ic.alternateCls.alternateWrapper();
|
|
54931
56095
|
}
|
|
54932
56096
|
}
|
|
54933
56097
|
|
|
@@ -55474,6 +56638,7 @@ class iCn3D {
|
|
|
55474
56638
|
this.annoSnpClinVarCls = new AnnoSnpClinVar(this);
|
|
55475
56639
|
this.annoSsbondCls = new AnnoSsbond(this);
|
|
55476
56640
|
this.annoTransMemCls = new AnnoTransMem(this);
|
|
56641
|
+
this.domain3dCls = new Domain3d(this);
|
|
55477
56642
|
|
|
55478
56643
|
this.addTrackCls = new AddTrack(this);
|
|
55479
56644
|
this.annotationCls = new Annotation(this);
|
|
@@ -55726,7 +56891,7 @@ class iCn3DUI {
|
|
|
55726
56891
|
//even when multiple iCn3D viewers are shown together.
|
|
55727
56892
|
this.pre = this.cfg.divid + "_";
|
|
55728
56893
|
|
|
55729
|
-
this.REVISION = '3.
|
|
56894
|
+
this.REVISION = '3.9.0';
|
|
55730
56895
|
|
|
55731
56896
|
// In nodejs, iCn3D defines "window = {navigator: {}}"
|
|
55732
56897
|
this.bNode = (Object.keys(window).length < 2) ? true : false;
|
|
@@ -56241,6 +57406,7 @@ exports.Delphi = Delphi;
|
|
|
56241
57406
|
exports.DensityCifParser = DensityCifParser;
|
|
56242
57407
|
exports.Diagram2d = Diagram2d;
|
|
56243
57408
|
exports.Dialog = Dialog;
|
|
57409
|
+
exports.Domain3d = Domain3d;
|
|
56244
57410
|
exports.Draw = Draw;
|
|
56245
57411
|
exports.DrawGraph = DrawGraph;
|
|
56246
57412
|
exports.Dsn6Parser = Dsn6Parser;
|