Skip to content
Draft
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
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [py312]
environment: [py312, py313, py314]
steps:
- uses: actions/checkout@v6
- uses: prefix-dev/setup-pixi@v0.9.5
Expand All @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [py311, py312, py313]
environment: [py312, py313, py314]
steps:
- uses: actions/checkout@v6
- uses: prefix-dev/setup-pixi@v0.9.5
Expand Down
68 changes: 2 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,3 @@
# UPSTAGE
# upstage_des

UPSTAGE is a **U**niversal **P**latform for **S**imulating
**T**asks and **A**ctors with **G**raphs and **E**vents built atop
[__`SimPy 4`__][simpy-repo].

## ✨ Try it in your browser ✨

➡️ **https://gtri.github.io/upstage/demo**

## What is UPSTAGE for?

__UPSTAGE__ is a Python framework for creating robust, behavior-driven Discrete Event Simulations (DES). The primary goal of UPSTAGE is to enable the quick creation of simulations at any desired level of abstraction with built-in data recording, simulation integrity and runtime checks, and assistance for the usual pitfalls in custom discrete-event simulation: interrupts and cancellations. It is designed is to simplify the development process for simulation models of *complex systems of systems*.

__UPSTAGE__ leverages the extensible [__`SimPy`__][simpy-docs] library and adds two concepts to accelerate the generation of complex discrete-event simulations.

1. `Actor` - i.e., an entity that has `State`
2. `Task` - i.e., actions actors can perform and that can be organized into a `TaskNetwork`.

Actors can have multiple networks running on them, their states can be shared, and there are features for interactions between task networks running on the same actor. Those tasks modify the states on their actor, with features for real-time states that update on request without requiring time-stepping or modifying the existing events.

![image](docs/source/_static/upstage-flow.png)

Additional features include:

1. Context-aware `EnvironmentContext`, accessed via `UpstageBase`, enabling thread-safe simulation globals for the _Stage_ and _Named Entities_ (see below).
1. __Active States__ (e.g.,`LinearChangingState`) represent continuous-time attributes of actors that can be queried at discrete points in time, or trigger events when they reach a certain level.
1. Spatial-aware data types (e.g., `CartesianLocation`) and states like the waypoint-following `GeodeticLocationChangingState`.
1. Geodetic and cartesian positions, distances, and motion - with ranged sensing.
1. `NamedEntity` in a thread-safe global context, enabling easier "director" logic creation with less argument passing in your code
1. The `Stage`: a global context variable for simulation properties and attributes. This enables under-the-hood coordination of motion, geography, and other features.
1. __Rehearsal__: Write planning and simulation code in one place only, and "rehearse" an actor through a task network using planning factors to discover task feasibility before the actor attempts to complete the task.
1. All States are recordable, and some record dataclass and dictionary values
1. A `Routine` class for building reusable event behaviors to simplify `Task` coding.
1. Point-To-Point and Routing Table communications handlers.
1. Numerous runtime checks and error handling for typical DES pitfalls: based on more than a decade of custom DES-building experience.
1. And more!

See the [documentation][upstage-docs] for tutorials and details.

## Requirements

UPSTAGE only requires Python 3.11+ and Simpy 4+.

## Installation

In an environment (Python 3.11+) of your choice:

```console
pip install upstage-des
```

## Documentation

See the [documentation][upstage-docs] for tutorials and additional details.

## How do I contribute or set up a develpment environment?

See [CONTRIBUTING][contributing] for instructions on setting up an environment and contributing.

For information on how to style your code, see the [Style Guide][style-guide].

[contributing]: ./CONTRIBUTING.md
[style-guide]: ./STYLE_GUIDE.md
[simpy-docs]: https://simpy.readthedocs.io/en/latest/
[simpy-repo]: https://gitlab.com/team-simpy/simpy/
[upstage-docs]: https://gtri.github.io/upstage
This is a software library for doing discrete event simulation.
18 changes: 0 additions & 18 deletions docs/source/class_refs.txt

This file was deleted.

9 changes: 0 additions & 9 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,10 @@
"Actor": "{py:class}`Actor <upstage_des.actor.Actor>`",
"State": "{py:class}`~upstage_des.states.State`",
"Task": "{py:class}`~upstage_des.task.Task`",
"TaskNetwork": "{py:class}`~upstage_des.task_network.TaskNetwork`",
"EnvironmentContext": "{py:class}`~upstage_des.base.EnvironmentContext`",
"UpstageBase": "{py:class}`~upstage_des.base.UpstageBase`",
"NamedEntity": "{py:class}`~upstage_des.base.NamedUpstageEntity`",
"LinearChangingState": "{py:class}`~upstage_des.states.LinearChangingState`",
"CartesianLocation": "{py:class}`~upstage_des.data_types.CartesianLocation`",
"GeodeticLocationChangingState": "{py:class}`~upstage_des.states.GeodeticLocationChangingState`",
"ResourceState": "{py:class}`~upstage_des.states.ResourceState`",
"SelfMonitoringStore": "{py:class}`~upstage_des.stores.SelfMonitoringStore`",
"DecisionTask": "{py:class}`~upstage_des.task.DecisionTask`",
"Routine": "{py:class}`~upstage_des.routines.Routine`",
"PointToPoint": "{py:class}`~upstage_des.communications.comms.PointToPointCommsManager`",
"RoutingTable": "{py:class}`~upstage_des.communications.routing.RoutingTableCommsManager`",
}


Expand Down
18 changes: 0 additions & 18 deletions docs/source/demo.md

This file was deleted.

42 changes: 42 additions & 0 deletions docs/source/features/logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Logging

UPSTAGE exposes a :mod:`logging` hierarchy rooted at ``upstage_des``. The
library is silent by default — a ``NullHandler`` is attached on import and
the package logger defaults to ``WARNING``. Opt in at your application
entry point

```{code-block} python
import logging

logging.basicConfig(level=logging.INFO, format="%(name)s: %(message)s")
logging.getLogger("upstage_des").setLevel(logging.INFO)
```

Actor events go to ``upstage_des.actor.<actor.name>``.

```{code-block} python
logging.getLogger("upstage_des.actor").setLevel(logging.INFO)
# Filter only for actors with certain values in the name
logging.getLogger("upstage_des.actor").addFilter(
lambda rec: "Plane" not in rec.name
)
```

Inside a custom :class:`Task`, call ``actor.write_to_log`` with printf-style
arguments. Formatting is deferred — when the log level is disabled and
``debug_logging=False`` on the actor, the interpolation never runs, so
``repr``/``str`` cost on your arguments is avoided in hot loops.

```{code-block} python
def task(self, *, actor):
actor.write_to_log("picked up %s (qty=%d)", item, qty) # INFO
actor.write_to_log("low fuel: %.1f%%", remaining, level=logging.WARNING)
```

Two independent sinks are driven by every ``write_to_log`` call:

* The per-actor in-memory list (``actor.write_to_log()`` /
``actor.get_log()``) — controlled by the ``debug_logging`` flag set at
actor construction. Use this for post-run analysis in notebooks.
* Python's ``logging`` — controlled by the standard level hierarchy.
Use this for structured sinks (files, JSON, stdout during dev).
51 changes: 14 additions & 37 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ assistance for the usual pitfalls in custom discrete-event simulation: interrupt

UPSTAGE - which is built on the [SimPy](https://simpy.readthedocs.io/en/latest/) library - contains two primary components that are assembled to create a broad array of simulations.

The components are {{ Actor }} - which contain {{ State }} - and {{ Task }}, which can be assembled into a {{ TaskNetwork }}. Actors can have multiple networks running on them, their states can be shared, and there are features for interactions between task networks running on the same actor. Those tasks modify the states on their actor, with features for real-time states that update on request without requiring time-stepping or modifying the existing events.
The components are {{ Actor }} - which contain {{ State }} - and {{ Task }}. Actors can have multiple networks running on them, their states can be shared, and there are features for interactions between task networks running on the same actor. Those tasks modify the states on their actor, with features for real-time states that update on request without requiring time-stepping or modifying the existing events.

```{image} _static/upstage-flow.png
:align: center
Expand All @@ -16,59 +16,36 @@ Additional features include:

1. Context-aware {{ EnvironmentContext }}, accessed via {{ UpstageBase }}, enabling thread-safe simulation globals for the Stage and Named Entities (see below).
2. Active States, such as {{ LinearChangingState }} which represent continuous-time attributes of actors at discrete points.
3. Spatial-aware data types like {{ CartesianLocation }}, and states like the waypoint-following {{ GeodeticLocationChangingState }}.
4. Geodetic and cartesian positions, distances, and motion - with ranged sensing.
5. {{ NamedEntity }} in a thread-safe global context, enabling easier "director" logic creation with fewer args in your code
6. The stage: a global context variable for simulation properties and attributes. This enables under-the-hood coordination of motion, geography, and other features.
7. Rehearsal: Write planning and simulation code in one place only, and "rehearse" an actor through a task network using planning factors to discover task feasibility.
8. All States are recordable, and some record dataclass and dictionary values.
9. A {{ Routine }} class for building reusable event behaviors to simplify {{ Task }} coding.
10. {{ PointToPoint }} and {{ RoutingTable }} communications handlers
11. Numerous runtime checks and error handling for typical DES pitfalls: based on years of custom DES-building experience.
12. And more!
3. Named Entitites in a thread-safe global context, enabling easier "director" logic creation with fewer args in your code
4. The stage: a global context variable for simulation properties and attributes. This enables under-the-hood coordination of motion, geography, and other features.
5. All States are recordable, and some record dataclass and dictionary values.
6. Numerous runtime checks and error handling for typical DES pitfalls: based on years of custom DES-building experience.
7. And more!

```{note}
This project is under active development.
This project is under active development. This branch of the docs is for the unreleased version 1.0. The docs may be innacurate.
```

## Demo
## Installation from source

Try one of these demos in your browser with JupyterLite.

```{toctree}
:caption: UPSTAGE Demos
:maxdepth: 1

demo.md
```

## Installation

In a suitable Python environment (3.11+):

```console
(venv) $ pip install upstage-des
```

### Installation from source

Alternatively, you can download UPSTAGE and install it manually. Clone, or download the archive and extract it. From the extraction location (and within a suitable Python environment):
You can download UPSTAGE and install it manually. Clone, or download the archive and extract it. From the extraction location (and within a suitable Python environment):

```console
(venv) $ python -m pip install .
```

(or just `pip install .`)

## User Guide
## Features

```{toctree}
:caption: Guide
:maxdepth: 3
:caption: Features
:maxdepth: 2

user_guide/index
features/logging.md
```


## Contributing

To contribute to UPSTAGE, or to learn the steps for building documentation, running tests, and putting
Expand Down
Loading
Loading