icn3d 3.7.1 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/icn3d.js +586 -166
  2. package/package.json +1 -1
package/icn3d.js CHANGED
@@ -15168,24 +15168,7 @@ class Saltbridge {
15168
15168
  || (atom.het && me.parasCls.cationsTrimArray.indexOf(atom.elem) !== -1)
15169
15169
  || (atom.het && atom.elem === "N" && atom.bonds.length == 1);
15170
15170
 
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;
15171
+ let bAtomCondAnion = this.isAnion(atom);
15189
15172
 
15190
15173
  bAtomCondCation = (ic.bOpm) ? bAtomCondCation && atom.resn !== 'DUM' : bAtomCondCation;
15191
15174
  bAtomCondAnion = (ic.bOpm) ? bAtomCondAnion && atom.resn !== 'DUM' : bAtomCondAnion;
@@ -15216,10 +15199,7 @@ class Saltbridge {
15216
15199
  || ( atom.resn === 'ARG' && (atom.name === "NH1" || atom.name === "NH2"))
15217
15200
  || (atom.het && me.parasCls.cationsTrimArray.indexOf(atom.elem) !== -1);
15218
15201
 
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);
15202
+ let bAtomCondAnion = this.isAnion(atom);
15223
15203
 
15224
15204
  bAtomCondCation = (ic.bOpm) ? bAtomCondCation && atom.resn !== 'DUM' : bAtomCondCation;
15225
15205
  bAtomCondAnion = (ic.bOpm) ? bAtomCondAnion && atom.resn !== 'DUM' : bAtomCondAnion;
@@ -15330,6 +15310,35 @@ class Saltbridge {
15330
15310
  return hbondsAtoms;
15331
15311
  }
15332
15312
 
15313
+ isAnion(atom) { let ic = this.icn3d, me = ic.icn3dui;
15314
+ // For ligand, "O" in carboxy group may be negatively charged. => to be improved
15315
+ let bLigNeg = undefined;
15316
+ if(atom.het && atom.elem === "O" && atom.bonds.length == 1) {
15317
+ let cAtom = ic.atoms[atom.bonds[0]];
15318
+ for(let j = 0; j < cAtom.bonds.length; ++j) {
15319
+ let serial = cAtom.bonds[j];
15320
+ if(ic.atoms[serial].elem == "O" && serial != atom.serial) {
15321
+ bLigNeg = true;
15322
+ break;
15323
+ }
15324
+ }
15325
+ }
15326
+
15327
+ // "O" in phosphae or sulfate group is neagatively charged
15328
+ if(atom.elem === "O" && atom.bonds.length == 1) {
15329
+ let pAtom = ic.atoms[atom.bonds[0]];
15330
+ if(pAtom.elem == "P" || pAtom.elem == "S") bLigNeg = true;
15331
+ }
15332
+
15333
+ let bAtomCondAnion = ( atom.resn === 'GLU' && (atom.name === "OE1" || atom.name === "OE2") )
15334
+ || ( atom.resn === 'ASP' && (atom.name === "OD1" || atom.name === "OD2") )
15335
+ || ( ic.nucleotides.hasOwnProperty(atom.serial) && (atom.name === "OP1" || atom.name === "OP2" || atom.name === "O1P" || atom.name === "O2P"))
15336
+ || (atom.het && me.parasCls.anionsTrimArray.indexOf(atom.elem) !== -1)
15337
+ || bLigNeg;
15338
+
15339
+ return bAtomCondAnion;
15340
+ }
15341
+
15333
15342
  hideSaltbridge() { let ic = this.icn3d; ic.icn3dui;
15334
15343
  ic.opts["saltbridge"] = "no";
15335
15344
  if(ic.lines === undefined) ic.lines = { };
@@ -15477,7 +15486,7 @@ class GetGraph {
15477
15486
  return resStr;
15478
15487
  }
15479
15488
 
15480
- drawResNode(node, i, r, gap, margin, y, setName, bVertical, bContactMap) { let ic = this.icn3d; ic.icn3dui;
15489
+ drawResNode(node, i, r, gap, margin, y, setName, bVertical, bContactMap, bAfMap) { let ic = this.icn3d; ic.icn3dui;
15481
15490
  let x, resid = node.r.substr(4);
15482
15491
  if(bVertical) {
15483
15492
  x = margin - i *(r + gap);
@@ -15503,7 +15512,7 @@ class GetGraph {
15503
15512
  let strokewidth = '1';
15504
15513
  let textcolor = '#000';
15505
15514
  let fontsize = '6px'; // '6';
15506
- let html = "<g class='icn3d-node' resid='" + resid + "' >";
15515
+ let html = (bAfMap) ? "<g>" : "<g class='icn3d-node' resid='" + resid + "' >";
15507
15516
  html += "<title>" + node.id + "</title>";
15508
15517
  if(bVertical) {
15509
15518
  html += "<circle cx='" + y + "' cy='" + x + "' r='" + r + "' fill='" + color + "' stroke-width='" + strokewidth + "' stroke='" + strokecolor + "' resid='" + resid + "' />";
@@ -15516,18 +15525,27 @@ class GetGraph {
15516
15525
  html += "</g>";
15517
15526
  return html;
15518
15527
  }
15519
- getNodeTopBottom(nameHash, name2node, bReverseNode, bCommon, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15528
+ getNodeTopBottom(nameHash, name2node, bReverseNode, bCommonDiff, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15520
15529
  let thisClass = this;
15521
15530
  let nodeArray1 = [], nodeArray2 = [], name2nodeCommon = {};
15531
+
15532
+ let separatorCommon = "=>", separatorDiff = "==>", postCommon = "-", postDiff = "--";
15522
15533
  for(let name in nameHash) {
15523
15534
  let node = name2node[name];
15524
15535
  if(!node) continue;
15525
15536
 
15526
- if(bCommon) {
15537
+ if(bCommonDiff == 1 || bCommonDiff == 2) {
15527
15538
  node = me.hashUtilsCls.cloneHash(node);
15528
15539
 
15529
- let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : '-';
15530
- node.id += ">" + mapping;
15540
+ if(bCommonDiff == 1) {
15541
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : postCommon;
15542
+ node.id += separatorCommon + mapping;
15543
+ }
15544
+ else {
15545
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : postDiff;
15546
+ node.id += separatorDiff + mapping;
15547
+ }
15548
+
15531
15549
  name2nodeCommon[node.id] = node;
15532
15550
  }
15533
15551
 
@@ -15881,6 +15899,7 @@ class LineGraph {
15881
15899
  // Original node: {id : "Q24.A.2AJF", r : "1_1_2AJF_A_24", s: "a", ...}
15882
15900
  // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
15883
15901
  let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
15902
+ let nodeArray1SplitDiff = [], nodeArray2SplitDiff = [], linkArraySplitDiff = [], nameHashSplitDiff = [];
15884
15903
  let linkedNodeCnt = {};
15885
15904
 
15886
15905
  for(let i = 0, il = structureArray.length; i < il; ++i) {
@@ -15894,6 +15913,11 @@ class LineGraph {
15894
15913
  linkArraySplitCommon[i] = [];
15895
15914
  nameHashSplitCommon[i] = {};
15896
15915
 
15916
+ nodeArray1SplitDiff[i] = [];
15917
+ nodeArray2SplitDiff[i] = [];
15918
+ linkArraySplitDiff[i] = [];
15919
+ nameHashSplitDiff[i] = {};
15920
+
15897
15921
  struc2index[structureArray[i]] = i;
15898
15922
  }
15899
15923
 
@@ -15940,6 +15964,8 @@ class LineGraph {
15940
15964
  }
15941
15965
 
15942
15966
  // set linkArraySplitCommon and nameHashSplitCommon
15967
+ // set linkArraySplitDiff and nameHashSplitDiff
15968
+ let separatorCommon = "=>", separatorDiff = "==>", postCommon = "-", postDiff = "--";
15943
15969
  for(let i = 0, il = linkArray.length; i < il; ++i) {
15944
15970
  let link = linkArray[i];
15945
15971
  let nodeA = name2node[link.source];
@@ -15969,33 +15995,53 @@ class LineGraph {
15969
15995
 
15970
15996
  let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15971
15997
 
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];
15998
+ let linkCommon = me.hashUtilsCls.cloneHash(link);
15999
+ linkCommon.source += (ic.chainsMapping[chainid1][resid1]) ? separatorCommon + ic.chainsMapping[chainid1][resid1] : separatorCommon + postCommon;
16000
+ linkCommon.target += (ic.chainsMapping[chainid2][resid2]) ? separatorCommon + ic.chainsMapping[chainid2][resid2] : separatorCommon + postCommon;
15976
16001
 
16002
+ let linkDiff = me.hashUtilsCls.cloneHash(link);
16003
+ linkDiff.source += (ic.chainsMapping[chainid1][resid1]) ? separatorDiff + ic.chainsMapping[chainid1][resid1] : separatorDiff + postDiff;
16004
+ linkDiff.target += (ic.chainsMapping[chainid2][resid2]) ? separatorDiff + ic.chainsMapping[chainid2][resid2] : separatorDiff + postDiff;
16005
+
16006
+ if(linkedNodeCnt[mappingid] == structureArray.length) {
15977
16007
  linkArraySplitCommon[index].push(linkCommon);
15978
16008
  }
16009
+ else {
16010
+ linkArraySplitDiff[index].push(linkDiff);
16011
+ }
15979
16012
 
16013
+ // use the original node names and thus use the original link
15980
16014
  nameHashSplitCommon[index][link.source] = ic.chainsMapping[chainid1][resid1];
15981
16015
  nameHashSplitCommon[index][link.target] = ic.chainsMapping[chainid2][resid2];
16016
+
16017
+ nameHashSplitDiff[index][link.source] = ic.chainsMapping[chainid1][resid1];
16018
+ nameHashSplitDiff[index][link.target] = ic.chainsMapping[chainid2][resid2];
15982
16019
  }
15983
16020
  }
15984
16021
  }
15985
16022
 
15986
16023
  let len1Split = [], len2Split = [], maxWidth = 0;
15987
16024
  let strucArray = [];
16025
+ let bCommonDiff = 1;
15988
16026
  for(let i = 0, il = structureArray.length; i < il; ++i) {
15989
16027
  let nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node);
15990
16028
  nodeArray1Split[i] = nodeArraysTmp.nodeArray1;
15991
16029
  nodeArray2Split[i] = nodeArraysTmp.nodeArray2;
15992
16030
 
15993
- let bCommon = true;
15994
- nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommon, nameHashSplitCommon[i]);
16031
+ // common interactions
16032
+ bCommonDiff = 1;
16033
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommonDiff, nameHashSplitCommon[i]);
15995
16034
  nodeArray1SplitCommon[i] = nodeArraysTmp.nodeArray1;
15996
16035
  nodeArray2SplitCommon[i] = nodeArraysTmp.nodeArray2;
15997
16036
  name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
15998
16037
 
16038
+ // different interactions
16039
+ bCommonDiff = 2;
16040
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommonDiff, nameHashSplitDiff[i]);
16041
+ nodeArray1SplitDiff[i] = nodeArraysTmp.nodeArray1;
16042
+ nodeArray2SplitDiff[i] = nodeArraysTmp.nodeArray2;
16043
+ name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
16044
+
15999
16045
  len1Split[i] = nodeArray1Split[i].length;
16000
16046
  len2Split[i] = nodeArray2Split[i].length;
16001
16047
 
@@ -16019,66 +16065,53 @@ class LineGraph {
16019
16065
  //width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16020
16066
  heightAll =(me.utilsCls.sumArray(len1Split) + 2*strucArray.length) *(r + gap) + 4 * marginY
16021
16067
  + 2 * legendWidth + textHeight*strucArray.length;
16022
- // show common interaction as well
16023
- heightAll *= 2;
16068
+ // show common and diff interaction as well
16069
+ heightAll *= 3;
16024
16070
 
16025
16071
  width = (maxWidth + 2) * (r + gap) + 2 * marginX + legendWidth;
16026
16072
 
16027
16073
  } else {
16028
16074
  height = 110 + textHeight;
16029
16075
  heightAll = height * strucArray.length;
16030
- // show common interaction as well
16031
- heightAll *= 2;
16076
+ // show common and diff interaction as well
16077
+ heightAll *= 3;
16032
16078
 
16033
16079
  width = (maxWidth + 2) * (r + gap) + 2 * marginX;
16034
16080
  }
16035
- let id, graphWidth;
16081
+ let id;
16036
16082
  if(bScatterplot) {
16037
16083
  ic.scatterplotWidth = 2 * width;
16038
- graphWidth = ic.scatterplotWidth;
16084
+ ic.scatterplotWidth;
16039
16085
  id = me.scatterplotid;
16040
16086
  } else {
16041
16087
  ic.linegraphWidth = 2 * width;
16042
- graphWidth = ic.linegraphWidth;
16088
+ ic.linegraphWidth;
16043
16089
  id = me.linegraphid;
16044
16090
  }
16045
16091
  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>";
16047
- html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
16092
+ "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>";
16093
+ html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "'>";
16048
16094
 
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;
16095
+ let result, heightFinal = 0;
16096
+
16097
+ bCommonDiff = 0; // 0: all interactions, 1: common interactions, 2: different interactions
16098
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1Split, nodeArray2Split, linkArraySplit, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16060
16099
 
16061
- if(i > 0) ic.lineGraphStr += ', \n';
16062
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i, nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i]);
16063
- }
16100
+ heightFinal = result.heightFinal;
16101
+ html += result.html;
16064
16102
 
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;
16103
+ bCommonDiff = 1;
16104
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1SplitCommon, nodeArray2SplitCommon, linkArraySplitCommon, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16076
16105
 
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
- }
16106
+ heightFinal = result.heightFinal;
16107
+ html += result.html;
16108
+
16109
+ bCommonDiff = 2;
16110
+ result = this.drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1SplitDiff, nodeArray2SplitDiff, linkArraySplitDiff, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY);
16081
16111
 
16112
+ heightFinal = result.heightFinal;
16113
+ html += result.html;
16114
+
16082
16115
  html += "</svg>";
16083
16116
  } else {
16084
16117
  if(!bScatterplot) {
@@ -16136,6 +16169,45 @@ class LineGraph {
16136
16169
  return html;
16137
16170
  }
16138
16171
 
16172
+ drawGraphPerType(bCommonDiff, structureArray, bScatterplot, nodeArray1, nodeArray2, linkArray, name2node, heightFinal, height, textHeight, len1Split, r, gap, marginY) { let ic = this.icn3d; ic.icn3dui;
16173
+ let html = "";
16174
+
16175
+ // draw common interaction
16176
+ let label, postfix;
16177
+ if(bCommonDiff == 0) {
16178
+ label = "Interactions in structure ";
16179
+ postfix = "";
16180
+ }
16181
+ else if(bCommonDiff == 1) {
16182
+ label = "Common interactions in structure ";
16183
+ postfix = "_common";
16184
+ }
16185
+ else if(bCommonDiff == 2) {
16186
+ label = "Different interactions in structure ";
16187
+ postfix = "_diff";
16188
+ }
16189
+
16190
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
16191
+ if(bScatterplot) {
16192
+ html += this.drawScatterplot_base(nodeArray1[i], nodeArray2[i], linkArray[i], name2node, heightFinal, undefined, label + structureArray[i], textHeight);
16193
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
16194
+ } else {
16195
+ html += this.drawLineGraph_base(nodeArray1[i], nodeArray2[i], linkArray[i], name2node, heightFinal, label + structureArray[i], textHeight);
16196
+ }
16197
+ heightFinal += height;
16198
+
16199
+ if(bCommonDiff) { // very beginning
16200
+ if(i > 0) ic.lineGraphStr += ', \n';
16201
+ }
16202
+ else {
16203
+ ic.lineGraphStr += ', \n';
16204
+ }
16205
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(structureArray[i], i + postfix, nodeArray1[i], nodeArray2[i], linkArray[i]);
16206
+ }
16207
+
16208
+ return {"heightFinal": heightFinal, "html": html};
16209
+ }
16210
+
16139
16211
  getIdArrayFromNode(node) { let ic = this.icn3d, me = ic.icn3dui;
16140
16212
  let idArray = []; // 1_1_1KQ2_A_1
16141
16213
  idArray.push('');
@@ -16226,7 +16298,7 @@ class LineGraph {
16226
16298
  return html;
16227
16299
  }
16228
16300
 
16229
- drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight) { let ic = this.icn3d; ic.icn3dui;
16301
+ drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight, bAfMap) { let ic = this.icn3d; ic.icn3dui;
16230
16302
  let html = '';
16231
16303
  let len1 = nodeArray1.length,
16232
16304
  len2 = nodeArray2.length;
@@ -16252,12 +16324,12 @@ class LineGraph {
16252
16324
  node2posSet2 = {};
16253
16325
  let x = legendWidth + marginX;
16254
16326
  for(let i = 0; i < len1; ++i) {
16255
- nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true);
16327
+ nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true, undefined, bAfMap);
16256
16328
  node2posSet1[nodeArray1[i].id] = { x: x, y: margin1 - i *(r + gap) };
16257
16329
  }
16258
16330
  let y = height + heightTotal -(legendWidth + marginY);
16259
16331
  for(let i = 0; i < len2; ++i) {
16260
- nodeHtml += ic.getGraphCls.drawResNode(nodeArray2[i], i, r, gap, margin2, y, 'b', false, bContactMap);
16332
+ nodeHtml += ic.getGraphCls.drawResNode(nodeArray2[i], i, r, gap, margin2, y, 'b', false, bContactMap, bAfMap);
16261
16333
  node2posSet2[nodeArray2[i].id] = { x: margin2 + i *(r + gap), y: y };
16262
16334
  }
16263
16335
  for(let i = 0, il = linkArray.length; i < il; ++i) {
@@ -16267,10 +16339,10 @@ class LineGraph {
16267
16339
 
16268
16340
  if(!node1 || !node2) continue;
16269
16341
 
16270
- html += this.drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap);
16342
+ html += this.drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap);
16271
16343
 
16272
- if(bContactMap) { // draw symmetric contact map
16273
- html += this.drawOnePairNode(link, node2, node1, node2posSet1, node2posSet2, bContactMap);
16344
+ if(bContactMap && !bAfMap) { // draw symmetric contact map, bAfmap just need to draw once
16345
+ html += this.drawOnePairNode(link, node2, node1, node2posSet1, node2posSet2, bContactMap, bAfMap);
16274
16346
  }
16275
16347
  }
16276
16348
  // show nodes later
@@ -16278,7 +16350,7 @@ class LineGraph {
16278
16350
  return html;
16279
16351
  }
16280
16352
 
16281
- drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap) { let ic = this.icn3d, me = ic.icn3dui;
16353
+ drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap) { let ic = this.icn3d, me = ic.icn3dui;
16282
16354
  let html = '';
16283
16355
 
16284
16356
  let factor = 1;
@@ -16308,21 +16380,31 @@ class LineGraph {
16308
16380
  strokecolor = "#" + me.htmlCls.contactColor;
16309
16381
  }
16310
16382
 
16383
+ if(bContactMap) strokecolor = "#" + link.c;
16384
+
16311
16385
  let linestrokewidth;
16312
16386
  if(link.v == me.htmlCls.contactValue) {
16313
16387
  linestrokewidth = 1;
16314
16388
  } else {
16315
16389
  linestrokewidth = 2;
16316
16390
  }
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 + "' />";
16391
+
16392
+ if(bAfMap && ic.hex2skip[link.c]) ;
16393
+ else if(bAfMap && ic.hex2id[link.c]) {
16394
+ let id = ic.hex2id[link.c];
16395
+ html += "<use href='#" + id + "' x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' />";
16321
16396
  }
16322
16397
  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 + "' />";
16398
+ html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
16399
+ html += "<title>Interaction of residue " + node1.id + " with residue " + node2.id + "</title>";
16400
+ if(bContactMap) {
16401
+ html += "<rect x='" +(pos2.x - halfSize).toString() + "' y='" +(pos1.y - halfSize).toString() + "' width='" + rectSize + "' height='" + rectSize + "' fill='" + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
16402
+ }
16403
+ else {
16404
+ 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
+ }
16406
+ html += "</g>";
16324
16407
  }
16325
- html += "</g>";
16326
16408
 
16327
16409
  return html;
16328
16410
  }
@@ -23282,11 +23364,11 @@ class AlignParser {
23282
23364
  ic.alignmolid2color.push(tmpHash);
23283
23365
  }
23284
23366
 
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];
23367
+ //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];
23368
+ //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
23369
  // 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];
23370
+ 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];
23371
+ 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
23372
 
23291
23373
  let d3 = $.ajax({
23292
23374
  url: url3,
@@ -23821,14 +23903,14 @@ class MmdbParser {
23821
23903
  // b: b-factor, s: water, ft: pdbsite
23822
23904
  //&ft=1
23823
23905
  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;
23906
+ 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
23907
  }
23826
23908
  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
- }
23909
+ 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;
23910
+ }
23829
23911
 
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';
23912
+ // 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
23913
+ if(me.cfg.blast_rep_id !== undefined) url += '&bu=0';
23832
23914
 
23833
23915
  ic.bCid = undefined;
23834
23916
 
@@ -24084,7 +24166,7 @@ class MmdbParser {
24084
24166
  } // for each domainArray
24085
24167
  } // for each molid
24086
24168
 
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
24169
+ // "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
24170
  ic.bAssemblyUseAsu =(data.asuAtomCount !== undefined) ? true : false;
24089
24171
  if(type !== undefined) {
24090
24172
  ic.bAssemblyUseAsu = false;
@@ -24710,7 +24792,7 @@ class ChainalignParser {
24710
24792
  let pos1 = alignArray[0].indexOf('_');
24711
24793
  ic.mmdbid_t = alignArray[0].substr(0, pos1).toUpperCase();
24712
24794
  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;
24795
+ 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
24796
  if(me.cfg.inpara !== undefined) url_t += me.cfg.inpara;
24715
24797
 
24716
24798
  let ajaxArray = [];
@@ -24736,7 +24818,7 @@ class ChainalignParser {
24736
24818
  let chainalignFinal = ic.mmdbid_q + "_" + ic.chain_q + "," + ic.mmdbid_t + "_" + ic.chain_t;
24737
24819
 
24738
24820
  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;
24821
+ 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
24822
 
24741
24823
  if(me.cfg.inpara !== undefined) url_q += me.cfg.inpara;
24742
24824
 
@@ -26613,6 +26695,19 @@ class LoadScript {
26613
26695
 
26614
26696
  return;
26615
26697
  }
26698
+ else if(ic.commands[i].trim().indexOf('set af align error map') == 0) {
26699
+ let strArray = ic.commands[i].split("|||");
26700
+ let command = strArray[0].trim();
26701
+
26702
+ $.when(thisClass.applyCommandAfmap(command)).then(function() {
26703
+ //if(!me.cfg.notebook && dialog && dialog.hasClass("ui-dialog-content")) dialog.dialog( "close" );
26704
+
26705
+ //ic.drawCls.draw();
26706
+ thisClass.execCommandsBase(i + 1, end, steps);
26707
+ });
26708
+
26709
+ return;
26710
+ }
26616
26711
  else {
26617
26712
  ic.applyCommandCls.applyCommand(ic.commands[i]);
26618
26713
  }
@@ -26807,13 +26902,13 @@ class LoadScript {
26807
26902
  }
26808
26903
  else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
26809
26904
  me.cfg.mmdbid = id;
26810
- me.cfg.buidx = 1;
26905
+ me.cfg.bu = 1;
26811
26906
 
26812
26907
  ic.mmdbParserCls.downloadMmdb(id);
26813
26908
  }
26814
26909
  else if(command.indexOf('load mmdb0') !== -1) {
26815
26910
  me.cfg.mmdbid = id;
26816
- me.cfg.buidx = 0;
26911
+ me.cfg.bu = 0;
26817
26912
 
26818
26913
  ic.mmdbParserCls.downloadMmdb(id);
26819
26914
  }
@@ -26946,6 +27041,23 @@ class LoadScript {
26946
27041
  return ic.deferredRealign.promise();
26947
27042
  }
26948
27043
 
27044
+ applyCommandAfmapBase(command) { let ic = this.icn3d; ic.icn3dui;
27045
+ let afid = command.substr(command.lastIndexOf(' ') + 1);
27046
+
27047
+ ic.contactMapCls.afErrorMap(afid);
27048
+ }
27049
+
27050
+ applyCommandAfmap(command) { let ic = this.icn3d; ic.icn3dui;
27051
+ let thisClass = this;
27052
+
27053
+ // chain functions together
27054
+ ic.deferredAfmap = new $.Deferred(function() {
27055
+ thisClass.applyCommandAfmapBase(command);
27056
+ }); // end of me.deferred = $.Deferred(function() {
27057
+
27058
+ return ic.deferredAfmap.promise();
27059
+ }
27060
+
26949
27061
  applyCommandGraphinteractionBase(command) { let ic = this.icn3d; ic.icn3dui;
26950
27062
  let paraArray = command.split(' | ');
26951
27063
  if(paraArray.length >= 3) {
@@ -30941,6 +31053,14 @@ class ApplyCommand {
30941
31053
 
30942
31054
  $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
30943
31055
  }
31056
+ else if(command.indexOf('alignerrormap scale') == 0) {
31057
+ let pos = command.lastIndexOf(' ');
31058
+ let scale = command.substr(pos + 1);
31059
+
31060
+ $("#" + me.alignerrormapid + "_scale").val(scale);
31061
+
31062
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
31063
+ }
30944
31064
  else if(command.indexOf('graph force') == 0) {
30945
31065
  let pos = command.lastIndexOf(' ');
30946
31066
  me.htmlCls.force = parseInt(command.substr(pos + 1));
@@ -38791,7 +38911,7 @@ class Selection {
38791
38911
  }
38792
38912
 
38793
38913
  toggleMembrane(bShowMembrane) {var ic = this.icn3d, me = ic.icn3dui;
38794
- let structureArray = Object.keys(ic.structures);
38914
+ let structureArray = (ic.structures) ? Object.keys(ic.structures) : [];
38795
38915
 
38796
38916
  for(let i = 0, il = structureArray.length; i < il; ++i) {
38797
38917
  let structure = structureArray[i];
@@ -42911,20 +43031,29 @@ class SaveFile {
42911
43031
  }
42912
43032
  }
42913
43033
 
42914
- saveSvg(id, filename) { let ic = this.icn3d; ic.icn3dui;
42915
- let svg = this.getSvgXml(id);
43034
+ saveSvg(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
43035
+ if(me.bNode) return '';
43036
+
43037
+ let width = $("#" + id).width();
43038
+ let height = $("#" + id).height();
43039
+
43040
+ if(bContactmap) height = width;
42916
43041
 
42917
- let blob = new Blob([svg], {type: "image/svg+xml"});
43042
+ let svgXml = this.getSvgXml(id, width, height, bContactmap);
43043
+
43044
+ let blob = new Blob([svgXml], {type: "image/svg+xml"});
42918
43045
  saveAs(blob, filename);
42919
43046
  }
42920
43047
 
42921
- getSvgXml(id) { let ic = this.icn3d, me = ic.icn3dui;
43048
+ getSvgXml(id, width, height, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
42922
43049
  if(me.bNode) return '';
42923
43050
 
42924
43051
  // font is not good
42925
43052
  let svg_data = document.getElementById(id).innerHTML; //put id of your svg element here
42926
43053
 
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/\">";
43054
+ let viewbox = (width && height) ? "<svg viewBox=\"0 0 " + width + " " + height + "\"" : "<svg";
43055
+ //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/\">";
43056
+ 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
43057
 
42929
43058
  //if you have some additional styling like graph edges put them inside <style> tag
42930
43059
  let style = "<style>text {font-family: sans-serif; font-weight: bold; font-size: 18px;}</style>";
@@ -42934,9 +43063,14 @@ class SaveFile {
42934
43063
  return full_svg;
42935
43064
  }
42936
43065
 
42937
- savePng(id, filename, width, height) { let ic = this.icn3d, me = ic.icn3dui;
43066
+ savePng(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
42938
43067
  if(me.bNode) return '';
42939
43068
 
43069
+ let width = $("#" + id).width();
43070
+ let height = $("#" + id).height();
43071
+
43072
+ if(bContactmap) height = width;
43073
+
42940
43074
  // https://stackoverflow.com/questions/3975499/convert-svg-to-image-jpeg-png-etc-in-the-browser
42941
43075
  let svg = document.getElementById(id);
42942
43076
  let bbox = svg.getBBox();
@@ -42950,7 +43084,7 @@ class SaveFile {
42950
43084
  let ctx = canvas.getContext("2d");
42951
43085
  ctx.clearRect(0, 0, bbox.width, bbox.height);
42952
43086
 
42953
- let data = this.getSvgXml(id); //(new XMLSerializer()).serializeToString(copy); //ic.saveFileCls.getSvgXml();
43087
+ let data = this.getSvgXml(id, width, height, bContactmap); //(new XMLSerializer()).serializeToString(copy); //ic.saveFileCls.getSvgXml();
42954
43088
  let DOMURL = window.URL || window.webkitURL || window;
42955
43089
  let svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
42956
43090
 
@@ -43662,6 +43796,10 @@ class ClickMenu {
43662
43796
  me.myEventCls.onIds("#" + me.pre + "mn1_xyzfile", "click", function(e) { me.icn3d;
43663
43797
  me.htmlCls.dialogCls.openDlg('dl_xyzfile', 'Please input XYZ File');
43664
43798
  });
43799
+
43800
+ me.myEventCls.onIds("#" + me.pre + "mn1_afmapfile", "click", function(e) { me.icn3d;
43801
+ me.htmlCls.dialogCls.openDlg('dl_afmapfile', 'Please input AlphaFold aligned error File');
43802
+ });
43665
43803
  // },
43666
43804
  // clkMn1_urlfile: function() {
43667
43805
  me.myEventCls.onIds("#" + me.pre + "mn1_urlfile", "click", function(e) { me.icn3d;
@@ -46035,6 +46173,7 @@ class SetMenu {
46035
46173
  html += me.htmlCls.setHtmlCls.getLink('mn1_mol2file', 'Mol2 File');
46036
46174
  html += me.htmlCls.setHtmlCls.getLink('mn1_sdffile', 'SDF File');
46037
46175
  html += me.htmlCls.setHtmlCls.getLink('mn1_xyzfile', 'XYZ File');
46176
+ html += me.htmlCls.setHtmlCls.getLink('mn1_afmapfile', 'AlphaFold Aligned Error File');
46038
46177
  if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46039
46178
  html += "<li>-</li>";
46040
46179
  html += me.htmlCls.setHtmlCls.getLink('mn1_pngimage', 'iCn3D PNG Image');
@@ -47392,6 +47531,7 @@ class Dialog {
47392
47531
  let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
47393
47532
  let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
47394
47533
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
47534
+ let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
47395
47535
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
47396
47536
  let bAlignmentInit = $('#' + me.pre + 'dl_alignment').hasClass('ui-dialog-content'); // initialized
47397
47537
  let bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
@@ -47407,6 +47547,7 @@ class Dialog {
47407
47547
  if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
47408
47548
  if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
47409
47549
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
47550
+ if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
47410
47551
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
47411
47552
  if(bAlignmentInit) status.bAlignmentInit2 = $('#' + me.pre + 'dl_alignment').dialog( 'isOpen' );
47412
47553
  if(bTwoddgmInit) status.bTwoddgmInit2 = $('#' + me.pre + 'dl_2ddgm').dialog( 'isOpen' );
@@ -47451,13 +47592,14 @@ class Dialog {
47451
47592
  close: function(e) {
47452
47593
  let status = thisClass.getDialogStatus();
47453
47594
 
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)
47595
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47596
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47597
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47598
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47599
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bScatterplot2 && !status.bContactmap2 && !status.bAlignerrormap2)
47600
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bContactmap2 && !status.bAlignerrormap2)
47601
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bAlignerrormap2)
47602
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) && !status.bGraph2 && !status.bAlignmentInit2 && !status.bTable2 && !status.bLineGraph2 && !status.bScatterplot2 && !status.bContactmap2)
47461
47603
  ) {
47462
47604
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
47463
47605
  //ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH - twoddgmWidth, me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT, true);
@@ -47484,7 +47626,7 @@ class Dialog {
47484
47626
 
47485
47627
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
47486
47628
  }
47487
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap') {
47629
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
47488
47630
  //var bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
47489
47631
  //var bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
47490
47632
 
@@ -47507,6 +47649,10 @@ class Dialog {
47507
47649
  let width = ic.contactmapWidth * ratio;
47508
47650
  $("#" + me.contactmapid).attr("width", width);
47509
47651
  }
47652
+ else if(id == me.pre + 'dl_alignerrormap') {
47653
+ let width = ic.alignerrormapWidth * ratio;
47654
+ $("#" + me.alignerrormapid).attr("width", width);
47655
+ }
47510
47656
  }
47511
47657
  }
47512
47658
  });
@@ -47602,7 +47748,7 @@ class Dialog {
47602
47748
 
47603
47749
  let status = this.getDialogStatus();
47604
47750
 
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') {
47751
+ 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
47752
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
47607
47753
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
47608
47754
 
@@ -47638,13 +47784,14 @@ class Dialog {
47638
47784
  modal: false,
47639
47785
  position: position,
47640
47786
  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))
47787
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47788
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47789
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47790
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47791
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47792
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
47793
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bAlignerrormap2))
47794
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
47648
47795
  ) {
47649
47796
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
47650
47797
  let canvasWidth = me.utilsCls.isMobile() ? me.htmlCls.WIDTH : me.htmlCls.WIDTH - twoddgmWidth;
@@ -47670,7 +47817,7 @@ class Dialog {
47670
47817
 
47671
47818
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
47672
47819
  }
47673
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap') {
47820
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
47674
47821
  //var bTwoddgmInit = $('#' + me.pre + 'dl_2ddgm').hasClass('ui-dialog-content'); // initialized
47675
47822
  //var bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
47676
47823
 
@@ -47693,6 +47840,10 @@ class Dialog {
47693
47840
  let width = ic.contactmapWidth * ratio;
47694
47841
  $("#" + me.contactmapid).attr("width", width);
47695
47842
  }
47843
+ else if(id == me.pre + 'dl_alignerrormap') {
47844
+ let width = ic.alignerrormapWidth * ratio;
47845
+ $("#" + me.alignerrormapid).attr("width", width);
47846
+ }
47696
47847
  }
47697
47848
  }
47698
47849
  });
@@ -47815,7 +47966,7 @@ class Dialog {
47815
47966
  let width = 400, height = 150;
47816
47967
  let twoddgmWidth = me.htmlCls.width2d + 20;
47817
47968
 
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') {
47969
+ 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
47970
  $( "#" + id ).show();
47820
47971
 
47821
47972
  height =(me.htmlCls.HEIGHT) * 0.5;
@@ -47853,6 +48004,11 @@ class Dialog {
47853
48004
 
47854
48005
  $("#" + me.contactmapid).attr("width", width);
47855
48006
  }
48007
+ else if(id == me.pre + 'dl_alignerrormap') {
48008
+ let width = ic.alignerrormapWidth * ratio;
48009
+
48010
+ $("#" + me.alignerrormapid).attr("width", width);
48011
+ }
47856
48012
  });
47857
48013
  }
47858
48014
  else {
@@ -47986,8 +48142,11 @@ class SetDialog {
47986
48142
  html += "Note: AlphaFold produces a per-residue confidence score (pLDDT) between 0 and 100:<br>";
47987
48143
  html += me.htmlCls.clickMenuCls.setAlphaFoldLegend() + "<br>";
47988
48144
 
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>";
48145
+ let afid = (me.cfg.afid) ? me.cfg.afid : 'Q76EI6';
48146
+
48147
+ 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>";
48148
+ html += me.htmlCls.buttonStr + "reload_af'>Load Structure</button>"
48149
+ + me.htmlCls.buttonStr + "reload_afmap' style='margin-left:30px'>Load Aligned Error Map (slow)</button>";
47991
48150
  html += "</div>";
47992
48151
 
47993
48152
  html += me.htmlCls.divStr + "dl_opmid' class='" + dialogClass + "'>";
@@ -48083,6 +48242,12 @@ class SetDialog {
48083
48242
  html += "XYZ File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "xyzfile' size=8> ";
48084
48243
  html += me.htmlCls.buttonStr + "reload_xyzfile'>Load</button>";
48085
48244
  html += "</div>";
48245
+
48246
+ html += me.htmlCls.divStr + "dl_afmapfile' class='" + dialogClass + "'>";
48247
+ html += "AlphaFold Aligned Error File: " + me.htmlCls.inputFileStr + "id='" + me.pre + "afmapfile' size=8> ";
48248
+ html += me.htmlCls.buttonStr + "reload_afmapfile'>Load</button>";
48249
+ html += "</div>";
48250
+
48086
48251
  html += me.htmlCls.divStr + "dl_urlfile' class='" + dialogClass + "'>";
48087
48252
  html += "File type: ";
48088
48253
  html += "<select id='" + me.pre + "filetype'>";
@@ -48106,9 +48271,16 @@ class SetDialog {
48106
48271
  html += me.htmlCls.buttonStr + "reload_mmcif'>Load</button>";
48107
48272
  html += "</div>";
48108
48273
 
48109
- html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "'>";
48274
+ html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "' style='max-width:500px'>";
48110
48275
  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/>";
48276
+ 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>";
48277
+ 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="'
48278
+ + me.pre + 'asu_bu_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="width:15px;" title="Expand"></span><span id="'
48279
+ + me.pre + 'asu_bu_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="display:none; width:15px;" title="Shrink"></span></div>';
48280
+
48281
+ html += me.htmlCls.divStr + "asu_bu' style='display:none;'>";
48282
+ 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>';
48283
+
48112
48284
  html += "</div>";
48113
48285
 
48114
48286
  html += me.htmlCls.divStr + "dl_blast_rep_id' style='max-width:500px;' class='" + dialogClass + "'>";
@@ -48444,6 +48616,33 @@ class SetDialog {
48444
48616
 
48445
48617
  html += "</div>";
48446
48618
 
48619
+ html += me.htmlCls.divStr + "dl_alignerrormap' style='background-color:white' class='" + dialogClass + "'>";
48620
+
48621
+ //html += me.htmlCls.divNowrapStr + "Hold Ctrl key to select multiple nodes." + me.htmlCls.space3 + "</div>";
48622
+
48623
+ me.alignerrormapid = me.pre + 'alignerrormap';
48624
+ html += me.htmlCls.divNowrapStr + buttonStrTmp + me.alignerrormapid + '_svg">SVG</button>' + me.htmlCls.space2;
48625
+ html += buttonStrTmp + me.alignerrormapid + '_png">PNG (slow)</button>' + me.htmlCls.space2;
48626
+ html += buttonStrTmp + me.alignerrormapid + '_json">JSON</button>' + me.htmlCls.space4;
48627
+ html += "<b>Scale</b>: <select id='" + me.alignerrormapid + "_scale'>";
48628
+
48629
+ //let optArray5 = ['0.01', '0.02', '0.04', '0.06', '0.08', '0.1', '0.2', '0.4', '0.6', '0.8', '1'];
48630
+ html += me.htmlCls.setHtmlCls.getOptionHtml(optArray5, 2);
48631
+
48632
+ html += "</select></div><br>";
48633
+
48634
+ //min: 004d00, max: FFFFFF
48635
+ let startColorStr = '#004d00';
48636
+ let endColorStr = '#FFFFFF';
48637
+ let rangeStr = startColorStr + ' 0%, ' + endColorStr + ' 100%';
48638
+
48639
+ html += "<div style='width:200px'><div style='height: 12px; border: 1px solid #000; background: linear-gradient(to right, " + rangeStr + ");'></div>";
48640
+ 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>";
48641
+
48642
+ html += '<div id="' + me.pre + 'alignerrormapDiv"></div>';
48643
+
48644
+ html += "</div>";
48645
+
48447
48646
  html += me.htmlCls.divStr + "dl_elecmap2fofc' class='" + dialogClass + "'>";
48448
48647
  html += "<span style='white-space:nowrap;font-weight:bold;'>Contour at: <select id='" + me.pre + "sigma2fofc'>";
48449
48648
 
@@ -49178,6 +49377,16 @@ class Events {
49178
49377
  window.open(hostUrl + '?afid=' + $("#" + me.pre + "afid").val(), '_blank');
49179
49378
  });
49180
49379
 
49380
+ me.myEventCls.onIds("#" + me.pre + "reload_afmap", "click", function(e) { let ic = me.icn3d;
49381
+ e.preventDefault();
49382
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49383
+ let afid = me.cfg.afid ? me.cfg.afid : $("#" + me.pre + "afid").val();
49384
+
49385
+ me.htmlCls.clickMenuCls.setLogCmd("set af align error map " + afid, true);
49386
+
49387
+ ic.contactMapCls.afErrorMap(afid);
49388
+ });
49389
+
49181
49390
  me.myEventCls.onIds("#" + me.pre + "afid", "keyup", function(e) { me.icn3d;
49182
49391
  if (e.keyCode === 13) {
49183
49392
  e.preventDefault();
@@ -49261,8 +49470,8 @@ class Events {
49261
49470
  }
49262
49471
 
49263
49472
  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');
49473
+ //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&bu=0', '_blank');
49474
+ window.open(hostUrl + '?chainalign=' + alignment + '&resnum=' + resalign + '&resdef=' + predefinedres + '&showalignseq=1&bu=0', '_blank');
49266
49475
  });
49267
49476
 
49268
49477
  me.myEventCls.onIds("#" + me.pre + "reload_mutation_3d", "click", function(e) { me.icn3d;
@@ -49337,24 +49546,24 @@ class Events {
49337
49546
  // clickReload_mmdb: function() {
49338
49547
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb", "click", function(e) { me.icn3d;
49339
49548
  e.preventDefault();
49340
- if(!me.cfg.notebook) dialog.dialog( "close" );
49549
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49341
49550
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb1 " + $("#" + me.pre + "mmdbid").val(), false);
49342
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=1', '_blank');
49551
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=1', '_blank');
49343
49552
  });
49344
49553
 
49345
49554
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb_asym", "click", function(e) { me.icn3d;
49346
49555
  e.preventDefault();
49347
- if(!me.cfg.notebook) dialog.dialog( "close" );
49556
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49348
49557
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49349
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49558
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=0', '_blank');
49350
49559
  });
49351
49560
 
49352
49561
  me.myEventCls.onIds("#" + me.pre + "mmdbid", "keyup", function(e) { me.icn3d;
49353
49562
  if (e.keyCode === 13) {
49354
49563
  e.preventDefault();
49355
- if(!me.cfg.notebook) dialog.dialog( "close" );
49564
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
49356
49565
  me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49357
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49566
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&bu=0', '_blank');
49358
49567
  }
49359
49568
  });
49360
49569
 
@@ -49740,6 +49949,35 @@ class Events {
49740
49949
  reader.readAsText(file);
49741
49950
  }
49742
49951
  });
49952
+
49953
+ me.myEventCls.onIds("#" + me.pre + "reload_afmapfile", "click", function(e) { let ic = me.icn3d;
49954
+ e.preventDefault();
49955
+ ic.bInitial = true;
49956
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49957
+ //close all dialog
49958
+ if(!me.cfg.notebook) {
49959
+ $(".ui-dialog-content").dialog("close");
49960
+ }
49961
+ else {
49962
+ ic.resizeCanvasCls.closeDialogs();
49963
+ }
49964
+ let file = $("#" + me.pre + "afmapfile")[0].files[0];
49965
+ if(!file) {
49966
+ var aaa = 1; //alert("Please select a file before clicking 'Load'");
49967
+ }
49968
+ else {
49969
+ me.htmlCls.setHtmlCls.fileSupport();
49970
+ let reader = new FileReader();
49971
+ reader.onload = function(e) {
49972
+ let dataStr = e.target.result; // or = reader.result;
49973
+ me.htmlCls.clickMenuCls.setLogCmd('load AlphaFold aligned error file ' + $("#" + me.pre + "afmapfile").val(), false);
49974
+
49975
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show predicted aligned error map');
49976
+ ic.contactMapCls.processAfErrorMap(JSON.parse(dataStr));
49977
+ };
49978
+ reader.readAsText(file);
49979
+ }
49980
+ });
49743
49981
  // },
49744
49982
  // clickReload_urlfile: function() {
49745
49983
  me.myEventCls.onIds("#" + me.pre + "reload_urlfile", "click", function(e) { let ic = me.icn3d;
@@ -49992,9 +50230,7 @@ class Events {
49992
50230
  me.myEventCls.onIds("#" + me.svgid + "_png", "click", function(e) { let ic = me.icn3d;
49993
50231
  e.preventDefault();
49994
50232
  //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);
50233
+ ic.saveFileCls.savePng(me.svgid, ic.inputid + "_force_directed_graph.png");
49998
50234
  });
49999
50235
  me.myEventCls.onIds("#" + me.svgid + "_json", "click", function(e) { let ic = me.icn3d;
50000
50236
  e.preventDefault();
@@ -50013,9 +50249,7 @@ class Events {
50013
50249
  $(document).on("click", "#" + me.svgid_ct + "_png", function(e) { let ic = me.icn3d;
50014
50250
  e.preventDefault();
50015
50251
  //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);
50252
+ ic.saveFileCls.savePng(me.svgid_ct, ic.inputid + "_cartoon.png");
50019
50253
  });
50020
50254
  $(document).on("click", "#" + me.svgid_ct + "_json", function(e) { let ic = me.icn3d;
50021
50255
  e.preventDefault();
@@ -50041,9 +50275,7 @@ class Events {
50041
50275
  me.myEventCls.onIds("#" + me.linegraphid + "_png", "click", function(e) { let ic = me.icn3d;
50042
50276
  e.preventDefault();
50043
50277
  //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);
50278
+ ic.saveFileCls.savePng(me.linegraphid, ic.inputid + "_line_graph.png");
50047
50279
  });
50048
50280
  me.myEventCls.onIds("#" + me.linegraphid + "_json", "click", function(e) { let ic = me.icn3d;
50049
50281
  e.preventDefault();
@@ -50069,9 +50301,7 @@ class Events {
50069
50301
  me.myEventCls.onIds("#" + me.scatterplotid + "_png", "click", function(e) { let ic = me.icn3d;
50070
50302
  e.preventDefault();
50071
50303
  //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);
50304
+ ic.saveFileCls.savePng(me.scatterplotid, ic.inputid + "_scatterplot.png");
50075
50305
  });
50076
50306
  me.myEventCls.onIds("#" + me.scatterplotid + "_json", "click", function(e) { let ic = me.icn3d;
50077
50307
  e.preventDefault();
@@ -50093,14 +50323,12 @@ class Events {
50093
50323
  me.myEventCls.onIds("#" + me.contactmapid + "_svg", "click", function(e) { let ic = me.icn3d;
50094
50324
  e.preventDefault();
50095
50325
  //if(!me.cfg.notebook) dialog.dialog( "close" );
50096
- ic.saveFileCls.saveSvg(me.contactmapid, ic.inputid + "_contactmap.svg");
50326
+ ic.saveFileCls.saveSvg(me.contactmapid, ic.inputid + "_contactmap.svg", true);
50097
50327
  });
50098
50328
  me.myEventCls.onIds("#" + me.contactmapid + "_png", "click", function(e) { let ic = me.icn3d;
50099
50329
  e.preventDefault();
50100
50330
  //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);
50331
+ ic.saveFileCls.savePng(me.contactmapid, ic.inputid + "_contactmap.png", true);
50104
50332
  });
50105
50333
  me.myEventCls.onIds("#" + me.contactmapid + "_json", "click", function(e) { let ic = me.icn3d;
50106
50334
  e.preventDefault();
@@ -50112,11 +50340,39 @@ class Events {
50112
50340
  ic.saveFileCls.saveFile(ic.inputid + "_contactmap.json", "text", [graphStr2]);
50113
50341
  });
50114
50342
  me.myEventCls.onIds("#" + me.contactmapid + "_scale", "change", function(e) { let ic = me.icn3d;
50343
+ e.preventDefault();
50344
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50345
+ let scale = $("#" + me.contactmapid + "_scale").val();
50346
+ $("#" + me.contactmapid).attr("width",(ic.contactmapWidth * parseFloat(scale)).toString() + "px");
50347
+ me.htmlCls.clickMenuCls.setLogCmd("contactmap scale " + scale, true);
50348
+ });
50349
+
50350
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_svg", "click", function(e) { let ic = me.icn3d;
50351
+ e.preventDefault();
50352
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50353
+ ic.saveFileCls.saveSvg(me.alignerrormapid, ic.inputid + "_alignerrormap.svg", true);
50354
+ });
50355
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_png", "click", function(e) { let ic = me.icn3d;
50356
+ e.preventDefault();
50357
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50358
+ ic.saveFileCls.savePng(me.alignerrormapid, ic.inputid + "_alignerrormap.png", true);
50359
+ });
50360
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_json", "click", function(e) { let ic = me.icn3d;
50361
+ e.preventDefault();
50362
+ //if(!me.cfg.notebook) dialog.dialog( "close" );
50363
+ let graphStr2 = ic.alignerrormapStr.substr(0, ic.alignerrormapStr.lastIndexOf('}'));
50364
+
50365
+ graphStr2 += me.htmlCls.setHtmlCls.getLinkColor();
50366
+
50367
+ ic.saveFileCls.saveFile(ic.inputid + "_alignerrormap.json", "text", [graphStr2]);
50368
+ });
50369
+
50370
+ me.myEventCls.onIds("#" + me.alignerrormapid + "_scale", "change", function(e) { let ic = me.icn3d;
50115
50371
  e.preventDefault();
50116
50372
  //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);
50373
+ let scale = $("#" + me.alignerrormapid + "_scale").val();
50374
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
50375
+ me.htmlCls.clickMenuCls.setLogCmd("alignerrormap scale " + scale, true);
50120
50376
  });
50121
50377
 
50122
50378
  me.myEventCls.onIds("#" + me.svgid + "_label", "change", function(e) { me.icn3d;
@@ -52533,7 +52789,115 @@ class ContactMap {
52533
52789
  }
52534
52790
  }
52535
52791
 
52536
- drawContactMap(lineGraphStr) { let ic = this.icn3d, me = ic.icn3dui;
52792
+ afErrorMap(afid) { let ic = this.icn3d, me = ic.icn3dui;
52793
+ let thisClass = this;
52794
+
52795
+ me.htmlCls.dialogCls.openDlg('dl_alignerrormap', 'Show predicted aligned error map');
52796
+
52797
+ let url, dataType;
52798
+
52799
+ url = "https://alphafold.ebi.ac.uk/files/AF-" + afid + "-F1-predicted_aligned_error_v2.json";
52800
+
52801
+ dataType = "json";
52802
+
52803
+ $.ajax({
52804
+ url: url,
52805
+ dataType: dataType,
52806
+ cache: true,
52807
+ tryCount : 0,
52808
+ retryLimit : 1,
52809
+ success: function(data) {
52810
+ thisClass.processAfErrorMap(data);
52811
+ },
52812
+ error : function(xhr, textStatus, errorThrown ) {
52813
+ this.tryCount++;
52814
+ if(this.tryCount <= this.retryLimit) {
52815
+ //try again
52816
+ $.ajax(this);
52817
+ return;
52818
+ }
52819
+ var aaa = 1; //alert("There are some problems in loading the predicted aligned error file...");
52820
+ return;
52821
+ }
52822
+ });
52823
+ }
52824
+
52825
+ processAfErrorMap(dataJson) { let ic = this.icn3d, me = ic.icn3dui;
52826
+ // json format: [{"residue1": [1, ..., 1, ..., n, ..., n], "residue2": [1, 2, ..., n, ..., 1, 2, ..., n],
52827
+ // "distance": [n*n matrix],"max_predicted_aligned_error":31.75}]
52828
+ let distMatrix = dataJson[0].distance;
52829
+ let max = dataJson[0].max_predicted_aligned_error;
52830
+ if(!distMatrix || !max) {
52831
+ var aaa = 1; //alert("The predicted aligned error file didn't have the right format...");
52832
+ return;
52833
+ }
52834
+
52835
+ // generate lineGraphStr
52836
+ // e.g., {"nodes": [{"id":"A1.A","r":"1_1_1TOP_A_1","s":"ab","x":1,"y":21,"c":"FF00FF"}, ...],
52837
+ // "links": [{"source": "A1.A", "target": "S2.A", "v": 3, "c": "FF00FF"}, ...]}
52838
+ let nodeStr = '"nodes": [', linkStr = '"links": [';
52839
+ let bNode = false, bLink = false;
52840
+ let postA = '', postB = '.';
52841
+
52842
+ // initialize some parameters if no structure wasloaded yet
52843
+ if(!ic.chains) ic.init_base();
52844
+
52845
+ let chainidArray = Object.keys(ic.chains);
52846
+ let chainid = (chainidArray.length == 1) ? chainidArray[0] : 'stru_A';
52847
+
52848
+ let dim = parseInt(Math.sqrt(distMatrix.length));
52849
+
52850
+ //for(let chainid in ic.chains) {
52851
+ //for(let i = 0, il = ic.chainsSeq[chainid].length; i < il; ++i) {
52852
+ for(let i = 0; i < dim; ++i) {
52853
+ let resi = (ic.chainsSeq[chainid]) ? ic.chainsSeq[chainid][i].resi : i + 1;
52854
+ let resn = (ic.chainsSeq[chainid]) ? ic.chainsSeq[chainid][i].name : '*';
52855
+ let resid = chainid + '_' + resi;
52856
+ let atom = (ic.residues[resid]) ? ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid])
52857
+ : {color: me.parasCls.thr(0x888888)};
52858
+ let chain = chainid.substr(chainid.indexOf('_') + 1);
52859
+ let color = atom.color.getHexString();
52860
+
52861
+ if(bNode) nodeStr += ', ';
52862
+ let idStr = resn + resi + '.' + chain;
52863
+ nodeStr += '{"id":"' + idStr + postA + '","r":"1_1_' + resid + '","s":"a","c":"' + color + '"}\n';
52864
+ nodeStr += ', {"id":"' + idStr + postB + '","r":"1_1_' + resid + '","s":"b","c":"' + color + '"}';
52865
+ bNode = true;
52866
+
52867
+ //for(let j = 0, jl = ic.chainsSeq[chainid].length; j < jl; ++j) {
52868
+ //for(let j = 0; j < dim; ++j) {
52869
+ for(let j = i; j < dim; ++j) { // half map
52870
+ let resi2 = (ic.chainsSeq[chainid]) ? ic.chainsSeq[chainid][j].resi : j + 1;
52871
+ let resn2 = (ic.chainsSeq[chainid]) ? ic.chainsSeq[chainid][j].name : '*';
52872
+ let idStr2 = resn2 + resi2 + '.' + chain;
52873
+ let index = i * dim + j;
52874
+ // max dark green color 004d00, 0x4d = 77, 77/255 = 0.302
52875
+ // 0: 004d00, max: FFFFFF
52876
+ let ratio = (distMatrix[index]) ? distMatrix[index] / max : 0;
52877
+ let r = parseInt(ratio*255).toString(16);
52878
+ let g = parseInt(((1.0 - 0.302)*ratio + 0.302) * 255).toString(16);
52879
+ let rHex = (r.length == 1) ? '0' + r : r;
52880
+ let gHex = (g.length == 1) ? '0' + g : g;
52881
+ let bHex = rHex;
52882
+ let color2 = rHex + gHex + bHex;
52883
+
52884
+ if(bLink) linkStr += ', ';
52885
+ linkStr += '{"source": "' + idStr + postA + '", "target": "' + idStr2 + postB + '", "v": 11, "c": "' + color2 + '"}\n';
52886
+ bLink = true;
52887
+ }
52888
+ }
52889
+ //}
52890
+
52891
+ dataJson = {};
52892
+
52893
+ let lineGraphStr = '{' + nodeStr + '], ' + linkStr + ']}';
52894
+ let bAfMap = true;
52895
+ this.drawContactMap(lineGraphStr, bAfMap, max);
52896
+
52897
+ if(ic.deferredAfmap !== undefined) ic.deferredAfmap.resolve();
52898
+ }
52899
+
52900
+ drawContactMap(lineGraphStr, bAfMap, max) { let ic = this.icn3d, me = ic.icn3dui;
52537
52901
  let html, graph = JSON.parse(lineGraphStr);
52538
52902
  let linkArray = graph.links;
52539
52903
 
@@ -52567,7 +52931,7 @@ class ContactMap {
52567
52931
 
52568
52932
  let graphStr = '{\n';
52569
52933
 
52570
- let struc1 = Object.keys(ic.structures)[0];
52934
+ let struc1 = (ic.structures.length > 0) ? ic.structures[0] : 'stru';
52571
52935
  let len1 = nodeArray1.length,
52572
52936
  len2 = nodeArray2.length;
52573
52937
  let factor = 1;
@@ -52581,20 +52945,76 @@ class ContactMap {
52581
52945
  width =(len2 + 2) *(r + gap) + 2 * marginX + legendWidth;
52582
52946
 
52583
52947
  let id, graphWidth;
52584
- ic.contactmapWidth = 2 * width;
52585
- graphWidth = ic.contactmapWidth;
52586
- id = me.contactmapid;
52948
+ if(bAfMap) {
52949
+ ic.alignerrormapWidth = 2 * width;
52950
+ graphWidth = ic.alignerrormapWidth;
52951
+ id = me.alignerrormapid;
52952
+ }
52953
+ else {
52954
+ ic.contactmapWidth = 2 * width;
52955
+ graphWidth = ic.contactmapWidth;
52956
+ id = me.contactmapid;
52957
+ }
52958
+
52587
52959
  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'>";
52960
+ html += "<svg xmlns='http://www.w3.org/2000/svg' id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
52589
52961
  let bContactMap = true;
52590
- html += ic.lineGraphCls.drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, 0, bContactMap);
52962
+
52963
+ if(bAfMap) { // cleaned the code by using "use" in SVG, but didn't improve rendering
52964
+ let factor = 1;
52965
+ let r = 3 * factor;
52966
+ let rectSize = 2 * r;
52967
+
52968
+ ic.hex2id = {};
52969
+ let threshold = 29.0 / max;
52970
+ ic.hex2skip = {}; // do not display any error larger than 29 angstrom
52971
+
52972
+ html += "<defs>";
52973
+
52974
+ let linestrokewidth = 1;
52975
+ let nRef = 1000;
52976
+ for(let i = 0; i < nRef; ++i) {
52977
+ let ratio = 1.0 * i / nRef;
52978
+ let r = parseInt(ratio*255).toString(16);
52979
+ let g = parseInt(((1.0 - 0.302)*ratio + 0.302) * 255).toString(16);
52980
+ let rHex = (r.length == 1) ? '0' + r : r;
52981
+ let gHex = (g.length == 1) ? '0' + g : g;
52982
+ let bHex = rHex;
52983
+ let color = rHex + gHex + bHex;
52984
+ let strokecolor = "#" + color;
52985
+
52986
+ let idRect = me.pre + "afmap_" + i;
52987
+
52988
+ ic.hex2id[color] = idRect;
52989
+ if(ratio > threshold) {
52990
+ ic.hex2skip[color] = idRect;
52991
+ }
52992
+
52993
+ //html += "<g id='" + id + "'>";
52994
+ html += "<rect id='" + idRect + "' x='0' y='0' width='" + rectSize + "' height='" + rectSize + "' fill='"
52995
+ + strokecolor + "' stroke-width='" + linestrokewidth + "' stroke='" + strokecolor + "' />";
52996
+ //html += "</g>"
52997
+ }
52998
+ html += "</defs>";
52999
+ }
53000
+
53001
+ html += ic.lineGraphCls.drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, 0, bContactMap, undefined, undefined, bAfMap);
52591
53002
  graphStr += ic.getGraphCls.updateGraphJson(struc1, 1, nodeArray1, nodeArray2, linkArray);
52592
53003
  html += "</svg>";
52593
53004
 
52594
53005
  graphStr += '}\n';
52595
- ic.contactmapStr = graphStr;
53006
+ if(bAfMap) {
53007
+ ic.alignerrormapStr = graphStr;
53008
+ $("#" + ic.pre + "alignerrormapDiv").html(html);
53009
+
53010
+ let scale = $("#" + me.alignerrormapid + "_scale").val();
53011
+ $("#" + me.alignerrormapid).attr("width",(ic.alignerrormapWidth * parseFloat(scale)).toString() + "px");
53012
+ }
53013
+ else {
53014
+ ic.contactmapStr = graphStr;
53015
+ $("#" + ic.pre + "contactmapDiv").html(html);
53016
+ }
52596
53017
 
52597
- $("#" + ic.pre + "contactmapDiv").html(html);
52598
53018
  return html;
52599
53019
  }
52600
53020
  }
@@ -55151,7 +55571,7 @@ class iCn3DUI {
55151
55571
  //even when multiple iCn3D viewers are shown together.
55152
55572
  this.pre = this.cfg.divid + "_";
55153
55573
 
55154
- this.REVISION = '3.7.1';
55574
+ this.REVISION = '3.8.0';
55155
55575
 
55156
55576
  // In nodejs, iCn3D defines "window = {navigator: {}}"
55157
55577
  this.bNode = (Object.keys(window).length < 2) ? true : false;