icn3d 3.33.2 → 3.34.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.
package/icn3d.js CHANGED
@@ -13188,6 +13188,7 @@ class Dialog {
13188
13188
  let bGraph = $('#' + me.pre + 'dl_graph').hasClass('ui-dialog-content'); // initialized
13189
13189
  let bLineGraph = $('#' + me.pre + 'dl_linegraph').hasClass('ui-dialog-content'); // initialized
13190
13190
  let bScatterplot = $('#' + me.pre + 'dl_scatterplot').hasClass('ui-dialog-content'); // initialized
13191
+ let bLigplot = $('#' + me.pre + 'dl_ligplot').hasClass('ui-dialog-content'); // initialized
13191
13192
  let bContactmap = $('#' + me.pre + 'dl_contactmap').hasClass('ui-dialog-content'); // initialized
13192
13193
  let bAlignerrormap = $('#' + me.pre + 'dl_alignerrormap').hasClass('ui-dialog-content'); // initialized
13193
13194
  let bTable = $('#' + me.pre + 'dl_interactionsorted').hasClass('ui-dialog-content'); // initialized
@@ -13197,13 +13198,14 @@ class Dialog {
13197
13198
  let bSetsInit = $('#' + me.pre + 'dl_definedsets').hasClass('ui-dialog-content'); // initialized
13198
13199
 
13199
13200
  status.bSelectannotationsInit2 = false, status.bGraph2 = false, status.bLineGraph2 = false;
13200
- status.bScatterplot2 = false, status.bTable2 = false, status.bAlignmentInit2 = false;
13201
+ status.bScatterplot2 = false, status.bLigplot2 = false, status.bTable2 = false, status.bAlignmentInit2 = false;
13201
13202
  status.bTwoddgmInit2 = false, status.bTwodctnInit2 = false, status.bSetsInit2 = false;
13202
13203
 
13203
13204
  id2flag.dl_selectannotations = 'bSelectannotationsInit2';
13204
13205
  id2flag.dl_graph = 'bGraph2';
13205
13206
  id2flag.dl_linegraph = 'bLineGraph2';
13206
- id2flag.dl_scatterplot = 'bScatterplot2';
13207
+ id2flag.dl_scatterplot = 'bScatterplot2';
13208
+ id2flag.dl_ligplot = 'bLigplot2';
13207
13209
  id2flag.dl_contactmap = 'bContactmap2';
13208
13210
  id2flag.dl_alignerrormap = 'bAlignerrormap2';
13209
13211
  id2flag.dl_interactionsorted = 'bTable2';
@@ -13216,6 +13218,7 @@ class Dialog {
13216
13218
  if(bGraph) status.bGraph2 = $('#' + me.pre + 'dl_graph').dialog( 'isOpen' );
13217
13219
  if(bLineGraph) status.bLineGraph2 = $('#' + me.pre + 'dl_linegraph').dialog( 'isOpen' );
13218
13220
  if(bScatterplot) status.bScatterplot2 = $('#' + me.pre + 'dl_scatterplot').dialog( 'isOpen' );
13221
+ if(bLigplot) status.bLigplot2 = $('#' + me.pre + 'dl_ligplot').dialog( 'isOpen' );
13219
13222
  if(bContactmap) status.bContactmap2 = $('#' + me.pre + 'dl_contactmap').dialog( 'isOpen' );
13220
13223
  if(bAlignerrormap) status.bAlignerror2 = $('#' + me.pre + 'dl_alignerrormap').dialog( 'isOpen' );
13221
13224
  if(bTable) status.bTable2 = $('#' + me.pre + 'dl_interactionsorted').dialog( 'isOpen' );
@@ -13302,7 +13305,7 @@ class Dialog {
13302
13305
 
13303
13306
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
13304
13307
  }
13305
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13308
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_ligplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13306
13309
  let oriWidth =(status.bTwoddgmInit2 || status.bSetsInit2) ?(me.htmlCls.WIDTH - twoddgmWidth)/2 : me.htmlCls.WIDTH / 2;
13307
13310
  let ratio = $("#" + id).width() / oriWidth;
13308
13311
 
@@ -13314,6 +13317,14 @@ class Dialog {
13314
13317
  let width = ic.scatterplotWidth * ratio;
13315
13318
  $("#" + me.scatterplotid).attr("width", width);
13316
13319
  }
13320
+ else if(id == me.pre + 'dl_ligplot') {
13321
+ let width = ic.ligplotWidth * ratio;
13322
+ $("#" + me.ligplotid).attr("width", width);
13323
+ }
13324
+ else if(id == me.pre + 'dl_ligplot') {
13325
+ let width = ic.ligplotWidth * ratio;
13326
+ $("#" + me.ligplotid).attr("width", width);
13327
+ }
13317
13328
  else if(id == me.pre + 'dl_contactmap') {
13318
13329
  let width = ic.contactmapWidth * ratio;
13319
13330
  $("#" + me.contactmapid).attr("width", width);
@@ -13367,7 +13378,7 @@ class Dialog {
13367
13378
  close: function(e) {
13368
13379
  let status = thisClass.getDialogStatus().status;
13369
13380
 
13370
- if((!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bTable2) &&(!status.bAlignmentInit2) ) {
13381
+ if((!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bTable2) &&(!status.bAlignmentInit2) ) {
13371
13382
  //ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH, me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT, true);
13372
13383
  ic.resizeCanvasCls.resizeCanvas(me.htmlCls.WIDTH, me.htmlCls.HEIGHT, true);
13373
13384
  }
@@ -13396,7 +13407,7 @@ class Dialog {
13396
13407
 
13397
13408
  let status = this.getDialogStatus().status;
13398
13409
 
13399
- if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13410
+ if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13400
13411
  //var dialogWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
13401
13412
  let dialogWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
13402
13413
 
@@ -13432,14 +13443,15 @@ class Dialog {
13432
13443
  modal: false,
13433
13444
  position: position,
13434
13445
  close: function(e) {
13435
- if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13436
- ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13437
- ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13438
- ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13439
- ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13440
- ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13441
- ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bAlignerrormap2))
13442
- ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2))
13446
+ if((id === me.pre + 'dl_selectannotations' &&(!status.bAlignmentInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13447
+ ||(id === me.pre + 'dl_graph' &&(!status.bSelectannotationsInit2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13448
+ ||(id === me.pre + 'dl_alignment' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13449
+ ||(id === me.pre + 'dl_interactionsorted' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13450
+ ||(id === me.pre + 'dl_linegraph' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13451
+ ||(id === me.pre + 'dl_scatterplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bLigplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13452
+ ||(id === me.pre + 'dl_ligplot' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bContactmap2) &&(!status.bAlignerrormap2))
13453
+ ||(id === me.pre + 'dl_contactmap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bAlignerrormap2))
13454
+ ||(id === me.pre + 'dl_alignerrormap' &&(!status.bSelectannotationsInit2) &&(!status.bGraph2) &&(!status.bAlignmentInit2) &&(!status.bTable2) &&(!status.bLineGraph2) &&(!status.bScatterplot2) &&(!status.bLigplot2) &&(!status.bContactmap2))
13443
13455
  ) {
13444
13456
  if(status.bTwoddgmInit2 || status.bTwodctnInit2 || status.bSetsInit2) {
13445
13457
  let canvasWidth = me.utilsCls.isMobile() ? me.htmlCls.WIDTH : me.htmlCls.WIDTH - twoddgmWidth;
@@ -13465,7 +13477,7 @@ class Dialog {
13465
13477
 
13466
13478
  d3.select("#" + me.svgid).attr("width", width).attr("height", height);
13467
13479
  }
13468
- else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13480
+ else if(id == me.pre + 'dl_linegraph' || id == me.pre + 'dl_scatterplot' || id == me.pre + 'dl_ligplot' || id == me.pre + 'dl_contactmap' || id == me.pre + 'dl_alignerrormap') {
13469
13481
  let oriWidth =(status.bTwoddgmInit2 || status.bSetsInit2) ?(me.htmlCls.WIDTH - twoddgmWidth)/2 : me.htmlCls.WIDTH / 2;
13470
13482
  let ratio = $("#" + id).width() / oriWidth;
13471
13483
 
@@ -13477,6 +13489,10 @@ class Dialog {
13477
13489
  let width = ic.scatterplotWidth * ratio;
13478
13490
  $("#" + me.scatterplotid).attr("width", width);
13479
13491
  }
13492
+ else if(id == me.pre + 'dl_ligplot') {
13493
+ let width = ic.ligplotWidth * ratio;
13494
+ $("#" + me.ligplotid).attr("width", width);
13495
+ }
13480
13496
  else if(id == me.pre + 'dl_contactmap') {
13481
13497
  let width = ic.contactmapWidth * ratio;
13482
13498
  $("#" + me.contactmapid).attr("width", width);
@@ -13498,7 +13514,7 @@ class Dialog {
13498
13514
 
13499
13515
  //if(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH >= me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT) {
13500
13516
  if(me.htmlCls.WIDTH >= me.htmlCls.HEIGHT) {
13501
- if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bTable2 || status.bAlignmentInit2) {
13517
+ if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bLigplot2 || status.bTable2 || status.bAlignmentInit2) {
13502
13518
  //tmpWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
13503
13519
  tmpWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
13504
13520
  }
@@ -13537,7 +13553,7 @@ class Dialog {
13537
13553
 
13538
13554
  //if(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH >= me.htmlCls.HEIGHT - me.htmlCls.LESSHEIGHT - me.htmlCls.EXTRAHEIGHT) {
13539
13555
  if(me.htmlCls.WIDTH >= me.htmlCls.HEIGHT) {
13540
- if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bTable2 || status.bAlignmentInit2) {
13556
+ if(status.bSelectannotationsInit2 || status.bGraph2 || status.bLineGraph2 || status.bScatterplot2 || status.bLigplot2 || status.bTable2 || status.bAlignmentInit2) {
13541
13557
  //tmpWidth = 0.5 *(me.htmlCls.WIDTH - me.htmlCls.LESSWIDTH) - twoddgmWidth * 0.5;
13542
13558
  tmpWidth = 0.5 *(me.htmlCls.WIDTH) - twoddgmWidth * 0.5;
13543
13559
  }
@@ -13617,7 +13633,7 @@ class Dialog {
13617
13633
  let width = 400, height = 150;
13618
13634
  let twoddgmWidth = me.htmlCls.width2d + 20;
13619
13635
 
13620
- if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13636
+ if(id === me.pre + 'dl_selectannotations' || id === me.pre + 'dl_graph' || id === me.pre + 'dl_linegraph' || id === me.pre + 'dl_scatterplot' || id === me.pre + 'dl_ligplot' || id === me.pre + 'dl_contactmap' || id === me.pre + 'dl_alignerrormap' || id === me.pre + 'dl_interactionsorted' || id === me.pre + 'dl_alignment') {
13621
13637
  $( "#" + id ).show();
13622
13638
  $( "#" + id + "_nb").show();
13623
13639
  $( "#" + id + "_title").html(title);
@@ -13652,6 +13668,11 @@ class Dialog {
13652
13668
 
13653
13669
  $("#" + me.scatterplotid).attr("width", width);
13654
13670
  }
13671
+ else if(id == me.pre + 'dl_ligplot') {
13672
+ let width = ic.ligplotWidth * ratio;
13673
+
13674
+ $("#" + me.ligplotid).attr("width", width);
13675
+ }
13655
13676
  else if(id == me.pre + 'dl_contactmap') {
13656
13677
  let width = ic.contactmapWidth * ratio;
13657
13678
 
@@ -14350,6 +14371,8 @@ class SetDialog {
14350
14371
 
14351
14372
  html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondScatterplot'>2D Interaction Map</button> " + me.htmlCls.buttonStr + "hbondScatterplot2' style='margin-left:12px'>2D Map with Reference Numbers</button> to show map</div><br>";
14352
14373
 
14374
+ html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondLigplot'>2D Interaction for One Ligand/Residue</button> with atom details</div><br>";
14375
+
14353
14376
  tmpStr = ': </td><td><input style="margin-left:-12px" type="text" id="';
14354
14377
 
14355
14378
  html += "<div style='text-indent:1.1em'>" + me.htmlCls.buttonStr + "hbondGraph'>2D Graph(Force-Directed)</button> to show interactions with strength parameters in 0-200:</div>";
@@ -14516,6 +14539,40 @@ class SetDialog {
14516
14539
 
14517
14540
  html += "</div>";
14518
14541
 
14542
+
14543
+ html += me.htmlCls.divStr + "dl_ligplot' sty2D Interaction for One Ligand/Residule='background-color:white' class='" + dialogClass + "'>";
14544
+ html += this.addNotebookTitle('dl_ligplot', 'e with Atom Details');
14545
+
14546
+ html += me.htmlCls.divNowrapStr + "<b>Note</b>: Nodes can be dragged or clicked. Hold Ctrl key to select multiple nodes. " + me.htmlCls.space3;
14547
+
14548
+ html += '<div style="width:20px; margin-top:6px; display:inline-block;"><span id="'
14549
+ + me.pre + 'dl_ligplotcolor_expand" class="ui-icon ui-icon-plus icn3d-expand icn3d-link" style="display:none; width:15px;" title="Expand"></span><span id="'
14550
+ + me.pre + 'dl_ligplotcolor_shrink" class="ui-icon ui-icon-minus icn3d-shrink icn3d-link" style="width:15px;" title="Shrink"></span></div></div>';
14551
+
14552
+ html += me.htmlCls.divStr + "dl_ligplotcolor' style='inline-block;'>";
14553
+
14554
+ // html += "The real interaction distances are not in scale, and are about twice the distances of dashed line segments.<br>Some \"Contact\" lines are only shown partially to simplify the view.<br>";
14555
+ html += "<b>Color Legend</b>: <br>";
14556
+
14557
+ html += me.htmlCls.setHtmlCls.setColorHints();
14558
+
14559
+ html += "<br></div>";
14560
+
14561
+ me.ligplotid = me.pre + 'ligplot';
14562
+ html += me.htmlCls.divNowrapStr + buttonStrTmp + me.ligplotid + '_svg">SVG</button>' + me.htmlCls.space2;
14563
+ html += buttonStrTmp + me.ligplotid + '_png">PNG</button>' + me.htmlCls.space2;
14564
+ // html += buttonStrTmp + me.ligplotid + '_json">JSON</button>' + me.htmlCls.space4;
14565
+ html += "<b>Scale</b>: <select id='" + me.ligplotid + "_scale'>";
14566
+
14567
+ html += me.htmlCls.setHtmlCls.getOptionHtml(optArray4, 5);
14568
+
14569
+ html += "</select></div><br>";
14570
+ html += '<div id="' + me.pre + 'ligplotDiv"></div>';
14571
+
14572
+ html += "</div>";
14573
+
14574
+
14575
+
14519
14576
  html += me.htmlCls.divStr + "dl_contactmap' style='background-color:white' class='" + dialogClass + "'>";
14520
14577
  html += this.addNotebookTitle('dl_contactmap', 'Contact Map');
14521
14578
 
@@ -15570,6 +15627,7 @@ class Events {
15570
15627
 
15571
15628
  ic.diagram2dCls.click2Ddgm();
15572
15629
  ic.cartoon2dCls.click2Dcartoon();
15630
+ ic.ligplotCls.clickLigplot();
15573
15631
  ic.addTrackCls.clickAddTrackButton();
15574
15632
  ic.resizeCanvasCls.windowResize();
15575
15633
  ic.annotationCls.setTabs();
@@ -17191,6 +17249,13 @@ class Events {
17191
17249
  thisClass.setLogCmd("show ref number", true);
17192
17250
  await ic.showInterCls.showInteractions('scatterplot');
17193
17251
  });
17252
+ me.myEventCls.onIds("#" + me.pre + "hbondLigplot", "click", async function(e) { let ic = me.icn3d;
17253
+ e.preventDefault();
17254
+
17255
+ ic.bShownRefnum = false;
17256
+ thisClass.setLogCmd("hide ref number", true);
17257
+ await ic.showInterCls.showInteractions('ligplot');
17258
+ });
17194
17259
  // select residues
17195
17260
  $(document).on("click", "#" + me.svgid + " circle.selected", function(e) { let ic = me.icn3d;
17196
17261
  e.stopImmediatePropagation();
@@ -17301,6 +17366,33 @@ class Events {
17301
17366
  thisClass.setLogCmd("scatterplot scale " + scale, true);
17302
17367
  });
17303
17368
 
17369
+ me.myEventCls.onIds("#" + me.ligplotid + "_svg", "click", function(e) { let ic = me.icn3d;
17370
+ e.preventDefault();
17371
+
17372
+ ic.saveFileCls.saveSvg(me.ligplotid, ic.inputid + "_ligplot.svg", undefined, true);
17373
+ });
17374
+ me.myEventCls.onIds("#" + me.ligplotid + "_png", "click", function(e) { let ic = me.icn3d;
17375
+ e.preventDefault();
17376
+
17377
+ ic.saveFileCls.savePng(me.ligplotid, ic.inputid + "_ligplot.png", undefined, true);
17378
+ });
17379
+ // me.myEventCls.onIds("#" + me.ligplotid + "_json", "click", function(e) { let ic = me.icn3d;
17380
+ // e.preventDefault();
17381
+
17382
+ // let graphStr2 = ic.ligplotStr.substr(0, ic.ligplotStr.lastIndexOf('}'));
17383
+
17384
+ // graphStr2 += me.htmlCls.setHtmlCls.getLinkColor();
17385
+
17386
+ // ic.saveFileCls.saveFile(ic.inputid + "_ligplot.json", "text", [graphStr2]);
17387
+ // });
17388
+ me.myEventCls.onIds("#" + me.ligplotid + "_scale", "change", function(e) { let ic = me.icn3d;
17389
+ e.preventDefault();
17390
+
17391
+ let scale = $("#" + me.ligplotid + "_scale").val();
17392
+ $("#" + me.ligplotid).attr("width",(ic.ligplotWidth * parseFloat(scale)).toString() + "px");
17393
+ thisClass.setLogCmd("ligplot scale " + scale, true);
17394
+ });
17395
+
17304
17396
  me.myEventCls.onIds("#" + me.contactmapid + "_svg", "click", function(e) { let ic = me.icn3d;
17305
17397
  e.preventDefault();
17306
17398
 
@@ -36758,7 +36850,8 @@ class Contact {
36758
36850
  if(oriCalpha === undefined) oriCalpha = oriAtom;
36759
36851
 
36760
36852
  if(bGetPairs) {
36761
- oriResidName = oriAtom.resn + ' $' + oriAtom.structure + '.' + oriAtom.chain + ':' + oriAtom.resi;
36853
+ let serialList = (oriAtom.name.indexOf('pi') == 0 && oriAtom.ring) ? oriAtom.ring.join(',') : oriAtom.serial;
36854
+ oriResidName = oriAtom.resn + ' $' + oriAtom.structure + '.' + oriAtom.chain + ':' + oriAtom.resi + ' ' + serialList;
36762
36855
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
36763
36856
  }
36764
36857
 
@@ -36803,13 +36896,14 @@ class Contact {
36803
36896
  if(bGetPairs) {
36804
36897
  let chain_resi2 = atom.structure + '_' + atom.chain + '_' + atom.resi;
36805
36898
 
36806
- residName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi;
36899
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
36900
+ residName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + ' ' + serialList;
36807
36901
  //var dist = Math.sqrt(atomDistSq).toFixed(1);
36808
36902
  let dist1 = atomDist.toFixed(1);
36809
36903
  let dist2 = calpha.coord.distanceTo(oriCalpha.coord).toFixed(1);
36810
36904
 
36811
36905
  let resids = chain_resi + '_' + oriAtom.resn + ',' + chain_resi2 + '_' + atom.resn;
36812
- let residNames = oriResidName + ',' + residName;
36906
+ let residNames = oriResidName + '|' + residName;
36813
36907
  if(ic.resids2interAll[resids] === undefined
36814
36908
  || ic.resids2interAll[resids]['contact'] === undefined
36815
36909
  || !ic.resids2interAll[resids]['contact'].hasOwnProperty(residNames)
@@ -36826,12 +36920,12 @@ class Contact {
36826
36920
  if(!bInternal) {
36827
36921
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
36828
36922
  if(ic.resids2inter[resids]['contact'] === undefined) ic.resids2inter[resids]['contact'] = {};
36829
- ic.resids2inter[resids]['contact'][oriResidName + ',' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36923
+ ic.resids2inter[resids]['contact'][oriResidName + '|' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36830
36924
  }
36831
36925
 
36832
36926
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
36833
36927
  if(ic.resids2interAll[resids]['contact'] === undefined) ic.resids2interAll[resids]['contact'] = {};
36834
- ic.resids2interAll[resids]['contact'][oriResidName + ',' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36928
+ ic.resids2interAll[resids]['contact'][oriResidName + '|' + residName] = dist1 + '_' + dist2 + '_' + oriAtom.name + '_' + atom.name + '_' + cnt;
36835
36929
  }
36836
36930
  }
36837
36931
  } // if(bGetPairs) {
@@ -37257,7 +37351,8 @@ class HBond {
37257
37351
  chain_resi_atom = chain_resi + "_" + atom.name;
37258
37352
 
37259
37353
  //var oriResidName = atom.resn + ' ' + chain_resi_atom;
37260
- let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name;
37354
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
37355
+ let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name + ' ' + serialList;
37261
37356
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37262
37357
 
37263
37358
  for (let j in atomHbond) {
@@ -37382,24 +37477,25 @@ class HBond {
37382
37477
  residueHash[chain_resi2] = 1;
37383
37478
 
37384
37479
  //var residName = atomHbond[j].resn + " " + atomHbond[j].structure + "_" + atomHbond[j].chain + "_" + atomHbond[j].resi + '_' + atomHbond[j].name;
37385
- let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name;
37480
+ let serialList = (atomHbond[j].name.indexOf('pi') == 0 && atomHbond[j].ring) ? atomHbond[j].ring.join(',') : atomHbond[j].serial;
37481
+ let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name + ' ' + serialList;
37386
37482
 
37387
37483
  let resids = chain_resi + '_' + atom.resn + ',' + chain_resi2 + '_' + atomHbond[j].resn;
37388
37484
 
37389
37485
  if(ic.resids2interAll[resids] === undefined
37390
37486
  || ic.resids2interAll[resids]['ionic'] === undefined
37391
- || !ic.resids2interAll[resids]['ionic'].hasOwnProperty(oriResidName + ',' + residName) ) {
37487
+ || !ic.resids2interAll[resids]['ionic'].hasOwnProperty(oriResidName + '|' + residName) ) {
37392
37488
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
37393
37489
 
37394
37490
  if(!bInternal) {
37395
37491
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
37396
37492
  if(ic.resids2inter[resids]['hbond'] === undefined) ic.resids2inter[resids]['hbond'] = {};
37397
- ic.resids2inter[resids]['hbond'][oriResidName + ',' + residName] = dist.toFixed(1);
37493
+ ic.resids2inter[resids]['hbond'][oriResidName + '|' + residName] = dist.toFixed(1);
37398
37494
  }
37399
37495
 
37400
37496
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
37401
37497
  if(ic.resids2interAll[resids]['hbond'] === undefined) ic.resids2interAll[resids]['hbond'] = {};
37402
- ic.resids2interAll[resids]['hbond'][oriResidName + ',' + residName] = dist.toFixed(1);
37498
+ ic.resids2interAll[resids]['hbond'][oriResidName + '|' + residName] = dist.toFixed(1);
37403
37499
  }
37404
37500
  } // end of for (let j in atomHbond) {
37405
37501
  }
@@ -37552,7 +37648,8 @@ class PiHalogen {
37552
37648
 
37553
37649
  for (let i in atoms1a) {
37554
37650
  let atom1 = atoms1a[i];
37555
- let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name;
37651
+ let serialList = (atom1.name.indexOf('pi') == 0 && atom1.ring) ? atom1.ring.join(',') : atom1.serial;
37652
+ let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name + ' ' + serialList;
37556
37653
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37557
37654
 
37558
37655
  for (let j in atoms1b) {
@@ -37596,7 +37693,8 @@ class PiHalogen {
37596
37693
 
37597
37694
  for (let i in atoms2a) {
37598
37695
  let atom1 = atoms2a[i];
37599
- let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name;
37696
+ let serialList = (atom1.name.indexOf('pi') == 0 && atom1.ring) ? atom1.ring.join(',') : atom1.serial;
37697
+ let oriResidName = atom1.resn + ' $' + atom1.structure + '.' + atom1.chain + ':' + atom1.resi + '@' + atom1.name + ' ' + serialList;
37600
37698
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
37601
37699
 
37602
37700
  // available in 1b and 2a
@@ -37761,7 +37859,8 @@ class PiHalogen {
37761
37859
  }
37762
37860
  }
37763
37861
 
37764
- let residName = atom2.resn + ' $' + atom2.structure + '.' + atom2.chain + ':' + atom2.resi + '@' + atom2.name;
37862
+ let serialList = (atom2.name.indexOf('pi') == 0 && atom2.ring) ? atom2.ring.join(',') : atom2.serial;
37863
+ let residName = atom2.resn + ' $' + atom2.structure + '.' + atom2.chain + ':' + atom2.resi + '@' + atom2.name + ' ' + serialList;
37765
37864
 
37766
37865
  //if(ic.resid2Residhash[oriResidName][residName] === undefined || ic.resid2Residhash[oriResidName][residName] > dist) {
37767
37866
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
@@ -37773,12 +37872,12 @@ class PiHalogen {
37773
37872
  if(!bInternal) {
37774
37873
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
37775
37874
  if(ic.resids2inter[resids][interactionType] === undefined) ic.resids2inter[resids][interactionType] = {};
37776
- ic.resids2inter[resids][interactionType][oriResidName + ',' + residName] = dist.toFixed(1);
37875
+ ic.resids2inter[resids][interactionType][oriResidName + '|' + residName] = dist.toFixed(1);
37777
37876
  }
37778
37877
 
37779
37878
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
37780
37879
  if(ic.resids2interAll[resids][interactionType] === undefined) ic.resids2interAll[resids][interactionType] = {};
37781
- ic.resids2interAll[resids][interactionType][oriResidName + ',' + residName] = dist.toFixed(1);
37880
+ ic.resids2interAll[resids][interactionType][oriResidName + '|' + residName] = dist.toFixed(1);
37782
37881
 
37783
37882
  return true;
37784
37883
  }
@@ -38025,12 +38124,13 @@ class PiHalogen {
38025
38124
  // Print the i-th cycle
38026
38125
  let coord = new THREE.Vector3();
38027
38126
  let cnt = 0, serial;
38028
- let coordArray = [];
38127
+ let coordArray = [], ringArray = [];
38029
38128
  if(cycles.hasOwnProperty(i)) {
38030
38129
  for (let j = 0, jl = cycles[i].length; j < jl; ++j) {
38031
38130
  serial = cycles[i][j];
38032
38131
  coord.add(ic.atoms[serial].coord);
38033
38132
  coordArray.push(ic.atoms[serial].coord);
38133
+ ringArray.push(serial);
38034
38134
  ++cnt;
38035
38135
  }
38036
38136
  }
@@ -38050,7 +38150,7 @@ class PiHalogen {
38050
38150
 
38051
38151
  let atom = ic.atoms[serial];
38052
38152
  name2atom[resid + '_pi' + serial] = {resn: atom.resn, name: 'pi' + serial, coord: coord, serial: atom.serial,
38053
- structure: atom.structure, chain: atom.chain, resi: atom.resi, normal: normal};
38153
+ structure: atom.structure, chain: atom.chain, resi: atom.resi, normal: normal, ring: ringArray};
38054
38154
  }
38055
38155
  }
38056
38156
  }
@@ -38148,7 +38248,8 @@ class Saltbridge {
38148
38248
  chain_resi = atom.structure + "_" + atom.chain + "_" + atom.resi;
38149
38249
  chain_resi_atom = chain_resi + "_" + atom.name;
38150
38250
 
38151
- let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name;
38251
+ let serialList = (atom.name.indexOf('pi') == 0 && atom.ring) ? atom.ring.join(',') : atom.serial;
38252
+ let oriResidName = atom.resn + ' $' + atom.structure + '.' + atom.chain + ':' + atom.resi + '@' + atom.name + ' ' + serialList;
38152
38253
  if(ic.resid2Residhash[oriResidName] === undefined) ic.resid2Residhash[oriResidName] = {};
38153
38254
 
38154
38255
  let atomHbond = {};
@@ -38213,7 +38314,8 @@ class Saltbridge {
38213
38314
  residueHash[chain_resi] = 1;
38214
38315
  residueHash[chain_resi2] = 1;
38215
38316
 
38216
- let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name;
38317
+ let serialList = (atomHbond[j].name.indexOf('pi') == 0 && atomHbond[j].ring) ? atomHbond[j].ring.join(',') : atomHbond[j].serial;
38318
+ let residName = atomHbond[j].resn + ' $' + atomHbond[j].structure + '.' + atomHbond[j].chain + ':' + atomHbond[j].resi + '@' + atomHbond[j].name + ' ' + serialList;
38217
38319
 
38218
38320
  //if(ic.resid2Residhash[oriResidName][residName] === undefined || ic.resid2Residhash[oriResidName][residName] > dist) {
38219
38321
  ic.resid2Residhash[oriResidName][residName] = dist.toFixed(1);
@@ -38224,12 +38326,12 @@ class Saltbridge {
38224
38326
  if(!bInternal) {
38225
38327
  if(ic.resids2inter[resids] === undefined) ic.resids2inter[resids] = {};
38226
38328
  if(ic.resids2inter[resids]['ionic'] === undefined) ic.resids2inter[resids]['ionic'] = {};
38227
- ic.resids2inter[resids]['ionic'][oriResidName + ',' + residName] = dist.toFixed(1);
38329
+ ic.resids2inter[resids]['ionic'][oriResidName + '|' + residName] = dist.toFixed(1);
38228
38330
  }
38229
38331
 
38230
38332
  if(ic.resids2interAll[resids] === undefined) ic.resids2interAll[resids] = {};
38231
38333
  if(ic.resids2interAll[resids]['ionic'] === undefined) ic.resids2interAll[resids]['ionic'] = {};
38232
- ic.resids2interAll[resids]['ionic'][oriResidName + ',' + residName] = dist.toFixed(1);
38334
+ ic.resids2interAll[resids]['ionic'][oriResidName + '|' + residName] = dist.toFixed(1);
38233
38335
 
38234
38336
  } // end of for (let j in atomHbond) {
38235
38337
  }
@@ -49614,20 +49716,9 @@ class LineGraph {
49614
49716
  } else {
49615
49717
  linestrokewidth = (link.n == 1) ? 2 : 4;
49616
49718
  }
49617
- let strokecolor;
49618
- if(link.v == me.htmlCls.hbondValue) {
49619
- strokecolor = "#" + me.htmlCls.hbondColor;
49620
- } else if(link.v == me.htmlCls.ionicValue) {
49621
- strokecolor = "#" + me.htmlCls.ionicColor;
49622
- } else if(link.v == me.htmlCls.halogenValue) {
49623
- strokecolor = "#" + me.htmlCls.halogenColor;
49624
- } else if(link.v == me.htmlCls.picationValue) {
49625
- strokecolor = "#" + me.htmlCls.picationColor;
49626
- } else if(link.v == me.htmlCls.pistackingValue) {
49627
- strokecolor = "#" + me.htmlCls.pistackingColor;
49628
- } else if(link.v == me.htmlCls.contactValue) {
49629
- strokecolor = "#" + me.htmlCls.contactColor;
49630
- }
49719
+
49720
+ let strokecolor = this.getStrokecolor(link.v);
49721
+
49631
49722
  html += "<g class='icn3d-interaction' resid1='" + resid1 + "' resid2='" + resid2 + "' >";
49632
49723
  let interactStr = (link.n == 1) ? 'Interaction' : link.n + ' interactions';
49633
49724
  if(link.n > 1) html += "<title>" + interactStr + " of residue " + node1.id + " with residue " + node2.id + "</title>";
@@ -49690,6 +49781,44 @@ class LineGraph {
49690
49781
  return html;
49691
49782
  }
49692
49783
 
49784
+ getStrokecolor(value, type) { let ic = this.icn3d, me = ic.icn3dui;
49785
+ let strokecolor = "#000";
49786
+
49787
+ if(value) {
49788
+ if(value == me.htmlCls.hbondValue) {
49789
+ strokecolor = "#" + me.htmlCls.hbondColor;
49790
+ } else if(value == me.htmlCls.ionicValue) {
49791
+ strokecolor = "#" + me.htmlCls.ionicColor;
49792
+ } else if(value == me.htmlCls.halogenValue) {
49793
+ strokecolor = "#" + me.htmlCls.halogenColor;
49794
+ } else if(value == me.htmlCls.picationValue) {
49795
+ strokecolor = "#" + me.htmlCls.picationColor;
49796
+ } else if(value == me.htmlCls.pistackingValue) {
49797
+ strokecolor = "#" + me.htmlCls.pistackingColor;
49798
+ } else if(value == me.htmlCls.contactValue) {
49799
+ strokecolor = "#" + me.htmlCls.contactColor;
49800
+ }
49801
+ }
49802
+
49803
+ if(type) {
49804
+ if(type == 'hbond') {
49805
+ strokecolor = "#" + me.htmlCls.hbondColor;
49806
+ } else if(type == 'ionic') {
49807
+ strokecolor = "#" + me.htmlCls.ionicColor;
49808
+ } else if(type == 'halogen') {
49809
+ strokecolor = "#" + me.htmlCls.halogenColor;
49810
+ } else if(type == 'pi-cation') {
49811
+ strokecolor = "#" + me.htmlCls.picationColor;
49812
+ } else if(type == 'pi-stacking') {
49813
+ strokecolor = "#" + me.htmlCls.pistackingColor;
49814
+ } else if(type == 'contact') {
49815
+ strokecolor = "#" + me.htmlCls.contactColor;
49816
+ }
49817
+ }
49818
+
49819
+ return strokecolor;
49820
+ }
49821
+
49693
49822
  drawOnePairNode(link, node1, node2, node2posSet1, node2posSet2, bContactMap, bAfMap) { let ic = this.icn3d, me = ic.icn3dui;
49694
49823
  let html = '';
49695
49824
 
@@ -49705,20 +49834,7 @@ class LineGraph {
49705
49834
  let pos2 = node2posSet2[node2.id];
49706
49835
  if(pos1 === undefined || pos2 === undefined) return html;
49707
49836
 
49708
- let strokecolor;
49709
- if(link.v == me.htmlCls.hbondValue) {
49710
- strokecolor = "#" + me.htmlCls.hbondColor;
49711
- } else if(link.v == me.htmlCls.ionicValue) {
49712
- strokecolor = "#" + me.htmlCls.ionicColor;
49713
- } else if(link.v == me.htmlCls.halogenValue) {
49714
- strokecolor = "#" + me.htmlCls.halogenColor;
49715
- } else if(link.v == me.htmlCls.picationValue) {
49716
- strokecolor = "#" + me.htmlCls.picationColor;
49717
- } else if(link.v == me.htmlCls.pistackingValue) {
49718
- strokecolor = "#" + me.htmlCls.pistackingColor;
49719
- } else if(link.v == me.htmlCls.contactValue) {
49720
- strokecolor = "#" + me.htmlCls.contactColor;
49721
- }
49837
+ let strokecolor = this.getStrokecolor(link.v);
49722
49838
 
49723
49839
  if(bContactMap) strokecolor = "#" + link.c;
49724
49840
 
@@ -50298,6 +50414,10 @@ class GetGraph {
50298
50414
  convertLabel2Resid(residLabel) {var ic = this.icn3d; ic.icn3dui;
50299
50415
  //ASN $1KQ2.A:6@ND2
50300
50416
  //or ASN $1KQ2.A:6
50417
+ // or ASN $1KQ2.A:6@ND2 1234
50418
+ let idArray = residLabel.split(' ');
50419
+ residLabel = (idArray.length == 2) ? residLabel : residLabel.substr(0, residLabel.lastIndexOf(' '));
50420
+
50301
50421
  residLabel.indexOf(' ');
50302
50422
  let pos2Tmp = residLabel.indexOf('@');
50303
50423
  let pos2 =(pos2Tmp !== -1) ? pos2Tmp : residLabel.length;
@@ -50332,6 +50452,25 @@ class ShowInter {
50332
50452
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atoms);
50333
50453
  ic.dAtoms = me.hashUtilsCls.unionHash(ic.dAtoms, atoms2);
50334
50454
 
50455
+ if(type == 'ligplot') {
50456
+ let residueHash1 = ic.firstAtomObjCls.getResiduesFromAtoms(atoms);
50457
+ let residueHash2 = ic.firstAtomObjCls.getResiduesFromAtoms(atoms2);
50458
+
50459
+ if(Object.keys(residueHash1).length > 1 && Object.keys(residueHash2).length > 1) {
50460
+ var aaa = 1; //alert("Please select one ligand or residue as one of the interaction sets...");
50461
+ return;
50462
+ }
50463
+
50464
+ // switch the sets to make the first set as the ligand
50465
+ if(Object.keys(residueHash1).length < Object.keys(residueHash2).length) {
50466
+ nameArray2 = $("#" + ic.pre + "atomsCustomHbond").val();
50467
+ nameArray = $("#" + ic.pre + "atomsCustomHbond2").val();
50468
+
50469
+ atoms = ic.definedSetsCls.getAtomsFromNameArray(nameArray);
50470
+ atoms2 = ic.definedSetsCls.getAtomsFromNameArray(nameArray2);
50471
+ }
50472
+ }
50473
+
50335
50474
  if(nameArray2.length == 0) {
50336
50475
  var aaa = 1; //alert("Please select the first set");
50337
50476
  }
@@ -50375,6 +50514,9 @@ class ShowInter {
50375
50514
  else if(type == 'scatterplot') {
50376
50515
  me.htmlCls.clickMenuCls.setLogCmd("scatterplot interaction pairs | " + tmpStr, true);
50377
50516
  }
50517
+ else if(type == 'ligplot') {
50518
+ me.htmlCls.clickMenuCls.setLogCmd("ligplot interaction pairs | " + tmpStr, true);
50519
+ }
50378
50520
  else if(type == 'graph') { // force-directed graph
50379
50521
  let dist_ss = parseInt($("#" + ic.pre + "dist_ss").val());
50380
50522
  let dist_coil = parseInt($("#" + ic.pre + "dist_coil").val());
@@ -51063,6 +51205,9 @@ class ViewInterPairs {
51063
51205
  let svgHtml = ic.lineGraphCls.drawLineGraph(ic.graphStr, true);
51064
51206
  $("#" + ic.pre + "scatterplotDiv").html(svgHtml);
51065
51207
  }
51208
+ else if(type == 'ligplot') {
51209
+ await ic.ligplotCls.drawLigplot(atomSet1);
51210
+ }
51066
51211
  else if(bContactMapLocal) {
51067
51212
  me.htmlCls.dialogCls.openDlg('dl_contactmap', 'Show contact map');
51068
51213
  let bAnyAtom = true;
@@ -51152,7 +51297,9 @@ class ViewInterPairs {
51152
51297
  }
51153
51298
  }
51154
51299
 
51155
- getAllInteractionTable(type) { let ic = this.icn3d, me = ic.icn3dui;
51300
+ getAllInteractionTable(type, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d, me = ic.icn3dui;
51301
+ let svgHtmlNode = '', svgHtmlLine = '';
51302
+
51156
51303
  let bondCnt = [];
51157
51304
 
51158
51305
  let residsArray = Object.keys(ic.resids2inter);
@@ -51191,41 +51338,54 @@ class ViewInterPairs {
51191
51338
  }
51192
51339
  let labels2dist, result;
51193
51340
  labels2dist = ic.resids2inter[resids]['hbond'];
51194
- result = this.getInteractionPairDetails(labels2dist, type, 'hbond');
51341
+ result = this.getInteractionPairDetails(labels2dist, type, 'hbond', index2xy, xlen, ylen, xcenter, ycenter);
51195
51342
  strHbond += result.html;
51196
51343
  cntHbond += result.cnt;
51344
+ svgHtmlNode += result.svgHtmlNode;
51345
+ svgHtmlLine += result.svgHtmlLine;
51197
51346
  if(result.cnt > 0) residname2List += residname2 + ":hbond_" + result.cnt + " ";
51198
51347
 
51199
51348
  labels2dist = ic.resids2inter[resids]['ionic'];
51200
- result = this.getInteractionPairDetails(labels2dist, type, 'ionic');
51349
+ result = this.getInteractionPairDetails(labels2dist, type, 'ionic', index2xy, xlen, ylen, xcenter, ycenter);
51201
51350
  strIonic += result.html;
51202
51351
  cntIonic += result.cnt;
51352
+ svgHtmlNode += result.svgHtmlNode;
51353
+ svgHtmlLine += result.svgHtmlLine;
51203
51354
  if(result.cnt > 0) residname2List += residname2 + ":ionic_" + result.cnt + " ";
51204
51355
 
51205
- labels2dist = ic.resids2inter[resids]['contact'];
51206
- result = this.getContactPairDetails(labels2dist, type, 'contact');
51207
- strContact += result.html;
51208
- cntContact += result.cnt;
51209
- if(result.cnt > 0) residname2List += residname2 + ":contact_" + result.cnt + " ";
51210
-
51211
51356
  labels2dist = ic.resids2inter[resids]['halogen'];
51212
- result = this.getInteractionPairDetails(labels2dist, type, 'halogen');
51357
+ result = this.getInteractionPairDetails(labels2dist, type, 'halogen', index2xy, xlen, ylen, xcenter, ycenter);
51213
51358
  strHalegen += result.html;
51214
51359
  cntHalegen += result.cnt;
51360
+ svgHtmlNode += result.svgHtmlNode;
51361
+ svgHtmlLine += result.svgHtmlLine;
51215
51362
  if(result.cnt > 0) residname2List += residname2 + ":halogen_" + result.cnt + " ";
51216
51363
 
51217
51364
  labels2dist = ic.resids2inter[resids]['pi-cation'];
51218
- result = this.getInteractionPairDetails(labels2dist, type, 'pi-cation');
51365
+ result = this.getInteractionPairDetails(labels2dist, type, 'pi-cation', index2xy, xlen, ylen, xcenter, ycenter);
51219
51366
  strPication += result.html;
51220
51367
  cntPication += result.cnt;
51368
+ svgHtmlNode += result.svgHtmlNode;
51369
+ svgHtmlLine += result.svgHtmlLine;
51221
51370
  if(result.cnt > 0) residname2List += residname2 + ":pi-cation_" + result.cnt + " ";
51222
51371
 
51223
51372
  labels2dist = ic.resids2inter[resids]['pi-stacking'];
51224
- result = this.getInteractionPairDetails(labels2dist, type, 'pi-stacking');
51373
+ result = this.getInteractionPairDetails(labels2dist, type, 'pi-stacking', index2xy, xlen, ylen, xcenter, ycenter);
51225
51374
  strPistacking += result.html;
51226
51375
  cntPistacking += result.cnt;
51376
+ svgHtmlNode += result.svgHtmlNode;
51377
+ svgHtmlLine += result.svgHtmlLine;
51227
51378
  if(result.cnt > 0) residname2List += residname2 + ":pi-stacking_" + result.cnt + " ";
51228
51379
 
51380
+ // put contact as the last one since contact will use the same node as other interactions in ligand-protein interactoin
51381
+ labels2dist = ic.resids2inter[resids]['contact'];
51382
+ result = this.getContactPairDetails(labels2dist, type, 'contact', index2xy, xlen, ylen, xcenter, ycenter);
51383
+ strContact += result.html;
51384
+ cntContact += result.cnt;
51385
+ svgHtmlNode += result.svgHtmlNode;
51386
+ svgHtmlLine += result.svgHtmlLine;
51387
+ if(result.cnt > 0) residname2List += residname2 + ":contact_" + result.cnt + " ";
51388
+
51229
51389
  prevResidname1 = residname1;
51230
51390
  prevIds = ids;
51231
51391
  }
@@ -51253,7 +51413,7 @@ class ViewInterPairs {
51253
51413
  html += tmpText;
51254
51414
  html += '</tbody></table><br/>';
51255
51415
  }
51256
- return {html: html, bondCnt: bondCnt};
51416
+ return {html: html, bondCnt: bondCnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine};
51257
51417
  }
51258
51418
  getInteractionPerResidue(prevIds, strHbond, strIonic, strContact, strHalegen, strPication, strPistacking,
51259
51419
  cntHbond, cntIonic, cntContact, cntHalegen, cntPication, cntPistacking) { let ic = this.icn3d; ic.icn3dui;
@@ -51268,15 +51428,24 @@ class ViewInterPairs {
51268
51428
  tmpText += '</tr>';
51269
51429
  return tmpText;
51270
51430
  }
51271
- getInteractionPairDetails(labels2dist, type, interactionType) { let ic = this.icn3d; ic.icn3dui;
51272
- let tmpText = '', cnt = 0;
51431
+ getInteractionPairDetails(labels2dist, type, interactionType, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d; ic.icn3dui;
51432
+ let svgHtmlNode = '', svgHtmlLine = '', tmpText = '', cnt = 0;
51273
51433
  let colorText1 = ' <span style="background-color:#';
51274
51434
  let colorText2 = '">&nbsp;&nbsp;&nbsp;</span>';
51275
51435
  if(labels2dist !== undefined) {
51436
+ if(!ic.resid2cnt) ic.resid2cnt = {};
51437
+ if(!ic.resid2ToXy) ic.resid2ToXy = {};
51438
+ if(!ic.nodeid2lineid) ic.nodeid2lineid = {};
51276
51439
  for(let labels in labels2dist) {
51277
- let resid1_resid2 = labels.split(',');
51278
- let resid1 =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51279
- let resid2 =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51440
+ let resid1_resid2 = labels.split('|');
51441
+ let resid1Ori =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51442
+ let resid2Ori =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51443
+ //resid1: MET $3GVU.A:364@N 1234
51444
+ let pos1 = resid1Ori.lastIndexOf(' ');
51445
+ let pos2 = resid2Ori.lastIndexOf(' ');
51446
+ let resid1 = resid1Ori.substr(0, pos1);
51447
+ let resid2 = resid2Ori.substr(0, pos2);
51448
+
51280
51449
  let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
51281
51450
  let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
51282
51451
  let color1 = (atom1.color) ? atom1.color.getHexString() : '';
@@ -51288,38 +51457,125 @@ class ViewInterPairs {
51288
51457
  tmpText += '<td align="center"><button class="' + ic.pre + 'selres" resid="' + resid1 + '|' + resid2 + '">Highlight</button></td>';
51289
51458
  tmpText += '</tr>';
51290
51459
  ++cnt;
51460
+
51461
+ if(index2xy) {
51462
+ let serialArray1 = resid1Ori.substr(pos1 + 1).split(',');
51463
+
51464
+ let result = ic.ligplotCls.getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter);
51465
+ svgHtmlNode += result.node;
51466
+ svgHtmlLine += result.line;
51467
+ }
51291
51468
  }
51292
51469
  }
51293
- return {html: tmpText, cnt: cnt}
51470
+ return {html: tmpText, cnt: cnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine}
51294
51471
  }
51295
- getContactPairDetails(labels2dist, type) { let ic = this.icn3d; ic.icn3dui;
51296
- let tmpText = '', cnt = 0;
51472
+
51473
+ getContactPairDetails(labels2dist, type, interactionType, index2xy, xlen, ylen, xcenter, ycenter) { let ic = this.icn3d; ic.icn3dui;
51474
+ let svgHtmlNode = '', svgHtmlLine = '', tmpText = '', cnt = 0;
51297
51475
  let colorText1 = ' <span style="background-color:#';
51298
51476
  let colorText2 = '">&nbsp;&nbsp;&nbsp;</span>';
51299
51477
  if(labels2dist !== undefined) {
51478
+ let resids2distCnt = {};
51479
+ if(!ic.resid2cnt) ic.resid2cnt = {};
51480
+ if(!ic.resid2ToXy) ic.resid2ToXy = {};
51481
+ if(!ic.nodeid2lineid) ic.nodeid2lineid = {};
51300
51482
  for(let labels in labels2dist) {
51301
- let resid1_resid2 = labels.split(',');
51302
- let resid1 =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51303
- let resid2 =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51483
+ let resid1_resid2 = labels.split('|');
51484
+ let resid1Ori =(type == 'save1') ? resid1_resid2[0] : resid1_resid2[1];
51485
+ let resid2Ori =(type == 'save1') ? resid1_resid2[1] : resid1_resid2[0];
51486
+ //resid1: MET $3GVU.A:364 1234
51487
+ let pos1 = resid1Ori.lastIndexOf(' ');
51488
+ let pos2 = resid2Ori.lastIndexOf(' ');
51489
+
51490
+ let serialArray1 = resid1Ori.substr(pos1 + 1).split(',');
51491
+ let resid1 = resid1Ori.substr(0, pos1);
51492
+ if(index2xy) {
51493
+ // add atom name to resid1
51494
+ resid1 += '@' + ic.atoms[serialArray1[0]].name;
51495
+ }
51496
+
51497
+ let resid2 = resid2Ori.substr(0, pos2);
51498
+ let resids = resid1 + '|' + resid2;
51499
+
51500
+ let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
51501
+ ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
51502
+ // let color1 = (atom1.color) ? atom1.color.getHexString() : '';
51503
+ let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
51504
+ ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
51505
+ // let color2 = (atom2.color) ? atom2.color.getHexString() : '';
51506
+ let dist1_dist2_atom1_atom2 = labels2dist[labels].split('_');
51507
+ let dist1 = parseFloat(dist1_dist2_atom1_atom2[0]);
51508
+ // let dist2 = parseFloat(dist1_dist2_atom1_atom2[1]);
51509
+ // let atom1Name = dist1_dist2_atom1_atom2[2];
51510
+ // let atom2Name = dist1_dist2_atom1_atom2[3];
51511
+ let contactCnt = parseInt(dist1_dist2_atom1_atom2[4]);
51512
+ if(!resids2distCnt.hasOwnProperty(resids)) {
51513
+ resids2distCnt[resids] = {'dist1': dist1, 'dist1_dist2_atom1_atom2': dist1_dist2_atom1_atom2, 'cnt': contactCnt, 'serialArray1': serialArray1};
51514
+ }
51515
+ else {
51516
+ resids2distCnt[resids].cnt += contactCnt;
51517
+ if(dist1 < resids2distCnt[resids].dist1) {
51518
+ resids2distCnt[resids].dist1 = dist1;
51519
+ resids2distCnt[resids].dist1_dist2_atom1_atom2 = dist1_dist2_atom1_atom2;
51520
+ resids2distCnt[resids].serialArray1 = serialArray1;
51521
+ }
51522
+ }
51523
+ }
51524
+
51525
+ let resid2ToResid1 = {};
51526
+ for(let resids in resids2distCnt) {
51527
+ let resid1_resid2 = resids.split('|');
51528
+ let resid1 = resid1_resid2[0];
51529
+ let resid2 = resid1_resid2[1];
51530
+
51531
+ if(!resid2ToResid1.hasOwnProperty(resid2)) {
51532
+ resid2ToResid1[resid2] = [resid1];
51533
+ }
51534
+ else {
51535
+ resid2ToResid1[resid2].push(resid1);
51536
+ }
51537
+
51304
51538
  let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
51305
51539
  let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
51306
51540
  let color1 = (atom1.color) ? atom1.color.getHexString() : '';
51307
51541
  let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
51308
51542
  let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
51309
51543
  let color2 = (atom2.color) ? atom2.color.getHexString() : '';
51310
- let dist1_dist2_atom1_atom2 = labels2dist[labels].split('_');
51544
+ let dist1_dist2_atom1_atom2 = resids2distCnt[resids].dist1_dist2_atom1_atom2;
51311
51545
  let dist1 = dist1_dist2_atom1_atom2[0];
51312
51546
  let dist2 = dist1_dist2_atom1_atom2[1];
51313
51547
  let atom1Name = dist1_dist2_atom1_atom2[2];
51314
51548
  let atom2Name = dist1_dist2_atom1_atom2[3];
51315
- let contactCnt = dist1_dist2_atom1_atom2[4];
51549
+ let contactCnt = 1; //resids2distCnt[resids].cnt;
51550
+
51316
51551
  tmpText += '<tr><td><span style="white-space:nowrap"><input type="checkbox" class="' + ic.pre + 'seloneres" id="' + ic.pre + 'inter2_' + cnt + 'a" resid="' + resid1 + '"/> ' + resid1 + '@' + atom1Name + colorText1 + color1 + colorText2 + '</span></td><td><span style="white-space:nowrap"><input type="checkbox" class="' + ic.pre + 'seloneres" id="' + ic.pre + 'inter2_' + cnt + 'b" resid="' + resid2 + '"/> ' + resid2 + '@' + atom2Name + colorText1 + color2 + colorText2 + '</span></td><td align="center">' + contactCnt + '</td><td align="center">' + dist1 + '</td><td align="center">' + dist2 + '</td>';
51317
51552
  tmpText += '<td align="center"><button class="' + ic.pre + 'selres" resid="' + resid1 + '|' + resid2 + '">Highlight</button></td>';
51318
51553
  tmpText += '</tr>';
51319
51554
  cnt += parseInt(contactCnt);
51320
51555
  }
51556
+
51557
+ if(index2xy) {
51558
+ for(let resid2 in resid2ToResid1) {
51559
+ let resid1Array = resid2ToResid1[resid2];
51560
+ let prevX2, prevY2;
51561
+ for(let i = 0, il = resid1Array.length; i < il; ++i) {
51562
+ let resid1 = resid1Array[i];
51563
+ let resids = resid1 + '|' + resid2;
51564
+
51565
+ let serialArray1 = resids2distCnt[resids].serialArray1;
51566
+
51567
+ let bNotDrawNode = (i == 0) ? false : true;
51568
+ let result = ic.ligplotCls.getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter, bNotDrawNode, prevX2, prevY2);
51569
+ svgHtmlNode += result.node;
51570
+ svgHtmlLine += result.line;
51571
+ prevX2 = result.x2;
51572
+ prevY2 = result.y2;
51573
+ }
51574
+ }
51575
+ }
51321
51576
  }
51322
- return {html: tmpText, cnt: cnt}
51577
+
51578
+ return {html: tmpText, cnt: cnt, svgHtmlNode: svgHtmlNode, svgHtmlLine: svgHtmlLine};
51323
51579
  }
51324
51580
 
51325
51581
  //Export the list of residues in some chain interacting with residues in another chain.
@@ -52727,8 +52983,8 @@ class ChainalignParser {
52727
52983
  let chain_t = idArray[3];
52728
52984
  let chainid_t = mmdbid_t + '_' + chain_t;
52729
52985
 
52730
- let atomSet_t = (me.cfg.resrange) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[0].split(','), chainid_t).hAtoms : ic.chains[chainid_t];
52731
- let atomSet_q = (me.cfg.resrange) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[index].split(','), chainid_q).hAtoms : ic.chains[chainid_q];
52986
+ let atomSet_t = (resRangeArray[0]) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[0].split(','), chainid_t).hAtoms : ic.chains[chainid_t];
52987
+ let atomSet_q = (resRangeArray[index]) ? ic.realignParserCls.getSeqCoorResid(resRangeArray[index].split(','), chainid_q).hAtoms : ic.chains[chainid_q];
52732
52988
  // end of original version =============
52733
52989
 
52734
52990
  /*
@@ -55386,6 +55642,22 @@ class MmdbParser {
55386
55642
  hAtoms = ic.loadAtomDataCls.loadAtomDataIn(data, pdbid, 'mmdbid', undefined, type, chainid, chainIndex, bLastQuery, bNoTransformNoSeqalign);
55387
55643
  }
55388
55644
 
55645
+ // show ligand-protein interaction
55646
+ if(me.cfg.ligand) { // sid123059722
55647
+ for(let chainid in ic.chainid2sid) {
55648
+ if(ic.chainid2sid[chainid] == me.cfg.ligand.substr(3)) {
55649
+ // save a set named me.cfg.ligand
55650
+ let residueHash = ic.firstAtomObjCls.getResiduesFromAtoms(ic.chains[chainid]);
55651
+ let idArray = Object.keys(residueHash)[0].split('_');
55652
+ let select = '.' + idArray[1] + ':' + idArray[2];
55653
+
55654
+ await ic.selByCommCls.selectByCommand(select, me.cfg.ligand, me.cfg.ligand);
55655
+ break;
55656
+ }
55657
+ }
55658
+ }
55659
+ ic.hAtoms = hAtoms;
55660
+
55389
55661
  // set 3d domains
55390
55662
  let structure = data.pdbId;
55391
55663
 
@@ -65973,6 +66245,7 @@ class ApplyCommand {
65973
66245
  || commandOri.indexOf('save2 interaction pairs') == 0
65974
66246
  || commandOri.indexOf('line graph interaction pairs') == 0
65975
66247
  || commandOri.indexOf('scatterplot interaction pairs') == 0
66248
+ || commandOri.indexOf('ligplot interaction pairs') == 0
65976
66249
  ) {
65977
66250
  let paraArray = commandOri.split(' | ');
65978
66251
  if(paraArray.length >= 3) {
@@ -66030,6 +66303,9 @@ class ApplyCommand {
66030
66303
  else if(commandOri.indexOf('scatterplot interaction pairs') == 0) {
66031
66304
  type = 'scatterplot';
66032
66305
  }
66306
+ else if(commandOri.indexOf('ligplot interaction pairs') == 0) {
66307
+ type = 'ligplot';
66308
+ }
66033
66309
 
66034
66310
  await ic.viewInterPairsCls.viewInteractionPairs(nameArray2, nameArray, bHbondCalc, type, bHbond, bSaltbridge, bInteraction, bHalogen, bPication, bPistacking);
66035
66311
  }
@@ -66089,6 +66365,14 @@ class ApplyCommand {
66089
66365
 
66090
66366
  $("#" + me.scatterplotid).attr("width",(ic.scatterplotWidth * parseFloat(scale)).toString() + "px");
66091
66367
  }
66368
+ else if(command.indexOf('ligplot scale') == 0) {
66369
+ let pos = command.lastIndexOf(' ');
66370
+ let scale = command.substr(pos + 1);
66371
+
66372
+ $("#" + me.ligplotid + "_scale").val(scale);
66373
+
66374
+ $("#" + me.ligplotid).attr("width",(ic.ligplotWidth * parseFloat(scale)).toString() + "px");
66375
+ }
66092
66376
  else if(command.indexOf('contactmap scale') == 0) {
66093
66377
  let pos = command.lastIndexOf(' ');
66094
66378
  let scale = command.substr(pos + 1);
@@ -66742,6 +67026,7 @@ class ApplyCommand {
66742
67026
  else if(cmd.indexOf('save2 interaction pairs') == 0) return hbondIntStr + ': "Set 2" button';
66743
67027
  else if(cmd.indexOf('line graph interaction pairs') == 0) return hbondIntStr + ': "2D Interaction Network" button';
66744
67028
  else if(cmd.indexOf('scatterplot interaction pairs') == 0) return hbondIntStr + ': "2D Interaction Map" button';
67029
+ else if(cmd.indexOf('ligplot interaction pairs') == 0) return hbondIntStr + ': "2D Interaction for One Ligand/Residue" button';
66745
67030
  else if(cmd.indexOf('graph label') == 0) return forceStr + ': "Label Size" menu';
66746
67031
  else if(cmd.indexOf('graph force') == 0) return forceStr + ': "Force on Nodes" menu';
66747
67032
  else if(cmd.indexOf('hide edges') == 0) return forceStr + ': "Internal Edges" menu';
@@ -75299,6 +75584,12 @@ class Diagram2d {
75299
75584
  thisClass.clickNode(this);
75300
75585
  });
75301
75586
 
75587
+ $(document).on("click", "#" + ic.pre + "dl_ligplot .icn3d-node", function(e) { thisClass.icn3d;
75588
+ e.stopImmediatePropagation();
75589
+
75590
+ thisClass.clickNode(this);
75591
+ });
75592
+
75302
75593
  //$("#" + ic.pre + "dl_linegraph .icn3d-interaction", "click", function(e) { let ic = this.icn3d, me = ic.icn3dui;
75303
75594
  $(document).on("click", "#" + ic.pre + "dl_linegraph .icn3d-interaction", function(e) { let ic = thisClass.icn3d;
75304
75595
  e.stopImmediatePropagation();
@@ -75381,6 +75672,8 @@ class Diagram2d {
75381
75672
  let strokeWidth = 2;
75382
75673
  $(node).find('circle').attr('stroke', me.htmlCls.ORANGE);
75383
75674
  $(node).find('circle').attr('stroke-width', strokeWidth);
75675
+ $(node).find('rect').attr('stroke', me.htmlCls.ORANGE);
75676
+ $(node).find('rect').attr('stroke-width', strokeWidth);
75384
75677
 
75385
75678
  ic.hAtoms = me.hashUtilsCls.unionHash(ic.hAtoms, ic.residues[resid]);
75386
75679
 
@@ -76498,6 +76791,364 @@ class Cartoon2d {
76498
76791
  }
76499
76792
  }
76500
76793
 
76794
+ /**
76795
+ * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
76796
+ */
76797
+
76798
+ class Ligplot {
76799
+ constructor(icn3d) {
76800
+ this.icn3d = icn3d;
76801
+ }
76802
+
76803
+ async drawLigplot(atomSet1) { let ic = this.icn3d, me = ic.icn3dui;
76804
+ me.htmlCls.dialogCls.openDlg('dl_ligplot', 'Show ligand interactions with atom details');
76805
+
76806
+ let widthOri, heightOri, width = 100, height = 100;
76807
+ ic.len4ang = 80;
76808
+
76809
+ // get SVG from backend
76810
+ let pdbStr = ic.saveFileCls.getAtomPDB(atomSet1);
76811
+ pdbStr = pdbStr.trim();
76812
+ pdbStr = pdbStr.replace(/\n\n/g, '\n'); // remove empty lines
76813
+
76814
+ let dataObj = {'pdb2svg': pdbStr};
76815
+ let url = me.htmlCls.baseUrl + "openbabel/openbabel.cgi";
76816
+ let dataStr = await me.getAjaxPostPromise(url, dataObj, undefined, undefined, undefined, undefined, 'text');
76817
+
76818
+ let lineArray = dataStr.split('\n');
76819
+ let lineSvg = '', nodeSvg = '', index2xy = {};
76820
+ let xsum = 0, ysum = 0, cnt = 0;
76821
+ ic.svgGridSize = ic.len4ang; // make the scg into many grids to tell whether the grid is empty, 30 is about bond length (1.5 angstrom)
76822
+ ic.gridXY2used = {};
76823
+ for(let i = 0, il = lineArray.length; i < il; ++i) {
76824
+ let line = lineArray[i];
76825
+ if(line.indexOf('<svg width') == 0) {
76826
+ //<svg width="100" height="100" x="0" y="0" viewBox="0 0 634.256 380"
76827
+ // get real width and height
76828
+ let start = line.indexOf('viewBox="') + 9;
76829
+ let linePart = line.substr(start);
76830
+ let viewbox = linePart.substr(0, linePart.indexOf('"'));
76831
+ let viewboxArray = viewbox.split(' ');
76832
+ widthOri = parseFloat(viewboxArray[2]);
76833
+ heightOri = parseFloat(viewboxArray[3]);
76834
+ width = widthOri + 2*ic.len4ang;
76835
+ height = heightOri + 2*ic.len4ang;
76836
+ }
76837
+ else if(line.indexOf('<line') == 0) {
76838
+ lineSvg += line + '\n';
76839
+ }
76840
+ else if(line.indexOf('<text') == 0) {
76841
+ if(line.indexOf('font-size="12"') != -1) {
76842
+ // index node
76843
+ //<text x="40.000000" y="120.000000" fill="rgb(255,0,0)" stroke-width="0" font-weight="bold" font-size="12" >1</text>
76844
+ let start = line.indexOf('>') + 1;
76845
+ let indexPart = line.substr(start);
76846
+ let index = parseInt(indexPart.substr(0, indexPart.indexOf('<')));
76847
+
76848
+ start = line.indexOf('x="') + 3;
76849
+ let xPart = line.substr(start);
76850
+ let x = parseFloat(xPart.substr(0, xPart.indexOf('"')));
76851
+
76852
+ start = line.indexOf('y="') + 3;
76853
+ let yPart = line.substr(start);
76854
+ let y = parseFloat(yPart.substr(0, yPart.indexOf('"')));
76855
+
76856
+ index2xy[index] = {"x": x, "y": y};
76857
+ let xGrid = parseInt(x / ic.svgGridSize);
76858
+ let yGrid = parseInt(y / ic.svgGridSize);
76859
+ ic.gridXY2used[xGrid + '_' + yGrid] = 1;
76860
+
76861
+ xsum += x;
76862
+ ysum += y;
76863
+ ++cnt;
76864
+ }
76865
+ else { // font-size > 12
76866
+ nodeSvg += line + '\n';
76867
+ }
76868
+ }
76869
+ else if(line.indexOf('</svg>') == 0) {
76870
+ break;
76871
+ }
76872
+ }
76873
+
76874
+ let xcenter = xsum / cnt, ycenter = ysum / cnt;
76875
+
76876
+ let id = me.ligplotid;
76877
+ ic.ligplotWidth = width;
76878
+ let graphWidth = ic.ligplotWidth;
76879
+
76880
+ let textHeight = 30;
76881
+ let heightAll = height + textHeight;
76882
+
76883
+ let offset = - ic.len4ang;
76884
+ let svgHtml = "<svg id='" + id + "' viewBox='" + offset + "," + offset + "," + width + "," + heightAll + "' width='" + graphWidth + "px' font-family='sans-serif' stroke='rgb(0,0,0)' stroke-width='2' stroke-linecap='round'>";
76885
+
76886
+ let xlen = parseInt(widthOri / ic.svgGridSize), ylen = parseInt(heightOri / ic.svgGridSize);
76887
+ let result = ic.viewInterPairsCls.getAllInteractionTable("save1", index2xy, xlen, ylen, xcenter, ycenter); // sort on the ligand/set1
76888
+ ic.bLigplot = true;
76889
+
76890
+ svgHtml += lineSvg + result.svgHtmlLine;
76891
+
76892
+ svgHtml += nodeSvg + result.svgHtmlNode;
76893
+
76894
+ svgHtml += "</svg>";
76895
+
76896
+ $("#" + ic.pre + "ligplotDiv").html(svgHtml);
76897
+
76898
+ this.setEventsForLigplot();
76899
+ }
76900
+
76901
+
76902
+ getSvgPerPair(serialArray1, resid1, resid2, interactionType, index2xy, xlen, ylen, xcenter, ycenter, bNotDrawNode, prevX2, prevY2) { let ic = this.icn3d, me = ic.icn3dui;
76903
+ let xOffset = 1, yOffset = -1;
76904
+ let bondLen = (interactionType == 'hbond' || interactionType == 'contact' || interactionType == 'halogen') ? ic.len4ang : ic.len4ang * 1.5; // real distance should be bout 120, not 80
76905
+ let shortBondLen = ic.len4ang / 2;
76906
+ let strokeWidth = (interactionType == 'contact') ? 1 : 2;
76907
+
76908
+ let resid1Real = ic.getGraphCls.convertLabel2Resid(resid1);
76909
+ let atom1 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid1Real]);
76910
+ let resid2Real = ic.getGraphCls.convertLabel2Resid(resid2);
76911
+ let atom2 = ic.firstAtomObjCls.getFirstAtomObj(ic.residues[resid2Real]);
76912
+
76913
+ let xSum = 0, ySum = 0, cntPoint = 0;
76914
+ let baseSerial = atom1.serial;
76915
+ for(let i = 0, il = serialArray1.length; i < il; ++i) {
76916
+ let index = serialArray1[i] - baseSerial + 1;
76917
+ xSum += index2xy[index].x;
76918
+ ySum += index2xy[index].y;
76919
+ ++cntPoint;
76920
+ }
76921
+
76922
+ let x1 = xSum / cntPoint - xOffset;
76923
+ let y1 = ySum / cntPoint - yOffset;
76924
+
76925
+ if(!ic.resid2cnt.hasOwnProperty(resid1)) {
76926
+ ic.resid2cnt[resid1] = 0;
76927
+ }
76928
+ else {
76929
+ ++ic.resid2cnt[resid1];
76930
+ }
76931
+
76932
+ let x2, y2, angle;
76933
+ if(!bNotDrawNode && !ic.resid2ToXy.hasOwnProperty(resid2Real)) {
76934
+ // 1st and ideal way to find a position. If failed, use the 2nd way
76935
+ let xGrid = parseInt(x1 / ic.svgGridSize);
76936
+ let yGrid = parseInt(y1 / ic.svgGridSize);
76937
+ let gridArray = [];
76938
+ for(let i = 1; i >= -1; --i) { // try right-bottom first
76939
+ for(let j = 1; j >= -1; --j) {
76940
+ if(!(i == 0 && j == 0)) {
76941
+ if(xGrid + i >= 0 && xGrid + i <= xlen && yGrid + j >= 0 && yGrid + j <= ylen) gridArray.push((xGrid + i) + '_' + (yGrid + j));
76942
+ }
76943
+ }
76944
+ }
76945
+ for(let i = 2; i >= -2; --i) { // try right-bottom first
76946
+ for(let j = 2; j >= -2; --j) {
76947
+ if(!(i >= -1 && i <= 1 && j >= -1 && j <= 1 )) {
76948
+ if(xGrid + i >= 0 && xGrid + i <= xlen && yGrid + j >= 0 && yGrid + j <= ylen) gridArray.push((xGrid + i) + '_' + (yGrid + j));
76949
+ }
76950
+ }
76951
+ }
76952
+
76953
+ let bFound = false, xyGrids;
76954
+ for(let i = 0, il = gridArray.length; i < il; ++i) {
76955
+ if(!ic.gridXY2used[gridArray[i]]) { // found a spot to put the residue
76956
+ xyGrids = gridArray[i].split('_');
76957
+ x2 = (parseInt(xyGrids[0]) + 0.5) * ic.svgGridSize;
76958
+ y2 = (parseInt(xyGrids[1]) + 0.5) * ic.svgGridSize;
76959
+
76960
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
76961
+ let x2b = bondLen / dist * (x2 - x1) + x1;
76962
+ let y2b = bondLen / dist * (y2 - y1) + y1;
76963
+ x2 = x2b;
76964
+ y2 = y2b;
76965
+
76966
+ ic.gridXY2used[gridArray[i]] = 1;
76967
+ bFound = true;
76968
+ break;
76969
+ }
76970
+ }
76971
+
76972
+ if(!bFound) {
76973
+ // 2nd way to find a position from the center to the outside
76974
+ let dx = x1 - xcenter;
76975
+ let dy = y1 - ycenter;
76976
+
76977
+ let baseAngle = 0;
76978
+ if(Math.abs(dx) > Math.abs(dy)) { // extend along x-axis
76979
+ if(dx > 0) { // +x direction
76980
+ baseAngle = 0;
76981
+ }
76982
+ else { // -x direction
76983
+ baseAngle = 180;
76984
+ }
76985
+ }
76986
+ else { // extend along y-axis
76987
+ if(dy > 0) { // +y direction
76988
+ baseAngle = 90;
76989
+ }
76990
+ else { // -y direction
76991
+ baseAngle = 270;
76992
+ }
76993
+ }
76994
+ angle = baseAngle - 10 + ic.resid2cnt[resid1] * 30;
76995
+
76996
+ x2 = x1 + bondLen * Math.cos(angle * Math.PI/180);
76997
+ y2 = y1 + bondLen * Math.sin(angle * Math.PI/180);
76998
+ }
76999
+ }
77000
+
77001
+ let oneLetterRes = me.utilsCls.residueName2Abbr(atom2.resn.substr(0, 3));
77002
+ let resName2 = oneLetterRes + atom2.resi;
77003
+ let textColor2 = (atom2.color) ? atom2.color.getHexString() : '000';
77004
+ let lineColor = ic.lineGraphCls.getStrokecolor(undefined, interactionType);
77005
+
77006
+ // let node = '<circle cx="' + x2 + '" cy="' + y2 + '" r="8" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2 + '"></circle>\n<text x="' + x2 + '" y="' + y2 + '" stroke="#000" stroke-width="1px" text-anchor="middle" alignment-baseline="central" font-size="8px">' + resName2 + '</text>';
77007
+
77008
+ let node = '', line = '';
77009
+
77010
+ // id can't contain comma and thus use '-'
77011
+ // sometimes the same ligand atom is used in both Hbond and contact. THus we add "interactionType"
77012
+ let idpair = resid2Real + '--' + serialArray1.join('-') + interactionType;
77013
+
77014
+ let id = resid2Real;
77015
+ if(bNotDrawNode || ic.resid2ToXy.hasOwnProperty(id)) {
77016
+ x2 = (ic.resid2ToXy.hasOwnProperty(id)) ? ic.resid2ToXy[id].x2 : prevX2;
77017
+ y2 = (ic.resid2ToXy.hasOwnProperty(id)) ? ic.resid2ToXy[id].y2 : prevY2;
77018
+
77019
+ // draw a short line from x2, y2 to x1, y1 with the distance shortBondLen
77020
+ let x1b = x1, y1b = y1, bShort = 0;
77021
+ if(interactionType == 'contact') {
77022
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
77023
+ if(shortBondLen < dist) {
77024
+ x1b = shortBondLen / dist * (x1 - x2) + x2;
77025
+ y1b = shortBondLen / dist * (y1 - y2) + y2;
77026
+ bShort = 1;
77027
+ }
77028
+ }
77029
+
77030
+ line += '<line id="' + idpair + '" x1="' + x1b.toFixed(2) + '" y1="' + y1b.toFixed(2) + '" x2="' + x2.toFixed(2) + '" y2="' + y2.toFixed(2) + '" x0="' + x1.toFixed(2) + '" y0="' + y1.toFixed(2) + '" short="' + bShort + '" opacity="1.0" stroke="' + lineColor + '" stroke-width="' + strokeWidth + '" stroke-dasharray="5,5"/>\n';
77031
+ }
77032
+ else {
77033
+ node +='<g>';
77034
+ node += '<title>' + resName2 + '</title>';
77035
+ // node += '<circle class='icn3d-ctnode' cx="' + x2.toFixed(2) + '" cy="' + y2.toFixed(2) + '" r="10" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2Real + '"/>';
77036
+ let boxWidth = 28, boxHeight = 14;
77037
+ node += '<rect id="' + id + '_node" x="' + (x2 - boxWidth*0.5).toFixed(2) + '" y="' + (y2 - boxHeight*0.5).toFixed(2) + '" width="' + boxWidth + '" height="' + boxHeight + '" rx="2" ry="2" fill="#' + textColor2 + '" stroke-width="1" stroke="' + textColor2 + '" resid="' + resid2Real + '"/>';
77038
+
77039
+ node += '<text class="icn3d-ctnode" resid="' + id + '" id="' + id + '" x="' + x2.toFixed(2) + '" y="' + y2.toFixed(2) + '" fill="#000" stroke="none" text-anchor="middle" alignment-baseline="central" style="font-size:10px">' + resName2 + '</text>';
77040
+ node += '</g>\n';
77041
+
77042
+ line += '<line id="' + idpair + '" x1="' + x1.toFixed(2) + '" y1="' + y1.toFixed(2) + '" x2="' + x2.toFixed(2) + '" y2="' + y2.toFixed(2) + '" opacity="1.0" stroke="' + lineColor + '" stroke-width="' + strokeWidth + '" stroke-dasharray="5,5"/>\n';
77043
+
77044
+ if(interactionType != 'contact') {
77045
+ if(!ic.resid2ToXy.hasOwnProperty(resid2Real)) ic.resid2ToXy[resid2Real] = {x2: x2, y2: y2};
77046
+ }
77047
+ }
77048
+
77049
+ if(!ic.nodeid2lineid.hasOwnProperty(id)) ic.nodeid2lineid[id] = [];
77050
+ ic.nodeid2lineid[id].push(idpair);
77051
+
77052
+ return {node: node, line: line, x2: x2, y2: y2};
77053
+ }
77054
+
77055
+ setEventsForLigplot() { let ic = this.icn3d, me = ic.icn3dui;
77056
+ //https://stackoverflow.com/questions/1108480/svg-draggable-using-jquery-and-jquery-svg
77057
+ $("#" + me.ligplotid + " .icn3d-ctnode")
77058
+ .draggable({
77059
+ start: function( e, ui ) {
77060
+ let oriX= parseFloat(e.target.getAttribute('x'));
77061
+ let oriY = parseFloat(e.target.getAttribute('y'));
77062
+
77063
+ e.target.setAttribute('x', oriX);
77064
+ e.target.setAttribute('y', oriY);
77065
+ },
77066
+ drag: function( e, ui ) {
77067
+ let offsetX = $("#" + me.ligplotid).offset().left + ic.len4ang; // ic.len4ang was defined in svg viewbox
77068
+ let offsetY = $("#" + me.ligplotid).offset().top + ic.len4ang;
77069
+
77070
+ let id = e.target.getAttribute('resid');
77071
+ let x = (e.clientX - offsetX);
77072
+ let y = (e.clientY - offsetY);
77073
+
77074
+ let oriX = parseFloat(e.target.getAttribute('x'));
77075
+ let oriY = parseFloat(e.target.getAttribute('y'));
77076
+
77077
+ // change for each step
77078
+ let dx = (x - oriX) / ic.resizeRatioX;
77079
+ let dy = (y - oriY) / ic.resizeRatioY;
77080
+
77081
+ // move the text label
77082
+ oriX = parseFloat($("#" + id + "_node").attr('x'));
77083
+ oriY = parseFloat($("#" + id + "_node").attr('y'));
77084
+
77085
+ $("#" + id + "_node").attr('x', oriX + dx);
77086
+ $("#" + id + "_node").attr('y', oriY + dy);
77087
+
77088
+ // update the center
77089
+ e.target.setAttribute('x', x);
77090
+ e.target.setAttribute('y', y);
77091
+
77092
+ // update the edges
77093
+ if(ic.nodeid2lineid[id]) {
77094
+ for(let i = 0, il = ic.nodeid2lineid[id].length; i < il; ++i) {
77095
+ let idpair = ic.nodeid2lineid[id][i];
77096
+
77097
+ updateEdges(idpair, id);
77098
+ }
77099
+ }
77100
+
77101
+ function updateEdges(idpair, id) {
77102
+ if(idpair && idpair.indexOf(id) != -1) {
77103
+ let idArray = idpair.split('--');
77104
+ if(idArray.length == 2) {
77105
+ let id2;
77106
+ id2 = idArray[0];
77107
+
77108
+ let x2 = parseFloat($("#" + id2).attr('x'));
77109
+ let y2 = parseFloat($("#" + id2).attr('y'));
77110
+
77111
+ $("#" + idpair).attr('x2', x2);
77112
+ $("#" + idpair).attr('y2', y2);
77113
+
77114
+ let x1 = $("#" + idpair).attr('x1');
77115
+ let y1 = $("#" + idpair).attr('y1');
77116
+ let x1b = x1, y1b = y1;
77117
+
77118
+ let bShort = parseInt($("#" + idpair).attr('short'));
77119
+ if(bShort) { // adjust x1,y1
77120
+ x1 = $("#" + idpair).attr('x0');
77121
+ y1 = $("#" + idpair).attr('y0');
77122
+
77123
+ let dist = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
77124
+ let shortBondLen = ic.len4ang / 2;
77125
+
77126
+ if(shortBondLen < dist) {
77127
+ x1b = shortBondLen / dist * (x1 - x2) + x2;
77128
+ y1b = shortBondLen / dist * (y1 - y2) + y2;
77129
+ }
77130
+ }
77131
+
77132
+ $("#" + idpair).attr('x1', x1b);
77133
+ $("#" + idpair).attr('y1', y1b);
77134
+ }
77135
+ } // if
77136
+ } // function
77137
+ }
77138
+ });
77139
+ }
77140
+
77141
+ clickLigplot() { let ic = this.icn3d; ic.icn3dui;
77142
+ let thisClass = this;
77143
+
77144
+ $(document).on("click", "#" + ic.pre + "dl_ligplot .icn3d-ctnode", function(e) { let ic = thisClass.icn3d;
77145
+ e.stopImmediatePropagation();
77146
+
77147
+ ic.diagram2dCls.clickNode(this);
77148
+ });
77149
+ }
77150
+ }
77151
+
76501
77152
  /**
76502
77153
  * @author Jiyao Wang <wangjiy@ncbi.nlm.nih.gov> / https://github.com/ncbi/icn3d
76503
77154
  */
@@ -77181,7 +77832,7 @@ class SaveFile {
77181
77832
  }
77182
77833
  }
77183
77834
 
77184
- saveSvg(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
77835
+ saveSvg(id, filename, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
77185
77836
  if(me.bNode) return '';
77186
77837
 
77187
77838
  let width = $("#" + id).width();
@@ -77189,19 +77840,26 @@ class SaveFile {
77189
77840
 
77190
77841
  if(bContactmap) height = width;
77191
77842
 
77192
- let svgXml = this.getSvgXml(id, width, height, bContactmap);
77843
+ if(bLigplot) {
77844
+ width += ic.len4ang;
77845
+ height += ic.len4ang;
77846
+ }
77847
+
77848
+ let svgXml = this.getSvgXml(id, width, height, bContactmap, bLigplot);
77193
77849
 
77194
77850
  let blob = new Blob([svgXml], {type: "image/svg+xml"});
77195
77851
  saveAs(blob, filename);
77196
77852
  }
77197
77853
 
77198
- getSvgXml(id, width, height, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
77854
+ getSvgXml(id, width, height, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
77199
77855
  if(me.bNode) return '';
77200
77856
 
77201
77857
  // font is not good
77202
77858
  let svg_data = document.getElementById(id).innerHTML; //put id of your svg element here
77203
77859
 
77204
- let viewbox = (width && height) ? "<svg viewBox=\"0 0 " + width + " " + height + "\"" : "<svg";
77860
+ let startX = (bLigplot) ? -30 : 0;
77861
+ let startY = (bLigplot) ? -30 : 0;
77862
+ let viewbox = (width && height) ? "<svg viewBox=\"" + startX + " " + startY + " " + width + " " + height + "\"" : "<svg";
77205
77863
  //let head = viewbox + " title=\"graph\" version=\"1.1\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
77206
77864
  let head = viewbox + " title=\"graph\" xmlns:xl=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
77207
77865
 
@@ -77213,7 +77871,7 @@ class SaveFile {
77213
77871
  return full_svg;
77214
77872
  }
77215
77873
 
77216
- savePng(id, filename, bContactmap) { let ic = this.icn3d, me = ic.icn3dui;
77874
+ savePng(id, filename, bContactmap, bLigplot) { let ic = this.icn3d, me = ic.icn3dui;
77217
77875
  if(me.bNode) return '';
77218
77876
 
77219
77877
  let width = $("#" + id).width();
@@ -77226,7 +77884,7 @@ class SaveFile {
77226
77884
  let bbox = svg.getBBox();
77227
77885
 
77228
77886
  let copy = svg.cloneNode(true);
77229
- ic.lineGraphCls.copyStylesInline(copy, svg);
77887
+ if(!bLigplot) ic.lineGraphCls.copyStylesInline(copy, svg);
77230
77888
  let canvas = document.createElement("CANVAS");
77231
77889
  canvas.width = width;
77232
77890
  canvas.height = height;
@@ -81019,6 +81677,7 @@ class iCn3D {
81019
81677
  this.shareLinkCls = new ShareLink(this);
81020
81678
  this.diagram2dCls = new Diagram2d(this);
81021
81679
  this.cartoon2dCls = new Cartoon2d(this);
81680
+ this.ligplotCls = new Ligplot(this);
81022
81681
 
81023
81682
  this.rayCls = new Ray(this);
81024
81683
  this.controlCls = new Control(this);
@@ -81245,7 +81904,7 @@ class iCn3DUI {
81245
81904
  //even when multiple iCn3D viewers are shown together.
81246
81905
  this.pre = this.cfg.divid + "_";
81247
81906
 
81248
- this.REVISION = '3.33.3';
81907
+ this.REVISION = '3.34.0';
81249
81908
 
81250
81909
  // In nodejs, iCn3D defines "window = {navigator: {}}"
81251
81910
  this.bNode = (Object.keys(window).length < 2) ? true : false;
@@ -81688,7 +82347,8 @@ iCn3DUI.prototype.show3DStructure = async function(pdbStr) { let me = this;
81688
82347
 
81689
82348
  ic.bChainAlign = true;
81690
82349
  ic.inputid = me.cfg.chainalign;
81691
- ic.loadCmd = 'load chainalignment ' + me.cfg.chainalign + ' | resnum ' + me.cfg.resnum + ' | resdef ' + me.cfg.resdef + ' | aligntool ' + me.cfg.aligntool + ' | parameters ' + me.cfg.inpara + ' | resrange ' + me.cfg.resrange;
82350
+ let resrangeStr = (me.cfg.resrange) ? ' | resrange ' + me.cfg.resrange : '';
82351
+ ic.loadCmd = 'load chainalignment ' + me.cfg.chainalign + ' | resnum ' + me.cfg.resnum + ' | resdef ' + me.cfg.resdef + ' | aligntool ' + me.cfg.aligntool + ' | parameters ' + me.cfg.inpara + resrangeStr;
81692
82352
  me.htmlCls.clickMenuCls.setLogCmd(ic.loadCmd, true);
81693
82353
  await ic.chainalignParserCls.downloadChainalignment(me.cfg.chainalign);
81694
82354
  }