icn3d 3.4.11 → 3.7.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 +1551 -566
  2. package/package.json +1 -1
package/icn3d.js CHANGED
@@ -3952,7 +3952,7 @@ class ParasCls {
3952
3952
  black: this.thr(0x000000),
3953
3953
  grey: this.thr(0xCCCCCC),
3954
3954
  white: this.thr(0xFFFFFF),
3955
- transparent: this.thr(0x000000)
3955
+ transparent: this.thr(0xFFFFFF) //this.thr(0x000000)
3956
3956
  };
3957
3957
 
3958
3958
  this.residueColors = {
@@ -4113,6 +4113,7 @@ class ParasCls {
4113
4113
  }
4114
4114
 
4115
4115
  thr(color) { this.icn3dui;
4116
+ if(color == '#0') color = '#000';
4116
4117
  return new THREE.Color(color);
4117
4118
  }
4118
4119
  }
@@ -4483,6 +4484,16 @@ class UtilsCls {
4483
4484
  if(viewer_width && me.htmlCls.WIDTH > viewer_width) me.htmlCls.WIDTH = viewer_width;
4484
4485
  if(viewer_height && me.htmlCls.HEIGHT > viewer_height) me.htmlCls.HEIGHT = viewer_height;
4485
4486
  }
4487
+
4488
+ sumArray(numArray) {
4489
+ let sum = 0;
4490
+
4491
+ for(let i = 0, il = numArray.length; i < il; ++i) {
4492
+ sum += numArray[i];
4493
+ }
4494
+
4495
+ return sum;
4496
+ }
4486
4497
  }
4487
4498
 
4488
4499
  /**
@@ -7258,7 +7269,8 @@ class Strand {
7258
7269
  let atomsAdjust = {};
7259
7270
 
7260
7271
  //if( (bHighlight === 1 || bHighlight === 2) && !ic.bAllAtoms) {
7261
- if( !ic.bAllAtoms) {
7272
+ //if( !ic.bAllAtoms) {
7273
+ if( Object.keys(atoms).length < Object.keys(ic.atoms).length) {
7262
7274
  atomsAdjust = this.getSSExpandedAtoms(atoms);
7263
7275
  }
7264
7276
  else {
@@ -11885,7 +11897,8 @@ class ShareLink {
11885
11897
 
11886
11898
  if(ic.commands.length > start) {
11887
11899
  let command_tf = ic.commands[start].split('|||');
11888
- prevCommandStr = command_tf[0].trim();
11900
+ let command_tf2 = command_tf[0].split('&command=');
11901
+ prevCommandStr = command_tf2[0].trim();
11889
11902
 
11890
11903
  //statefile += ic.commands[start] + "\n";
11891
11904
 
@@ -11896,7 +11909,8 @@ class ShareLink {
11896
11909
  let tmpUrl = '';
11897
11910
  for(let il = ic.commands.length; i < il; ++i) {
11898
11911
  let command_tf = ic.commands[i].split('|||');
11899
- let commandStr = command_tf[0].trim();
11912
+ let command_tf2 = command_tf[0].split('&command=');
11913
+ let commandStr = command_tf2[0].trim();
11900
11914
 
11901
11915
  //statefile += ic.commands[i] + "\n";
11902
11916
 
@@ -11947,7 +11961,7 @@ class ShareLink {
11947
11961
  }
11948
11962
 
11949
11963
  statefile = statefile.replace(/!/g, Object.keys(ic.structures)[0] + '_');
11950
- if((ic.bInputfile && !ic.bInputUrlfile) || url.length > 4000) url = statefile;
11964
+ if((ic.bInputfile && !ic.bInputUrlfile) || (ic.bInputUrlfile && ic.bAppend) || url.length > 4000) url = statefile;
11951
11965
  let id;
11952
11966
  if(ic.structures !== undefined && Object.keys(ic.structures).length == 1 && ic.inputid !== undefined) {
11953
11967
  id = Object.keys(ic.structures)[0];
@@ -11967,22 +11981,27 @@ class ShareLink {
11967
11981
 
11968
11982
  let text = "";
11969
11983
  if(ic.bInputfile) {
11970
- url = this.shareLinkUrl(bAllCommands); // output state file if ic.bInputfile is true or the URL is mor than 4000 chars
11984
+ url = this.shareLinkUrl(bAllCommands); // output state file if ic.bInputfile is true or the URL is more than 4000 chars
11971
11985
 
11972
- text += "\nStart of type file======\n";
11973
- text += ic.InputfileType + "\n";
11974
- text += "End of type file======\n";
11986
+ if(url.substr(0,4) == 'http') {
11987
+ text += "\nShare Link: " + url;
11988
+ }
11989
+ else {
11990
+ text += "\nStart of type file======\n";
11991
+ text += ic.InputfileType + "\n";
11992
+ text += "End of type file======\n";
11975
11993
 
11976
- text += "Start of data file======\n";
11977
- //text += ic.InputfileData;
11978
- /// text += ic.saveFileCls.getPDBHeader();
11979
- text += ic.saveFileCls.getAtomPDB(ic.atoms);
11994
+ text += "Start of data file======\n";
11995
+ //text += ic.InputfileData;
11996
+ /// text += ic.saveFileCls.getPDBHeader();
11997
+ text += ic.saveFileCls.getAtomPDB(ic.atoms);
11980
11998
 
11981
- text += "End of data file======\n";
11999
+ text += "End of data file======\n";
11982
12000
 
11983
- text += "Start of state file======\n";
11984
- text += url;
11985
- text += "End of state file======\n";
12001
+ text += "Start of state file======\n";
12002
+ text += url + "\n";
12003
+ text += "End of state file======\n";
12004
+ }
11986
12005
  }
11987
12006
  else {
11988
12007
  url = this.shareLinkUrl();
@@ -11992,7 +12011,7 @@ class ShareLink {
11992
12011
 
11993
12012
  text += "\nStart of state file======\n";
11994
12013
 
11995
- text += url;
12014
+ text += url + "\n";
11996
12015
  text += "End of state file======\n";
11997
12016
  }
11998
12017
  else {
@@ -12018,11 +12037,14 @@ class HlObjects {
12018
12037
  //Show the highlight for the selected atoms: hAtoms.
12019
12038
  addHlObjects(color, bRender, atomsHash) { let ic = this.icn3d, me = ic.icn3dui;
12020
12039
  if(color === undefined) color = ic.hColor;
12021
- if(atomsHash === undefined) atomsHash = ic.hAtoms;
12040
+ //if(atomsHash === undefined) atomsHash = ic.hAtoms;
12041
+ let atomsHashDisplay = (atomsHash) ? me.hashUtilsCls.intHash(atomsHash, ic.dAtoms) : me.hashUtilsCls.intHash(ic.hAtoms, ic.dAtoms);
12022
12042
 
12023
- ic.applyDisplayCls.applyDisplayOptions(ic.opts, me.hashUtilsCls.intHash(atomsHash, ic.dAtoms), ic.bHighlight);
12043
+ ic.applyDisplayCls.applyDisplayOptions(ic.opts, atomsHashDisplay, ic.bHighlight);
12024
12044
 
12025
- if( (bRender) || (ic.bRender) ) ic.drawCls.render();
12045
+ if( (bRender) || (ic.bRender) ) {
12046
+ ic.drawCls.render();
12047
+ }
12026
12048
  };
12027
12049
 
12028
12050
  //Remove the highlight. The atom selection does not change.
@@ -14311,6 +14333,9 @@ class HBond {
14311
14333
  break;
14312
14334
  }
14313
14335
  }
14336
+
14337
+ if(!C_atom) continue;
14338
+
14314
14339
  let inAcceptorC = C_atom.coord;
14315
14340
  let inAcceptorO = inAcceptor.coord;
14316
14341
 
@@ -14585,9 +14610,10 @@ class PiHalogen {
14585
14610
  // available in 1a and 1b
14586
14611
  // only parallel or perpendicular
14587
14612
  if(interactionType == 'pi-stacking' && atom1.normal !== undefined && atom2.normal !== undefined) {
14588
- let dotResult = Math.abs(atom1.normal.dot(atom2.normal));
14613
+ Math.abs(atom1.normal.dot(atom2.normal));
14589
14614
  // perpendicular 30 degree || parellel, 30 degree
14590
- if(dotResult > 0.5 && dotResult < 0.866) continue;
14615
+ // remove this condition on Nov 19, 2021
14616
+ //if(dotResult > 0.5 && dotResult < 0.866) continue;
14591
14617
  }
14592
14618
 
14593
14619
  let bResult = this.getHalogenPiInteractions(atom1, atom2, type, interactionType, threshold, maxlengthSq, oriResidName, bInternal);
@@ -15467,7 +15493,7 @@ class GetGraph {
15467
15493
  let strokecolor = '#000';
15468
15494
  let strokewidth = '1';
15469
15495
  let textcolor = '#000';
15470
- let fontsize = '6';
15496
+ let fontsize = '6px'; // '6';
15471
15497
  let html = "<g class='icn3d-node' resid='" + resid + "' >";
15472
15498
  html += "<title>" + node.id + "</title>";
15473
15499
  if(bVertical) {
@@ -15481,23 +15507,31 @@ class GetGraph {
15481
15507
  html += "</g>";
15482
15508
  return html;
15483
15509
  }
15484
- getNodeTopBottom(nameHash, name2node, bReverseNode) { let ic = this.icn3d; ic.icn3dui;
15510
+ getNodeTopBottom(nameHash, name2node, bReverseNode, bCommon, nameHashCommon) { let ic = this.icn3d, me = ic.icn3dui;
15485
15511
  let thisClass = this;
15486
- let nodeArray1 = [], nodeArray2 = [];
15512
+ let nodeArray1 = [], nodeArray2 = [], name2nodeCommon = {};
15487
15513
  for(let name in nameHash) {
15488
15514
  let node = name2node[name];
15489
15515
  if(!node) continue;
15490
15516
 
15517
+ if(bCommon) {
15518
+ node = me.hashUtilsCls.cloneHash(node);
15519
+
15520
+ let mapping = (nameHashCommon[name]) ? nameHashCommon[name] : '-';
15521
+ node.id += ">" + mapping;
15522
+ name2nodeCommon[node.id] = node;
15523
+ }
15524
+
15491
15525
  if(node.s == 'a') {
15492
15526
  nodeArray1.push(node);
15493
15527
  }
15494
15528
  else if(node.s == 'b') {
15495
15529
  nodeArray2.push(node);
15496
15530
  }
15497
- else if(node.s == 'ab') {
15498
- nodeArray1.push(node);
15499
- nodeArray2.push(node);
15500
- }
15531
+ //else if(node.s == 'ab') {
15532
+ // nodeArray1.push(node);
15533
+ // nodeArray2.push(node);
15534
+ //}
15501
15535
  }
15502
15536
  // sort array
15503
15537
  nodeArray1.sort(function(a,b) {
@@ -15506,7 +15540,7 @@ class GetGraph {
15506
15540
  nodeArray2.sort(function(a,b) {
15507
15541
  return thisClass.compNode(a, b, bReverseNode);
15508
15542
  });
15509
- return {"nodeArray1": nodeArray1, "nodeArray2": nodeArray2}
15543
+ return {"nodeArray1": nodeArray1, "nodeArray2": nodeArray2, "name2node": name2nodeCommon};
15510
15544
  }
15511
15545
  updateGraphJson(struc, index, nodeArray1, nodeArray2, linkArray) { let ic = this.icn3d, me = ic.icn3dui;
15512
15546
  let lineGraphStr = '';
@@ -15829,22 +15863,31 @@ class LineGraph {
15829
15863
  let structureArray = ic.resid2specCls.atoms2structureArray(ic.hAtoms);
15830
15864
  //if(Object.keys(ic.structures).length > 1) {
15831
15865
  if(structureArray.length > 1) {
15832
- let nodeArray1a = [],
15833
- nodeArray1b = [],
15834
- nodeArray2a = [],
15835
- nodeArray2b = [],
15836
- nodeArray3a = [],
15837
- nodeArray3b = [];
15838
- //let struc1 = Object.keys(ic.structures)[0],
15839
- // struc2 = Object.keys(ic.structures)[1];
15840
- let struc1 = structureArray[0],
15841
- struc2 = structureArray[1];
15842
- let linkArrayA = [],
15843
- linkArrayB = [],
15844
- linkArrayAB = [];
15845
- let nameHashA = {},
15846
- nameHashB = {},
15847
- nameHashAB = {};
15866
+
15867
+ let struc2index= {};
15868
+ let nodeArray1Split = [], nodeArray2Split = [], linkArraySplit = [], nameHashSplit = [];
15869
+
15870
+ // show common interactions: nodes will be the same. The links/interactins are different.
15871
+ // The mapped residue name and number are attached to "id".
15872
+ // Original node: {id : "Q24.A.2AJF", r : "1_1_2AJF_A_24", s: "a", ...}
15873
+ // Node for common interaction: {id : "Q24.A.2AJF|Q24", r : "1_1_2AJF_A_24", s: "a", ...}
15874
+ let nodeArray1SplitCommon = [], nodeArray2SplitCommon = [], linkArraySplitCommon = [], nameHashSplitCommon = [];
15875
+ let linkedNodeCnt = {};
15876
+
15877
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15878
+ nodeArray1Split[i] = [];
15879
+ nodeArray2Split[i] = [];
15880
+ linkArraySplit[i] = [];
15881
+ nameHashSplit[i] = {};
15882
+
15883
+ nodeArray1SplitCommon[i] = [];
15884
+ nodeArray2SplitCommon[i] = [];
15885
+ linkArraySplitCommon[i] = [];
15886
+ nameHashSplitCommon[i] = {};
15887
+
15888
+ struc2index[structureArray[i]] = i;
15889
+ }
15890
+
15848
15891
  for(let i = 0, il = linkArray.length; i < il; ++i) {
15849
15892
  let link = linkArray[i];
15850
15893
  let nodeA = name2node[link.source];
@@ -15854,70 +15897,131 @@ class LineGraph {
15854
15897
  continue;
15855
15898
  }
15856
15899
 
15857
- //var idArrayA = nodeA.r.split('_'); // 1_1_1KQ2_A_1
15858
- let idArrayA = [];
15859
- idArrayA.push('');
15860
- idArrayA.push('');
15900
+ let idArrayA = this.getIdArrayFromNode(nodeA);
15901
+ let idArrayB = this.getIdArrayFromNode(nodeB);
15861
15902
 
15862
- let tmpStr = nodeA.r.substr(4);
15863
- idArrayA = idArrayA.concat(me.utilsCls.getIdArray(tmpStr));
15903
+ let index = struc2index[idArrayA[2]];
15864
15904
 
15865
- //var idArrayB = nodeB.r.split('_'); // 1_1_1KQ2_A_1
15866
- let idArrayB = [];
15867
- idArrayB.push('');
15868
- idArrayB.push('');
15905
+ if(idArrayA[2] == structureArray[index] && idArrayB[2] == structureArray[index]) {
15906
+ linkArraySplit[index].push(link);
15907
+ nameHashSplit[index][link.source] = 1;
15908
+ nameHashSplit[index][link.target] = 1;
15869
15909
 
15870
- tmpStr = nodeB.r.substr(4);
15871
- idArrayB = idArrayB.concat(me.utilsCls.getIdArray(tmpStr));
15910
+ let chainid1 = idArrayA[2] + '_' + idArrayA[3];
15911
+ let chainid2 = idArrayB[2] + '_' + idArrayB[3];
15912
+ let resid1 = chainid1 + '_' + idArrayA[4];
15913
+ let resid2 = chainid2 + '_' + idArrayB[4];
15872
15914
 
15873
- if(idArrayA[2] == struc1 && idArrayB[2] == struc1) {
15874
- linkArrayA.push(link);
15875
- nameHashA[link.source] = 1;
15876
- nameHashA[link.target] = 1;
15877
- } else if(idArrayA[2] == struc2 && idArrayB[2] == struc2) {
15878
- linkArrayB.push(link);
15879
- nameHashB[link.source] = 1;
15880
- nameHashB[link.target] = 1;
15881
- } else {
15882
- linkArrayAB.push(link);
15883
- nameHashAB[link.source] = 1;
15884
- nameHashAB[link.target] = 1;
15885
- }
15886
- }
15887
- let nodeArraysA = ic.getGraphCls.getNodeTopBottom(nameHashA, name2node);
15888
- nodeArray1a = nodeArraysA.nodeArray1;
15889
- nodeArray1b = nodeArraysA.nodeArray2;
15890
- let nodeArraysB = ic.getGraphCls.getNodeTopBottom(nameHashB, name2node);
15891
- nodeArray2a = nodeArraysB.nodeArray1;
15892
- nodeArray2b = nodeArraysB.nodeArray2;
15893
- let nodeArraysAB = ic.getGraphCls.getNodeTopBottom(nameHashAB, name2node, true);
15894
- nodeArray3a = nodeArraysAB.nodeArray1;
15895
- nodeArray3b = nodeArraysAB.nodeArray2;
15896
- let len1a = nodeArray1a.length,
15897
- len1b = nodeArray1b.length;
15898
- let len2a = nodeArray2a.length,
15899
- len2b = nodeArray2b.length;
15900
- let len3a = nodeArray3a.length,
15901
- len3b = nodeArray3b.length;
15902
- let maxLen = Math.max(len1a, len1b, len2a, len2b, len3a, len3b);
15915
+ let mapping1, mapping2;
15916
+
15917
+ if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15918
+ && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15919
+ mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
15920
+ mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
15921
+
15922
+ let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15923
+ if(!linkedNodeCnt.hasOwnProperty(mappingid)) {
15924
+ linkedNodeCnt[mappingid] = 1;
15925
+ }
15926
+ else {
15927
+ ++linkedNodeCnt[mappingid];
15928
+ }
15929
+ }
15930
+ }
15931
+ }
15932
+
15933
+ // set linkArraySplitCommon and nameHashSplitCommon
15934
+ for(let i = 0, il = linkArray.length; i < il; ++i) {
15935
+ let link = linkArray[i];
15936
+ let nodeA = name2node[link.source];
15937
+ let nodeB = name2node[link.target];
15938
+
15939
+ if(!nodeA || !nodeB || !nodeA.r || !nodeB.r) {
15940
+ continue;
15941
+ }
15942
+
15943
+ let idArrayA = this.getIdArrayFromNode(nodeA);
15944
+ let idArrayB = this.getIdArrayFromNode(nodeB);
15945
+
15946
+ let index = struc2index[idArrayA[2]];
15947
+
15948
+ if(idArrayA[2] == structureArray[index] && idArrayB[2] == structureArray[index]) {
15949
+ let chainid1 = idArrayA[2] + '_' + idArrayA[3];
15950
+ let chainid2 = idArrayB[2] + '_' + idArrayB[3];
15951
+ let resid1 = chainid1 + '_' + idArrayA[4];
15952
+ let resid2 = chainid2 + '_' + idArrayB[4];
15953
+
15954
+ let mapping1, mapping2;
15955
+
15956
+ if(ic.chainsMapping[chainid1] && ic.chainsMapping[chainid1][resid1]
15957
+ && ic.chainsMapping[chainid2] && ic.chainsMapping[chainid2][resid2]) {
15958
+ mapping1 = (nodeA.s == "a") ? ic.chainsMapping[chainid1][resid1] : ic.chainsMapping[chainid2][resid2];
15959
+ mapping2 = (nodeA.s == "a") ? ic.chainsMapping[chainid2][resid2] : ic.chainsMapping[chainid1][resid1];
15960
+
15961
+ let mappingid = mapping1 + '_' + mapping2 + '_' + link.c; // link.c determines the interaction type
15962
+
15963
+ if(linkedNodeCnt[mappingid] == structureArray.length) {
15964
+ let linkCommon = me.hashUtilsCls.cloneHash(link);
15965
+ linkCommon.source += '>' + ic.chainsMapping[chainid1][resid1];
15966
+ linkCommon.target += '>' + ic.chainsMapping[chainid2][resid2];
15967
+
15968
+ linkArraySplitCommon[index].push(linkCommon);
15969
+ }
15970
+
15971
+ nameHashSplitCommon[index][link.source] = ic.chainsMapping[chainid1][resid1];
15972
+ nameHashSplitCommon[index][link.target] = ic.chainsMapping[chainid2][resid2];
15973
+ }
15974
+ }
15975
+ }
15976
+
15977
+ let len1Split = [], len2Split = [], maxWidth = 0;
15903
15978
  let strucArray = [];
15904
- if(linkArrayA.length > 0) strucArray.push(struc1);
15905
- if(linkArrayB.length > 0) strucArray.push(struc2);
15906
- if(linkArrayAB.length > 0) strucArray.push(struc1 + '_' + struc2);
15979
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15980
+ let nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node);
15981
+ nodeArray1Split[i] = nodeArraysTmp.nodeArray1;
15982
+ nodeArray2Split[i] = nodeArraysTmp.nodeArray2;
15983
+
15984
+ let bCommon = true;
15985
+ nodeArraysTmp = ic.getGraphCls.getNodeTopBottom(nameHashSplit[i], name2node, undefined, bCommon, nameHashSplitCommon[i]);
15986
+ nodeArray1SplitCommon[i] = nodeArraysTmp.nodeArray1;
15987
+ nodeArray2SplitCommon[i] = nodeArraysTmp.nodeArray2;
15988
+ name2node = me.hashUtilsCls.unionHash(name2node, nodeArraysTmp.name2node);
15989
+
15990
+ len1Split[i] = nodeArray1Split[i].length;
15991
+ len2Split[i] = nodeArray2Split[i].length;
15992
+
15993
+ maxWidth = Math.max(maxWidth, len2Split[i]);
15994
+
15995
+ //if(linkArraySplit[i].length > 0) strucArray.push(structureArray[i]);
15996
+ strucArray.push(structureArray[i]);
15997
+ }
15998
+
15907
15999
  let factor = 1;
15908
16000
  let r = 3 * factor;
15909
16001
  let gap = 7 * factor;
15910
16002
  let height, width, heightAll;
15911
16003
  let marginX = 10,
15912
16004
  marginY = 10,
15913
- legendWidth = 30;
16005
+ legendWidth = 30,
16006
+ textHeight = 20;
16007
+
15914
16008
  if(bScatterplot) {
15915
- heightAll =(len1a + 2 + len2a + 2) *(r + gap) + 4 * marginY + 2 * legendWidth;
15916
- width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16009
+ //heightAll =(len1a + 2 + len2a + 2) *(r + gap) + 4 * marginY + 2 * legendWidth;
16010
+ //width =(Math.max(len1b, len2b) + 2) *(r + gap) + 2 * marginX + legendWidth;
16011
+ heightAll =(me.utilsCls.sumArray(len1Split) + 2*strucArray.length) *(r + gap) + 4 * marginY
16012
+ + 2 * legendWidth + textHeight*strucArray.length;
16013
+ // show common interaction as well
16014
+ heightAll *= 2;
16015
+
16016
+ width = (maxWidth + 2) * (r + gap) + 2 * marginX + legendWidth;
16017
+
15917
16018
  } else {
15918
- height = 110;
16019
+ height = 110 + textHeight;
15919
16020
  heightAll = height * strucArray.length;
15920
- width = maxLen *(r + gap) + 2 * marginX;
16021
+ // show common interaction as well
16022
+ heightAll *= 2;
16023
+
16024
+ width = (maxWidth + 2) * (r + gap) + 2 * marginX;
15921
16025
  }
15922
16026
  let id, graphWidth;
15923
16027
  if(bScatterplot) {
@@ -15930,43 +16034,42 @@ class LineGraph {
15930
16034
  id = me.linegraphid;
15931
16035
  }
15932
16036
  html =(strucArray.length == 0) ? "No interactions found for each structure<br><br>" :
15933
- "2D integration graph for structure(s) <b>" + strucArray + "</b><br><br>";
16037
+ "2D integration graph for " + strucArray.length + " structure(s) <b>" + strucArray + "</b>. Common interactions are shown in the last " + strucArray.length + " graphs.<br><br>";
15934
16038
  html += "<svg id='" + id + "' viewBox='0,0," + width + "," + heightAll + "' width='" + graphWidth + "px'>";
15935
- let heightFinal = 0;
15936
- if(linkArrayA.length > 0) {
16039
+
16040
+ let heightFinal = 0;
16041
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15937
16042
  if(bScatterplot) {
15938
- heightFinal -= 15;
15939
- html += this.drawScatterplot_base(nodeArray1a, nodeArray1b, linkArrayA, name2node, heightFinal);
15940
- heightFinal = 15;
15941
- height =(len1a + 1) *(r + gap) + 2 * marginY;
16043
+ //heightFinal -= 15;
16044
+ html += this.drawScatterplot_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, undefined, "Interactions in structure " + strucArray[i], textHeight);
16045
+ //heightFinal = 15;
16046
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
15942
16047
  } else {
15943
- html += this.drawLineGraph_base(nodeArray1a, nodeArray1b, linkArrayA, name2node, heightFinal);
16048
+ html += this.drawLineGraph_base(nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i], name2node, heightFinal, "Interactions in structure " + strucArray[i], textHeight);
15944
16049
  }
15945
16050
  heightFinal += height;
15946
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(struc1, 1, nodeArray1a, nodeArray1b, linkArrayA);
16051
+
16052
+ if(i > 0) ic.lineGraphStr += ', \n';
16053
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i, nodeArray1Split[i], nodeArray2Split[i], linkArraySplit[i]);
15947
16054
  }
15948
- if(linkArrayB.length > 0) {
16055
+
16056
+ // draw common interaction
16057
+ for(let i = 0, il = structureArray.length; i < il; ++i) {
15949
16058
  if(bScatterplot) {
15950
- html += this.drawScatterplot_base(nodeArray2a, nodeArray2b, linkArrayB, name2node, heightFinal);
15951
- height =(len2a + 1) *(r + gap) + 2 * marginY;
16059
+ //heightFinal -= 15;
16060
+ html += this.drawScatterplot_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, undefined, "Common interactions in structure " + strucArray[i], textHeight);
16061
+ //heightFinal = 15;
16062
+ height =(len1Split[i] + 1) *(r + gap) + 2 * marginY + textHeight;
15952
16063
  } else {
15953
- html += this.drawLineGraph_base(nodeArray2a, nodeArray2b, linkArrayB, name2node, heightFinal);
16064
+ html += this.drawLineGraph_base(nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i], name2node, heightFinal, "Common interactions in structure " + strucArray[i], textHeight);
15954
16065
  }
15955
16066
  heightFinal += height;
15956
- if(linkArrayA.length > 0) ic.lineGraphStr += ', \n';
15957
- ic.lineGraphStr += ic.getGraphCls.updateGraphJson(struc2, 2, nodeArray2a, nodeArray2b, linkArrayB);
15958
- }
15959
- if(linkArrayAB.length > 0 && !bScatterplot) {
15960
- html += this.drawLineGraph_base(nodeArray3a, nodeArray3b, linkArrayAB, name2node, heightFinal);
15961
- if(linkArrayA.length > 0 || linkArrayB.length > 0) ic.lineGraphStr += ', \n';
15962
- ic.lineGraphStr += '"structure1_2": {"id1": "' + struc1 + '", "id2": "' + struc2 + '", "nodes1":[';
15963
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(nodeArray3a);
15964
- ic.lineGraphStr += '], \n"nodes2":[';
15965
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(nodeArray3b);
15966
- ic.lineGraphStr += '], \n"links":[';
15967
- ic.lineGraphStr += me.utilsCls.getJSONFromArray(linkArrayAB);
15968
- ic.lineGraphStr += ']}';
16067
+
16068
+ //if(i > 0) ic.lineGraphStr += ', \n';
16069
+ ic.lineGraphStr += ', \n';
16070
+ ic.lineGraphStr += ic.getGraphCls.updateGraphJson(strucArray[i], i + '_common', nodeArray1SplitCommon[i], nodeArray2SplitCommon[i], linkArraySplitCommon[i]);
15969
16071
  }
16072
+
15970
16073
  html += "</svg>";
15971
16074
  } else {
15972
16075
  if(!bScatterplot) {
@@ -16024,7 +16127,18 @@ class LineGraph {
16024
16127
  return html;
16025
16128
  }
16026
16129
 
16027
- drawLineGraph_base(nodeArray1, nodeArray2, linkArray, name2node, height) { let ic = this.icn3d, me = ic.icn3dui;
16130
+ getIdArrayFromNode(node) { let ic = this.icn3d, me = ic.icn3dui;
16131
+ let idArray = []; // 1_1_1KQ2_A_1
16132
+ idArray.push('');
16133
+ idArray.push('');
16134
+
16135
+ let tmpStr = node.r.substr(4);
16136
+ idArray = idArray.concat(me.utilsCls.getIdArray(tmpStr));
16137
+
16138
+ return idArray;
16139
+ }
16140
+
16141
+ drawLineGraph_base(nodeArray1, nodeArray2, linkArray, name2node, height, label, textHeight) { let ic = this.icn3d, me = ic.icn3dui;
16028
16142
  let html = '';
16029
16143
  let len1 = nodeArray1.length,
16030
16144
  len2 = nodeArray2.length;
@@ -16041,6 +16155,11 @@ class LineGraph {
16041
16155
  margin2 = margin;
16042
16156
  margin1 = Math.abs(len1 - len2) *(r + gap) * 0.5 + margin;
16043
16157
  }
16158
+
16159
+ // draw label
16160
+ height += textHeight;
16161
+ html += "<text x='" + margin1 + "' y='" + height + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16162
+
16044
16163
  let h1 = 30 + height,
16045
16164
  h2 = 80 + height;
16046
16165
  let nodeHtml = '';
@@ -16096,7 +16215,7 @@ class LineGraph {
16096
16215
  return html;
16097
16216
  }
16098
16217
 
16099
- drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap) { let ic = this.icn3d; ic.icn3dui;
16218
+ drawScatterplot_base(nodeArray1, nodeArray2, linkArray, name2node, height, bContactMap, label, textHeight) { let ic = this.icn3d; ic.icn3dui;
16100
16219
  let html = '';
16101
16220
  let len1 = nodeArray1.length,
16102
16221
  len2 = nodeArray2.length;
@@ -16107,12 +16226,19 @@ class LineGraph {
16107
16226
  let marginX = 10,
16108
16227
  marginY = 20;
16109
16228
  let heightTotal =(len1 + 1) *(r + gap) + legendWidth + 2 * marginY;
16229
+
16230
+ // draw label
16231
+ height += textHeight;
16232
+
16233
+ html += "<text x='" + marginX + "' y='" + (height + 15).toString() + "' style='font-size:8px; font-weight:bold'>" + label + "</text>";
16234
+
16110
16235
  let margin1 = height + heightTotal -(legendWidth + marginY +(r + gap)); // y-axis
16111
16236
  let margin2 = legendWidth + marginX +(r + gap); // x-axis
16112
- let x = legendWidth + marginX;
16237
+
16113
16238
  let nodeHtml = '';
16114
16239
  let node2posSet1 = {},
16115
16240
  node2posSet2 = {};
16241
+ let x = legendWidth + marginX;
16116
16242
  for(let i = 0; i < len1; ++i) {
16117
16243
  nodeHtml += ic.getGraphCls.drawResNode(nodeArray1[i], i, r, gap, margin1, x, 'a', true);
16118
16244
  node2posSet1[nodeArray1[i].id] = { x: x, y: margin1 - i *(r + gap) };
@@ -16484,8 +16610,9 @@ class ViewInterPairs {
16484
16610
  tmpText = 'Set 2';
16485
16611
  }
16486
16612
  html += '<div style="text-align:center"><br><b>Interactions Sorted on ' + tmpText + '</b>: <button class="' + ic.pre + 'showintercntonly" style="margin-left:20px">Show Count Only</button><button class="' + ic.pre + 'showinterdetails" style="margin-left:20px">Show Details</button></div>';
16487
- html += this.getAllInteractionTable(type).html;
16488
- bondCnt = this.getAllInteractionTable(type).bondCnt;
16613
+ let result = this.getAllInteractionTable(type);
16614
+ html += result.html;
16615
+ bondCnt = result.bondCnt;
16489
16616
 
16490
16617
  $("#" + ic.pre + "dl_interactionsorted").html(html);
16491
16618
  me.htmlCls.dialogCls.openDlg('dl_interactionsorted', 'Show sorted interactions');
@@ -18358,7 +18485,7 @@ class ResidueLabels {
18358
18485
  if(me.bNode) return;
18359
18486
 
18360
18487
  let size = 18;
18361
- let background = "#CCCCCC";
18488
+ let background = "#FFFFFF"; //"#CCCCCC";
18362
18489
 
18363
18490
  let atomsHash = me.hashUtilsCls.intHash(ic.hAtoms, atoms);
18364
18491
 
@@ -18398,7 +18525,15 @@ class ResidueLabels {
18398
18525
  label.factor = 0.3;
18399
18526
 
18400
18527
  let atomColorStr = atom.color.getHexString().toUpperCase();
18401
- label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18528
+ //label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18529
+ //if(bSchematic) label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18530
+ // don't change residue labels
18531
+ if(bNumber) {
18532
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd;
18533
+ }
18534
+ else {
18535
+ label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18536
+ }
18402
18537
  label.background = background;
18403
18538
  //label.alpha = alpha; // ic.labelCls.hideLabels() didn't work. Remove this line for now
18404
18539
 
@@ -18442,7 +18577,7 @@ class ResidueLabels {
18442
18577
  label.text = atom.elem;
18443
18578
  label.size = size;
18444
18579
 
18445
- label.color = "#" + atom.color.getHexString();
18580
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : atom.color.getHexString();
18446
18581
  label.background = background;
18447
18582
 
18448
18583
  ic.labels['schematic'].push(label);
@@ -18480,7 +18615,8 @@ class ResidueLabels {
18480
18615
  }
18481
18616
 
18482
18617
  let atomColorStr = atom.color.getHexString().toUpperCase();
18483
- label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18618
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18619
+ if(bElement) label.color = (atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
18484
18620
  label.background = background;
18485
18621
 
18486
18622
  ic.labels['residue'].push(label);
@@ -19259,7 +19395,8 @@ class Scap {
19259
19395
  if(!ic.alertAlt) {
19260
19396
  ic.alertAlt = true;
19261
19397
 
19262
- if(ic.bRender) var aaa = 1; //alert('Please press the letter "a" to alternate between wild type and mutant.');
19398
+ //if(ic.bRender) var aaa = 1; //alert('Please press the letter "a" to alternate between wild type and mutant.');
19399
+ var aaa = 1; //alert('Please press the letter "a" to alternate between wild type and mutant.');
19263
19400
  }
19264
19401
  }
19265
19402
 
@@ -19907,8 +20044,7 @@ class LoadPDB {
19907
20044
  // modified from iview (http://istar.cse.cuhk.edu.hk/iview/)
19908
20045
  //This PDB parser feeds the viewer with the content of a PDB file, pdbData.
19909
20046
  loadPDB(src, pdbid, bOpm, bVector, bMutation, bAppend) { let ic = this.icn3d, me = ic.icn3dui;
19910
- let helices = [], sheets = [];
19911
- //ic.atoms = {}
20047
+ let bNMR = false;
19912
20048
  let lines = src.split('\n');
19913
20049
 
19914
20050
  let chainsTmp = {}; // serial -> atom
@@ -19947,20 +20083,23 @@ class LoadPDB {
19947
20083
  serial = (ic.atoms) ? Object.keys(ic.atoms).length : 0;
19948
20084
  }
19949
20085
 
19950
- let sheetArray = [], sheetStart = [], sheetEnd = [], helixArray = [], helixStart = [], helixEnd = [];
20086
+ //let helices = [], sheets = [];
20087
+ let sheetArray = [], sheetStart = [], sheetEnd = [], helixArray = [], helixStart = [], helixEnd = [];
19951
20088
 
19952
20089
  let chainNum, residueNum, oriResidueNum;
19953
20090
  let prevChainNum = '', prevResidueNum = '', prevOriResidueNum = '';
19954
20091
 
19955
20092
  let oriSerial2NewSerial = {};
19956
20093
 
19957
- let chainMissingResidueArray = {};
20094
+ //let chainMissingResidueArray = {}
19958
20095
 
19959
20096
  let id = (pdbid) ? pdbid : 'stru';
19960
20097
 
19961
- let maxMissingResi = 0, prevMissingChain = '';
20098
+ let prevMissingChain = '';
19962
20099
  let CSerial, prevCSerial, OSerial, prevOSerial;
19963
20100
 
20101
+ let structure = "stru";
20102
+
19964
20103
  for (let i in lines) {
19965
20104
  let line = lines[i];
19966
20105
  let record = line.substr(0, 6);
@@ -19981,6 +20120,12 @@ class LoadPDB {
19981
20120
  }
19982
20121
  }
19983
20122
 
20123
+ structure = id;
20124
+
20125
+ if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
20126
+ structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
20127
+ }
20128
+
19984
20129
  ic.molTitle = '';
19985
20130
 
19986
20131
  } else if (record === 'TITLE ') {
@@ -19995,22 +20140,23 @@ class LoadPDB {
19995
20140
  let startResi = parseInt(line.substr(21, 4));
19996
20141
  let endResi = parseInt(line.substr(33, 4));
19997
20142
 
19998
- let chain_resi;
19999
20143
  for(let j = startResi; j <= endResi; ++j) {
20000
- chain_resi = startChain + "_" + j;
20001
- helixArray.push(chain_resi);
20144
+ let resid = structure + "_" + startChain + "_" + j;
20145
+ helixArray.push(resid);
20002
20146
 
20003
- if(j === startResi) helixStart.push(chain_resi);
20004
- if(j === endResi) helixEnd.push(chain_resi);
20147
+ if(j === startResi) helixStart.push(resid);
20148
+ if(j === endResi) helixEnd.push(resid);
20005
20149
  }
20006
-
20150
+ /*
20007
20151
  helices.push({
20152
+ structure: structure,
20008
20153
  chain: startChain,
20009
20154
  initialResidue: startResi,
20010
20155
  initialInscode: line.substr(25, 1),
20011
20156
  terminalResidue: endResi,
20012
20157
  terminalInscode: line.substr(37, 1),
20013
20158
  });
20159
+ */
20014
20160
  } else if (record === 'SHEET ') {
20015
20161
  //ic.bSecondaryStructure = true;
20016
20162
  if(bOpm === undefined || !bOpm) ic.bSecondaryStructure = true;
@@ -20021,20 +20167,22 @@ class LoadPDB {
20021
20167
  let endResi = parseInt(line.substr(33, 4));
20022
20168
 
20023
20169
  for(let j = startResi; j <= endResi; ++j) {
20024
- let chain_resi = startChain + "_" + j;
20025
- sheetArray.push(chain_resi);
20170
+ let resid = structure + "_" + startChain + "_" + j;
20171
+ sheetArray.push(resid);
20026
20172
 
20027
- if(j === startResi) sheetStart.push(chain_resi);
20028
- if(j === endResi) sheetEnd.push(chain_resi);
20173
+ if(j === startResi) sheetStart.push(resid);
20174
+ if(j === endResi) sheetEnd.push(resid);
20029
20175
  }
20030
-
20176
+ /*
20031
20177
  sheets.push({
20178
+ structure: structure,
20032
20179
  chain: startChain,
20033
20180
  initialResidue: startResi,
20034
20181
  initialInscode: line.substr(26, 1),
20035
20182
  terminalResidue: endResi,
20036
20183
  terminalInscode: line.substr(37, 1),
20037
20184
  });
20185
+ */
20038
20186
  } else if (record === 'HBOND ') {
20039
20187
  if(bOpm === undefined || !bOpm) ic.bSecondaryStructure = true;
20040
20188
  /*
@@ -20081,6 +20229,11 @@ class LoadPDB {
20081
20229
  if(line.indexOf('1/2 of bilayer thickness:') !== -1) { // OPM transmembrane protein
20082
20230
  ic.halfBilayerSize = parseFloat(line.substr(line.indexOf(':') + 1).trim());
20083
20231
  }
20232
+ else if (type == 210) {
20233
+ if((line.substr(11, 32).trim() == 'EXPERIMENT TYPE') && line.substr(45).trim() == 'NMR') {
20234
+ bNMR = true;
20235
+ }
20236
+ }
20084
20237
  else if (type == 350 && line.substr(13, 5) == 'BIOMT') {
20085
20238
  let n = parseInt(line[18]) - 1;
20086
20239
  //var m = parseInt(line.substr(21, 2));
@@ -20097,7 +20250,8 @@ class LoadPDB {
20097
20250
  let resn = line.substr(15, 3);
20098
20251
  //let chain = line.substr(19, 1);
20099
20252
  let chain = line.substr(18, 2).trim();
20100
- let resi = parseInt(line.substr(21, 5));
20253
+ //let resi = parseInt(line.substr(21, 5));
20254
+ let resi = line.substr(21, 5);
20101
20255
 
20102
20256
  //var structure = parseInt(line.substr(13, 1));
20103
20257
  //if(line.substr(13, 1) == ' ') structure = 1;
@@ -20105,20 +20259,15 @@ class LoadPDB {
20105
20259
  //var chainNum = structure + '_' + chain;
20106
20260
  let chainNum = id + '_' + chain;
20107
20261
 
20108
- if(chainMissingResidueArray[chainNum] === undefined) chainMissingResidueArray[chainNum] = [];
20262
+ if(ic.chainMissingResidueArray[chainNum] === undefined) ic.chainMissingResidueArray[chainNum] = [];
20109
20263
  let resObject = {};
20110
20264
  resObject.resi = resi;
20111
20265
  resObject.name = me.utilsCls.residueName2Abbr(resn).toLowerCase();
20112
20266
 
20113
- if(chain != prevMissingChain) {
20114
- maxMissingResi = 0;
20115
- }
20116
-
20117
20267
  // not all listed residues are considered missing, e.g., PDB ID 4OR2, only the firts four residues are considered missing
20118
- if(!isNaN(resi) && (prevMissingChain == '' || (chain != prevMissingChain) || (chain == prevMissingChain && resi > maxMissingResi)) ) {
20119
- chainMissingResidueArray[chainNum].push(resObject);
20120
-
20121
- maxMissingResi = resi;
20268
+ //if(!isNaN(resi) && (prevMissingChain == '' || (chain != prevMissingChain) || (chain == prevMissingChain && resi > maxMissingResi)) ) {
20269
+ if(prevMissingChain == '' || (chain != prevMissingChain) || (chain == prevMissingChain) ) {
20270
+ ic.chainMissingResidueArray[chainNum].push(resObject);
20122
20271
  prevMissingChain = chain;
20123
20272
  }
20124
20273
 
@@ -20134,21 +20283,27 @@ class LoadPDB {
20134
20283
  } else if (record === 'ENDMDL') {
20135
20284
  ++moleculeNum;
20136
20285
  id = 'stru';
20286
+
20287
+ structure = id;
20288
+ if(id == 'stru' || bMutation || (bAppend && id.length != 4)) { // bMutation: side chain prediction
20289
+ structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
20290
+ }
20291
+
20292
+ //helices = [];
20293
+ //sheets = [];
20294
+ if(!bNMR) {
20295
+ sheetArray = [];
20296
+ sheetStart = [];
20297
+ sheetEnd = [];
20298
+ helixArray = [];
20299
+ helixStart = [];
20300
+ helixEnd = [];
20301
+ }
20137
20302
  } else if (record === 'JRNL ') {
20138
20303
  if(line.substr(12, 4) === 'PMID') {
20139
20304
  ic.pmid = line.substr(19).trim();
20140
20305
  }
20141
20306
  } else if (record === 'ATOM ' || record === 'HETATM') {
20142
- //if(id == 'stru' && bOpm) {
20143
- // id = pdbid;
20144
- //}
20145
-
20146
- let structure = id;
20147
- //if(id == 'stru' || bMutation || (bAppend && id == 'stru')) { // bMutation: side chain prediction
20148
- if(id == 'stru' || bMutation || (bAppend)) { // bMutation: side chain prediction
20149
- structure = (moleculeNum === 1) ? id : id + moleculeNum.toString();
20150
- }
20151
-
20152
20307
  let alt = line.substr(16, 1);
20153
20308
  //if (alt !== " " && alt !== "A") continue;
20154
20309
 
@@ -20190,7 +20345,7 @@ class LoadPDB {
20190
20345
 
20191
20346
  residueNum = chainNum + "_" + resi;
20192
20347
 
20193
- let chain_resi = chain + "_" + resi;
20348
+ //let chain_resi = chain + "_" + resi;
20194
20349
 
20195
20350
  let x = parseFloat(line.substr(30, 8));
20196
20351
  let y = parseFloat(line.substr(38, 8));
@@ -20241,27 +20396,26 @@ class LoadPDB {
20241
20396
 
20242
20397
  // Assign secondary structures from the input
20243
20398
  // if a residue is assigned both sheet and helix, it is assigned as sheet
20244
- if($.inArray(chain_resi, sheetArray) !== -1) {
20399
+ if(this.isSecondary(residueNum, sheetArray, bNMR)) {
20245
20400
  ic.atoms[serial].ss = 'sheet';
20246
-
20247
- if($.inArray(chain_resi, sheetStart) !== -1) {
20401
+ if(this.isSecondary(residueNum, sheetStart, bNMR)) {
20248
20402
  ic.atoms[serial].ssbegin = true;
20249
20403
  }
20250
20404
 
20251
20405
  // do not use else if. Some residues are both start and end of secondary structure
20252
- if($.inArray(chain_resi, sheetEnd) !== -1) {
20406
+ if(this.isSecondary(residueNum, sheetEnd, bNMR)) {
20253
20407
  ic.atoms[serial].ssend = true;
20254
20408
  }
20255
20409
  }
20256
- else if($.inArray(chain_resi, helixArray) !== -1) {
20410
+ else if(this.isSecondary(residueNum, helixArray, bNMR)) {
20257
20411
  ic.atoms[serial].ss = 'helix';
20258
20412
 
20259
- if($.inArray(chain_resi, helixStart) !== -1) {
20413
+ if(this.isSecondary(residueNum, helixStart, bNMR)) {
20260
20414
  ic.atoms[serial].ssbegin = true;
20261
20415
  }
20262
20416
 
20263
20417
  // do not use else if. Some residues are both start and end of secondary structure
20264
- if($.inArray(chain_resi, helixEnd) !== -1) {
20418
+ if(this.isSecondary(residueNum, helixEnd, bNMR)) {
20265
20419
  ic.atoms[serial].ssend = true;
20266
20420
  }
20267
20421
  }
@@ -20359,7 +20513,7 @@ class LoadPDB {
20359
20513
  if(ic.chains[chainNum] === undefined) ic.chains[chainNum] = {};
20360
20514
  ic.chains[chainNum] = me.hashUtilsCls.unionHash2Atoms(ic.chains[chainNum], chainsTmp, ic.atoms);
20361
20515
 
20362
- if(!bMutation) this.adjustSeq(chainMissingResidueArray);
20516
+ if(!bMutation) this.adjustSeq(ic.chainMissingResidueArray);
20363
20517
 
20364
20518
  // ic.missingResidues = [];
20365
20519
  // for(let chainid in chainMissingResidueArray) {
@@ -20544,10 +20698,11 @@ class LoadPDB {
20544
20698
  for(let chainNum in ic.chainsSeq) {
20545
20699
  if(chainMissingResidueArray[chainNum] === undefined) continue;
20546
20700
 
20547
- let A = ic.chainsSeq[chainNum];
20548
- //var A2 = ic.chainsAn[chainNum][0];
20549
- //var A3 = ic.chainsAn[chainNum][1];
20550
- let B = chainMissingResidueArray[chainNum];
20701
+ //let A = ic.chainsSeq[chainNum];
20702
+ //let B = chainMissingResidueArray[chainNum];
20703
+
20704
+ let A = chainMissingResidueArray[chainNum];
20705
+ let B = ic.chainsSeq[chainNum];
20551
20706
 
20552
20707
  let m = A.length;
20553
20708
  let n = B.length;
@@ -20565,7 +20720,7 @@ class LoadPDB {
20565
20720
  j = 0;
20566
20721
  k = 0;
20567
20722
  while (i < m && j < n) {
20568
- if (A[i].resi <= B[j].resi) {
20723
+ if (parseInt(A[i].resi) <= parseInt(B[j].resi)) {
20569
20724
  C[k] = A[i];
20570
20725
  //C2[k] = A2[i];
20571
20726
  //C3[k] = A3[i];
@@ -20701,6 +20856,24 @@ class LoadPDB {
20701
20856
  return {'chainresiCalphaHash': chainCalphaHash, 'center': ic.center.clone()}
20702
20857
  }
20703
20858
 
20859
+ isSecondary(resid, residArray, bNMR) { let ic = this.icn3d; ic.icn3dui;
20860
+ if(!bNMR) {
20861
+ return $.inArray(resid, residArray) != -1;
20862
+ }
20863
+ else {
20864
+ let chain_resi = resid.substr(resid.indexOf('_') + 1);
20865
+
20866
+ let bFound = false;
20867
+ for(let i = 0, il = residArray.length; i < il; ++i) {
20868
+ if(chain_resi == residArray[i].substr(residArray[i].indexOf('_') + 1)) {
20869
+ bFound = true;
20870
+ break;
20871
+ }
20872
+ }
20873
+
20874
+ return bFound;
20875
+ }
20876
+ }
20704
20877
  }
20705
20878
 
20706
20879
  /**
@@ -20748,6 +20921,7 @@ class LoadAtomData {
20748
20921
  let refinedStr =(me.cfg.inpara && me.cfg.inpara.indexOf('atype=1') !== -1) ? 'Invariant Core ' : '';
20749
20922
  ic.molTitle = refinedStr + 'Structure Alignment of ';
20750
20923
 
20924
+ let bTitle = false;
20751
20925
  for(let i = 0, il = data.alignedStructures[0].length; i < il; ++i) {
20752
20926
  let structure = data.alignedStructures[0][i];
20753
20927
 
@@ -20785,10 +20959,13 @@ class LoadAtomData {
20785
20959
  ic.molTitle += " and ";
20786
20960
  if(structure.descr !== undefined) ic.pmid += "_";
20787
20961
  }
20962
+
20963
+ bTitle = true;
20788
20964
  }
20789
20965
 
20790
20966
  ic.molTitle += ' from VAST+';
20791
20967
 
20968
+ if(!bTitle) ic.molTitle = '';
20792
20969
  }
20793
20970
  else { // mmdbid or mmcifid
20794
20971
  if(data.descr !== undefined) ic.molTitle += data.descr.name;
@@ -22288,7 +22465,7 @@ class PdbParser {
22288
22465
  let url, dataType;
22289
22466
 
22290
22467
  if(bAf) {
22291
- url = "https://alphafold.ebi.ac.uk/files/AF-" + pdbid + "-F1-model_v1.pdb";
22468
+ url = "https://alphafold.ebi.ac.uk/files/AF-" + pdbid + "-F1-model_v2.pdb";
22292
22469
  ic.ParserUtilsCls.setYourNote(pdbid.toUpperCase() + '(AlphaFold) in iCn3D');
22293
22470
  }
22294
22471
  else {
@@ -22340,7 +22517,7 @@ class PdbParser {
22340
22517
 
22341
22518
  //Load structures from a "URL". Due to the same domain policy of Ajax call, the URL should be in the same
22342
22519
  //domain. "type" could be "pdb", "mol2", "sdf", or "xyz" for pdb file, mol2file, sdf file, and xyz file, respectively.
22343
- downloadUrl(url, type) { let ic = this.icn3d, me = ic.icn3dui;
22520
+ downloadUrl(url, type, command) { let ic = this.icn3d, me = ic.icn3dui;
22344
22521
  let thisClass = this;
22345
22522
 
22346
22523
  let pos = url.lastIndexOf('/');
@@ -22377,6 +22554,7 @@ class PdbParser {
22377
22554
 
22378
22555
  if(type === 'pdb') {
22379
22556
  thisClass.loadPdbData(data);
22557
+ ic.loadScriptCls.loadScript(command);
22380
22558
  }
22381
22559
  else if(type === 'mol2') {
22382
22560
  ic.mol2ParserCls.loadMol2Data(data);
@@ -22392,7 +22570,7 @@ class PdbParser {
22392
22570
  }
22393
22571
  else if(type === 'icn3dpng') {
22394
22572
  ic.mmcifParserCls.loadMmcifData(data);
22395
- me.htmlCls.setHtmlCls.loadPng(data);
22573
+ me.htmlCls.setHtmlCls.loadPng(data, command);
22396
22574
  }
22397
22575
  },
22398
22576
  error : function(xhr, textStatus, errorThrown ) {
@@ -23003,13 +23181,13 @@ class AlignParser {
23003
23181
 
23004
23182
  request
23005
23183
  .fail(function() {
23006
- var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data.");
23184
+ var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data in the VAST+ database. You can try the VAST alignment by visiting the VAST+ page https://www.ncbi.nlm.nih.gov/Structure/vastplus/vastplus.cgi?uid=[PDB ID] (e.g., uid=1KQ2), and clicking \"Original VAST\"");
23007
23185
  return false;
23008
23186
  })
23009
23187
  .then(function( data ) {
23010
23188
  seqalign = data.seqalign;
23011
23189
  if(seqalign === undefined) {
23012
- var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data.");
23190
+ var aaa = 1; //alert("These two MMDB IDs " + alignArray + " do not have 3D alignment data in the VAST+ database. You can try the VAST alignment by visiting the VAST+ page https://www.ncbi.nlm.nih.gov/Structure/vastplus/vastplus.cgi?uid=[PDB ID] (e.g., uid=1KQ2), and clicking \"Original VAST\"");
23013
23191
  return false;
23014
23192
  }
23015
23193
 
@@ -23092,11 +23270,11 @@ class AlignParser {
23092
23270
  ic.alignmolid2color.push(tmpHash);
23093
23271
  }
23094
23272
 
23095
- //var url3 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&atomonly=1&uid=' + ic.mmdbidArray[0];
23096
- //var url4 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&atomonly=1&uid=' + ic.mmdbidArray[1];
23273
+ //var url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[0];
23274
+ //var url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&atomonly=1&uid=" + ic.mmdbidArray[1];
23097
23275
  // need the parameter moleculeInfor
23098
- let url3 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=' + ic.mmdbidArray[0];
23099
- let url4 = me.htmlCls.baseUrl + 'mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=' + ic.mmdbidArray[1];
23276
+ let url3 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[0];
23277
+ let url4 = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbidArray[1];
23100
23278
 
23101
23279
  let d3 = $.ajax({
23102
23280
  url: url3,
@@ -23631,10 +23809,10 @@ class MmdbParser {
23631
23809
  // b: b-factor, s: water, ft: pdbsite
23632
23810
  //&ft=1
23633
23811
  if(bGi) {
23634
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&simple=1&gi=" + mmdbid;
23812
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&gi=" + mmdbid;
23635
23813
  }
23636
23814
  else {
23637
- url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&simple=1&uid=" + mmdbid;
23815
+ url = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&simple=1&uid=" + mmdbid;
23638
23816
  }
23639
23817
 
23640
23818
  // use asymmetric unit for BLAST search, e.g., https://www.ncbi.nlm.nih.gov/Structure/icn3d/full.html?from=blast&blast_rep_id=5XZC_B&query_id=1TUP_A&command=view+annotations;set+annotation+cdd;set+annotation+site;set+view+detailed+view;select+chain+5XZC_B;show+selection&log$=align&blast_rank=1&RID=EPUCYNVV014&buidx=0
@@ -24520,7 +24698,7 @@ class ChainalignParser {
24520
24698
  let pos1 = alignArray[0].indexOf('_');
24521
24699
  ic.mmdbid_t = alignArray[0].substr(0, pos1).toUpperCase();
24522
24700
  ic.chain_t = alignArray[0].substr(pos1+1);
24523
- let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=" + ic.mmdbid_t;
24701
+ let url_t = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_t;
24524
24702
  if(me.cfg.inpara !== undefined) url_t += me.cfg.inpara;
24525
24703
 
24526
24704
  let ajaxArray = [];
@@ -24546,7 +24724,7 @@ class ChainalignParser {
24546
24724
  let chainalignFinal = ic.mmdbid_q + "_" + ic.chain_q + "," + ic.mmdbid_t + "_" + ic.chain_t;
24547
24725
 
24548
24726
  let urlalign = me.htmlCls.baseUrl + "vastdyn/vastdyn.cgi?chainpairs=" + chainalignFinal;
24549
- let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&uid=" + ic.mmdbid_q;
24727
+ let url_q = me.htmlCls.baseUrl + "mmdb/mmdb_strview.cgi?v=2&program=icn3d&b=1&s=1&ft=1&buidx=" + me.cfg.buidx + "&uid=" + ic.mmdbid_q;
24550
24728
 
24551
24729
  if(me.cfg.inpara !== undefined) url_q += me.cfg.inpara;
24552
24730
 
@@ -26615,18 +26793,30 @@ class LoadScript {
26615
26793
  me.cfg.mmcifid = id;
26616
26794
  ic.mmcifParserCls.downloadMmcif(id);
26617
26795
  }
26618
- else if(command.indexOf('load mmdb') !== -1) {
26796
+ else if(command.indexOf('load mmdb') !== -1 || command.indexOf('load mmdb1') !== -1) {
26619
26797
  me.cfg.mmdbid = id;
26798
+ me.cfg.buidx = 1;
26620
26799
 
26621
26800
  ic.mmdbParserCls.downloadMmdb(id);
26622
26801
  }
26802
+ else if(command.indexOf('load mmdb0') !== -1) {
26803
+ me.cfg.mmdbid = id;
26804
+ me.cfg.buidx = 0;
26805
+
26806
+ ic.mmdbParserCls.downloadMmdb(id);
26807
+ }
26623
26808
  else if(command.indexOf('load gi') !== -1) {
26624
26809
  me.cfg.gi = id;
26625
26810
  ic.mmdbParserCls.downloadGi(id);
26626
26811
  }
26627
- else if(command.indexOf('load seq_struct_ids') !== -1) {
26812
+ else if(command.indexOf('load seq_struct_ids ') !== -1) {
26813
+ ic.bSmithwm = false;
26628
26814
  ic.mmdbParserCls.downloadBlast_rep_id(id);
26629
26815
  }
26816
+ else if(command.indexOf('load seq_struct_ids_smithwm ') !== -1) {
26817
+ ic.bSmithwm = true;
26818
+ ic.mmdbParserCls.downloadBlast_rep_id(id);
26819
+ }
26630
26820
  else if(command.indexOf('load cid') !== -1) {
26631
26821
  me.cfg.cid = id;
26632
26822
  ic.sdfParserCls.downloadCid(id);
@@ -27248,7 +27438,9 @@ class ShowSeq {
27248
27438
  }
27249
27439
  }
27250
27440
  giSeq = giSeqTmp;
27251
- let divLength = me.htmlCls.RESIDUE_WIDTH * ic.giSeq[chnid].length + 200;
27441
+ //let divLength = me.htmlCls.RESIDUE_WIDTH * ic.giSeq[chnid].length + 200;
27442
+ let divLength = me.htmlCls.RESIDUE_WIDTH * (ic.giSeq[chnid].length + ic.nTotalGap) + 200;
27443
+
27252
27444
  let seqLength = ic.giSeq[chnid].length;
27253
27445
  if(seqLength > ic.maxAnnoLength) {
27254
27446
  ic.maxAnnoLength = seqLength;
@@ -27401,7 +27593,7 @@ class ShowSeq {
27401
27593
  html += '</div>'; // corresponds to above: html += '<div class="icn3d-dl_sequence">';
27402
27594
  html3 += '</div></div>';
27403
27595
  if(me.cfg.blast_rep_id === chnid) {
27404
- htmlTmp = '<div id="' + ic.pre + 'giseq_sequence" class="icn3d-dl_sequence" style="border: solid 1px #000;">';
27596
+ htmlTmp = '<div id="' + ic.pre + 'giseq_sequence" class="icn3d-dl_sequence" style="border: solid 1px #000">';
27405
27597
  }
27406
27598
  else {
27407
27599
  htmlTmp = '<div id="' + ic.pre + 'giseq_sequence" class="icn3d-dl_sequence">';
@@ -28875,7 +29067,7 @@ class Analysis {
28875
29067
  //Display chain name in the 3D structure display for the chains intersecting with the atoms in "atomHash".
28876
29068
  addChainLabels(atoms) {var ic = this.icn3d, me = ic.icn3dui;
28877
29069
  let size = 18;
28878
- let background = "#CCCCCC";
29070
+ let background = "#FFFFFF"; //"#CCCCCC";
28879
29071
  let atomsHash = me.hashUtilsCls.intHash(ic.hAtoms, atoms);
28880
29072
  if(ic.labels['chain'] === undefined) ic.labels['chain'] = [];
28881
29073
  let chainHash = ic.firstAtomObjCls.getChainsFromAtoms(atomsHash);
@@ -28888,8 +29080,8 @@ class Analysis {
28888
29080
  if(proteinName.length > 20) proteinName = proteinName.substr(0, 20) + '...';
28889
29081
  label.text = 'Chain ' + chainName + ': ' + proteinName;
28890
29082
  label.size = size;
28891
- let atomColorStr = ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chainid]).color.getHexString().toUpperCase();
28892
- label.color =(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
29083
+ ic.firstAtomObjCls.getFirstCalphaAtomObj(ic.chains[chainid]).color.getHexString().toUpperCase();
29084
+ label.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomColorStr === "CCCCCC" || atomColorStr === "C8C8C8") ? "#888888" : "#" + atomColorStr;
28893
29085
  label.background = background;
28894
29086
  ic.labels['chain'].push(label);
28895
29087
  }
@@ -28899,7 +29091,7 @@ class Analysis {
28899
29091
  //as "N-" and "C-". The termini of nucleotides are labeled as "5'" and "3'".
28900
29092
  addTerminiLabels(atoms) {var ic = this.icn3d, me = ic.icn3dui;
28901
29093
  let size = 18;
28902
- let background = "#CCCCCC";
29094
+ let background = "#FFFFFF"; //"#CCCCCC";
28903
29095
  let protNucl;
28904
29096
  protNucl = me.hashUtilsCls.unionHash(protNucl, ic.proteins);
28905
29097
  protNucl = me.hashUtilsCls.unionHash(protNucl, ic.nucleotides);
@@ -28923,10 +29115,10 @@ class Analysis {
28923
29115
  }
28924
29116
  labelN.size = size;
28925
29117
  labelC.size = size;
28926
- let atomNColorStr = firstAtom.color.getHexString().toUpperCase();
28927
- let atomCColorStr = lastAtom.color.getHexString().toUpperCase();
28928
- labelN.color =(atomNColorStr === "CCCCCC" || atomNColorStr === "C8C8C8") ? "#888888" : "#" + atomNColorStr;
28929
- labelC.color =(atomCColorStr === "CCCCCC" || atomCColorStr === "C8C8C8") ? "#888888" : "#" + atomCColorStr;
29118
+ firstAtom.color.getHexString().toUpperCase();
29119
+ lastAtom.color.getHexString().toUpperCase();
29120
+ labelN.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomNColorStr === "CCCCCC" || atomNColorStr === "C8C8C8") ? "#888888" : "#" + atomNColorStr;
29121
+ labelC.color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //(atomCColorStr === "CCCCCC" || atomCColorStr === "C8C8C8") ? "#888888" : "#" + atomCColorStr;
28930
29122
  labelN.background = background;
28931
29123
  labelC.background = background;
28932
29124
  ic.labels['chain'].push(labelN);
@@ -28961,11 +29153,44 @@ class AnnoCddSite {
28961
29153
  // live search for AlphaFold structures
28962
29154
  //if(me.cfg.afid) {
28963
29155
 
28964
- if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) {
29156
+ // use precalculated CDD annotation if
29157
+ if( (Object.keys(ic.structures).length == 1 && (me.cfg.mmtfid || me.cfg.pdbid || me.cfg.opmid || me.cfg.mmdbid || me.cfg.gi || me.cfg.uniprotid || me.cfg.blast_rep_id || me.cfg.cid || me.cfg.mmcifid))
29158
+ || (Object.keys(ic.structures).length == 2 && me.cfg.align) ) {
29159
+ $.ajax({
29160
+ url: url,
29161
+ dataType: 'jsonp',
29162
+ cache: true,
29163
+ tryCount : 0,
29164
+ retryLimit : 1,
29165
+ success: function(data) {
29166
+ thisClass.parseCddData([data], chnidArray);
29167
+ if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29168
+ },
29169
+ error : function(xhr, textStatus, errorThrown ) {
29170
+ this.tryCount++;
29171
+ if(this.tryCount <= this.retryLimit) {
29172
+ //try again
29173
+ $.ajax(this);
29174
+ return;
29175
+ }
29176
+
29177
+ thisClass.getNoCdd(chnidBaseArray);
29178
+ if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29179
+
29180
+ return;
29181
+ }
29182
+ });
29183
+ }
29184
+ else {
28965
29185
  let ajaxArray = [];
28966
29186
 
28967
29187
  for(let i = 0, il = chnidArray.length; i < il; ++i) {
28968
- let seq = Array.isArray(ic.giSeq[chnidArray[i]]) ? ic.giSeq[chnidArray[i]].join('') : ic.giSeq[chnidArray[i]];
29188
+ //let seq = Array.isArray(ic.giSeq[chnidArray[i]]) ? ic.giSeq[chnidArray[i]].join('') : ic.giSeq[chnidArray[i]];
29189
+ let seq = Array.isArray(ic.giSeq[chnidArray[i]]) ? ic.giSeq[chnidArray[i]].join('').toUpperCase() : ic.giSeq[chnidArray[i]].toUpperCase();
29190
+
29191
+ // remove water molecules
29192
+ seq = seq.replace(/O/g, '');
29193
+
28969
29194
  //url = me.htmlCls.baseUrl + "cdannots/cdannots.fcgi?fmt&live=lcl&queries=" + ic.giSeq[chnidArray[0]].join('');
28970
29195
  url = me.htmlCls.baseUrl + "cdannots/cdannots.fcgi?fmt&live=lcl&queries=" + seq;
28971
29196
 
@@ -28992,32 +29217,6 @@ class AnnoCddSite {
28992
29217
  return;
28993
29218
  });
28994
29219
  }
28995
- else {
28996
- $.ajax({
28997
- url: url,
28998
- dataType: 'jsonp',
28999
- cache: true,
29000
- tryCount : 0,
29001
- retryLimit : 1,
29002
- success: function(data) {
29003
- thisClass.parseCddData([data], chnidArray);
29004
- if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29005
- },
29006
- error : function(xhr, textStatus, errorThrown ) {
29007
- this.tryCount++;
29008
- if(this.tryCount <= this.retryLimit) {
29009
- //try again
29010
- $.ajax(this);
29011
- return;
29012
- }
29013
-
29014
- thisClass.getNoCdd(chnidBaseArray);
29015
- if(ic.deferredAnnoCddSite !== undefined) ic.deferredAnnoCddSite.resolve();
29016
-
29017
- return;
29018
- }
29019
- });
29020
- }
29021
29220
  }
29022
29221
 
29023
29222
  parseCddData(dataArray, chnidArray, bSeq) { let ic = this.icn3d, me = ic.icn3dui;
@@ -29508,7 +29707,7 @@ class Picking {
29508
29707
  let text =(ic.pk == 1) ? atom.resn + atom.resi + '@' + atom.name : atom.resn + atom.resi;
29509
29708
  if(ic.structures !== undefined && Object.keys(ic.structures).length > 1) {
29510
29709
  text = atom.structure + '_' + atom.chain + ' ' + text;
29511
- $("#" + ic.pre + "popup").css("width", "140px");
29710
+ $("#" + ic.pre + "popup").css("width", "160px");
29512
29711
  }
29513
29712
  else {
29514
29713
  $("#" + ic.pre + "popup").css("width", "80px");
@@ -29736,8 +29935,9 @@ class ApplyCommand {
29736
29935
  ic.bAddCommands = false;
29737
29936
 
29738
29937
  let commandTransformation = commandStr.split('|||');
29938
+ let commandTransformation2 = commandTransformation[0].split('%7C%7C%7C'); // sometimes encoded transformation is also included
29739
29939
 
29740
- let commandOri = commandTransformation[0].replace(/\s+/g, ' ').trim();
29940
+ let commandOri = commandTransformation2[0].replace(/\s+/g, ' ').trim();
29741
29941
  let command = commandOri.toLowerCase();
29742
29942
 
29743
29943
  // exact match =============
@@ -30333,15 +30533,18 @@ class ApplyCommand {
30333
30533
  let value = command.substr(command.lastIndexOf(' ') + 1);
30334
30534
  ic.opts['background'] = value;
30335
30535
 
30336
- if(value == 'white' || value == 'grey') {
30337
- $("#" + ic.pre + "title").css("color", "black");
30338
- $("#" + ic.pre + "titlelink").css("color", "black");
30536
+ if(value == 'black') {
30537
+ $("#" + ic.pre + "title").css("color", me.htmlCls.GREYD);
30538
+ $("#" + ic.pre + "titlelink").css("color", me.htmlCls.GREYD);
30339
30539
  }
30340
30540
  else {
30341
- $("#" + ic.pre + "title").css("color", me.htmlCls.GREYD);
30342
- $("#" + ic.pre + "titlelink").css("color", me.htmlCls.GREYD);
30541
+ $("#" + ic.pre + "title").css("color", "black");
30542
+ $("#" + ic.pre + "titlelink").css("color", "black");
30343
30543
  }
30344
30544
  }
30545
+ else if(command.indexOf('set label color') == 0) {
30546
+ ic.labelcolor = command.substr(command.lastIndexOf(' ') + 1);
30547
+ }
30345
30548
  else if(commandOri.indexOf('set thickness') == 0) {
30346
30549
  let paraArray = command.split(' | ');
30347
30550
 
@@ -30396,6 +30599,13 @@ class ApplyCommand {
30396
30599
 
30397
30600
  ic.drawCls.draw();
30398
30601
  }
30602
+ else if(commandOri.indexOf('set membrane') == 0) {
30603
+ let pos = command.lastIndexOf(' ');
30604
+
30605
+ ic.bMembrane = parseInt(command.substr(pos + 1));
30606
+
30607
+ ic.drawCls.draw();
30608
+ }
30399
30609
  else if(command.indexOf('set highlight color') == 0) {
30400
30610
  let color = command.substr(20);
30401
30611
  if(color === 'yellow') {
@@ -32166,6 +32376,8 @@ class SetSeqAlign {
32166
32376
  ic.alnChainsAnTtl[chainid1][6].push("");
32167
32377
 
32168
32378
  let alignIndex = 1;
32379
+ if(!ic.chainsMapping[chainid1]) ic.chainsMapping[chainid1] = {};
32380
+ if(!ic.chainsMapping[chainid2]) ic.chainsMapping[chainid2] = {};
32169
32381
  //for(let j = 0, jl = alignData.sseq.length; j < jl; ++j) {
32170
32382
  for(let j = start; j <= end; ++j) {
32171
32383
  // 0: internal resi id, 1: pdb resi id, 2: resn, 3: aligned or not
@@ -32197,6 +32409,10 @@ class SetSeqAlign {
32197
32409
  ic.nconsHash2[chainid2 + '_' + resi] = 1;
32198
32410
  }
32199
32411
 
32412
+ // mapping, use the firstsequence as the reference structure
32413
+ ic.chainsMapping[chainid1][chainid1 + '_' + id2aligninfo[j].resi] = id2aligninfo[j].resn + id2aligninfo[j].resi;
32414
+ ic.chainsMapping[chainid2][chainid2 + '_' + resi] = id2aligninfo[j].resn + id2aligninfo[j].resi;
32415
+
32200
32416
  color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(id2aligninfo[j].resn, resn);
32201
32417
 
32202
32418
  // expensive and thus remove
@@ -32381,6 +32597,8 @@ class SetSeqAlign {
32381
32597
  if(ic.qt_start_end[chainIndex] === undefined) return;
32382
32598
 
32383
32599
  let alignIndex = 1;
32600
+ if(!ic.chainsMapping[chainid1]) ic.chainsMapping[chainid1] = {};
32601
+ if(!ic.chainsMapping[chainid2]) ic.chainsMapping[chainid2] = {};
32384
32602
  for(let i = 0, il = ic.qt_start_end[chainIndex].length; i < il; ++i) {
32385
32603
  //var start1 = ic.qt_start_end[chainIndex][i].q_start - 1;
32386
32604
  //var start2 = ic.qt_start_end[chainIndex][i].t_start - 1;
@@ -32474,6 +32692,10 @@ class SetSeqAlign {
32474
32692
  ic.nconsHash2[chainid2 + '_' + resi2] = 1;
32475
32693
  }
32476
32694
 
32695
+ // mapping, use the firstsequence as the reference structure
32696
+ ic.chainsMapping[chainid1][chainid1 + '_' + resi1] = resn1 + resi1;
32697
+ ic.chainsMapping[chainid2][chainid2 + '_' + resi2] = resn1 + resi1;
32698
+
32477
32699
  color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(resn1, resn2);
32478
32700
 
32479
32701
  let bFirstResi =(i === 0 && j === 0) ? true : false;
@@ -32523,6 +32745,8 @@ class SetSeqAlign {
32523
32745
  // let prevChainid1 = '', prevChainid2 = '', cnt1 = 0, cnt2 = 0;
32524
32746
 
32525
32747
  let residuesHash = {};
32748
+ if(!ic.chainsMapping[chainid_t]) ic.chainsMapping[chainid_t] = {};
32749
+ if(!ic.chainsMapping[chainid]) ic.chainsMapping[chainid] = {};
32526
32750
 
32527
32751
  for(let i = 0, il = ic.realignResid[structure1].length; i < il; ++i) {
32528
32752
  let resObject1 = ic.realignResid[structure1][i];
@@ -32549,6 +32773,11 @@ class SetSeqAlign {
32549
32773
  else {
32550
32774
  color = "#0000FF";
32551
32775
  }
32776
+
32777
+ // mapping, use the firstsequence as the reference structure
32778
+ ic.chainsMapping[chainid_t][chainid_t + '_' + resObject1.resi] = resObject1.resn + resObject1.resi;
32779
+ ic.chainsMapping[chainid][chainid + '_' + resObject2.resi] = resObject1.resn + resObject1.resi;
32780
+
32552
32781
  let color2 = '#' + ic.showAnnoCls.getColorhexFromBlosum62(resObject1.resn, resObject2.resn);
32553
32782
 
32554
32783
  resObject1.color = color;
@@ -33433,13 +33662,16 @@ class MmcifParser {
33433
33662
  let thisClass = this;
33434
33663
 
33435
33664
  let url, dataType;
33436
-
33665
+ /*
33437
33666
  if(me.utilsCls.isMac()) { // safari has a problem in getting data from https://files.rcsb.org/header/
33438
33667
  url = "https://files.rcsb.org/view/" + mmcifid + ".cif";
33439
33668
  }
33440
33669
  else {
33441
33670
  url = "https://files.rcsb.org/header/" + mmcifid + ".cif";
33442
33671
  }
33672
+ */
33673
+
33674
+ url = "https://files.rcsb.org/header/" + mmcifid + ".cif";
33443
33675
 
33444
33676
  dataType = "text";
33445
33677
 
@@ -33564,7 +33796,7 @@ class MmcifParser {
33564
33796
  if(type === 'mmtfid' && missingseq !== undefined) {
33565
33797
  // adjust missing residues
33566
33798
  let maxMissingResi = 0, prevMissingChain = '';
33567
- let chainMissingResidueArray = {};
33799
+ //let chainMissingResidueArray = {}
33568
33800
  for(let i = 0, il = missingseq.length; i < il; ++i) {
33569
33801
 
33570
33802
  let resn = missingseq[i].resn;
@@ -33573,7 +33805,7 @@ class MmcifParser {
33573
33805
 
33574
33806
  let chainNum = mmcifid + '_' + chain;
33575
33807
 
33576
- if(chainMissingResidueArray[chainNum] === undefined) chainMissingResidueArray[chainNum] = [];
33808
+ if(ic.chainMissingResidueArray[chainNum] === undefined) ic.chainMissingResidueArray[chainNum] = [];
33577
33809
  let resObject = {};
33578
33810
  resObject.resi = resi;
33579
33811
  resObject.name = me.utilsCls.residueName2Abbr(resn).toLowerCase();
@@ -33584,14 +33816,14 @@ class MmcifParser {
33584
33816
 
33585
33817
  // not all listed residues are considered missing, e.g., PDB ID 4OR2, only the firts four residues are considered missing
33586
33818
  if(!isNaN(resi) &&(prevMissingChain == '' ||(chain != prevMissingChain) ||(chain == prevMissingChain && resi > maxMissingResi)) ) {
33587
- chainMissingResidueArray[chainNum].push(resObject);
33819
+ ic.chainMissingResidueArray[chainNum].push(resObject);
33588
33820
 
33589
33821
  maxMissingResi = resi;
33590
33822
  prevMissingChain = chain;
33591
33823
  }
33592
33824
  }
33593
33825
 
33594
- ic.loadPDBCls.adjustSeq(chainMissingResidueArray);
33826
+ ic.loadPDBCls.adjustSeq(ic.chainMissingResidueArray);
33595
33827
  }
33596
33828
 
33597
33829
  if(ic.deferredSymmetry !== undefined) ic.deferredSymmetry.resolve();
@@ -33616,7 +33848,7 @@ class MmcifParser {
33616
33848
  if(type === 'mmtfid' && data.missingseq !== undefined) {
33617
33849
  // adjust missing residues
33618
33850
  let maxMissingResi = 0, prevMissingChain = '';
33619
- let chainMissingResidueArray = {};
33851
+ //let chainMissingResidueArray = {}
33620
33852
  for(let i = 0, il = data.missingseq.length; i < il; ++i) {
33621
33853
 
33622
33854
  let resn = data.missingseq[i].resn;
@@ -33625,7 +33857,7 @@ class MmcifParser {
33625
33857
 
33626
33858
  let chainNum = mmcifid + '_' + chain;
33627
33859
 
33628
- if(chainMissingResidueArray[chainNum] === undefined) chainMissingResidueArray[chainNum] = [];
33860
+ if(ic.chainMissingResidueArray[chainNum] === undefined) ic.chainMissingResidueArray[chainNum] = [];
33629
33861
  let resObject = {};
33630
33862
  resObject.resi = resi;
33631
33863
  resObject.name = me.utilsCls.residueName2Abbr(resn).toLowerCase();
@@ -33643,7 +33875,7 @@ class MmcifParser {
33643
33875
  }
33644
33876
  }
33645
33877
 
33646
- ic.loadPDBCls.adjustSeq(chainMissingResidueArray);
33878
+ ic.loadPDBCls.adjustSeq(ic.chainMissingResidueArray);
33647
33879
  }
33648
33880
 
33649
33881
  if(ic.deferredSymmetry !== undefined) ic.deferredSymmetry.resolve();
@@ -33839,8 +34071,16 @@ class HlSeq {
33839
34071
  .on('click', '.icn3d-seqTitle', function(e) { let ic = thisClass.icn3d;
33840
34072
  e.stopImmediatePropagation();
33841
34073
 
33842
- ic.bAlignSeq = false;
33843
- ic.bAnnotations = true;
34074
+ //if($(this).attr('id') === ic.pre + "dl_sequence2") {
34075
+ if($(this).parents('div').attr('id') === ic.pre + "dl_sequence2") {
34076
+ ic.bAlignSeq = true;
34077
+ ic.bAnnotations = false;
34078
+ }
34079
+ //else if($(this).attr('id') === ic.pre + "dl_annotations") {
34080
+ else {
34081
+ ic.bAlignSeq = false;
34082
+ ic.bAnnotations = true;
34083
+ }
33844
34084
 
33845
34085
  // select annotation title
33846
34086
  //$("div .ui-selected", this).each(function() {
@@ -33869,8 +34109,9 @@ class HlSeq {
33869
34109
 
33870
34110
  $("#" + ic.pre + "dl_sequence2").add("[id^=" + ic.pre + "giseq]").add("[id^=" + ic.pre + "custom]").add("[id^=" + ic.pre + "site]").add("[id^=" + ic.pre + "clinvar]").add("[id^=" + ic.pre + "snp]").add("[id^=" + ic.pre + "cdd]").add("[id^=" + ic.pre + "domain]").add("[id^=" + ic.pre + "interaction]").add("[id^=" + ic.pre + "ssbond]").add("[id^=" + ic.pre + "crosslink]").add("[id^=" + ic.pre + "transmem]").on('click', '.icn3d-residue', function(e) { let ic = thisClass.icn3d;
33871
34111
  e.stopImmediatePropagation();
33872
-
33873
- if($(this).attr('id') === ic.pre + "dl_sequence2") {
34112
+ /*
34113
+ //if($(this).attr('id') === ic.pre + "dl_sequence2") {
34114
+ if($(this).parents('span').parents('div').attr('id') === ic.pre + "dl_sequence2") {
33874
34115
  ic.bAlignSeq = true;
33875
34116
  ic.bAnnotations = false;
33876
34117
  }
@@ -33879,7 +34120,7 @@ class HlSeq {
33879
34120
  ic.bAlignSeq = false;
33880
34121
  ic.bAnnotations = true;
33881
34122
  }
33882
-
34123
+ */
33883
34124
  // select residues
33884
34125
  //$("span.ui-selected", this).each(function() {
33885
34126
  let id = $(this).attr('id');
@@ -33918,7 +34159,8 @@ class HlSeq {
33918
34159
  $("#" + ic.pre + "dl_sequence2").add("[id^=" + ic.pre + "giseq]").add("[id^=" + ic.pre + "custom]").add("[id^=" + ic.pre + "site]").add("[id^=" + ic.pre + "feat]").add("[id^=" + ic.pre + "clinvar]").add("[id^=" + ic.pre + "snp]").add("[id^=" + ic.pre + "cdd]").add("[id^=" + ic.pre + "domain]").add("[id^=" + ic.pre + "interaction]").add("[id^=" + ic.pre + "ssbond]").add("[id^=" + ic.pre + "crosslink]").add("[id^=" + ic.pre + "transmem]").on('click', '.icn3d-seqTitle', function(e) { let ic = thisClass.icn3d;
33919
34160
  e.stopImmediatePropagation();
33920
34161
 
33921
- if($(this).attr('id') === ic.pre + "dl_sequence2") {
34162
+ //if($(this).attr('id') === ic.pre + "dl_sequence2") {
34163
+ if($(this).parents('div').attr('id') === ic.pre + "dl_sequence2") {
33922
34164
  ic.bAlignSeq = true;
33923
34165
  ic.bAnnotations = false;
33924
34166
  }
@@ -34115,7 +34357,7 @@ class HlSeq {
34115
34357
 
34116
34358
  //var size = parseInt(ic.LABELSIZE * 10 / commandname.length);
34117
34359
  let size = ic.LABELSIZE;
34118
- let color = "FFFF00";
34360
+ let color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //"FFFF00";
34119
34361
  if(position !== undefined) ic.analysisCls.addLabel(commanddescr, position.center.x, position.center.y, position.center.z, size, color, undefined, 'custom');
34120
34362
 
34121
34363
  ic.drawCls.draw();
@@ -34149,6 +34391,10 @@ class HlSeq {
34149
34391
  selectResidues(id, that) { let ic = this.icn3d, me = ic.icn3dui;
34150
34392
  if(me.bNode) return;
34151
34393
 
34394
+ if(ic.bSelectResidue === false && !ic.bShift && !ic.bCtrl) {
34395
+ ic.selectionCls.removeSelection();
34396
+ }
34397
+
34152
34398
  if(id !== undefined && id !== '') {
34153
34399
  // add "align_" in front of id so that full sequence and aligned sequence will not conflict
34154
34400
  //if(id.substr(0, 5) === 'align') id = id.substr(5);
@@ -34321,7 +34567,7 @@ class ShowAnno {
34321
34567
  }
34322
34568
  }
34323
34569
  }
34324
- else if(me.cfg.blast_rep_id !== undefined) { // align sequence to structure
34570
+ else if(me.cfg.blast_rep_id !== undefined && !ic.bSmithwm) { // align sequence to structure
34325
34571
  let url = me.htmlCls.baseUrl + 'pwaln/pwaln.fcgi?from=querytarget';
34326
34572
  let dataObj = {'targets': me.cfg.blast_rep_id, 'queries': me.cfg.query_id};
34327
34573
  if(me.cfg.query_from_to !== undefined ) {
@@ -34363,6 +34609,63 @@ class ShowAnno {
34363
34609
  }
34364
34610
  });
34365
34611
  } // align seq to structure
34612
+ else if(me.cfg.blast_rep_id !== undefined && ic.bSmithwm) { // align sequence to structure
34613
+ //{'targets': me.cfg.blast_rep_id, 'queries': me.cfg.query_id}
34614
+ let idArray = [me.cfg.blast_rep_id];
34615
+
34616
+ let target, query;
34617
+ if(me.cfg.query_id.indexOf('>') != -1) { //FASTA with header
34618
+ query = me.cfg.query_id.substr(me.cfg.query_id.indexOf('\n') + 1);
34619
+ }
34620
+ else if(!(/\d/.test(me.cfg.query_id)) || me.cfg.query_id.length > 50) { //FASTA
34621
+ query = me.cfg.query_id;
34622
+ }
34623
+ else { // accession
34624
+ idArray.push(me.cfg.query_id);
34625
+ }
34626
+
34627
+ // show the sequence and 3D structure
34628
+ //var url = "https://eme.utilsCls.ncbi.nlm.nih.gov/entrez/eUtilsCls/efetch.fcgi?db=protein&retmode=json&rettype=fasta&id=" + chnidBaseArray;
34629
+ let url = me.htmlCls.baseUrl + "/vastdyn/vastdyn.cgi?chainlist=" + idArray;
34630
+
34631
+ $.ajax({
34632
+ url: url,
34633
+ dataType: 'jsonp', //'text',
34634
+ cache: true,
34635
+ tryCount : 0,
34636
+ retryLimit : 1,
34637
+ success: function(chainid_seq) {
34638
+ let index = 0;
34639
+ for(let acc in chainid_seq) {
34640
+ if(index == 0) {
34641
+ target = chainid_seq[acc];
34642
+ }
34643
+ else if(!query) {
34644
+ query = chainid_seq[acc];
34645
+ }
34646
+
34647
+ ++index;
34648
+ }
34649
+
34650
+ let match_score = 1, mismatch = -1, gap = -1, extension = -1;
34651
+ ic.seqStructAlignDataSmithwm = ic.alignSWCls.alignSW(target, query, match_score, mismatch, gap, extension);
34652
+
34653
+ thisClass.showAnnoSeqData(nucleotide_chainid, chemical_chainid, chemical_set);
34654
+ },
34655
+ error : function(xhr, textStatus, errorThrown ) {
34656
+ this.tryCount++;
34657
+ if(this.tryCount <= this.retryLimit) {
34658
+ //try again
34659
+ $.ajax(this);
34660
+ return;
34661
+ }
34662
+
34663
+ var aaa = 1; //alert("Can not retrieve the sequence of the accession(s) " + idArray.join(", "));
34664
+
34665
+ return;
34666
+ }
34667
+ });
34668
+ } // align seq to structure
34366
34669
  }
34367
34670
  ic.bAnnoShown = true;
34368
34671
  }
@@ -34458,7 +34761,7 @@ class ShowAnno {
34458
34761
  $.ajax(this);
34459
34762
  return;
34460
34763
  }
34461
- this.enableHlSeq();
34764
+ thisClass.enableHlSeq();
34462
34765
  console.log( "No data were found for the protein " + chnidBaseArray + "..." );
34463
34766
  for(let chnid in ic.protein_chainid) {
34464
34767
  let chnidBase = ic.protein_chainid[chnid];
@@ -34590,7 +34893,7 @@ class ShowAnno {
34590
34893
  if(me.cfg.blast_rep_id != chnid) {
34591
34894
  ic.showSeqCls.showSeq(chnid, chnidBase);
34592
34895
  }
34593
- else if(me.cfg.blast_rep_id == chnid && ic.seqStructAlignData.data === undefined) {
34896
+ else if(me.cfg.blast_rep_id == chnid && ic.seqStructAlignData === undefined && ic.seqStructAlignDataSmithwm === undefined) {
34594
34897
  let title;
34595
34898
  if(me.cfg.query_id.length > 14) {
34596
34899
  title = 'Query: ' + me.cfg.query_id.substr(0, 6) + '...';
@@ -34606,7 +34909,7 @@ class ShowAnno {
34606
34909
  var aaa = 1; //alert('The sequence can NOT be aligned to the structure');
34607
34910
  ic.showSeqCls.showSeq(chnid, chnidBase, undefined, title, compTitle, text, compText);
34608
34911
  }
34609
- else if(me.cfg.blast_rep_id == chnid && ic.seqStructAlignData.data !== undefined) { // align sequence to structure
34912
+ else if(me.cfg.blast_rep_id == chnid && (ic.seqStructAlignData !== undefined || ic.seqStructAlignDataSmithwm !== undefined) ) { // align sequence to structure
34610
34913
  //var title = 'Query: ' + me.cfg.query_id.substr(0, 6);
34611
34914
  let title;
34612
34915
  if(me.cfg.query_id.length > 14) {
@@ -34615,27 +34918,72 @@ class ShowAnno {
34615
34918
  else {
34616
34919
  title =(isNaN(me.cfg.query_id)) ? 'Query: ' + me.cfg.query_id : 'Query: gi ' + me.cfg.query_id;
34617
34920
  }
34618
- let data = ic.seqStructAlignData;
34619
34921
 
34620
- let query, target;
34621
- if(data.data !== undefined) {
34622
- query = data.data[0].query;
34623
- //target = data.data[0].targets[chnid.replace(/_/g, '')];
34624
- target = data.data[0].targets[chnid];
34625
- target =(target !== undefined && target.hsps.length > 0) ? target.hsps[0] : undefined;
34922
+
34923
+ let evalue, targetSeq, querySeq, segArray;
34924
+
34925
+ if(ic.seqStructAlignData !== undefined) {
34926
+ let query, target;
34927
+ let data = ic.seqStructAlignData;
34928
+ if(data.data !== undefined) {
34929
+ query = data.data[0].query;
34930
+ //target = data.data[0].targets[chnid.replace(/_/g, '')];
34931
+ target = data.data[0].targets[chnid];
34932
+ target =(target !== undefined && target.hsps.length > 0) ? target.hsps[0] : undefined;
34933
+ }
34934
+
34935
+ if(query !== undefined && target !== undefined) {
34936
+ evalue = target.scores.e_value.toPrecision(2);
34937
+ if(evalue > 1e-200) evalue = parseFloat(evalue).toExponential();
34938
+ target.scores.bit_score;
34939
+ //var targetSeq = data.targets[chnid.replace(/_/g, '')].seqdata;
34940
+ targetSeq = data.targets[chnid].seqdata;
34941
+ querySeq = query.seqdata;
34942
+ segArray = target.segs;
34943
+ }
34944
+ }
34945
+ else { // mimic the output of the cgi pwaln.fcgi
34946
+ let data = ic.seqStructAlignDataSmithwm;
34947
+ evalue = data.score;
34948
+ targetSeq = data.target.replace(/-/g, '');
34949
+ querySeq = data.query.replace(/-/g, '');
34950
+ segArray = [];
34951
+ // target, 0-based: orifrom, orito
34952
+ // query, 0-based: from, to
34953
+
34954
+ let targetCnt = -1, queryCnt = -1;
34955
+ let bAlign = false, seg = {};
34956
+ for(let i = 0, il = data.target.length; i < il; ++i) {
34957
+ if(data.target[i] != '-') ++targetCnt;
34958
+ if(data.query[i] != '-') ++queryCnt;
34959
+ if(!bAlign && data.target[i] != '-' && data.query[i] != '-') {
34960
+ bAlign = true;
34961
+ seg.orifrom = targetCnt;
34962
+ seg.from = queryCnt;
34963
+ }
34964
+ else if(bAlign && (data.target[i] == '-' || data.query[i] == '-') ) {
34965
+ bAlign = false;
34966
+ seg.orito = (data.target[i] == '-') ? targetCnt : targetCnt - 1;
34967
+ seg.to = (data.query[i] == '-') ? queryCnt : queryCnt - 1;
34968
+ segArray.push(seg);
34969
+ seg = {};
34970
+ }
34971
+ }
34972
+
34973
+ // end condition
34974
+ if(data.target[data.target.length - 1] != '-' && data.query[data.target.length - 1] != '-') {
34975
+ seg.orito = targetCnt;
34976
+ seg.to = queryCnt;
34977
+
34978
+ segArray.push(seg);
34979
+ }
34626
34980
  }
34981
+
34627
34982
  let text = '', compText = '';
34628
34983
  ic.queryStart = '';
34629
34984
  ic.queryEnd = '';
34630
- let evalue;
34631
- if(query !== undefined && target !== undefined) {
34632
- evalue = target.scores.e_value.toPrecision(2);
34633
- if(evalue > 1e-200) evalue = parseFloat(evalue).toExponential();
34634
- target.scores.bit_score;
34635
- //var targetSeq = data.targets[chnid.replace(/_/g, '')].seqdata;
34636
- let targetSeq = data.targets[chnid].seqdata;
34637
- let querySeq = query.seqdata;
34638
- let segArray = target.segs;
34985
+
34986
+ if(segArray !== undefined) {
34639
34987
  let target2queryHash = {};
34640
34988
  if(ic.targetGapHash === undefined) ic.targetGapHash = {};
34641
34989
  ic.fullpos2ConsTargetpos = {};
@@ -34663,6 +35011,7 @@ class ShowAnno {
34663
35011
  prevTargetTo = seg.orito;
34664
35012
  prevQueryTo = seg.to;
34665
35013
  }
35014
+
34666
35015
  // the missing residues at the end of the seq will be filled up in the API showNewTrack()
34667
35016
  let nGap = 0;
34668
35017
  ic.alnChainsSeq[chnid] = [];
@@ -34703,13 +35052,14 @@ class ShowAnno {
34703
35052
  compText += ' ';
34704
35053
  }
34705
35054
  }
35055
+
34706
35056
  //title += ', E: ' + evalue;
34707
35057
  }
34708
35058
  else {
34709
35059
  text += "cannot be aligned";
34710
35060
  var aaa = 1; //alert('The sequence can NOT be aligned to the structure');
34711
35061
  }
34712
- let compTitle = 'BLAST, E: ' + evalue;
35062
+ let compTitle = (ic.seqStructAlignData !== undefined) ? 'BLAST, E: ' + evalue : 'Score: ' + evalue;
34713
35063
  ic.showSeqCls.showSeq(chnid, chnidBase, undefined, title, compTitle, text, compText);
34714
35064
  let residueidHash = {};
34715
35065
  let residueid;
@@ -35101,7 +35451,7 @@ class AnnoDomain {
35101
35451
  }
35102
35452
  ic.showAnnoCls.enableHlSeq();
35103
35453
  ic.bAjax3ddomain = true;
35104
- bAjaxDone1 = true;
35454
+ //bAjaxDone1 = true;
35105
35455
  if(ic.deferred3ddomain !== undefined) {
35106
35456
  if(me.cfg.align === undefined || me.cfg.chainalign === undefined) {
35107
35457
  ic.deferred3ddomain.resolve();
@@ -35314,7 +35664,7 @@ class AnnoSnpClinVar {
35314
35664
  ic.labels['clinvar'] = [];
35315
35665
  //var size = Math.round(ic.LABELSIZE * 10 / label.length);
35316
35666
  let size = ic.LABELSIZE;
35317
- let color = "#FFFF00";
35667
+ let color = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd; //"#FFFF00";
35318
35668
  ic.analysisCls.addLabel(label, position.center.x + 1, position.center.y + 1, position.center.z + 1, size, color, undefined, 'clinvar');
35319
35669
  ic.hAtoms = {};
35320
35670
  for(let j in ic.residues[residueid]) {
@@ -37595,23 +37945,25 @@ class HlUpdate {
37595
37945
  $("#" + ic.pre + "atomsCustom")[0].blur();
37596
37946
  }
37597
37947
 
37948
+ //Update the highlight of 3D structure, 2D interaction, sequences, and the menu of defined sets
37949
+ //according to the current highlighted atoms.
37598
37950
  updateHlAll(commandnameArray, bSetMenu, bUnion, bForceHighlight) { let ic = this.icn3d, me = ic.icn3dui;
37599
- // update the previously highlisghted atoms for switching between all and selection
37600
- ic.prevHighlightAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
37951
+ // update the previously highlisghted atoms for switching between all and selection
37952
+ ic.prevHighlightAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
37601
37953
 
37602
- this.updateHlObjects(bForceHighlight);
37954
+ this.updateHlObjects(bForceHighlight);
37603
37955
 
37604
- if(commandnameArray !== undefined) {
37605
- this.updateHlSeqInChain(commandnameArray, bUnion);
37606
- }
37607
- else {
37608
- this.updateHlSeq(undefined, undefined, bUnion);
37609
- }
37956
+ if(commandnameArray !== undefined) {
37957
+ this.updateHlSeqInChain(commandnameArray, bUnion);
37958
+ }
37959
+ else {
37960
+ this.updateHlSeq(undefined, undefined, bUnion);
37961
+ }
37610
37962
 
37611
- this.updateHl2D();
37612
- if(bSetMenu === undefined || bSetMenu) this.updateHlMenus(commandnameArray);
37963
+ this.updateHl2D();
37964
+ if(bSetMenu === undefined || bSetMenu) this.updateHlMenus(commandnameArray);
37613
37965
 
37614
- //ic.annotationCls.showAnnoSelectedChains();
37966
+ //ic.annotationCls.showAnnoSelectedChains();
37615
37967
  }
37616
37968
 
37617
37969
  //Update the highlight of 3D structure display according to the current highlighted atoms.
@@ -37915,27 +38267,6 @@ class HlUpdate {
37915
38267
  $( this ).removeClass('icn3d-highlightSeq');
37916
38268
  });
37917
38269
  }
37918
-
37919
- //Update the highlight of 3D structure, 2D interaction, sequences, and the menu of defined sets
37920
- //according to the current highlighted atoms.
37921
- updateHlAll(commandnameArray, bSetMenu, bUnion, bForceHighlight) { let ic = this.icn3d, me = ic.icn3dui;
37922
- // update the previously highlisghted atoms for switching between all and selection
37923
- ic.prevHighlightAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
37924
-
37925
- this.updateHlObjects(bForceHighlight);
37926
-
37927
- if(commandnameArray !== undefined) {
37928
- this.updateHlSeqInChain(commandnameArray, bUnion);
37929
- }
37930
- else {
37931
- this.updateHlSeq(undefined, undefined, bUnion);
37932
- }
37933
-
37934
- this.updateHl2D();
37935
- if(bSetMenu === undefined || bSetMenu) this.updateHlMenus(commandnameArray);
37936
-
37937
- //ic.annotationCls.showAnnoSelectedChains();
37938
- }
37939
38270
  }
37940
38271
 
37941
38272
  /**
@@ -38235,9 +38566,12 @@ class Selection {
38235
38566
  ic.graphStr = this.getGraphDataForDisplayed();
38236
38567
  }
38237
38568
 
38569
+ // don not redraw graphs after the selection changes
38570
+ /*
38238
38571
  if(ic.bGraph) ic.drawGraphCls.drawGraph(ic.graphStr, ic.pre + 'dl_graph');
38239
38572
  if(ic.bLinegraph) ic.lineGraphCls.drawLineGraph(ic.graphStr);
38240
38573
  if(ic.bScatterplot) ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
38574
+ */
38241
38575
  }
38242
38576
 
38243
38577
  hideSelection() { let ic = this.icn3d, me = ic.icn3dui;
@@ -38318,6 +38652,9 @@ class Selection {
38318
38652
 
38319
38653
  ic.loadScriptCls.renderFinalStep(1);
38320
38654
  ic.definedSetsCls.setMode('all');
38655
+
38656
+ ic.selectionCls.selectAll();
38657
+
38321
38658
  me.htmlCls.clickMenuCls.setLogCmd("reset", true);
38322
38659
 
38323
38660
  ic.hlUpdateCls.removeSeqChainBkgd();
@@ -38441,7 +38778,7 @@ class Selection {
38441
38778
  ic.drawCls.draw();
38442
38779
  }
38443
38780
 
38444
- toggleMembrane() {var ic = this.icn3d, me = ic.icn3dui;
38781
+ toggleMembrane(bShowMembrane) {var ic = this.icn3d, me = ic.icn3dui;
38445
38782
  let structureArray = Object.keys(ic.structures);
38446
38783
 
38447
38784
  for(let i = 0, il = structureArray.length; i < il; ++i) {
@@ -38456,6 +38793,7 @@ class Selection {
38456
38793
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atomsHash);
38457
38794
  oriStyle = 'nothing';
38458
38795
  }
38796
+
38459
38797
  for(let j in atomsHash) {
38460
38798
  let atom = ic.atoms[j];
38461
38799
  if(oriStyle !== 'nothing') {
@@ -38464,10 +38802,14 @@ class Selection {
38464
38802
  else {
38465
38803
  atom.style = 'stick';
38466
38804
  }
38805
+
38806
+ if(bShowMembrane !== undefined) {
38807
+ atom.style = (bShowMembrane) ? 'stick' : 'nothing';
38808
+ }
38467
38809
  }
38468
38810
  }
38469
38811
 
38470
- ic.drawCls.draw();
38812
+ if(bShowMembrane === undefined) ic.drawCls.draw();
38471
38813
  }
38472
38814
 
38473
38815
  adjustMembrane(extra_mem_z, intra_mem_z) {var ic = this.icn3d; ic.icn3dui;
@@ -38758,7 +39100,8 @@ class SetStyle {
38758
39100
  setBackground(color) {var ic = this.icn3d, me = ic.icn3dui;
38759
39101
  ic.setOptionCls.setOption('background', color);
38760
39102
  me.htmlCls.clickMenuCls.setLogCmd('set background ' + color, true);
38761
- let titleColor =(color == 'black' || color == 'transparent') ? me.htmlCls.GREYD : 'black';
39103
+ //let titleColor =(color == 'black' || color == 'transparent') ? me.htmlCls.GREYD : 'black';
39104
+ let titleColor = (color == 'black') ? me.htmlCls.GREYD : 'black';
38762
39105
  $("#" + ic.pre + "title").css("color", titleColor);
38763
39106
  $("#" + ic.pre + "titlelink").css("color", titleColor);
38764
39107
  }
@@ -39281,10 +39624,11 @@ class TextSprite {
39281
39624
 
39282
39625
  let a = parameters.hasOwnProperty("alpha") ? parameters["alpha"] : 1.0;
39283
39626
 
39284
- let bBkgd = true;
39627
+ let bBkgd = false; //true;
39285
39628
  let bSchematic = false;
39286
39629
  if(parameters.hasOwnProperty("bSchematic") && parameters["bSchematic"]) {
39287
39630
  bSchematic = true;
39631
+ bBkgd = true;
39288
39632
 
39289
39633
  fontsize = 40;
39290
39634
  }
@@ -39304,9 +39648,13 @@ class TextSprite {
39304
39648
  }
39305
39649
 
39306
39650
  let textAlpha = 1.0;
39307
-
39308
- let textColor = parameters.hasOwnProperty("textColor") && parameters["textColor"] !== undefined ? me.utilsCls.hexToRgb(parameters["textColor"], textAlpha) : { r:255, g:255, b:0, a:1.0 };
39309
- if(!textColor) textColor = { r:255, g:255, b:0, a:1.0 };
39651
+ // default yellow
39652
+ //let textColor = parameters.hasOwnProperty("textColor") && parameters["textColor"] !== undefined ? me.utilsCls.hexToRgb(parameters["textColor"], textAlpha) : { r:255, g:255, b:0, a:1.0 };
39653
+ // default black or white
39654
+ let defaultColor = (ic.opts.background != 'black') ? { r:0, g:0, b:0, a:1.0 } : { r:255, g:255, b:0, a:1.0 };
39655
+ let textColor = parameters.hasOwnProperty("textColor") && parameters["textColor"] !== undefined ? me.utilsCls.hexToRgb(parameters["textColor"], textAlpha)
39656
+ : defaultColor;
39657
+ if(!textColor) textColor = defaultColor;
39310
39658
 
39311
39659
  let canvas = document.createElement('canvas');
39312
39660
 
@@ -39443,6 +39791,7 @@ class Label {
39443
39791
 
39444
39792
  for(let name in labels) {
39445
39793
  let labelArray = (labels[name] !== undefined) ? labels[name] : [];
39794
+ let defaultColor = (ic.opts.background != 'black') ? ic.colorWhitebkgd : ic.colorBlackbkgd;
39446
39795
 
39447
39796
  for (let i = 0, il = labelArray.length; i < il; ++i) {
39448
39797
  let label = labelArray[i];
@@ -39453,7 +39802,9 @@ class Label {
39453
39802
  if(label.background == 0) label.background = undefined;
39454
39803
 
39455
39804
  let labelsize = (label.size !== undefined) ? label.size : ic.LABELSIZE;
39456
- let labelcolor = (label.color !== undefined) ? label.color : '#ffff00';
39805
+ let labelcolor = (label.color !== undefined) ? label.color : defaultColor;
39806
+ if(ic.labelcolor) labelcolor = ic.labelcolor;
39807
+
39457
39808
  let labelbackground = (label.background !== undefined) ? label.background : '#cccccc';
39458
39809
  let labelalpha = (label.alpha !== undefined) ? label.alpha : 1.0;
39459
39810
 
@@ -39479,7 +39830,8 @@ class Label {
39479
39830
  }
39480
39831
  }
39481
39832
 
39482
- bb.position.set(label.position.x, label.position.y, label.position.z);
39833
+ let labelOffset = (name == 'schematic' || name == 'residue') ? 0 : ic.coilWidth; // 0.3
39834
+ bb.position.set(label.position.x + labelOffset, label.position.y + labelOffset, label.position.z + labelOffset);
39483
39835
  ic.mdl.add(bb);
39484
39836
  // do not add labels to objects for pk
39485
39837
  }
@@ -39654,49 +40006,68 @@ class ApplyDisplay {
39654
40006
  atomsObj = {};
39655
40007
  } // end if(bHighlight === 1)
39656
40008
 
39657
- ic.setStyleCls.setStyle2Atoms(atoms);
40009
+ if(ic.bInitial) {
40010
+ if(me.htmlCls.setHtmlCls.getCookie('membrane') != '') {
40011
+ let bMembrane = parseInt(me.htmlCls.setHtmlCls.getCookie('membrane'));
39658
40012
 
39659
- //ic.bAllAtoms = (Object.keys(atoms).length === Object.keys(ic.atoms).length);
39660
- ic.bAllAtoms = false;
39661
- if(atoms && atoms !== undefined ) {
39662
- ic.bAllAtoms = (Object.keys(atoms).length === Object.keys(ic.atoms).length);
40013
+ if(ic.bMembrane != bMembrane) {
40014
+ me.htmlCls.clickMenuCls.setLogCmd('set membrane ' + bMembrane, true);
40015
+ }
40016
+
40017
+ ic.bMembrane = (!isNaN(bMembrane)) ? parseInt(bMembrane) : 0;
40018
+ }
40019
+
40020
+ // show membrane
40021
+ if(ic.bMembrane) {
40022
+ ic.selectionCls.toggleMembrane(true);
40023
+ }
40024
+ else {
40025
+ ic.selectionCls.toggleMembrane(false);
40026
+ }
39663
40027
  }
39664
40028
 
40029
+ ic.setStyleCls.setStyle2Atoms(atoms);
40030
+
40031
+ //ic.bAllAtoms = false;
40032
+ //if(atoms && atoms !== undefined ) {
40033
+ // ic.bAllAtoms = (Object.keys(atoms).length === Object.keys(ic.atoms).length);
40034
+ //}
40035
+
39665
40036
  let chemicalSchematicRadius = ic.cylinderRadius * 0.5;
39666
40037
 
39667
40038
  // remove schematic labels
39668
40039
  //if(ic.labels !== undefined) ic.labels['schematic'] = undefined;
39669
40040
  if(ic.labels !== undefined) delete ic.labels['schematic'];
39670
-
39671
- let bOnlySideChains = false;
39672
-
40041
+ /*
39673
40042
  if(bHighlight) {
39674
- let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(ic.hAtoms);
40043
+ //let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(ic.hAtoms);
39675
40044
 
39676
40045
  let proteinAtoms = me.hashUtilsCls.intHash(ic.hAtoms, ic.proteins);
40046
+
39677
40047
  let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(proteinAtoms);
40048
+ let residueHashCalpha = ic.firstAtomObjCls.getResiduesFromCalphaAtoms(proteinAtoms);
39678
40049
 
39679
- if(Object.keys(residueHash) > Object.keys(residueHashCalpha)) { // some residues have only side chains
40050
+ if(Object.keys(residueHash).length > Object.keys(residueHashCalpha).length) { // some residues have only side chains
39680
40051
  bOnlySideChains = true;
39681
40052
  }
39682
40053
  }
39683
-
40054
+ */
39684
40055
  for(let style in ic.style2atoms) {
39685
40056
  // 14 styles: ribbon, strand, cylinder and plate, nucleotide cartoon, o3 trace, schematic, c alpha trace, b factor tube, lines, stick, ball and stick, sphere, dot, nothing
39686
40057
  let atomHash = ic.style2atoms[style];
39687
40058
  //var bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "O3'", "O3*") || me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash), "P");
39688
40059
  let bPhosphorusOnly = me.utilsCls.isCalphaPhosOnly(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms));
39689
40060
 
39690
- //if(style === 'ribbon') {
39691
- if(style === 'ribbon' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
40061
+ if(style === 'ribbon') {
40062
+ //if(style === 'ribbon' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
39692
40063
  ic.strandCls.createStrand(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), 2, undefined, true, undefined, undefined, false, ic.ribbonthickness, bHighlight);
39693
40064
  }
39694
- //else if(style === 'strand') {
39695
- else if(style === 'strand' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
40065
+ else if(style === 'strand') {
40066
+ //else if(style === 'strand' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
39696
40067
  ic.strandCls.createStrand(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), null, null, null, null, null, false, undefined, bHighlight);
39697
40068
  }
39698
- //else if(style === 'cylinder and plate') {
39699
- else if(style === 'cylinder and plate' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
40069
+ else if(style === 'cylinder and plate') {
40070
+ //else if(style === 'cylinder and plate' && (!bHighlight || (bHighlight && !bOnlySideChains))) {
39700
40071
  ic.cylinderCls.createCylinderHelix(me.hashUtilsCls.hash2Atoms(atomHash, ic.atoms), ic.cylinderHelixRadius, bHighlight);
39701
40072
  }
39702
40073
  else if(style === 'nucleotide cartoon') {
@@ -39787,11 +40158,30 @@ class ApplyDisplay {
39787
40158
  if(ic.labels !== undefined && Object.keys(ic.labels).length > 0) {
39788
40159
  ic.labelCls.hideLabels();
39789
40160
 
40161
+ // change label color
40162
+ for(let labeltype in ic.labels) {
40163
+ if(labeltype != 'schematic') this.changeLabelColor(ic.labels[labeltype]);
40164
+ }
40165
+
39790
40166
  // labels
39791
40167
  ic.labelCls.createLabelRepresentation(ic.labels);
39792
40168
  }
39793
40169
  }
39794
40170
 
40171
+ changeLabelColor(labelArray) { let ic = this.icn3d; ic.icn3dui;
40172
+ if(labelArray) {
40173
+ for(let i = 0, il = labelArray.length; i < il; ++i) {
40174
+ let label = labelArray[i];
40175
+ if((ic.opts.background != 'black') && label.color == ic.colorBlackbkgd) {
40176
+ label.color = ic.colorWhitebkgd;
40177
+ }
40178
+ else if((ic.opts.background == 'black') && label.color == ic.colorWhitebkgd) {
40179
+ label.color = ic.colorBlackbkgd;
40180
+ }
40181
+ }
40182
+ }
40183
+ }
40184
+
39795
40185
  selectMainChainSubset(atoms) { let ic = this.icn3d; ic.icn3dui;
39796
40186
  let nuclMainArray = ["C1'", "C1*", "C2'", "C2*", "C3'", "C3*", "C4'", "C4*", "C5'", "C5*", "O3'", "O3*", "O4'", "O4*", "O5'", "O5*", "P", "OP1", "O1P", "OP2", "O2P"];
39797
40187
 
@@ -40259,14 +40649,16 @@ class ApplyOther {
40259
40649
  }
40260
40650
  }
40261
40651
 
40262
- if(me.htmlCls.setHtmlCls.getCookie('glycan') != '') {
40263
- let bGlycansCartoon = parseInt(me.htmlCls.setHtmlCls.getCookie('glycan'));
40652
+ if(ic.bInitial) {
40653
+ if(me.htmlCls.setHtmlCls.getCookie('glycan') != '') {
40654
+ let bGlycansCartoon = parseInt(me.htmlCls.setHtmlCls.getCookie('glycan'));
40264
40655
 
40265
- if(ic.bGlycansCartoon != bGlycansCartoon) {
40266
- me.htmlCls.clickMenuCls.setLogCmd('set glycan ' + bGlycansCartoon, true);
40267
- }
40656
+ if(ic.bGlycansCartoon != bGlycansCartoon) {
40657
+ me.htmlCls.clickMenuCls.setLogCmd('set glycan ' + bGlycansCartoon, true);
40658
+ }
40268
40659
 
40269
- ic.bGlycansCartoon = bGlycansCartoon;
40660
+ ic.bGlycansCartoon = bGlycansCartoon;
40661
+ }
40270
40662
  }
40271
40663
 
40272
40664
  // add cartoon for glycans
@@ -41497,7 +41889,6 @@ class Instancing {
41497
41889
  let mdlImpostorTmp = new THREE.Object3D();
41498
41890
  let mdl_ghostTmp = new THREE.Object3D();
41499
41891
 
41500
- console.log("no instancing, Object.keys(ic.structures).length: " + Object.keys(ic.structures).length);
41501
41892
  // for (let i = 0; i < ic.biomtMatrices.length; i++) { // skip itself
41502
41893
  for (let i = 0; i < ic.biomtMatrices.length && Object.keys(ic.structures).length == 1; i++) { // skip itself
41503
41894
  let mat = ic.biomtMatrices[i];
@@ -41895,7 +42286,6 @@ console.log("no instancing, Object.keys(ic.structures).length: " + Object.keys(i
41895
42286
  let identity = new THREE.Matrix4();
41896
42287
  identity.identity();
41897
42288
 
41898
- console.log("instancing, Object.keys(ic.structures).length: " + Object.keys(ic.structures).length);
41899
42289
  for (let i = 0; i < ic.biomtMatrices.length && Object.keys(ic.structures).length == 1; i++) { // skip itself
41900
42290
  let mat = ic.biomtMatrices[i];
41901
42291
  if (mat === undefined) continue;
@@ -42055,7 +42445,9 @@ class Draw {
42055
42445
  // ic.renderer.gammaOutput = true
42056
42446
 
42057
42447
  ic.renderer.setPixelRatio( window.devicePixelRatio ); // r71
42058
- if(ic.scene) ic.renderer.render(ic.scene, cam);
42448
+ if(ic.scene) {
42449
+ ic.renderer.render(ic.scene, cam);
42450
+ }
42059
42451
  }
42060
42452
 
42061
42453
  }
@@ -42579,7 +42971,7 @@ class SaveFile {
42579
42971
  };
42580
42972
  }
42581
42973
 
42582
- exportCustomAtoms() {var ic = this.icn3d; ic.icn3dui;
42974
+ exportCustomAtoms(bDetails) {var ic = this.icn3d; ic.icn3dui;
42583
42975
  let html = "";
42584
42976
  let nameArray =(ic.defNames2Residues !== undefined) ? Object.keys(ic.defNames2Residues).sort() : [];
42585
42977
  for(let i = 0, il = nameArray.length; i < il; ++i) {
@@ -42588,9 +42980,8 @@ class SaveFile {
42588
42980
  ic.defNames2Descr[name];
42589
42981
  let command = ic.defNames2Command[name];
42590
42982
  command = command.replace(/,/g, ', ');
42591
- html += name + "\tselect ";
42592
- html += ic.resid2specCls.residueids2spec(residueArray);
42593
- html += "\n";
42983
+
42984
+ html += this.exportResidues(name, residueArray, bDetails);
42594
42985
  } // outer for
42595
42986
  nameArray =(ic.defNames2Atoms !== undefined) ? Object.keys(ic.defNames2Atoms).sort() : [];
42596
42987
  for(let i = 0, il = nameArray.length; i < il; ++i) {
@@ -42600,15 +42991,51 @@ class SaveFile {
42600
42991
  let command = ic.defNames2Command[name];
42601
42992
  command = command.replace(/,/g, ', ');
42602
42993
  let residueArray = ic.resid2specCls.atoms2residues(atomArray);
42603
- if(residueArray.length > 0) {
42604
- html += name + "\tselect ";
42605
- html += ic.resid2specCls.residueids2spec(residueArray);
42606
- html += "\n";
42607
- }
42994
+
42995
+ html += this.exportResidues(name, residueArray, bDetails);
42608
42996
  } // outer for
42609
42997
  return html;
42610
42998
  }
42611
42999
 
43000
+ exportResidues(name, residueArray, bDetails) {var ic = this.icn3d, me = ic.icn3dui;
43001
+ let html = '';
43002
+
43003
+ if(residueArray.length > 0) {
43004
+ if(bDetails) {
43005
+ let chainidHash = {};
43006
+ for(let i = 0, il = residueArray.length; i < il; ++i) {
43007
+ let resid = residueArray[i];
43008
+ let atom = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid]);
43009
+ let chainid = atom.structure + '_' + atom.chain;
43010
+ let resnAbbr = me.utilsCls.residueName2Abbr(atom.resn);
43011
+ let resName = resnAbbr + atom.resi;
43012
+
43013
+ if(!chainidHash.hasOwnProperty(chainid)) {
43014
+ chainidHash[chainid] = [];
43015
+ }
43016
+
43017
+ chainidHash[chainid].push(resName);
43018
+ }
43019
+
43020
+ html += name + ":\n";
43021
+ for(let chainid in chainidHash) {
43022
+ let resStr = (chainidHash[chainid].length == 1) ? "residue" : "residues";
43023
+ html += chainid + " (" + chainidHash[chainid].length + " " + resStr + "): ";
43024
+ html += chainidHash[chainid].join(", ");
43025
+ html += "\n";
43026
+ }
43027
+ html += "\n";
43028
+ }
43029
+ else {
43030
+ html += name + "\tselect ";
43031
+ html += ic.resid2specCls.residueids2spec(residueArray);
43032
+ html += "\n";
43033
+ }
43034
+ }
43035
+
43036
+ return html;
43037
+ }
43038
+
42612
43039
  //getAtomPDB: function(atomHash, bPqr, bPdb, bNoChem) { let ic = this.icn3d, me = ic.icn3dui;
42613
43040
  getAtomPDB(atomHash, bPqr, bNoChem, bNoHeader) { let ic = this.icn3d, me = ic.icn3dui;
42614
43041
  let pdbStr = '';
@@ -42700,37 +43127,53 @@ class SaveFile {
42700
43127
  }
42701
43128
  }
42702
43129
 
43130
+ /*
42703
43131
  // get missing residues
42704
- let chainid2missingResi = {};
43132
+ let ic.chainMissingResidueArray = {};
42705
43133
  for(let chainid in ic.chainsSeq) {
42706
43134
  let pos = chainid.indexOf('_');
42707
- chainid.substr(0, pos);
43135
+ let chain = chainid.substr(0, pos);
42708
43136
 
42709
43137
  for(let i = 0, il = ic.chainsSeq[chainid].length; i < il; ++i) {
42710
43138
  let resi = ic.chainsSeq[chainid][i].resi;
42711
43139
  let resid = chainid + '_' + resi;
42712
43140
  if(!ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid])) { // mising coordinate
42713
- if(chainid2missingResi[chainid] === undefined) chainid2missingResi[chainid] = [];
43141
+ if(ic.chainMissingResidueArray[chainid] === undefined) ic.chainMissingResidueArray[chainid] = [];
42714
43142
  let seq = me.utilsCls.residueAbbr2Name(ic.chainsSeq[chainid][i].name);
42715
43143
  let resiObj = {'resi': resi, 'seq': seq};
42716
- chainid2missingResi[chainid].push(resiObj);
43144
+ ic.chainMissingResidueArray[chainid].push(resiObj);
42717
43145
  }
42718
43146
  }
42719
43147
  }
42720
43148
 
42721
43149
  // add missing residues "REMARK 465..."
42722
- for(let chainid in chainid2missingResi) {
43150
+ for(let chainid in ic.chainMissingResidueArray) {
42723
43151
  let pos = chainid.indexOf('_');
42724
43152
  let chain = chainid.substr(pos + 1, 2);
42725
43153
  let stru = chainid.substr(0, pos);
42726
43154
 
42727
- for(let i = 0, il = chainid2missingResi[chainid].length; i < il; ++i) {
42728
- let resi = chainid2missingResi[chainid][i].resi;
42729
- let seq = chainid2missingResi[chainid][i].seq;
43155
+ for(let i = 0, il = ic.chainMissingResidueArray[chainid].length; i < il; ++i) {
43156
+ let resi = ic.chainMissingResidueArray[chainid][i].resi;
43157
+ let seq = ic.chainMissingResidueArray[chainid][i].seq;
42730
43158
 
42731
43159
  stru2header[stru] += "REMARK 465 " + seq.padStart(3, " ") + chain.padStart(2, " ") + " " + resi.toString().padStart(5, " ") + "\n";
42732
43160
  }
42733
43161
  }
43162
+ */
43163
+
43164
+ // add missing residues "REMARK 465..."
43165
+ for(let chainid in ic.chainMissingResidueArray) {
43166
+ let pos = chainid.indexOf('_');
43167
+ let chain = chainid.substr(pos + 1, 2);
43168
+ let stru = chainid.substr(0, pos);
43169
+
43170
+ for(let i = 0, il = ic.chainMissingResidueArray[chainid].length; i < il; ++i) {
43171
+ let resi = ic.chainMissingResidueArray[chainid][i].resi;
43172
+ let resn = me.utilsCls.residueAbbr2Name(ic.chainMissingResidueArray[chainid][i].name);
43173
+
43174
+ stru2header[stru] += "REMARK 465 " + resn.padStart(3, " ") + chain.padStart(2, " ") + " " + resi.toString().padStart(5, " ") + "\n";
43175
+ }
43176
+ }
42734
43177
 
42735
43178
  let connStr = '';
42736
43179
  let struArray = Object.keys(ic.structures);
@@ -43009,7 +43452,7 @@ class SaveFile {
43009
43452
  if(ic.molTitle !== undefined && ic.molTitle !== '') {
43010
43453
  let title = ic.molTitle;
43011
43454
 
43012
- let titlelinkColor =(ic.opts['background'] == 'white' || ic.opts['background'] == 'grey') ? 'black' : me.htmlCls.GREYD;
43455
+ let titlelinkColor =(ic.opts['background'] == 'black') ? me.htmlCls.GREYD : 'black';
43013
43456
 
43014
43457
  if(ic.inputid === undefined) {
43015
43458
  if(ic.molTitle.length > 40) title = ic.molTitle.substr(0, 40) + "...";
@@ -43456,6 +43899,21 @@ class ClickMenu {
43456
43899
  let file_pref =(ic.inputid) ? ic.inputid : "custom";
43457
43900
  ic.saveFileCls.saveFile(file_pref + '_selections.txt', 'text', [text]);
43458
43901
  });
43902
+
43903
+ me.myEventCls.onIds("#" + me.pre + "mn1_exportSelDetails", "click", function(e) { let ic = me.icn3d;
43904
+ thisClass.setLogCmd("export all selections with details", false);
43905
+ if(ic.bSetChainsAdvancedMenu === undefined || !ic.bSetChainsAdvancedMenu) {
43906
+ let prevHAtoms = me.hashUtilsCls.cloneHash(ic.hAtoms);
43907
+ ic.definedSetsCls.setPredefinedInMenu();
43908
+ ic.bSetChainsAdvancedMenu = true;
43909
+ ic.hAtoms = me.hashUtilsCls.cloneHash(prevHAtoms);
43910
+ }
43911
+ let bDetails = true;
43912
+ let text = ic.saveFileCls.exportCustomAtoms(bDetails);
43913
+ let file_pref =(ic.inputid) ? ic.inputid : "custom";
43914
+ ic.saveFileCls.saveFile(file_pref + '_sel_details.txt', 'text', [text]);
43915
+ });
43916
+
43459
43917
  // },
43460
43918
  // clkMn1_sharelink: function() {
43461
43919
  me.myEventCls.onIds("#" + me.pre + "mn1_sharelink", "click", function(e) { let ic = me.icn3d;
@@ -44597,6 +45055,10 @@ class ClickMenu {
44597
45055
  me.myEventCls.onIds("#" + me.pre + "mn6_addlabelSelection", "click", function(e) { me.icn3d;
44598
45056
  me.htmlCls.dialogCls.openDlg('dl_addlabelselection', 'Add custom labels by the selected');
44599
45057
  });
45058
+
45059
+ me.myEventCls.onIds("#" + me.pre + "mn6_labelColor", "click", function(e) { me.icn3d;
45060
+ me.htmlCls.dialogCls.openDlg('dl_labelColor', 'Change color for all labels');
45061
+ });
44600
45062
  // },
44601
45063
  // clkMn2_saveselection: function() {
44602
45064
  me.myEventCls.onIds("#" + me.pre + "mn2_saveselection", "click", function(e) { me.icn3d;
@@ -44605,7 +45067,8 @@ class ClickMenu {
44605
45067
  // },
44606
45068
  // clkMn6_addlabelNo: function() {
44607
45069
  me.myEventCls.onIds(["#" + me.pre + "mn6_addlabelNo", "#" + me.pre + "removeLabels"], "click", function(e) { let ic = me.icn3d;
44608
- ic.pickpair = false;
45070
+ ic.labelcolor = undefined;
45071
+ ic.pickpair = false;
44609
45072
  //ic.labels['residue'] = [];
44610
45073
  //ic.labels['custom'] = [];
44611
45074
  let select = "set labels off";
@@ -45158,6 +45621,8 @@ class SetMenu {
45158
45621
  setTopMenusHtml(id, str1, str2) { let me = this.icn3dui;
45159
45622
  if(me.bNode) return '';
45160
45623
 
45624
+ let titleColor =(me.htmlCls.opts['background'] == 'black') ? me.htmlCls.GREYD : 'black';
45625
+
45161
45626
  let html = "";
45162
45627
 
45163
45628
  html += "<div style='position:relative;'>";
@@ -45173,15 +45638,15 @@ class SetMenu {
45173
45638
  let tdStr = '<td valign="top">';
45174
45639
  html += tdStr + this.setMenu1() + '</td>';
45175
45640
 
45176
- if(!me.cfg.simplemenu) {
45641
+ //if(!me.cfg.simplemenu) {
45177
45642
  html += tdStr + this.setMenu2() + '</td>';
45178
- }
45643
+ //}
45179
45644
 
45180
45645
  html += tdStr + this.setMenu2b() + '</td>';
45181
45646
  html += tdStr + this.setMenu3() + '</td>';
45182
45647
  html += tdStr + this.setMenu4() + '</td>';
45183
45648
 
45184
- if(!me.cfg.simplemenu) {
45649
+ //if(!me.cfg.simplemenu) {
45185
45650
  html += tdStr + this.setMenu5() + '</td>';
45186
45651
  //html += tdStr + this.setMenu5b() + '</td>';
45187
45652
  html += tdStr + this.setMenu6() + '</td>';
@@ -45192,7 +45657,7 @@ class SetMenu {
45192
45657
  html += tdStr + '<div class="icn3d-commandTitle" style="white-space:nowrap; margin-top:10px; border-left:solid 1px #888888"><span id="' + me.pre + 'selection_expand" class="icn3d-expand icn3d-link" title="Expand">' + me.htmlCls.space2 + 'Toolbar <span class="ui-icon ui-icon-plus" style="width:15px"></span>' + me.htmlCls.space2 + '</span><span id="' + me.pre + 'selection_shrink" class="icn3d-shrink icn3d-link" style="display:none;" title="Shrink">' + me.htmlCls.space2 + 'Toolbar <span class="ui-icon ui-icon-minus" style="width:15px"></span>' + me.htmlCls.space2 + '</span></div></td>';
45193
45658
 
45194
45659
  html += tdStr + '<div class="icn3d-commandTitle" style="white-space:nowrap; margin-top:8px; border-left:solid 1px #888888">' + me.htmlCls.space2 + '<input type="text" id="' + me.pre + 'search_seq" size="10" placeholder="one-letter seq."> <button style="white-space:nowrap;" id="' + me.pre + 'search_seq_button">Search</button> <a style="text-decoration: none;" href="' + me.htmlCls.baseUrl + 'icn3d/icn3d.html#selectb" target="_blank" title="Specification tips">?</a></div></td>';
45195
- }
45660
+ //}
45196
45661
 
45197
45662
  html += "</tr>";
45198
45663
  html += "</table>";
@@ -45201,7 +45666,7 @@ class SetMenu {
45201
45666
  html += this.setTools();
45202
45667
 
45203
45668
  // show title at the top left corner
45204
- html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:table-row; margin: 85px 0px 0px 5px; color:" + me.htmlCls.GREYD + "; width:" + me.htmlCls.WIDTH + "px'></div>";
45669
+ html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:table-row; margin: 85px 0px 0px 5px; color:" + titleColor + "; width:" + me.htmlCls.WIDTH + "px'></div>";
45205
45670
 
45206
45671
  html += me.htmlCls.divStr + "viewer' style='position:relative; width:100%; height:100%; background-color: " + me.htmlCls.GREYD + ";'>";
45207
45672
 
@@ -45218,7 +45683,7 @@ class SetMenu {
45218
45683
  let tmpStr = 'top:180px; font-size: 1.8em;';
45219
45684
  html += me.htmlCls.divStr + "wait' style='position:absolute; left:50px; " + tmpStr + " color: #444444;'>Loading data...</div>";
45220
45685
  }
45221
- html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #000;'>Your browser does not support WebGL.</canvas>";
45686
+ html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #FFF;'>Your browser does not support WebGL.</canvas>";
45222
45687
 
45223
45688
  // separate for the log box
45224
45689
  if(me.cfg.showcommand === undefined || me.cfg.showcommand) {
@@ -45254,6 +45719,8 @@ class SetMenu {
45254
45719
  setTopMenusHtmlMobile(id, str1, str2) { let me = this.icn3dui;
45255
45720
  if(me.bNode) return '';
45256
45721
 
45722
+ let titleColor =(me.htmlCls.opts['background'] == 'black') ? me.htmlCls.GREYD : 'black';
45723
+
45257
45724
  let html = "";
45258
45725
 
45259
45726
  html += "<div style='position:relative;'>";
@@ -45323,8 +45790,6 @@ class SetMenu {
45323
45790
  //html += me.htmlCls.setMenuCls.setTools();
45324
45791
 
45325
45792
  // show title at the top left corner
45326
- let titleColor =(me.htmlCls.opts['background'] == 'white' || me.htmlCls.opts['background'] == 'grey') ? 'black' : me.htmlCls.GREYD;
45327
-
45328
45793
  html += me.htmlCls.divStr + "title' class='icn3d-commandTitle' style='font-size:1.2em; font-weight:normal; position:absolute; z-index:1; float:left; display:block; margin: 12px 0px 0px 40px; color:" + titleColor + "; width:" +(me.htmlCls.WIDTH - 40).toString() + "px'></div>";
45329
45794
  html += me.htmlCls.divStr + "viewer' style='position:relative; width:100%; height:100%; background-color: " + me.htmlCls.GREYD + ";'>";
45330
45795
  html += me.htmlCls.divStr + "mnLogSection'>";
@@ -45336,7 +45801,7 @@ class SetMenu {
45336
45801
  let tmpStr = 'top:180px; font-size: 1.8em;';
45337
45802
  html += me.htmlCls.divStr + "wait' style='position:absolute; left:50px; " + tmpStr + " color: #444444;'>Loading data...</div>";
45338
45803
  }
45339
- html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #000;'>Your browser does not support WebGL.</canvas>";
45804
+ html += "<canvas id='" + me.pre + "canvas' style='width:100%; height: 100%; background-color: #FFF;'>Your browser does not support WebGL.</canvas>";
45340
45805
 
45341
45806
  // separate for the log box
45342
45807
  if(me.cfg.showcommand === undefined || me.cfg.showcommand) {
@@ -45528,15 +45993,18 @@ class SetMenu {
45528
45993
  let html = "";
45529
45994
 
45530
45995
  html += "<ul class='icn3d-mn-item'>";
45996
+ html += "<li><a href='https://www.ncbi.nlm.nih.gov/structure' target='_blank'>Search Structure " + me.htmlCls.wifiStr + "</a></li>";
45531
45997
  html += "<li><span>Retrieve by ID</span>";
45532
45998
  html += "<ul>";
45533
45999
  html += me.htmlCls.setHtmlCls.getLink('mn1_mmdbid', 'MMDB ID ' + me.htmlCls.wifiStr);
45534
46000
  html += me.htmlCls.setHtmlCls.getLink('mn1_mmtfid', 'MMTF ID ' + me.htmlCls.wifiStr);
45535
46001
  html += me.htmlCls.setHtmlCls.getLink('mn1_pdbid', 'PDB ID ' + me.htmlCls.wifiStr);
45536
46002
  html += me.htmlCls.setHtmlCls.getLink('mn1_afid', 'AlphaFold UniProt ID ' + me.htmlCls.wifiStr);
45537
- html += me.htmlCls.setHtmlCls.getLink('mn1_opmid', 'OPM PDB ID ' + me.htmlCls.wifiStr);
45538
- html += me.htmlCls.setHtmlCls.getLink('mn1_mmcifid', 'mmCIF ID ' + me.htmlCls.wifiStr);
45539
- html += me.htmlCls.setHtmlCls.getLink('mn1_gi', 'NCBI gi ' + me.htmlCls.wifiStr);
46003
+ if(!me.cfg.simplemenu) {
46004
+ html += me.htmlCls.setHtmlCls.getLink('mn1_opmid', 'OPM PDB ID ' + me.htmlCls.wifiStr);
46005
+ html += me.htmlCls.setHtmlCls.getLink('mn1_mmcifid', 'mmCIF ID ' + me.htmlCls.wifiStr);
46006
+ html += me.htmlCls.setHtmlCls.getLink('mn1_gi', 'NCBI gi ' + me.htmlCls.wifiStr);
46007
+ }
45540
46008
  html += me.htmlCls.setHtmlCls.getLink('mn1_uniprotid', 'UniProt ID ' + me.htmlCls.wifiStr);
45541
46009
  html += me.htmlCls.setHtmlCls.getLink('mn1_cid', 'PubChem CID ' + me.htmlCls.wifiStr);
45542
46010
  html += "</ul>";
@@ -45546,29 +46014,32 @@ class SetMenu {
45546
46014
  // html += me.htmlCls.setHtmlCls.getLink('mn1_pdbfile', 'PDB File');
45547
46015
  // html += me.htmlCls.setHtmlCls.getLink('mn1_pdbfile_app', 'PDB File (append)');
45548
46016
  html += me.htmlCls.setHtmlCls.getLink('mn1_pdbfile_app', 'PDB File (appendable)');
45549
- html += me.htmlCls.setHtmlCls.getLink('mn1_mmciffile', 'mmCIF File');
46017
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_mmciffile', 'mmCIF File');
45550
46018
  html += me.htmlCls.setHtmlCls.getLink('mn1_mol2file', 'Mol2 File');
45551
46019
  html += me.htmlCls.setHtmlCls.getLink('mn1_sdffile', 'SDF File');
45552
46020
  html += me.htmlCls.setHtmlCls.getLink('mn1_xyzfile', 'XYZ File');
45553
- html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46021
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_urlfile', 'URL(Same Host) ' + me.htmlCls.wifiStr);
45554
46022
  html += "<li>-</li>";
45555
46023
  html += me.htmlCls.setHtmlCls.getLink('mn1_pngimage', 'iCn3D PNG Image');
45556
46024
  html += me.htmlCls.setHtmlCls.getLink('mn1_state', 'State/Script File');
45557
- html += me.htmlCls.setHtmlCls.getLink('mn1_fixedversion', 'Share Link in Archived Ver. ' + me.htmlCls.wifiStr);
46025
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn1_fixedversion', 'Share Link in Archived Ver. ' + me.htmlCls.wifiStr);
45558
46026
  html += me.htmlCls.setHtmlCls.getLink('mn1_selection', 'Selection File');
45559
- html += "<li>-</li>";
46027
+
46028
+ if(!me.cfg.simplemenu) {
46029
+ html += "<li>-</li>";
45560
46030
 
45561
- html += "<li><span>Electron Density(DSN6)</span>";
45562
- html += "<ul>";
45563
- html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6', 'Local File');
45564
- html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6url', 'URL(Same Host) ' + me.htmlCls.wifiStr);
45565
- html += "</ul>";
46031
+ html += "<li><span>Electron Density(DSN6)</span>";
46032
+ html += "<ul>";
46033
+ html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6', 'Local File');
46034
+ html += me.htmlCls.setHtmlCls.getLink('mn1_dsn6url', 'URL(Same Host) ' + me.htmlCls.wifiStr);
46035
+ html += "</ul>";
46036
+ }
45566
46037
 
45567
46038
  html += "</ul>";
45568
46039
  html += "</li>";
45569
46040
  html += "<li><span>Align</span>";
45570
46041
  html += "<ul>";
45571
- html += me.htmlCls.setHtmlCls.getLink('mn1_blast_rep_id', 'Sequence to Structure ' + me.htmlCls.wifiStr);
46042
+ html += me.htmlCls.setHtmlCls.getLink('mn1_blast_rep_id', 'Sequence to Structure');
45572
46043
  html += me.htmlCls.setHtmlCls.getLink('mn1_align', 'Structure to Structure ' + me.htmlCls.wifiStr);
45573
46044
  //html += me.htmlCls.setHtmlCls.getLink('mn1_chainalign', 'Chain to Chain');
45574
46045
  html += me.htmlCls.setHtmlCls.getLink('mn1_chainalign', 'Multiple Chains ' + me.htmlCls.wifiStr);
@@ -45593,15 +46064,18 @@ class SetMenu {
45593
46064
  html += "<li>-</li>";
45594
46065
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportVrml', 'WRL/VRML(Color)');
45595
46066
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportStl', 'STL');
45596
- html += "<li>-</li>";
45597
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerYes', 'Add All Stabilizers');
45598
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerNo', 'Remove All Stabilizers');
45599
- html += "<li>-</li>";
45600
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerOne', 'Add One Stabilizer');
45601
- html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerRmOne', 'Remove One Stabilizer');
45602
- html += "<li>-</li>";
45603
- html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessSet', 'Set Thickness');
45604
- //html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessReset', 'Reset Thickness');
46067
+
46068
+ if(!me.cfg.simplemenu) {
46069
+ html += "<li>-</li>";
46070
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerYes', 'Add All Stabilizers');
46071
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerNo', 'Remove All Stabilizers');
46072
+ html += "<li>-</li>";
46073
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerOne', 'Add One Stabilizer');
46074
+ html += me.htmlCls.setHtmlCls.getLink('mn1_stabilizerRmOne', 'Remove One Stabilizer');
46075
+ html += "<li>-</li>";
46076
+ html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessSet', 'Set Thickness');
46077
+ //html += me.htmlCls.setHtmlCls.getLink('mn1_thicknessReset', 'Reset Thickness');
46078
+ }
45605
46079
  }
45606
46080
  else {
45607
46081
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportVrml', 'VRML(Color)');
@@ -45619,14 +46093,17 @@ class SetMenu {
45619
46093
  html += "<ul>";
45620
46094
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas', 'Original Size & HTML');
45621
46095
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas1', 'Original Size');
45622
- html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas2', '2X Large');
45623
- html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas4', '4X Large');
45624
- html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas8', '8X Large');
46096
+ if(!me.cfg.simplemenu) {
46097
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas2', '2X Large');
46098
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas4', '4X Large');
46099
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportCanvas8', '8X Large');
46100
+ }
45625
46101
  html += "</ul>";
45626
46102
  html += "</li>";
45627
46103
 
45628
46104
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportState', 'State File');
45629
46105
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportSelections', 'Selection File');
46106
+ html += me.htmlCls.setHtmlCls.getLink('mn1_exportSelDetails', 'Selection Details');
45630
46107
  html += me.htmlCls.setHtmlCls.getLink('mn1_exportCounts', 'Residue Counts');
45631
46108
 
45632
46109
  /*
@@ -45688,9 +46165,9 @@ class SetMenu {
45688
46165
 
45689
46166
  html += "<ul class='icn3d-mn-item'>";
45690
46167
 
45691
- html += me.htmlCls.setHtmlCls.getLink('mn2_definedsets', 'Defined Sets');
46168
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn2_definedsets', 'Defined Sets');
45692
46169
  html += me.htmlCls.setHtmlCls.getLink('mn2_selectall', 'All');
45693
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectdisplayed', 'Displayed Set');
46170
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn2_selectdisplayed', 'Displayed Set');
45694
46171
  html += me.htmlCls.setHtmlCls.getLink('mn2_aroundsphere', 'by Distance');
45695
46172
 
45696
46173
  html += "<li><span>by Property</span>";
@@ -45704,11 +46181,13 @@ class SetMenu {
45704
46181
  html += "</ul>";
45705
46182
  html += "</li>";
45706
46183
 
45707
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectcomplement', 'Inverse');
45708
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainchains', 'Main Chains');
45709
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectsidechains', 'Side Chains');
45710
- html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainsidechains', 'Main & Side Chains');
45711
- html += me.htmlCls.setHtmlCls.getLink('mn2_command', 'Advanced');
46184
+ if(!me.cfg.simplemenu) {
46185
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectcomplement', 'Inverse');
46186
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainchains', 'Main Chains');
46187
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectsidechains', 'Side Chains');
46188
+ html += me.htmlCls.setHtmlCls.getLink('mn2_selectmainsidechains', 'Main & Side Chains');
46189
+ html += me.htmlCls.setHtmlCls.getLink('mn2_command', 'Advanced');
46190
+ }
45712
46191
 
45713
46192
  if(me.cfg.cid === undefined) {
45714
46193
  html += "<li><span>Select on 3D</span>";
@@ -45745,22 +46224,24 @@ class SetMenu {
45745
46224
 
45746
46225
  html += "<li>-</li>";
45747
46226
 
45748
- html += "<li><span>Highlight Color</span>";
45749
- html += "<ul>";
45750
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrYellow', 'Yellow', true);
45751
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrGreen', 'Green');
45752
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrRed', 'Red');
45753
- html += "</ul>";
45754
- html += "</li>";
45755
- html += "<li><span>Highlight Style</span>";
45756
- html += "<ul>";
46227
+ if(!me.cfg.simplemenu) {
46228
+ html += "<li><span>Highlight Color</span>";
46229
+ html += "<ul>";
46230
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrYellow', 'Yellow', true);
46231
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrGreen', 'Green');
46232
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_clr', 'mn2_hl_clrRed', 'Red');
46233
+ html += "</ul>";
46234
+ html += "</li>";
46235
+ html += "<li><span>Highlight Style</span>";
46236
+ html += "<ul>";
45757
46237
 
45758
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleOutline', 'Outline', true);
45759
- html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleObject', '3D Objects');
45760
- //html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleNone', 'No Highlight');
46238
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleOutline', 'Outline', true);
46239
+ html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleObject', '3D Objects');
46240
+ //html += me.htmlCls.setHtmlCls.getRadio('mn2_hl_style', 'mn2_hl_styleNone', 'No Highlight');
45761
46241
 
45762
- html += "</ul>";
45763
- html += "</li>";
46242
+ html += "</ul>";
46243
+ html += "</li>";
46244
+ }
45764
46245
 
45765
46246
  //html += me.htmlCls.setHtmlCls.getLink('mn2_hl_styleNone', 'Clear Highlight');
45766
46247
 
@@ -45799,7 +46280,7 @@ class SetMenu {
45799
46280
  html += "<ul class='icn3d-mn-item'>";
45800
46281
 
45801
46282
  html += me.htmlCls.setHtmlCls.getLink('mn2_show_selected', 'View Selection');
45802
- html += me.htmlCls.setHtmlCls.getLink('mn2_hide_selected', 'Hide Selection');
46283
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn2_hide_selected', 'Hide Selection');
45803
46284
  html += me.htmlCls.setHtmlCls.getLink('mn2_selectedcenter', 'Zoom in Selection');
45804
46285
  html += me.htmlCls.setHtmlCls.getLink('mn6_center', 'Center Selection');
45805
46286
  html += me.htmlCls.setHtmlCls.getLink('mn2_fullstru', 'View Full Structure');
@@ -45877,8 +46358,10 @@ class SetMenu {
45877
46358
  html += "</ul>";
45878
46359
  html += "</li>";
45879
46360
 
45880
- html += me.htmlCls.setHtmlCls.getLink('mn6_back', 'Undo');
45881
- html += me.htmlCls.setHtmlCls.getLink('mn6_forward', 'Redo');
46361
+ if(!me.cfg.simplemenu) {
46362
+ html += me.htmlCls.setHtmlCls.getLink('mn6_back', 'Undo');
46363
+ html += me.htmlCls.setHtmlCls.getLink('mn6_forward', 'Redo');
46364
+ }
45882
46365
 
45883
46366
  html += me.htmlCls.setHtmlCls.getLink('mn6_fullscreen', 'Full Screen');
45884
46367
  // html += me.htmlCls.setHtmlCls.getLink('mn6_exitfullscreen', 'Exit Full Screen');
@@ -46026,21 +46509,22 @@ class SetMenu {
46026
46509
 
46027
46510
  html += me.htmlCls.setHtmlCls.getLink('mn3_setThickness', 'Preferences');
46028
46511
 
46029
- html += "<li>-</li>";
46030
-
46031
- html += me.htmlCls.setHtmlCls.getLink('mn3_styleSave', 'Save Style');
46032
- html += me.htmlCls.setHtmlCls.getLink('mn3_styleApplySave', 'Apply Saved Style');
46512
+ if(!me.cfg.simplemenu) {
46513
+ html += "<li>-</li>";
46514
+ html += me.htmlCls.setHtmlCls.getLink('mn3_styleSave', 'Save Style');
46515
+ html += me.htmlCls.setHtmlCls.getLink('mn3_styleApplySave', 'Apply Saved Style');
46516
+ }
46033
46517
 
46034
46518
  html += "<li>-</li>";
46035
46519
 
46036
46520
  html += "<li><span>Surface Type</span>";
46037
46521
  html += "<ul>";
46038
46522
  html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceVDW', 'Van der Waals');
46039
- html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceVDWContext', 'VDW with Context');
46523
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceVDWContext', 'VDW with Context');
46040
46524
  html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceMolecular', 'Molecular Surface');
46041
- html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceMolecularContext', 'MS with Context');
46525
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceMolecularContext', 'MS with Context');
46042
46526
  html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceSAS', 'Solvent Accessible');
46043
- html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceSASContext', 'SA with Context');
46527
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn5_surface', 'mn5_surfaceSASContext', 'SA with Context');
46044
46528
  html += "</ul>";
46045
46529
  html += "</li>";
46046
46530
 
@@ -46063,36 +46547,38 @@ class SetMenu {
46063
46547
  html += "</li>";
46064
46548
 
46065
46549
  if(me.cfg.cid === undefined && me.cfg.align === undefined && me.cfg.chainalign === undefined) {
46066
- html += "<li>-</li>";
46067
-
46068
- html += "<li id='" + me.pre + "mapWrapper1'><span>Electron Density</span>";
46069
- html += "<ul>";
46070
- html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmap2fofc', '2Fo-Fc Map');
46071
- html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmapfofc', 'Fo-Fc Map');
46072
- html += "</ul>";
46073
- html += "</li>";
46074
-
46075
- html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_elecmapNo', 'Remove Map', 'mapWrapper2');
46550
+ if(!me.cfg.simplemenu) {
46551
+ html += "<li>-</li>";
46076
46552
 
46077
- html += "<li id='" + me.pre + "mapWrapper3'><span>Map Wireframe</span>";
46078
- html += "<ul>";
46079
- html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeYes', 'Yes', true);
46080
- html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeNo', 'No');
46081
- html += "</ul>";
46082
- html += "</li>";
46083
-
46084
- if(me.cfg.mmtfid === undefined) {
46085
- //html += "<li>-</li>";
46553
+ html += "<li id='" + me.pre + "mapWrapper1'><span>Electron Density</span>";
46554
+ html += "<ul>";
46555
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmap2fofc', '2Fo-Fc Map');
46556
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_elecmap', 'mn5_elecmapfofc', 'Fo-Fc Map');
46557
+ html += "</ul>";
46558
+ html += "</li>";
46086
46559
 
46087
- html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmap', 'EM Density Map', 'emmapWrapper1');
46088
- html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmapNo', 'Remove EM Map', 'emmapWrapper2');
46560
+ html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_elecmapNo', 'Remove Map', 'mapWrapper2');
46089
46561
 
46090
- html += "<li id='" + me.pre + "emmapWrapper3'><span>EM Map Wireframe</span>";
46562
+ html += "<li id='" + me.pre + "mapWrapper3'><span>Map Wireframe</span>";
46091
46563
  html += "<ul>";
46092
- html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeYes', 'Yes', true);
46093
- html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeNo', 'No');
46564
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeYes', 'Yes', true);
46565
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_mapwireframe', 'mn5_mapwireframeNo', 'No');
46094
46566
  html += "</ul>";
46095
46567
  html += "</li>";
46568
+
46569
+ if(me.cfg.mmtfid === undefined) {
46570
+ //html += "<li>-</li>";
46571
+
46572
+ html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmap', 'EM Density Map', 'emmapWrapper1');
46573
+ html += me.htmlCls.setHtmlCls.getLinkWrapper('mn5_emmapNo', 'Remove EM Map', 'emmapWrapper2');
46574
+
46575
+ html += "<li id='" + me.pre + "emmapWrapper3'><span>EM Map Wireframe</span>";
46576
+ html += "<ul>";
46577
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeYes', 'Yes', true);
46578
+ html += me.htmlCls.setHtmlCls.getRadio('mn5_emmapwireframe', 'mn5_emmapwireframeNo', 'No');
46579
+ html += "</ul>";
46580
+ html += "</li>";
46581
+ }
46096
46582
  }
46097
46583
  }
46098
46584
 
@@ -46100,20 +46586,22 @@ class SetMenu {
46100
46586
 
46101
46587
  html += "<li><span>Background</span>";
46102
46588
  html += "<ul>";
46103
- html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdTransparent', 'Transparent', true);
46104
- html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdBlack', 'Black');
46589
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdTransparent', 'Transparent');
46590
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdBlack', 'Black', true);
46105
46591
  html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdGrey', 'Gray');
46106
46592
  html += me.htmlCls.setHtmlCls.getRadio('mn6_bkgd', 'mn6_bkgdWhite', 'White');
46107
46593
  html += "</ul>";
46108
46594
  html += "</li>";
46109
46595
 
46110
- html += "<li><span>Dialog Color</span>";
46111
- html += "<ul>";
46112
- html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlue', 'Blue', true);
46113
- html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeOrange', 'Orange');
46114
- html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlack', 'Black');
46115
- html += "</ul>";
46116
- html += "</li>";
46596
+ if(!me.cfg.simplemenu) {
46597
+ html += "<li><span>Dialog Color</span>";
46598
+ html += "<ul>";
46599
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlue', 'Blue', true);
46600
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeOrange', 'Orange');
46601
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_theme', 'mn6_themeBlack', 'Black');
46602
+ html += "</ul>";
46603
+ html += "</li>";
46604
+ }
46117
46605
 
46118
46606
  // html += "<li><span>Two-color Helix</span>";
46119
46607
  // html += "<ul>";
@@ -46357,8 +46845,10 @@ class SetMenu {
46357
46845
 
46358
46846
  html += "</ul>";
46359
46847
 
46360
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrCustom', 'Color Picker');
46361
- html += "<li>-</li>";
46848
+ if(!me.cfg.simplemenu) {
46849
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrCustom', 'Color Picker');
46850
+ html += "<li>-</li>";
46851
+ }
46362
46852
 
46363
46853
  if(me.cfg.cid === undefined) {
46364
46854
  //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrRainbow', 'Rainbow (R-V)');
@@ -46368,12 +46858,14 @@ class SetMenu {
46368
46858
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrRainbowChain', 'for Chains');
46369
46859
  html += "</ul>";
46370
46860
 
46371
- //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'Spectrum (V-R)');
46372
- html += "<li><span style='padding-left:1.5em;'>Spectrum (V-R)</span>";
46373
- html += "<ul>";
46374
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'for Selection');
46375
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrumChain', 'for Chains');
46376
- html += "</ul>";
46861
+ if(!me.cfg.simplemenu) {
46862
+ //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'Spectrum (V-R)');
46863
+ html += "<li><span style='padding-left:1.5em;'>Spectrum (V-R)</span>";
46864
+ html += "<ul>";
46865
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrum', 'for Selection');
46866
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrSpectrumChain', 'for Chains');
46867
+ html += "</ul>";
46868
+ }
46377
46869
 
46378
46870
  html += "<li><span style='padding-left:1.5em;'>Secondary</span>";
46379
46871
  html += "<ul>";
@@ -46402,7 +46894,7 @@ class SetMenu {
46402
46894
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrBfactorNorm', 'Percentile');
46403
46895
  html += "</ul>";
46404
46896
 
46405
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrArea', 'Solvent<br><span style="padding-left:1.5em;">Accessibility</span>');
46897
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrArea', 'Solvent<br><span style="padding-left:1.5em;">Accessibility</span>');
46406
46898
 
46407
46899
  if(me.cfg.align !== undefined || me.cfg.chainalign !== undefined || me.cfg.blast_rep_id !== undefined) {
46408
46900
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrChain', 'Chain');
@@ -46416,10 +46908,12 @@ class SetMenu {
46416
46908
  }
46417
46909
 
46418
46910
  if(me.cfg.cid === undefined) {
46419
- html += "<li><span style='padding-left:1.5em;'>Defined Sets</span>";
46420
- html += "<ul>";
46421
- html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrsets', 'Rainbow for Selected Sets<br>in "Analysis > Defined Sets"');
46422
- html += "</ul>";
46911
+ if(!me.cfg.simplemenu) {
46912
+ html += "<li><span style='padding-left:1.5em;'>Defined Sets</span>";
46913
+ html += "<ul>";
46914
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrsets', 'Rainbow for Selected Sets<br>in "Analysis > Defined Sets"');
46915
+ html += "</ul>";
46916
+ }
46423
46917
  }
46424
46918
 
46425
46919
  //html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrResidue', 'Residue');
@@ -46442,17 +46936,21 @@ class SetMenu {
46442
46936
  }
46443
46937
 
46444
46938
  //if(me.cfg.afid) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrConfidence', 'AF Confidence');
46445
- if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrConfidence', 'AlphaFold<br><span style="padding-left:1.5em;">Confidence</span>');
46939
+ if(!me.cfg.mmtfid && !me.cfg.pdbid && !me.cfg.opmid && !me.cfg.mmdbid && !me.cfg.gi && !me.cfg.uniprotid && !me.cfg.blast_rep_id && !me.cfg.cid && !me.cfg.mmcifid && !me.cfg.align && !me.cfg.chainalign) {
46940
+ html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrConfidence', 'AlphaFold<br><span style="padding-left:1.5em;">Confidence</span>');
46941
+ }
46446
46942
  }
46447
46943
  else {
46448
46944
  //if(!me.cfg.hidelicense) html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn1_delphi2', 'DelPhi<br><span style="padding-left:1.5em;">Potential ' + me.htmlCls.licenseStr + '</span>');
46449
46945
  html += me.htmlCls.setHtmlCls.getRadio('mn4_clr', 'mn4_clrAtom', 'Atom', true);
46450
46946
  }
46451
46947
 
46452
- html += "<li>-</li>";
46948
+ if(!me.cfg.simplemenu) {
46949
+ html += "<li>-</li>";
46453
46950
 
46454
- html += me.htmlCls.setHtmlCls.getLink('mn4_clrSave', 'Save Color');
46455
- html += me.htmlCls.setHtmlCls.getLink('mn4_clrApplySave', 'Apply Saved Color');
46951
+ html += me.htmlCls.setHtmlCls.getLink('mn4_clrSave', 'Save Color');
46952
+ html += me.htmlCls.setHtmlCls.getLink('mn4_clrApplySave', 'Apply Saved Color');
46953
+ }
46456
46954
 
46457
46955
  html += "<li><br/></li>";
46458
46956
  html += "</ul>";
@@ -46513,8 +47011,8 @@ class SetMenu {
46513
47011
  html += me.htmlCls.setHtmlCls.getLink('mn6_hbondsYes', 'Interactions');
46514
47012
  //html += me.htmlCls.setHtmlCls.getLink('mn6_hbondsNo', 'Remove H-Bonds <br>& Interactions');
46515
47013
 
46516
- html += me.htmlCls.setHtmlCls.getLink('mn6_contactmap', 'Contact Map');
46517
-
47014
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn6_contactmap', 'Contact Map');
47015
+ /*
46518
47016
  html += "<li><span>Bring to Front</span>";
46519
47017
  html += "<ul>";
46520
47018
  html += me.htmlCls.setHtmlCls.getLink('mn1_window_table', 'Interaction Table');
@@ -46523,22 +47021,26 @@ class SetMenu {
46523
47021
  html += me.htmlCls.setHtmlCls.getLink('mn1_window_graph', '2D Graph(Force-Directed)');
46524
47022
  html += "</ul>";
46525
47023
  html += "</li>";
47024
+ */
46526
47025
 
46527
47026
  if(!me.cfg.notebook) {
46528
47027
  html += me.htmlCls.setHtmlCls.getLink('mn1_mutation', 'Mutation ' + me.htmlCls.wifiStr);
46529
47028
  }
46530
47029
 
46531
- html += "<li>-</li>";
47030
+ if(!me.cfg.simplemenu) html += "<li>-</li>";
46532
47031
  }
46533
47032
 
46534
47033
  if(!me.cfg.notebook && !me.cfg.hidelicense) {
46535
47034
  html += me.htmlCls.setHtmlCls.getLink('mn1_delphi', 'DelPhi Potential ' + me.htmlCls.licenseStr);
46536
- html += "<li><span>Load PQR/Phi</span>";
46537
- html += "<ul>";
46538
- html += me.htmlCls.setHtmlCls.getLink('mn1_phi', 'Local PQR/Phi/Cube File');
46539
- html += me.htmlCls.setHtmlCls.getLink('mn1_phiurl', 'URL PQR/Phi/Cube File');
46540
- html += "</ul>";
46541
- html += me.htmlCls.setHtmlCls.getLink('delphipqr', 'Download PQR');
47035
+
47036
+ if(!me.cfg.simplemenu) {
47037
+ html += "<li><span>Load PQR/Phi</span>";
47038
+ html += "<ul>";
47039
+ html += me.htmlCls.setHtmlCls.getLink('mn1_phi', 'Local PQR/Phi/Cube File');
47040
+ html += me.htmlCls.setHtmlCls.getLink('mn1_phiurl', 'URL PQR/Phi/Cube File');
47041
+ html += "</ul>";
47042
+ html += me.htmlCls.setHtmlCls.getLink('delphipqr', 'Download PQR');
47043
+ }
46542
47044
 
46543
47045
  html += "<li>-</li>";
46544
47046
  }
@@ -46566,6 +47068,8 @@ class SetMenu {
46566
47068
  html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_addlabelTermini', 'N- & C-Termini');
46567
47069
  }
46568
47070
 
47071
+ html += "<li>-</li>";
47072
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_labelColor', 'Change Label Color', true);
46569
47073
  html += me.htmlCls.setHtmlCls.getRadio('mn6_addlabel', 'mn6_addlabelNo', 'Remove', true);
46570
47074
  html += "</ul>";
46571
47075
  html += "</li>";
@@ -46593,12 +47097,14 @@ class SetMenu {
46593
47097
  html += "<li>-</li>";
46594
47098
 
46595
47099
  if(me.cfg.cid === undefined) {
46596
- html += "<li><span>Chem. Binding</span>";
46597
- html += "<ul>";
46598
- html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindingshow', 'Show');
46599
- html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindinghide', 'Hide', true);
46600
- html += "</ul>";
46601
- html += "</li>";
47100
+ if(!me.cfg.simplemenu) {
47101
+ html += "<li><span>Chem. Binding</span>";
47102
+ html += "<ul>";
47103
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindingshow', 'Show');
47104
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_chemicalbinding', 'mn6_chemicalbindinghide', 'Hide', true);
47105
+ html += "</ul>";
47106
+ html += "</li>";
47107
+ }
46602
47108
 
46603
47109
  html += "<li><span>Disulfide Bonds</span>";
46604
47110
  html += "<ul>";
@@ -46608,15 +47114,19 @@ class SetMenu {
46608
47114
  html += "</ul>";
46609
47115
  html += "</li>";
46610
47116
 
46611
- html += "<li><span>Cross-Linkages</span>";
46612
- html += "<ul>";
46613
- html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsYes', 'Show', true);
46614
- html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsExport', 'Export Pairs');
46615
- html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsNo', 'Hide');
46616
- html += "</ul>";
46617
- html += "</li>";
47117
+ if(!me.cfg.simplemenu) {
47118
+ html += "<li><span>Cross-Linkages</span>";
47119
+ html += "<ul>";
47120
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsYes', 'Show', true);
47121
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsExport', 'Export Pairs');
47122
+ html += me.htmlCls.setHtmlCls.getRadio('mn6_clbonds', 'mn6_clbondsNo', 'Hide');
47123
+ html += "</ul>";
47124
+ html += "</li>";
47125
+ }
46618
47126
 
46619
47127
  let bOnePdb = me.cfg.mmtfid !== undefined || me.cfg.pdbid !== undefined || me.cfg.opmid !== undefined || me.cfg.mmcifid !== undefined || me.cfg.mmdbid !== undefined || me.cfg.gi !== undefined || me.cfg.blast_rep_id !== undefined;
47128
+ console.log("me.cfg.mmdbid: " + me.cfg.mmdbid + " bOnePdb: " + bOnePdb);
47129
+
46620
47130
  if(bOnePdb) {
46621
47131
  html += "<li id='" + me.pre + "assemblyWrapper'><span>Assembly</span>";
46622
47132
  html += "<ul>";
@@ -46632,16 +47142,18 @@ class SetMenu {
46632
47142
  html += "<li><span>Symmetry</span>";
46633
47143
  html += "<ul>";
46634
47144
  if(bOnePdb) html += me.htmlCls.setHtmlCls.getLink('mn6_symmetry', 'from PDB(precalculated) ' + me.htmlCls.wifiStr);
46635
- html += me.htmlCls.setHtmlCls.getLink('mn6_symd', 'from SymD(Dynamic) ' + me.htmlCls.wifiStr);
46636
- html += me.htmlCls.setHtmlCls.getLink('mn6_clear_sym', 'Clear SymD Symmetry');
46637
- html += me.htmlCls.setHtmlCls.getLink('mn6_axes_only', 'Show Axes Only');
47145
+ if(!me.cfg.simplemenu) {
47146
+ html += me.htmlCls.setHtmlCls.getLink('mn6_symd', 'from SymD(Dynamic) ' + me.htmlCls.wifiStr);
47147
+ html += me.htmlCls.setHtmlCls.getLink('mn6_clear_sym', 'Clear SymD Symmetry');
47148
+ html += me.htmlCls.setHtmlCls.getLink('mn6_axes_only', 'Show Axes Only');
47149
+ }
46638
47150
  html += "</ul>";
46639
47151
  html += "</li>";
46640
47152
 
46641
47153
  html += "<li>-</li>";
46642
47154
  }
46643
47155
 
46644
- html += me.htmlCls.setHtmlCls.getLink('mn6_yournote', 'Window Title');
47156
+ if(!me.cfg.simplemenu) html += me.htmlCls.setHtmlCls.getLink('mn6_yournote', 'Window Title');
46645
47157
 
46646
47158
  if(me.cfg.cid !== undefined) {
46647
47159
  html += "<li><span>Links</span>";
@@ -46725,16 +47237,18 @@ class SetMenu {
46725
47237
  html += "</ul>";
46726
47238
  html += "</li>";
46727
47239
 
46728
- html += "<li><span>Develop</span>";
46729
- html += "<ul>";
46730
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUse' target='_blank'>How to Embed</a></li>";
46731
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#datastructure' target='_blank'>Data Structure</a></li>";
46732
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#classstructure' target='_blank'>Class Structure</a></li>";
46733
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#addclass' target='_blank'>Add New Classes</a></li>";
46734
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#modifyfunction' target='_blank'>Modify Functions</a></li>";
46735
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#restfulapi' target='_blank'>RESTful APIs</a></li>";
46736
- html += "</ul>";
46737
- html += "</li>";
47240
+ if(!me.cfg.simplemenu) {
47241
+ html += "<li><span>Develop</span>";
47242
+ html += "<ul>";
47243
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUse' target='_blank'>How to Embed</a></li>";
47244
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#datastructure' target='_blank'>Data Structure</a></li>";
47245
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#classstructure' target='_blank'>Class Structure</a></li>";
47246
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#addclass' target='_blank'>Add New Classes</a></li>";
47247
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#modifyfunction' target='_blank'>Modify Functions</a></li>";
47248
+ html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#restfulapi' target='_blank'>RESTful APIs</a></li>";
47249
+ html += "</ul>";
47250
+ html += "</li>";
47251
+ }
46738
47252
 
46739
47253
  html += liStr + me.htmlCls.baseUrl + "icn3d/docs/icn3d_help.html' target='_blank'>Help Doc " + me.htmlCls.wifiStr + "</a></li>";
46740
47254
 
@@ -46744,7 +47258,7 @@ class SetMenu {
46744
47258
  html += "<ul>";
46745
47259
  html += "<li><span>Rotate</span>";
46746
47260
  html += "<ul>";
46747
- html += "<li>Left Mouse</li>";
47261
+ html += "<li>Left Mouse (Click & Drag)</li>";
46748
47262
  html += "<li>Key l: Left</li>";
46749
47263
  html += "<li>Key j: Right</li>";
46750
47264
  html += "<li>Key i: Up</li>";
@@ -46757,20 +47271,20 @@ class SetMenu {
46757
47271
  html += "</li>";
46758
47272
  html += "<li><span>Zoom</span>";
46759
47273
  html += "<ul>";
46760
- html += "<li>Middle Mouse</li>";
47274
+ html += "<li>Middle Mouse <br>(Pinch & Spread)</li>";
46761
47275
  html += "<li>Key z: Zoom in</li>";
46762
47276
  html += "<li>Key x: Zoom out</li>";
46763
47277
  html += "</ul>";
46764
47278
  html += "</li>";
46765
47279
  html += "<li><span>Translate</span>";
46766
47280
  html += "<ul>";
46767
- html += "<li>Right Mouse</li>";
47281
+ html += "<li>Right Mouse <br>(Two Finger Click & Drag)</li>";
46768
47282
  html += "</ul>";
46769
47283
  html += "</li>";
46770
47284
  html += "</ul>";
46771
47285
  html += "</li>";
46772
47286
 
46773
- html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUseStep5' target='_blank'>Selection Hints</a></li>";
47287
+ if(!me.cfg.simplemenu) html += liStr + me.htmlCls.baseUrl + "icn3d/icn3d.html#HowToUseStep5' target='_blank'>Selection Hints</a></li>";
46774
47288
 
46775
47289
  html += "<li><br/></li>";
46776
47290
  html += "</ul>";
@@ -47371,6 +47885,8 @@ class SetDialog {
47371
47885
 
47372
47886
  let html = "";
47373
47887
 
47888
+ let defaultColor = "#ffff00"; //ic.colorBlackbkgd;
47889
+
47374
47890
  me.htmlCls.optionStr = "<option value=";
47375
47891
 
47376
47892
  html += "<!-- dialog will not be part of the form -->";
@@ -47526,7 +48042,7 @@ class SetDialog {
47526
48042
  html += "<b>Optional 1</b>, full chains are used for structure alignment<br/><br/>";
47527
48043
  html += "<b>Optional 2</b>, sequence alignment (followed by structure alignemnt) based on residue numbers in the First/Master chain: <br>" + me.htmlCls.inputTextStr + "id='" + me.pre + "resalignids' placeholder='1,5,10-50' size=50><br/><br/>";
47528
48044
  html += "<b>Optional 3</b>, predefined alignment with residue numbers in each chain specified (one chain per line): <br><textarea id='" + me.pre + "predefinedres' rows='5' style='width: 100%; height: " +(me.htmlCls.LOG_HEIGHT) + "px; padding: 0px; border: 0px;' placeholder='1,5,10-50\n1,5,10-50\n1,5,10-50'></textarea><br/><br/>";
47529
- html += me.htmlCls.buttonStr + "reload_chainalign'>Align Biological Unit</button>" + me.htmlCls.buttonStr + "reload_chainalign_asym' style='margin-left:30px'>Align Asymmetric Unit</button><br/><br/>";
48045
+ html += me.htmlCls.buttonStr + "reload_chainalign_asym'>Align Asymmetric Unit</button>" + me.htmlCls.buttonStr + "reload_chainalign' style='margin-left:30px'>Align Biological Unit</button><br/><br/>";
47530
48046
  html += "(Note: To align chains in custom PDB files, you could concatenate PDB files in a single PDB file with the separation line \"ENDMDL\". Then load it in \"Open File > PDB File\" in the \"File\" menu and click \"View Sequences & Annotations\" in the \"Window\" menu. Finally select multiple chains in the sequence window and click \"Realign Selection\" in the \"File\" menu.)<br><br>";
47531
48047
  html += "</div></div>";
47532
48048
 
@@ -47575,16 +48091,18 @@ class SetDialog {
47575
48091
  html += "</div>";
47576
48092
 
47577
48093
  html += me.htmlCls.divStr + "dl_mmdbid' class='" + dialogClass + "'>";
47578
- html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> ";
47579
- html += me.htmlCls.buttonStr + "reload_mmdb'>Load</button>";
48094
+ html += "MMDB or PDB ID: " + me.htmlCls.inputTextStr + "id='" + me.pre + "mmdbid' value='1TUP' size=8> <br><br>";
48095
+ html += me.htmlCls.buttonStr + "reload_mmdb_asym'>Load Asymmetric Unit (All Chains)</button>" + me.htmlCls.buttonStr + "reload_mmdb' style='margin-left:30px'>Load Biological Unit</button><br/><br/>";
47580
48096
  html += "</div>";
47581
48097
 
47582
48098
  html += me.htmlCls.divStr + "dl_blast_rep_id' style='max-width:500px;' class='" + dialogClass + "'>";
47583
- html += "Enter a Sequence ID(or FASTA sequence) and the aligned Structure ID, which can be found using the <a href='https://blast.ncbi.nlm.nih.gov/Blast.cgi?PROGRAM=blastp&PAGE_TYPE=BlastSearch&DATABASE=pdb' target='_blank'>BLAST</a> search against the pdb database with the Sequence ID or FASTA sequence as input.<br><br> ";
48099
+ html += "Enter a Sequence ID (or FASTA sequence) and the aligned Structure ID, which can be found using the <a href='https://blast.ncbi.nlm.nih.gov/Blast.cgi?PROGRAM=blastp&PAGE_TYPE=BlastSearch&DATABASE=pdb' target='_blank'>BLAST</a> search against the pdb database with the Sequence ID or FASTA sequence as input.<br><br> ";
47584
48100
  html += "<b>Sequence ID</b>(NCBI protein accession of a sequence): " + me.htmlCls.inputTextStr + "id='" + me.pre + "query_id' value='NP_001108451.1' size=8><br> ";
47585
48101
  html += "or FASTA sequence: <br><textarea id='" + me.pre + "query_fasta' rows='5' style='width: 100%; height: " +(me.htmlCls.LOG_HEIGHT) + "px; padding: 0px; border: 0px;'></textarea><br><br>";
47586
48102
  html += "<b>Structure ID</b>(NCBI protein accession of a chain of a 3D structure): " + me.htmlCls.inputTextStr + "id='" + me.pre + "blast_rep_id' value='1TSR_A' size=8><br> ";
47587
- html += me.htmlCls.buttonStr + "reload_blast_rep_id'>Load</button>";
48103
+ //html += me.htmlCls.buttonStr + "reload_blast_rep_id'>Load</button>";
48104
+ html += me.htmlCls.buttonStr + "reload_blast_rep_id'>Align with BLAST</button> " + me.htmlCls.wifiStr
48105
+ + me.htmlCls.buttonStr + "reload_alignsw' style='margin-left:30px'>Align with Smith-Waterman</button>";
47588
48106
  html += "</div>";
47589
48107
 
47590
48108
  html += me.htmlCls.divStr + "dl_yournote' class='" + dialogClass + "'>";
@@ -47965,23 +48483,28 @@ class SetDialog {
47965
48483
  html += me.htmlCls.divStr + "dl_addlabel' class='" + dialogClass + "'>";
47966
48484
  html += "1. Text: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labeltext' value='Text' size=4><br/>";
47967
48485
  html += "2. Size: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelsize' value='18' size=4 maxlength=2><br/>";
47968
- html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor' value='ffff00' size=4><br/>";
47969
- html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd' value='cccccc' size=4><br/>";
48486
+ html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor' value='" + defaultColor + "' size=4><br/>";
48487
+ //html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd' value='' size=4><br/>";
47970
48488
  if(me.utilsCls.isMobile()) {
47971
- html += me.htmlCls.spanNowrapStr + "5. Touch TWO atoms</span><br/>";
48489
+ html += me.htmlCls.spanNowrapStr + "4. Touch TWO atoms</span><br/>";
47972
48490
  }
47973
48491
  else {
47974
- html += me.htmlCls.spanNowrapStr + "5. Pick TWO atoms while holding \"Alt\" key</span><br/>";
48492
+ html += me.htmlCls.spanNowrapStr + "4. Pick TWO atoms while holding \"Alt\" key</span><br/>";
47975
48493
  }
47976
- html += me.htmlCls.spanNowrapStr + "6. " + me.htmlCls.buttonStr + "applypick_labels'>Display</button></span>";
48494
+ html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applypick_labels'>Display</button></span>";
47977
48495
  html += "</div>";
47978
48496
 
47979
48497
  html += me.htmlCls.divStr + "dl_addlabelselection' class='" + dialogClass + "'>";
47980
48498
  html += "1. Text: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labeltext2' value='Text' size=4><br/>";
47981
48499
  html += "2. Size: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelsize2' value='18' size=4 maxlength=2><br/>";
47982
- html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor2' value='ffff00' size=4><br/>";
47983
- html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd2' value='cccccc' size=4><br/>";
47984
- html += me.htmlCls.spanNowrapStr + "5. " + me.htmlCls.buttonStr + "applyselection_labels'>Display</button></span>";
48500
+ html += "3. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolor2' value='" + defaultColor + "' size=4><br/>";
48501
+ //html += "4. Background: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelbkgd2' value='' size=4><br/>";
48502
+ html += me.htmlCls.spanNowrapStr + "4. " + me.htmlCls.buttonStr + "applyselection_labels'>Display</button></span>";
48503
+ html += "</div>";
48504
+
48505
+ html += me.htmlCls.divStr + "dl_labelColor' class='" + dialogClass + "'>";
48506
+ html += "Color for all labels: " + me.htmlCls.inputTextStr + "id='" + me.pre + "labelcolorall' value='" + defaultColor + "' size=4><br/><br/>";
48507
+ html += me.htmlCls.spanNowrapStr + me.htmlCls.buttonStr + "applylabelcolor'>Display</button></span>";
47985
48508
  html += "</div>";
47986
48509
 
47987
48510
  html += me.htmlCls.divStr + "dl_distance' class='" + dialogClass + "'>";
@@ -47991,7 +48514,7 @@ class SetDialog {
47991
48514
  else {
47992
48515
  html += me.htmlCls.spanNowrapStr + "1. Pick TWO atoms while holding \"Alt\" key</span><br/>";
47993
48516
  }
47994
- html += me.htmlCls.spanNowrapStr + "2. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor' value='ffff00' size=4><br/>";
48517
+ html += me.htmlCls.spanNowrapStr + "2. Line Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor' value='" + defaultColor + "' size=4><br/>";
47995
48518
  html += me.htmlCls.spanNowrapStr + "3. " + me.htmlCls.buttonStr + "applypick_measuredistance'>Display</button></span>";
47996
48519
  html += "</div>";
47997
48520
 
@@ -48022,7 +48545,7 @@ class SetDialog {
48022
48545
 
48023
48546
  html += "</td></tr></table>";
48024
48547
 
48025
- html += me.htmlCls.spanNowrapStr + "2. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor2' value='ffff00' size=4><br/><br/>";
48548
+ html += me.htmlCls.spanNowrapStr + "2. Color: " + me.htmlCls.inputTextStr + "id='" + me.pre + "distancecolor2' value='" + defaultColor + "' size=4><br/><br/>";
48026
48549
  html += me.htmlCls.spanNowrapStr + "3. " + me.htmlCls.buttonStr + "applydist2'>Display</button></span>";
48027
48550
  html += "</div>";
48028
48551
 
@@ -48799,20 +49322,24 @@ class Events {
48799
49322
  me.myEventCls.onIds("#" + me.pre + "reload_mmdb", "click", function(e) { me.icn3d;
48800
49323
  e.preventDefault();
48801
49324
  if(!me.cfg.notebook) dialog.dialog( "close" );
48802
- me.htmlCls.clickMenuCls.setLogCmd("load mmdb " + $("#" + me.pre + "mmdbid").val(), false);
48803
- //ic.mmdbParserCls.downloadMmdb($("#" + me.pre + "mmdbid").val());
48804
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
48805
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
49325
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb1 " + $("#" + me.pre + "mmdbid").val(), false);
49326
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=1', '_blank');
48806
49327
  });
48807
49328
 
49329
+ me.myEventCls.onIds("#" + me.pre + "reload_mmdb_asym", "click", function(e) { me.icn3d;
49330
+ e.preventDefault();
49331
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49332
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49333
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49334
+ });
49335
+
48808
49336
  me.myEventCls.onIds("#" + me.pre + "mmdbid", "keyup", function(e) { me.icn3d;
48809
49337
  if (e.keyCode === 13) {
48810
49338
  e.preventDefault();
48811
49339
  if(!me.cfg.notebook) dialog.dialog( "close" );
48812
- me.htmlCls.clickMenuCls.setLogCmd("load mmdb " + $("#" + me.pre + "mmdbid").val(), false);
48813
- //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
48814
- window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val(), '_blank');
48815
- }
49340
+ me.htmlCls.clickMenuCls.setLogCmd("load mmdb0 " + $("#" + me.pre + "mmdbid").val(), false);
49341
+ window.open(hostUrl + '?mmdbid=' + $("#" + me.pre + "mmdbid").val() + '&buidx=0', '_blank');
49342
+ }
48816
49343
  });
48817
49344
 
48818
49345
  // },
@@ -48826,12 +49353,27 @@ class Events {
48826
49353
  me.htmlCls.clickMenuCls.setLogCmd("load seq_struct_ids " + query_id + "," + blast_rep_id, false);
48827
49354
  query_id =(query_id !== '' && query_id !== undefined) ? query_id : query_fasta;
48828
49355
  //window.open(me.htmlCls.baseUrl + 'icn3d/full.html?from=icn3d&blast_rep_id=' + blast_rep_id
48829
- window.open(hostUrl + '?from=icn3d&blast_rep_id=' + blast_rep_id
49356
+ window.open(hostUrl + '?from=icn3d&alg=blast&blast_rep_id=' + blast_rep_id
48830
49357
  + '&query_id=' + query_id
48831
49358
  + '&command=view annotations; set annotation cdd; set annotation site; set view detailed view; select chain '
48832
49359
  + blast_rep_id + '; show selection', '_blank');
48833
49360
  });
48834
49361
 
49362
+ me.myEventCls.onIds("#" + me.pre + "reload_alignsw", "click", function(e) { me.icn3d;
49363
+ e.preventDefault();
49364
+ if(!me.cfg.notebook) dialog.dialog( "close" );
49365
+ let query_id = $("#" + me.pre + "query_id").val();
49366
+ let query_fasta = encodeURIComponent($("#" + me.pre + "query_fasta").val());
49367
+ let blast_rep_id = $("#" + me.pre + "blast_rep_id").val();
49368
+ me.htmlCls.clickMenuCls.setLogCmd("load seq_struct_ids_smithwm " + query_id + "," + blast_rep_id, false);
49369
+ query_id =(query_id !== '' && query_id !== undefined) ? query_id : query_fasta;
49370
+
49371
+ window.open(hostUrl + '?from=icn3d&alg=smithwm&blast_rep_id=' + blast_rep_id
49372
+ + '&query_id=' + query_id
49373
+ + '&command=view annotations; set annotation cdd; set annotation site; set view detailed view; select chain '
49374
+ + blast_rep_id + '; show selection', '_blank');
49375
+ });
49376
+
48835
49377
  // },
48836
49378
  // clickReload_gi: function() {
48837
49379
  me.myEventCls.onIds("#" + me.pre + "reload_gi", "click", function(e) { me.icn3d;
@@ -49070,11 +49612,11 @@ class Events {
49070
49612
  thisClass.loadPdbFile(bAppend);
49071
49613
  });
49072
49614
 
49073
- me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", function(e) { me.icn3d;
49615
+ me.myEventCls.onIds("#" + me.pre + "reload_pdbfile_app", "click", function(e) { let ic = me.icn3d;
49074
49616
  e.preventDefault();
49075
49617
 
49076
- var bAppend = true;
49077
- thisClass.loadPdbFile(bAppend);
49618
+ ic.bAppend = true;
49619
+ thisClass.loadPdbFile(ic.bAppend);
49078
49620
  });
49079
49621
 
49080
49622
  // },
@@ -49658,6 +50200,15 @@ class Events {
49658
50200
  me.htmlCls.clickMenuCls.setLogCmd('add label ' + text + ' | x ' + x.toPrecision(4) + ' y ' + y.toPrecision(4) + ' z ' + z.toPrecision(4) + sizeStr + colorStr + backgroundStr + ' | type custom', true);
49659
50201
  ic.drawCls.draw();
49660
50202
  });
50203
+
50204
+ me.myEventCls.onIds("#" + me.pre + "applylabelcolor", "click", function(e) { let ic = me.icn3d;
50205
+ e.preventDefault();
50206
+ if(!me.cfg.notebook) dialog.dialog( "close" );
50207
+ ic.labelcolor = $("#" + me.pre + "labelcolorall" ).val();
50208
+
50209
+ me.htmlCls.clickMenuCls.setLogCmd('set label color ' + ic.labelcolor, true);
50210
+ ic.drawCls.draw();
50211
+ });
49661
50212
  // },
49662
50213
  // clickApplypick_stabilizer: function() {
49663
50214
  me.myEventCls.onIds("#" + me.pre + "applypick_stabilizer", "click", function(e) { let ic = me.icn3d;
@@ -50517,6 +51068,7 @@ class SetHtml {
50517
51068
  let light2 = 0.4;
50518
51069
  let light3 = 0.2;
50519
51070
  let bGlycansCartoon = 0;
51071
+ let bMembrane = 1;
50520
51072
 
50521
51073
  // retrieve from cache
50522
51074
  if(type == 'style') {
@@ -50545,6 +51097,10 @@ class SetHtml {
50545
51097
  bGlycansCartoon = parseFloat(this.getCookie('glycan'));
50546
51098
  }
50547
51099
 
51100
+ if(this.getCookie('membrane') != '') {
51101
+ bMembrane = parseFloat(this.getCookie('membrane'));
51102
+ }
51103
+
50548
51104
  html += "<b>Note</b>: The following parameters will be saved in cache. You just need to set them once. <br><br>";
50549
51105
 
50550
51106
  html += "<b>1. Shininess</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "shininess' value='" + shininess + "' size=4>" + me.htmlCls.space3 + "(for the shininess of the 3D objects, default 40)<br/><br/>";
@@ -50567,7 +51123,9 @@ class SetHtml {
50567
51123
  html += "<b>Ball Scale</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "ballscale_" + type + "' value='" + ballscale + "' size=4>" + me.htmlCls.space3 + "(for styles 'Ball and Stick' and 'Dot', default 0.3)<br/>";
50568
51124
 
50569
51125
  if(type == 'style') {
50570
- html += "<br><b>4. Show Glycan Cartoon</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "glycan' value='" + bGlycansCartoon + "' size=4>" + me.htmlCls.space3 + "(0: hide, 1: show, default 0)<br/><br/>";
51126
+ html += "<br><b>4. Show Glycan Cartoon</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "glycan' value='" + bGlycansCartoon + "' size=4>" + me.htmlCls.space3 + "(0: hide, 1: show, default 0)<br/>";
51127
+
51128
+ html += "<br><b>5. Show Membrane</b>: " + me.htmlCls.inputTextStr + "id='" + me.pre + "membrane' value='" + bMembrane + "' size=4>" + me.htmlCls.space3 + "(0: hide, 1: show, default 1)<br/><br/>";
50571
51129
  }
50572
51130
 
50573
51131
  html += me.htmlCls.spanNowrapStr + "" + me.htmlCls.buttonStr + "apply_thickness_" + type + "'>Apply</button></span>&nbsp;&nbsp;&nbsp;";
@@ -50760,8 +51318,8 @@ class SetHtml {
50760
51318
 
50761
51319
  html += "<span style='white-space:nowrap;font-weight:bold;'>Potential contour at: <select id='" + me.pre + name1 + "contour'>";
50762
51320
 
50763
- let optArray1b = ['0.5', '1', '2', '4', '6', '8', '10'];
50764
- html += this.getOptionHtml(optArray1b, 1);
51321
+ let optArray1b = ['0.5', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
51322
+ html += this.getOptionHtml(optArray1b, 2);
50765
51323
 
50766
51324
  html += "</select> kT/e(25.6mV at 298K)</span><br/><br/>";
50767
51325
 
@@ -50825,7 +51383,7 @@ class SetHtml {
50825
51383
 
50826
51384
  html += "<span style='white-space:nowrap;font-weight:bold;'>Surface with max potential at: <select id='" + me.pre + name1 + "contour2'>";
50827
51385
 
50828
- let optArray1c = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
51386
+ let optArray1c = ['0.5', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
50829
51387
  html += this.getOptionHtml(optArray1c, 2);
50830
51388
 
50831
51389
  html += "</select> kT/e(25.6mV at 298K)</span><br/><br/>";
@@ -51038,7 +51596,7 @@ class SetHtml {
51038
51596
  });
51039
51597
  }
51040
51598
 
51041
- loadPng(imageStr) { let me = this.icn3dui, ic = me.icn3d;
51599
+ loadPng(imageStr, command) { let me = this.icn3dui, ic = me.icn3d;
51042
51600
  let matchedStr = 'Share Link: ';
51043
51601
  let pos = imageStr.indexOf(matchedStr);
51044
51602
  let matchedStrState = "Start of state file======\n";
@@ -51055,6 +51613,8 @@ class SetHtml {
51055
51613
  let matchedStrData = "Start of data file======\n";
51056
51614
  let posData = imageStr.indexOf(matchedStrData);
51057
51615
  ic.bInputfile =(posData == -1) ? false : true;
51616
+ let commandStr = (command) ? command.replace(/;/g, "\n") : '';
51617
+
51058
51618
  if(ic.bInputfile) {
51059
51619
  let posDataEnd = imageStr.indexOf("End of data file======\n");
51060
51620
  let data = imageStr.substr(posData + matchedStrData.length, posDataEnd - posData - matchedStrData.length);
@@ -51070,7 +51630,9 @@ class SetHtml {
51070
51630
  //var posState = imageStr.indexOf(matchedStrState);
51071
51631
  let posStateEnd = imageStr.indexOf("End of state file======\n");
51072
51632
  let statefile = imageStr.substr(posState + matchedStrState.length, posStateEnd - posState- matchedStrState.length);
51073
- statefile = decodeURIComponent(statefile);
51633
+ //statefile = decodeURIComponent(statefile);
51634
+ statefile = decodeURIComponent(statefile + "\n" + commandStr);
51635
+
51074
51636
  if(type === 'pdb') {
51075
51637
  $.when( ic.pdbParserCls.loadPdbData(data))
51076
51638
  .then(function() {
@@ -51102,7 +51664,9 @@ class SetHtml {
51102
51664
  //var posState = imageStr.indexOf(matchedStrState);
51103
51665
  let posStateEnd = imageStr.indexOf("End of state file======\n");
51104
51666
  let statefile = imageStr.substr(posState + matchedStrState.length, posStateEnd - posState- matchedStrState.length);
51105
- statefile = decodeURIComponent(statefile);
51667
+ //statefile = decodeURIComponent(statefile);
51668
+ statefile = decodeURIComponent(statefile + "\n" + commandStr);
51669
+
51106
51670
  ic.commands = [];
51107
51671
  ic.optsHistory = [];
51108
51672
  ic.loadScriptCls.loadScript(statefile, true);
@@ -51165,6 +51729,7 @@ class SetHtml {
51165
51729
  $("#" + me.pre + "light2").val('0.4');
51166
51730
  $("#" + me.pre + "light3").val('0.2');
51167
51731
  $("#" + me.pre + "glycan").val('0');
51732
+ $("#" + me.pre + "membrane").val('1');
51168
51733
  }
51169
51734
 
51170
51735
  ic.shininess = parseFloat($("#" + me.pre + "shininess").val()); //40;
@@ -51172,6 +51737,7 @@ class SetHtml {
51172
51737
  ic.light2 = parseFloat($("#" + me.pre + "light2").val()); //0.4;
51173
51738
  ic.light3 = parseFloat($("#" + me.pre + "light3").val()); //0.2;
51174
51739
  ic.bGlycansCartoon = parseInt($("#" + me.pre + "glycan").val()); //0;
51740
+ ic.bMembrane = parseInt($("#" + me.pre + "membrane").val()); //1;
51175
51741
  }
51176
51742
 
51177
51743
  if(bReset) {
@@ -51202,6 +51768,7 @@ class SetHtml {
51202
51768
  this.setCookie('light2', ic.light2, exdays);
51203
51769
  this.setCookie('light3', ic.light3, exdays);
51204
51770
  this.setCookie('glycan', ic.bGlycansCartoon, exdays);
51771
+ this.setCookie('membrane', ic.bMembrane, exdays);
51205
51772
  }
51206
51773
 
51207
51774
  this.setCookieForThickness();
@@ -51214,6 +51781,9 @@ class SetHtml {
51214
51781
  }
51215
51782
  else {
51216
51783
  me.htmlCls.clickMenuCls.setLogCmd('set thickness | linerad ' + ic.lineRadius + ' | coilrad ' + ic.coilWidth + ' | stickrad ' + ic.cylinderRadius + ' | tracerad ' + ic.traceRadius + ' | ribbonthick ' + ic.ribbonthickness + ' | proteinwidth ' + ic.helixSheetWidth + ' | nucleotidewidth ' + ic.nucleicAcidWidth + ' | ballscale ' + ic.dotSphereScale, true);
51784
+
51785
+ me.htmlCls.clickMenuCls.setLogCmd('set glycan ' + ic.bGlycansCartoon, true);
51786
+ me.htmlCls.clickMenuCls.setLogCmd('set membrane ' + ic.bMembrane, true);
51217
51787
  }
51218
51788
 
51219
51789
  ic.drawCls.draw();
@@ -51263,7 +51833,7 @@ class Html {
51263
51833
  this.cfg = this.icn3dui.cfg;
51264
51834
 
51265
51835
  this.opts = {};
51266
- this.opts['background'] = 'transparent'; //transparent, black, grey, white
51836
+ this.opts['background'] = 'black'; //transparent, black, grey, white
51267
51837
 
51268
51838
  this.WIDTH = 400; // total width of view area
51269
51839
  this.HEIGHT = 400; // total height of view area
@@ -53019,6 +53589,398 @@ class DensityCifParser {
53019
53589
  }
53020
53590
  }
53021
53591
 
53592
+ /**
53593
+ * @author Jack Lin, modified from https://github.com/lh3/bioseq-js/blob/master/bioseq.js
53594
+ */
53595
+
53596
+ //import { HashUtilsCls } from '../../utils/hashUtilsCls.js';
53597
+
53598
+ //import { Html } from '../../html/html.js';
53599
+
53600
+ //import { SaveFile } from '../export/saveFile.js';
53601
+ //import { PdbParser } from '../parsers/pdbParser.js';
53602
+
53603
+ class AlignSW {
53604
+ constructor(icn3d) {
53605
+ this.icn3d = icn3d;
53606
+ }
53607
+
53608
+ alignSW(target, query, match_score, mismatch, gap, extension, is_local = false) { let ic = this.icn3d; ic.icn3dui;
53609
+ //let time_start = new Date().getTime();
53610
+
53611
+ let rst = this.bsa_align(is_local, target, query, [match_score, mismatch], [gap, extension]);
53612
+ let str = 'score: ' + rst[0] + '\n';
53613
+ str += 'start: ' + rst[1] + '\n';
53614
+ str += 'cigar: ' + this.bsa_cigar2str(rst[2]) + '\n\n';
53615
+ str += 'alignment:\n\n';
53616
+ let fmt = this.bsa_cigar2gaps(target, query, rst[1], rst[2]);
53617
+
53618
+ /*
53619
+ //let anno_seq = document.getElementById("div0_dl_annotations")
53620
+ let algn = "<div id=waterman_alignment><span>" + 'score: ' + rst[0] + '<br>' + 'start: ' + rst[1] + '<br>' + 'cigar: ' + this.bsa_cigar2str(rst[2]) + '<br><br>' + 'alignment:' + '<br>'
53621
+
53622
+ let linelen = 100,
53623
+ n_lines = 10;
53624
+ for (let l = 0; l < fmt[0].length; l += linelen) {
53625
+ str += fmt[0].substr(l, linelen) + '\n';
53626
+ str += fmt[2].substr(l, linelen) + '\n';
53627
+ str += fmt[1].substr(l, linelen) + '\n\n';
53628
+ n_lines += 4;
53629
+ }
53630
+
53631
+ algn += '<pre>'
53632
+ algn += fmt[0] + '<br>';
53633
+ algn += fmt[2] + '<br>';
53634
+ algn += fmt[1] + '<br><br>';
53635
+ algn += '</pre><br>' + "</span></div>"
53636
+
53637
+ //anno_seq.innerHTML += algn
53638
+
53639
+ //let elapse = (new Date().getTime() - time_start) / 1000.0;
53640
+ //console.log("in " + elapse.toFixed(3) + "s");
53641
+ */
53642
+ let algn = {};
53643
+ algn.score = rst[0];
53644
+ algn.start = rst[1];
53645
+ algn.cigar = this.bsa_cigar2str(rst[2]);
53646
+ algn.target = fmt[0];
53647
+ algn.query = fmt[1];
53648
+
53649
+ return algn;
53650
+ }
53651
+
53652
+ /**
53653
+ * Encode a sequence string with table
53654
+ *
53655
+ * @param seq sequence
53656
+ * @param table encoding table; must be of size 256
53657
+ *
53658
+ * @return an integer array
53659
+ */
53660
+
53661
+ bsg_enc_seq(seq, table) { let ic = this.icn3d; ic.icn3dui;
53662
+ if (table == null) return null;
53663
+ let s = [];
53664
+ s.length = seq.length;
53665
+ for (let i = 0; i < seq.length; ++i)
53666
+ s[i] = table[seq.charCodeAt(i)];
53667
+ return s;
53668
+ }
53669
+
53670
+ /*
53671
+ ks_revcomp(s) { let ic = this.icn3d, me = ic.icn3dui;
53672
+ let ks_comp = {'A':'T','C':'G','G':'C','T':'A','M':'K','K':'M','Y':'R','R':'Y','V':'B','B':'V','H':'D','D':'H',
53673
+ 'a':'t','c':'g','g':'c','t':'a','m':'k','k':'m','y':'r','r':'y','v':'b','b':'v','h':'d','d':'h'};
53674
+
53675
+ let i, t = '';
53676
+ for (i = 0; i < s.length; ++i) {
53677
+ let c = s.charAt(s.length - 1 - i);
53678
+ let d = ks_comp[c];
53679
+ t += d? d : c;
53680
+ }
53681
+ return t;
53682
+ }
53683
+ */
53684
+
53685
+ /**************************
53686
+ *** Pairwise alignment ***
53687
+ **************************/
53688
+
53689
+ /*
53690
+ * The following implements local and global pairwise alignment with affine gap
53691
+ * penalties. There are two formulations: the Durbin formulation as is
53692
+ * described in his book and the Green formulation as is implemented in phrap.
53693
+ * The Durbin formulation is easier to understand, while the Green formulation
53694
+ * is simpler to code and probably faster in practice.
53695
+ *
53696
+ * The Durbin formulation is:
53697
+ *
53698
+ * M(i,j) = max{M(i-1,j-1)+S(i,j), E(i-1,j-1), F(i-1,j-1)}
53699
+ * E(i,j) = max{M(i-1,j)-q-r, F(i-1,j)-q-r, E(i-1,j)-r}
53700
+ * F(i,j) = max{M(i,j-1)-q-r, F(i,j-1)-r, E(i,j-1)-q-r}
53701
+ *
53702
+ * where q is the gap open penalty, r the gap extension penalty and S(i,j) is
53703
+ * the score between the i-th residue in the row sequence and the j-th residue
53704
+ * in the column sequence. Note that the original Durbin formulation disallows
53705
+ * transitions between between E and F states, but we allow them here.
53706
+ *
53707
+ * In the Green formulation, we introduce:
53708
+ *
53709
+ * H(i,j) = max{M(i,j), E(i,j), F(i,j)}
53710
+ *
53711
+ * The recursion becomes:
53712
+ *
53713
+ * H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
53714
+ * E(i,j) = max{H(i-1,j)-q, E(i-1,j)} - r
53715
+ * F(i,j) = max{H(i,j-1)-q, F(i,j-1)} - r
53716
+ *
53717
+ * It is in fact equivalent to the Durbin formulation. In implementation, we
53718
+ * calculate the scores in a different order:
53719
+ *
53720
+ * H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
53721
+ * E(i+1,j) = max{H(i,j)-q, E(i,j)} - r
53722
+ * F(i,j+1) = max{H(i,j)-q, F(i,j)} - r
53723
+ *
53724
+ * i.e. at cell (i,j), we compute E for the next row and F for the next column.
53725
+ * Please see inline comments below for details.
53726
+ *
53727
+ *
53728
+ * The following implementation is ported from klib/ksw.c. The original C
53729
+ * implementation has a few bugs which have been fixed here. Like the C
53730
+ * version, this implementation should be very efficient. It could be made more
53731
+ * efficient if we use typed integer arrays such as Uint8Array. In addition,
53732
+ * I mixed the local and global alignments together. For performance,
53733
+ * it would be preferred to separate them out.
53734
+ */
53735
+
53736
+ /**
53737
+ * Generate scoring matrix from match/mismatch score
53738
+ *
53739
+ * @param n size of the alphabet
53740
+ * @param a match score, positive
53741
+ * @param b mismatch score, negative
53742
+ *
53743
+ * @return sqaure scoring matrix. The last row and column are zero, for
53744
+ * matching an ambiguous residue.
53745
+ */
53746
+ bsa_gen_score_matrix(n, a, b) { let ic = this.icn3d; ic.icn3dui;
53747
+ let m = [];
53748
+ if (b > 0) b = -b; // mismatch score b should be non-positive
53749
+ let i, j;
53750
+ for (i = 0; i < n - 1; ++i) {
53751
+ m[i] = [];
53752
+ for (j = 0; j < n - 1; ++j)
53753
+ m[i][j] = i == j ? a : b;
53754
+ m[i][j] = 0;
53755
+ }
53756
+ m[n - 1] = [];
53757
+ for (let j = 0; j < n; ++j) m[n - 1][j] = 0;
53758
+ return m;
53759
+ }
53760
+
53761
+ /**
53762
+ * Generate query profile (a preprocessing step)
53763
+ *
53764
+ * @param _s sequence in string or post bsg_enc_seq()
53765
+ * @param _m score matrix or [match,mismatch] array
53766
+ * @param table encoding table; must be consistent with _s and _m
53767
+ *
53768
+ * @return query profile. It is a two-dimensional integer matrix.
53769
+ */
53770
+ bsa_gen_query_profile(_s, _m, table) { let ic = this.icn3d; ic.icn3dui;
53771
+ let s = typeof _s == 'string' ? this.bsg_enc_seq(_s, table) : _s;
53772
+ let qp = [],
53773
+ matrix;
53774
+ if (_m.length >= 2 && typeof _m[0] == 'number' && typeof _m[1] == 'number') { // match/mismatch score
53775
+ if (table == null) return null;
53776
+ let n = typeof table == 'number' ? table : table[table.length - 1] + 1;
53777
+ matrix = this.bsa_gen_score_matrix(n, _m[0], _m[1]);
53778
+ } else matrix = _m; // _m is already a matrix; FIXME: check if it is really a square matrix!
53779
+ for (let j = 0; j < matrix.length; ++j) {
53780
+ let qpj, mj = matrix[j];
53781
+ qpj = qp[j] = [];
53782
+ for (let i = 0; i < s.length; ++i)
53783
+ qpj[i] = mj[s[i]];
53784
+ }
53785
+ return qp;
53786
+ }
53787
+
53788
+ /**
53789
+ * Local or global pairwise alignemnt
53790
+ *
53791
+ * @param is_local perform local alignment
53792
+ * @param target target string
53793
+ * @param query query string or query profile
53794
+ * @param matrix square score matrix or [match,mismatch] array
53795
+ * @param gapsc [gap_open,gap_ext] array; k-length gap costs gap_open+gap_ext*k
53796
+ * @param w bandwidth, disabled by default
53797
+ * @param table encoding table. It defaults to bst_nt5.
53798
+ *
53799
+ * @return [score,target_start,cigar]. cigar is encoded in the BAM way, where
53800
+ * higher 28 bits keeps the length and lower 4 bits the operation in order of
53801
+ * "MIDNSH". See bsa_cigar2str() for converting cigar to string.
53802
+ */
53803
+ bsa_align(is_local, target, query, matrix, gapsc, w, table) { let ic = this.icn3d; ic.icn3dui;
53804
+ let bst_nt5 = [
53805
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53806
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53807
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53808
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53809
+ 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
53810
+ 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53811
+ 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4,
53812
+ 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53813
+
53814
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53815
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53816
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53817
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53818
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53819
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53820
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
53821
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
53822
+ ];
53823
+
53824
+ // convert bases to integers
53825
+ if (table == null) table = bst_nt5;
53826
+ let t = this.bsg_enc_seq(target, table);
53827
+ let qp = this.bsa_gen_query_profile(query, matrix, table);
53828
+ let qlen = qp[0].length;
53829
+
53830
+ // adjust band width
53831
+ let max_len = qlen > t.length ? qlen : t.length;
53832
+ w = w == null || w < 0 ? max_len : w;
53833
+ let len_diff = t.target > qlen ? t.target - qlen : qlen - t.target;
53834
+ w = w > len_diff ? w : len_diff;
53835
+
53836
+ // set gap score
53837
+ let gapo, gape; // these are penalties which should be non-negative
53838
+ if (typeof gapsc == 'number') gapo = 0, gape = gapsc > 0 ? gapsc : -gapsc;
53839
+ else gapo = gapsc[0] > 0 ? gapsc[0] : -gapsc[0], gape = gapsc[1] > 0 ? gapsc[1] : -gapsc[1];
53840
+ let gapoe = gapo + gape; // penalty for opening the first gap
53841
+
53842
+ // initial values
53843
+ let NEG_INF = -0x40000000;
53844
+ let H = [],
53845
+ E = [],
53846
+ z = [],
53847
+ score, max = 0,
53848
+ end_i = -1,
53849
+ end_j = -1;
53850
+ if (is_local) {
53851
+ for (let j = 0; j <= qlen; ++j) H[j] = E[j] = 0;
53852
+ } else {
53853
+ H[0] = 0;
53854
+ E[0] = -gapoe - gapoe;
53855
+ for (let j = 1; j <= qlen; ++j) {
53856
+ if (j >= w) H[j] = E[j] = NEG_INF; // everything is -inf outside the band
53857
+ else H[j] = -(gapoe + gape * (j - 1)), E[j] = -(gapoe + gapoe + gape * j);
53858
+ }
53859
+ }
53860
+
53861
+ // the DP loop
53862
+ for (let i = 0; i < t.length; ++i) {
53863
+ let h1 = 0,
53864
+ f = 0,
53865
+ m = 0,
53866
+ mj = -1;
53867
+ let zi, qpi = qp[t[i]];
53868
+ zi = z[i] = [];
53869
+ let beg = i > w ? i - w : 0;
53870
+ let end = i + w + 1 < qlen ? i + w + 1 : qlen; // only loop through [beg,end) of the query sequence
53871
+ if (!is_local) {
53872
+ h1 = beg > 0 ? NEG_INF : -(gapoe + gape * i);
53873
+ f = beg > 0 ? NEG_INF : -(gapoe + gapoe + gape * i);
53874
+ }
53875
+ for (let j = beg; j < end; ++j) {
53876
+ // At the beginning of the loop: h=H[j]=H(i-1,j-1), e=E[j]=E(i,j), f=F(i,j) and h1=H(i,j-1)
53877
+ // If we only want to compute the max score, delete all lines involving direction "d".
53878
+ let e = E[j],
53879
+ h = H[j],
53880
+ d;
53881
+ H[j] = h1; // set H(i,j-1) for the next row
53882
+ h += qpi[j]; // h = H(i-1,j-1) + S(i,j)
53883
+ d = h >= e ? 0 : 1;
53884
+ h = h >= e ? h : e;
53885
+ d = h >= f ? d : 2;
53886
+ h = h >= f ? h : f; // h = H(i,j) = max{H(i-1,j-1)+S(i,j), E(i,j), F(i,j)}
53887
+ d = !is_local || h > 0 ? d : 1 << 6;
53888
+ h1 = h; // save H(i,j) to h1 for the next column
53889
+ mj = m > h ? mj : j;
53890
+ m = m > h ? m : h; // update the max score in this row
53891
+ h -= gapoe;
53892
+ h = !is_local || h > 0 ? h : 0;
53893
+ e -= gape;
53894
+ d |= e > h ? 1 << 2 : 0;
53895
+ e = e > h ? e : h; // e = E(i+1,j)
53896
+ E[j] = e; // save E(i+1,j) for the next row
53897
+ f -= gape;
53898
+ d |= f > h ? 2 << 4 : 0;
53899
+ f = f > h ? f : h; // f = F(i,j+1)
53900
+ zi[j] = d; // z[i,j] keeps h for the current cell and e/f for the next cell
53901
+ }
53902
+ H[end] = h1, E[end] = is_local ? 0 : NEG_INF;
53903
+ if (m > max) max = m, end_i = i, end_j = mj;
53904
+ }
53905
+ if (is_local && max == 0) return null;
53906
+ score = is_local ? max : H[qlen];
53907
+
53908
+ let cigar = [],
53909
+ tmp, which = 0,
53910
+ i, k, start_i = 0;
53911
+ if (is_local) {
53912
+ i = end_i, k = end_j;
53913
+ if (end_j != qlen - 1) // then add soft cliping
53914
+ this.push_cigar(cigar, 4, qlen - 1 - end_j);
53915
+ } else i = t.length - 1, k = (i + w + 1 < qlen ? i + w + 1 : qlen) - 1; // (i,k) points to the last cell
53916
+ while (i >= 0 && k >= 0) {
53917
+ tmp = z[i][k - (i > w ? i - w : 0)];
53918
+ which = tmp >> (which << 1) & 3;
53919
+ if (which == 0 && tmp >> 6) break;
53920
+ if (which == 0) which = tmp & 3;
53921
+ if (which == 0) { this.push_cigar(cigar, 0, 1);--i, --k; } // match
53922
+ else if (which == 1) { this.push_cigar(cigar, 2, 1);--i; } // deletion
53923
+ else { this.push_cigar(cigar, 1, 1), --k; } // insertion
53924
+ }
53925
+ if (is_local) {
53926
+ if (k >= 0) this.push_cigar(cigar, 4, k + 1); // add soft clipping
53927
+ start_i = i + 1;
53928
+ } else { // add the first insertion or deletion
53929
+ if (i >= 0) this.push_cigar(cigar, 2, i + 1);
53930
+ if (k >= 0) this.push_cigar(cigar, 1, k + 1);
53931
+ }
53932
+ for (let i = 0; i < cigar.length >> 1; ++i) // reverse CIGAR
53933
+ tmp = cigar[i], cigar[i] = cigar[cigar.length - 1 - i], cigar[cigar.length - 1 - i] = tmp;
53934
+ return [score, start_i, cigar];
53935
+ }
53936
+
53937
+ // backtrack to recover the alignment/cigar
53938
+ push_cigar(ci, op, len) { let ic = this.icn3d; ic.icn3dui;
53939
+ if (ci.length == 0 || op != (ci[ci.length - 1] & 0xf))
53940
+ ci.push(len << 4 | op);
53941
+ else ci[ci.length - 1] += len << 4;
53942
+ }
53943
+
53944
+ bsa_cigar2gaps(target, query, start, cigar) { let ic = this.icn3d; ic.icn3dui;
53945
+ let oq = '',
53946
+ ot = '',
53947
+ mid = '',
53948
+ lq = 0,
53949
+ lt = start;
53950
+ for (let k = 0; k < cigar.length; ++k) {
53951
+ let op = cigar[k] & 0xf,
53952
+ len = cigar[k] >> 4;
53953
+ if (op == 0) { // match
53954
+ oq += query.substr(lq, len);
53955
+ ot += target.substr(lt, len);
53956
+ lq += len, lt += len;
53957
+ } else if (op == 1) { // insertion
53958
+ oq += query.substr(lq, len);
53959
+ ot += Array(len + 1).join("-");
53960
+ lq += len;
53961
+ } else if (op == 2) { // deletion
53962
+ oq += Array(len + 1).join("-");
53963
+ ot += target.substr(lt, len);
53964
+ lt += len;
53965
+ } else if (op == 4) { // soft clip
53966
+ lq += len;
53967
+ }
53968
+ }
53969
+ let ut = ot.toUpperCase();
53970
+ let uq = oq.toUpperCase();
53971
+ for (let k = 0; k < ut.length; ++k)
53972
+ mid += ut.charAt(k) == uq.charAt(k) ? '|' : ' ';
53973
+ return [ot, oq, mid];
53974
+ }
53975
+
53976
+ bsa_cigar2str(cigar) { let ic = this.icn3d; ic.icn3dui;
53977
+ let s = [];
53978
+ for (let k = 0; k < cigar.length; ++k)
53979
+ s.push((cigar[k] >> 4).toString() + "MIDNSHP=XB".charAt(cigar[k] & 0xf));
53980
+ return s.join("");
53981
+ }
53982
+ }
53983
+
53022
53984
  /**
53023
53985
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
53024
53986
  */
@@ -53114,7 +54076,7 @@ class Ray {
53114
54076
  // the intersections are sorted so that the closest point is the first one.
53115
54077
  intersects[ 0 ].point.sub(position); // mdl.position was moved to the original (0,0,0) after reading the molecule coordinates. The raycasting was done based on the original. The position of the original should be substracted.
53116
54078
 
53117
- let threshold = 0.5;
54079
+ let threshold = ic.rayThreshold; //0.5;
53118
54080
  let atom = this.getAtomsFromPosition(intersects[ 0 ].point, threshold); // the second parameter is the distance threshold. The first matched atom will be returned. Use 1 angstrom, not 2 angstrom. If it's 2 angstrom, other atom will be returned.
53119
54081
 
53120
54082
  while(!atom && threshold < 10) {
@@ -53643,6 +54605,8 @@ class iCn3D {
53643
54605
  this.bImpo = true;
53644
54606
  this.bInstanced = true;
53645
54607
 
54608
+ this.chainMissingResidueArray = {};
54609
+
53646
54610
  if(!this.icn3dui.bNode) {
53647
54611
  this.bExtFragDepth = this.renderer.extensions.get( "EXT_frag_depth" );
53648
54612
  if(!this.bExtFragDepth) {
@@ -53702,7 +54666,7 @@ class iCn3D {
53702
54666
  this.bCalphaOnly = false; // by default the input has both Calpha and O, used for drawing strands. If atoms have Calpha only, the orientation of the strands is random
53703
54667
  // this.bSSOnly = false; // a flag to turn on when only helix and bricks are available to draw 3D dgm
53704
54668
 
53705
- this.bAllAtoms = true; // no need to adjust atom for strand style
54669
+ // this.bAllAtoms = true; // no need to adjust atom for strand style
53706
54670
 
53707
54671
  this.bConsiderNeighbors = false; // a flag to show surface considering the neighboring atoms or not
53708
54672
 
@@ -53763,10 +54727,14 @@ class iCn3D {
53763
54727
 
53764
54728
  this.LABELSIZE = 30;
53765
54729
 
54730
+ this.rayThreshold = 0.5; // threadshold for raycast
54731
+ this.colorBlackbkgd = '#ffff00';
54732
+ this.colorWhitebkgd = '#000000';
54733
+
53766
54734
  //The default display options
53767
54735
  this.optsOri = {};
53768
54736
  this.optsOri['camera'] = 'perspective'; //perspective, orthographic
53769
- this.optsOri['background'] = 'transparent'; //transparent, black, grey, white
54737
+ this.optsOri['background'] = 'black'; //transparent, black, grey, white
53770
54738
  this.optsOri['color'] = 'chain'; //spectrum, secondary structure, charge, hydrophobic, conserved, chain, residue, atom, b factor, red, green, blue, magenta, yellow, cyan, white, grey, custom
53771
54739
  this.optsOri['proteins'] = 'ribbon'; //ribbon, strand, cylinder and plate, schematic, c alpha trace, backbone, b factor tube, lines, stick, ball and stick, sphere, nothing
53772
54740
  this.optsOri['sidec'] = 'nothing'; //lines, stick, ball and stick, sphere, nothing
@@ -53958,6 +54926,7 @@ class iCn3D {
53958
54926
  this.dsspCls = new Dssp(this);
53959
54927
  this.scapCls = new Scap(this);
53960
54928
  this.symdCls = new Symd(this);
54929
+ this.alignSWCls = new AlignSW(this);
53961
54930
 
53962
54931
  this.analysisCls = new Analysis(this);
53963
54932
  this.resizeCanvasCls = new ResizeCanvas(this);
@@ -54014,6 +54983,8 @@ iCn3D.prototype.init_base = function (bKeepCmd) {
54014
54983
  this.chainsAn = {}; // structure_chain name -> array of annotations, such as residue number
54015
54984
  this.chainsAnTitle = {}; // structure_chain name -> array of annotation title
54016
54985
 
54986
+ this.chainsMapping = {}; // structure_chain name -> residue id hash such as {'structure_chain_resi1': 'reference residue such as K10', ...}
54987
+
54017
54988
  this.alnChainsSeq = {}; // structure_chain name -> array of residue object: {mmdbid, chain, resi, resn, aligned}
54018
54989
  this.alnChainsAnno = {}; // structure_chain name -> array of annotations, such as residue number
54019
54990
  this.alnChainsAnTtl = {}; // structure_chain name -> array of annotation title
@@ -54090,9 +55061,13 @@ iCn3D.prototype.init_base = function (bKeepCmd) {
54090
55061
 
54091
55062
  this.axes = [];
54092
55063
 
54093
- this.bGlycansCartoon = false;
55064
+ this.bGlycansCartoon = 0;
55065
+ this.bMembrane = 1;
54094
55066
 
54095
55067
  this.chainid2offset = {};
55068
+
55069
+ this.chainMissingResidueArray = {};
55070
+ this.nTotalGap = 0;
54096
55071
  };
54097
55072
 
54098
55073
  //Reset parameters for displaying the loaded structure.
@@ -54159,7 +55134,7 @@ class iCn3DUI {
54159
55134
  //even when multiple iCn3D viewers are shown together.
54160
55135
  this.pre = this.cfg.divid + "_";
54161
55136
 
54162
- this.REVISION = '3.4.11';
55137
+ this.REVISION = '3.7.0';
54163
55138
 
54164
55139
  // In nodejs, iCn3D defines "window = {navigator: {}}"
54165
55140
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -54205,7 +55180,7 @@ class iCn3DUI {
54205
55180
  iCn3DUI.prototype.show3DStructure = function() { let me = this;
54206
55181
  let thisClass = this;
54207
55182
  me.deferred = $.Deferred(function() {
54208
- if(me.cfg.menumode == 1) {
55183
+ if(me.cfg.menuicon) {
54209
55184
  me.htmlCls.wifiStr = '<i class="icn3d-wifi" title="requires internet">&nbsp;</i>';
54210
55185
  me.htmlCls.licenseStr = '<i class="icn3d-license" title="requires license">&nbsp;</i>';
54211
55186
  }
@@ -54336,7 +55311,7 @@ iCn3DUI.prototype.show3DStructure = function() { let me = this;
54336
55311
 
54337
55312
  ic.loadCmd = 'load url ' + url + ' | type ' + type;
54338
55313
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
54339
- ic.pdbParserCls.downloadUrl(url, type);
55314
+ ic.pdbParserCls.downloadUrl(url, type, me.cfg.command);
54340
55315
  }
54341
55316
  else if(me.cfg.mmtfid !== undefined) {
54342
55317
  ic.inputid = me.cfg.mmtfid;
@@ -54387,7 +55362,16 @@ iCn3DUI.prototype.show3DStructure = function() { let me = this;
54387
55362
  // custom seqeunce has query_id such as "Query_78989" in BLAST
54388
55363
  if(me.cfg.query_id.substr(0,5) !== 'Query' && me.cfg.rid === undefined) {
54389
55364
  ic.inputid = me.cfg.query_id + '_' + me.cfg.blast_rep_id;
54390
- ic.loadCmd = 'load seq_struct_ids ' + me.cfg.query_id + ',' + me.cfg.blast_rep_id;
55365
+
55366
+ if(me.cfg.alg == 'smithwm') {
55367
+ ic.loadCmd = 'load seq_struct_ids_smithwm ' + me.cfg.query_id + ',' + me.cfg.blast_rep_id;
55368
+ ic.bSmithwm = true;
55369
+ }
55370
+ else {
55371
+ ic.loadCmd = 'load seq_struct_ids ' + me.cfg.query_id + ',' + me.cfg.blast_rep_id;
55372
+ ic.bSmithwm = false;
55373
+ }
55374
+
54391
55375
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
54392
55376
  ic.mmdbParserCls.downloadBlast_rep_id(me.cfg.query_id + ',' + me.cfg.blast_rep_id);
54393
55377
  }
@@ -54627,6 +55611,7 @@ class printMsg {
54627
55611
 
54628
55612
  exports.AddTrack = AddTrack;
54629
55613
  exports.AlignParser = AlignParser;
55614
+ exports.AlignSW = AlignSW;
54630
55615
  exports.AlignSeq = AlignSeq;
54631
55616
  exports.Alternate = Alternate;
54632
55617
  exports.Analysis = Analysis;