icn3d 3.7.1 → 3.8.3

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 +795 -220
  2. package/package.json +3 -2
package/icn3d.js CHANGED
@@ -6862,10 +6862,11 @@ class Tube {
6862
6862
  firstAtom = atom;
6863
6863
  }
6864
6864
 
6865
- //if (index > 0 && (currentChain !== atom.chain || Math.abs(atom.coord.x - prevAtom.coord.x) > maxDist || Math.abs(atom.coord.y - prevAtom.coord.y) > maxDist || Math.abs(atom.coord.z - prevAtom.coord.z) > maxDist
6866
- // || (currentResi + 1 !== atom.resi && (Math.abs(atom.coord.x - prevAtom.coord.x) > maxDist2 || Math.abs(atom.coord.y - prevAtom.coord.y) > maxDist2 || Math.abs(atom.coord.z - prevAtom.coord.z) > maxDist2) )
6865
+ atom.structure + '_' + atom.chain + '_' + (parseInt(atom.resi) - 1).toString();
6866
+
6867
6867
  if (index > 0 && (currentChain !== atom.chain || Math.abs(atom.coord.x - prevAtom.coord.x) > maxDist || Math.abs(atom.coord.y - prevAtom.coord.y) > maxDist || Math.abs(atom.coord.z - prevAtom.coord.z) > maxDist
6868
- || (parseInt(currentResi) + 1 < parseInt(atom.resi) && (Math.abs(atom.coord.x - prevAtom.coord.x) > maxDist2 || Math.abs(atom.coord.y - prevAtom.coord.y) > maxDist2 || Math.abs(atom.coord.z - prevAtom.coord.z) > maxDist2) )
6868
+ // || (parseInt(currentResi) + 1 < parseInt(atom.resi) && (Math.abs(atom.coord.x - prevAtom.coord.x) > maxDist2 || Math.abs(atom.coord.y - prevAtom.coord.y) > maxDist2 || Math.abs(atom.coord.z - prevAtom.coord.z) > maxDist2) && ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]) && ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.residues[resid]).ss == 'helix')
6869
+ || (parseInt(currentResi) + 1 < parseInt(atom.resi) && (Math.abs(atom.coord.x - prevAtom.coord.x) > maxDist2 || Math.abs(atom.coord.y - prevAtom.coord.y) > maxDist2 || Math.abs(atom.coord.z - prevAtom.coord.z) > maxDist2))
6869
6870
  ) ) {
6870
6871
  if(bHighlight !== 2) {
6871
6872
  if(!isNaN(firstAtom.resi) && !isNaN(prevAtom.resi)) {
@@ -7658,7 +7659,6 @@ class Strand {
7658
7659
  }
7659
7660
 
7660
7661
  currentChain = atom.chain;
7661
- atom.resi;
7662
7662
  ss = atom.ss;
7663
7663
  ssend = atom.ssend;
7664
7664
  prevAtomid = atom.serial;
@@ -12045,7 +12045,6 @@ class HlObjects {
12045
12045
 
12046
12046
  //Show the highlight for the selected atoms: hAtoms.
12047
12047
  addHlObjects(color, bRender, atomsHash) { let ic = this.icn3d, me = ic.icn3dui;
12048
- if(color === undefined) color = ic.hColor;
12049
12048
  //if(atomsHash === undefined) atomsHash = ic.hAtoms;
12050
12049
  let atomsHashDisplay = (atomsHash) ? me.hashUtilsCls.intHash(atomsHash, ic.dAtoms) : me.hashUtilsCls.intHash(ic.hAtoms, ic.dAtoms);
12051
12050
 
@@ -13356,13 +13355,14 @@ class DefinedSets {
13356
13355
  dAtoms = me.hashUtilsCls.unionHash(dAtoms, ic.alnChains[alignChain]);
13357
13356
  }
13358
13357
 
13359
- let residuesHash = {};
13358
+ let residuesHash = {}, chains = {};
13360
13359
  for(let i in dAtoms) {
13361
13360
  let atom = ic.atoms[i];
13362
13361
 
13363
13362
  let chainid = atom.structure + '_' + atom.chain;
13364
13363
  let resid = chainid + '_' + atom.resi;
13365
13364
  residuesHash[resid] = 1;
13365
+ chains[chainid] = 1;
13366
13366
  }
13367
13367
 
13368
13368
  let commandname = 'protein_aligned';
@@ -14361,9 +14361,7 @@ class HBond {
14361
14361
  }
14362
14362
 
14363
14363
  //if(result > kMaxHBondEnergy) {
14364
- if(atom.ss == 'helix' && atomHbond[j].ss == 'helix' && result > kMaxHBondEnergy) {
14365
- continue;
14366
- }
14364
+ if(atom.ss == 'helix' && atomHbond[j].ss == 'helix' && result > kMaxHBondEnergy) ;
14367
14365
  }
14368
14366
  }
14369
14367
  else {
@@ -15168,24 +15166,7 @@ class Saltbridge {
15168
15166
  || (atom.het && me.parasCls.cationsTrimArray.indexOf(atom.elem) !== -1)
15169
15167
  || (atom.het && atom.elem === "N" && atom.bonds.length == 1);
15170
15168
 
15171
- // For ligand, "O" in carboxy group may be negatively charged. => to be improved
15172
- let bLigNeg = undefined;
15173
- if(atom.het && atom.elem === "O" && atom.bonds.length == 1) {
15174
- let cAtom = ic.atoms[atom.bonds[0]];
15175
- for(let j = 0; j < cAtom.bonds.length; ++j) {
15176
- let serial = cAtom.bonds[j];
15177
- if(ic.atoms[serial].elem == "O" && serial != atom.serial) {
15178
- bLigNeg = true;
15179
- break;
15180
- }
15181
- }
15182
- }
15183
-
15184
- let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15185
- || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15186
- || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15187
- || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1)
15188
- || bLigNeg;
15169
+ let bAtomCondAnion = this.isAnion(atom);
15189
15170
 
15190
15171
  bAtomCondCation = (ic.bOpm) ? bAtomCondCation && atom.resn !== 'DUM' : bAtomCondCation;
15191
15172
  bAtomCondAnion = (ic.bOpm) ? bAtomCondAnion && atom.resn !== 'DUM' : bAtomCondAnion;
@@ -15216,10 +15197,7 @@ class Saltbridge {
15216
15197
  || ( atom.resn === 'ARG' && (atom.name === "NH1" || atom.name === "NH2"))
15217
15198
  || (atom.het && me.parasCls.cationsTrimArray.indexOf(atom.elem) !== -1);
15218
15199
 
15219
- let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15220
- || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15221
- || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15222
- || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1);
15200
+ let bAtomCondAnion = this.isAnion(atom);
15223
15201
 
15224
15202
  bAtomCondCation = (ic.bOpm) ? bAtomCondCation && atom.resn !== 'DUM' : bAtomCondCation;
15225
15203
  bAtomCondAnion = (ic.bOpm) ? bAtomCondAnion && atom.resn !== 'DUM' : bAtomCondAnion;
@@ -15330,6 +15308,35 @@ class Saltbridge {
15330
15308
  return hbondsAtoms;
15331
15309
  }
15332
15310
 
15311
+ isAnion(atom) { let ic = this.icn3d, me = ic.icn3dui;
15312
+ // For ligand, "O" in carboxy group may be negatively charged. => to be improved
15313
+ let bLigNeg = undefined;
15314
+ if(atom.het && atom.elem === "O" && atom.bonds.length == 1) {
15315
+ let cAtom = ic.atoms[atom.bonds[0]];
15316
+ for(let j = 0; j < cAtom.bonds.length; ++j) {
15317
+ let serial = cAtom.bonds[j];
15318
+ if(ic.atoms[serial].elem == "O" && serial != atom.serial) {
15319
+ bLigNeg = true;
15320
+ break;
15321
+ }
15322
+ }
15323
+ }
15324
+
15325
+ // "O" in phosphae or sulfate group is neagatively charged
15326
+ if(atom.elem === "O" && atom.bonds.length == 1) {
15327
+ let pAtom = ic.atoms[atom.bonds[0]];
15328
+ if(pAtom.elem == "P" || pAtom.elem == "S") bLigNeg = true;
15329
+ }
15330
+
15331
+ let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15332
+ || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15333
+ || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15334
+ || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1)
15335
+ || bLigNeg;
15336
+
15337
+ return bAtomCondAnion;
15338
+ }
15339
+
15333
15340
  hideSaltbridge() { let ic = this.icn3d; ic.icn3dui;
15334
15341
  ic.opts["saltbridge"] = "no";
15335
15342
  if(ic.lines === undefined) ic.lines = { };
@@ -15477,7 +15484,7 @@ class GetGraph {
15477
15484
  return resStr;
15478
15485
  }
15479
15486
 
15480
- drawResNode(node, i, r, gap, margin, y, setName, bVertical, bContactMap) { let ic = this.icn3d; ic.icn3dui;
15487
+ drawResNode(node, i, r, gap, margin, y, setName, bVertical, bContactMap, bAfMap) { let ic = this.icn3d; ic.icn3dui;
15481
15488
  let x, resid = node.r.substr(4);
15482
15489
  if(bVertical) {
15483
15490
  x = margin - i *(r + gap);
@@ -15503,6 +15510,7 @@ class GetGraph {
15503
15510
  let strokewidth = '1';
15504
15511
  let textcolor = '#000';
15505
15512
  let fontsize = '6px'; // '6';
15513
+ //let html = (bAfMap) ? "<g>" : "<g class='icn3d-node' resid='" + resid + "' >";
15506
15514
  let html = "<g class='icn3d-node' resid='" + resid + "' >";
15507
15515
  html += "<title>" + node.id + "</title>";
15508
15516
  if(bVertical) {
@@ -15516,18 +15524,27 @@ class GetGraph {
15516
15524
  html += "</g>";
15517
15525
  return html;
15518
15526
  }
15519
- 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;
15520
15528
  let thisClass = this;
15521
15529
  let nodeArray1 = [], nodeArray2 = [], name2nodeCommon = {};
15530
+
15531
+ let separatorCommon = "=>", separatorDiff = "==>", postCommon = "-", postDiff = "--";
15522
15532
  for(let name in nameHash) {
15523
15533
  let node = name2node[name];
15524
15534
  if(!node) continue;
15525
15535
 
15526
- if(bCommon) {
15536
+ if(bCommonDiff == 1 || bCommonDiff == 2) {
15527
15537
  node = me.hashUtilsCls.cloneHash(node);
15528
15538
 
15529
- let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : '-';
15530
- 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
+
15531
15548
  name2nodeCommon[node.id] = node;
15532
15549
  }
15533
15550
 
@@ -15537,10 +15554,10 @@ class GetGraph {
15537
15554
  else if(node.s == 'b') {
15538
15555
  nodeArray2.push(node);
15539
15556
  }
15540
- //else if(node.s == 'ab') {
15541
- // nodeArray1.push(node);
15542
- // nodeArray2.push(node);
15543
- //}
15557
+ else if(node.s == 'ab') {
15558
+ nodeArray1.push(node);
15559
+ nodeArray2.push(node);
15560
+ }
15544
15561
  }
15545
15562
  // sort array
15546
15563
  nodeArray1.sort(function(a,b) {
@@ -15597,9 +15614,12 @@ class GetGraph {
15597
15614
  }
15598
15615
  ic.graphStr = JSON.stringify(graphJson);
15599
15616
  }
15617
+
15618
+ /*
15600
15619
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
15601
15620
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
15602
15621
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
15622
+ */
15603
15623
  }
15604
15624
 
15605
15625
  handleForce() { let ic = this.icn3d, me = ic.icn3dui;
@@ -15881,6 +15901,7 @@ class LineGraph {
15881
15901
  // Original node: {id : "Q24.A.2AJF", r : "1_1_2AJF_A_24", s: "a", ...}
15882
15902
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
15883
15903
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
15904
+ let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
15884
15905
  let linkedNodeCnt = {};
15885
15906
 
15886
15907
  for(let i = 0, il = structureArray.length; i < il; ++i) {
@@ -15894,6 +15915,11 @@ class LineGraph {
15894
15915
  linkArraySplitCommon[i] = [];
15895
15916
  nameHashSplitCommon[i] = {};
15896
15917
 
15918
+ nodeArray1SplitDiff[i] = [];
15919
+ nodeArray2SplitDiff[i] = [];
15920
+ linkArraySplitDiff[i] = [];
15921
+ nameHashSplitDiff[i] = {};
15922
+
15897
15923
  struc2index[structureArray[i]] = i;
15898
15924
  }
15899
15925
 
@@ -15922,7 +15948,7 @@ class LineGraph {
15922
15948
  let resid2 = chainid2 + '_' + idArrayB[4];
15923
15949
 
15924
15950
  let mapping1, mapping2;
15925
-
15951
+
15926
15952
  if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15927
15953
  && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15928
15954
  mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
@@ -15938,8 +15964,10 @@ class LineGraph {
15938
15964
  }
15939
15965
  }
15940
15966
  }
15941
-
15967
+
15942
15968
  // set linkArraySplitCommon and nameHashSplitCommon
15969
+ // set linkArraySplitDiff and nameHashSplitDiff
15970
+ let separatorCommon = "=>", separatorDiff = "==>", postCommon = "-", postDiff = "--";
15943
15971
  for(let i = 0, il = linkArray.length; i < il; ++i) {
15944
15972
  let link = linkArray[i];
15945
15973
  let nodeA = name2node[link.source];
@@ -15969,33 +15997,53 @@ class LineGraph {
15969
15997
 
15970
15998
  let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15971
15999
 
15972
- if(linkedNodeCnt[mappingid] == structureArray.length) {
15973
- let linkCommon = me.hashUtilsCls.cloneHash(link);
15974
- linkCommon.source += '>' + ic.chainsMapping[chainid1][resid1];
15975
- linkCommon.target += '>' + ic.chainsMapping[chainid2][resid2];
16000
+ let linkCommon = me.hashUtilsCls.cloneHash(link);
16001
+ linkCommon.source += (ic.chainsMapping[chainid1][resid1]) ? separatorCommon + ic.chainsMapping[chainid1][resid1] : separatorCommon + postCommon;
16002
+ linkCommon.target += (ic.chainsMapping[chainid2][resid2]) ? separatorCommon + ic.chainsMapping[chainid2][resid2] : separatorCommon + postCommon;
15976
16003
 
16004
+ let linkDiff = me.hashUtilsCls.cloneHash(link);
16005
+ linkDiff.source += (ic.chainsMapping[chainid1][resid1]) ? separatorDiff + ic.chainsMapping[chainid1][resid1] : separatorDiff + postDiff;
16006
+ linkDiff.target += (ic.chainsMapping[chainid2][resid2]) ? separatorDiff + ic.chainsMapping[chainid2][resid2] : separatorDiff + postDiff;
16007
+
16008
+ if(linkedNodeCnt[mappingid] == structureArray.length) {
15977
16009
  linkArraySplitCommon[index].push(linkCommon);
15978
16010
  }
16011
+ else {
16012
+ linkArraySplitDiff[index].push(linkDiff);
16013
+ }
15979
16014
 
16015
+ // use the original node names and thus use the original link
15980
16016
  nameHashSplitCommon[index][link.source] = ic.chainsMapping[chainid1][resid1];
15981
16017
  nameHashSplitCommon[index][link.target] = ic.chainsMapping[chainid2][resid2];
16018
+
16019
+ nameHashSplitDiff[index][link.source] = ic.chainsMapping[chainid1][resid1];
16020
+ nameHashSplitDiff[index][link.target] = ic.chainsMapping[chainid2][resid2];
15982
16021
  }
15983
16022
  }
15984
16023
  }
15985
16024
 
15986
16025
  let len1Split = [], len2Split = [], maxWidth = 0;
15987
16026
  let strucArray = [];
16027
+ let bCommonDiff = 1;
15988
16028
  for(let i = 0, il = structureArray.length; i < il; ++i) {
15989
16029
  let nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node);
15990
16030
  nodeArray1Split[i] = nodeArraysTmp.nodeArray1;
15991
16031
  nodeArray2Split[i] = nodeArraysTmp.nodeArray2;
15992
16032
 
15993
- let bCommon = true;
15994
- nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommon, nameHashSplitCommon[i]);
16033
+ // common interactions
16034
+ bCommonDiff = 1;
16035
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommonDiff, nameHashSplitCommon[i]);
15995
16036
  nodeArray1SplitCommon[i] = nodeArraysTmp.nodeArray1;
15996
16037
  nodeArray2SplitCommon[i] = nodeArraysTmp.nodeArray2;
15997
16038
  name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
15998
16039
 
16040
+ // different interactions
16041
+ bCommonDiff = 2;
16042
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommonDiff, nameHashSplitDiff[i]);
16043
+ nodeArray1SplitDiff[i] = nodeArraysTmp.nodeArray1;
16044
+ nodeArray2SplitDiff[i] = nodeArraysTmp.nodeArray2;
16045
+ name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
16046
+
15999
16047
  len1Split[i] = nodeArray1Split[i].length;
16000
16048
  len2Split[i] = nodeArray2Split[i].length;
16001
16049
 
@@ -16019,16 +16067,16 @@ class LineGraph {
16019
16067
  //width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16020
16068
  heightAll =(me.utilsCls.sumArray(len1Split) + 2*strucArray.length) *(r + gap) + 4 * marginY
16021
16069
  + 2 * legendWidth + textHeight*strucArray.length;
16022
- // show common interaction as well
16023
- heightAll *= 2;
16070
+ // show common and diff interaction as well
16071
+ heightAll *= 3;
16024
16072
 
16025
16073
  width = (maxWidth + 2) * (r + gap) + 2 * marginX + legendWidth;
16026
16074
 
16027
16075
  } else {
16028
16076
  height = 110 + textHeight;
16029
16077
  heightAll = height * strucArray.length;
16030
- // show common interaction as well
16031
- heightAll *= 2;
16078
+ // show common and diff interaction as well
16079
+ heightAll *= 3;
16032
16080
 
16033
16081
  width = (maxWidth + 2) * (r + gap) + 2 * marginX;
16034
16082
  }
@@ -16043,42 +16091,29 @@ class LineGraph {
16043
16091
  id = me.linegraphid;
16044
16092
  }
16045
16093
  html =(strucArray.length == 0) ? "No interactions found for each structure<br><br>" :
16046
- "2D integration graph for " + strucArray.length + " structure(s) <b>" + strucArray + "</b>. Common interactions are shown in the last " + strucArray.length + " graphs.<br><br>";
16094
+ "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>";
16047
16095
  html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
16048
16096
 
16049
- let heightFinal = 0;
16050
- for(let i = 0, il = structureArray.length; i < il; ++i) {
16051
- if(bScatterplot) {
16052
- //heightFinal -= 15;
16053
- html += this.drawScatterplot_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, undefined, "Interactions in structure " + strucArray[i], textHeight);
16054
- //heightFinal = 15;
16055
- height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16056
- } else {
16057
- html += this.drawLineGraph_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, "Interactions in structure " + strucArray[i], textHeight);
16058
- }
16059
- heightFinal += height;
16097
+ let result, heightFinal = 0;
16098
+
16099
+ bCommonDiff = 0; // 0: all interactions, 1: common interactions, 2: different interactions
16100
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1Split, nodeArray2Split, linkArraySplit, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16060
16101
 
16061
- if(i > 0) ic.lineGraphStr += ', \n';
16062
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i, nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i]);
16063
- }
16102
+ heightFinal = result.heightFinal;
16103
+ html += result.html;
16064
16104
 
16065
- // draw common interaction
16066
- for(let i = 0, il = structureArray.length; i < il; ++i) {
16067
- if(bScatterplot) {
16068
- //heightFinal -= 15;
16069
- html += this.drawScatterplot_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, undefined, "Common interactions in structure " + strucArray[i], textHeight);
16070
- //heightFinal = 15;
16071
- height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16072
- } else {
16073
- html += this.drawLineGraph_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, "Common interactions in structure " + strucArray[i], textHeight);
16074
- }
16075
- heightFinal += height;
16105
+ bCommonDiff = 1;
16106
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1SplitCommon, nodeArray2SplitCommon, linkArraySplitCommon, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16076
16107
 
16077
- //if(i > 0) ic.lineGraphStr += ', \n';
16078
- ic.lineGraphStr += ', \n';
16079
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i + '_common', nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i]);
16080
- }
16108
+ heightFinal = result.heightFinal;
16109
+ html += result.html;
16110
+
16111
+ bCommonDiff = 2;
16112
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1SplitDiff, nodeArray2SplitDiff, linkArraySplitDiff, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16081
16113
 
16114
+ heightFinal = result.heightFinal;
16115
+ html += result.html;
16116
+
16082
16117
  html += "</svg>";
16083
16118
  } else {
16084
16119
  if(!bScatterplot) {
@@ -16136,6 +16171,45 @@ class LineGraph {
16136
16171
  return html;
16137
16172
  }
16138
16173
 
16174
+ drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1, nodeArray2, linkArray, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY) { let ic = this.icn3d; ic.icn3dui;
16175
+ let html = "";
16176
+
16177
+ // draw common interaction
16178
+ let label, postfix;
16179
+ if(bCommonDiff == 0) {
16180
+ label = "Interactions in ";
16181
+ postfix = "";
16182
+ }
16183
+ else if(bCommonDiff == 1) {
16184
+ label = "Common interactions in ";
16185
+ postfix = "_common";
16186
+ }
16187
+ else if(bCommonDiff == 2) {
16188
+ label = "Different interactions in ";
16189
+ postfix = "_diff";
16190
+ }
16191
+
16192
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
16193
+ if(bScatterplot) {
16194
+ html += this.drawScatterplot_base(nodeArray1[i], nodeArray2[i], linkArray[i], name2node, heightFinal, undefined, label + structureArray[i], textHeight);
16195
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16196
+ } else {
16197
+ html += this.drawLineGraph_base(nodeArray1[i], nodeArray2[i], linkArray[i], name2node, heightFinal, label + structureArray[i], textHeight);
16198
+ }
16199
+ heightFinal += height;
16200
+
16201
+ if(bCommonDiff) { // very beginning
16202
+ if(i > 0) ic.lineGraphStr += ', \n';
16203
+ }
16204
+ else {
16205
+ ic.lineGraphStr += ', \n';
16206
+ }
16207
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(structureArray[i], i + postfix, nodeArray1[i], nodeArray2[i], linkArray[i]);
16208
+ }
16209
+
16210
+ return {"heightFinal": heightFinal, "html": html};
16211
+ }
16212
+
16139
16213
  getIdArrayFromNode(node) { let ic = this.icn3d, me = ic.icn3dui;
16140
16214
  let idArray = []; // 1_1_1KQ2_A_1
16141
16215
  idArray.push('');
@@ -16168,7 +16242,7 @@ class LineGraph {
16168
16242
  // draw label
16169
16243
  if(label) {
16170
16244
  height += textHeight;
16171
- html += "<text x='" + margin1 + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16245
+ html += "<text x='" + margin + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16172
16246
  }
16173
16247
 
16174
16248
  let h1 = 30 + height,
@@ -16226,7 +16300,7 @@ class LineGraph {
16226
16300
  return html;
16227
16301
  }
16228
16302
 
16229
- drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight) { let ic = this.icn3d; ic.icn3dui;
16303
+ drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight, bAfMap) { let ic = this.icn3d; ic.icn3dui;
16230
16304
  let html = '';
16231
16305
  let len1 = nodeArray1.length,
16232
16306
  len2 = nodeArray2.length;
@@ -16252,12 +16326,12 @@ class LineGraph {
16252
16326
  node2posSet2 = {};
16253
16327
  let x = legendWidth + marginX;
16254
16328
  for(let i = 0; i < len1; ++i) {
16255
- nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true);
16329
+ nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true, undefined, bAfMap);
16256
16330
  node2posSet1[nodeArray1[i].id] = { x: x, y: margin1 - i *(r + gap) };
16257
16331
  }
16258
16332
  let y = height + heightTotal -(legendWidth + marginY);
16259
16333
  for(let i = 0; i < len2; ++i) {
16260
- nodeHtml += ic.getGraphCls.drawResNode(nodeArray2[i], i, r, gap, margin2, y, 'b', false, bContactMap);
16334
+ nodeHtml += ic.getGraphCls.drawResNode(nodeArray2[i], i, r, gap, margin2, y, 'b', false, bContactMap, bAfMap);
16261
16335
  node2posSet2[nodeArray2[i].id] = { x: margin2 + i *(r + gap), y: y };
16262
16336
  }
16263
16337
  for(let i = 0, il = linkArray.length; i < il; ++i) {
@@ -16267,10 +16341,10 @@ class LineGraph {
16267
16341
 
16268
16342
  if(!node1 || !node2) continue;
16269
16343
 
16270
- html += this.drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap);
16344
+ html += this.drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap);
16271
16345
 
16272
- if(bContactMap) { // draw symmetric contact map
16273
- html += this.drawOnePairNode(link, node2, node1, node2posSet1, node2posSet2, bContactMap);
16346
+ if(bContactMap && !bAfMap) { // draw symmetric contact map, bAfmap just need to draw once
16347
+ html += this.drawOnePairNode(link, node2, node1, node2posSet1, node2posSet2, bContactMap, bAfMap);
16274
16348
  }
16275
16349
  }
16276
16350
  // show nodes later
@@ -16278,7 +16352,7 @@ class LineGraph {
16278
16352
  return html;
16279
16353
  }
16280
16354
 
16281
- drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap) { let ic = this.icn3d, me = ic.icn3dui;
16355
+ drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap) { let ic = this.icn3d, me = ic.icn3dui;
16282
16356
  let html = '';
16283
16357
 
16284
16358
  let factor = 1;
@@ -16308,21 +16382,36 @@ class LineGraph {
16308
16382
  strokecolor = "#" + me.htmlCls.contactColor;
16309
16383
  }
16310
16384
 
16385
+ if(bContactMap) strokecolor = "#" + link.c;
16386
+
16311
16387
  let linestrokewidth;
16312
16388
  if(link.v == me.htmlCls.contactValue) {
16313
16389
  linestrokewidth = 1;
16314
16390
  } else {
16315
16391
  linestrokewidth = 2;
16316
16392
  }
16317
- html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
16318
- html += "<title>Interaction of residue " + node1.id + " with residue " + node2.id + "</title>";
16319
- if(bContactMap) {
16320
- html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16393
+
16394
+ if(bAfMap && ic.hex2skip[link.c]) ;
16395
+ else if(bAfMap && ic.hex2id[link.c]) {
16396
+ ic.hex2id[link.c];
16397
+ // html += "<use href='#" + id + "' x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' />";
16398
+
16399
+ //html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
16400
+ //html += "<title>Interaction of residue " + node1.id + " with residue " + node2.id + "</title>";
16401
+ html += "<rect class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16402
+ //html += "</g>";
16321
16403
  }
16322
16404
  else {
16323
- 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 + "' />";
16405
+ html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
16406
+ html += "<title>Interaction of residue " + node1.id + " with residue " + node2.id + "</title>";
16407
+ if(bContactMap) {
16408
+ html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16409
+ }
16410
+ else {
16411
+ 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 + "' />";
16412
+ }
16413
+ html += "</g>";
16324
16414
  }
16325
- html += "</g>";
16326
16415
 
16327
16416
  return html;
16328
16417
  }
@@ -19274,19 +19363,19 @@ class Scap {
19274
19363
  //snp: 6M0J_E_484_K,6M0J_E_501_Y,6M0J_E_417_N
19275
19364
  let snpStr = '';
19276
19365
  let snpArray = snp.split(','); //stru_chain_resi_snp
19277
- let atomHash = {}, residArray = [];
19366
+ let atomHash = {}, snpResidArray = [];
19278
19367
  for(let i = 0, il = snpArray.length; i < il; ++i) {
19279
19368
  let idArray = snpArray[i].split('_'); //stru_chain_resi_snp
19280
19369
 
19281
19370
  let resid = idArray[0] + '_' + idArray[1] + '_' + idArray[2];
19282
19371
  atomHash = me.hashUtilsCls.unionHash(atomHash, ic.residues[resid]);
19283
- residArray.push(resid);
19372
+ snpResidArray.push(resid);
19284
19373
 
19285
19374
  snpStr += idArray[1] + '_' + idArray[2] + '_' + idArray[3];
19286
19375
  if(i != il -1) snpStr += ',';
19287
19376
  }
19288
19377
 
19289
- let selectSpec = ic.resid2specCls.residueids2spec(residArray);
19378
+ let selectSpec = ic.resid2specCls.residueids2spec(snpResidArray);
19290
19379
  let select = "select " + selectSpec;
19291
19380
 
19292
19381
  let bGetPairs = false;
@@ -19295,7 +19384,7 @@ class Scap {
19295
19384
  let result = ic.showInterCls.pickCustomSphere_base(radius, atomHash, ic.atoms, false, false, undefined, select, bGetPairs);
19296
19385
 
19297
19386
 
19298
- residArray = Object.keys(result.residues);
19387
+ let residArray = Object.keys(result.residues);
19299
19388
  ic.hAtoms = {};
19300
19389
  for(let index = 0, indexl = residArray.length; index < indexl; ++index) {
19301
19390
  let residueid = residArray[index];
@@ -19342,6 +19431,18 @@ class Scap {
19342
19431
  let bAddition = true;
19343
19432
  let hAtom1 = me.hashUtilsCls.cloneHash(ic.hAtoms);
19344
19433
 
19434
+ // the wild type is the reference
19435
+ for(let serial in hAtom1) {
19436
+ let atom = ic.atoms[serial];
19437
+ let chainid = atom.structure + '_' + atom.chain;
19438
+ let resid = chainid + '_' + atom.resi;
19439
+
19440
+ if(!ic.chainsMapping.hasOwnProperty(chainid)) {
19441
+ ic.chainsMapping[chainid] = {};
19442
+ }
19443
+ ic.chainsMapping[chainid][resid] = me.utilsCls.residueName2Abbr(atom.resn) + atom.resi;
19444
+ }
19445
+
19345
19446
  ic.hAtoms = {};
19346
19447
  ic.loadPDBCls.loadPDB(pdbData, pdbid, false, false, bAddition);
19347
19448
  let hAtom2 = me.hashUtilsCls.cloneHash(ic.hAtoms);
@@ -19354,17 +19455,31 @@ class Scap {
19354
19455
 
19355
19456
  ic.opts['color'] = 'chain';
19356
19457
  ic.setColorCls.setColorByOptions(ic.opts, ic.dAtoms);
19357
-
19358
19458
  for(let serial in hAtom2) {
19359
19459
  let atom = ic.atoms[serial];
19360
19460
  if(!atom.het) {
19361
19461
  // use the same color as the wild type
19362
- let resid = atom.structure.substr(0, 4) + '_' + atom.chain + '_' + atom.resi;
19462
+ let resid = atom.structure.substr(0, atom.structure.length - 1) + '_' + atom.chain + '_' + atom.resi;
19363
19463
 
19364
19464
  let atomWT = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
19365
19465
  ic.atoms[serial].color = atomWT.color;
19366
19466
  ic.atomPrevColors[serial] = atomWT.color;
19367
19467
  }
19468
+
19469
+ let chainid = atom.structure + '_' + atom.chain;
19470
+ let resid = chainid + '_' + atom.resi;
19471
+ let residWT = atom.structure.substr(0, atom.structure.length - 1) + '_' + atom.chain + '_' + atom.resi;
19472
+
19473
+ if(!ic.chainsMapping.hasOwnProperty(chainid)) {
19474
+ ic.chainsMapping[chainid] = {};
19475
+ }
19476
+ ic.chainsMapping[chainid][resid] = me.utilsCls.residueName2Abbr(atom.resn) + atom.resi;
19477
+ // use the wild type as reference
19478
+
19479
+ if(snpResidArray.indexOf(residWT) != -1) {
19480
+ let atomWT = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[residWT]);
19481
+ ic.chainsMapping[chainid][resid] = me.utilsCls.residueName2Abbr(atomWT.resn) + atomWT.resi;
19482
+ }
19368
19483
  }
19369
19484
 
19370
19485
  if(bPdb) {
@@ -20914,6 +21029,7 @@ class LoadAtomData {
20914
21029
  let serial = serialBase;
20915
21030
 
20916
21031
  let serial2structure = {}; // for "align" only
21032
+ let mmdbid2pdbid = {}; // for "align" only
20917
21033
 
20918
21034
  if(alignType === undefined || alignType === 'target') {
20919
21035
  ic.pmid = data.pubmedId;
@@ -20942,10 +21058,11 @@ class LoadAtomData {
20942
21058
  }
20943
21059
 
20944
21060
  let pdbidTmp = structure.pdbId;
20945
- structure.mmdbId;
21061
+ let mmdbidTmp = structure.mmdbId;
20946
21062
 
20947
21063
  for(let j = structure.serialInterval[0], jl = structure.serialInterval[1]; j <= jl; ++j) {
20948
21064
  serial2structure[j] = pdbidTmp.toString();
21065
+ mmdbid2pdbid[mmdbidTmp] = pdbidTmp;
20949
21066
  }
20950
21067
 
20951
21068
  for(let j = 0, jl = structure.molecules.length; j < jl; ++j) {
@@ -23282,11 +23399,11 @@ class AlignParser {
23282
23399
  ic.alignmolid2color.push(tmpHash);
23283
23400
  }
23284
23401
 
23285
- //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];
23286
- //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];
23402
+ //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];
23403
+ //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];
23287
23404
  // need the parameter moleculeInfor
23288
- 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];
23289
- 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];
23405
+ 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];
23406
+ 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];
23290
23407
 
23291
23408
  let d3 = $.ajax({
23292
23409
  url: url3,
@@ -23745,7 +23862,7 @@ class MmdbParser {
23745
23862
  }
23746
23863
 
23747
23864
  let molid2rescount = data.moleculeInfor;
23748
- let molid2chain = {};
23865
+ let molid2color = {}, chain2molid = {}, molid2chain = {};
23749
23866
  let chainNameHash = {};
23750
23867
  for(let i in molid2rescount) {
23751
23868
  if(Object.keys(molid2rescount[i]).length === 0) continue;
@@ -23761,6 +23878,9 @@ class MmdbParser {
23761
23878
 
23762
23879
  let chainNameFinal =(chainNameHash[chainName] === 1) ? chainName : chainName + chainNameHash[chainName].toString();
23763
23880
  let chain = id + '_' + chainNameFinal;
23881
+
23882
+ molid2color[i] = color;
23883
+ chain2molid[chain] = i;
23764
23884
  molid2chain[i] = chain;
23765
23885
 
23766
23886
  ic.chainsColor[chain] =(type !== undefined) ? me.parasCls.thr(me.htmlCls.GREY8) : me.parasCls.thr(color);
@@ -23821,14 +23941,14 @@ class MmdbParser {
23821
23941
  // b: b-factor, s: water, ft: pdbsite
23822
23942
  //&ft=1
23823
23943
  if(bGi) {
23824
- 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;
23944
+ 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;
23825
23945
  }
23826
23946
  else {
23827
- 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;
23828
- }
23947
+ 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;
23948
+ }
23829
23949
 
23830
- // 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
23831
- if(me.cfg.blast_rep_id !== undefined) url += '&buidx=0';
23950
+ // 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
23951
+ if(me.cfg.blast_rep_id !== undefined) url += '&bu=0';
23832
23952
 
23833
23953
  ic.bCid = undefined;
23834
23954
 
@@ -23923,13 +24043,13 @@ class MmdbParser {
23923
24043
  }
23924
24044
 
23925
24045
  downloadMmdbPart2(type) { let ic = this.icn3d, me = ic.icn3dui;
23926
- if(ic.bAssemblyUseAsu) { // set up symmetric matrices
24046
+ if(ic.bAssemblyUseAsu) {
23927
24047
  $("#" + ic.pre + "assemblyWrapper").show();
23928
- ic.bAssembly = true;
24048
+ //ic.bAssembly = true;
23929
24049
  }
23930
24050
  else {
23931
24051
  $("#" + ic.pre + "assemblyWrapper").hide();
23932
- ic.bAssembly = false;
24052
+ //ic.bAssembly = false;
23933
24053
  }
23934
24054
 
23935
24055
  if(ic.emd !== undefined) {
@@ -24084,7 +24204,7 @@ class MmdbParser {
24084
24204
  } // for each domainArray
24085
24205
  } // for each molid
24086
24206
 
24087
- // "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
24207
+ // "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
24088
24208
  ic.bAssemblyUseAsu =(data.asuAtomCount !== undefined) ? true : false;
24089
24209
  if(type !== undefined) {
24090
24210
  ic.bAssemblyUseAsu = false;
@@ -24710,7 +24830,7 @@ class ChainalignParser {
24710
24830
  let pos1 = alignArray[0].indexOf('_');
24711
24831
  ic.mmdbid_t = alignArray[0].substr(0, pos1).toUpperCase();
24712
24832
  ic.chain_t = alignArray[0].substr(pos1+1);
24713
- 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;
24833
+ 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;
24714
24834
  if(me.cfg.inpara !== undefined) url_t += me.cfg.inpara;
24715
24835
 
24716
24836
  let ajaxArray = [];
@@ -24736,7 +24856,7 @@ class ChainalignParser {
24736
24856
  let chainalignFinal = ic.mmdbid_q + "_" + ic.chain_q + "," + ic.mmdbid_t + "_" + ic.chain_t;
24737
24857
 
24738
24858
  let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?chainpairs=" + chainalignFinal;
24739
- 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;
24859
+ 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;
24740
24860
 
24741
24861
  if(me.cfg.inpara !== undefined) url_q += me.cfg.inpara;
24742
24862
 
@@ -26613,6 +26733,32 @@ class LoadScript {
26613
26733
 
26614
26734
  return;
26615
26735
  }
26736
+ else if(ic.commands[i].trim().indexOf('set half pae map') == 0) {
26737
+ let strArray = ic.commands[i].split("|||");
26738
+ let command = strArray[0].trim();
26739
+
26740
+ $.when(thisClass.applyCommandAfmap(command)).then(function() {
26741
+ //if(!me.cfg.notebook && dialog && dialog.hasClass("ui-dialog-content")) dialog.dialog( "close" );
26742
+
26743
+ //ic.drawCls.draw();
26744
+ thisClass.execCommandsBase(i + 1, end, steps);
26745
+ });
26746
+
26747
+ return;
26748
+ }
26749
+ else if(ic.commands[i].trim().indexOf('set full pae map') == 0) {
26750
+ let strArray = ic.commands[i].split("|||");
26751
+ let command = strArray[0].trim();
26752
+
26753
+ $.when(thisClass.applyCommandAfmap(command, true)).then(function() {
26754
+ //if(!me.cfg.notebook && dialog && dialog.hasClass("ui-dialog-content")) dialog.dialog( "close" );
26755
+
26756
+ //ic.drawCls.draw();
26757
+ thisClass.execCommandsBase(i + 1, end, steps);
26758
+ });
26759
+
26760
+ return;
26761
+ }
26616
26762
  else {
26617
26763
  ic.applyCommandCls.applyCommand(ic.commands[i]);
26618
26764
  }
@@ -26807,13 +26953,13 @@ class LoadScript {
26807
26953
  }
26808
26954
  else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
26809
26955
  me.cfg.mmdbid = id;
26810
- me.cfg.buidx = 1;
26956
+ me.cfg.bu = 1;
26811
26957
 
26812
26958
  ic.mmdbParserCls.downloadMmdb(id);
26813
26959
  }
26814
26960
  else if(command.indexOf('load mmdb0') !== -1) {
26815
26961
  me.cfg.mmdbid = id;
26816
- me.cfg.buidx = 0;
26962
+ me.cfg.bu = 0;
26817
26963
 
26818
26964
  ic.mmdbParserCls.downloadMmdb(id);
26819
26965
  }
@@ -26946,6 +27092,23 @@ class LoadScript {
26946
27092
  return ic.deferredRealign.promise();
26947
27093
  }
26948
27094
 
27095
+ applyCommandAfmapBase(command, bFull) { let ic = this.icn3d; ic.icn3dui;
27096
+ let afid = command.substr(command.lastIndexOf(' ') + 1);
27097
+
27098
+ ic.contactMapCls.afErrorMap(afid, bFull);
27099
+ }
27100
+
27101
+ applyCommandAfmap(command, bFull) { let ic = this.icn3d; ic.icn3dui;
27102
+ let thisClass = this;
27103
+
27104
+ // chain functions together
27105
+ ic.deferredAfmap = new $.Deferred(function() {
27106
+ thisClass.applyCommandAfmapBase(command, bFull);
27107
+ }); // end of me.deferred = $.Deferred(function() {
27108
+
27109
+ return ic.deferredAfmap.promise();
27110
+ }
27111
+
26949
27112
  applyCommandGraphinteractionBase(command) { let ic = this.icn3d; ic.icn3dui;
26950
27113
  let paraArray = command.split(' | ');
26951
27114
  if(paraArray.length >= 3) {
@@ -28220,14 +28383,14 @@ class AddTrack {
28220
28383
 
28221
28384
  let strand, itemRgb;
28222
28385
 
28223
- if(fieldArray.length > 4) fieldArray[4];
28386
+ if(fieldArray.length > 4) ;
28224
28387
  if(fieldArray.length > 5) strand = fieldArray[5]; // ., +, or -
28225
- if(fieldArray.length > 6) fieldArray[6];
28226
- if(fieldArray.length > 7) fieldArray[7];
28388
+ if(fieldArray.length > 6) ;
28389
+ if(fieldArray.length > 7) ;
28227
28390
  if(fieldArray.length > 8) itemRgb = fieldArray[8];
28228
- if(fieldArray.length > 9) fieldArray[9];
28229
- if(fieldArray.length > 10) fieldArray[10];
28230
- if(fieldArray.length > 11) fieldArray[11];
28391
+ if(fieldArray.length > 9) ;
28392
+ if(fieldArray.length > 10) ;
28393
+ if(fieldArray.length > 11) ;
28231
28394
 
28232
28395
  let title = trackName;
28233
28396
 
@@ -30941,6 +31104,14 @@ class ApplyCommand {
30941
31104
 
30942
31105
  $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
30943
31106
  }
31107
+ else if(command.indexOf('alignerrormap scale') == 0) {
31108
+ let pos = command.lastIndexOf(' ');
31109
+ let scale = command.substr(pos + 1);
31110
+
31111
+ $("#" + me.alignerrormapid + "_scale").val(scale);
31112
+
31113
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
31114
+ }
30944
31115
  else if(command.indexOf('graph force') == 0) {
30945
31116
  let pos = command.lastIndexOf(' ');
30946
31117
  me.htmlCls.force = parseInt(command.substr(pos + 1));
@@ -33880,7 +34051,7 @@ class MmcifParser {
33880
34051
 
33881
34052
  // not all listed residues are considered missing, e.g., PDB ID 4OR2, only the firts four residues are considered missing
33882
34053
  if(!isNaN(resi) &&(prevMissingChain == '' ||(chain != prevMissingChain) ||(chain == prevMissingChain && resi > maxMissingResi)) ) {
33883
- chainMissingResidueArray[chainNum].push(resObject);
34054
+ ic.chainMissingResidueArray[chainNum].push(resObject);
33884
34055
 
33885
34056
  maxMissingResi = resi;
33886
34057
  prevMissingChain = chain;
@@ -33957,7 +34128,7 @@ class MmcifParser {
33957
34128
  }
33958
34129
  }
33959
34130
 
33960
- loadMmcifSymmetry(assembly) { let ic = this.icn3d; ic.icn3dui;
34131
+ loadMmcifSymmetry(assembly) { let ic = this.icn3d, me = ic.icn3dui;
33961
34132
  // load assembly info
33962
34133
  //var assembly = data.assembly;
33963
34134
  //var pmatrix = data.pmatrix;
@@ -33970,6 +34141,11 @@ class MmcifParser {
33970
34141
  }
33971
34142
 
33972
34143
  ic.asuCnt = ic.biomtMatrices.length;
34144
+
34145
+ // show bioassembly
34146
+ if(me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.asuCnt > ic.maxatomcnt) {
34147
+ ic.bAssembly = true;
34148
+ }
33973
34149
  }
33974
34150
 
33975
34151
  loadMmcifOpmDataPart2(data, pdbid) { let ic = this.icn3d, me = ic.icn3dui;
@@ -37640,6 +37816,18 @@ class Diagram2d {
37640
37816
  ic.bSelectResidue = false;
37641
37817
  */
37642
37818
  });
37819
+
37820
+ $(document).on("click", "#" + ic.pre + "dl_alignerrormap .icn3d-interaction", function(e) { thisClass.icn3d;
37821
+ e.stopImmediatePropagation();
37822
+
37823
+ thisClass.clickInteraction(this);
37824
+ });
37825
+
37826
+ $(document).on("click", "#" + ic.pre + "dl_alignerrormap .icn3d-node", function(e) { thisClass.icn3d;
37827
+ e.stopImmediatePropagation();
37828
+
37829
+ thisClass.clickNode(this);
37830
+ });
37643
37831
  }
37644
37832
 
37645
37833
  clickNode(node) { let ic = this.icn3d, me = ic.icn3dui;
@@ -38791,7 +38979,7 @@ class Selection {
38791
38979
  }
38792
38980
 
38793
38981
  toggleMembrane(bShowMembrane) {var ic = this.icn3d, me = ic.icn3dui;
38794
- let structureArray = Object.keys(ic.structures);
38982
+ let structureArray = (ic.structures) ? Object.keys(ic.structures) : [];
38795
38983
 
38796
38984
  for(let i = 0, il = structureArray.length; i < il; ++i) {
38797
38985
  let structure = structureArray[i];
@@ -39875,7 +40063,6 @@ class ApplyDisplay {
39875
40063
 
39876
40064
  //Apply style and label options to a certain set of atoms.
39877
40065
  applyDisplayOptions(options, atoms, bHighlight) { let ic = this.icn3d, me = ic.icn3dui;
39878
- if(options === undefined) options = ic.opts;
39879
40066
 
39880
40067
  // get parameters from cookies
39881
40068
  if(!me.bNode && me.htmlCls.setHtmlCls.getCookie('lineRadius') != '') {
@@ -42377,7 +42564,12 @@ class Draw {
42377
42564
  ic.setColorCls.applyPrevColor();
42378
42565
 
42379
42566
  if(ic.biomtMatrices !== undefined && ic.biomtMatrices.length > 1) {
42380
- if(ic.bAssembly && Object.keys(ic.structures).length == 1) {
42567
+ // show bioassembly in two cases
42568
+ // 1. asymmetric unit: me.cfg.bu == 0
42569
+ // 2. biological unit with less than ic.maxatomcnt atom:
42570
+ // me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.biomtMatrices.length < ic.maxatomcnt
42571
+ if(ic.bAssembly && Object.keys(ic.structures).length == 1 && (me.cfg.bu == 0
42572
+ || (me.cfg.bu == 1 && Object.keys(ic.atoms).length * ic.biomtMatrices.length > ic.maxatomcnt)) ) {
42381
42573
  ic.instancingCls.drawSymmetryMates();
42382
42574
  }
42383
42575
  else {
@@ -42911,20 +43103,29 @@ class SaveFile {
42911
43103
  }
42912
43104
  }
42913
43105
 
42914
- saveSvg(id, filename) { let ic = this.icn3d; ic.icn3dui;
42915
- let svg = this.getSvgXml(id);
43106
+ saveSvg(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
43107
+ if(me.bNode) return '';
43108
+
43109
+ let width = $("#" + id).width();
43110
+ let height = $("#" + id).height();
43111
+
43112
+ if(bContactmap) height = width;
43113
+
43114
+ let svgXml = this.getSvgXml(id, width, height, bContactmap);
42916
43115
 
42917
- let blob = new Blob([svg], {type: "image/svg+xml"});
43116
+ let blob = new Blob([svgXml], {type: "image/svg+xml"});
42918
43117
  saveAs(blob, filename);
42919
43118
  }
42920
43119
 
42921
- getSvgXml(id) { let ic = this.icn3d, me = ic.icn3dui;
43120
+ getSvgXml(id, width, height, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
42922
43121
  if(me.bNode) return '';
42923
43122
 
42924
43123
  // font is not good
42925
43124
  let svg_data = document.getElementById(id).innerHTML; //put id of your svg element here
42926
43125
 
42927
- 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/\">";
43126
+ let viewbox = (width && height) ? "<svg viewBox=\"0 0 " + width + " " + height + "\"" : "<svg";
43127
+ //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/\">";
43128
+ 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/\">";
42928
43129
 
42929
43130
  //if you have some additional styling like graph edges put them inside <style> tag
42930
43131
  let style = "<style>text {font-family: sans-serif; font-weight: bold; font-size: 18px;}</style>";
@@ -42934,9 +43135,14 @@ class SaveFile {
42934
43135
  return full_svg;
42935
43136
  }
42936
43137
 
42937
- savePng(id, filename, width, height) { let ic = this.icn3d, me = ic.icn3dui;
43138
+ savePng(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
42938
43139
  if(me.bNode) return '';
42939
43140
 
43141
+ let width = $("#" + id).width();
43142
+ let height = $("#" + id).height();
43143
+
43144
+ if(bContactmap) height = width;
43145
+
42940
43146
  // https://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-the-browser
42941
43147
  let svg = document.getElementById(id);
42942
43148
  let bbox = svg.getBBox();
@@ -42950,7 +43156,7 @@ class SaveFile {
42950
43156
  let ctx = canvas.getContext("2d");
42951
43157
  ctx.clearRect(0, 0, bbox.width, bbox.height);
42952
43158
 
42953
- let data = this.getSvgXml(id); //(new XMLSerializer()).serializeToString(copy); //ic.saveFileCls.getSvgXml();
43159
+ let data = this.getSvgXml(id, width, height, bContactmap); //(new XMLSerializer()).serializeToString(copy); //ic.saveFileCls.getSvgXml();
42954
43160
  let DOMURL = window.URL || window.webkitURL || window;
42955
43161
  let svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
42956
43162
 
@@ -43662,6 +43868,10 @@ class ClickMenu {
43662
43868
  me.myEventCls.onIds("#" + me.pre + "mn1_xyzfile", "click", function(e) { me.icn3d;
43663
43869
  me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ File');
43664
43870
  });
43871
+
43872
+ me.myEventCls.onIds("#" + me.pre + "mn1_afmapfile", "click", function(e) { me.icn3d;
43873
+ me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold PAE File');
43874
+ });
43665
43875
  // },
43666
43876
  // clkMn1_urlfile: function() {
43667
43877
  me.myEventCls.onIds("#" + me.pre + "mn1_urlfile", "click", function(e) { me.icn3d;
@@ -46035,6 +46245,8 @@ class SetMenu {
46035
46245
  html += me.htmlCls.setHtmlCls.getLink('mn1_mol2file', 'Mol2 File');
46036
46246
  html += me.htmlCls.setHtmlCls.getLink('mn1_sdffile', 'SDF File');
46037
46247
  html += me.htmlCls.setHtmlCls.getLink('mn1_xyzfile', 'XYZ File');
46248
+ html += me.htmlCls.setHtmlCls.getLink('mn1_afmapfile', 'AlphaFold PAE File');
46249
+
46038
46250
  if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46039
46251
  html += "<li>-</li>";
46040
46252
  html += me.htmlCls.setHtmlCls.getLink('mn1_pngimage', 'iCn3D PNG Image');
@@ -47147,8 +47359,14 @@ class SetMenu {
47147
47359
  html += "<li id='" + me.pre + "assemblyWrapper'><span>Assembly</span>";
47148
47360
  html += "<ul>";
47149
47361
 
47150
- html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly');
47151
- html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit', true);
47362
+ if(me.cfg.bu == 0) {
47363
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly');
47364
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit', true);
47365
+ }
47366
+ else {
47367
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyYes', 'Biological Assembly', true);
47368
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_assembly', 'mn6_assemblyNo', 'Asymmetric Unit');
47369
+ }
47152
47370
 
47153
47371
  html += "</ul>";
47154
47372
  html += "</li>";
@@ -47392,6 +47610,7 @@ class Dialog {
47392
47610
  let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
47393
47611
  let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
47394
47612
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
47613
+ let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
47395
47614
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
47396
47615
  let bAlignmentInit = $('#' + me.pre + 'dl_alignment').hasClass('ui-dialog-content'); // initialized
47397
47616
  let bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
@@ -47407,6 +47626,7 @@ class Dialog {
47407
47626
  if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
47408
47627
  if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
47409
47628
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
47629
+ if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
47410
47630
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
47411
47631
  if(bAlignmentInit) status.bAlignmentInit2 = $('#' + me.pre + 'dl_alignment').dialog( 'isOpen' );
47412
47632
  if(bTwoddgmInit) status.bTwoddgmInit2 = $('#' + me.pre + 'dl_2ddgm').dialog( 'isOpen' );
@@ -47451,13 +47671,14 @@ class Dialog {
47451
47671
  close: function(e) {
47452
47672
  let status = thisClass.getDialogStatus();
47453
47673
 
47454
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47455
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47456
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47457
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47458
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bScatterplot2 && !status.bContactmap2)
47459
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bContactmap2)
47460
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2)
47674
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47675
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47676
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47677
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47678
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47679
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bContactmap2 && !status.bAlignerrormap2)
47680
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bAlignerrormap2)
47681
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47461
47682
  ) {
47462
47683
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
47463
47684
  //ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH - twoddgmWidth, me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT, true);
@@ -47484,7 +47705,7 @@ class Dialog {
47484
47705
 
47485
47706
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
47486
47707
  }
47487
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap') {
47708
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
47488
47709
  //var bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
47489
47710
  //var bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
47490
47711
 
@@ -47507,6 +47728,10 @@ class Dialog {
47507
47728
  let width = ic.contactmapWidth * ratio;
47508
47729
  $("#" + me.contactmapid).attr("width", width);
47509
47730
  }
47731
+ else if(id == me.pre + 'dl_alignerrormap') {
47732
+ let width = ic.alignerrormapWidth * ratio;
47733
+ $("#" + me.alignerrormapid).attr("width", width);
47734
+ }
47510
47735
  }
47511
47736
  }
47512
47737
  });
@@ -47602,7 +47827,7 @@ class Dialog {
47602
47827
 
47603
47828
  let status = this.getDialogStatus();
47604
47829
 
47605
- 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') {
47830
+ 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') {
47606
47831
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
47607
47832
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
47608
47833
 
@@ -47638,13 +47863,14 @@ class Dialog {
47638
47863
  modal: false,
47639
47864
  position: position,
47640
47865
  close: function(e) {
47641
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47642
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47643
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47644
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47645
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47646
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2))
47647
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2))
47866
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47867
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47868
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47869
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47870
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47871
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47872
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bAlignerrormap2))
47873
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47648
47874
  ) {
47649
47875
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
47650
47876
  let canvasWidth = me.utilsCls.isMobile() ? me.htmlCls.WIDTH : me.htmlCls.WIDTH - twoddgmWidth;
@@ -47670,7 +47896,7 @@ class Dialog {
47670
47896
 
47671
47897
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
47672
47898
  }
47673
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap') {
47899
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
47674
47900
  //var bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
47675
47901
  //var bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
47676
47902
 
@@ -47693,6 +47919,10 @@ class Dialog {
47693
47919
  let width = ic.contactmapWidth * ratio;
47694
47920
  $("#" + me.contactmapid).attr("width", width);
47695
47921
  }
47922
+ else if(id == me.pre + 'dl_alignerrormap') {
47923
+ let width = ic.alignerrormapWidth * ratio;
47924
+ $("#" + me.alignerrormapid).attr("width", width);
47925
+ }
47696
47926
  }
47697
47927
  }
47698
47928
  });
@@ -47815,7 +48045,7 @@ class Dialog {
47815
48045
  let width = 400, height = 150;
47816
48046
  let twoddgmWidth = me.htmlCls.width2d + 20;
47817
48047
 
47818
- 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') {
48048
+ 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') {
47819
48049
  $( "#" + id ).show();
47820
48050
 
47821
48051
  height =(me.htmlCls.HEIGHT) * 0.5;
@@ -47853,6 +48083,11 @@ class Dialog {
47853
48083
 
47854
48084
  $("#" + me.contactmapid).attr("width", width);
47855
48085
  }
48086
+ else if(id == me.pre + 'dl_alignerrormap') {
48087
+ let width = ic.alignerrormapWidth * ratio;
48088
+
48089
+ $("#" + me.alignerrormapid).attr("width", width);
48090
+ }
47856
48091
  });
47857
48092
  }
47858
48093
  else {
@@ -47986,8 +48221,12 @@ class SetDialog {
47986
48221
  html += "Note: AlphaFold produces a per-residue confidence score (pLDDT) between 0 and 100:<br>";
47987
48222
  html += me.htmlCls.clickMenuCls.setAlphaFoldLegend() + "<br>";
47988
48223
 
47989
- 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> ";
47990
- html += me.htmlCls.buttonStr + "reload_af'>Load</button>";
48224
+ let afid = (me.cfg.afid) ? me.cfg.afid : 'Q76EI6';
48225
+
48226
+ 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>";
48227
+ html += me.htmlCls.buttonStr + "reload_af'>Load Structure</button>"
48228
+ + me.htmlCls.buttonStr + "reload_afmap' style='margin-left:30px'>Load Half PAE Map</button>"
48229
+ + me.htmlCls.buttonStr + "reload_afmapfull' style='margin-left:30px'>Load Full PAE Map (slow)</button>";
47991
48230
  html += "</div>";
47992
48231
 
47993
48232
  html += me.htmlCls.divStr + "dl_opmid' class='" + dialogClass + "'>";
@@ -48066,6 +48305,12 @@ class SetDialog {
48066
48305
  html += "<div style='width:500px'>";
48067
48306
  html += 'Please specify the mutations with a comma separated mutation list. Each mutation can be specified as "[PDB ID]_[Chain ID]_[Residue Number]_[One Letter Mutatnt Residue]". E.g., the mutation of N501Y in the E chain of PDB 6M0J can be specified as "6M0J_E_501_Y". <br/><br/>';
48068
48307
  html += "<div style='display:inline-block; width:110px'>Mutations: </div>" + me.htmlCls.inputTextStr + "id='" + me.pre + "mutationids' value='6M0J_E_484_K,6M0J_E_501_Y,6M0J_E_417_N' size=50><br/><br/>";
48308
+
48309
+ html += "<b>Data Source</b>: <select id='" + me.pre + "idsource'>";
48310
+ html += "<option value='mmdbid' selected>PDB ID</option>";
48311
+ html += "<option value='afid'>AlphaFold UniProt ID</option>";
48312
+ html += "</select><br/><br/>";
48313
+
48069
48314
  html += me.htmlCls.buttonStr + "reload_mutation_3d' title='Show the mutations in 3D using the scap program'>3D with scap</button>";
48070
48315
  html += me.htmlCls.buttonStr + "reload_mutation_inter' style='margin-left:20px' title='Show the mutations in 3D and the change of interactions'>Interactions</button>";
48071
48316
  html += me.htmlCls.buttonStr + "reload_mutation_pdb' style='margin-left:20px' title='Show the mutations in 3D and export the PDB of the mutant within 10 angstrom'>PDB</button>";
@@ -48083,6 +48328,13 @@ class SetDialog {
48083
48328
  html += "XYZ File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "xyzfile' size=8> ";
48084
48329
  html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
48085
48330
  html += "</div>";
48331
+
48332
+ html += me.htmlCls.divStr + "dl_afmapfile' class='" + dialogClass + "'>";
48333
+ html += "AlphaFold PAE File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "afmapfile' size=8> <br><br>";
48334
+ html += me.htmlCls.buttonStr + "reload_afmapfile'>Load Half PAE Map</button>"
48335
+ + me.htmlCls.buttonStr + "reload_afmapfilefull' style='margin-left:30px'>Load Full PAE Map (slow)</button>";
48336
+ html += "</div>";
48337
+
48086
48338
  html += me.htmlCls.divStr + "dl_urlfile' class='" + dialogClass + "'>";
48087
48339
  html += "File type: ";
48088
48340
  html += "<select id='" + me.pre + "filetype'>";
@@ -48106,9 +48358,16 @@ class SetDialog {
48106
48358
  html += me.htmlCls.buttonStr + "reload_mmcif'>Load</button>";
48107
48359
  html += "</div>";
48108
48360
 
48109
- html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "'>";
48361
+ html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "' style='max-width:500px'>";
48110
48362
  html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> <br><br>";
48111
- 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/>";
48363
+ 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>";
48364
+ 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="'
48365
+ + me.pre + 'asu_bu_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="width:15px;" title="Expand"></span><span id="'
48366
+ + me.pre + 'asu_bu_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="display:none; width:15px;" title="Shrink"></span></div>';
48367
+
48368
+ html += me.htmlCls.divStr + "asu_bu' style='display:none;'>";
48369
+ 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>';
48370
+
48112
48371
  html += "</div>";
48113
48372
 
48114
48373
  html += me.htmlCls.divStr + "dl_blast_rep_id' style='max-width:500px;' class='" + dialogClass + "'>";
@@ -48444,6 +48703,33 @@ class SetDialog {
48444
48703
 
48445
48704
  html += "</div>";
48446
48705
 
48706
+ html += me.htmlCls.divStr + "dl_alignerrormap' style='background-color:white' class='" + dialogClass + "'>";
48707
+
48708
+ html += me.htmlCls.divNowrapStr + "Hold Ctrl key to select multiple nodes." + me.htmlCls.space3 + "</div>";
48709
+
48710
+ me.alignerrormapid = me.pre + 'alignerrormap';
48711
+ html += me.htmlCls.divNowrapStr + buttonStrTmp + me.alignerrormapid + '_svg">SVG</button>' + me.htmlCls.space2;
48712
+ html += buttonStrTmp + me.alignerrormapid + '_png">PNG (slow)</button>' + me.htmlCls.space2;
48713
+ html += buttonStrTmp + me.alignerrormapid + '_json">JSON</button>' + me.htmlCls.space4;
48714
+ html += '<b>Scale</b>: <select id="' + me.alignerrormapid + '_scale">';
48715
+
48716
+ //let optArray5 = ['0.01', '0.02', '0.04', '0.06', '0.08', '0.1', '0.2', '0.4', '0.6', '0.8', '1'];
48717
+ html += me.htmlCls.setHtmlCls.getOptionHtml(optArray5, 2);
48718
+
48719
+ html += "</select></div><br>";
48720
+
48721
+ //min: 004d00, max: FFFFFF
48722
+ let startColorStr = '#004d00';
48723
+ let endColorStr = '#FFFFFF';
48724
+ let rangeStr = startColorStr + ' 0%, ' + endColorStr + ' 100%';
48725
+
48726
+ html += "<div style='width:200px'><div style='height: 12px; border: 1px solid #000; background: linear-gradient(to right, " + rangeStr + ");'></div>";
48727
+ 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>";
48728
+
48729
+ html += '<div id="' + me.pre + 'alignerrormapDiv"></div>';
48730
+
48731
+ html += "</div>";
48732
+
48447
48733
  html += me.htmlCls.divStr + "dl_elecmap2fofc' class='" + dialogClass + "'>";
48448
48734
  html += "<span style='white-space:nowrap;font-weight:bold;'>Contour at: <select id='" + me.pre + "sigma2fofc'>";
48449
48735
 
@@ -49178,6 +49464,25 @@ class Events {
49178
49464
  window.open(hostUrl + '?afid=' + $("#" + me.pre + "afid").val(), '_blank');
49179
49465
  });
49180
49466
 
49467
+ me.myEventCls.onIds("#" + me.pre + "reload_afmap", "click", function(e) { let ic = me.icn3d;
49468
+ e.preventDefault();
49469
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49470
+ let afid = me.cfg.afid ? me.cfg.afid : $("#" + me.pre + "afid").val();
49471
+
49472
+ me.htmlCls.clickMenuCls.setLogCmd("set half pae map " + afid, true);
49473
+
49474
+ ic.contactMapCls.afErrorMap(afid);
49475
+ });
49476
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfull", "click", function(e) { let ic = me.icn3d;
49477
+ e.preventDefault();
49478
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49479
+ let afid = me.cfg.afid ? me.cfg.afid : $("#" + me.pre + "afid").val();
49480
+
49481
+ me.htmlCls.clickMenuCls.setLogCmd("set full pae map " + afid, true);
49482
+
49483
+ ic.contactMapCls.afErrorMap(afid, true);
49484
+ });
49485
+
49181
49486
  me.myEventCls.onIds("#" + me.pre + "afid", "keyup", function(e) { me.icn3d;
49182
49487
  if (e.keyCode === 13) {
49183
49488
  e.preventDefault();
@@ -49211,23 +49516,23 @@ class Events {
49211
49516
  // },
49212
49517
  // clickReload_align_refined: function() {
49213
49518
  me.myEventCls.onIds("#" + me.pre + "reload_align_refined", "click", function(e) { me.icn3d;
49214
- e.preventDefault();
49215
- if(!me.cfg.notebook) dialog.dialog( "close" );
49216
- let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49217
- me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=1', false);
49218
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=1', '_blank');
49219
- window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=1', '_blank');
49220
- });
49519
+ e.preventDefault();
49520
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49521
+ let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49522
+ me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=1&bu=1', false);
49523
+ //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=1', '_blank');
49524
+ window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=1&bu=1', '_blank');
49525
+ });
49221
49526
  // },
49222
49527
  // clickReload_align_ori: function() {
49223
49528
  me.myEventCls.onIds("#" + me.pre + "reload_align_ori", "click", function(e) { me.icn3d;
49224
- e.preventDefault();
49225
- if(!me.cfg.notebook) dialog.dialog( "close" );
49226
- let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49227
- me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=0', false);
49228
- //window.open( me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=0', '_blank');
49229
- window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=0', '_blank');
49230
- });
49529
+ e.preventDefault();
49530
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49531
+ let alignment = $("#" + me.pre + "alignid1").val() + "," + $("#" + me.pre + "alignid2").val();
49532
+ me.htmlCls.clickMenuCls.setLogCmd("load alignment " + alignment + ' | parameters &atype=0&bu=1', false);
49533
+ //window.open( me.htmlCls.baseUrl + 'icn3d/full.html?align=' + alignment + '&showalignseq=1&atype=0', '_blank');
49534
+ window.open(hostUrl + '?align=' + alignment + '&showalignseq=1&atype=0&bu=1', '_blank');
49535
+ });
49231
49536
  // },
49232
49537
  // clickReload_chainalign: function() {
49233
49538
  me.myEventCls.onIds("#" + me.pre + "reload_chainalign", "click", function(e) { me.icn3d;
@@ -49261,34 +49566,37 @@ class Events {
49261
49566
  }
49262
49567
 
49263
49568
  me.htmlCls.clickMenuCls.setLogCmd("load chains " + alignment + " on asymmetric unit | residues " + resalign + " | resdef " + predefinedres, false);
49264
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&buidx=0', '_blank');
49265
- window.open(hostUrl + '?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&buidx=0', '_blank');
49569
+ //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&bu=0', '_blank');
49570
+ window.open(hostUrl + '?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&bu=0', '_blank');
49266
49571
  });
49267
49572
 
49268
49573
  me.myEventCls.onIds("#" + me.pre + "reload_mutation_3d", "click", function(e) { me.icn3d;
49269
49574
  e.preventDefault();
49270
49575
  if(!me.cfg.notebook) dialog.dialog( "close" );
49271
49576
  let mutationids = $("#" + me.pre + "mutationids").val();
49272
- let mmdbid = mutationids.substr(0, mutationids.indexOf('_'));
49577
+ let idsource = $("#" + me.pre + "idsource").val();
49578
+ let mmdbid = mutationids.substr(0, mutationids.indexOf('_'));
49273
49579
  me.htmlCls.clickMenuCls.setLogCmd("3d of mutation " + mutationids, false);
49274
49580
  //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + mmdbid + '&command=scap 3d ' + mutationids + '; select displayed set', '_blank');
49275
- window.open(hostUrl + '?mmdbid=' + mmdbid + '&command=scap 3d ' + mutationids + '; select displayed set', '_blank');
49581
+ window.open(hostUrl + '?' + idsource + '=' + mmdbid + '&command=scap 3d ' + mutationids + '; select displayed set', '_blank');
49276
49582
  });
49277
49583
 
49278
49584
  me.myEventCls.onIds("#" + me.pre + "reload_mutation_pdb", "click", function(e) { me.icn3d;
49279
49585
  e.preventDefault();
49280
49586
  if(!me.cfg.notebook) dialog.dialog( "close" );
49281
49587
  let mutationids = $("#" + me.pre + "mutationids").val();
49588
+ let idsource = $("#" + me.pre + "idsource").val();
49282
49589
  let mmdbid = mutationids.substr(0, mutationids.indexOf('_'));
49283
49590
  me.htmlCls.clickMenuCls.setLogCmd("pdb of mutation " + mutationids, false);
49284
49591
  //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + mmdbid + '&command=scap pdb ' + mutationids + '; select displayed set', '_blank');
49285
- window.open(hostUrl + '?mmdbid=' + mmdbid + '&command=scap pdb ' + mutationids + '; select displayed set', '_blank');
49592
+ window.open(hostUrl + '?' + idsource + '=' + mmdbid + '&command=scap pdb ' + mutationids + '; select displayed set', '_blank');
49286
49593
  });
49287
49594
 
49288
49595
  me.myEventCls.onIds("#" + me.pre + "reload_mutation_inter", "click", function(e) { let ic = me.icn3d;
49289
49596
  e.preventDefault();
49290
49597
  if(!me.cfg.notebook) dialog.dialog( "close" );
49291
49598
  let mutationids = $("#" + me.pre + "mutationids").val();
49599
+ let idsource = $("#" + me.pre + "idsource").val();
49292
49600
 
49293
49601
  let mutationArray = mutationids.split(',');
49294
49602
  let residArray = [];
@@ -49310,7 +49618,7 @@ class Events {
49310
49618
  me.htmlCls.clickMenuCls.setLogCmd("interaction change of mutation " + mutationids, false);
49311
49619
  //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + mmdbid + '&command=scap interaction ' + mutationids + '; select ' + selectSpec + ' | name test; line graph interaction pairs | selected non-selected | hbonds,salt bridge,interactions,halogen,pi-cation,pi-stacking | false | threshold 3.8 6 4 3.8 6 5.5; adjust dialog dl_linegraph; select displayed set', '_blank');
49312
49620
  //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + mmdbid + '&command=scap interaction ' + mutationids, '_blank');
49313
- window.open(hostUrl + '?mmdbid=' + mmdbid + '&command=scap interaction ' + mutationids, '_blank');
49621
+ window.open(hostUrl + '?' + idsource + '=' + mmdbid + '&command=scap interaction ' + mutationids, '_blank');
49314
49622
  });
49315
49623
 
49316
49624
  // },
@@ -49337,24 +49645,24 @@ class Events {
49337
49645
  // clickReload_mmdb: function() {
49338
49646
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb", "click", function(e) { me.icn3d;
49339
49647
  e.preventDefault();
49340
- if(!me.cfg.notebook) dialog.dialog( "close" );
49648
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49341
49649
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb1 " + $("#" + me.pre + "mmdbid").val(), false);
49342
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=1', '_blank');
49650
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=1', '_blank');
49343
49651
  });
49344
49652
 
49345
49653
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb_asym", "click", function(e) { me.icn3d;
49346
49654
  e.preventDefault();
49347
- if(!me.cfg.notebook) dialog.dialog( "close" );
49655
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49348
49656
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49349
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49657
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=0', '_blank');
49350
49658
  });
49351
49659
 
49352
49660
  me.myEventCls.onIds("#" + me.pre + "mmdbid", "keyup", function(e) { me.icn3d;
49353
49661
  if (e.keyCode === 13) {
49354
49662
  e.preventDefault();
49355
- if(!me.cfg.notebook) dialog.dialog( "close" );
49663
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49356
49664
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49357
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49665
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=0', '_blank');
49358
49666
  }
49359
49667
  });
49360
49668
 
@@ -49740,6 +50048,64 @@ class Events {
49740
50048
  reader.readAsText(file);
49741
50049
  }
49742
50050
  });
50051
+
50052
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
50053
+ e.preventDefault();
50054
+ ic.bInitial = true;
50055
+ if(!me.cfg.notebook) dialog.dialog( "close" );
50056
+ //close all dialog
50057
+ if(!me.cfg.notebook) {
50058
+ $(".ui-dialog-content").dialog("close");
50059
+ }
50060
+ else {
50061
+ ic.resizeCanvasCls.closeDialogs();
50062
+ }
50063
+ let file = $("#" + me.pre + "afmapfile")[0].files[0];
50064
+ if(!file) {
50065
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
50066
+ }
50067
+ else {
50068
+ me.htmlCls.setHtmlCls.fileSupport();
50069
+ let reader = new FileReader();
50070
+ reader.onload = function(e) {
50071
+ let dataStr = e.target.result; // or = reader.result;
50072
+ me.htmlCls.clickMenuCls.setLogCmd('load AlphaFold PAE file ' + $("#" + me.pre + "afmapfile").val(), false);
50073
+
50074
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show Predicted Aligned Error (PAE) map');
50075
+ ic.contactMapCls.processAfErrorMap(JSON.parse(dataStr));
50076
+ };
50077
+ reader.readAsText(file);
50078
+ }
50079
+ });
50080
+
50081
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfilefull", "click", function(e) { let ic = me.icn3d;
50082
+ e.preventDefault();
50083
+ ic.bInitial = true;
50084
+ if(!me.cfg.notebook) dialog.dialog( "close" );
50085
+ //close all dialog
50086
+ if(!me.cfg.notebook) {
50087
+ $(".ui-dialog-content").dialog("close");
50088
+ }
50089
+ else {
50090
+ ic.resizeCanvasCls.closeDialogs();
50091
+ }
50092
+ let file = $("#" + me.pre + "afmapfile")[0].files[0];
50093
+ if(!file) {
50094
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
50095
+ }
50096
+ else {
50097
+ me.htmlCls.setHtmlCls.fileSupport();
50098
+ let reader = new FileReader();
50099
+ reader.onload = function(e) {
50100
+ let dataStr = e.target.result; // or = reader.result;
50101
+ me.htmlCls.clickMenuCls.setLogCmd('load AlphaFold PAE file ' + $("#" + me.pre + "afmapfile").val(), false);
50102
+
50103
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show Predicted Aligned Error (PAE) map');
50104
+ ic.contactMapCls.processAfErrorMap(JSON.parse(dataStr), true);
50105
+ };
50106
+ reader.readAsText(file);
50107
+ }
50108
+ });
49743
50109
  // },
49744
50110
  // clickReload_urlfile: function() {
49745
50111
  me.myEventCls.onIds("#" + me.pre + "reload_urlfile", "click", function(e) { let ic = me.icn3d;
@@ -49992,9 +50358,7 @@ class Events {
49992
50358
  me.myEventCls.onIds("#" + me.svgid + "_png", "click", function(e) { let ic = me.icn3d;
49993
50359
  e.preventDefault();
49994
50360
  //if(!me.cfg.notebook) dialog.dialog( "close" );
49995
- let width = $("#" + me.pre + "dl_graph").width();
49996
- let height = $("#" + me.pre + "dl_graph").height();
49997
- ic.saveFileCls.savePng(me.svgid, ic.inputid + "_force_directed_graph.png", width, height);
50361
+ ic.saveFileCls.savePng(me.svgid, ic.inputid + "_force_directed_graph.png");
49998
50362
  });
49999
50363
  me.myEventCls.onIds("#" + me.svgid + "_json", "click", function(e) { let ic = me.icn3d;
50000
50364
  e.preventDefault();
@@ -50013,9 +50377,7 @@ class Events {
50013
50377
  $(document).on("click", "#" + me.svgid_ct + "_png", function(e) { let ic = me.icn3d;
50014
50378
  e.preventDefault();
50015
50379
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50016
- let width = $("#" + me.pre + "dl_2dctn").width();
50017
- let height = $("#" + me.pre + "dl_2dctn").height();
50018
- ic.saveFileCls.savePng(me.svgid_ct, ic.inputid + "_cartoon.png", width, height);
50380
+ ic.saveFileCls.savePng(me.svgid_ct, ic.inputid + "_cartoon.png");
50019
50381
  });
50020
50382
  $(document).on("click", "#" + me.svgid_ct + "_json", function(e) { let ic = me.icn3d;
50021
50383
  e.preventDefault();
@@ -50041,9 +50403,7 @@ class Events {
50041
50403
  me.myEventCls.onIds("#" + me.linegraphid + "_png", "click", function(e) { let ic = me.icn3d;
50042
50404
  e.preventDefault();
50043
50405
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50044
- let width = $("#" + me.pre + "dl_linegraph").width();
50045
- let height = $("#" + me.pre + "dl_linegraph").height();
50046
- ic.saveFileCls.savePng(me.linegraphid, ic.inputid + "_line_graph.png", width, height);
50406
+ ic.saveFileCls.savePng(me.linegraphid, ic.inputid + "_line_graph.png");
50047
50407
  });
50048
50408
  me.myEventCls.onIds("#" + me.linegraphid + "_json", "click", function(e) { let ic = me.icn3d;
50049
50409
  e.preventDefault();
@@ -50069,9 +50429,7 @@ class Events {
50069
50429
  me.myEventCls.onIds("#" + me.scatterplotid + "_png", "click", function(e) { let ic = me.icn3d;
50070
50430
  e.preventDefault();
50071
50431
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50072
- let width = $("#" + me.pre + "dl_scatterplot").width();
50073
- let height = $("#" + me.pre + "dl_scatterplot").height();
50074
- ic.saveFileCls.savePng(me.scatterplotid, ic.inputid + "_scatterplot.png", width, height);
50432
+ ic.saveFileCls.savePng(me.scatterplotid, ic.inputid + "_scatterplot.png");
50075
50433
  });
50076
50434
  me.myEventCls.onIds("#" + me.scatterplotid + "_json", "click", function(e) { let ic = me.icn3d;
50077
50435
  e.preventDefault();
@@ -50093,14 +50451,12 @@ class Events {
50093
50451
  me.myEventCls.onIds("#" + me.contactmapid + "_svg", "click", function(e) { let ic = me.icn3d;
50094
50452
  e.preventDefault();
50095
50453
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50096
- ic.saveFileCls.saveSvg(me.contactmapid, ic.inputid + "_contactmap.svg");
50454
+ ic.saveFileCls.saveSvg(me.contactmapid, ic.inputid + "_contactmap.svg", true);
50097
50455
  });
50098
50456
  me.myEventCls.onIds("#" + me.contactmapid + "_png", "click", function(e) { let ic = me.icn3d;
50099
50457
  e.preventDefault();
50100
50458
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50101
- let width = $("#" + me.pre + "dl_contactmap").width();
50102
- let height = $("#" + me.pre + "dl_contactmap").height();
50103
- ic.saveFileCls.savePng(me.contactmapid, ic.inputid + "_contactmap.png", width, height);
50459
+ ic.saveFileCls.savePng(me.contactmapid, ic.inputid + "_contactmap.png", true);
50104
50460
  });
50105
50461
  me.myEventCls.onIds("#" + me.contactmapid + "_json", "click", function(e) { let ic = me.icn3d;
50106
50462
  e.preventDefault();
@@ -50112,11 +50468,47 @@ class Events {
50112
50468
  ic.saveFileCls.saveFile(ic.inputid + "_contactmap.json", "text", [graphStr2]);
50113
50469
  });
50114
50470
  me.myEventCls.onIds("#" + me.contactmapid + "_scale", "change", function(e) { let ic = me.icn3d;
50471
+ e.preventDefault();
50472
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50473
+ let scale = $("#" + me.contactmapid + "_scale").val();
50474
+ $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
50475
+ me.htmlCls.clickMenuCls.setLogCmd("contactmap scale " + scale, true);
50476
+ });
50477
+
50478
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_svg", "click", function(e) { let ic = me.icn3d;
50479
+ e.preventDefault();
50480
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50481
+ ic.saveFileCls.saveSvg(me.alignerrormapid, ic.inputid + "_alignerrormap.svg", true);
50482
+ });
50483
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_png", "click", function(e) { let ic = me.icn3d;
50484
+ e.preventDefault();
50485
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50486
+ ic.saveFileCls.savePng(me.alignerrormapid, ic.inputid + "_alignerrormap.png", true);
50487
+ });
50488
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_full", "click", function(e) { let ic = me.icn3d;
50489
+ e.preventDefault();
50490
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50491
+ ic.contactMapCls.afErrorMap(afid, true);
50492
+
50493
+
50494
+ });
50495
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_json", "click", function(e) { let ic = me.icn3d;
50496
+ e.preventDefault();
50497
+
50498
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50499
+ let graphStr2 = ic.alignerrormapStr.substr(0, ic.alignerrormapStr.lastIndexOf('}'));
50500
+
50501
+ graphStr2 += me.htmlCls.setHtmlCls.getLinkColor();
50502
+
50503
+ ic.saveFileCls.saveFile(ic.inputid + "_alignerrormap.json", "text", [graphStr2]);
50504
+ });
50505
+
50506
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_scale", "change", function(e) { let ic = me.icn3d;
50115
50507
  e.preventDefault();
50116
50508
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50117
- let scale = $("#" + me.contactmapid + "_scale").val();
50118
- $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
50119
- me.htmlCls.clickMenuCls.setLogCmd("contactmap scale " + scale, true);
50509
+ let scale = $("#" + me.alignerrormapid + "_scale").val();
50510
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
50511
+ me.htmlCls.clickMenuCls.setLogCmd("alignerrormap scale " + scale, true);
50120
50512
  });
50121
50513
 
50122
50514
  me.myEventCls.onIds("#" + me.svgid + "_label", "change", function(e) { me.icn3d;
@@ -52533,7 +52925,142 @@ class ContactMap {
52533
52925
  }
52534
52926
  }
52535
52927
 
52536
- drawContactMap(lineGraphStr) { let ic = this.icn3d, me = ic.icn3dui;
52928
+ afErrorMap(afid, bFull) { let ic = this.icn3d, me = ic.icn3dui;
52929
+ let thisClass = this;
52930
+
52931
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show Predicted Aligned Error (PAE) map');
52932
+
52933
+ let url, dataType;
52934
+
52935
+ url = "https://alphafold.ebi.ac.uk/files/AF-" + afid + "-F1-predicted_aligned_error_v2.json";
52936
+
52937
+ dataType = "json";
52938
+
52939
+ $.ajax({
52940
+ url: url,
52941
+ dataType: dataType,
52942
+ cache: true,
52943
+ tryCount : 0,
52944
+ retryLimit : 1,
52945
+ success: function(data) {
52946
+ thisClass.processAfErrorMap(data, bFull);
52947
+ },
52948
+ error : function(xhr, textStatus, errorThrown ) {
52949
+ this.tryCount++;
52950
+ if(this.tryCount <= this.retryLimit) {
52951
+ //try again
52952
+ $.ajax(this);
52953
+ return;
52954
+ }
52955
+ var aaa = 1; //alert("There are some problems in loading the PAE file...");
52956
+ return;
52957
+ }
52958
+ });
52959
+ }
52960
+
52961
+ processAfErrorMap(dataJson, bFull) { let ic = this.icn3d, me = ic.icn3dui;
52962
+ // json format: [{"residue1": [1, ..., 1, ..., n, ..., n], "residue2": [1, 2, ..., n, ..., 1, 2, ..., n],
52963
+ // "distance": [n*n matrix],"max_predicted_aligned_error":31.75}]
52964
+ let distMatrix = dataJson[0].distance;
52965
+ let max = dataJson[0].max_predicted_aligned_error;
52966
+ if(!distMatrix || !max) {
52967
+ var aaa = 1; //alert("The PAE file didn't have the right format...");
52968
+ return;
52969
+ }
52970
+
52971
+ // generate lineGraphStr
52972
+ // e.g., {"nodes": [{"id":"A1.A","r":"1_1_1TOP_A_1","s":"ab","x":1,"y":21,"c":"FF00FF"}, ...],
52973
+ // "links": [{"source": "A1.A", "target": "S2.A", "v": 3, "c": "FF00FF"}, ...]}
52974
+ let nodeStr = '"nodes": [', linkStr = '"links": [';
52975
+ let bNode = false, bLink = false;
52976
+ let postA = '', postB = '.';
52977
+
52978
+ // initialize some parameters if no structure wasloaded yet
52979
+ let bStruData;
52980
+ if(!ic.chains || Object.keys(ic.chains).length == 0) {
52981
+ bStruData = false;
52982
+ ic.init_base();
52983
+ }
52984
+ else {
52985
+ bStruData = true;
52986
+ }
52987
+
52988
+ //let chainidArray = Object.keys(ic.chains);
52989
+ //let chainid = (chainidArray.length == 1) ? chainidArray[0] : 'stru_A';
52990
+
52991
+ let dim = parseInt(Math.sqrt(distMatrix.length));
52992
+
52993
+ // map index with residue number when the structure has multiple chains
52994
+ let index = 0;
52995
+ let index2resObj = {};
52996
+ for(let chainid in ic.chains) {
52997
+ for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
52998
+ index2resObj[index] = ic.chainsSeq[chainid][j];
52999
+ index2resObj[index].chainid = chainid;
53000
+ ++index;
53001
+ }
53002
+ }
53003
+
53004
+ //for(let chainid in ic.chains) {
53005
+ //for(let i = 0, il = ic.chainsSeq[chainid].length; i < il; ++i) {
53006
+ index = 0;
53007
+ for(let i = 0; i < dim; ++i) {
53008
+ let resi = (bStruData) ? index2resObj[i].resi : i + 1;
53009
+ let resn = (bStruData) ? index2resObj[i].name : '*';
53010
+ let chainid = (bStruData) ? index2resObj[i].chainid : 'stru_A';
53011
+
53012
+ let resid = chainid + '_' + resi;
53013
+ let atom = (ic.residues[resid]) ? ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid])
53014
+ : {color: me.parasCls.thr(0x888888)};
53015
+ let chain = chainid.substr(chainid.indexOf('_') + 1);
53016
+ let color = atom.color.getHexString();
53017
+
53018
+ if(bNode) nodeStr += ', ';
53019
+ let idStr = resn + resi + '.' + chain;
53020
+ nodeStr += '{"id":"' + idStr + postA + '","r":"1_1_' + resid + '","s":"a","c":"' + color + '"}\n';
53021
+ nodeStr += ', {"id":"' + idStr + postB + '","r":"1_1_' + resid + '","s":"b","c":"' + color + '"}';
53022
+ bNode = true;
53023
+
53024
+ let start = (bFull) ? 0 : i; // full map, or half map
53025
+
53026
+ //for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
53027
+ //for(let j = 0; j < dim; ++j) {
53028
+ for(let j = start; j < dim; ++j) {
53029
+ index = i * dim + j;
53030
+ let resi2 = (bStruData) ? index2resObj[j].resi : j + 1;
53031
+ let resn2 = (bStruData) ? index2resObj[j].name : '*';
53032
+ let chainid2 = (bStruData) ? index2resObj[j].chainid : 'stru_A';
53033
+ let chain2 = chainid2.substr(chainid2.indexOf('_') + 1);
53034
+
53035
+ let idStr2 = resn2 + resi2 + '.' + chain2;
53036
+
53037
+ // max dark green color 004d00, 0x4d = 77, 77/255 = 0.302
53038
+ // 0: 004d00, max: FFFFFF
53039
+ let ratio = (distMatrix[index]) ? distMatrix[index] / max : 0;
53040
+ let r = parseInt(ratio*255).toString(16);
53041
+ let g = parseInt(((1.0 - 0.302)*ratio + 0.302) * 255).toString(16);
53042
+ let rHex = (r.length == 1) ? '0' + r : r;
53043
+ let gHex = (g.length == 1) ? '0' + g : g;
53044
+ let bHex = rHex;
53045
+ let color2 = rHex + gHex + bHex;
53046
+
53047
+ if(bLink) linkStr += ', ';
53048
+ linkStr += '{"source": "' + idStr + postA + '", "target": "' + idStr2 + postB + '", "v": 11, "c": "' + color2 + '"}\n';
53049
+ bLink = true;
53050
+ }
53051
+ }
53052
+ //}
53053
+
53054
+ dataJson = {};
53055
+
53056
+ let lineGraphStr = '{' + nodeStr + '], ' + linkStr + ']}';
53057
+ let bAfMap = true;
53058
+ this.drawContactMap(lineGraphStr, bAfMap, max);
53059
+
53060
+ if(ic.deferredAfmap !== undefined) ic.deferredAfmap.resolve();
53061
+ }
53062
+
53063
+ drawContactMap(lineGraphStr, bAfMap, max) { let ic = this.icn3d, me = ic.icn3dui;
52537
53064
  let html, graph = JSON.parse(lineGraphStr);
52538
53065
  let linkArray = graph.links;
52539
53066
 
@@ -52567,7 +53094,7 @@ class ContactMap {
52567
53094
 
52568
53095
  let graphStr = '{\n';
52569
53096
 
52570
- let struc1 = Object.keys(ic.structures)[0];
53097
+ let struc1 = (ic.structures.length > 0) ? ic.structures[0] : 'stru';
52571
53098
  let len1 = nodeArray1.length,
52572
53099
  len2 = nodeArray2.length;
52573
53100
  let factor = 1;
@@ -52581,20 +53108,68 @@ class ContactMap {
52581
53108
  width =(len2 + 2) *(r + gap) + 2 * marginX + legendWidth;
52582
53109
 
52583
53110
  let id, graphWidth;
52584
- ic.contactmapWidth = 2 * width;
52585
- graphWidth = ic.contactmapWidth;
52586
- id = me.contactmapid;
53111
+ if(bAfMap) {
53112
+ ic.alignerrormapWidth = 2 * width;
53113
+ graphWidth = ic.alignerrormapWidth;
53114
+ id = me.alignerrormapid;
53115
+ }
53116
+ else {
53117
+ ic.contactmapWidth = 2 * width;
53118
+ graphWidth = ic.contactmapWidth;
53119
+ id = me.contactmapid;
53120
+ }
53121
+
52587
53122
  html =(linkArray.length > 0) ? "" : "No interactions found for these two sets<br><br>";
52588
- html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
53123
+ html += "<svg xmlns='http://www.w3.org/2000/svg' id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
52589
53124
  let bContactMap = true;
52590
- html += ic.lineGraphCls.drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, 0, bContactMap);
53125
+
53126
+ if(bAfMap) { // cleaned the code by using "use" in SVG, but didn't improve rendering
53127
+
53128
+ ic.hex2id = {};
53129
+ let threshold = 29.0 / max;
53130
+ ic.hex2skip = {}; // do not display any error larger than 29 angstrom
53131
+ let nRef = 1000;
53132
+ for(let i = 0; i < nRef; ++i) {
53133
+ let ratio = 1.0 * i / nRef;
53134
+ let r = parseInt(ratio*255).toString(16);
53135
+ let g = parseInt(((1.0 - 0.302)*ratio + 0.302) * 255).toString(16);
53136
+ let rHex = (r.length == 1) ? '0' + r : r;
53137
+ let gHex = (g.length == 1) ? '0' + g : g;
53138
+ let bHex = rHex;
53139
+ let color = rHex + gHex + bHex;
53140
+
53141
+ let idRect = me.pre + "afmap_" + i;
53142
+
53143
+ ic.hex2id[color] = idRect;
53144
+ if(ratio > threshold) {
53145
+ ic.hex2skip[color] = idRect;
53146
+ }
53147
+
53148
+ //html += "<g id='" + id + "'>";
53149
+ // html += "<rect id='" + idRect + "' x='0' y='0' width='" + rectSize + "' height='" + rectSize + "' fill='"
53150
+ // + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
53151
+ //html += "</g>"
53152
+ }
53153
+ // html += "</defs>";
53154
+ }
53155
+
53156
+ html += ic.lineGraphCls.drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, 0, bContactMap, undefined, undefined, bAfMap);
52591
53157
  graphStr += ic.getGraphCls.updateGraphJson(struc1, 1, nodeArray1, nodeArray2, linkArray);
52592
53158
  html += "</svg>";
52593
53159
 
52594
53160
  graphStr += '}\n';
52595
- ic.contactmapStr = graphStr;
53161
+ if(bAfMap) {
53162
+ ic.alignerrormapStr = graphStr;
53163
+ $("#" + ic.pre + "alignerrormapDiv").html(html);
53164
+
53165
+ let scale = $("#" + me.alignerrormapid + "_scale").val();
53166
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
53167
+ }
53168
+ else {
53169
+ ic.contactmapStr = graphStr;
53170
+ $("#" + ic.pre + "contactmapDiv").html(html);
53171
+ }
52596
53172
 
52597
- $("#" + ic.pre + "contactmapDiv").html(html);
52598
53173
  return html;
52599
53174
  }
52600
53175
  }
@@ -54974,7 +55549,7 @@ iCn3D.prototype.init = function (bKeepCmd) {
54974
55549
  //this.inputid = {"idtype": undefined, "id":undefined}; // support pdbid, mmdbid
54975
55550
 
54976
55551
  this.biomtMatrices = [];
54977
- this.bAssembly = true;
55552
+ this.bAssembly = false; //true;
54978
55553
 
54979
55554
  this.bDrawn = false;
54980
55555
  this.bSecondaryStructure = false;
@@ -55112,7 +55687,7 @@ iCn3D.prototype.reinitAfterLoad = function () { let ic = this, me = ic.icn3dui;
55112
55687
  ic.lines = {}; // hash of name -> a list of solid or dashed lines. Each line contains 'position1', 'position2', 'color', and a boolean of 'dashed'
55113
55688
  // line name could be custom, hbond, ssbond, distance
55114
55689
 
55115
- ic.bAssembly = true;
55690
+ ic.bAssembly = false; //true;
55116
55691
  };
55117
55692
 
55118
55693
  iCn3D.prototype.resetConfig = function () { let ic = this, me = ic.icn3dui;
@@ -55151,7 +55726,7 @@ class iCn3DUI {
55151
55726
  //even when multiple iCn3D viewers are shown together.
55152
55727
  this.pre = this.cfg.divid + "_";
55153
55728
 
55154
- this.REVISION = '3.7.1';
55729
+ this.REVISION = '3.8.2';
55155
55730
 
55156
55731
  // In nodejs, iCn3D defines "window = {navigator: {}}"
55157
55732
  this.bNode = (Object.keys(window).length < 2) ? true : false;