icn3d 3.12.3 → 3.12.7
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 +919 -255
- package/icn3d.min.js +1 -1
- package/icn3d.module.js +919 -255
- package/package.json +1 -1
package/icn3d.js
CHANGED
|
@@ -11762,7 +11762,7 @@ class ShareLink {
|
|
|
11762
11762
|
if(bPngHtml) url += "&random=" + parseInt(Math.random() * 1000); // generate a new shorten URL and thus image name everytime
|
|
11763
11763
|
//var inputid =(ic.inputid) ? ic.inputid : "custom";
|
|
11764
11764
|
let inputid = Object.keys(ic.structures).join('_');
|
|
11765
|
-
if(inputid == '
|
|
11765
|
+
if(inputid == 'stru') {
|
|
11766
11766
|
if(ic.filename) {
|
|
11767
11767
|
inputid = ic.filename;
|
|
11768
11768
|
}
|
|
@@ -16811,7 +16811,7 @@ class ViewInterPairs {
|
|
|
16811
16811
|
ic.bGraph = true;
|
|
16812
16812
|
// show only displayed set in 2D graph
|
|
16813
16813
|
if(Object.keys(atomSet2).length + Object.keys(atomSet1).length > Object.keys(ic.dAtoms).length) {
|
|
16814
|
-
ic.graphStr = ic.
|
|
16814
|
+
ic.graphStr = ic.selectionCls.getGraphDataForDisplayed();
|
|
16815
16815
|
}
|
|
16816
16816
|
|
|
16817
16817
|
if(ic.bD3 === undefined) {
|
|
@@ -19494,13 +19494,14 @@ class Scap {
|
|
|
19494
19494
|
//snp: 6M0J_E_484_K,6M0J_E_501_Y,6M0J_E_417_N
|
|
19495
19495
|
let snpStr = '';
|
|
19496
19496
|
let snpArray = snp.split(','); //stru_chain_resi_snp
|
|
19497
|
-
let atomHash = {}, snpResidArray = [];
|
|
19497
|
+
let atomHash = {}, snpResidArray = [], chainResi2pdb = {};
|
|
19498
19498
|
for(let i = 0, il = snpArray.length; i < il; ++i) {
|
|
19499
19499
|
let idArray = snpArray[i].split('_'); //stru_chain_resi_snp
|
|
19500
19500
|
|
|
19501
19501
|
let resid = idArray[0] + '_' + idArray[1] + '_' + idArray[2];
|
|
19502
19502
|
atomHash = me.hashUtilsCls.unionHash(atomHash, ic.residues[resid]);
|
|
19503
19503
|
snpResidArray.push(resid);
|
|
19504
|
+
chainResi2pdb[idArray[1] + '_' + idArray[2]] = '';
|
|
19504
19505
|
|
|
19505
19506
|
snpStr += idArray[1] + '_' + idArray[2] + '_' + idArray[3];
|
|
19506
19507
|
if(i != il -1) snpStr += ',';
|
|
@@ -19534,7 +19535,7 @@ class Scap {
|
|
|
19534
19535
|
/// let pdbStr = ic.saveFileCls.getPDBHeader() + ic.saveFileCls.getAtomPDB(ic.hAtoms);
|
|
19535
19536
|
let pdbStr = ic.saveFileCls.getAtomPDB(ic.hAtoms);
|
|
19536
19537
|
|
|
19537
|
-
let url =
|
|
19538
|
+
let url = me.htmlCls.baseUrl + "scap/scap.cgi";
|
|
19538
19539
|
|
|
19539
19540
|
let pdbid = Object.keys(ic.structures)[0]; //Object.keys(ic.structures).toString();
|
|
19540
19541
|
let dataObj = {'pdb': pdbStr, 'snp': snpStr, 'pdbid': pdbid, 'v': '2'};
|
|
@@ -19574,19 +19575,64 @@ class Scap {
|
|
|
19574
19575
|
ic.chainsMapping[chainid][resid] = me.utilsCls.residueName2Abbr(atom.resn) + atom.resi;
|
|
19575
19576
|
}
|
|
19576
19577
|
|
|
19578
|
+
//ic.hAtoms = {};
|
|
19579
|
+
//ic.loadPDBCls.loadPDB(pdbData, pdbid, false, false, bAddition);
|
|
19580
|
+
//let hAtom2 = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
19581
|
+
|
|
19582
|
+
// get the mutant pdb
|
|
19583
|
+
let lines = pdbData.split('\n');
|
|
19584
|
+
let allChainResiHash = {};
|
|
19585
|
+
for (let i in lines) {
|
|
19586
|
+
let line = lines[i];
|
|
19587
|
+
let record = line.substr(0, 6);
|
|
19588
|
+
|
|
19589
|
+
if (record === 'ATOM ' || record === 'HETATM') {
|
|
19590
|
+
let chain = line.substr(20, 2).trim();
|
|
19591
|
+
if(chain === '') chain = 'A';
|
|
19592
|
+
|
|
19593
|
+
let resi = line.substr(22, 5).trim();
|
|
19594
|
+
let chainResi = chain + '_' + resi;
|
|
19595
|
+
|
|
19596
|
+
if(chainResi2pdb.hasOwnProperty(chainResi)) {
|
|
19597
|
+
chainResi2pdb[chainResi] += line + '\n';
|
|
19598
|
+
}
|
|
19599
|
+
|
|
19600
|
+
allChainResiHash[chainResi] = 1;
|
|
19601
|
+
}
|
|
19602
|
+
}
|
|
19603
|
+
|
|
19604
|
+
// get the full mutatnt PDB
|
|
19605
|
+
let pdbDataMutant = ic.saveFileCls.getAtomPDB(ic.atoms, false, false, false, chainResi2pdb);
|
|
19577
19606
|
ic.hAtoms = {};
|
|
19578
|
-
|
|
19579
|
-
|
|
19607
|
+
let bMutation = true;
|
|
19608
|
+
ic.loadPDBCls.loadPDB(pdbDataMutant, pdbid, false, false, bMutation, bAddition);
|
|
19609
|
+
//let allAtoms2 = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
19610
|
+
|
|
19611
|
+
ic.setStyleCls.setAtomStyleByOptions(ic.opts);
|
|
19612
|
+
ic.setColorCls.setColorByOptions(ic.opts, ic.hAtoms);
|
|
19613
|
+
|
|
19614
|
+
// get the mutant residues in the sphere
|
|
19615
|
+
let hAtom2 = {};
|
|
19616
|
+
for(let serial in ic.hAtoms) {
|
|
19617
|
+
let atom = ic.atoms[serial];
|
|
19618
|
+
let chainResi = atom.chain + '_' + atom.resi;
|
|
19619
|
+
if(allChainResiHash.hasOwnProperty(chainResi)) {
|
|
19620
|
+
hAtom2[serial] = 1;
|
|
19621
|
+
}
|
|
19622
|
+
}
|
|
19580
19623
|
|
|
19581
|
-
ic.hAtoms = me.hashUtilsCls.unionHash(
|
|
19582
|
-
ic.
|
|
19624
|
+
ic.hAtoms = me.hashUtilsCls.unionHash(hAtom1, hAtom2);
|
|
19625
|
+
//ic.hAtoms = me.hashUtilsCls.unionHash(hAtom1, allAtoms2);
|
|
19626
|
+
ic.dAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
19627
|
+
//ic.dAtoms = ic.hAtoms;
|
|
19583
19628
|
|
|
19584
19629
|
ic.transformCls.zoominSelection();
|
|
19585
19630
|
ic.setOptionCls.setStyle('proteins', 'stick');
|
|
19586
19631
|
|
|
19587
|
-
ic.opts['color'] = 'chain';
|
|
19588
|
-
ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
|
|
19632
|
+
//ic.opts['color'] = 'chain';
|
|
19633
|
+
//ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
|
|
19589
19634
|
for(let serial in hAtom2) {
|
|
19635
|
+
//for(let serial in allAtoms2) {
|
|
19590
19636
|
let atom = ic.atoms[serial];
|
|
19591
19637
|
if(!atom.het) {
|
|
19592
19638
|
// use the same color as the wild type
|
|
@@ -19613,13 +19659,19 @@ class Scap {
|
|
|
19613
19659
|
}
|
|
19614
19660
|
}
|
|
19615
19661
|
|
|
19662
|
+
// ic.hAtoms = me.hashUtilsCls.unionHash(hAtom1, hAtoms2);
|
|
19663
|
+
// ic.dAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
|
|
19664
|
+
// //ic.dAtoms = ic.hAtoms;
|
|
19665
|
+
|
|
19666
|
+
// ic.transformCls.zoominSelection();
|
|
19667
|
+
// ic.setOptionCls.setStyle('proteins', 'stick');
|
|
19668
|
+
|
|
19616
19669
|
if(bPdb) {
|
|
19617
|
-
let pdbStr = '';
|
|
19618
|
-
|
|
19619
|
-
pdbStr += ic.saveFileCls.getAtomPDB(ic.hAtoms);
|
|
19670
|
+
//let pdbStr = '';
|
|
19671
|
+
//pdbStr += ic.saveFileCls.getAtomPDB(ic.hAtoms);
|
|
19620
19672
|
|
|
19621
19673
|
let file_pref =(ic.inputid) ? ic.inputid : "custom";
|
|
19622
|
-
ic.saveFileCls.saveFile(file_pref + '_' + snpStr + '.pdb', 'text', [
|
|
19674
|
+
ic.saveFileCls.saveFile(file_pref + '_' + snpStr + '.pdb', 'text', [pdbDataMutant]);
|
|
19623
19675
|
|
|
19624
19676
|
ic.drawCls.draw();
|
|
19625
19677
|
}
|
|
@@ -20320,23 +20372,23 @@ class LoadPDB {
|
|
|
20320
20372
|
}
|
|
20321
20373
|
else {
|
|
20322
20374
|
// remove the last structure
|
|
20323
|
-
if(ic.alertAlt) {
|
|
20324
|
-
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
}
|
|
20337
|
-
else {
|
|
20375
|
+
// if(ic.alertAlt) {
|
|
20376
|
+
// let nStru = ic.oriNStru + 1; //Object.keys(ic.structures).length;
|
|
20377
|
+
// let chainArray = ic.structures[nStru - 1];
|
|
20378
|
+
// for(let i = 0, il = (chainArray) ? chainArray.length : 0; i < il; ++i) {
|
|
20379
|
+
// for(let j in ic.chains[chainArray[i]]) {
|
|
20380
|
+
// delete ic.atoms[j];
|
|
20381
|
+
// delete ic.hAtoms[j];
|
|
20382
|
+
// delete ic.dAtoms[j];
|
|
20383
|
+
// }
|
|
20384
|
+
// delete ic.chains[chainArray[i]];
|
|
20385
|
+
// }
|
|
20386
|
+
|
|
20387
|
+
// delete ic.structures[nStru - 1];
|
|
20388
|
+
// }
|
|
20389
|
+
// else {
|
|
20338
20390
|
ic.oriNStru = (ic.structures) ? Object.keys(ic.structures).length : 0;
|
|
20339
|
-
}
|
|
20391
|
+
// }
|
|
20340
20392
|
|
|
20341
20393
|
moleculeNum = ic.oriNStru + 1; //Object.keys(ic.structures).length + 1;
|
|
20342
20394
|
// Concatenation of two pdbs will have several atoms for the same serial
|
|
@@ -20353,12 +20405,12 @@ class LoadPDB {
|
|
|
20353
20405
|
|
|
20354
20406
|
//let chainMissingResidueArray = {}
|
|
20355
20407
|
|
|
20356
|
-
let id = (pdbid) ? pdbid : '
|
|
20408
|
+
let id = (pdbid) ? pdbid : 'stru';
|
|
20357
20409
|
|
|
20358
20410
|
let prevMissingChain = '';
|
|
20359
20411
|
let CSerial, prevCSerial, OSerial, prevOSerial;
|
|
20360
20412
|
|
|
20361
|
-
let structure = "
|
|
20413
|
+
let structure = "stru";
|
|
20362
20414
|
|
|
20363
20415
|
let bHeader = false;
|
|
20364
20416
|
|
|
@@ -20374,18 +20426,19 @@ class LoadPDB {
|
|
|
20374
20426
|
|
|
20375
20427
|
if(id == '') {
|
|
20376
20428
|
if(bAppend) {
|
|
20377
|
-
id = "
|
|
20429
|
+
id = "stru";
|
|
20378
20430
|
}
|
|
20379
20431
|
else {
|
|
20380
|
-
//if(!ic.inputid) ic.inputid = '
|
|
20381
|
-
id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : "
|
|
20432
|
+
//if(!ic.inputid) ic.inputid = 'stru';
|
|
20433
|
+
id = (ic.inputid && ic.inputid.indexOf('/') == -1) ? ic.inputid.substr(0, 10) : "stru"; //ic.filename.substr(0, 4);
|
|
20382
20434
|
}
|
|
20383
20435
|
}
|
|
20384
20436
|
|
|
20385
20437
|
structure = id;
|
|
20386
20438
|
|
|
20387
|
-
//if(id == '
|
|
20388
|
-
if(id == '
|
|
20439
|
+
//if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
|
|
20440
|
+
//if(id == 'stru' || bMutation) { // bMutation: side chain prediction
|
|
20441
|
+
if(id == 'stru') {
|
|
20389
20442
|
structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
|
|
20390
20443
|
}
|
|
20391
20444
|
|
|
@@ -20455,17 +20508,17 @@ class LoadPDB {
|
|
|
20455
20508
|
ic.ssbondpnts[id].push(resid1);
|
|
20456
20509
|
ic.ssbondpnts[id].push(resid2);
|
|
20457
20510
|
} else if (record === 'REMARK') {
|
|
20458
|
-
let
|
|
20511
|
+
let remarkType = parseInt(line.substr(7, 3));
|
|
20459
20512
|
|
|
20460
20513
|
if(line.indexOf('1/2 of bilayer thickness:') !== -1) { // OPM transmembrane protein
|
|
20461
20514
|
ic.halfBilayerSize = parseFloat(line.substr(line.indexOf(':') + 1).trim());
|
|
20462
20515
|
}
|
|
20463
|
-
else if (
|
|
20516
|
+
else if (remarkType == 210) {
|
|
20464
20517
|
if((line.substr(11, 32).trim() == 'EXPERIMENT TYPE') && line.substr(45).trim() == 'NMR') {
|
|
20465
20518
|
bNMR = true;
|
|
20466
20519
|
}
|
|
20467
20520
|
}
|
|
20468
|
-
else if (
|
|
20521
|
+
else if (remarkType == 350 && line.substr(13, 5) == 'BIOMT') {
|
|
20469
20522
|
let n = parseInt(line[18]) - 1;
|
|
20470
20523
|
//var m = parseInt(line.substr(21, 2));
|
|
20471
20524
|
let m = parseInt(line.substr(21, 2)) - 1; // start from 1
|
|
@@ -20477,7 +20530,7 @@ class LoadPDB {
|
|
|
20477
20530
|
ic.biomtMatrices[m].elements[n + 12] = parseFloat(line.substr(54, 14));
|
|
20478
20531
|
}
|
|
20479
20532
|
// missing residues
|
|
20480
|
-
else if (
|
|
20533
|
+
else if (remarkType == 465 && line.substr(18, 1) == ' ' && line.substr(20, 1) == ' ' && line.substr(21, 1) != 'S') {
|
|
20481
20534
|
let resn = line.substr(15, 3);
|
|
20482
20535
|
//let chain = line.substr(19, 1);
|
|
20483
20536
|
let chain = line.substr(18, 2).trim();
|
|
@@ -20503,7 +20556,7 @@ class LoadPDB {
|
|
|
20503
20556
|
}
|
|
20504
20557
|
|
|
20505
20558
|
}
|
|
20506
|
-
else if (
|
|
20559
|
+
else if (remarkType == 900 && ic.emd === undefined && line.substr(34).trim() == 'RELATED DB: EMDB') {
|
|
20507
20560
|
//REMARK 900 RELATED ID: EMD-3906 RELATED DB: EMDB
|
|
20508
20561
|
ic.emd = line.substr(23, 11).trim();
|
|
20509
20562
|
}
|
|
@@ -20513,11 +20566,12 @@ class LoadPDB {
|
|
|
20513
20566
|
ic.organism = ic.organism.substr(0, ic.organism.length - 1);
|
|
20514
20567
|
} else if (record === 'ENDMDL') {
|
|
20515
20568
|
++moleculeNum;
|
|
20516
|
-
id = '
|
|
20569
|
+
id = 'stru';
|
|
20517
20570
|
|
|
20518
20571
|
structure = id;
|
|
20519
|
-
//if(id == '
|
|
20520
|
-
if(id == '
|
|
20572
|
+
//if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
|
|
20573
|
+
//if(id == 'stru' || bMutation) { // bMutation: side chain prediction
|
|
20574
|
+
if(id == 'stru') {
|
|
20521
20575
|
structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
|
|
20522
20576
|
}
|
|
20523
20577
|
|
|
@@ -20539,8 +20593,9 @@ class LoadPDB {
|
|
|
20539
20593
|
}
|
|
20540
20594
|
} else if (record === 'ATOM ' || record === 'HETATM') {
|
|
20541
20595
|
structure = id;
|
|
20542
|
-
//if(id == '
|
|
20543
|
-
if(id == '
|
|
20596
|
+
//if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
|
|
20597
|
+
//if(id == 'stru' || bMutation) { // bMutation: side chain prediction
|
|
20598
|
+
if(id == 'stru') {
|
|
20544
20599
|
structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
|
|
20545
20600
|
}
|
|
20546
20601
|
|
|
@@ -20792,23 +20847,9 @@ class LoadPDB {
|
|
|
20792
20847
|
// remove the reference
|
|
20793
20848
|
lines = null;
|
|
20794
20849
|
|
|
20795
|
-
let
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
let n = curResAtoms.length;
|
|
20799
|
-
for (let j = 0; j < n; ++j) {
|
|
20800
|
-
let atom0 = curResAtoms[j];
|
|
20801
|
-
for (let k = j + 1; k < n; ++k) {
|
|
20802
|
-
let atom1 = curResAtoms[k];
|
|
20803
|
-
if (atom0.alt === atom1.alt && me.utilsCls.hasCovalentBond(atom0, atom1)) {
|
|
20804
|
-
//if (me.utilsCls.hasCovalentBond(atom0, atom1)) {
|
|
20805
|
-
atom0.bonds.push(atom1.serial);
|
|
20806
|
-
atom1.bonds.push(atom0.serial);
|
|
20807
|
-
}
|
|
20808
|
-
}
|
|
20809
|
-
f && f(atom0);
|
|
20810
|
-
}
|
|
20811
|
-
};
|
|
20850
|
+
let firstAtom = ic.firstAtomObjCls.getFirstAtomObj(ic.hAtoms);
|
|
20851
|
+
let curChain = firstAtom.chain, curResi = firstAtom.resi, curResAtoms = [];
|
|
20852
|
+
|
|
20812
20853
|
let pmin = new THREE.Vector3( 9999, 9999, 9999);
|
|
20813
20854
|
let pmax = new THREE.Vector3(-9999,-9999,-9999);
|
|
20814
20855
|
let psum = new THREE.Vector3();
|
|
@@ -20818,7 +20859,9 @@ class LoadPDB {
|
|
|
20818
20859
|
let lipidResidHash = {};
|
|
20819
20860
|
|
|
20820
20861
|
// assign atoms
|
|
20821
|
-
|
|
20862
|
+
let prevCarbonArray = [firstAtom]; // add a dummy atom
|
|
20863
|
+
//for (let i in ic.atoms) {
|
|
20864
|
+
for (let i in ic.hAtoms) {
|
|
20822
20865
|
let atom = ic.atoms[i];
|
|
20823
20866
|
let coord = atom.coord;
|
|
20824
20867
|
psum.add(coord);
|
|
@@ -20867,22 +20910,28 @@ class LoadPDB {
|
|
|
20867
20910
|
atom.color = me.parasCls.atomColors[atom.elem];
|
|
20868
20911
|
}
|
|
20869
20912
|
|
|
20870
|
-
if
|
|
20871
|
-
// a new residue, add the residue-residue bond beides the regular bonds
|
|
20872
|
-
refreshBonds(
|
|
20873
|
-
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
}
|
|
20877
|
-
});
|
|
20913
|
+
if(!(curChain === atom.chain && curResi === atom.resi)) {
|
|
20914
|
+
// a new residue, add the residue-residue bond beides the regular bonds
|
|
20915
|
+
this.refreshBonds(curResAtoms, prevCarbonArray[0]);
|
|
20916
|
+
|
|
20917
|
+
prevCarbonArray.splice(0, 1); // remove the first carbon
|
|
20918
|
+
|
|
20878
20919
|
curChain = atom.chain;
|
|
20879
20920
|
curResi = atom.resi;
|
|
20880
20921
|
//curInsc = atom.insc;
|
|
20881
20922
|
curResAtoms.length = 0;
|
|
20882
20923
|
}
|
|
20883
20924
|
curResAtoms.push(atom);
|
|
20925
|
+
|
|
20926
|
+
if(atom.name === 'C' || atom.name === 'O3\'') {
|
|
20927
|
+
prevCarbonArray.push(atom);
|
|
20928
|
+
}
|
|
20884
20929
|
} // end of for
|
|
20885
20930
|
|
|
20931
|
+
// last residue
|
|
20932
|
+
//refreshBonds();
|
|
20933
|
+
this.refreshBonds(curResAtoms, prevCarbonArray[0]);
|
|
20934
|
+
|
|
20886
20935
|
// reset lipid
|
|
20887
20936
|
for(let resid in lipidResidHash) {
|
|
20888
20937
|
let atomHash = ic.residues[resid];
|
|
@@ -20899,9 +20948,6 @@ class LoadPDB {
|
|
|
20899
20948
|
}
|
|
20900
20949
|
}
|
|
20901
20950
|
|
|
20902
|
-
// last residue
|
|
20903
|
-
refreshBonds();
|
|
20904
|
-
|
|
20905
20951
|
ic.pmin = pmin;
|
|
20906
20952
|
ic.pmax = pmax;
|
|
20907
20953
|
|
|
@@ -20937,6 +20983,28 @@ class LoadPDB {
|
|
|
20937
20983
|
}
|
|
20938
20984
|
}
|
|
20939
20985
|
|
|
20986
|
+
// refresh for atoms in each residue
|
|
20987
|
+
refreshBonds(curResAtoms, prevCarbon) { let ic = this.icn3d, me = ic.icn3dui;
|
|
20988
|
+
let n = curResAtoms.length;
|
|
20989
|
+
for (let j = 0; j < n; ++j) {
|
|
20990
|
+
let atom0 = curResAtoms[j];
|
|
20991
|
+
for (let k = j + 1; k < n; ++k) {
|
|
20992
|
+
let atom1 = curResAtoms[k];
|
|
20993
|
+
if (atom0.alt === atom1.alt && me.utilsCls.hasCovalentBond(atom0, atom1)) {
|
|
20994
|
+
//if (me.utilsCls.hasCovalentBond(atom0, atom1)) {
|
|
20995
|
+
atom0.bonds.push(atom1.serial);
|
|
20996
|
+
atom1.bonds.push(atom0.serial);
|
|
20997
|
+
}
|
|
20998
|
+
}
|
|
20999
|
+
|
|
21000
|
+
//f && f(atom0);
|
|
21001
|
+
if (prevCarbon && (prevCarbon.name === 'C' || prevCarbon.name === 'O3\'') && (atom0.name === 'N' || atom0.name === 'P') && me.utilsCls.hasCovalentBond(atom0, prevCarbon)) {
|
|
21002
|
+
atom0.bonds.push(prevCarbon.serial);
|
|
21003
|
+
prevCarbon.bonds.push(atom0.serial);
|
|
21004
|
+
}
|
|
21005
|
+
}
|
|
21006
|
+
}
|
|
21007
|
+
|
|
20940
21008
|
adjustSeq(chainMissingResidueArray) { let ic = this.icn3d; ic.icn3dui;
|
|
20941
21009
|
// adjust sequences
|
|
20942
21010
|
for(let chainNum in ic.chainsSeq) {
|
|
@@ -21239,12 +21307,13 @@ class LoadAtomData {
|
|
|
21239
21307
|
else { // mmdbid or mmcifid
|
|
21240
21308
|
if(data.descr !== undefined) ic.molTitle += data.descr.name;
|
|
21241
21309
|
if(type === 'mmdbid') {
|
|
21242
|
-
let pdbidTmp = data.pdbId;
|
|
21310
|
+
let pdbidTmp = (isNaN(id)) ? id : data.pdbId;
|
|
21243
21311
|
let chainHash = {};
|
|
21244
21312
|
|
|
21245
21313
|
if(ic.alignmolid2color === undefined) ic.alignmolid2color = [];
|
|
21246
21314
|
|
|
21247
21315
|
let molidCnt = 1;
|
|
21316
|
+
|
|
21248
21317
|
for(let molid in data.moleculeInfor) {
|
|
21249
21318
|
if(Object.keys(data.moleculeInfor[molid]).length === 0) continue;
|
|
21250
21319
|
|
|
@@ -21259,11 +21328,10 @@ class LoadAtomData {
|
|
|
21259
21328
|
chainHash[chain] = 1;
|
|
21260
21329
|
}
|
|
21261
21330
|
|
|
21262
|
-
if(((ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t)) && alignType === 'query')
|
|
21263
|
-
//chainid += me.htmlCls.postfix;
|
|
21264
|
-
chainid = pdbidTmp + me.htmlCls.postfix + '_' + chain;
|
|
21265
|
-
}
|
|
21331
|
+
if(((ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t)) && alignType === 'query') ;
|
|
21266
21332
|
|
|
21333
|
+
//if(chainidInput && chainidInput.substr(chainidInput.indexOf('_') + 1) == chain) chainid = chainidInput;
|
|
21334
|
+
|
|
21267
21335
|
let kind = data.moleculeInfor[molid].kind;
|
|
21268
21336
|
let color = data.moleculeInfor[molid].color;
|
|
21269
21337
|
let sid = data.moleculeInfor[molid].sid;
|
|
@@ -21329,7 +21397,7 @@ class LoadAtomData {
|
|
|
21329
21397
|
let bSetResi = false;
|
|
21330
21398
|
|
|
21331
21399
|
//if(mmdbId !== prevmmdbId) resiArray = [];
|
|
21332
|
-
if(atm.chain === undefined &&(type === 'mmdbid' || type === 'align')) {
|
|
21400
|
+
if(atm.chain === undefined && (type === 'mmdbid' || type === 'align')) {
|
|
21333
21401
|
if(type === 'mmdbid') {
|
|
21334
21402
|
molid = atm.ids.m;
|
|
21335
21403
|
|
|
@@ -21395,14 +21463,13 @@ class LoadAtomData {
|
|
|
21395
21463
|
atm.structure = mmdbId;
|
|
21396
21464
|
|
|
21397
21465
|
if(type === 'mmdbid' &&((ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t))
|
|
21398
|
-
&& alignType === 'query')
|
|
21399
|
-
atm.structure += me.htmlCls.postfix;
|
|
21400
|
-
}
|
|
21466
|
+
&& alignType === 'query') ;
|
|
21401
21467
|
}
|
|
21402
21468
|
|
|
21403
21469
|
structureNum = atm.structure;
|
|
21404
21470
|
|
|
21405
21471
|
chainNum = structureNum + '_' + atm.chain;
|
|
21472
|
+
|
|
21406
21473
|
//if(ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t && alignType === 'query') chainNum += me.htmlCls.postfix;
|
|
21407
21474
|
|
|
21408
21475
|
//var resiCorrection = 0;
|
|
@@ -21705,10 +21772,7 @@ class LoadAtomData {
|
|
|
21705
21772
|
let seqArray = data.sequences[chain];
|
|
21706
21773
|
let chainid = id + '_' + chain;
|
|
21707
21774
|
|
|
21708
|
-
if(((ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t)) && alignType === 'query')
|
|
21709
|
-
//chainid += me.htmlCls.postfix;
|
|
21710
|
-
chainid = id + me.htmlCls.postfix + '_' + chain;
|
|
21711
|
-
}
|
|
21775
|
+
if(((ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t)) && alignType === 'query') ;
|
|
21712
21776
|
|
|
21713
21777
|
ic.ParserUtilsCls.getMissingResidues(seqArray, type, chainid); // assign ic.chainsSeq
|
|
21714
21778
|
}
|
|
@@ -21763,6 +21827,7 @@ class LoadAtomData {
|
|
|
21763
21827
|
|
|
21764
21828
|
ic.loadPDBCls.setSsbond();
|
|
21765
21829
|
}
|
|
21830
|
+
|
|
21766
21831
|
if(type === 'mmdbid' && Object.keys(ic.structures).length == 1) {
|
|
21767
21832
|
let disulfideArray = data.disulfides;
|
|
21768
21833
|
|
|
@@ -23859,7 +23924,7 @@ class OpmParser {
|
|
|
23859
23924
|
let thisClass = this;
|
|
23860
23925
|
let url, dataType;
|
|
23861
23926
|
|
|
23862
|
-
if(!pdbid) pdbid = '
|
|
23927
|
+
if(!pdbid) pdbid = 'stru';
|
|
23863
23928
|
|
|
23864
23929
|
url = "https://www.ncbi.nlm.nih.gov/Structure/mmdb/mmdb_strview.cgi?v=2&program=icn3d&opm&uid=" + pdbid.toLowerCase();
|
|
23865
23930
|
dataType = "jsonp";
|
|
@@ -24057,6 +24122,7 @@ class MmdbParser {
|
|
|
24057
24122
|
this.parseMmdbDataPart1(data, type);
|
|
24058
24123
|
|
|
24059
24124
|
let id =(data.pdbId !== undefined) ? data.pdbId : data.mmdbId;
|
|
24125
|
+
if(chainid) id = chainid.substr(0, chainid.indexOf('_'));
|
|
24060
24126
|
|
|
24061
24127
|
let hAtoms = ic.loadAtomDataCls.loadAtomDataIn(data, id, 'mmdbid', undefined, type, chainid, chainIndex, bLastQuery, bNoTransformNoSeqalign);
|
|
24062
24128
|
|
|
@@ -24480,12 +24546,19 @@ class RealignParser {
|
|
|
24480
24546
|
|
|
24481
24547
|
ic.opts['color'] = 'grey';
|
|
24482
24548
|
ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
|
|
24483
|
-
|
|
24484
|
-
for(let index = 0, indexl = chainidArray.length - 1; index < indexl; ++index) {
|
|
24485
|
-
let chainpair = chainidArray[0] + ',' + chainidArray[index + 1];
|
|
24549
|
+
|
|
24550
|
+
for(let index = 0, indexl = chainidArray.length - 1; index < indexl; ++index) {
|
|
24486
24551
|
let fromStruct = chainidArray[index + 1].substr(0, chainidArray[index + 1].indexOf('_')); //.toUpperCase();
|
|
24487
24552
|
|
|
24488
|
-
if(toStruct == fromStruct) fromStruct += me.htmlCls.postfix;
|
|
24553
|
+
//if(toStruct == fromStruct) fromStruct += me.htmlCls.postfix;
|
|
24554
|
+
|
|
24555
|
+
let chainTo = toStruct + chainidArray[0].substr(chainidArray[0].indexOf('_'));
|
|
24556
|
+
let chainFrom = fromStruct + chainidArray[index + 1].substr(chainidArray[index + 1].indexOf('_'));
|
|
24557
|
+
|
|
24558
|
+
chainidArray[0] = chainTo;
|
|
24559
|
+
chainidArray[index + 1] = chainFrom;
|
|
24560
|
+
|
|
24561
|
+
let chainpair = chainTo + ',' + chainFrom;
|
|
24489
24562
|
|
|
24490
24563
|
if(!struct2SeqHash[chainpair]) continue;
|
|
24491
24564
|
|
|
@@ -24506,11 +24579,9 @@ class RealignParser {
|
|
|
24506
24579
|
ic.realignResid[fromStruct].push({'resid':residArray2[i], 'resn':seq2[i]});
|
|
24507
24580
|
}
|
|
24508
24581
|
|
|
24509
|
-
let chainTo = chainidArray[0];
|
|
24510
|
-
let chainFrom = chainidArray[index + 1];
|
|
24511
|
-
|
|
24512
24582
|
let bChainAlign = true;
|
|
24513
24583
|
// set ic.qt_start_end in alignCoords()
|
|
24584
|
+
|
|
24514
24585
|
let hAtomsTmp = ic.ParserUtilsCls.alignCoords(coord2, coord1, fromStruct, undefined, chainTo, chainFrom, index + 1, bChainAlign);
|
|
24515
24586
|
hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
|
|
24516
24587
|
}
|
|
@@ -24546,7 +24617,13 @@ class RealignParser {
|
|
|
24546
24617
|
let fromStruct = chainidArray[index + 1].substr(0, chainidArray[index + 1].indexOf('_')); //.toUpperCase();
|
|
24547
24618
|
if(!bRealign) fromStruct = fromStruct.toUpperCase();
|
|
24548
24619
|
|
|
24549
|
-
if(toStruct == fromStruct) fromStruct += me.htmlCls.postfix;
|
|
24620
|
+
//if(toStruct == fromStruct) fromStruct += me.htmlCls.postfix;
|
|
24621
|
+
|
|
24622
|
+
let chainTo = toStruct + chainidArray[0].substr(chainidArray[0].indexOf('_'));
|
|
24623
|
+
let chainFrom = fromStruct + chainidArray[index + 1].substr(chainidArray[index + 1].indexOf('_'));
|
|
24624
|
+
|
|
24625
|
+
chainidArray[0] = chainTo;
|
|
24626
|
+
chainidArray[index + 1] = chainFrom;
|
|
24550
24627
|
|
|
24551
24628
|
let seq1 = struct2SeqHash[toStruct];
|
|
24552
24629
|
let seq2 = struct2SeqHash[fromStruct];
|
|
@@ -24604,8 +24681,8 @@ class RealignParser {
|
|
|
24604
24681
|
}
|
|
24605
24682
|
}
|
|
24606
24683
|
|
|
24607
|
-
let chainTo = chainidArray[0];
|
|
24608
|
-
let chainFrom = chainidArray[index + 1];
|
|
24684
|
+
//let chainTo = chainidArray[0];
|
|
24685
|
+
//let chainFrom = chainidArray[index + 1];
|
|
24609
24686
|
|
|
24610
24687
|
let bChainAlign = true;
|
|
24611
24688
|
let hAtomsTmp = ic.ParserUtilsCls.alignCoords(coordsFrom, coordsTo, fromStruct, undefined, chainTo, chainFrom, index + 1, bChainAlign);
|
|
@@ -24639,7 +24716,7 @@ class RealignParser {
|
|
|
24639
24716
|
// align seq
|
|
24640
24717
|
//ic.hAtoms = ic.chainalignParserCls.setMsa(chainidArray, bRealign);
|
|
24641
24718
|
ic.hAtoms = ic.chainalignParserCls.setMsa(chainidArray);
|
|
24642
|
-
|
|
24719
|
+
|
|
24643
24720
|
ic.transformCls.zoominSelection();
|
|
24644
24721
|
|
|
24645
24722
|
|
|
@@ -24649,12 +24726,13 @@ class RealignParser {
|
|
|
24649
24726
|
ic.opts['color'] = 'identity';
|
|
24650
24727
|
//ic.setColorCls.setColorByOptions(ic.opts, ic.atoms);
|
|
24651
24728
|
ic.setColorCls.setColorByOptions(ic.opts, ic.hAtoms);
|
|
24652
|
-
|
|
24729
|
+
|
|
24653
24730
|
let name = 'protein_aligned';
|
|
24654
24731
|
ic.selectionCls.saveSelection(name, name);
|
|
24655
|
-
|
|
24732
|
+
|
|
24656
24733
|
ic.drawCls.draw();
|
|
24657
24734
|
ic.hlUpdateCls.updateHlAll();
|
|
24735
|
+
|
|
24658
24736
|
if(ic.deferredRealign !== undefined) ic.deferredRealign.resolve();
|
|
24659
24737
|
}
|
|
24660
24738
|
else {
|
|
@@ -24791,9 +24869,6 @@ class RealignParser {
|
|
|
24791
24869
|
if(i == 0) {
|
|
24792
24870
|
mmdbid_t = mmdbid;
|
|
24793
24871
|
}
|
|
24794
|
-
else if(mmdbid_t == mmdbid) {
|
|
24795
|
-
mmdbid += me.htmlCls.postfix;
|
|
24796
|
-
}
|
|
24797
24872
|
|
|
24798
24873
|
let chainid = mmdbid + chainidArray[i].substr(pos);
|
|
24799
24874
|
if(i == 0) chainid_t = chainid;
|
|
@@ -24801,7 +24876,6 @@ class RealignParser {
|
|
|
24801
24876
|
if(!ic.chainsSeq[chainid]) {
|
|
24802
24877
|
//var aaa = 1; //alert("Please select one chain per structure and try it again...");
|
|
24803
24878
|
//return;
|
|
24804
|
-
|
|
24805
24879
|
continue;
|
|
24806
24880
|
}
|
|
24807
24881
|
|
|
@@ -24839,8 +24913,8 @@ class RealignParser {
|
|
|
24839
24913
|
|
|
24840
24914
|
// slave
|
|
24841
24915
|
resiArray = predefinedResPair[1].split(",");
|
|
24842
|
-
result = thisClass.getSeqCoorResid(resiArray, chainid, base);
|
|
24843
|
-
|
|
24916
|
+
result = thisClass.getSeqCoorResid(resiArray, chainid, base);
|
|
24917
|
+
|
|
24844
24918
|
if(!struct2SeqHash[chainidpair][mmdbid]) struct2SeqHash[chainidpair][mmdbid] = '';
|
|
24845
24919
|
if(!struct2CoorHash[chainidpair][mmdbid]) struct2CoorHash[chainidpair][mmdbid] = [];
|
|
24846
24920
|
if(!struct2resid[chainidpair][mmdbid]) struct2resid[chainidpair][mmdbid] = [];
|
|
@@ -25005,8 +25079,11 @@ class RealignParser {
|
|
|
25005
25079
|
let bFound = false;
|
|
25006
25080
|
for(let serial in ic.residues[resid]) {
|
|
25007
25081
|
let atom = ic.atoms[serial];
|
|
25008
|
-
|
|
25009
|
-
|
|
25082
|
+
|
|
25083
|
+
//if((ic.proteins.hasOwnProperty(serial) && atom.name == "CA" && atom.elem == "C")
|
|
25084
|
+
// ||(ic.nucleotides.hasOwnProperty(serial) &&(atom.name == "O3'" || atom.name == "O3*") && atom.elem == "O") ) {
|
|
25085
|
+
if((atom.name == "CA" && atom.elem == "C")
|
|
25086
|
+
||((atom.name == "O3'" || atom.name == "O3*") && atom.elem == "O") ) {
|
|
25010
25087
|
struct2CoorArray.push(atom.coord.clone());
|
|
25011
25088
|
bFound = true;
|
|
25012
25089
|
break;
|
|
@@ -25034,7 +25111,7 @@ class ChainalignParser {
|
|
|
25034
25111
|
let mmdbid_t, mmdbid_q;
|
|
25035
25112
|
mmdbid_t = chainidArray[0].substr(0, chainidArray[0].indexOf('_'));
|
|
25036
25113
|
let bLastQuery = false;
|
|
25037
|
-
if(mmdbid_t.length >
|
|
25114
|
+
if(mmdbid_t.length > 5) {
|
|
25038
25115
|
let bAppend = false, bNoDssp = true;
|
|
25039
25116
|
hAtoms = ic.pdbParserCls.loadPdbData(data1, mmdbid_t, false, bAppend, 'target', bLastQuery, bNoDssp);
|
|
25040
25117
|
}
|
|
@@ -25047,7 +25124,10 @@ class ChainalignParser {
|
|
|
25047
25124
|
if(i == data2Array.length - 1) bLastQuery = true;
|
|
25048
25125
|
// each alignment has a chainIndex i
|
|
25049
25126
|
mmdbid_q = chainidArray[i + 1].substr(0, chainidArray[i + 1].indexOf('_'));
|
|
25050
|
-
|
|
25127
|
+
//mmdbid_q = (mmdbid_q_tmp.length == 5) ? mmdbid_q_tmp.substr(0, 4) : mmdbid_q_tmp; // added postfixfor same PDB IDs
|
|
25128
|
+
|
|
25129
|
+
//if(mmdbid_q.length > 4) {
|
|
25130
|
+
if(mmdbid_q.length > 5) { // PDB ID plus postfix could be 5
|
|
25051
25131
|
let bAppend = true, bNoDssp = true;
|
|
25052
25132
|
hAtomsTmp = ic.pdbParserCls.loadPdbData(data2Array[i], mmdbid_q, false, bAppend, 'query', bLastQuery, bNoDssp);
|
|
25053
25133
|
}
|
|
@@ -25485,10 +25565,21 @@ class ChainalignParser {
|
|
|
25485
25565
|
let domainArray = (me.cfg.domainids) ? me.cfg.domainids.split(',') : [];
|
|
25486
25566
|
if(domainArray.length < alignArray.length) domainArray = [];
|
|
25487
25567
|
|
|
25568
|
+
let struct2cnt = {};
|
|
25488
25569
|
for(let i = 0, il = alignArray.length; i < il; ++i) {
|
|
25489
25570
|
let chainid = alignArray[i];
|
|
25490
25571
|
let pos = chainid.indexOf('_');
|
|
25491
|
-
|
|
25572
|
+
let struct = chainid.substr(0, pos).toUpperCase();
|
|
25573
|
+
if(!struct2cnt.hasOwnProperty(struct)) {
|
|
25574
|
+
struct2cnt[struct] = 1;
|
|
25575
|
+
}
|
|
25576
|
+
else {
|
|
25577
|
+
++struct2cnt[struct];
|
|
25578
|
+
}
|
|
25579
|
+
|
|
25580
|
+
struct = (struct2cnt[struct] == 1) ? struct : struct + struct2cnt[struct];
|
|
25581
|
+
|
|
25582
|
+
alignArray[i] = struct + chainid.substr(pos);
|
|
25492
25583
|
}
|
|
25493
25584
|
|
|
25494
25585
|
ic.chainidArray = alignArray;
|
|
@@ -25501,7 +25592,7 @@ class ChainalignParser {
|
|
|
25501
25592
|
let targetAjax;
|
|
25502
25593
|
|
|
25503
25594
|
let url_t;
|
|
25504
|
-
if(ic.mmdbid_t.length >
|
|
25595
|
+
if(ic.mmdbid_t.length > 5) {
|
|
25505
25596
|
url_t = "https://alphafold.ebi.ac.uk/files/AF-" + ic.mmdbid_t + "-F1-model_v2.pdb";
|
|
25506
25597
|
|
|
25507
25598
|
targetAjax = $.ajax({
|
|
@@ -25533,11 +25624,13 @@ class ChainalignParser {
|
|
|
25533
25624
|
ic.pdbChainIndexHash = {};
|
|
25534
25625
|
for(let index = 1, indexLen = alignArray.length; index < indexLen; ++index) {
|
|
25535
25626
|
let pos2 = alignArray[index].indexOf('_');
|
|
25536
|
-
|
|
25627
|
+
let mmdbid_q_tmp = alignArray[index].substr(0, pos2).toUpperCase();
|
|
25628
|
+
ic.mmdbid_q = (mmdbid_q_tmp.length == 5) ? mmdbid_q_tmp.substr(0, 4) : mmdbid_q_tmp; // added postfix for same PDB IDs
|
|
25629
|
+
|
|
25537
25630
|
ic.chain_q = alignArray[index].substr(pos2+1);
|
|
25538
25631
|
|
|
25539
25632
|
let url_q, queryAjax;
|
|
25540
|
-
if(ic.mmdbid_q.length >
|
|
25633
|
+
if(ic.mmdbid_q.length > 5) {
|
|
25541
25634
|
url_q = "https://alphafold.ebi.ac.uk/files/AF-" + ic.mmdbid_q + "-F1-model_v2.pdb";
|
|
25542
25635
|
|
|
25543
25636
|
queryAjax = $.ajax({
|
|
@@ -25562,7 +25655,9 @@ class ChainalignParser {
|
|
|
25562
25655
|
|
|
25563
25656
|
for(let index = 1, indexLen = alignArray.length; index < indexLen; ++index) {
|
|
25564
25657
|
let pos2 = alignArray[index].indexOf('_');
|
|
25565
|
-
|
|
25658
|
+
let mmdbid_q_tmp = alignArray[index].substr(0, pos2).toUpperCase();
|
|
25659
|
+
ic.mmdbid_q = (mmdbid_q_tmp.length == 5) ? mmdbid_q_tmp.substr(0, 4) : mmdbid_q_tmp; // added postfix for same PDB IDs
|
|
25660
|
+
|
|
25566
25661
|
ic.chain_q = alignArray[index].substr(pos2+1);
|
|
25567
25662
|
|
|
25568
25663
|
if(!me.cfg.resnum && !me.cfg.resdef) {
|
|
@@ -25587,7 +25682,7 @@ class ChainalignParser {
|
|
|
25587
25682
|
|
|
25588
25683
|
ajaxArray.push(alignAjax);
|
|
25589
25684
|
|
|
25590
|
-
ic.pdbChainIndexHash[index] =
|
|
25685
|
+
ic.pdbChainIndexHash[index] = mmdbid_q_tmp + "_" + ic.chain_q + "_" + ic.mmdbid_t + "_" + ic.chain_t;
|
|
25591
25686
|
}
|
|
25592
25687
|
else {
|
|
25593
25688
|
// get the dynamic alignment after loading the structures
|
|
@@ -25617,7 +25712,7 @@ class ChainalignParser {
|
|
|
25617
25712
|
// index = 0: the mmdb data of target
|
|
25618
25713
|
let targetData = dataArray[0][0];
|
|
25619
25714
|
let header = 'HEADER ' + mmdbid_t + '\n';
|
|
25620
|
-
if(mmdbid_t.length >
|
|
25715
|
+
if(mmdbid_t.length > 5) targetData = header + targetData;
|
|
25621
25716
|
|
|
25622
25717
|
ic.t_trans_add = [];
|
|
25623
25718
|
ic.q_trans_sub = [];
|
|
@@ -25636,7 +25731,7 @@ class ChainalignParser {
|
|
|
25636
25731
|
let mmdbid_q = chainidArray[index].substr(0, pos).toUpperCase();
|
|
25637
25732
|
|
|
25638
25733
|
let header = 'HEADER ' + mmdbid_q + '\n';
|
|
25639
|
-
if(mmdbid_q.length >
|
|
25734
|
+
if(mmdbid_q.length > 5) queryData = header + queryData;
|
|
25640
25735
|
|
|
25641
25736
|
if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
|
|
25642
25737
|
) {
|
|
@@ -25811,9 +25906,9 @@ class ChainalignParser {
|
|
|
25811
25906
|
}
|
|
25812
25907
|
|
|
25813
25908
|
downloadMmdbAf(idlist, bQuery) { let ic = this.icn3d, me = ic.icn3dui;
|
|
25814
|
-
|
|
25909
|
+
let thisClass = this;
|
|
25815
25910
|
|
|
25816
|
-
|
|
25911
|
+
ic.deferredMmdbaf = $.Deferred(function() {
|
|
25817
25912
|
ic.structArray = idlist.split(',');
|
|
25818
25913
|
|
|
25819
25914
|
let ajaxArray = [];
|
|
@@ -25822,7 +25917,7 @@ class ChainalignParser {
|
|
|
25822
25917
|
let url_t, targetAjax;
|
|
25823
25918
|
let structure = ic.structArray[i];
|
|
25824
25919
|
|
|
25825
|
-
if(isNaN(structure) && structure.length >
|
|
25920
|
+
if(isNaN(structure) && structure.length > 5) {
|
|
25826
25921
|
url_t = "https://alphafold.ebi.ac.uk/files/AF-" + ic.structArray[i] + "-F1-model_v2.pdb";
|
|
25827
25922
|
|
|
25828
25923
|
targetAjax = $.ajax({
|
|
@@ -25871,7 +25966,7 @@ class ChainalignParser {
|
|
|
25871
25966
|
for(let index = 0, indexl = structArray.length; index < indexl; ++index) {
|
|
25872
25967
|
let queryData = dataArray[index][0];
|
|
25873
25968
|
let header = 'HEADER ' + structArray[index] + '\n';
|
|
25874
|
-
if(structArray[index].length >
|
|
25969
|
+
if(structArray[index].length > 5) queryData = header + queryData;
|
|
25875
25970
|
|
|
25876
25971
|
if(queryData !== undefined && JSON.stringify(queryData).indexOf('Oops there was a problem') === -1
|
|
25877
25972
|
) {
|
|
@@ -25901,7 +25996,8 @@ class ChainalignParser {
|
|
|
25901
25996
|
bAppend = true;
|
|
25902
25997
|
}
|
|
25903
25998
|
|
|
25904
|
-
if(structArray[i].length > 4) {
|
|
25999
|
+
//if(structArray[i].length > 4) {
|
|
26000
|
+
if(structArray[i].length > 5) { // PDB ID plus postfix could be 5
|
|
25905
26001
|
let bNoDssp = true;
|
|
25906
26002
|
hAtomsTmp = ic.pdbParserCls.loadPdbData(queryDataArray[i], structArray[i], false, bAppend, targetOrQuery, bLastQuery, bNoDssp);
|
|
25907
26003
|
}
|
|
@@ -27872,7 +27968,7 @@ class LoadScript {
|
|
|
27872
27968
|
me.cfg.mmcifid = id;
|
|
27873
27969
|
ic.mmcifParserCls.downloadMmcif(id);
|
|
27874
27970
|
}
|
|
27875
|
-
else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
|
|
27971
|
+
else if(command.indexOf('load mmdb ') !== -1 || command.indexOf('load mmdb1 ') !== -1) {
|
|
27876
27972
|
me.cfg.mmdbid = id;
|
|
27877
27973
|
me.cfg.bu = 1;
|
|
27878
27974
|
|
|
@@ -27888,13 +27984,13 @@ class LoadScript {
|
|
|
27888
27984
|
me.cfg.mmdbafid = id;
|
|
27889
27985
|
me.cfg.bu = 1;
|
|
27890
27986
|
|
|
27891
|
-
ic.
|
|
27987
|
+
ic.chainalignParserCls.downloadMmdbAf(id);
|
|
27892
27988
|
}
|
|
27893
27989
|
else if(command.indexOf('load mmdbaf0') !== -1) {
|
|
27894
27990
|
me.cfg.mmdbafid = id;
|
|
27895
27991
|
me.cfg.bu = 0;
|
|
27896
27992
|
|
|
27897
|
-
ic.
|
|
27993
|
+
ic.chainalignParserCls.downloadMmdbAf(id);
|
|
27898
27994
|
}
|
|
27899
27995
|
else if(command.indexOf('load gi') !== -1) {
|
|
27900
27996
|
me.cfg.gi = id;
|
|
@@ -30539,7 +30635,7 @@ class AddTrack {
|
|
|
30539
30635
|
|
|
30540
30636
|
//this.showNewTrack(chainid, title, text);
|
|
30541
30637
|
//me.htmlCls.clickMenuCls.setLogCmd("add track | chainid " + chainid + " | title " + title + " | text " + this.simplifyText(text), true);
|
|
30542
|
-
let result =
|
|
30638
|
+
let result = thisClass.getFullText(text);
|
|
30543
30639
|
|
|
30544
30640
|
thisClass.showNewTrack(chainid, title, result.text, undefined, undefined, 'custom', undefined, undefined, result.fromArray, result.toArray);
|
|
30545
30641
|
|
|
@@ -31629,7 +31725,19 @@ class AnnoCddSite {
|
|
|
31629
31725
|
}
|
|
31630
31726
|
}
|
|
31631
31727
|
}
|
|
31632
|
-
|
|
31728
|
+
|
|
31729
|
+
let bCoordinates = false;
|
|
31730
|
+
for(let i = 0, il = adjustedResPosArray.length; i < il; ++i) {
|
|
31731
|
+
let resid = chnid + "_" + adjustedResPosArray[i];
|
|
31732
|
+
if(ic.residues.hasOwnProperty(resid)) {
|
|
31733
|
+
bCoordinates = true;
|
|
31734
|
+
break;
|
|
31735
|
+
}
|
|
31736
|
+
}
|
|
31737
|
+
|
|
31738
|
+
let linkStr = (bCoordinates) ? 'icn3d-link icn3d-blue' : '';
|
|
31739
|
+
|
|
31740
|
+
let htmlTmp2 = '<div class="icn3d-seqTitle ' + linkStr + '" site="site" posarray="' + adjustedResPosArray.toString() + '" shorttitle="' + title + '" setname="' + chnid + '_site_' + index + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
|
|
31633
31741
|
let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
|
|
31634
31742
|
let htmlTmp = '<span class="icn3d-seqLine">';
|
|
31635
31743
|
html3 += htmlTmp2 + htmlTmp3 + '<br>';
|
|
@@ -31785,7 +31893,25 @@ class AnnoCddSite {
|
|
|
31785
31893
|
if(bDomain) pssmid2fromArray[pssmid] = fromArray;
|
|
31786
31894
|
if(bDomain) pssmid2toArray[pssmid] = toArray;
|
|
31787
31895
|
|
|
31788
|
-
let
|
|
31896
|
+
let bCoordinates = false;
|
|
31897
|
+
for(let i = 0, il = fromArray.length; i < il; ++i) {
|
|
31898
|
+
let from = fromArray[i], to = toArray[i];
|
|
31899
|
+
for(let j = from; j <= to; ++j) {
|
|
31900
|
+
let resid = chnid + "_" + j;
|
|
31901
|
+
if(ic.residues.hasOwnProperty(resid)) {
|
|
31902
|
+
bCoordinates = true;
|
|
31903
|
+
break;
|
|
31904
|
+
}
|
|
31905
|
+
}
|
|
31906
|
+
|
|
31907
|
+
if(bCoordinates) {
|
|
31908
|
+
break;
|
|
31909
|
+
}
|
|
31910
|
+
}
|
|
31911
|
+
|
|
31912
|
+
let linkStr = (bCoordinates) ? 'icn3d-link icn3d-blue' : '';
|
|
31913
|
+
|
|
31914
|
+
let htmlTmp2 = '<div class="icn3d-seqTitle ' + linkStr + '" ' + type + '="' + acc + '" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + title + '" setname="' + setname + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
|
|
31789
31915
|
let htmlTmp3 = '<span class="icn3d-residueNum" title="residue count">' + resCnt.toString() + ' Res</span>';
|
|
31790
31916
|
html3 += htmlTmp2 + htmlTmp3 + '<br>';
|
|
31791
31917
|
let htmlTmp = '<span class="icn3d-seqLine">';
|
|
@@ -31793,7 +31919,7 @@ class AnnoCddSite {
|
|
|
31793
31919
|
if(bDomain) {
|
|
31794
31920
|
html2 += '<div style="width:20px; display:inline-block;"><span id="' + ic.pre + chnid + '_' + acc + '_' + r + '_cddseq_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="width:15px;" title="Expand"></span><span id="' + ic.pre + chnid + '_' + acc + '_' + r + '_cddseq_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="display:none; width:15px;" title="Shrink"></span></div>';
|
|
31795
31921
|
}
|
|
31796
|
-
html2 += '<div style="width:' + titleSpace + 'px!important;" class="icn3d-seqTitle
|
|
31922
|
+
html2 += '<div style="width:' + titleSpace + 'px!important;" class="icn3d-seqTitle ' + linkStr + '" ' + type + '="' + acc + '" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + setname + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + title + ' </div>';
|
|
31797
31923
|
html2 += htmlTmp3 + htmlTmp;
|
|
31798
31924
|
let pre = type + index.toString();
|
|
31799
31925
|
for(let i = 0, il = ic.giSeq[chnid].length; i < il; ++i) {
|
|
@@ -31819,7 +31945,7 @@ class AnnoCddSite {
|
|
|
31819
31945
|
for(let i = 0, il = fromArray.length; i < il; ++i) {
|
|
31820
31946
|
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);
|
|
31821
31947
|
html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;"> </div>';
|
|
31822
|
-
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
|
|
31948
|
+
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 ' + linkStr + '" domain="' +(index+1).toString() + '" from="' + fromArray + '" to="' + toArray + '" shorttitle="' + title + '" index="' + index + '" setname="' + setname + '" id="' + chnid + '_domain_' + index + '_' + r + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + domain + ' </div>';
|
|
31823
31949
|
}
|
|
31824
31950
|
}
|
|
31825
31951
|
else { // with potential gaps
|
|
@@ -31838,7 +31964,7 @@ class AnnoCddSite {
|
|
|
31838
31964
|
html2 += ic.showSeqCls.insertGapOverview(chnid, fromArray2[i]);
|
|
31839
31965
|
let emptyWidth =(i == 0) ? Math.round(ic.seqAnnWidth *(fromArray2[i] - ic.baseResi[chnid] - 1) /(ic.maxAnnoLength + ic.nTotalGap)) : Math.round(ic.seqAnnWidth *(fromArray2[i] - toArray2[i-1] - 1) /(ic.maxAnnoLength + ic.nTotalGap));
|
|
31840
31966
|
html2 += '<div style="display:inline-block; width:' + emptyWidth + 'px;"> </div>';
|
|
31841
|
-
html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(toArray2[i] - fromArray2[i] + 1) /(ic.maxAnnoLength + ic.nTotalGap)) + 'px;" class="icn3d-seqTitle
|
|
31967
|
+
html2 += '<div style="display:inline-block; color:white!important; font-weight:bold; background-color:#' + color + '; width:' + Math.round(ic.seqAnnWidth *(toArray2[i] - fromArray2[i] + 1) /(ic.maxAnnoLength + ic.nTotalGap)) + 'px;" class="icn3d-seqTitle ' + linkStr + '" domain="' +(index+1).toString() + '" from="' + fromArray2 + '" to="' + toArray2 + '" shorttitle="' + title + '" index="' + index + '" setname="' + setname + '" id="' + chnid + '_domain_' + index + '_' + r + '" anno="sequence" chain="' + chnid + '" title="' + fulltitle + '">' + domain + ' </div>';
|
|
31842
31968
|
}
|
|
31843
31969
|
}
|
|
31844
31970
|
htmlTmp = '<span class="icn3d-residueNum" title="residue count"> ' + resCnt.toString() + ' Residues</span>';
|
|
@@ -34901,14 +35027,14 @@ class SetSeqAlign {
|
|
|
34901
35027
|
let residueid2 = chainid2 + '_' + resi;
|
|
34902
35028
|
let ss1 = ic.secondaries[residueid1];
|
|
34903
35029
|
let ss2 = ic.secondaries[residueid2];
|
|
34904
|
-
if(ss2
|
|
35030
|
+
if(ss2) {
|
|
34905
35031
|
ic.alnChainsAnno[chainid1][0].push(ss2);
|
|
34906
35032
|
}
|
|
34907
35033
|
else {
|
|
34908
35034
|
ic.alnChainsAnno[chainid1][0].push('-');
|
|
34909
35035
|
}
|
|
34910
35036
|
|
|
34911
|
-
if(ss1
|
|
35037
|
+
if(ss1) {
|
|
34912
35038
|
ic.alnChainsAnno[chainid1][1].push(ss1);
|
|
34913
35039
|
}
|
|
34914
35040
|
else {
|
|
@@ -34925,7 +35051,7 @@ class SetSeqAlign {
|
|
|
34925
35051
|
ic.alnChainsAnno[chainid1][3].push(numberStr); // symbol: 10, 20, etc, empty for rest
|
|
34926
35052
|
|
|
34927
35053
|
++alignIndex;
|
|
34928
|
-
} // end for(let j
|
|
35054
|
+
} // end for(let j
|
|
34929
35055
|
} // end for(let i
|
|
34930
35056
|
|
|
34931
35057
|
seqalign = {};
|
|
@@ -34958,11 +35084,6 @@ class SetSeqAlign {
|
|
|
34958
35084
|
let chainLen = ic.chainsSeq[mmdbid2 + '_' + chain2].length;
|
|
34959
35085
|
ic.qt_start_end[chainIndex] = {"q_start":1, "q_end": chainLen, "t_start":1, "t_end": chainLen};
|
|
34960
35086
|
}
|
|
34961
|
-
|
|
34962
|
-
if(mmdbid2 !== undefined && mmdbid2 === mmdbid1) {
|
|
34963
|
-
//chainid1 += me.htmlCls.postfix;
|
|
34964
|
-
chainid2 = mmdbid2 + me.htmlCls.postfix + "_" + chain2;
|
|
34965
|
-
}
|
|
34966
35087
|
}
|
|
34967
35088
|
else {
|
|
34968
35089
|
//var chainidArray = me.cfg.chainalign.split(',');
|
|
@@ -34983,10 +35104,7 @@ class SetSeqAlign {
|
|
|
34983
35104
|
chainid1 = mmdbid1 + "_" + chain1;
|
|
34984
35105
|
chainid2 = mmdbid2 + "_" + chain2;
|
|
34985
35106
|
|
|
34986
|
-
if(mmdbid2 !== undefined && mmdbid2 === ic.mmdbid_t)
|
|
34987
|
-
//chainid1 += me.htmlCls.postfix;
|
|
34988
|
-
chainid2 = mmdbid2 + me.htmlCls.postfix + "_" + chain2;
|
|
34989
|
-
}
|
|
35107
|
+
if(mmdbid2 !== undefined && mmdbid2 === ic.mmdbid_t) ;
|
|
34990
35108
|
}
|
|
34991
35109
|
|
|
34992
35110
|
ic.conservedName1 = chainid1 + '_cons';
|
|
@@ -35224,6 +35342,7 @@ class SetSeqAlign {
|
|
|
35224
35342
|
let resi2range_t = {}; // aaccumulative aligned residues in the template chain
|
|
35225
35343
|
// start and end of MSA
|
|
35226
35344
|
let start_t = 9999, end_t = -1;
|
|
35345
|
+
|
|
35227
35346
|
for(let index = 1, indexl = chainidArray.length; index < indexl; ++index) {
|
|
35228
35347
|
let chainIndex = index - 1;
|
|
35229
35348
|
for(let i = 0, il = ic.qt_start_end[chainIndex].length; i < il; ++i) {
|
|
@@ -35325,7 +35444,7 @@ class SetSeqAlign {
|
|
|
35325
35444
|
|
|
35326
35445
|
hAtoms = me.hashUtilsCls.unionHash(hAtoms, hAtomsTmp);
|
|
35327
35446
|
}
|
|
35328
|
-
|
|
35447
|
+
|
|
35329
35448
|
// 3. assign the varaible ic.alnChainsAnno
|
|
35330
35449
|
for(let i = 0; i < 3 + 2*n; ++i) {
|
|
35331
35450
|
if(ic.alnChainsAnno[chainid1][i] === undefined ) ic.alnChainsAnno[chainid1][i] = [];
|
|
@@ -35402,7 +35521,7 @@ class SetSeqAlign {
|
|
|
35402
35521
|
resi = resiPos;
|
|
35403
35522
|
}
|
|
35404
35523
|
else {
|
|
35405
|
-
if(ic.chainsSeq[chainid][resiPos]
|
|
35524
|
+
if(!ic.chainsSeq[chainid] || !ic.chainsSeq[chainid][resiPos]) {
|
|
35406
35525
|
resi = '';
|
|
35407
35526
|
}
|
|
35408
35527
|
else {
|
|
@@ -35427,7 +35546,7 @@ class SetSeqAlign {
|
|
|
35427
35546
|
}
|
|
35428
35547
|
}
|
|
35429
35548
|
else {
|
|
35430
|
-
if(ic.chainsSeq[chainid][resiPos]
|
|
35549
|
+
if(!ic.chainsSeq[chainid] || !ic.chainsSeq[chainid][resiPos]) {
|
|
35431
35550
|
resn = '';
|
|
35432
35551
|
}
|
|
35433
35552
|
else {
|
|
@@ -35443,18 +35562,21 @@ class SetSeqAlign {
|
|
|
35443
35562
|
let nGap = 0;
|
|
35444
35563
|
|
|
35445
35564
|
let pos_t; // position to add gap
|
|
35446
|
-
for(let j = 0, jl = ic.alnChainsSeq[chainid1].length; j < jl; ++j) {
|
|
35447
|
-
//add gap before the mapping region
|
|
35448
|
-
if(parseInt(ic.alnChainsSeq[chainid1][j].resi) == resi_t) {
|
|
35449
|
-
pos_t = j;
|
|
35450
|
-
break;
|
|
35451
|
-
}
|
|
35452
35565
|
|
|
35453
|
-
|
|
35454
|
-
|
|
35455
|
-
|
|
35456
|
-
|
|
35457
|
-
|
|
35566
|
+
if(ic.alnChainsSeq[chainid1]) {
|
|
35567
|
+
for(let j = 0, jl = ic.alnChainsSeq[chainid1].length; j < jl; ++j) {
|
|
35568
|
+
//add gap before the mapping region
|
|
35569
|
+
if(parseInt(ic.alnChainsSeq[chainid1][j].resi) == resi_t) {
|
|
35570
|
+
pos_t = j;
|
|
35571
|
+
break;
|
|
35572
|
+
}
|
|
35573
|
+
|
|
35574
|
+
if(ic.alnChainsSeq[chainid1][j].resn == '-') {
|
|
35575
|
+
++nGap;
|
|
35576
|
+
}
|
|
35577
|
+
else {
|
|
35578
|
+
nGap = 0;
|
|
35579
|
+
}
|
|
35458
35580
|
}
|
|
35459
35581
|
}
|
|
35460
35582
|
|
|
@@ -35463,13 +35585,14 @@ class SetSeqAlign {
|
|
|
35463
35585
|
|
|
35464
35586
|
addGapAllAlnChains(chainidArray, alignedChainIndice, chainid1, resi_t, len) { let ic = this.icn3d; ic.icn3dui;
|
|
35465
35587
|
let result = this.getResiPosInTemplate(chainid1, resi_t);
|
|
35466
|
-
|
|
35588
|
+
result.ngap; let pos_t = result.pos;
|
|
35467
35589
|
|
|
35468
35590
|
// add gaps for all previously aligned sequences, not the current sequence, which is the last one
|
|
35469
35591
|
for(let j = 0, jl = alignedChainIndice.length - 1; j < jl; ++j) {
|
|
35470
35592
|
let chainidTmp = chainidArray[alignedChainIndice[j]];
|
|
35471
35593
|
let gapResObject = this.getResObject(chainidTmp, true);
|
|
35472
|
-
for(let k = 0, kl = len - nGap; k < kl; ++k) {
|
|
35594
|
+
//for(let k = 0, kl = len - nGap; k < kl; ++k) {
|
|
35595
|
+
for(let k = 0, kl = len; k < kl; ++k) {
|
|
35473
35596
|
ic.alnChainsSeq[chainidTmp].splice(pos_t, 0, gapResObject);
|
|
35474
35597
|
}
|
|
35475
35598
|
}
|
|
@@ -35513,8 +35636,8 @@ class SetSeqAlign {
|
|
|
35513
35636
|
pos2 = chainid.indexOf('_');
|
|
35514
35637
|
|
|
35515
35638
|
//mmdbid1 = ic.mmdbid_t;
|
|
35516
|
-
mmdbid1 = chainidArray[0].substr(0, pos1)
|
|
35517
|
-
mmdbid2 = chainid.substr(0, pos2)
|
|
35639
|
+
mmdbid1 = chainidArray[0].substr(0, pos1); //.toUpperCase();
|
|
35640
|
+
mmdbid2 = chainid.substr(0, pos2); //.toUpperCase();
|
|
35518
35641
|
|
|
35519
35642
|
chain1 = chainidArray[0].substr(pos1 + 1);
|
|
35520
35643
|
chain2 = chainid.substr(pos2 + 1);
|
|
@@ -35527,9 +35650,7 @@ class SetSeqAlign {
|
|
|
35527
35650
|
chainid1 = mmdbid1 + "_" + chain1;
|
|
35528
35651
|
chainid2 = mmdbid2 + "_" + chain2;
|
|
35529
35652
|
|
|
35530
|
-
if(mmdbid2 !== undefined && mmdbid2 === ic.mmdbid_t)
|
|
35531
|
-
chainid2 = mmdbid2 + me.htmlCls.postfix + "_" + chain2;
|
|
35532
|
-
}
|
|
35653
|
+
if(mmdbid2 !== undefined && mmdbid2 === ic.mmdbid_t) ;
|
|
35533
35654
|
|
|
35534
35655
|
//ic.alnChainsSeq[chainid2] = [];
|
|
35535
35656
|
ic.alnChains[chainid2] = {};
|
|
@@ -36367,7 +36488,7 @@ class ParserUtils {
|
|
|
36367
36488
|
|
|
36368
36489
|
//var dxymax = npoint / 2.0 * step;
|
|
36369
36490
|
|
|
36370
|
-
pdbid =(pdbid) ? pdbid.toUpperCase() : '
|
|
36491
|
+
pdbid =(pdbid) ? pdbid.toUpperCase() : 'stru';
|
|
36371
36492
|
|
|
36372
36493
|
ic.structures[pdbid].push(pdbid + '_MEM');
|
|
36373
36494
|
ic.chains[pdbid + '_MEM'] = {};
|
|
@@ -36518,7 +36639,7 @@ class ParserUtils {
|
|
|
36518
36639
|
$("#" + id + "_shrink").show();
|
|
36519
36640
|
|
|
36520
36641
|
if(me.cfg.align !== undefined) {
|
|
36521
|
-
let bShowHighlight = false;
|
|
36642
|
+
let bShowHighlight = false;
|
|
36522
36643
|
let seqObj = me.htmlCls.alignSeqCls.getAlignSequencesAnnotations(Object.keys(ic.alnChains), undefined, undefined, bShowHighlight);
|
|
36523
36644
|
$("#" + ic.pre + "dl_sequence2").html(seqObj.sequencesHtml);
|
|
36524
36645
|
$("#" + ic.pre + "dl_sequence2").width(me.htmlCls.RESIDUE_WIDTH * seqObj.maxSeqCnt + 200);
|
|
@@ -36911,7 +37032,7 @@ class MmcifParser {
|
|
|
36911
37032
|
//loadAtomDataIn. The deferred parameter was resolved after the parsing so that other javascript code can be executed.
|
|
36912
37033
|
loadMmcifData(data, mmcifid) { let ic = this.icn3d; ic.icn3dui;
|
|
36913
37034
|
if(!mmcifid) mmcifid = data.mmcif;
|
|
36914
|
-
if(!mmcifid) mmcifid = '
|
|
37035
|
+
if(!mmcifid) mmcifid = 'stru';
|
|
36915
37036
|
|
|
36916
37037
|
if(data.atoms !== undefined) {
|
|
36917
37038
|
ic.init();
|
|
@@ -37289,7 +37410,7 @@ class HlSeq {
|
|
|
37289
37410
|
if(ic.bNCBI && ($(that).attr('domain') !== undefined || $(that).attr('feat') !== undefined || $(that).attr('3ddomain') !== undefined) ) {
|
|
37290
37411
|
let residNCBI = chainid + '_' + (j+1).toString();
|
|
37291
37412
|
// AlphaFold domains calculated on-the-fly have no conversion
|
|
37292
|
-
if(structure.length >
|
|
37413
|
+
if(structure.length > 5) {
|
|
37293
37414
|
residueid = residNCBI;
|
|
37294
37415
|
}
|
|
37295
37416
|
else if(ic.residNCBI2resid[residNCBI]) {
|
|
@@ -37336,7 +37457,7 @@ class HlSeq {
|
|
|
37336
37457
|
if(ic.bNCBI) {
|
|
37337
37458
|
let residNCBI = chainid + '_' +(parseInt(posArray[i])+1).toString();
|
|
37338
37459
|
// AlphaFold domains calculated on-the-fly have no conversion
|
|
37339
|
-
if(structure.length >
|
|
37460
|
+
if(structure.length > 5) {
|
|
37340
37461
|
residueid = residNCBI;
|
|
37341
37462
|
}
|
|
37342
37463
|
else if(ic.residNCBI2resid[residNCBI]) {
|
|
@@ -39931,10 +40052,7 @@ class Diagram2d {
|
|
|
39931
40052
|
|
|
39932
40053
|
let chainNameFinal =(chainNameHash[chainName] === 1) ? chainName : chainName + chainNameHash[chainName].toString();
|
|
39933
40054
|
let chainid = mmdbid + '_' + chainNameFinal;
|
|
39934
|
-
if(ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t && structureIndex === 0)
|
|
39935
|
-
//chainid += me.htmlCls.postfix;
|
|
39936
|
-
chainid = mmdbid + me.htmlCls.postfix + '_' + chainNameFinal;
|
|
39937
|
-
}
|
|
40055
|
+
if(ic.mmdbid_q !== undefined && ic.mmdbid_q === ic.mmdbid_t && structureIndex === 0) ;
|
|
39938
40056
|
|
|
39939
40057
|
molid2chain[molid] = chainid;
|
|
39940
40058
|
molid2color[molid] = color;
|
|
@@ -44049,6 +44167,8 @@ class ApplySsbonds {
|
|
|
44049
44167
|
}
|
|
44050
44168
|
}
|
|
44051
44169
|
|
|
44170
|
+
//https://github.com/mrdoob/three.js/blob/master/examples/webxr_vr_cubes.html
|
|
44171
|
+
|
|
44052
44172
|
class VRButton {
|
|
44053
44173
|
constructor(icn3d) {
|
|
44054
44174
|
this.icn3d = icn3d;
|
|
@@ -44084,10 +44204,12 @@ class VRButton {
|
|
|
44084
44204
|
}
|
|
44085
44205
|
|
|
44086
44206
|
function onSessionEnded( /*event*/ ) {
|
|
44087
|
-
// the display is weird somehow
|
|
44088
44207
|
// reset orientation after VR
|
|
44089
44208
|
ic.transformCls.resetOrientation();
|
|
44090
|
-
|
|
44209
|
+
|
|
44210
|
+
ic.bVr = false;
|
|
44211
|
+
//ic.mdl.scale.copy(new THREE.Vector3( 1, 1, 1 ));
|
|
44212
|
+
|
|
44091
44213
|
ic.drawCls.draw();
|
|
44092
44214
|
|
|
44093
44215
|
currentSession.removeEventListener( 'end', onSessionEnded );
|
|
@@ -44125,8 +44247,10 @@ class VRButton {
|
|
|
44125
44247
|
ic.bImpo = false;
|
|
44126
44248
|
//ic.bInstanced = false;
|
|
44127
44249
|
|
|
44128
|
-
|
|
44129
|
-
ic.
|
|
44250
|
+
ic.bVr = true;
|
|
44251
|
+
//ic.mdl.scale.copy(ic.mdl.scale.multiplyScalar(0.2));
|
|
44252
|
+
|
|
44253
|
+
ic.drawCls.draw(ic.bVr);
|
|
44130
44254
|
|
|
44131
44255
|
if ( currentSession === null ) {
|
|
44132
44256
|
|
|
@@ -44227,29 +44351,6 @@ class VRButton {
|
|
|
44227
44351
|
return button;
|
|
44228
44352
|
|
|
44229
44353
|
} else {
|
|
44230
|
-
/*
|
|
44231
|
-
const message = document.createElement( 'a' );
|
|
44232
|
-
|
|
44233
|
-
if ( window.isSecureContext === false ) {
|
|
44234
|
-
|
|
44235
|
-
message.href = document.location.href.replace( /^http:/, 'https:' );
|
|
44236
|
-
message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message
|
|
44237
|
-
|
|
44238
|
-
} else {
|
|
44239
|
-
|
|
44240
|
-
message.href = 'https://immersiveweb.dev/';
|
|
44241
|
-
message.innerHTML = 'WEBXR NOT AVAILABLE';
|
|
44242
|
-
|
|
44243
|
-
}
|
|
44244
|
-
|
|
44245
|
-
message.style.left = 'calc(50% - 90px)';
|
|
44246
|
-
message.style.width = '180px';
|
|
44247
|
-
message.style.textDecoration = 'none';
|
|
44248
|
-
|
|
44249
|
-
stylizeElement( message );
|
|
44250
|
-
|
|
44251
|
-
return message;
|
|
44252
|
-
*/
|
|
44253
44354
|
const message = document.createElement( 'span' );
|
|
44254
44355
|
return message;
|
|
44255
44356
|
}
|
|
@@ -44276,6 +44377,8 @@ class VRButton {
|
|
|
44276
44377
|
|
|
44277
44378
|
}
|
|
44278
44379
|
|
|
44380
|
+
//https://github.com/mrdoob/three.js/blob/master/examples/webxr_ar_cones.html
|
|
44381
|
+
|
|
44279
44382
|
class ARButton {
|
|
44280
44383
|
constructor(icn3d) {
|
|
44281
44384
|
this.icn3d = icn3d;
|
|
@@ -44347,6 +44450,13 @@ class ARButton {
|
|
|
44347
44450
|
}
|
|
44348
44451
|
|
|
44349
44452
|
function onSessionEnded( /*event*/ ) {
|
|
44453
|
+
// reset orientation after VR
|
|
44454
|
+
ic.transformCls.resetOrientation();
|
|
44455
|
+
|
|
44456
|
+
ic.bAr = false;
|
|
44457
|
+
//ic.mdl.scale.copy(new THREE.Vector3( 1, 1, 1 ));
|
|
44458
|
+
|
|
44459
|
+
ic.drawCls.draw();
|
|
44350
44460
|
|
|
44351
44461
|
currentSession.removeEventListener( 'end', onSessionEnded );
|
|
44352
44462
|
|
|
@@ -44380,13 +44490,16 @@ class ARButton {
|
|
|
44380
44490
|
};
|
|
44381
44491
|
|
|
44382
44492
|
button.onclick = function () {
|
|
44383
|
-
// imposter didn't work well in
|
|
44384
|
-
|
|
44493
|
+
// imposter didn't work well in AR
|
|
44494
|
+
ic.bImpo = false;
|
|
44385
44495
|
|
|
44386
|
-
|
|
44496
|
+
// important to keet the background transparent
|
|
44497
|
+
ic.opts['background'] = 'transparent';
|
|
44387
44498
|
|
|
44388
|
-
|
|
44389
|
-
|
|
44499
|
+
ic.bAr = true;
|
|
44500
|
+
//ic.mdl.scale.copy(ic.mdl.scale.multiplyScalar(0.2));
|
|
44501
|
+
|
|
44502
|
+
ic.drawCls.draw(ic.bAr);
|
|
44390
44503
|
|
|
44391
44504
|
if ( currentSession === null ) {
|
|
44392
44505
|
|
|
@@ -49607,6 +49720,220 @@ class XRControllerModelFactory {
|
|
|
49607
49720
|
|
|
49608
49721
|
}
|
|
49609
49722
|
|
|
49723
|
+
//import * as THREE from './three/three.module.js';
|
|
49724
|
+
|
|
49725
|
+
// copied from https://github.com/NikLever/Learn-WebXR/blob/master/libs/ControllerGestures.js
|
|
49726
|
+
// created by Nik Lever
|
|
49727
|
+
|
|
49728
|
+
class ControllerGestures extends THREE.EventDispatcher{
|
|
49729
|
+
constructor( renderer ){
|
|
49730
|
+
super();
|
|
49731
|
+
|
|
49732
|
+
if (renderer === undefined){
|
|
49733
|
+
console.error('ControllerGestures must be passed a renderer');
|
|
49734
|
+
return;
|
|
49735
|
+
}
|
|
49736
|
+
|
|
49737
|
+
const clock = new THREE.Clock();
|
|
49738
|
+
|
|
49739
|
+
this.controller1 = renderer.xr.getController(0);
|
|
49740
|
+
this.controller1.userData.gestures = { index: 0 };
|
|
49741
|
+
this.controller1.userData.selectPressed = false;
|
|
49742
|
+
this.controller1.addEventListener( 'selectstart', onSelectStart );
|
|
49743
|
+
this.controller1.addEventListener( 'selectend', onSelectEnd );
|
|
49744
|
+
|
|
49745
|
+
this.controller2 = renderer.xr.getController(1);
|
|
49746
|
+
this.controller2.userData.gestures = { index: 1 };
|
|
49747
|
+
this.controller2.userData.selectPressed = false;
|
|
49748
|
+
this.controller2.addEventListener( 'selectstart', onSelectStart );
|
|
49749
|
+
this.controller2.addEventListener( 'selectend', onSelectEnd );
|
|
49750
|
+
|
|
49751
|
+
this.doubleClickLimit = 0.2;
|
|
49752
|
+
this.pressMinimum = 0.4;
|
|
49753
|
+
this.right = new THREE.Vector3(1,0,0);
|
|
49754
|
+
this.up = new THREE.Vector3(0,1,0);
|
|
49755
|
+
|
|
49756
|
+
this.type = 'unknown';
|
|
49757
|
+
this.touchCount = 0;
|
|
49758
|
+
|
|
49759
|
+
this.clock = clock;
|
|
49760
|
+
|
|
49761
|
+
const self = this;
|
|
49762
|
+
|
|
49763
|
+
function onSelectStart( ){
|
|
49764
|
+
const data = this.userData.gestures;
|
|
49765
|
+
|
|
49766
|
+
data.startPosition = undefined;
|
|
49767
|
+
data.startTime = clock.getElapsedTime();
|
|
49768
|
+
|
|
49769
|
+
if ( self.type.indexOf('tap') == -1) data.taps = 0;
|
|
49770
|
+
|
|
49771
|
+
self.type = 'unknown';
|
|
49772
|
+
this.userData.selectPressed = true;
|
|
49773
|
+
|
|
49774
|
+
self.touchCount++;
|
|
49775
|
+
|
|
49776
|
+
console.log( `onSelectStart touchCount: ${ self.touchCount }` );
|
|
49777
|
+
}
|
|
49778
|
+
|
|
49779
|
+
function onSelectEnd( ){
|
|
49780
|
+
const data = this.userData.gestures;
|
|
49781
|
+
|
|
49782
|
+
data.endTime = clock.getElapsedTime();
|
|
49783
|
+
const startToEnd = data.endTime - data.startTime;
|
|
49784
|
+
|
|
49785
|
+
//console.log(`ControllerGestures.onSelectEnd: startToEnd:${startToEnd.toFixed(2)} taps:${data.taps}`);
|
|
49786
|
+
|
|
49787
|
+
if (self.type === 'swipe'){
|
|
49788
|
+
const direction = ( self.controller1.position.y < data.startPosition.y) ? "DOWN" : "UP";
|
|
49789
|
+
self.dispatchEvent( { type:'swipe', direction } );
|
|
49790
|
+
self.type = 'unknown';
|
|
49791
|
+
}else if (self.type !== "pinch" && self.type !== "rotate" && self.type !== 'pan'){
|
|
49792
|
+
if ( startToEnd < self.doubleClickLimit ){
|
|
49793
|
+
self.type = "tap";
|
|
49794
|
+
data.taps++;
|
|
49795
|
+
}else if ( startToEnd > self.pressMinimum ){
|
|
49796
|
+
self.dispatchEvent( { type: 'press', position: self.controller1.position, matrixWorld: self.controller1.matrixWorld } );
|
|
49797
|
+
self.type = 'unknown';
|
|
49798
|
+
}
|
|
49799
|
+
}else {
|
|
49800
|
+
self.type = 'unknown';
|
|
49801
|
+
}
|
|
49802
|
+
|
|
49803
|
+
this.userData.selectPressed = false;
|
|
49804
|
+
data.startPosition = undefined;
|
|
49805
|
+
|
|
49806
|
+
self.touchCount--;
|
|
49807
|
+
}
|
|
49808
|
+
}
|
|
49809
|
+
|
|
49810
|
+
get multiTouch(){
|
|
49811
|
+
let result;
|
|
49812
|
+
if ( this.controller1 === undefined || this.controller2 === undefined ){
|
|
49813
|
+
result = false;
|
|
49814
|
+
}else {
|
|
49815
|
+
result = this.controller1.userData.selectPressed && this.controller2.userData.selectPressed;
|
|
49816
|
+
}
|
|
49817
|
+
const self = this;
|
|
49818
|
+
console.log( `ControllerGestures multiTouch: ${result} touchCount:${self.touchCount}`);
|
|
49819
|
+
return result;
|
|
49820
|
+
}
|
|
49821
|
+
|
|
49822
|
+
get touch(){
|
|
49823
|
+
let result;
|
|
49824
|
+
if ( this.controller1 === undefined || this.controller2 === undefined ){
|
|
49825
|
+
result = false;
|
|
49826
|
+
}else {
|
|
49827
|
+
result = this.controller1.userData.selectPressed || this.controller2.userData.selectPressed;
|
|
49828
|
+
}
|
|
49829
|
+
//console.log( `ControllerGestures touch: ${result}`);
|
|
49830
|
+
return result;
|
|
49831
|
+
}
|
|
49832
|
+
|
|
49833
|
+
get debugMsg(){
|
|
49834
|
+
return this.type;
|
|
49835
|
+
}
|
|
49836
|
+
|
|
49837
|
+
update(){
|
|
49838
|
+
const data1 = this.controller1.userData.gestures;
|
|
49839
|
+
const data2 = this.controller2.userData.gestures;
|
|
49840
|
+
const currentTime = this.clock.getElapsedTime();
|
|
49841
|
+
|
|
49842
|
+
let elapsedTime;
|
|
49843
|
+
|
|
49844
|
+
if (this.controller1.userData.selectPressed && data1.startPosition === undefined){
|
|
49845
|
+
elapsedTime = currentTime - data1.startTime;
|
|
49846
|
+
if (elapsedTime > 0.05 ) data1.startPosition = this.controller1.position.clone();
|
|
49847
|
+
}
|
|
49848
|
+
|
|
49849
|
+
if (this.controller2.userData.selectPressed && data2.startPosition === undefined){
|
|
49850
|
+
elapsedTime = currentTime - data2.startTime;
|
|
49851
|
+
if (elapsedTime > 0.05 ) data2.startPosition = this.controller2.position.clone();
|
|
49852
|
+
}
|
|
49853
|
+
|
|
49854
|
+
if (!this.controller1.userData.selectPressed && this.type === 'tap' ){
|
|
49855
|
+
//Only dispatch event after double click limit is passed
|
|
49856
|
+
elapsedTime = this.clock.getElapsedTime() - data1.endTime;
|
|
49857
|
+
if (elapsedTime > this.doubleClickLimit){
|
|
49858
|
+
console.log( `ControllerGestures.update dispatchEvent taps:${data1.taps}` );
|
|
49859
|
+
switch( data1.taps ){
|
|
49860
|
+
case 1:
|
|
49861
|
+
this.dispatchEvent( { type: 'tap', position: this.controller1.position, matrixWorld: this.controller1.matrixWorld } );
|
|
49862
|
+
break;
|
|
49863
|
+
case 2:
|
|
49864
|
+
this.dispatchEvent( { type: 'doubletap', position: this.controller1.position, matrixWorld: this.controller1.matrixWorld } );
|
|
49865
|
+
break;
|
|
49866
|
+
case 3:
|
|
49867
|
+
this.dispatchEvent( { type: 'tripletap', position: this.controller1.position, matrixWorld: this.controller1.matrixWorld } );
|
|
49868
|
+
break;
|
|
49869
|
+
case 4:
|
|
49870
|
+
this.dispatchEvent( { type: 'quadtap', position: this.controller1.position, matrixWorld: this.controller1.matrixWorld } );
|
|
49871
|
+
break;
|
|
49872
|
+
}
|
|
49873
|
+
this.type = "unknown";
|
|
49874
|
+
data1.taps = 0;
|
|
49875
|
+
}
|
|
49876
|
+
}
|
|
49877
|
+
|
|
49878
|
+
if (this.type === 'unknown' && this.touch){
|
|
49879
|
+
if (data1.startPosition !== undefined){
|
|
49880
|
+
if (this.multiTouch){
|
|
49881
|
+
if (data2.startPosition !== undefined){
|
|
49882
|
+
//startPosition is undefined for 1/20 sec
|
|
49883
|
+
//test for pinch or rotate
|
|
49884
|
+
const startDistance = data1.startPosition.distanceTo( data2.startPosition );
|
|
49885
|
+
const currentDistance = this.controller1.position.distanceTo( this.controller2.position );
|
|
49886
|
+
const delta = currentDistance - startDistance;
|
|
49887
|
+
if ( Math.abs(delta) > 0.01 ){
|
|
49888
|
+
this.type = 'pinch';
|
|
49889
|
+
this.startDistance = this.controller1.position.distanceTo( this.controller2.position );
|
|
49890
|
+
this.dispatchEvent( { type: 'pinch', delta: 0, scale: 1, initialise: true } );
|
|
49891
|
+
}else {
|
|
49892
|
+
const v1 = data2.startPosition.clone().sub( data1.startPosition ).normalize();
|
|
49893
|
+
const v2 = this.controller2.position.clone().sub( this.controller1.position ).normalize();
|
|
49894
|
+
const theta = v1.angleTo( v2 );
|
|
49895
|
+
if (Math.abs(theta) > 0.2){
|
|
49896
|
+
this.type = 'rotate';
|
|
49897
|
+
this.startVector = v2.clone();
|
|
49898
|
+
this.dispatchEvent( { type: 'rotate', theta: 0, initialise: true } );
|
|
49899
|
+
}
|
|
49900
|
+
}
|
|
49901
|
+
}
|
|
49902
|
+
}else {
|
|
49903
|
+
//test for swipe or pan
|
|
49904
|
+
let dist = data1.startPosition.distanceTo( this.controller1.position );
|
|
49905
|
+
elapsedTime = this.clock.getElapsedTime() - data1.startTime;
|
|
49906
|
+
const velocity = dist/elapsedTime;
|
|
49907
|
+
//console.log(`dist:${dist.toFixed(3)} velocity:${velocity.toFixed(3)}`);
|
|
49908
|
+
if ( dist > 0.01 && velocity > 0.1 ){
|
|
49909
|
+
const v = this.controller1.position.clone().sub( data1.startPosition );
|
|
49910
|
+
let maxY = (Math.abs(v.y) > Math.abs(v.x)) && (Math.abs(v.y) > Math.abs(v.z));
|
|
49911
|
+
if ( maxY )this.type = "swipe";
|
|
49912
|
+
}else if (dist > 0.006 && velocity < 0.03){
|
|
49913
|
+
this.type = "pan";
|
|
49914
|
+
this.startPosition = this.controller1.position.clone();
|
|
49915
|
+
this.dispatchEvent( { type: 'pan', delta: new THREE.Vector3(), initialise: true } );
|
|
49916
|
+
}
|
|
49917
|
+
}
|
|
49918
|
+
}
|
|
49919
|
+
}else if (this.type === 'pinch'){
|
|
49920
|
+
const currentDistance = this.controller1.position.distanceTo( this.controller2.position );
|
|
49921
|
+
const delta = currentDistance - this.startDistance;
|
|
49922
|
+
const scale = currentDistance/this.startDistance;
|
|
49923
|
+
this.dispatchEvent( { type: 'pinch', delta, scale });
|
|
49924
|
+
}else if (this.type === 'rotate'){
|
|
49925
|
+
const v = this.controller2.position.clone().sub( this.controller1.position ).normalize();
|
|
49926
|
+
let theta = this.startVector.angleTo( v );
|
|
49927
|
+
const cross = this.startVector.clone().cross( v );
|
|
49928
|
+
if (this.up.dot(cross) > 0) theta = -theta;
|
|
49929
|
+
this.dispatchEvent( { type: 'rotate', theta } );
|
|
49930
|
+
}else if (this.type === 'pan'){
|
|
49931
|
+
const delta = this.controller1.position.clone().sub( this.startPosition );
|
|
49932
|
+
this.dispatchEvent( { type: 'pan', delta } );
|
|
49933
|
+
}
|
|
49934
|
+
}
|
|
49935
|
+
}
|
|
49936
|
+
|
|
49610
49937
|
/**
|
|
49611
49938
|
* @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
|
|
49612
49939
|
*/
|
|
@@ -49627,6 +49954,8 @@ class Scene {
|
|
|
49627
49954
|
|
|
49628
49955
|
ic.cameraCls.setCamera();
|
|
49629
49956
|
|
|
49957
|
+
this.setVrAr();
|
|
49958
|
+
|
|
49630
49959
|
if(ic.bSkipChemicalbinding === undefined || !ic.bSkipChemicalbinding) {
|
|
49631
49960
|
ic.applyOtherCls.applyChemicalbindingOptions();
|
|
49632
49961
|
}
|
|
@@ -49767,22 +50096,6 @@ class Scene {
|
|
|
49767
50096
|
// highlight on impostors
|
|
49768
50097
|
ic.mdl_ghost = new THREE.Object3D(); // Impostor display
|
|
49769
50098
|
ic.scene_ghost.add(ic.mdl_ghost);
|
|
49770
|
-
|
|
49771
|
-
// for VR view
|
|
49772
|
-
let controller = ic.renderer.xr.getController( 0 );
|
|
49773
|
-
ic.scene.add( controller );
|
|
49774
|
-
|
|
49775
|
-
let controllerModelFactory = new XRControllerModelFactory();
|
|
49776
|
-
let controllerGrip = ic.renderer.xr.getControllerGrip( 0 );
|
|
49777
|
-
controllerGrip.add( controllerModelFactory.createControllerModel( controllerGrip ) );
|
|
49778
|
-
ic.scene.add( controllerGrip );
|
|
49779
|
-
|
|
49780
|
-
$("#" + me.pre + "VRButton").remove();
|
|
49781
|
-
//document.body.appendChild( ic.VRButtonCls.createButton( ic.renderer ) );
|
|
49782
|
-
$("#" + me.pre + "viewer").get(0).appendChild( ic.VRButtonCls.createButton( ic.renderer ) );
|
|
49783
|
-
|
|
49784
|
-
$("#" + me.pre + "ARButton").remove();
|
|
49785
|
-
$("#" + me.pre + "viewer").get(0).appendChild( ic.ARButtonCls.createButton( ic.renderer ) );
|
|
49786
50099
|
|
|
49787
50100
|
// related to pk
|
|
49788
50101
|
ic.objects = []; // define objects for pk, not all elements are used for pk
|
|
@@ -49814,8 +50127,196 @@ class Scene {
|
|
|
49814
50127
|
ic.cams = {
|
|
49815
50128
|
perspective: ic.perspectiveCamera,
|
|
49816
50129
|
orthographic: ic.orthographicCamera,
|
|
49817
|
-
};
|
|
50130
|
+
};
|
|
49818
50131
|
};
|
|
50132
|
+
|
|
50133
|
+
setVrAr() { let ic = this.icn3d, me = ic.icn3dui;
|
|
50134
|
+
|
|
50135
|
+
// https://github.com/NikLever/Learn-WebXR/tree/master/start
|
|
50136
|
+
// https://github.com/mrdoob/three.js/blob/master/examples/webxr_ar_cones.html
|
|
50137
|
+
// https://github.com/mrdoob/three.js/blob/master/examples/webxr_vr_cubes.html
|
|
50138
|
+
|
|
50139
|
+
if(ic.bVr) {
|
|
50140
|
+
/*
|
|
50141
|
+
ic.raycasterVR = new THREE.Raycaster();
|
|
50142
|
+
ic.workingMatrix = new THREE.Matrix4();
|
|
50143
|
+
ic.workingVector = new THREE.Vector3();
|
|
50144
|
+
ic.origin = new THREE.Vector3();
|
|
50145
|
+
|
|
50146
|
+
let radius = 0.08;
|
|
50147
|
+
let geometry = new THREE.IcosahedronBufferGeometry( radius, 2 );
|
|
50148
|
+
ic.highlightVR = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0xffffff, side: THREE.BackSide } ) );
|
|
50149
|
+
ic.highlightVR.scale.set(1.2, 1.2, 1.2);
|
|
50150
|
+
*/
|
|
50151
|
+
// modified from https://github.com/NikLever/Learn-WebXR/blob/master/complete/lecture3_7/app.js
|
|
50152
|
+
// add dolly to move camera
|
|
50153
|
+
ic.dolly = new THREE.Object3D();
|
|
50154
|
+
ic.dolly.position.z = 5;
|
|
50155
|
+
ic.dolly.add(ic.cam);
|
|
50156
|
+
ic.scene.add(ic.dolly);
|
|
50157
|
+
|
|
50158
|
+
ic.dummyCam = new THREE.Object3D();
|
|
50159
|
+
ic.cam.add(ic.dummyCam);
|
|
50160
|
+
|
|
50161
|
+
ic.clock = new THREE.Clock();
|
|
50162
|
+
|
|
50163
|
+
//controllers
|
|
50164
|
+
ic.controllers = this.getControllers();
|
|
50165
|
+
|
|
50166
|
+
ic.getInputSources = true; // default
|
|
50167
|
+
|
|
50168
|
+
function onSelectStart() {
|
|
50169
|
+
// this.children[0].scale.z = 10;
|
|
50170
|
+
this.userData.selectPressed = true;
|
|
50171
|
+
}
|
|
50172
|
+
|
|
50173
|
+
function onSelectEnd() {
|
|
50174
|
+
// this.children[0].scale.z = 0;
|
|
50175
|
+
// ic.highlightVR.visible = false;
|
|
50176
|
+
this.userData.selectPressed = false;
|
|
50177
|
+
}
|
|
50178
|
+
/*
|
|
50179
|
+
function buildController( data ) {
|
|
50180
|
+
let geometry, material;
|
|
50181
|
+
|
|
50182
|
+
switch ( data.targetRayMode ) {
|
|
50183
|
+
case 'tracked-pointer':
|
|
50184
|
+
geometry = new THREE.BufferGeometry();
|
|
50185
|
+
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) );
|
|
50186
|
+
geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) );
|
|
50187
|
+
|
|
50188
|
+
material = new THREE.LineBasicMaterial( { vertexColors: true, blending: THREE.AdditiveBlending } );
|
|
50189
|
+
|
|
50190
|
+
return new THREE.Line( geometry, material );
|
|
50191
|
+
|
|
50192
|
+
case 'gaze':
|
|
50193
|
+
geometry = new THREE.RingGeometry( 0.02, 0.04, 32 ).translate( 0, 0, - 1 );
|
|
50194
|
+
material = new THREE.MeshBasicMaterial( { opacity: 0.5, transparent: true } );
|
|
50195
|
+
return new THREE.Mesh( geometry, material );
|
|
50196
|
+
}
|
|
50197
|
+
}
|
|
50198
|
+
*/
|
|
50199
|
+
ic.controllers.forEach( (controller) => {
|
|
50200
|
+
controller.addEventListener( 'selectstart', onSelectStart );
|
|
50201
|
+
controller.addEventListener( 'selectend', onSelectEnd );
|
|
50202
|
+
/*
|
|
50203
|
+
controller.addEventListener( 'connected', function ( event ) {
|
|
50204
|
+
const mesh = buildController(event.data);
|
|
50205
|
+
mesh.scale.z = 0;
|
|
50206
|
+
this.add( mesh );
|
|
50207
|
+
} );
|
|
50208
|
+
controller.addEventListener( 'disconnected', function () {
|
|
50209
|
+
this.remove( this.children[ 0 ] );
|
|
50210
|
+
ic.controllers.forEach( (controllerTmp) => {
|
|
50211
|
+
controllerTmp = null;
|
|
50212
|
+
});
|
|
50213
|
+
//self.controllerGrip = null;
|
|
50214
|
+
} );
|
|
50215
|
+
*/
|
|
50216
|
+
});
|
|
50217
|
+
}
|
|
50218
|
+
else if(ic.bAr) {
|
|
50219
|
+
//Add gestures here
|
|
50220
|
+
ic.gestures = new ControllerGestures(ic.renderer);
|
|
50221
|
+
ic.scene.add(ic.gestures.controller1);
|
|
50222
|
+
ic.scene.add(ic.gestures.controller2);
|
|
50223
|
+
|
|
50224
|
+
ic.gestures.addEventListener('tap', (ev) => {
|
|
50225
|
+
//if(!ic.mdl.visible) {
|
|
50226
|
+
// ic.mdl.visible = true;
|
|
50227
|
+
//}
|
|
50228
|
+
|
|
50229
|
+
const controller = ic.gestures.controller1;
|
|
50230
|
+
//ic.mdl.position.set( 0, 0, - 0.3 ).applyMatrix4( controller.matrixWorld );
|
|
50231
|
+
ic.mdl.position.set( -0.03, 0, - 0.3 ).applyMatrix4( controller.matrixWorld );
|
|
50232
|
+
//ic.mdl.scale.copy(ic.mdl.scale.multiplyScalar(0.1));
|
|
50233
|
+
ic.mdl.scale.copy(new THREE.Vector3( 0.001, 0.001, 0.001 ));
|
|
50234
|
+
});
|
|
50235
|
+
|
|
50236
|
+
ic.gestures.addEventListener('doubletap', (ev) => {
|
|
50237
|
+
const controller = ic.gestures.controller1;
|
|
50238
|
+
//ic.mdl.position.set( 0, 0, - 0.3 ).applyMatrix4( controller.matrixWorld );
|
|
50239
|
+
ic.mdl.position.set( -0.06, 0, - 0.6 ).applyMatrix4( controller.matrixWorld );
|
|
50240
|
+
//ic.mdl.scale.copy(ic.mdl.scale.multiplyScalar(10));
|
|
50241
|
+
ic.mdl.scale.copy(new THREE.Vector3( 0.005, 0.005, 0.005 ));
|
|
50242
|
+
});
|
|
50243
|
+
/*
|
|
50244
|
+
ic.gestures.addEventListener('swipe', (ev) => {
|
|
50245
|
+
// if(ic.mdl.visible) {
|
|
50246
|
+
// ic.mdl.visible = false;
|
|
50247
|
+
// }
|
|
50248
|
+
});
|
|
50249
|
+
|
|
50250
|
+
ic.gestures.addEventListener('pan', (ev) => {
|
|
50251
|
+
// if(ev.initialise !== undefined) {
|
|
50252
|
+
// thisClass.startPosition = ic.mdl.position.clone();
|
|
50253
|
+
// }
|
|
50254
|
+
// else {
|
|
50255
|
+
// const pos = thisClass.startPosition.clone().add(ev.delta.multiplyScalar(3));
|
|
50256
|
+
// ic.mdl.position.copy(pos);
|
|
50257
|
+
// }
|
|
50258
|
+
});
|
|
50259
|
+
|
|
50260
|
+
ic.gestures.addEventListener('pinch', (ev) => {
|
|
50261
|
+
// if(ev.initialise !== undefined) {
|
|
50262
|
+
// thisClass.startScale = ic.mdl.scale.clone();
|
|
50263
|
+
// }
|
|
50264
|
+
// else {
|
|
50265
|
+
// const scale = thisClass.startScale.clone().multiplyScalar(ev.scale);
|
|
50266
|
+
// ic.mdl.scale.copy(scale);
|
|
50267
|
+
// }
|
|
50268
|
+
});
|
|
50269
|
+
|
|
50270
|
+
ic.gestures.addEventListener('rotate', (ev) => {
|
|
50271
|
+
// if(ev.initialise !== undefined) {
|
|
50272
|
+
// thisClass.startQuaternion = ic.mdl.quaternion.clone();
|
|
50273
|
+
// }
|
|
50274
|
+
// else {
|
|
50275
|
+
// ic.mdl.quaternion.copy(thisClass.startQuaternion);
|
|
50276
|
+
// ic.mdl.rotateY(ev.theta);
|
|
50277
|
+
// }
|
|
50278
|
+
});
|
|
50279
|
+
*/
|
|
50280
|
+
}
|
|
50281
|
+
|
|
50282
|
+
$("#" + me.pre + "VRButton").remove();
|
|
50283
|
+
$("#" + me.pre + "viewer").get(0).appendChild( ic.VRButtonCls.createButton( ic.renderer ) );
|
|
50284
|
+
|
|
50285
|
+
$("#" + me.pre + "ARButton").remove();
|
|
50286
|
+
$("#" + me.pre + "viewer").get(0).appendChild( ic.ARButtonCls.createButton( ic.renderer ) );
|
|
50287
|
+
}
|
|
50288
|
+
|
|
50289
|
+
getControllers() { let ic = this.icn3d; ic.icn3dui;
|
|
50290
|
+
const controllerModelFactory = new XRControllerModelFactory();
|
|
50291
|
+
/*
|
|
50292
|
+
const geometry = new THREE.BufferGeometry().setFromPoints( [
|
|
50293
|
+
new THREE.Vector3(0,0,0),
|
|
50294
|
+
new THREE.Vector3(0,0,-1)
|
|
50295
|
+
]);
|
|
50296
|
+
const line = new THREE.Line( geometry );
|
|
50297
|
+
line.name = 'line';
|
|
50298
|
+
line.scale.z = 0;
|
|
50299
|
+
*/
|
|
50300
|
+
|
|
50301
|
+
const controllers = [];
|
|
50302
|
+
|
|
50303
|
+
for(let i=0; i<=1; i++){
|
|
50304
|
+
const controller = ic.renderer.xr.getController( i );
|
|
50305
|
+
ic.dolly.add( controller );
|
|
50306
|
+
|
|
50307
|
+
// controller.add( line.clone() );
|
|
50308
|
+
controller.userData.selectPressed = false;
|
|
50309
|
+
ic.scene.add(controller);
|
|
50310
|
+
|
|
50311
|
+
controllers.push( controller );
|
|
50312
|
+
|
|
50313
|
+
const grip = ic.renderer.xr.getControllerGrip( i );
|
|
50314
|
+
grip.add( controllerModelFactory.createControllerModel( grip ));
|
|
50315
|
+
ic.scene.add( grip );
|
|
50316
|
+
}
|
|
50317
|
+
|
|
50318
|
+
return controllers;
|
|
50319
|
+
}
|
|
49819
50320
|
}
|
|
49820
50321
|
|
|
49821
50322
|
/**
|
|
@@ -51029,7 +51530,7 @@ class Draw {
|
|
|
51029
51530
|
}
|
|
51030
51531
|
|
|
51031
51532
|
//Draw the 3D structure. It rebuilds scene, applies previous color, applies the transformation, and renders the image.
|
|
51032
|
-
draw(
|
|
51533
|
+
draw(bVrAr) { let ic = this.icn3d, me = ic.icn3dui;
|
|
51033
51534
|
if(ic.bRender && (!ic.hAtoms || Object.keys(ic.hAtoms) == 0)) ic.hAtoms = me.hashUtilsCls.cloneHash(ic.atoms);
|
|
51034
51535
|
|
|
51035
51536
|
ic.sceneCls.rebuildScene();
|
|
@@ -51067,7 +51568,7 @@ class Draw {
|
|
|
51067
51568
|
}
|
|
51068
51569
|
|
|
51069
51570
|
this.applyTransformation(ic._zoomFactor, ic.mouseChange, ic.quaternion);
|
|
51070
|
-
this.render(
|
|
51571
|
+
this.render(bVrAr);
|
|
51071
51572
|
}
|
|
51072
51573
|
|
|
51073
51574
|
ic.impostorCls.clearImpostors();
|
|
@@ -51100,10 +51601,10 @@ class Draw {
|
|
|
51100
51601
|
}
|
|
51101
51602
|
|
|
51102
51603
|
//Render the scene and objects into pixels.
|
|
51103
|
-
render(
|
|
51604
|
+
render(bVrAr) { let ic = this.icn3d; ic.icn3dui;
|
|
51104
51605
|
let thisClass = this;
|
|
51105
51606
|
// setAnimationLoop is required for VR
|
|
51106
|
-
if(
|
|
51607
|
+
if(bVrAr) {
|
|
51107
51608
|
ic.renderer.setAnimationLoop( function() {
|
|
51108
51609
|
thisClass.render_base();
|
|
51109
51610
|
});
|
|
@@ -51113,8 +51614,39 @@ class Draw {
|
|
|
51113
51614
|
}
|
|
51114
51615
|
}
|
|
51115
51616
|
|
|
51617
|
+
handleController( controller, dt, selectPressed) { let ic = this.icn3d; ic.icn3dui;
|
|
51618
|
+
// modified from https://github.com/NikLever/Learn-WebXR/blob/master/complete/lecture3_7/app.js
|
|
51619
|
+
if ( selectPressed ){
|
|
51620
|
+
/*
|
|
51621
|
+
ic.workingMatrix.identity().extractRotation( controller.matrixWorld );
|
|
51622
|
+
|
|
51623
|
+
ic.raycasterVR.ray.origin.setFromMatrixPosition( controller.matrixWorld );
|
|
51624
|
+
ic.raycasterVR.ray.direction.set( 0, 0, - 1 ).applyMatrix4( ic.workingMatrix );
|
|
51625
|
+
|
|
51626
|
+
const intersects = ic.raycasterVR.intersectObjects( ic.objects );
|
|
51627
|
+
|
|
51628
|
+
if (intersects.length>0){
|
|
51629
|
+
intersects[0].object.add(ic.highlightVR);
|
|
51630
|
+
ic.highlightVR.visible = true;
|
|
51631
|
+
}else{
|
|
51632
|
+
ic.highlightVR.visible = false;
|
|
51633
|
+
}
|
|
51634
|
+
*/
|
|
51635
|
+
const speed = 5; //2;
|
|
51636
|
+
const quaternion = ic.dolly.quaternion.clone();
|
|
51637
|
+
//ic.dolly.quaternion.copy(ic.dummyCam.getWorldQuaternion());
|
|
51638
|
+
ic.dummyCam.getWorldQuaternion(ic.dolly.quaternion);
|
|
51639
|
+
ic.dolly.translateZ(-dt * speed);
|
|
51640
|
+
//ic.dolly.position.y = 0; // limit to a plane
|
|
51641
|
+
ic.dolly.quaternion.copy(quaternion);
|
|
51642
|
+
|
|
51643
|
+
}
|
|
51644
|
+
}
|
|
51645
|
+
|
|
51116
51646
|
//Render the scene and objects into pixels.
|
|
51117
51647
|
render_base() { let ic = this.icn3d, me = ic.icn3dui;
|
|
51648
|
+
let thisClass = this;
|
|
51649
|
+
|
|
51118
51650
|
if(me.bNode) return;
|
|
51119
51651
|
|
|
51120
51652
|
let cam = (ic.bControlGl && !me.bNode) ? window.cam : ic.cam;
|
|
@@ -51129,10 +51661,88 @@ class Draw {
|
|
|
51129
51661
|
}
|
|
51130
51662
|
|
|
51131
51663
|
ic.renderer.setPixelRatio( window.devicePixelRatio ); // r71
|
|
51664
|
+
|
|
51665
|
+
if(ic.bVr) {
|
|
51666
|
+
let dt = 0.04; // ic.clock.getDelta();
|
|
51667
|
+
|
|
51668
|
+
if (ic.controllers){
|
|
51669
|
+
// let result = this.getThumbStickMove();
|
|
51670
|
+
// let y = result.y * -1;
|
|
51671
|
+
// let pressed = result.pressed;
|
|
51672
|
+
|
|
51673
|
+
for(let i = 0, il = ic.controllers.length; i < il; ++i) {
|
|
51674
|
+
let controller = ic.controllers[i];
|
|
51675
|
+
dt = (i % 2 == 0) ? dt : -dt; // dt * y;
|
|
51676
|
+
thisClass.handleController( controller, dt, controller.userData.selectPressed );
|
|
51677
|
+
//thisClass.handleController( controller, dt, pressed );
|
|
51678
|
+
}
|
|
51679
|
+
}
|
|
51680
|
+
}
|
|
51681
|
+
else if(ic.bAr) {
|
|
51682
|
+
if ( ic.renderer.xr.isPresenting ){
|
|
51683
|
+
ic.gestures.update();
|
|
51684
|
+
}
|
|
51685
|
+
}
|
|
51686
|
+
|
|
51132
51687
|
if(ic.scene) {
|
|
51133
51688
|
ic.renderer.render(ic.scene, cam);
|
|
51134
51689
|
}
|
|
51135
51690
|
}
|
|
51691
|
+
|
|
51692
|
+
getThumbStickMove() { let ic = this.icn3d; ic.icn3dui;
|
|
51693
|
+
let y = 0;
|
|
51694
|
+
let btnPressed = false;
|
|
51695
|
+
|
|
51696
|
+
if ( ic.renderer.xr.isPresenting ){
|
|
51697
|
+
const session = ic.renderer.xr.getSession();
|
|
51698
|
+
const inputSources = session.inputSources;
|
|
51699
|
+
|
|
51700
|
+
if ( ic.getInputSources ){
|
|
51701
|
+
//const info = [];
|
|
51702
|
+
|
|
51703
|
+
inputSources.forEach( inputSource => {
|
|
51704
|
+
const gp = inputSource.gamepad;
|
|
51705
|
+
gp.axes;
|
|
51706
|
+
gp.buttons;
|
|
51707
|
+
const mapping = gp.mapping;
|
|
51708
|
+
ic.useStandard = (mapping == 'xr-standard');
|
|
51709
|
+
inputSource.handedness;
|
|
51710
|
+
const profiles = inputSource.profiles;
|
|
51711
|
+
ic.gamepadType = "";
|
|
51712
|
+
profiles.forEach( profile => {
|
|
51713
|
+
if (profile.indexOf('touchpad')!=-1) ic.gamepadType = 'touchpad';
|
|
51714
|
+
if (profile.indexOf('thumbstick')!=-1) ic.gamepadType = 'thumbstick';
|
|
51715
|
+
});
|
|
51716
|
+
inputSource.targetRayMode;
|
|
51717
|
+
//info.push({ gamepad, handedness, profiles, targetRayMode });
|
|
51718
|
+
});
|
|
51719
|
+
|
|
51720
|
+
//console.log( JSON.stringify(info) );
|
|
51721
|
+
|
|
51722
|
+
ic.getInputSources = false;
|
|
51723
|
+
}else if (ic.useStandard && ic.gamepadType != ""){
|
|
51724
|
+
inputSources.forEach( inputSource => {
|
|
51725
|
+
const gp = inputSource.gamepad;
|
|
51726
|
+
const thumbstick = (ic.gamepadType=='thumbstick');
|
|
51727
|
+
//{"trigger":{"button":0},"touchpad":{"button":2,"xAxis":0,"yAxis":1}},
|
|
51728
|
+
//"squeeze":{"button":1},"thumbstick":{"button":3,"xAxis":2,"yAxis":3},"button":{"button":6}}}
|
|
51729
|
+
const xaxisOffset = (thumbstick) ? 2 : 0;
|
|
51730
|
+
const btnIndex = (thumbstick) ? 3 : 2;
|
|
51731
|
+
btnPressed = gp.buttons[btnIndex].pressed;
|
|
51732
|
+
// if ( inputSource.handedness == 'right') {
|
|
51733
|
+
// } else if ( inputSource.handedness == 'left') {
|
|
51734
|
+
// }
|
|
51735
|
+
|
|
51736
|
+
//https://beej.us/blog/data/javascript-gamepad/
|
|
51737
|
+
// x,y-axis values are between -1 and 1
|
|
51738
|
+
gp.axes[xaxisOffset];
|
|
51739
|
+
y = gp.axes[xaxisOffset + 1];
|
|
51740
|
+
});
|
|
51741
|
+
}
|
|
51742
|
+
}
|
|
51743
|
+
|
|
51744
|
+
return {'y': y, 'pressed': btnPressed};
|
|
51745
|
+
}
|
|
51136
51746
|
}
|
|
51137
51747
|
|
|
51138
51748
|
/**
|
|
@@ -51739,7 +52349,7 @@ class SaveFile {
|
|
|
51739
52349
|
}
|
|
51740
52350
|
|
|
51741
52351
|
//getAtomPDB: function(atomHash, bPqr, bPdb, bNoChem) { let ic = this.icn3d, me = ic.icn3dui;
|
|
51742
|
-
getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader) { let ic = this.icn3d, me = ic.icn3dui;
|
|
52352
|
+
getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader, chainResi2pdb) { let ic = this.icn3d, me = ic.icn3dui;
|
|
51743
52353
|
let pdbStr = '';
|
|
51744
52354
|
|
|
51745
52355
|
// get all phosphate groups in lipids
|
|
@@ -51884,9 +52494,19 @@ class SaveFile {
|
|
|
51884
52494
|
let molNum = 1, prevStru = '';
|
|
51885
52495
|
//pdbStr += '\n';
|
|
51886
52496
|
|
|
52497
|
+
let addedChainResiHash = {};
|
|
51887
52498
|
for(let i in atomHash) {
|
|
51888
52499
|
let atom = ic.atoms[i];
|
|
51889
52500
|
|
|
52501
|
+
let chainResi = atom.chain + '_' + atom.resi;
|
|
52502
|
+
if(chainResi2pdb && chainResi2pdb.hasOwnProperty(chainResi)) {
|
|
52503
|
+
if(!addedChainResiHash.hasOwnProperty(chainResi)) {
|
|
52504
|
+
pdbStr += chainResi2pdb[chainResi];
|
|
52505
|
+
addedChainResiHash[chainResi] = 1;
|
|
52506
|
+
}
|
|
52507
|
+
continue;
|
|
52508
|
+
}
|
|
52509
|
+
|
|
51890
52510
|
// remove chemicals
|
|
51891
52511
|
if(bNoChem && atom.het) continue;
|
|
51892
52512
|
|
|
@@ -51899,8 +52519,9 @@ class SaveFile {
|
|
|
51899
52519
|
|
|
51900
52520
|
if(bMulStruc) pdbStr += 'MODEL ' + molNum + '\n';
|
|
51901
52521
|
|
|
51902
|
-
// add header
|
|
51903
|
-
|
|
52522
|
+
// add header
|
|
52523
|
+
let mutantInfo = (chainResi2pdb) ? "Mutated chain_residue " + Object.keys(chainResi2pdb) + '; ' : '';
|
|
52524
|
+
if(!bNoHeader) pdbStr += this.getPDBHeader(molNum - 1, stru2header, mutantInfo);
|
|
51904
52525
|
|
|
51905
52526
|
prevStru = atom.structure;
|
|
51906
52527
|
++molNum;
|
|
@@ -52128,21 +52749,25 @@ class SaveFile {
|
|
|
52128
52749
|
|
|
52129
52750
|
return pdbStr;
|
|
52130
52751
|
}
|
|
52131
|
-
getPDBHeader(struNum, stru2header) { let ic = this.icn3d; ic.icn3dui;
|
|
52752
|
+
getPDBHeader(struNum, stru2header, mutantInfo) { let ic = this.icn3d; ic.icn3dui;
|
|
52132
52753
|
if(struNum === undefined) struNum = 0;
|
|
52133
52754
|
|
|
52134
52755
|
let pdbStr = '';
|
|
52135
52756
|
let stru = Object.keys(ic.structures)[struNum];
|
|
52136
|
-
|
|
52757
|
+
let id = (mutantInfo) ? stru + '2' : stru;
|
|
52758
|
+
pdbStr += 'HEADER PDB From iCn3D'.padEnd(62, ' ') + id + '\n';
|
|
52137
52759
|
|
|
52138
52760
|
if(struNum == 0) {
|
|
52139
52761
|
let title =(ic.molTitle.length > 50) ? ic.molTitle.substr(0,47) + '...' : ic.molTitle;
|
|
52140
52762
|
// remove quotes
|
|
52141
52763
|
if(title.indexOf('"') != -1) title = '';
|
|
52764
|
+
if(mutantInfo) {
|
|
52765
|
+
title = mutantInfo + title;
|
|
52766
|
+
}
|
|
52142
52767
|
pdbStr += 'TITLE ' + title + '\n';
|
|
52143
52768
|
}
|
|
52144
52769
|
|
|
52145
|
-
if(stru2header) {
|
|
52770
|
+
if(stru2header && stru2header[stru]) {
|
|
52146
52771
|
pdbStr += stru2header[stru];
|
|
52147
52772
|
}
|
|
52148
52773
|
|
|
@@ -52205,6 +52830,9 @@ class SaveFile {
|
|
|
52205
52830
|
if(me.cfg.cid !== undefined) {
|
|
52206
52831
|
url = "https://www.ncbi.nlm.nih.gov/pccompound/?term=";
|
|
52207
52832
|
}
|
|
52833
|
+
else if(me.cfg.afid !== undefined) {
|
|
52834
|
+
url = "https://alphafold.ebi.ac.uk/search/text/";
|
|
52835
|
+
}
|
|
52208
52836
|
else {
|
|
52209
52837
|
//if(ic.inputid.indexOf(",") !== -1) {
|
|
52210
52838
|
if(Object.keys(ic.structures).length > 1) {
|
|
@@ -52224,11 +52852,17 @@ class SaveFile {
|
|
|
52224
52852
|
|
|
52225
52853
|
if(idArray.length === 1) {
|
|
52226
52854
|
url += ic.inputid;
|
|
52227
|
-
if(bLog) me.htmlCls.clickMenuCls.setLogCmd("link to
|
|
52855
|
+
if(bLog) me.htmlCls.clickMenuCls.setLogCmd("link to " + ic.inputid + ": " + url, false);
|
|
52228
52856
|
}
|
|
52229
52857
|
else if(idArray.length === 2) {
|
|
52230
|
-
|
|
52231
|
-
|
|
52858
|
+
if(me.cfg.afid) {
|
|
52859
|
+
url += idArray[0] + " " + idArray[1];
|
|
52860
|
+
}
|
|
52861
|
+
else {
|
|
52862
|
+
url += idArray[0] + " OR " + idArray[1];
|
|
52863
|
+
}
|
|
52864
|
+
|
|
52865
|
+
if(bLog) me.htmlCls.clickMenuCls.setLogCmd("link to structures " + idArray[0] + " and " + idArray[1] + ": " + url, false);
|
|
52232
52866
|
}
|
|
52233
52867
|
}
|
|
52234
52868
|
|
|
@@ -54908,7 +55542,7 @@ class SetMenu {
|
|
|
54908
55542
|
html += "<ul>";
|
|
54909
55543
|
html += me.htmlCls.setHtmlCls.getLink('mn1_vastplus', 'NCBI VAST+ (PDB Assembly)' + me.htmlCls.wifiStr);
|
|
54910
55544
|
html += me.htmlCls.setHtmlCls.getLink('mn1_vast', 'NCBI VAST (PDB)' + me.htmlCls.wifiStr);
|
|
54911
|
-
html += me.htmlCls.setHtmlCls.getLink('mn1_foldseek', 'Foldseek (PDB &
|
|
55545
|
+
html += me.htmlCls.setHtmlCls.getLink('mn1_foldseek', 'Foldseek (PDB & AlphaFold)' + me.htmlCls.wifiStr);
|
|
54912
55546
|
html += "</ul>";
|
|
54913
55547
|
|
|
54914
55548
|
html += "<li><span>Retrieve by ID</span>";
|
|
@@ -55224,11 +55858,22 @@ class SetMenu {
|
|
|
55224
55858
|
|
|
55225
55859
|
html += "<li>-</li>";
|
|
55226
55860
|
|
|
55861
|
+
let liStr = "<li><a href='";
|
|
55862
|
+
|
|
55227
55863
|
html += "<li><span>VR & AR Hints</span>";
|
|
55228
55864
|
html += "<ul>";
|
|
55229
|
-
html += "
|
|
55230
|
-
html += "
|
|
55865
|
+
html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#vr' target='_blank'>VR: VR Headsets</a></li>";
|
|
55866
|
+
html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#ar' target='_blank'>AR: Chrome in Android</a></li>";
|
|
55231
55867
|
html += "</ul>";
|
|
55868
|
+
/*
|
|
55869
|
+
let liStr = "<li><a href='";
|
|
55870
|
+
|
|
55871
|
+
html += "<ul class='icn3d-mn-item'>";
|
|
55872
|
+
|
|
55873
|
+
html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#about' target='_blank'>About iCn3D<span style='font-size:0.9em'> " + me.REVISION + "</span></a></li>";
|
|
55874
|
+
|
|
55875
|
+
html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#gallery' target='_blank'>Live Gallery " + me.htmlCls.wifiStr + "</a></li>";
|
|
55876
|
+
*/
|
|
55232
55877
|
|
|
55233
55878
|
html += me.htmlCls.setHtmlCls.getLink('mn6_sidebyside', 'Side by Side');
|
|
55234
55879
|
|
|
@@ -57752,7 +58397,7 @@ class SetDialog {
|
|
|
57752
58397
|
html += "</div>";
|
|
57753
58398
|
html += me.htmlCls.divStr + "tracktab4'>";
|
|
57754
58399
|
html += "Track Title: " + me.htmlCls.inputTextStr + "id='" + me.pre + "track_title' placeholder='track title' size=16> <br><br>";
|
|
57755
|
-
html += "Track Text(e.g., \"
|
|
58400
|
+
html += "Track Text (e.g., \"2 G, 5-6 RR\" defines a character \"G\" at the position 2 and two continuous characters \"RR\" at positions from 5 to 6. The starting position is 1): <br>";
|
|
57756
58401
|
html += "<textarea id='" + me.pre + "track_text' rows='5' style='width: 100%; height: " +(2*me.htmlCls.MENU_HEIGHT) + "px; padding: 0px; border: 0px;'></textarea><br><br>";
|
|
57757
58402
|
html += me.htmlCls.buttonStr + "addtrack_button4'>Add Track</button>";
|
|
57758
58403
|
html += "</div>";
|
|
@@ -58077,6 +58722,11 @@ class Events {
|
|
|
58077
58722
|
let pos = hostUrl.indexOf("?");
|
|
58078
58723
|
hostUrl = (pos == -1) ? hostUrl : hostUrl.substr(0, pos);
|
|
58079
58724
|
|
|
58725
|
+
// some URLs from VAST search are like https://www.ncbi.nlm.nih.gov/Structure/vast/icn3d/
|
|
58726
|
+
if(hostUrl == 'https://www.ncbi.nlm.nih.gov/Structure/vast/icn3d/') {
|
|
58727
|
+
hostUrl = 'https://www.ncbi.nlm.nih.gov/Structure/icn3d/';
|
|
58728
|
+
}
|
|
58729
|
+
|
|
58080
58730
|
ic.definedSetsCls.clickCustomAtoms();
|
|
58081
58731
|
ic.definedSetsCls.clickCommand_apply();
|
|
58082
58732
|
ic.definedSetsCls.clickModeswitch();
|
|
@@ -60248,6 +60898,7 @@ class AlignSeq {
|
|
|
60248
60898
|
let index = 0,
|
|
60249
60899
|
prevResCnt2nd = 0;
|
|
60250
60900
|
let firstChainid, oriChainid;
|
|
60901
|
+
|
|
60251
60902
|
// for(let i in ic.alnChains) {
|
|
60252
60903
|
for (let m = 0, ml = alignChainArray.length; m < ml; ++m) {
|
|
60253
60904
|
let i = alignChainArray[m];
|
|
@@ -60396,6 +61047,9 @@ class AlignSeq {
|
|
|
60396
61047
|
resiHtmlArray[j] += '<span class="icn3d-sheet"> </span>';
|
|
60397
61048
|
}
|
|
60398
61049
|
}
|
|
61050
|
+
else {
|
|
61051
|
+
resiHtmlArray[j] += '<span class="icn3d-sheet"> </span>';
|
|
61052
|
+
}
|
|
60399
61053
|
} else if (text == 'c') {
|
|
60400
61054
|
resiHtmlArray[j] += '<span class="icn3d-coil"> </span>';
|
|
60401
61055
|
} else if (text == 'o') {
|
|
@@ -61452,17 +62106,20 @@ class Alternate {
|
|
|
61452
62106
|
let viewSelectionAtomsCount = Object.keys(ic.viewSelectionAtoms).length;
|
|
61453
62107
|
let allAtomsCount = Object.keys(ic.atoms).length;
|
|
61454
62108
|
|
|
61455
|
-
ic.dAtoms = {};
|
|
62109
|
+
//ic.dAtoms = {};
|
|
62110
|
+
|
|
62111
|
+
// 1. alternate all structures
|
|
62112
|
+
//let moleculeArray = Object.keys(ic.structures);
|
|
61456
62113
|
|
|
61457
|
-
// alternate
|
|
61458
|
-
let
|
|
61459
|
-
|
|
61460
|
-
|
|
61461
|
-
|
|
61462
|
-
|
|
61463
|
-
|
|
61464
|
-
|
|
61465
|
-
|
|
62114
|
+
// 2. only alternate displayed structures
|
|
62115
|
+
let structureHash = {};
|
|
62116
|
+
for(let i in ic.viewSelectionAtoms) {
|
|
62117
|
+
let structure = ic.atoms[i].structure;
|
|
62118
|
+
structureHash[structure] = 1;
|
|
62119
|
+
}
|
|
62120
|
+
let moleculeArray = Object.keys(structureHash);
|
|
62121
|
+
|
|
62122
|
+
ic.dAtoms = {};
|
|
61466
62123
|
|
|
61467
62124
|
for(let i = 0, il = moleculeArray.length; i < il; ++i) {
|
|
61468
62125
|
let structure = moleculeArray[i];
|
|
@@ -62206,7 +62863,7 @@ class ContactMap {
|
|
|
62206
62863
|
|
|
62207
62864
|
let graphStr = '{\n';
|
|
62208
62865
|
|
|
62209
|
-
let struc1 = (ic.structures.length > 0) ? ic.structures[0] : '
|
|
62866
|
+
let struc1 = (ic.structures.length > 0) ? ic.structures[0] : 'stru';
|
|
62210
62867
|
let len1 = nodeArray1.length,
|
|
62211
62868
|
len2 = nodeArray2.length;
|
|
62212
62869
|
let factor = 1;
|
|
@@ -64554,6 +65211,8 @@ class iCn3D {
|
|
|
64554
65211
|
this.bNotLoadStructure = false;
|
|
64555
65212
|
|
|
64556
65213
|
this.InputfileData = '';
|
|
65214
|
+
this.bVr = false; // cflag to indicate whether in VR state
|
|
65215
|
+
this.bAr = false; // cflag to indicate whether in VR state
|
|
64557
65216
|
|
|
64558
65217
|
// default color range for Add Custom Color button in the Sequence & Annotation window
|
|
64559
65218
|
this.startColor = 'blue';
|
|
@@ -64885,7 +65544,7 @@ class iCn3DUI {
|
|
|
64885
65544
|
//even when multiple iCn3D viewers are shown together.
|
|
64886
65545
|
this.pre = this.cfg.divid + "_";
|
|
64887
65546
|
|
|
64888
|
-
this.REVISION = '3.12.
|
|
65547
|
+
this.REVISION = '3.12.5';
|
|
64889
65548
|
|
|
64890
65549
|
// In nodejs, iCn3D defines "window = {navigator: {}}"
|
|
64891
65550
|
this.bNode = (Object.keys(window).length < 2) ? true : false;
|
|
@@ -65053,6 +65712,11 @@ iCn3DUI.prototype.show3DStructure = function(pdbStr) { let me = this;
|
|
|
65053
65712
|
|
|
65054
65713
|
if(pdbStr) { // input pdbStr
|
|
65055
65714
|
ic.init();
|
|
65715
|
+
|
|
65716
|
+
ic.bInputfile = true;
|
|
65717
|
+
ic.InputfileType = 'pdb';
|
|
65718
|
+
ic.InputfileData = (ic.InputfileData) ? ic.InputfileData + '\nENDMDL\n' + pdbStr : pdbStr;
|
|
65719
|
+
|
|
65056
65720
|
ic.pdbParserCls.loadPdbData(pdbStr);
|
|
65057
65721
|
|
|
65058
65722
|
if(me.cfg.resdef !== undefined && me.cfg.chains !== undefined) {
|