anise icon indicating copy to clipboard operation
anise copied to clipboard

Reporting and analysis GUI

Open ChristopherRabotin opened this issue 8 months ago • 1 comments

High level description

The ANISE GUI should be revamped to support #466 .

Design ideas

Notes:

  • Closing a specific file is inconvenient in ANISE because the unloading happens with variable lifespan, not with a map.

----------------------------------
     |Load file|       | Tab: Info | Tab: Analysis
----------------------------------
de440s.bsp            x
myephem.bsp           x
earth_high_prec.bpc   x

In the info tab, display the data from only the currently selected file ... this causes another problem with the unloading. To only display data from one specific file, I'd need to either know which of the files is being queried and its index in the array of SPK/BPC files ... or I need to reload the almanac for each of the entries, plus one for all of them for the analysis (makes it complicated).

The analysis tab would have an expression builder panel, the evaluation (results) panel, and the event building panel. The evaluation panel should allow toggling between table display and graph display. If it's a graph, the first version of this GUI should display everything on the same plot. For event evaluation, the graph would not be available at all, only a table is available. Using egui_autocomplete, one could write out the LISP of the expression and its event evaluator. All of the panels would be displayed with egui_dock. The LISP can be saved to disk. The table of the results can be saved to disk as well, both in CSV and Parquet.

Finally, the CLI should also support the LISP parsing, and report creating from command line, e.g. anise-cli analysis -e my_expression.lisp -f de440.bsp,ephem.bsp -o report.csv

ChristopherRabotin avatar Jun 26 '25 03:06 ChristopherRabotin

Excellent question. This is where the choice of language directly influences the entire user experience. You're right, a Lisp-based DSL naturally suggests a visual "node-and-wire" graph, because its structure is a free-form tree of nested functions.

However, a Dhall-based DSL inspires a different, more structured, and arguably more user-friendly GUI for non-programmers. Because Dhall is based on typed records, unions, and lists, the GUI can be thought of less like a blank canvas for nodes and more like an intelligent, interactive "Report Builder" or a highly advanced form.

Let's design a potential GUI for your Dhall-based astrodynamics DSL.

The Core Philosophy: "Guided Construction," Not Blank-Canvas Programming

The GUI should be built around the Dhall schema. The schema tells the GUI exactly what fields, options, and data types are allowed at every step. This prevents errors and guides the user toward a valid report.

A powerful layout would be a three-panel design:

  1. Toolbox (Left Panel): A palette of all the available building blocks defined in your schema (Tasks, Data Sources, Filters, etc.).
  2. Builder (Center Panel): The main canvas where the user assembles the report. This will look more like a structured document than a node graph.
  3. Property Inspector (Right Panel): A context-sensitive panel that displays the fields for the block currently selected in the Builder.

GUI Mockup and Workflow

Let's walk through how your users would build their reports in this GUI.

The Main Interface

+--------------------------------+--------------------------------------+--------------------------------+
| TOOLBOX                        | REPORT BUILDER                       | PROPERTY INSPECTOR             |
|                                |                                      |                                |
| ▼ Tasks                        |  +--------------------------------+  | ⏹️ Task: FindEvents           |
|   [ 📄 Report Elements ]       |  | ▼ Task: Find Events            |  |                                |
|   [ ✨ Find Events ]           |  |   Frame: [ myCustomFrame  ]    |  | Frame:       [ 🔘 myCustomFrame ] |
|   [ ☀️ Eclipsing Durations ]   |  |   Condition: (Greater Than)    |  | Condition:   [ Greater Than > ]|
|                                |  |   Report: ["time", "sma"]      |  |   Column:    [ "sma"          ] |
| ▼ Data Sources                 |  +--------------------------------+  |   Value:     [ 500.0          ] |
|   [ ⏰ Time Range ]            |                                      |                                |
|   [ 🆔 NAIF ID ]               |                                      | Report:      [ List<String> + ]|
|                                |  +--------------------------------+  |              [ > "time"       ] |
| ▼ Filters                      |  | ▼ Data Source: Time Range      |  |              [ > "sma"        ] |
|   [ > Greater Than ]           |  |   Start: 2024-01-01T00:00:00Z  |  |                                |
|   [ < Less Than ]              |  |   End:   2024-02-01T00:00:00Z  |  |                                |
|   [ & AND ]                    |  |   Step:  12h                   |  |                                |
|                                |  +--------------------------------+  |                                |
|--------------------------------+--------------------------------------+--------------------------------|
| WORKSPACE (Variables)                                                                                  |
|  [ 🔵 myCustomFrame ]  [ ➕ Add New... ]                                                                 |
+--------------------------------------------------------------------------------------------------------+

Building Your Examples

Example 1: Simple Report

  1. User drags "Report Elements" from the Toolbox into the Builder.
  2. The Property Inspector immediately updates, showing the fields for this task: source and elements.
  3. The source field is of type DataSource. The GUI displays a dropdown menu labeled "Select Source...". The user selects "Time Range".
  4. The Inspector reveals the fields for TimeRange: start, end, and step. The user fills them in.
  5. The elements field is a List(Text). The GUI provides a simple list editor where the user clicks + to add the strings "sma", "ecc", and "inc".

Behind the Scenes: The GUI is constructing this Dhall record: { source = DataSource.TimeRange::{...}, task = Task.ReportElements { elements = [...] } }

Example 2: Custom Frame and Event Finding (The Power of this GUI)

This is where the structured approach shines.

  1. Define the Frame: The user needs to define myCustomFrame. They go to the Workspace panel at the bottom and click "Add New...".
  2. They name it myCustomFrame. The GUI now asks for its definition.
  3. The user drags "Custom Frame" from the Toolbox into the variable's value area.
  4. The Inspector shows the fields for a Custom frame: origin, boresight, and crosstrack.
  5. For the boresight field, the user drags "Axis Of" from the Toolbox. The Inspector updates, asking for the frame and axis vector, which the user provides.
  6. This is the "node-and-wire" part, but more structured: For the crosstrack field, the user drags "Cross Product". The Inspector shows two input slots: v1 and v2. The user can now drag the boresight definition they just created into the v1 slot.
  7. Build the Report: Now that myCustomFrame exists as a reusable component in the Workspace, the user drags "Find Events" into the main Builder.
  8. The Inspector asks for a Frame. The user simply drags the myCustomFrame variable from the Workspace and drops it onto the Frame slot in the Inspector.
  9. For the Condition, they drag a "Greater Than" filter from the Toolbox and configure its column ("sma") and value (500.0) in the Inspector.

Behind the Scenes: The GUI constructs the Dhall let bindings and references. let myCustomFrame = ... in { task = Task.FindEvents::{ frame = myCustomFrame, ... } }

Example 3: High-Level Task

This becomes trivial.

  1. User drags "Eclipsing Durations" from the Toolbox into the Builder.
  2. The Inspector shows the required fields: observer, frame, eclipsingBody.
  3. The user also needs a data source, so they drag "NAIF ID" into the Data Source area of the Builder and set the id to -85 in the Inspector.

Why This GUI is a Good Fit for Dhall

  • Schema-Driven: Every menu, field, and dropdown is populated directly from your Dhall schema. If you add a new filter, it automatically appears in the Toolbox.
  • Type-Safe: The GUI won't let a user drag a Filter into a field that expects a Frame. It enforces correctness visually.
  • Reduced "Spaghetti": Instead of hundreds of wires, connections are made by assigning variables or defining nested structures in the Inspector. This keeps the main Builder area clean and focused on the high-level steps of the report.
  • Clear Separation of Concerns: The Toolbox shows what's possible, the Builder shows the report structure, the Inspector shows the details, and the Workspace shows reusable components.

While the Lisp "node-and-wire" model is powerful for representing pure algorithms, the Dhall "structured builder" model is superior for a user-facing DSL where safety, clarity, and guided construction are paramount.

ChristopherRabotin avatar Jul 01 '25 16:07 ChristopherRabotin