Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add open dashboard menu item #176

Merged
merged 3 commits into from
Jun 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ Please see [here](https://github.com/hrntsm/Tunny/releases) for the data release
### Added

- Support Human-in-the-loop optimization
- Input FishPrint into the objective to start it.
- Add 2 sample gh file.
- Input FishPrint into the objective to start it
- Add 2 sample gh file
- Support CMA-ES with Margin
- It allows for more efficient optimization in mixed integer problems.
- Open optuna dashboard menu item

### Changed

Expand Down
10 changes: 0 additions & 10 deletions Tunny/TunnyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,4 @@ public class Tunny : GH_AssemblyInfo
public override string AuthorContact => "contact@hrntsm.com";
public override GH_LibraryLicense License => GH_LibraryLicense.opensource;
}

public class TunnyCategoryIcon : GH_AssemblyPriority
{
public override GH_LoadingInstruction PriorityLoad()
{
Grasshopper.Instances.ComponentServer.AddCategoryIcon("Tunny", Resource.TunnyIcon);
Grasshopper.Instances.ComponentServer.AddCategorySymbolName("Tunny", 'T');
return GH_LoadingInstruction.Proceed;
}
}
}
149 changes: 149 additions & 0 deletions Tunny/UI/LoadingInstruction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

using Grasshopper.GUI;
using Grasshopper.GUI.Canvas;
using Grasshopper.Kernel;

using Tunny.Resources;
using Tunny.Settings;
using Tunny.Util;

namespace Tunny.UI
{
public class LoadingInstruction : GH_AssemblyPriority, IDisposable
{
private ToolStripMenuItem _optunaDashboardToolStripMenuItem;

public override GH_LoadingInstruction PriorityLoad()
{
Grasshopper.Instances.ComponentServer.AddCategoryIcon("Tunny", Resource.TunnyIcon);
Grasshopper.Instances.ComponentServer.AddCategorySymbolName("Tunny", 'T');
Grasshopper.Instances.CanvasCreated += RegisterTunnyMenuItems;
return GH_LoadingInstruction.Proceed;
}

void RegisterTunnyMenuItems(GH_Canvas canvas)
{
Grasshopper.Instances.CanvasCreated -= RegisterTunnyMenuItems;

GH_DocumentEditor docEditor = Grasshopper.Instances.DocumentEditor;
if (docEditor != null)
{
SetupTunnyMenu(docEditor);
}
}
private void SetupTunnyMenu(GH_DocumentEditor docEditor)
{
ToolStripMenuItem tunnyToolStripMenuItem;
tunnyToolStripMenuItem = new ToolStripMenuItem();

docEditor.MainMenuStrip.SuspendLayout();

docEditor.MainMenuStrip.Items.AddRange(new ToolStripItem[] {
tunnyToolStripMenuItem
});

tunnyToolStripMenuItem.DropDownItems.AddRange(TunnyMenuItems.ToArray());
tunnyToolStripMenuItem.Name = "TunnyToolStripMenuItem";
tunnyToolStripMenuItem.Size = new Size(125, 29);
tunnyToolStripMenuItem.Text = "Tunny";

docEditor.MainMenuStrip.ResumeLayout(false);
docEditor.MainMenuStrip.PerformLayout();

GH_DocumentEditor.AggregateShortcutMenuItems += GH_DocumentEditor_AggregateShortcutMenuItems;
}

void GH_DocumentEditor_AggregateShortcutMenuItems(object sender, GH_MenuShortcutEventArgs e)
{
e.AppendItem(_optunaDashboardToolStripMenuItem);
}

private List<ToolStripMenuItem> TunnyMenuItems
{
get
{
var list = new List<ToolStripMenuItem>();

_optunaDashboardToolStripMenuItem = new ToolStripMenuItem
{
Name = "OptunaDashboardToolStripMenuItem",
Size = new Size(265, 30),
Text = "Run optuna-dashboard",
};
_optunaDashboardToolStripMenuItem.Click += OptunaDashboardToolStripMenuItem_Click;

list.Add(_optunaDashboardToolStripMenuItem);
return list;
}
}

private void OptunaDashboardToolStripMenuItem_Click(object sender, EventArgs e)
{
string componentFolder = Path.GetDirectoryName(Grasshopper.Instances.ComponentServer.FindObjectByName("Tunny", true, true).Location);

string pythonDirectory = componentFolder + "/python-3.10.0-embed-amd64";
string dashboardPath = pythonDirectory + "/Scripts/optuna-dashboard.exe";

if (!Directory.Exists(pythonDirectory) && !File.Exists(dashboardPath))
{
TunnyMessageBox.Show("optuna-dashboard is not installed.\nFirst install optuna-dashboard from the Tunny component.",
"optuna-dashboard is not installed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
else
{
RunOptunaDashboard(componentFolder, dashboardPath);
}
}

private static void RunOptunaDashboard(string componentFolder, string dashboardPath)
{
string settingsPath = componentFolder + @"\Settings.json";
string storagePath = string.Empty;
if (File.Exists(settingsPath))
{
var settings = TunnySettings.Deserialize(File.ReadAllText(settingsPath));
storagePath = settings.Storage.Path;
}
var ofd = new OpenFileDialog
{
FileName = Path.GetFileName(storagePath),
Filter = @"Journal Storage(*.log)|*.log|SQLite Storage(*.db,*.sqlite)|*.db;*.sqlite",
Title = @"Set Tunny result file path",
};
if (ofd.ShowDialog() == DialogResult.OK)
{
storagePath = GetStorageArgument(ofd.FileName);
DashboardHandler.RunDashboardProcess(dashboardPath, storagePath);
}
}

private static string GetStorageArgument(string path)
{
switch (Path.GetExtension(path))
{
case null:
return string.Empty;
case ".sqlite3":
case ".db":
return @"sqlite:///" + $"\"{path}\"";
case ".log":
return $"\"{path}\"";
default:
throw new NotImplementedException();
}
}

public void Dispose()
{
_optunaDashboardToolStripMenuItem.Dispose();
GC.SuppressFinalize(this);
}
}
}
26 changes: 1 addition & 25 deletions Tunny/UI/OptimizeWindowTab/VisualizeTab.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

Expand All @@ -20,30 +19,7 @@ private void DashboardButton_Click(object sender, EventArgs e)
return;
}

CheckExistDashboardProcess();
var dashboard = new Process();
dashboard.StartInfo.FileName = PythonInstaller.GetEmbeddedPythonPath() + @"\Scripts\optuna-dashboard.exe";
dashboard.StartInfo.Arguments = _settings.Storage.GetOptunaStorageCommandLinePathByExtension();
dashboard.StartInfo.UseShellExecute = false;
dashboard.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
dashboard.Start();

var browser = new Process();
browser.StartInfo.FileName = @"http://127.0.0.1:8080/";
browser.StartInfo.UseShellExecute = true;
browser.Start();
}

private static void CheckExistDashboardProcess()
{
Process[] dashboardProcess = Process.GetProcessesByName("optuna-dashboard");
if (dashboardProcess.Length > 0)
{
foreach (Process p in dashboardProcess)
{
p.Kill();
}
}
DashboardHandler.RunDashboardProcess(PythonInstaller.GetEmbeddedPythonPath() + @"\Scripts\optuna-dashboard.exe", _settings.Storage.GetOptunaStorageCommandLinePathByExtension());
}

private void VisualizeTargetStudy_Changed(object sender, EventArgs e)
Expand Down
35 changes: 35 additions & 0 deletions Tunny/Util/DashboardHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Diagnostics;

namespace Tunny.Util
{
public static class DashboardHandler
{
public static void RunDashboardProcess(string dashboardPath, string storageArgument)
{
CheckExistDashboardProcess();
var dashboard = new Process();
dashboard.StartInfo.FileName = dashboardPath;
dashboard.StartInfo.Arguments = storageArgument;
dashboard.StartInfo.UseShellExecute = false;
dashboard.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
dashboard.Start();

var browser = new Process();
browser.StartInfo.FileName = @"http://127.0.0.1:8080/";
browser.StartInfo.UseShellExecute = true;
browser.Start();
}

private static void CheckExistDashboardProcess()
{
Process[] dashboardProcess = Process.GetProcessesByName("optuna-dashboard");
if (dashboardProcess.Length > 0)
{
foreach (Process p in dashboardProcess)
{
p.Kill();
}
}
}
}
}