icn3d 3.7.0 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/icn3d.js +762 -219
  2. package/package.json +3 -2
package/icn3d.js CHANGED
@@ -2462,7 +2462,10 @@ THREE.TrackballControls = function ( object, domElement, icn3d ) {
2462
2462
 
2463
2463
  _eye.multiplyScalar( factor );
2464
2464
 
2465
- if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) icn3d._zoomFactor *= factor;
2465
+ if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) {
2466
+ icn3d._zoomFactor *= factor;
2467
+ icn3d.fogCls.setFog();
2468
+ }
2466
2469
 
2467
2470
  } else {
2468
2471
 
@@ -2475,7 +2478,10 @@ THREE.TrackballControls = function ( object, domElement, icn3d ) {
2475
2478
  factor = 1.0 + ( _this._zoomEnd.y - _this._zoomStart.y ) * _this.zoomSpeed;
2476
2479
  }
2477
2480
 
2478
- if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) icn3d._zoomFactor *= factor;
2481
+ if(icn3d !== undefined && icn3d._zoomFactor !== undefined && (bUpdate === undefined || bUpdate === true)) {
2482
+ icn3d._zoomFactor *= factor;
2483
+ icn3d.fogCls.setFog();
2484
+ }
2479
2485
 
2480
2486
  //if ( factor !== 1.0 && factor > 0.0 ) {
2481
2487
  if ( factor !== 1.0 ) {
@@ -5854,7 +5860,8 @@ class Fog {
5854
5860
  if(bZoomin) {
5855
5861
  let centerAtomsResults = ic.applyCenterCls.centerAtoms(ic.hAtoms);
5856
5862
  ic.maxD = centerAtomsResults.maxD;
5857
- if (ic.maxD < 5) ic.maxD = 5;
5863
+ //if (ic.maxD < 5) ic.maxD = 5;
5864
+ if (ic.maxD < 25) ic.maxD = 25;
5858
5865
  }
5859
5866
 
5860
5867
  let bInstance = (ic.biomtMatrices !== undefined && ic.biomtMatrices.length * ic.cnt > ic.maxatomcnt) ? true : false;
@@ -5871,7 +5878,9 @@ class Fog {
5871
5878
  ic.bSetFog = false;
5872
5879
  }
5873
5880
  else {
5874
- ic.scene.fog = new THREE.Fog(background, 2.5*ic.maxD, 4*ic.maxD);
5881
+ // adjust
5882
+ let zoomFactor = (ic._zoomFactor > 1) ? ic._zoomFactor * 1.0 : ic._zoomFactor;
5883
+ ic.scene.fog = new THREE.Fog(background, 2.5 * ic.maxD * zoomFactor, 4 * ic.maxD * zoomFactor);
5875
5884
  ic.bSetFog = true;
5876
5885
  ic.camMaxDFactorFog = 3;
5877
5886
  }
@@ -5890,9 +5899,9 @@ class Fog {
5890
5899
  ic.bSetFog = false;
5891
5900
  }
5892
5901
 
5893
- if(bZoomin && !bInstance) {
5894
- ic.transformCls.zoominSelection();
5895
- }
5902
+ //if(bZoomin && !bInstance) {
5903
+ // ic.transformCls.zoominSelection();
5904
+ //}
5896
5905
  }
5897
5906
  }
5898
5907
 
@@ -7649,7 +7658,6 @@ class Strand {
7649
7658
  }
7650
7659
 
7651
7660
  currentChain = atom.chain;
7652
- atom.resi;
7653
7661
  ss = atom.ss;
7654
7662
  ssend = atom.ssend;
7655
7663
  prevAtomid = atom.serial;
@@ -12036,7 +12044,6 @@ class HlObjects {
12036
12044
 
12037
12045
  //Show the highlight for the selected atoms: hAtoms.
12038
12046
  addHlObjects(color, bRender, atomsHash) { let ic = this.icn3d, me = ic.icn3dui;
12039
- if(color === undefined) color = ic.hColor;
12040
12047
  //if(atomsHash === undefined) atomsHash = ic.hAtoms;
12041
12048
  let atomsHashDisplay = (atomsHash) ? me.hashUtilsCls.intHash(atomsHash, ic.dAtoms) : me.hashUtilsCls.intHash(ic.hAtoms, ic.dAtoms);
12042
12049
 
@@ -13347,13 +13354,14 @@ class DefinedSets {
13347
13354
  dAtoms = me.hashUtilsCls.unionHash(dAtoms, ic.alnChains[alignChain]);
13348
13355
  }
13349
13356
 
13350
- let residuesHash = {};
13357
+ let residuesHash = {}, chains = {};
13351
13358
  for(let i in dAtoms) {
13352
13359
  let atom = ic.atoms[i];
13353
13360
 
13354
13361
  let chainid = atom.structure + '_' + atom.chain;
13355
13362
  let resid = chainid + '_' + atom.resi;
13356
13363
  residuesHash[resid] = 1;
13364
+ chains[chainid] = 1;
13357
13365
  }
13358
13366
 
13359
13367
  let commandname = 'protein_aligned';
@@ -15159,24 +15167,7 @@ class Saltbridge {
15159
15167
  || (atom.het && me.parasCls.cationsTrimArray.indexOf(atom.elem) !== -1)
15160
15168
  || (atom.het && atom.elem === "N" && atom.bonds.length == 1);
15161
15169
 
15162
- // For ligand, "O" in carboxy group may be negatively charged. => to be improved
15163
- let bLigNeg = undefined;
15164
- if(atom.het && atom.elem === "O" && atom.bonds.length == 1) {
15165
- let cAtom = ic.atoms[atom.bonds[0]];
15166
- for(let j = 0; j < cAtom.bonds.length; ++j) {
15167
- let serial = cAtom.bonds[j];
15168
- if(ic.atoms[serial].elem == "O" && serial != atom.serial) {
15169
- bLigNeg = true;
15170
- break;
15171
- }
15172
- }
15173
- }
15174
-
15175
- let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15176
- || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15177
- || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15178
- || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1)
15179
- || bLigNeg;
15170
+ let bAtomCondAnion = this.isAnion(atom);
15180
15171
 
15181
15172
  bAtomCondCation = (ic.bOpm) ? bAtomCondCation && atom.resn !== 'DUM' : bAtomCondCation;
15182
15173
  bAtomCondAnion = (ic.bOpm) ? bAtomCondAnion && atom.resn !== 'DUM' : bAtomCondAnion;
@@ -15207,10 +15198,7 @@ class Saltbridge {
15207
15198
  || ( atom.resn === 'ARG' && (atom.name === "NH1" || atom.name === "NH2"))
15208
15199
  || (atom.het && me.parasCls.cationsTrimArray.indexOf(atom.elem) !== -1);
15209
15200
 
15210
- let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15211
- || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15212
- || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15213
- || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1);
15201
+ let bAtomCondAnion = this.isAnion(atom);
15214
15202
 
15215
15203
  bAtomCondCation = (ic.bOpm) ? bAtomCondCation && atom.resn !== 'DUM' : bAtomCondCation;
15216
15204
  bAtomCondAnion = (ic.bOpm) ? bAtomCondAnion && atom.resn !== 'DUM' : bAtomCondAnion;
@@ -15321,6 +15309,35 @@ class Saltbridge {
15321
15309
  return hbondsAtoms;
15322
15310
  }
15323
15311
 
15312
+ isAnion(atom) { let ic = this.icn3d, me = ic.icn3dui;
15313
+ // For ligand, "O" in carboxy group may be negatively charged. => to be improved
15314
+ let bLigNeg = undefined;
15315
+ if(atom.het && atom.elem === "O" && atom.bonds.length == 1) {
15316
+ let cAtom = ic.atoms[atom.bonds[0]];
15317
+ for(let j = 0; j < cAtom.bonds.length; ++j) {
15318
+ let serial = cAtom.bonds[j];
15319
+ if(ic.atoms[serial].elem == "O" && serial != atom.serial) {
15320
+ bLigNeg = true;
15321
+ break;
15322
+ }
15323
+ }
15324
+ }
15325
+
15326
+ // "O" in phosphae or sulfate group is neagatively charged
15327
+ if(atom.elem === "O" && atom.bonds.length == 1) {
15328
+ let pAtom = ic.atoms[atom.bonds[0]];
15329
+ if(pAtom.elem == "P" || pAtom.elem == "S") bLigNeg = true;
15330
+ }
15331
+
15332
+ let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15333
+ || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15334
+ || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15335
+ || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1)
15336
+ || bLigNeg;
15337
+
15338
+ return bAtomCondAnion;
15339
+ }
15340
+
15324
15341
  hideSaltbridge() { let ic = this.icn3d; ic.icn3dui;
15325
15342
  ic.opts["saltbridge"] = "no";
15326
15343
  if(ic.lines === undefined) ic.lines = { };
@@ -15468,7 +15485,7 @@ class GetGraph {
15468
15485
  return resStr;
15469
15486
  }
15470
15487
 
15471
- drawResNode(node, i, r, gap, margin, y, setName, bVertical, bContactMap) { let ic = this.icn3d; ic.icn3dui;
15488
+ drawResNode(node, i, r, gap, margin, y, setName, bVertical, bContactMap, bAfMap) { let ic = this.icn3d; ic.icn3dui;
15472
15489
  let x, resid = node.r.substr(4);
15473
15490
  if(bVertical) {
15474
15491
  x = margin - i *(r + gap);
@@ -15494,7 +15511,7 @@ class GetGraph {
15494
15511
  let strokewidth = '1';
15495
15512
  let textcolor = '#000';
15496
15513
  let fontsize = '6px'; // '6';
15497
- let html = "<g class='icn3d-node' resid='" + resid + "' >";
15514
+ let html = (bAfMap) ? "<g>" : "<g class='icn3d-node' resid='" + resid + "' >";
15498
15515
  html += "<title>" + node.id + "</title>";
15499
15516
  if(bVertical) {
15500
15517
  html += "<circle cx='" + y + "' cy='" + x + "' r='" + r + "' fill='" + color + "' stroke-width='" + strokewidth + "' stroke='" + strokecolor + "' resid='" + resid + "' />";
@@ -15507,18 +15524,27 @@ class GetGraph {
15507
15524
  html += "</g>";
15508
15525
  return html;
15509
15526
  }
15510
- getNodeTopBottom(nameHash, name2node, bReverseNode, bCommon, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15527
+ getNodeTopBottom(nameHash, name2node, bReverseNode, bCommonDiff, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15511
15528
  let thisClass = this;
15512
15529
  let nodeArray1 = [], nodeArray2 = [], name2nodeCommon = {};
15530
+
15531
+ let separatorCommon = "=>", separatorDiff = "==>", postCommon = "-", postDiff = "--";
15513
15532
  for(let name in nameHash) {
15514
15533
  let node = name2node[name];
15515
15534
  if(!node) continue;
15516
15535
 
15517
- if(bCommon) {
15536
+ if(bCommonDiff == 1 || bCommonDiff == 2) {
15518
15537
  node = me.hashUtilsCls.cloneHash(node);
15519
15538
 
15520
- let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : '-';
15521
- node.id += ">" + mapping;
15539
+ if(bCommonDiff == 1) {
15540
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : postCommon;
15541
+ node.id += separatorCommon + mapping;
15542
+ }
15543
+ else {
15544
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : postDiff;
15545
+ node.id += separatorDiff + mapping;
15546
+ }
15547
+
15522
15548
  name2nodeCommon[node.id] = node;
15523
15549
  }
15524
15550
 
@@ -15872,6 +15898,7 @@ class LineGraph {
15872
15898
  // Original node: {id : "Q24.A.2AJF", r : "1_1_2AJF_A_24", s: "a", ...}
15873
15899
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
15874
15900
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
15901
+ let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
15875
15902
  let linkedNodeCnt = {};
15876
15903
 
15877
15904
  for(let i = 0, il = structureArray.length; i < il; ++i) {
@@ -15885,6 +15912,11 @@ class LineGraph {
15885
15912
  linkArraySplitCommon[i] = [];
15886
15913
  nameHashSplitCommon[i] = {};
15887
15914
 
15915
+ nodeArray1SplitDiff[i] = [];
15916
+ nodeArray2SplitDiff[i] = [];
15917
+ linkArraySplitDiff[i] = [];
15918
+ nameHashSplitDiff[i] = {};
15919
+
15888
15920
  struc2index[structureArray[i]] = i;
15889
15921
  }
15890
15922
 
@@ -15931,6 +15963,8 @@ class LineGraph {
15931
15963
  }
15932
15964
 
15933
15965
  // set linkArraySplitCommon and nameHashSplitCommon
15966
+ // set linkArraySplitDiff and nameHashSplitDiff
15967
+ let separatorCommon = "=>", separatorDiff = "==>", postCommon = "-", postDiff = "--";
15934
15968
  for(let i = 0, il = linkArray.length; i < il; ++i) {
15935
15969
  let link = linkArray[i];
15936
15970
  let nodeA = name2node[link.source];
@@ -15960,33 +15994,53 @@ class LineGraph {
15960
15994
 
15961
15995
  let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15962
15996
 
15963
- if(linkedNodeCnt[mappingid] == structureArray.length) {
15964
- let linkCommon = me.hashUtilsCls.cloneHash(link);
15965
- linkCommon.source += '>' + ic.chainsMapping[chainid1][resid1];
15966
- linkCommon.target += '>' + ic.chainsMapping[chainid2][resid2];
15997
+ let linkCommon = me.hashUtilsCls.cloneHash(link);
15998
+ linkCommon.source += (ic.chainsMapping[chainid1][resid1]) ? separatorCommon + ic.chainsMapping[chainid1][resid1] : separatorCommon + postCommon;
15999
+ linkCommon.target += (ic.chainsMapping[chainid2][resid2]) ? separatorCommon + ic.chainsMapping[chainid2][resid2] : separatorCommon + postCommon;
15967
16000
 
16001
+ let linkDiff = me.hashUtilsCls.cloneHash(link);
16002
+ linkDiff.source += (ic.chainsMapping[chainid1][resid1]) ? separatorDiff + ic.chainsMapping[chainid1][resid1] : separatorDiff + postDiff;
16003
+ linkDiff.target += (ic.chainsMapping[chainid2][resid2]) ? separatorDiff + ic.chainsMapping[chainid2][resid2] : separatorDiff + postDiff;
16004
+
16005
+ if(linkedNodeCnt[mappingid] == structureArray.length) {
15968
16006
  linkArraySplitCommon[index].push(linkCommon);
15969
16007
  }
16008
+ else {
16009
+ linkArraySplitDiff[index].push(linkDiff);
16010
+ }
15970
16011
 
16012
+ // use the original node names and thus use the original link
15971
16013
  nameHashSplitCommon[index][link.source] = ic.chainsMapping[chainid1][resid1];
15972
16014
  nameHashSplitCommon[index][link.target] = ic.chainsMapping[chainid2][resid2];
16015
+
16016
+ nameHashSplitDiff[index][link.source] = ic.chainsMapping[chainid1][resid1];
16017
+ nameHashSplitDiff[index][link.target] = ic.chainsMapping[chainid2][resid2];
15973
16018
  }
15974
16019
  }
15975
16020
  }
15976
16021
 
15977
16022
  let len1Split = [], len2Split = [], maxWidth = 0;
15978
16023
  let strucArray = [];
16024
+ let bCommonDiff = 1;
15979
16025
  for(let i = 0, il = structureArray.length; i < il; ++i) {
15980
16026
  let nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node);
15981
16027
  nodeArray1Split[i] = nodeArraysTmp.nodeArray1;
15982
16028
  nodeArray2Split[i] = nodeArraysTmp.nodeArray2;
15983
16029
 
15984
- let bCommon = true;
15985
- nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommon, nameHashSplitCommon[i]);
16030
+ // common interactions
16031
+ bCommonDiff = 1;
16032
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommonDiff, nameHashSplitCommon[i]);
15986
16033
  nodeArray1SplitCommon[i] = nodeArraysTmp.nodeArray1;
15987
16034
  nodeArray2SplitCommon[i] = nodeArraysTmp.nodeArray2;
15988
16035
  name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
15989
16036
 
16037
+ // different interactions
16038
+ bCommonDiff = 2;
16039
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommonDiff, nameHashSplitDiff[i]);
16040
+ nodeArray1SplitDiff[i] = nodeArraysTmp.nodeArray1;
16041
+ nodeArray2SplitDiff[i] = nodeArraysTmp.nodeArray2;
16042
+ name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
16043
+
15990
16044
  len1Split[i] = nodeArray1Split[i].length;
15991
16045
  len2Split[i] = nodeArray2Split[i].length;
15992
16046
 
@@ -16010,66 +16064,51 @@ class LineGraph {
16010
16064
  //width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16011
16065
  heightAll =(me.utilsCls.sumArray(len1Split) + 2*strucArray.length) *(r + gap) + 4 * marginY
16012
16066
  + 2 * legendWidth + textHeight*strucArray.length;
16013
- // show common interaction as well
16014
- heightAll *= 2;
16067
+ // show common and diff interaction as well
16068
+ heightAll *= 3;
16015
16069
 
16016
16070
  width = (maxWidth + 2) * (r + gap) + 2 * marginX + legendWidth;
16017
16071
 
16018
16072
  } else {
16019
16073
  height = 110 + textHeight;
16020
16074
  heightAll = height * strucArray.length;
16021
- // show common interaction as well
16022
- heightAll *= 2;
16075
+ // show common and diff interaction as well
16076
+ heightAll *= 3;
16023
16077
 
16024
16078
  width = (maxWidth + 2) * (r + gap) + 2 * marginX;
16025
16079
  }
16026
- let id, graphWidth;
16080
+ let id;
16027
16081
  if(bScatterplot) {
16028
16082
  ic.scatterplotWidth = 2 * width;
16029
- graphWidth = ic.scatterplotWidth;
16030
16083
  id = me.scatterplotid;
16031
16084
  } else {
16032
16085
  ic.linegraphWidth = 2 * width;
16033
- graphWidth = ic.linegraphWidth;
16034
16086
  id = me.linegraphid;
16035
16087
  }
16036
16088
  html =(strucArray.length == 0) ? "No interactions found for each structure<br><br>" :
16037
- "2D integration graph for " + strucArray.length + " structure(s) <b>" + strucArray + "</b>. Common interactions are shown in the last " + strucArray.length + " graphs.<br><br>";
16038
- html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
16089
+ "2D integration graph for " + strucArray.length + " structure(s) <b>" + strucArray + "</b>. There are three sections: \"Interactions\", \"Common interactions\", and \"Different interactions\". Each section has " + strucArray.length + " graphs.<br><br>";
16090
+ html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "'>";
16039
16091
 
16040
- let heightFinal = 0;
16041
- for(let i = 0, il = structureArray.length; i < il; ++i) {
16042
- if(bScatterplot) {
16043
- //heightFinal -= 15;
16044
- html += this.drawScatterplot_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, undefined, "Interactions in structure " + strucArray[i], textHeight);
16045
- //heightFinal = 15;
16046
- height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16047
- } else {
16048
- html += this.drawLineGraph_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, "Interactions in structure " + strucArray[i], textHeight);
16049
- }
16050
- heightFinal += height;
16092
+ let result, heightFinal = 0;
16093
+
16094
+ bCommonDiff = 0; // 0: all interactions, 1: common interactions, 2: different interactions
16095
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1Split, nodeArray2Split, linkArraySplit, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16051
16096
 
16052
- if(i > 0) ic.lineGraphStr += ', \n';
16053
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i, nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i]);
16054
- }
16097
+ heightFinal = result.heightFinal;
16098
+ html += result.html;
16055
16099
 
16056
- // draw common interaction
16057
- for(let i = 0, il = structureArray.length; i < il; ++i) {
16058
- if(bScatterplot) {
16059
- //heightFinal -= 15;
16060
- html += this.drawScatterplot_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, undefined, "Common interactions in structure " + strucArray[i], textHeight);
16061
- //heightFinal = 15;
16062
- height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16063
- } else {
16064
- html += this.drawLineGraph_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, "Common interactions in structure " + strucArray[i], textHeight);
16065
- }
16066
- heightFinal += height;
16100
+ bCommonDiff = 1;
16101
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1SplitCommon, nodeArray2SplitCommon, linkArraySplitCommon, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16067
16102
 
16068
- //if(i > 0) ic.lineGraphStr += ', \n';
16069
- ic.lineGraphStr += ', \n';
16070
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i + '_common', nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i]);
16071
- }
16103
+ heightFinal = result.heightFinal;
16104
+ html += result.html;
16072
16105
 
16106
+ bCommonDiff = 2;
16107
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1SplitDiff, nodeArray2SplitDiff, linkArraySplitDiff, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16108
+
16109
+ heightFinal = result.heightFinal;
16110
+ html += result.html;
16111
+
16073
16112
  html += "</svg>";
16074
16113
  } else {
16075
16114
  if(!bScatterplot) {
@@ -16127,6 +16166,45 @@ class LineGraph {
16127
16166
  return html;
16128
16167
  }
16129
16168
 
16169
+ drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1, nodeArray2, linkArray, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY) { let ic = this.icn3d; ic.icn3dui;
16170
+ let html = "";
16171
+
16172
+ // draw common interaction
16173
+ let label, postfix;
16174
+ if(bCommonDiff == 0) {
16175
+ label = "Interactions in structure ";
16176
+ postfix = "";
16177
+ }
16178
+ else if(bCommonDiff == 1) {
16179
+ label = "Common interactions in structure ";
16180
+ postfix = "_common";
16181
+ }
16182
+ else if(bCommonDiff == 2) {
16183
+ label = "Different interactions in structure ";
16184
+ postfix = "_diff";
16185
+ }
16186
+
16187
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
16188
+ if(bScatterplot) {
16189
+ html += this.drawScatterplot_base(nodeArray1[i], nodeArray2[i], linkArray[i], name2node, heightFinal, undefined, label + structureArray[i], textHeight);
16190
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16191
+ } else {
16192
+ html += this.drawLineGraph_base(nodeArray1[i], nodeArray2[i], linkArray[i], name2node, heightFinal, label + structureArray[i], textHeight);
16193
+ }
16194
+ heightFinal += height;
16195
+
16196
+ if(bCommonDiff) { // very beginning
16197
+ if(i > 0) ic.lineGraphStr += ', \n';
16198
+ }
16199
+ else {
16200
+ ic.lineGraphStr += ', \n';
16201
+ }
16202
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(structureArray[i], i + postfix, nodeArray1[i], nodeArray2[i], linkArray[i]);
16203
+ }
16204
+
16205
+ return {"heightFinal": heightFinal, "html": html};
16206
+ }
16207
+
16130
16208
  getIdArrayFromNode(node) { let ic = this.icn3d, me = ic.icn3dui;
16131
16209
  let idArray = []; // 1_1_1KQ2_A_1
16132
16210
  idArray.push('');
@@ -16157,8 +16235,10 @@ class LineGraph {
16157
16235
  }
16158
16236
 
16159
16237
  // draw label
16160
- height += textHeight;
16161
- html += "<text x='" + margin1 + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16238
+ if(label) {
16239
+ height += textHeight;
16240
+ html += "<text x='" + margin1 + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16241
+ }
16162
16242
 
16163
16243
  let h1 = 30 + height,
16164
16244
  h2 = 80 + height;
@@ -16215,7 +16295,7 @@ class LineGraph {
16215
16295
  return html;
16216
16296
  }
16217
16297
 
16218
- drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight) { let ic = this.icn3d; ic.icn3dui;
16298
+ drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight, bAfMap) { let ic = this.icn3d; ic.icn3dui;
16219
16299
  let html = '';
16220
16300
  let len1 = nodeArray1.length,
16221
16301
  len2 = nodeArray2.length;
@@ -16228,10 +16308,11 @@ class LineGraph {
16228
16308
  let heightTotal =(len1 + 1) *(r + gap) + legendWidth + 2 * marginY;
16229
16309
 
16230
16310
  // draw label
16231
- height += textHeight;
16311
+ if(label) {
16312
+ height += textHeight;
16313
+ html += "<text x='" + marginX + "' y='" + (height + 15).toString() + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16314
+ }
16232
16315
 
16233
- html += "<text x='" + marginX + "' y='" + (height + 15).toString() + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16234
-
16235
16316
  let margin1 = height + heightTotal -(legendWidth + marginY +(r + gap)); // y-axis
16236
16317
  let margin2 = legendWidth + marginX +(r + gap); // x-axis
16237
16318
 
@@ -16240,12 +16321,12 @@ class LineGraph {
16240
16321
  node2posSet2 = {};
16241
16322
  let x = legendWidth + marginX;
16242
16323
  for(let i = 0; i < len1; ++i) {
16243
- nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true);
16324
+ nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true, undefined, bAfMap);
16244
16325
  node2posSet1[nodeArray1[i].id] = { x: x, y: margin1 - i *(r + gap) };
16245
16326
  }
16246
16327
  let y = height + heightTotal -(legendWidth + marginY);
16247
16328
  for(let i = 0; i < len2; ++i) {
16248
- nodeHtml += ic.getGraphCls.drawResNode(nodeArray2[i], i, r, gap, margin2, y, 'b', false, bContactMap);
16329
+ nodeHtml += ic.getGraphCls.drawResNode(nodeArray2[i], i, r, gap, margin2, y, 'b', false, bContactMap, bAfMap);
16249
16330
  node2posSet2[nodeArray2[i].id] = { x: margin2 + i *(r + gap), y: y };
16250
16331
  }
16251
16332
  for(let i = 0, il = linkArray.length; i < il; ++i) {
@@ -16255,10 +16336,10 @@ class LineGraph {
16255
16336
 
16256
16337
  if(!node1 || !node2) continue;
16257
16338
 
16258
- html += this.drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap);
16339
+ html += this.drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap);
16259
16340
 
16260
- if(bContactMap) { // draw symmetric contact map
16261
- html += this.drawOnePairNode(link, node2, node1, node2posSet1, node2posSet2, bContactMap);
16341
+ if(bContactMap && !bAfMap) { // draw symmetric contact map, bAfmap just need to draw once
16342
+ html += this.drawOnePairNode(link, node2, node1, node2posSet1, node2posSet2, bContactMap, bAfMap);
16262
16343
  }
16263
16344
  }
16264
16345
  // show nodes later
@@ -16266,7 +16347,7 @@ class LineGraph {
16266
16347
  return html;
16267
16348
  }
16268
16349
 
16269
- drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap) { let ic = this.icn3d, me = ic.icn3dui;
16350
+ drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap) { let ic = this.icn3d, me = ic.icn3dui;
16270
16351
  let html = '';
16271
16352
 
16272
16353
  let factor = 1;
@@ -16296,21 +16377,31 @@ class LineGraph {
16296
16377
  strokecolor = "#" + me.htmlCls.contactColor;
16297
16378
  }
16298
16379
 
16380
+ if(bContactMap) strokecolor = "#" + link.c;
16381
+
16299
16382
  let linestrokewidth;
16300
16383
  if(link.v == me.htmlCls.contactValue) {
16301
16384
  linestrokewidth = 1;
16302
16385
  } else {
16303
16386
  linestrokewidth = 2;
16304
16387
  }
16305
- html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
16306
- html += "<title>Interaction of residue " + node1.id + " with residue " + node2.id + "</title>";
16307
- if(bContactMap) {
16308
- html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16388
+
16389
+ if(bAfMap && ic.hex2skip[link.c]) ;
16390
+ else if(bAfMap && ic.hex2id[link.c]) {
16391
+ let id = ic.hex2id[link.c];
16392
+ html += "<use href='#" + id + "' x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' />";
16309
16393
  }
16310
16394
  else {
16311
- html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' fill-opacity='0.6' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16395
+ html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
16396
+ html += "<title>Interaction of residue " + node1.id + " with residue " + node2.id + "</title>";
16397
+ if(bContactMap) {
16398
+ html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16399
+ }
16400
+ else {
16401
+ html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' fill-opacity='0.6' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16402
+ }
16403
+ html += "</g>";
16312
16404
  }
16313
- html += "</g>";
16314
16405
 
16315
16406
  return html;
16316
16407
  }
@@ -20902,6 +20993,7 @@ class LoadAtomData {
20902
20993
  let serial = serialBase;
20903
20994
 
20904
20995
  let serial2structure = {}; // for "align" only
20996
+ let mmdbid2pdbid = {}; // for "align" only
20905
20997
 
20906
20998
  if(alignType === undefined || alignType === 'target') {
20907
20999
  ic.pmid = data.pubmedId;
@@ -20930,10 +21022,11 @@ class LoadAtomData {
20930
21022
  }
20931
21023
 
20932
21024
  let pdbidTmp = structure.pdbId;
20933
- structure.mmdbId;
21025
+ let mmdbidTmp = structure.mmdbId;
20934
21026
 
20935
21027
  for(let j = structure.serialInterval[0], jl = structure.serialInterval[1]; j <= jl; ++j) {
20936
21028
  serial2structure[j] = pdbidTmp.toString();
21029
+ mmdbid2pdbid[mmdbidTmp] = pdbidTmp;
20937
21030
  }
20938
21031
 
20939
21032
  for(let j = 0, jl = structure.molecules.length; j < jl; ++j) {
@@ -23270,11 +23363,11 @@ class AlignParser {
23270
23363
  ic.alignmolid2color.push(tmpHash);
23271
23364
  }
23272
23365
 
23273
- //var url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[0];
23274
- //var url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[1];
23366
+ //var url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&atomonly=1&uid=" + ic.mmdbidArray[0];
23367
+ //var url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&atomonly=1&uid=" + ic.mmdbidArray[1];
23275
23368
  // need the parameter moleculeInfor
23276
- let url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[0];
23277
- let url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[1];
23369
+ let url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&uid=" + ic.mmdbidArray[0];
23370
+ let url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&uid=" + ic.mmdbidArray[1];
23278
23371
 
23279
23372
  let d3 = $.ajax({
23280
23373
  url: url3,
@@ -23733,7 +23826,7 @@ class MmdbParser {
23733
23826
  }
23734
23827
 
23735
23828
  let molid2rescount = data.moleculeInfor;
23736
- let molid2chain = {};
23829
+ let molid2color = {}, chain2molid = {}, molid2chain = {};
23737
23830
  let chainNameHash = {};
23738
23831
  for(let i in molid2rescount) {
23739
23832
  if(Object.keys(molid2rescount[i]).length === 0) continue;
@@ -23749,6 +23842,9 @@ class MmdbParser {
23749
23842
 
23750
23843
  let chainNameFinal =(chainNameHash[chainName] === 1) ? chainName : chainName + chainNameHash[chainName].toString();
23751
23844
  let chain = id + '_' + chainNameFinal;
23845
+
23846
+ molid2color[i] = color;
23847
+ chain2molid[chain] = i;
23752
23848
  molid2chain[i] = chain;
23753
23849
 
23754
23850
  ic.chainsColor[chain] =(type !== undefined) ? me.parasCls.thr(me.htmlCls.GREY8) : me.parasCls.thr(color);
@@ -23809,14 +23905,14 @@ class MmdbParser {
23809
23905
  // b: b-factor, s: water, ft: pdbsite
23810
23906
  //&ft=1
23811
23907
  if(bGi) {
23812
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&gi=" + mmdbid;
23908
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&simple=1&gi=" + mmdbid;
23813
23909
  }
23814
23910
  else {
23815
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&uid=" + mmdbid;
23816
- }
23911
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&simple=1&uid=" + mmdbid;
23912
+ }
23817
23913
 
23818
- // use asymmetric unit for BLAST search, e.g., https://www.ncbi.nlm.nih.gov/Structure/icn3d/full.html?from=blast&blast_rep_id=5XZC_B&query_id=1TUP_A&command=view+annotations;set+annotation+cdd;set+annotation+site;set+view+detailed+view;select+chain+5XZC_B;show+selection&log$=align&blast_rank=1&RID=EPUCYNVV014&buidx=0
23819
- if(me.cfg.blast_rep_id !== undefined) url += '&buidx=0';
23914
+ // use asymmetric unit for BLAST search, e.g., https://www.ncbi.nlm.nih.gov/Structure/icn3d/full.html?from=blast&blast_rep_id=5XZC_B&query_id=1TUP_A&command=view+annotations;set+annotation+cdd;set+annotation+site;set+view+detailed+view;select+chain+5XZC_B;show+selection&log$=align&blast_rank=1&RID=EPUCYNVV014&bu=0
23915
+ if(me.cfg.blast_rep_id !== undefined) url += '&bu=0';
23820
23916
 
23821
23917
  ic.bCid = undefined;
23822
23918
 
@@ -23911,13 +24007,13 @@ class MmdbParser {
23911
24007
  }
23912
24008
 
23913
24009
  downloadMmdbPart2(type) { let ic = this.icn3d, me = ic.icn3dui;
23914
- if(ic.bAssemblyUseAsu) { // set up symmetric matrices
24010
+ if(ic.bAssemblyUseAsu) {
23915
24011
  $("#" + ic.pre + "assemblyWrapper").show();
23916
- ic.bAssembly = true;
24012
+ //ic.bAssembly = true;
23917
24013
  }
23918
24014
  else {
23919
24015
  $("#" + ic.pre + "assemblyWrapper").hide();
23920
- ic.bAssembly = false;
24016
+ //ic.bAssembly = false;
23921
24017
  }
23922
24018
 
23923
24019
  if(ic.emd !== undefined) {
@@ -24072,7 +24168,7 @@ class MmdbParser {
24072
24168
  } // for each domainArray
24073
24169
  } // for each molid
24074
24170
 
24075
- // "asuAtomCount" is defined when: 1) atom count is over the threshold 2) buidx=1 3) asu atom count is smaller than biological unit atom count
24171
+ // "asuAtomCount" is defined when: 1) atom count is over the threshold 2) bu=1 3) asu atom count is smaller than biological unit atom count
24076
24172
  ic.bAssemblyUseAsu =(data.asuAtomCount !== undefined) ? true : false;
24077
24173
  if(type !== undefined) {
24078
24174
  ic.bAssemblyUseAsu = false;
@@ -24698,7 +24794,7 @@ class ChainalignParser {
24698
24794
  let pos1 = alignArray[0].indexOf('_');
24699
24795
  ic.mmdbid_t = alignArray[0].substr(0, pos1).toUpperCase();
24700
24796
  ic.chain_t = alignArray[0].substr(pos1+1);
24701
- let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_t;
24797
+ let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&uid=" + ic.mmdbid_t;
24702
24798
  if(me.cfg.inpara !== undefined) url_t += me.cfg.inpara;
24703
24799
 
24704
24800
  let ajaxArray = [];
@@ -24724,7 +24820,7 @@ class ChainalignParser {
24724
24820
  let chainalignFinal = ic.mmdbid_q + "_" + ic.chain_q + "," + ic.mmdbid_t + "_" + ic.chain_t;
24725
24821
 
24726
24822
  let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?chainpairs=" + chainalignFinal;
24727
- let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_q;
24823
+ let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&bu=" + me.cfg.bu + "&uid=" + ic.mmdbid_q;
24728
24824
 
24729
24825
  if(me.cfg.inpara !== undefined) url_q += me.cfg.inpara;
24730
24826
 
@@ -26601,6 +26697,32 @@ class LoadScript {
26601
26697
 
26602
26698
  return;
26603
26699
  }
26700
+ else if(ic.commands[i].trim().indexOf('set half pae map') == 0) {
26701
+ let strArray = ic.commands[i].split("|||");
26702
+ let command = strArray[0].trim();
26703
+
26704
+ $.when(thisClass.applyCommandAfmap(command)).then(function() {
26705
+ //if(!me.cfg.notebook && dialog && dialog.hasClass("ui-dialog-content")) dialog.dialog( "close" );
26706
+
26707
+ //ic.drawCls.draw();
26708
+ thisClass.execCommandsBase(i + 1, end, steps);
26709
+ });
26710
+
26711
+ return;
26712
+ }
26713
+ else if(ic.commands[i].trim().indexOf('set full pae map') == 0) {
26714
+ let strArray = ic.commands[i].split("|||");
26715
+ let command = strArray[0].trim();
26716
+
26717
+ $.when(thisClass.applyCommandAfmap(command, true)).then(function() {
26718
+ //if(!me.cfg.notebook && dialog && dialog.hasClass("ui-dialog-content")) dialog.dialog( "close" );
26719
+
26720
+ //ic.drawCls.draw();
26721
+ thisClass.execCommandsBase(i + 1, end, steps);
26722
+ });
26723
+
26724
+ return;
26725
+ }
26604
26726
  else {
26605
26727
  ic.applyCommandCls.applyCommand(ic.commands[i]);
26606
26728
  }
@@ -26795,13 +26917,13 @@ class LoadScript {
26795
26917
  }
26796
26918
  else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
26797
26919
  me.cfg.mmdbid = id;
26798
- me.cfg.buidx = 1;
26920
+ me.cfg.bu = 1;
26799
26921
 
26800
26922
  ic.mmdbParserCls.downloadMmdb(id);
26801
26923
  }
26802
26924
  else if(command.indexOf('load mmdb0') !== -1) {
26803
26925
  me.cfg.mmdbid = id;
26804
- me.cfg.buidx = 0;
26926
+ me.cfg.bu = 0;
26805
26927
 
26806
26928
  ic.mmdbParserCls.downloadMmdb(id);
26807
26929
  }
@@ -26934,6 +27056,23 @@ class LoadScript {
26934
27056
  return ic.deferredRealign.promise();
26935
27057
  }
26936
27058
 
27059
+ applyCommandAfmapBase(command, bFull) { let ic = this.icn3d; ic.icn3dui;
27060
+ let afid = command.substr(command.lastIndexOf(' ') + 1);
27061
+
27062
+ ic.contactMapCls.afErrorMap(afid, bFull);
27063
+ }
27064
+
27065
+ applyCommandAfmap(command, bFull) { let ic = this.icn3d; ic.icn3dui;
27066
+ let thisClass = this;
27067
+
27068
+ // chain functions together
27069
+ ic.deferredAfmap = new $.Deferred(function() {
27070
+ thisClass.applyCommandAfmapBase(command, bFull);
27071
+ }); // end of me.deferred = $.Deferred(function() {
27072
+
27073
+ return ic.deferredAfmap.promise();
27074
+ }
27075
+
26937
27076
  applyCommandGraphinteractionBase(command) { let ic = this.icn3d; ic.icn3dui;
26938
27077
  let paraArray = command.split(' | ');
26939
27078
  if(paraArray.length >= 3) {
@@ -28208,14 +28347,14 @@ class AddTrack {
28208
28347
 
28209
28348
  let strand, itemRgb;
28210
28349
 
28211
- if(fieldArray.length > 4) fieldArray[4];
28350
+ if(fieldArray.length > 4) ;
28212
28351
  if(fieldArray.length > 5) strand = fieldArray[5]; // ., +, or -
28213
- if(fieldArray.length > 6) fieldArray[6];
28214
- if(fieldArray.length > 7) fieldArray[7];
28352
+ if(fieldArray.length > 6) ;
28353
+ if(fieldArray.length > 7) ;
28215
28354
  if(fieldArray.length > 8) itemRgb = fieldArray[8];
28216
- if(fieldArray.length > 9) fieldArray[9];
28217
- if(fieldArray.length > 10) fieldArray[10];
28218
- if(fieldArray.length > 11) fieldArray[11];
28355
+ if(fieldArray.length > 9) ;
28356
+ if(fieldArray.length > 10) ;
28357
+ if(fieldArray.length > 11) ;
28219
28358
 
28220
28359
  let title = trackName;
28221
28360
 
@@ -30929,6 +31068,14 @@ class ApplyCommand {
30929
31068
 
30930
31069
  $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
30931
31070
  }
31071
+ else if(command.indexOf('alignerrormap scale') == 0) {
31072
+ let pos = command.lastIndexOf(' ');
31073
+ let scale = command.substr(pos + 1);
31074
+
31075
+ $("#" + me.alignerrormapid + "_scale").val(scale);
31076
+
31077
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
31078
+ }
30932
31079
  else if(command.indexOf('graph force') == 0) {
30933
31080
  let pos = command.lastIndexOf(' ');
30934
31081
  me.htmlCls.force = parseInt(command.substr(pos + 1));
@@ -33945,7 +34092,7 @@ class MmcifParser {
33945
34092
  }
33946
34093
  }
33947
34094
 
33948
- loadMmcifSymmetry(assembly) { let ic = this.icn3d; ic.icn3dui;
34095
+ loadMmcifSymmetry(assembly) { let ic = this.icn3d, me = ic.icn3dui;
33949
34096
  // load assembly info
33950
34097
  //var assembly = data.assembly;
33951
34098
  //var pmatrix = data.pmatrix;
@@ -33958,6 +34105,11 @@ class MmcifParser {
33958
34105
  }
33959
34106
 
33960
34107
  ic.asuCnt = ic.biomtMatrices.length;
34108
+
34109
+ // show bioassembly
34110
+ if(me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.asuCnt > ic.maxatomcnt) {
34111
+ ic.bAssembly = true;
34112
+ }
33961
34113
  }
33962
34114
 
33963
34115
  loadMmcifOpmDataPart2(data, pdbid) { let ic = this.icn3d, me = ic.icn3dui;
@@ -38779,7 +38931,7 @@ class Selection {
38779
38931
  }
38780
38932
 
38781
38933
  toggleMembrane(bShowMembrane) {var ic = this.icn3d, me = ic.icn3dui;
38782
- let structureArray = Object.keys(ic.structures);
38934
+ let structureArray = (ic.structures) ? Object.keys(ic.structures) : [];
38783
38935
 
38784
38936
  for(let i = 0, il = structureArray.length; i < il; ++i) {
38785
38937
  let structure = structureArray[i];
@@ -39863,7 +40015,6 @@ class ApplyDisplay {
39863
40015
 
39864
40016
  //Apply style and label options to a certain set of atoms.
39865
40017
  applyDisplayOptions(options, atoms, bHighlight) { let ic = this.icn3d, me = ic.icn3dui;
39866
- if(options === undefined) options = ic.opts;
39867
40018
 
39868
40019
  // get parameters from cookies
39869
40020
  if(!me.bNode && me.htmlCls.setHtmlCls.getCookie('lineRadius') != '') {
@@ -42365,7 +42516,12 @@ class Draw {
42365
42516
  ic.setColorCls.applyPrevColor();
42366
42517
 
42367
42518
  if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
42368
- if(ic.bAssembly && Object.keys(ic.structures).length == 1) {
42519
+ // show bioassembly in two cases
42520
+ // 1. asymmetric unit: me.cfg.bu == 0
42521
+ // 2. biological unit with less than ic.maxatomcnt atom:
42522
+ // me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.biomtMatrices.length < ic.maxatomcnt
42523
+ if(ic.bAssembly && Object.keys(ic.structures).length == 1 && (me.cfg.bu == 0
42524
+ || (me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.biomtMatrices.length > ic.maxatomcnt)) ) {
42369
42525
  ic.instancingCls.drawSymmetryMates();
42370
42526
  }
42371
42527
  else {
@@ -42662,10 +42818,10 @@ class Transform {
42662
42818
 
42663
42819
  if(ic.bRender) ic.drawCls.render();
42664
42820
  }
42665
-
42821
+ /*
42666
42822
  //Zoom in the structure at certain ratio, e.g., 0.1 is a reasonable value.
42667
42823
  zoomIn(normalizedFactor) { let ic = this.icn3d, me = ic.icn3dui;
42668
- let para = {};
42824
+ let para = {}
42669
42825
  para._zoomFactor = 1 - normalizedFactor;
42670
42826
  para.update = true;
42671
42827
  if(ic.bControlGl && !me.bNode) {
@@ -42675,12 +42831,14 @@ class Transform {
42675
42831
  ic.controls.update(para);
42676
42832
  }
42677
42833
 
42678
- if(ic.bRender) ic.drawCls.render();
42834
+ if(ic.bRender) {
42835
+ ic.drawCls.render();
42836
+ }
42679
42837
  }
42680
42838
 
42681
42839
  //Zoom out the structure at certain ratio, e.g., 0.1 is a reasonable value.
42682
42840
  zoomOut(normalizedFactor) { let ic = this.icn3d, me = ic.icn3dui;
42683
- let para = {};
42841
+ let para = {}
42684
42842
  para._zoomFactor = 1 + normalizedFactor;
42685
42843
  para.update = true;
42686
42844
 
@@ -42690,8 +42848,11 @@ class Transform {
42690
42848
  else {
42691
42849
  ic.controls.update(para);
42692
42850
  }
42693
- if(ic.bRender) ic.drawCls.render();
42851
+ if(ic.bRender) {
42852
+ ic.drawCls.render();
42853
+ }
42694
42854
  }
42855
+ */
42695
42856
 
42696
42857
  //Center on the selected atoms and zoom in.
42697
42858
  zoominSelection(atoms) { let ic = this.icn3d, me = ic.icn3dui;
@@ -42894,20 +43055,29 @@ class SaveFile {
42894
43055
  }
42895
43056
  }
42896
43057
 
42897
- saveSvg(id, filename) { let ic = this.icn3d; ic.icn3dui;
42898
- let svg = this.getSvgXml(id);
43058
+ saveSvg(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
43059
+ if(me.bNode) return '';
43060
+
43061
+ let width = $("#" + id).width();
43062
+ let height = $("#" + id).height();
43063
+
43064
+ if(bContactmap) height = width;
43065
+
43066
+ let svgXml = this.getSvgXml(id, width, height, bContactmap);
42899
43067
 
42900
- let blob = new Blob([svg], {type: "image/svg+xml"});
43068
+ let blob = new Blob([svgXml], {type: "image/svg+xml"});
42901
43069
  saveAs(blob, filename);
42902
43070
  }
42903
43071
 
42904
- getSvgXml(id) { let ic = this.icn3d, me = ic.icn3dui;
43072
+ getSvgXml(id, width, height, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
42905
43073
  if(me.bNode) return '';
42906
43074
 
42907
43075
  // font is not good
42908
43076
  let svg_data = document.getElementById(id).innerHTML; //put id of your svg element here
42909
43077
 
42910
- let head = "<svg title=\"graph\" version=\"1.1\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
43078
+ let viewbox = (width && height) ? "<svg viewBox=\"0 0 " + width + " " + height + "\"" : "<svg";
43079
+ //let head = viewbox + " title=\"graph\" version=\"1.1\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
43080
+ let head = viewbox + " title=\"graph\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
42911
43081
 
42912
43082
  //if you have some additional styling like graph edges put them inside <style> tag
42913
43083
  let style = "<style>text {font-family: sans-serif; font-weight: bold; font-size: 18px;}</style>";
@@ -42917,9 +43087,14 @@ class SaveFile {
42917
43087
  return full_svg;
42918
43088
  }
42919
43089
 
42920
- savePng(id, filename, width, height) { let ic = this.icn3d, me = ic.icn3dui;
43090
+ savePng(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
42921
43091
  if(me.bNode) return '';
42922
43092
 
43093
+ let width = $("#" + id).width();
43094
+ let height = $("#" + id).height();
43095
+
43096
+ if(bContactmap) height = width;
43097
+
42923
43098
  // https://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-the-browser
42924
43099
  let svg = document.getElementById(id);
42925
43100
  let bbox = svg.getBBox();
@@ -42933,7 +43108,7 @@ class SaveFile {
42933
43108
  let ctx = canvas.getContext("2d");
42934
43109
  ctx.clearRect(0, 0, bbox.width, bbox.height);
42935
43110
 
42936
- let data = this.getSvgXml(id); //(new XMLSerializer()).serializeToString(copy); //ic.saveFileCls.getSvgXml();
43111
+ let data = this.getSvgXml(id, width, height, bContactmap); //(new XMLSerializer()).serializeToString(copy); //ic.saveFileCls.getSvgXml();
42937
43112
  let DOMURL = window.URL || window.webkitURL || window;
42938
43113
  let svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
42939
43114
 
@@ -43645,6 +43820,10 @@ class ClickMenu {
43645
43820
  me.myEventCls.onIds("#" + me.pre + "mn1_xyzfile", "click", function(e) { me.icn3d;
43646
43821
  me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ File');
43647
43822
  });
43823
+
43824
+ me.myEventCls.onIds("#" + me.pre + "mn1_afmapfile", "click", function(e) { me.icn3d;
43825
+ me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold PAE File');
43826
+ });
43648
43827
  // },
43649
43828
  // clkMn1_urlfile: function() {
43650
43829
  me.myEventCls.onIds("#" + me.pre + "mn1_urlfile", "click", function(e) { me.icn3d;
@@ -46018,6 +46197,8 @@ class SetMenu {
46018
46197
  html += me.htmlCls.setHtmlCls.getLink('mn1_mol2file', 'Mol2 File');
46019
46198
  html += me.htmlCls.setHtmlCls.getLink('mn1_sdffile', 'SDF File');
46020
46199
  html += me.htmlCls.setHtmlCls.getLink('mn1_xyzfile', 'XYZ File');
46200
+ html += me.htmlCls.setHtmlCls.getLink('mn1_afmapfile', 'AlphaFold PAE File');
46201
+
46021
46202
  if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46022
46203
  html += "<li>-</li>";
46023
46204
  html += me.htmlCls.setHtmlCls.getLink('mn1_pngimage', 'iCn3D PNG Image');
@@ -47125,14 +47306,19 @@ class SetMenu {
47125
47306
  }
47126
47307
 
47127
47308
  let bOnePdb = me.cfg.mmtfid !== undefined || me.cfg.pdbid !== undefined || me.cfg.opmid !== undefined || me.cfg.mmcifid !== undefined || me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined;
47128
- console.log("me.cfg.mmdbid: " + me.cfg.mmdbid + " bOnePdb: " + bOnePdb);
47129
47309
 
47130
47310
  if(bOnePdb) {
47131
47311
  html += "<li id='" + me.pre + "assemblyWrapper'><span>Assembly</span>";
47132
47312
  html += "<ul>";
47133
47313
 
47134
- html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly', true);
47135
- html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit');
47314
+ if(me.cfg.bu == 0) {
47315
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly');
47316
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit', true);
47317
+ }
47318
+ else {
47319
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly', true);
47320
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit');
47321
+ }
47136
47322
 
47137
47323
  html += "</ul>";
47138
47324
  html += "</li>";
@@ -47376,6 +47562,7 @@ class Dialog {
47376
47562
  let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
47377
47563
  let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
47378
47564
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
47565
+ let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
47379
47566
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
47380
47567
  let bAlignmentInit = $('#' + me.pre + 'dl_alignment').hasClass('ui-dialog-content'); // initialized
47381
47568
  let bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
@@ -47391,6 +47578,7 @@ class Dialog {
47391
47578
  if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
47392
47579
  if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
47393
47580
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
47581
+ if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
47394
47582
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
47395
47583
  if(bAlignmentInit) status.bAlignmentInit2 = $('#' + me.pre + 'dl_alignment').dialog( 'isOpen' );
47396
47584
  if(bTwoddgmInit) status.bTwoddgmInit2 = $('#' + me.pre + 'dl_2ddgm').dialog( 'isOpen' );
@@ -47435,13 +47623,14 @@ class Dialog {
47435
47623
  close: function(e) {
47436
47624
  let status = thisClass.getDialogStatus();
47437
47625
 
47438
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47439
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47440
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47441
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47442
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bScatterplot2 && !status.bContactmap2)
47443
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bContactmap2)
47444
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2)
47626
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47627
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47628
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47629
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47630
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47631
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bContactmap2 && !status.bAlignerrormap2)
47632
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bAlignerrormap2)
47633
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47445
47634
  ) {
47446
47635
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
47447
47636
  //ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH - twoddgmWidth, me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT, true);
@@ -47468,7 +47657,7 @@ class Dialog {
47468
47657
 
47469
47658
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
47470
47659
  }
47471
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap') {
47660
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
47472
47661
  //var bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
47473
47662
  //var bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
47474
47663
 
@@ -47491,6 +47680,10 @@ class Dialog {
47491
47680
  let width = ic.contactmapWidth * ratio;
47492
47681
  $("#" + me.contactmapid).attr("width", width);
47493
47682
  }
47683
+ else if(id == me.pre + 'dl_alignerrormap') {
47684
+ let width = ic.alignerrormapWidth * ratio;
47685
+ $("#" + me.alignerrormapid).attr("width", width);
47686
+ }
47494
47687
  }
47495
47688
  }
47496
47689
  });
@@ -47586,7 +47779,7 @@ class Dialog {
47586
47779
 
47587
47780
  let status = this.getDialogStatus();
47588
47781
 
47589
- if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
47782
+ if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
47590
47783
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
47591
47784
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
47592
47785
 
@@ -47622,13 +47815,14 @@ class Dialog {
47622
47815
  modal: false,
47623
47816
  position: position,
47624
47817
  close: function(e) {
47625
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47626
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47627
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47628
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47629
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47630
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2))
47631
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2))
47818
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47819
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47820
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47821
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47822
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47823
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47824
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bAlignerrormap2))
47825
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47632
47826
  ) {
47633
47827
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
47634
47828
  let canvasWidth = me.utilsCls.isMobile() ? me.htmlCls.WIDTH : me.htmlCls.WIDTH - twoddgmWidth;
@@ -47654,7 +47848,7 @@ class Dialog {
47654
47848
 
47655
47849
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
47656
47850
  }
47657
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap') {
47851
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
47658
47852
  //var bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
47659
47853
  //var bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
47660
47854
 
@@ -47677,6 +47871,10 @@ class Dialog {
47677
47871
  let width = ic.contactmapWidth * ratio;
47678
47872
  $("#" + me.contactmapid).attr("width", width);
47679
47873
  }
47874
+ else if(id == me.pre + 'dl_alignerrormap') {
47875
+ let width = ic.alignerrormapWidth * ratio;
47876
+ $("#" + me.alignerrormapid).attr("width", width);
47877
+ }
47680
47878
  }
47681
47879
  }
47682
47880
  });
@@ -47799,7 +47997,7 @@ class Dialog {
47799
47997
  let width = 400, height = 150;
47800
47998
  let twoddgmWidth = me.htmlCls.width2d + 20;
47801
47999
 
47802
- if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
48000
+ if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
47803
48001
  $( "#" + id ).show();
47804
48002
 
47805
48003
  height =(me.htmlCls.HEIGHT) * 0.5;
@@ -47837,6 +48035,11 @@ class Dialog {
47837
48035
 
47838
48036
  $("#" + me.contactmapid).attr("width", width);
47839
48037
  }
48038
+ else if(id == me.pre + 'dl_alignerrormap') {
48039
+ let width = ic.alignerrormapWidth * ratio;
48040
+
48041
+ $("#" + me.alignerrormapid).attr("width", width);
48042
+ }
47840
48043
  });
47841
48044
  }
47842
48045
  else {
@@ -47970,8 +48173,12 @@ class SetDialog {
47970
48173
  html += "Note: AlphaFold produces a per-residue confidence score (pLDDT) between 0 and 100:<br>";
47971
48174
  html += me.htmlCls.clickMenuCls.setAlphaFoldLegend() + "<br>";
47972
48175
 
47973
- html += "<a href='https://alphafold.ebi.ac.uk/' target='_blank'>AlphaFold Uniprot</a> ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "afid' value='A0A061AD48' size=10> ";
47974
- html += me.htmlCls.buttonStr + "reload_af'>Load</button>";
48176
+ let afid = (me.cfg.afid) ? me.cfg.afid : 'Q76EI6';
48177
+
48178
+ html += "<a href='https://alphafold.ebi.ac.uk/' target='_blank'>AlphaFold Uniprot</a> ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "afid' value='" + afid + "' size=10><br><br>";
48179
+ html += me.htmlCls.buttonStr + "reload_af'>Load Structure</button>"
48180
+ + me.htmlCls.buttonStr + "reload_afmap' style='margin-left:30px'>Load Half PAE Map</button>"
48181
+ + me.htmlCls.buttonStr + "reload_afmapfull' style='margin-left:30px'>Load Full PAE Map (slow)</button>";
47975
48182
  html += "</div>";
47976
48183
 
47977
48184
  html += me.htmlCls.divStr + "dl_opmid' class='" + dialogClass + "'>";
@@ -48067,6 +48274,13 @@ class SetDialog {
48067
48274
  html += "XYZ File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "xyzfile' size=8> ";
48068
48275
  html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
48069
48276
  html += "</div>";
48277
+
48278
+ html += me.htmlCls.divStr + "dl_afmapfile' class='" + dialogClass + "'>";
48279
+ html += "AlphaFold PAE File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "afmapfile' size=8> <br><br>";
48280
+ html += me.htmlCls.buttonStr + "reload_afmapfile'>Load Half PAE Map</button>"
48281
+ + me.htmlCls.buttonStr + "reload_afmapfilefull' style='margin-left:30px'>Load Full PAE Map (slow)</button>";
48282
+ html += "</div>";
48283
+
48070
48284
  html += me.htmlCls.divStr + "dl_urlfile' class='" + dialogClass + "'>";
48071
48285
  html += "File type: ";
48072
48286
  html += "<select id='" + me.pre + "filetype'>";
@@ -48090,9 +48304,16 @@ class SetDialog {
48090
48304
  html += me.htmlCls.buttonStr + "reload_mmcif'>Load</button>";
48091
48305
  html += "</div>";
48092
48306
 
48093
- html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "'>";
48307
+ html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "' style='max-width:500px'>";
48094
48308
  html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> <br><br>";
48095
- html += me.htmlCls.buttonStr + "reload_mmdb_asym'>Load Asymmetric Unit (All Chains)</button>" + me.htmlCls.buttonStr + "reload_mmdb' style='margin-left:30px'>Load Biological Unit</button><br/><br/>";
48309
+ html += me.htmlCls.buttonStr + "reload_mmdb_asym'>Load Asymmetric Unit (All Chains)</button>" + me.htmlCls.buttonStr + "reload_mmdb' style='margin-left:30px'>Load Biological Unit</button><br/><br/><br>";
48310
+ html += '<b>Note</b>: The "<b>biological unit</b>" is the <b>biochemically active form of a biomolecule</b>, <div style="width:20px; margin:6px 0 0 20px; display:inline-block;"><span id="'
48311
+ + me.pre + 'asu_bu_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="width:15px;" title="Expand"></span><span id="'
48312
+ + me.pre + 'asu_bu_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="display:none; width:15px;" title="Shrink"></span></div>';
48313
+
48314
+ html += me.htmlCls.divStr + "asu_bu' style='display:none;'>";
48315
+ html += 'which can range from a monomer (single protein molecule) to an oligomer of 100+ protein molecules.<br><br>The "<b>asymmetric unit</b>" is the raw 3D structure data resolved by X-ray crystallography, NMR, or Cryo-electron microscopy. The asymmetric unit is equivalent to the biological unit in approximately 60% of structure records. In the remaining 40% of the records, the asymmetric unit represents a portion of the biological unit that can be reconstructed using crystallographic symmetry, or it represents multiple copies of the biological unit.</div>';
48316
+
48096
48317
  html += "</div>";
48097
48318
 
48098
48319
  html += me.htmlCls.divStr + "dl_blast_rep_id' style='max-width:500px;' class='" + dialogClass + "'>";
@@ -48428,6 +48649,33 @@ class SetDialog {
48428
48649
 
48429
48650
  html += "</div>";
48430
48651
 
48652
+ html += me.htmlCls.divStr + "dl_alignerrormap' style='background-color:white' class='" + dialogClass + "'>";
48653
+
48654
+ //html += me.htmlCls.divNowrapStr + "Hold Ctrl key to select multiple nodes." + me.htmlCls.space3 + "</div>";
48655
+
48656
+ me.alignerrormapid = me.pre + 'alignerrormap';
48657
+ html += me.htmlCls.divNowrapStr + buttonStrTmp + me.alignerrormapid + '_svg">SVG</button>' + me.htmlCls.space2;
48658
+ html += buttonStrTmp + me.alignerrormapid + '_png">PNG (slow)</button>' + me.htmlCls.space2;
48659
+ html += buttonStrTmp + me.alignerrormapid + '_json">JSON</button>' + me.htmlCls.space4;
48660
+ html += '<b>Scale</b>: <select id="' + me.alignerrormapid + '_scale">';
48661
+
48662
+ //let optArray5 = ['0.01', '0.02', '0.04', '0.06', '0.08', '0.1', '0.2', '0.4', '0.6', '0.8', '1'];
48663
+ html += me.htmlCls.setHtmlCls.getOptionHtml(optArray5, 2);
48664
+
48665
+ html += "</select></div><br>";
48666
+
48667
+ //min: 004d00, max: FFFFFF
48668
+ let startColorStr = '#004d00';
48669
+ let endColorStr = '#FFFFFF';
48670
+ let rangeStr = startColorStr + ' 0%, ' + endColorStr + ' 100%';
48671
+
48672
+ html += "<div style='width:200px'><div style='height: 12px; border: 1px solid #000; background: linear-gradient(to right, " + rangeStr + ");'></div>";
48673
+ html += "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr><td width='15%'>0</td><td width='15%'>5</td><td width='15%'>10</td><td width='15%'>15</td><td width='15%'>20</td><td width='15%'>25</td><td>30</td></tr><tr><td colspan='7' align='center'>Expected position error (Angstroms)</td></tr></table></div><br>";
48674
+
48675
+ html += '<div id="' + me.pre + 'alignerrormapDiv"></div>';
48676
+
48677
+ html += "</div>";
48678
+
48431
48679
  html += me.htmlCls.divStr + "dl_elecmap2fofc' class='" + dialogClass + "'>";
48432
48680
  html += "<span style='white-space:nowrap;font-weight:bold;'>Contour at: <select id='" + me.pre + "sigma2fofc'>";
48433
48681
 
@@ -49162,6 +49410,25 @@ class Events {
49162
49410
  window.open(hostUrl + '?afid=' + $("#" + me.pre + "afid").val(), '_blank');
49163
49411
  });
49164
49412
 
49413
+ me.myEventCls.onIds("#" + me.pre + "reload_afmap", "click", function(e) { let ic = me.icn3d;
49414
+ e.preventDefault();
49415
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49416
+ let afid = me.cfg.afid ? me.cfg.afid : $("#" + me.pre + "afid").val();
49417
+
49418
+ me.htmlCls.clickMenuCls.setLogCmd("set half pae map " + afid, true);
49419
+
49420
+ ic.contactMapCls.afErrorMap(afid);
49421
+ });
49422
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfull", "click", function(e) { let ic = me.icn3d;
49423
+ e.preventDefault();
49424
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49425
+ let afid = me.cfg.afid ? me.cfg.afid : $("#" + me.pre + "afid").val();
49426
+
49427
+ me.htmlCls.clickMenuCls.setLogCmd("set full pae map " + afid, true);
49428
+
49429
+ ic.contactMapCls.afErrorMap(afid, true);
49430
+ });
49431
+
49165
49432
  me.myEventCls.onIds("#" + me.pre + "afid", "keyup", function(e) { me.icn3d;
49166
49433
  if (e.keyCode === 13) {
49167
49434
  e.preventDefault();
@@ -49195,23 +49462,23 @@ class Events {
49195
49462
  // },
49196
49463
  // clickReload_align_refined: function() {
49197
49464
  me.myEventCls.onIds("#" + me.pre + "reload_align_refined", "click", function(e) { me.icn3d;
49198
- e.preventDefault();
49199
- if(!me.cfg.notebook) dialog.dialog( "close" );
49200
- let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49201
- me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=1', false);
49202
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=1', '_blank');
49203
- window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=1', '_blank');
49204
- });
49465
+ e.preventDefault();
49466
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49467
+ let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49468
+ me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=1&bu=1', false);
49469
+ //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=1', '_blank');
49470
+ window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=1&bu=1', '_blank');
49471
+ });
49205
49472
  // },
49206
49473
  // clickReload_align_ori: function() {
49207
49474
  me.myEventCls.onIds("#" + me.pre + "reload_align_ori", "click", function(e) { me.icn3d;
49208
- e.preventDefault();
49209
- if(!me.cfg.notebook) dialog.dialog( "close" );
49210
- let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49211
- me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=0', false);
49212
- //window.open( me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=0', '_blank');
49213
- window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=0', '_blank');
49214
- });
49475
+ e.preventDefault();
49476
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49477
+ let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49478
+ me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=0&bu=1', false);
49479
+ //window.open( me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=0', '_blank');
49480
+ window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=0&bu=1', '_blank');
49481
+ });
49215
49482
  // },
49216
49483
  // clickReload_chainalign: function() {
49217
49484
  me.myEventCls.onIds("#" + me.pre + "reload_chainalign", "click", function(e) { me.icn3d;
@@ -49245,8 +49512,8 @@ class Events {
49245
49512
  }
49246
49513
 
49247
49514
  me.htmlCls.clickMenuCls.setLogCmd("load chains " + alignment + " on asymmetric unit | residues " + resalign + " | resdef " + predefinedres, false);
49248
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&buidx=0', '_blank');
49249
- window.open(hostUrl + '?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&buidx=0', '_blank');
49515
+ //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&bu=0', '_blank');
49516
+ window.open(hostUrl + '?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&bu=0', '_blank');
49250
49517
  });
49251
49518
 
49252
49519
  me.myEventCls.onIds("#" + me.pre + "reload_mutation_3d", "click", function(e) { me.icn3d;
@@ -49321,24 +49588,24 @@ class Events {
49321
49588
  // clickReload_mmdb: function() {
49322
49589
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb", "click", function(e) { me.icn3d;
49323
49590
  e.preventDefault();
49324
- if(!me.cfg.notebook) dialog.dialog( "close" );
49591
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49325
49592
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb1 " + $("#" + me.pre + "mmdbid").val(), false);
49326
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=1', '_blank');
49593
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=1', '_blank');
49327
49594
  });
49328
49595
 
49329
49596
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb_asym", "click", function(e) { me.icn3d;
49330
49597
  e.preventDefault();
49331
- if(!me.cfg.notebook) dialog.dialog( "close" );
49598
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49332
49599
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49333
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49600
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=0', '_blank');
49334
49601
  });
49335
49602
 
49336
49603
  me.myEventCls.onIds("#" + me.pre + "mmdbid", "keyup", function(e) { me.icn3d;
49337
49604
  if (e.keyCode === 13) {
49338
49605
  e.preventDefault();
49339
- if(!me.cfg.notebook) dialog.dialog( "close" );
49606
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49340
49607
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49341
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49608
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=0', '_blank');
49342
49609
  }
49343
49610
  });
49344
49611
 
@@ -49724,6 +49991,64 @@ class Events {
49724
49991
  reader.readAsText(file);
49725
49992
  }
49726
49993
  });
49994
+
49995
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
49996
+ e.preventDefault();
49997
+ ic.bInitial = true;
49998
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49999
+ //close all dialog
50000
+ if(!me.cfg.notebook) {
50001
+ $(".ui-dialog-content").dialog("close");
50002
+ }
50003
+ else {
50004
+ ic.resizeCanvasCls.closeDialogs();
50005
+ }
50006
+ let file = $("#" + me.pre + "afmapfile")[0].files[0];
50007
+ if(!file) {
50008
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
50009
+ }
50010
+ else {
50011
+ me.htmlCls.setHtmlCls.fileSupport();
50012
+ let reader = new FileReader();
50013
+ reader.onload = function(e) {
50014
+ let dataStr = e.target.result; // or = reader.result;
50015
+ me.htmlCls.clickMenuCls.setLogCmd('load AlphaFold PAE file ' + $("#" + me.pre + "afmapfile").val(), false);
50016
+
50017
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show Predicted Aligned Error (PAE) map');
50018
+ ic.contactMapCls.processAfErrorMap(JSON.parse(dataStr));
50019
+ };
50020
+ reader.readAsText(file);
50021
+ }
50022
+ });
50023
+
50024
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfilefull", "click", function(e) { let ic = me.icn3d;
50025
+ e.preventDefault();
50026
+ ic.bInitial = true;
50027
+ if(!me.cfg.notebook) dialog.dialog( "close" );
50028
+ //close all dialog
50029
+ if(!me.cfg.notebook) {
50030
+ $(".ui-dialog-content").dialog("close");
50031
+ }
50032
+ else {
50033
+ ic.resizeCanvasCls.closeDialogs();
50034
+ }
50035
+ let file = $("#" + me.pre + "afmapfile")[0].files[0];
50036
+ if(!file) {
50037
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
50038
+ }
50039
+ else {
50040
+ me.htmlCls.setHtmlCls.fileSupport();
50041
+ let reader = new FileReader();
50042
+ reader.onload = function(e) {
50043
+ let dataStr = e.target.result; // or = reader.result;
50044
+ me.htmlCls.clickMenuCls.setLogCmd('load AlphaFold PAE file ' + $("#" + me.pre + "afmapfile").val(), false);
50045
+
50046
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show Predicted Aligned Error (PAE) map');
50047
+ ic.contactMapCls.processAfErrorMap(JSON.parse(dataStr), true);
50048
+ };
50049
+ reader.readAsText(file);
50050
+ }
50051
+ });
49727
50052
  // },
49728
50053
  // clickReload_urlfile: function() {
49729
50054
  me.myEventCls.onIds("#" + me.pre + "reload_urlfile", "click", function(e) { let ic = me.icn3d;
@@ -49976,9 +50301,7 @@ class Events {
49976
50301
  me.myEventCls.onIds("#" + me.svgid + "_png", "click", function(e) { let ic = me.icn3d;
49977
50302
  e.preventDefault();
49978
50303
  //if(!me.cfg.notebook) dialog.dialog( "close" );
49979
- let width = $("#" + me.pre + "dl_graph").width();
49980
- let height = $("#" + me.pre + "dl_graph").height();
49981
- ic.saveFileCls.savePng(me.svgid, ic.inputid + "_force_directed_graph.png", width, height);
50304
+ ic.saveFileCls.savePng(me.svgid, ic.inputid + "_force_directed_graph.png");
49982
50305
  });
49983
50306
  me.myEventCls.onIds("#" + me.svgid + "_json", "click", function(e) { let ic = me.icn3d;
49984
50307
  e.preventDefault();
@@ -49997,9 +50320,7 @@ class Events {
49997
50320
  $(document).on("click", "#" + me.svgid_ct + "_png", function(e) { let ic = me.icn3d;
49998
50321
  e.preventDefault();
49999
50322
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50000
- let width = $("#" + me.pre + "dl_2dctn").width();
50001
- let height = $("#" + me.pre + "dl_2dctn").height();
50002
- ic.saveFileCls.savePng(me.svgid_ct, ic.inputid + "_cartoon.png", width, height);
50323
+ ic.saveFileCls.savePng(me.svgid_ct, ic.inputid + "_cartoon.png");
50003
50324
  });
50004
50325
  $(document).on("click", "#" + me.svgid_ct + "_json", function(e) { let ic = me.icn3d;
50005
50326
  e.preventDefault();
@@ -50025,9 +50346,7 @@ class Events {
50025
50346
  me.myEventCls.onIds("#" + me.linegraphid + "_png", "click", function(e) { let ic = me.icn3d;
50026
50347
  e.preventDefault();
50027
50348
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50028
- let width = $("#" + me.pre + "dl_linegraph").width();
50029
- let height = $("#" + me.pre + "dl_linegraph").height();
50030
- ic.saveFileCls.savePng(me.linegraphid, ic.inputid + "_line_graph.png", width, height);
50349
+ ic.saveFileCls.savePng(me.linegraphid, ic.inputid + "_line_graph.png");
50031
50350
  });
50032
50351
  me.myEventCls.onIds("#" + me.linegraphid + "_json", "click", function(e) { let ic = me.icn3d;
50033
50352
  e.preventDefault();
@@ -50053,9 +50372,7 @@ class Events {
50053
50372
  me.myEventCls.onIds("#" + me.scatterplotid + "_png", "click", function(e) { let ic = me.icn3d;
50054
50373
  e.preventDefault();
50055
50374
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50056
- let width = $("#" + me.pre + "dl_scatterplot").width();
50057
- let height = $("#" + me.pre + "dl_scatterplot").height();
50058
- ic.saveFileCls.savePng(me.scatterplotid, ic.inputid + "_scatterplot.png", width, height);
50375
+ ic.saveFileCls.savePng(me.scatterplotid, ic.inputid + "_scatterplot.png");
50059
50376
  });
50060
50377
  me.myEventCls.onIds("#" + me.scatterplotid + "_json", "click", function(e) { let ic = me.icn3d;
50061
50378
  e.preventDefault();
@@ -50077,14 +50394,12 @@ class Events {
50077
50394
  me.myEventCls.onIds("#" + me.contactmapid + "_svg", "click", function(e) { let ic = me.icn3d;
50078
50395
  e.preventDefault();
50079
50396
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50080
- ic.saveFileCls.saveSvg(me.contactmapid, ic.inputid + "_contactmap.svg");
50397
+ ic.saveFileCls.saveSvg(me.contactmapid, ic.inputid + "_contactmap.svg", true);
50081
50398
  });
50082
50399
  me.myEventCls.onIds("#" + me.contactmapid + "_png", "click", function(e) { let ic = me.icn3d;
50083
50400
  e.preventDefault();
50084
50401
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50085
- let width = $("#" + me.pre + "dl_contactmap").width();
50086
- let height = $("#" + me.pre + "dl_contactmap").height();
50087
- ic.saveFileCls.savePng(me.contactmapid, ic.inputid + "_contactmap.png", width, height);
50402
+ ic.saveFileCls.savePng(me.contactmapid, ic.inputid + "_contactmap.png", true);
50088
50403
  });
50089
50404
  me.myEventCls.onIds("#" + me.contactmapid + "_json", "click", function(e) { let ic = me.icn3d;
50090
50405
  e.preventDefault();
@@ -50096,11 +50411,47 @@ class Events {
50096
50411
  ic.saveFileCls.saveFile(ic.inputid + "_contactmap.json", "text", [graphStr2]);
50097
50412
  });
50098
50413
  me.myEventCls.onIds("#" + me.contactmapid + "_scale", "change", function(e) { let ic = me.icn3d;
50414
+ e.preventDefault();
50415
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50416
+ let scale = $("#" + me.contactmapid + "_scale").val();
50417
+ $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
50418
+ me.htmlCls.clickMenuCls.setLogCmd("contactmap scale " + scale, true);
50419
+ });
50420
+
50421
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_svg", "click", function(e) { let ic = me.icn3d;
50422
+ e.preventDefault();
50423
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50424
+ ic.saveFileCls.saveSvg(me.alignerrormapid, ic.inputid + "_alignerrormap.svg", true);
50425
+ });
50426
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_png", "click", function(e) { let ic = me.icn3d;
50427
+ e.preventDefault();
50428
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50429
+ ic.saveFileCls.savePng(me.alignerrormapid, ic.inputid + "_alignerrormap.png", true);
50430
+ });
50431
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_full", "click", function(e) { let ic = me.icn3d;
50432
+ e.preventDefault();
50433
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50434
+ ic.contactMapCls.afErrorMap(afid, true);
50435
+
50436
+
50437
+ });
50438
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_json", "click", function(e) { let ic = me.icn3d;
50439
+ e.preventDefault();
50440
+
50441
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50442
+ let graphStr2 = ic.alignerrormapStr.substr(0, ic.alignerrormapStr.lastIndexOf('}'));
50443
+
50444
+ graphStr2 += me.htmlCls.setHtmlCls.getLinkColor();
50445
+
50446
+ ic.saveFileCls.saveFile(ic.inputid + "_alignerrormap.json", "text", [graphStr2]);
50447
+ });
50448
+
50449
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_scale", "change", function(e) { let ic = me.icn3d;
50099
50450
  e.preventDefault();
50100
50451
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50101
- let scale = $("#" + me.contactmapid + "_scale").val();
50102
- $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
50103
- me.htmlCls.clickMenuCls.setLogCmd("contactmap scale " + scale, true);
50452
+ let scale = $("#" + me.alignerrormapid + "_scale").val();
50453
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
50454
+ me.htmlCls.clickMenuCls.setLogCmd("alignerrormap scale " + scale, true);
50104
50455
  });
50105
50456
 
50106
50457
  me.myEventCls.onIds("#" + me.svgid + "_label", "change", function(e) { me.icn3d;
@@ -52517,7 +52868,142 @@ class ContactMap {
52517
52868
  }
52518
52869
  }
52519
52870
 
52520
- drawContactMap(lineGraphStr) { let ic = this.icn3d, me = ic.icn3dui;
52871
+ afErrorMap(afid, bFull) { let ic = this.icn3d, me = ic.icn3dui;
52872
+ let thisClass = this;
52873
+
52874
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show Predicted Aligned Error (PAE) map');
52875
+
52876
+ let url, dataType;
52877
+
52878
+ url = "https://alphafold.ebi.ac.uk/files/AF-" + afid + "-F1-predicted_aligned_error_v2.json";
52879
+
52880
+ dataType = "json";
52881
+
52882
+ $.ajax({
52883
+ url: url,
52884
+ dataType: dataType,
52885
+ cache: true,
52886
+ tryCount : 0,
52887
+ retryLimit : 1,
52888
+ success: function(data) {
52889
+ thisClass.processAfErrorMap(data, bFull);
52890
+ },
52891
+ error : function(xhr, textStatus, errorThrown ) {
52892
+ this.tryCount++;
52893
+ if(this.tryCount <= this.retryLimit) {
52894
+ //try again
52895
+ $.ajax(this);
52896
+ return;
52897
+ }
52898
+ var aaa = 1; //alert("There are some problems in loading the PAE file...");
52899
+ return;
52900
+ }
52901
+ });
52902
+ }
52903
+
52904
+ processAfErrorMap(dataJson, bFull) { let ic = this.icn3d, me = ic.icn3dui;
52905
+ // json format: [{"residue1": [1, ..., 1, ..., n, ..., n], "residue2": [1, 2, ..., n, ..., 1, 2, ..., n],
52906
+ // "distance": [n*n matrix],"max_predicted_aligned_error":31.75}]
52907
+ let distMatrix = dataJson[0].distance;
52908
+ let max = dataJson[0].max_predicted_aligned_error;
52909
+ if(!distMatrix || !max) {
52910
+ var aaa = 1; //alert("The PAE file didn't have the right format...");
52911
+ return;
52912
+ }
52913
+
52914
+ // generate lineGraphStr
52915
+ // e.g., {"nodes": [{"id":"A1.A","r":"1_1_1TOP_A_1","s":"ab","x":1,"y":21,"c":"FF00FF"}, ...],
52916
+ // "links": [{"source": "A1.A", "target": "S2.A", "v": 3, "c": "FF00FF"}, ...]}
52917
+ let nodeStr = '"nodes": [', linkStr = '"links": [';
52918
+ let bNode = false, bLink = false;
52919
+ let postA = '', postB = '.';
52920
+
52921
+ // initialize some parameters if no structure wasloaded yet
52922
+ let bStruData;
52923
+ if(!ic.chains || Object.keys(ic.chains).length == 0) {
52924
+ bStruData = false;
52925
+ ic.init_base();
52926
+ }
52927
+ else {
52928
+ bStruData = true;
52929
+ }
52930
+
52931
+ //let chainidArray = Object.keys(ic.chains);
52932
+ //let chainid = (chainidArray.length == 1) ? chainidArray[0] : 'stru_A';
52933
+
52934
+ let dim = parseInt(Math.sqrt(distMatrix.length));
52935
+
52936
+ // map index with residue number when the structure has multiple chains
52937
+ let index = 0;
52938
+ let index2resObj = {};
52939
+ for(let chainid in ic.chains) {
52940
+ for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
52941
+ index2resObj[index] = ic.chainsSeq[chainid][j];
52942
+ index2resObj[index].chainid = chainid;
52943
+ ++index;
52944
+ }
52945
+ }
52946
+
52947
+ //for(let chainid in ic.chains) {
52948
+ //for(let i = 0, il = ic.chainsSeq[chainid].length; i < il; ++i) {
52949
+ index = 0;
52950
+ for(let i = 0; i < dim; ++i) {
52951
+ let resi = (bStruData) ? index2resObj[i].resi : i + 1;
52952
+ let resn = (bStruData) ? index2resObj[i].name : '*';
52953
+ let chainid = (bStruData) ? index2resObj[i].chainid : 'stru_A';
52954
+
52955
+ let resid = chainid + '_' + resi;
52956
+ let atom = (ic.residues[resid]) ? ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid])
52957
+ : {color: me.parasCls.thr(0x888888)};
52958
+ let chain = chainid.substr(chainid.indexOf('_') + 1);
52959
+ let color = atom.color.getHexString();
52960
+
52961
+ if(bNode) nodeStr += ', ';
52962
+ let idStr = resn + resi + '.' + chain;
52963
+ nodeStr += '{"id":"' + idStr + postA + '","r":"1_1_' + resid + '","s":"a","c":"' + color + '"}\n';
52964
+ nodeStr += ', {"id":"' + idStr + postB + '","r":"1_1_' + resid + '","s":"b","c":"' + color + '"}';
52965
+ bNode = true;
52966
+
52967
+ let start = (bFull) ? 0 : i; // full map, or half map
52968
+
52969
+ //for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
52970
+ //for(let j = 0; j < dim; ++j) {
52971
+ for(let j = start; j < dim; ++j) {
52972
+ index = i * dim + j;
52973
+ let resi2 = (bStruData) ? index2resObj[j].resi : j + 1;
52974
+ let resn2 = (bStruData) ? index2resObj[j].name : '*';
52975
+ let chainid2 = (bStruData) ? index2resObj[j].chainid : 'stru_A';
52976
+ let chain2 = chainid2.substr(chainid2.indexOf('_') + 1);
52977
+
52978
+ let idStr2 = resn2 + resi2 + '.' + chain2;
52979
+
52980
+ // max dark green color 004d00, 0x4d = 77, 77/255 = 0.302
52981
+ // 0: 004d00, max: FFFFFF
52982
+ let ratio = (distMatrix[index]) ? distMatrix[index] / max : 0;
52983
+ let r = parseInt(ratio*255).toString(16);
52984
+ let g = parseInt(((1.0 - 0.302)*ratio + 0.302) * 255).toString(16);
52985
+ let rHex = (r.length == 1) ? '0' + r : r;
52986
+ let gHex = (g.length == 1) ? '0' + g : g;
52987
+ let bHex = rHex;
52988
+ let color2 = rHex + gHex + bHex;
52989
+
52990
+ if(bLink) linkStr += ', ';
52991
+ linkStr += '{"source": "' + idStr + postA + '", "target": "' + idStr2 + postB + '", "v": 11, "c": "' + color2 + '"}\n';
52992
+ bLink = true;
52993
+ }
52994
+ }
52995
+ //}
52996
+
52997
+ dataJson = {};
52998
+
52999
+ let lineGraphStr = '{' + nodeStr + '], ' + linkStr + ']}';
53000
+ let bAfMap = true;
53001
+ this.drawContactMap(lineGraphStr, bAfMap, max);
53002
+
53003
+ if(ic.deferredAfmap !== undefined) ic.deferredAfmap.resolve();
53004
+ }
53005
+
53006
+ drawContactMap(lineGraphStr, bAfMap, max) { let ic = this.icn3d, me = ic.icn3dui;
52521
53007
  let html, graph = JSON.parse(lineGraphStr);
52522
53008
  let linkArray = graph.links;
52523
53009
 
@@ -52551,7 +53037,7 @@ class ContactMap {
52551
53037
 
52552
53038
  let graphStr = '{\n';
52553
53039
 
52554
- let struc1 = Object.keys(ic.structures)[0];
53040
+ let struc1 = (ic.structures.length > 0) ? ic.structures[0] : 'stru';
52555
53041
  let len1 = nodeArray1.length,
52556
53042
  len2 = nodeArray2.length;
52557
53043
  let factor = 1;
@@ -52565,20 +53051,76 @@ class ContactMap {
52565
53051
  width =(len2 + 2) *(r + gap) + 2 * marginX + legendWidth;
52566
53052
 
52567
53053
  let id, graphWidth;
52568
- ic.contactmapWidth = 2 * width;
52569
- graphWidth = ic.contactmapWidth;
52570
- id = me.contactmapid;
53054
+ if(bAfMap) {
53055
+ ic.alignerrormapWidth = 2 * width;
53056
+ graphWidth = ic.alignerrormapWidth;
53057
+ id = me.alignerrormapid;
53058
+ }
53059
+ else {
53060
+ ic.contactmapWidth = 2 * width;
53061
+ graphWidth = ic.contactmapWidth;
53062
+ id = me.contactmapid;
53063
+ }
53064
+
52571
53065
  html =(linkArray.length > 0) ? "" : "No interactions found for these two sets<br><br>";
52572
- html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
53066
+ html += "<svg xmlns='http://www.w3.org/2000/svg' id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
52573
53067
  let bContactMap = true;
52574
- html += ic.lineGraphCls.drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, 0, bContactMap);
53068
+
53069
+ if(bAfMap) { // cleaned the code by using "use" in SVG, but didn't improve rendering
53070
+ let factor = 1;
53071
+ let r = 3 * factor;
53072
+ let rectSize = 2 * r;
53073
+
53074
+ ic.hex2id = {};
53075
+ let threshold = 29.0 / max;
53076
+ ic.hex2skip = {}; // do not display any error larger than 29 angstrom
53077
+
53078
+ html += "<defs>";
53079
+
53080
+ let linestrokewidth = 1;
53081
+ let nRef = 1000;
53082
+ for(let i = 0; i < nRef; ++i) {
53083
+ let ratio = 1.0 * i / nRef;
53084
+ let r = parseInt(ratio*255).toString(16);
53085
+ let g = parseInt(((1.0 - 0.302)*ratio + 0.302) * 255).toString(16);
53086
+ let rHex = (r.length == 1) ? '0' + r : r;
53087
+ let gHex = (g.length == 1) ? '0' + g : g;
53088
+ let bHex = rHex;
53089
+ let color = rHex + gHex + bHex;
53090
+ let strokecolor = "#" + color;
53091
+
53092
+ let idRect = me.pre + "afmap_" + i;
53093
+
53094
+ ic.hex2id[color] = idRect;
53095
+ if(ratio > threshold) {
53096
+ ic.hex2skip[color] = idRect;
53097
+ }
53098
+
53099
+ //html += "<g id='" + id + "'>";
53100
+ html += "<rect id='" + idRect + "' x='0' y='0' width='" + rectSize + "' height='" + rectSize + "' fill='"
53101
+ + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
53102
+ //html += "</g>"
53103
+ }
53104
+ html += "</defs>";
53105
+ }
53106
+
53107
+ html += ic.lineGraphCls.drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, 0, bContactMap, undefined, undefined, bAfMap);
52575
53108
  graphStr += ic.getGraphCls.updateGraphJson(struc1, 1, nodeArray1, nodeArray2, linkArray);
52576
53109
  html += "</svg>";
52577
53110
 
52578
53111
  graphStr += '}\n';
52579
- ic.contactmapStr = graphStr;
53112
+ if(bAfMap) {
53113
+ ic.alignerrormapStr = graphStr;
53114
+ $("#" + ic.pre + "alignerrormapDiv").html(html);
53115
+
53116
+ let scale = $("#" + me.alignerrormapid + "_scale").val();
53117
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
53118
+ }
53119
+ else {
53120
+ ic.contactmapStr = graphStr;
53121
+ $("#" + ic.pre + "contactmapDiv").html(html);
53122
+ }
52580
53123
 
52581
- $("#" + ic.pre + "contactmapDiv").html(html);
52582
53124
  return html;
52583
53125
  }
52584
53126
  }
@@ -54606,6 +55148,7 @@ class iCn3D {
54606
55148
  this.bInstanced = true;
54607
55149
 
54608
55150
  this.chainMissingResidueArray = {};
55151
+ this._zoomFactor = 1.0;
54609
55152
 
54610
55153
  if(!this.icn3dui.bNode) {
54611
55154
  this.bExtFragDepth = this.renderer.extensions.get( "EXT_frag_depth" );
@@ -54957,7 +55500,7 @@ iCn3D.prototype.init = function (bKeepCmd) {
54957
55500
  //this.inputid = {"idtype": undefined, "id":undefined}; // support pdbid, mmdbid
54958
55501
 
54959
55502
  this.biomtMatrices = [];
54960
- this.bAssembly = true;
55503
+ this.bAssembly = false; //true;
54961
55504
 
54962
55505
  this.bDrawn = false;
54963
55506
  this.bSecondaryStructure = false;
@@ -55095,7 +55638,7 @@ iCn3D.prototype.reinitAfterLoad = function () { let ic = this, me = ic.icn3dui;
55095
55638
  ic.lines = {}; // hash of name -> a list of solid or dashed lines. Each line contains 'position1', 'position2', 'color', and a boolean of 'dashed'
55096
55639
  // line name could be custom, hbond, ssbond, distance
55097
55640
 
55098
- ic.bAssembly = true;
55641
+ ic.bAssembly = false; //true;
55099
55642
  };
55100
55643
 
55101
55644
  iCn3D.prototype.resetConfig = function () { let ic = this, me = ic.icn3dui;
@@ -55134,7 +55677,7 @@ class iCn3DUI {
55134
55677
  //even when multiple iCn3D viewers are shown together.
55135
55678
  this.pre = this.cfg.divid + "_";
55136
55679
 
55137
- this.REVISION = '3.7.0';
55680
+ this.REVISION = '3.8.1';
55138
55681
 
55139
55682
  // In nodejs, iCn3D defines "window = {navigator: {}}"
55140
55683
  this.bNode = (Object.keys(window).length < 2) ? true : false;