Python API reference¶
Classes¶
pytraf.Network ¶
A road network with its link delay functions and turn table.
Links are numbered by their position in the input arrays and nodes are integers
from 0. Link delay is the BPR function
free_flow_time * (1 + b * (volume / capacity) ** power).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_nodes
|
int
|
Number of nodes; node ids are |
required |
from_node
|
NDArray[int64]
|
From-node of each link. |
required |
to_node
|
NDArray[int64]
|
To-node of each link. |
required |
free_flow_time
|
NDArray[float64]
|
Delay at zero flow, per link. |
required |
capacity
|
NDArray[float64]
|
Capacity per link; must be positive. |
required |
b
|
Optional[NDArray[float64]]
|
BPR |
None
|
power
|
Optional[NDArray[float64]]
|
BPR power per link (default 4). |
None
|
is_centroid
|
Optional[NDArray[bool_]]
|
Bool per node. A path may start or end at a centroid but never passes through it. Use for zone centroids. |
None
|
turns
|
Optional[Dict[str, NDArray[Any]]]
|
Optional turn table as a dict of arrays, with the columns |
None
|
allow_u_turns
|
bool
|
Allow immediate returns to the node a link came from. |
False
|
node_ids
property
¶
node_id of every node as written in the GMNS files (None otherwise).
link_ids
property
¶
link_id of every link; an undirected link appears twice (None otherwise).
is_centroid
property
¶
Per node: True if paths may only start or end there.
from_tables
staticmethod
¶
from_tables(
links: Any,
turns: Optional[Any] = None,
*,
num_nodes: Optional[int] = None,
is_centroid: Optional[Any] = None,
allow_u_turns: bool = False,
is_endpoint: Optional[Any] = None,
) -> Network
Builds a network from flat tables (pandas DataFrames or dicts of arrays).
links needs the columns from_node, to_node, free_flow_time and
capacity; b (default 0.15) and power (default 4) are optional.
Node ids are integers starting at 0 (num_nodes defaults to the largest id + 1).
Links get their ids from their row order, 0, 1, 2, ...
turns is optional and lists exceptions and delays by link ids. Columns:
from_link and to_link (required), banned (bool), penalty (fixed
delay, NaN = none) and delay_free_flow, delay_capacity, delay_b,
delay_power (a BPR delay on the turn's own flow; give all four or none).
Turns not listed are allowed at zero cost, except U-turns unless allow_u_turns.
Use :meth:turn_links to see which turns exist.
is_centroid marks nodes (zone centroids) that paths may start or end at but
not pass through. is_endpoint is the deprecated old name.
from_tntp
staticmethod
¶
Reads a TNTP *_net.tntp file. Node numbers become 0-based, links keep
file order and <FIRST THRU NODE> becomes the centroid mask.
from_gmns
staticmethod
¶
from_gmns(
path: str,
length_unit: Optional[str] = None,
speed_unit: Optional[str] = None,
zone_nodes_are_centroids: bool = False,
zone_nodes_are_endpoints: Optional[bool] = None,
) -> Network
Reads a GMNS dataset directory (node.csv, link.csv, optional
movement.csv and config.csv). Times are in minutes; capacity is per
link (per-lane capacity times lanes). Undirected links become two links.
length_unit (e.g. "mile", "foot", "km") and speed_unit
("mph", "kph") override config.csv and are required without it. A
movement table restricts an inbound link only if it lists a movement for it.
With zone_nodes_are_centroids zone nodes cannot be passed through.
zone_nodes_are_endpoints is the deprecated old name.
link_nodes ¶
Returns the from-node and to-node of every link.
turn_links ¶
Returns the incoming and outgoing link of every turn, indexed by turn id.
assign ¶
assign(
classes: Union[
Demand,
TrafficClass,
Sequence[Union[Demand, TrafficClass]],
],
*,
gap: float = 1e-06,
max_iter: int = 200,
order: Union[Order, str] = Order.FIXED,
seed: int = 0,
chunk_size: int = 0,
threads: Optional[int] = None,
link_preload: Optional[NDArray[float64]] = None,
turn_preload: Optional[NDArray[float64]] = None,
unreachable: Union[
Unreachable, str
] = Unreachable.ERROR,
) -> AssignResult
Finds the user equilibrium on this network by path-based gradient projection.
The same as pytraf.assign(self, classes, ...), where all the options are
described. Everything after classes is keyword-only.
pytraf.Demand ¶
Trips between nodes in long format (a zone is a node).
Repeated origin-destination pairs add up. Trips with the same origin and destination use no network and are skipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_nodes
|
int
|
Number of nodes of the network the demand is for. |
required |
origins
|
NDArray[int64]
|
Origin node of each entry. |
required |
destinations
|
NDArray[int64]
|
Destination node of each entry. |
required |
flows
|
NDArray[float64]
|
Trips per entry; non-negative. |
required |
unknown_zone_flow
property
¶
Trips dropped because their zone has no node (0 unless read with from_gmns).
from_table
staticmethod
¶
Builds the demand for network from a long-format table (a pandas
DataFrame or a dict of arrays) with columns origin, destination and
flow. Origins and destinations are node ids.
from_tntp
staticmethod
¶
Reads a TNTP *_trips.tntp file for network.
from_gmns
staticmethod
¶
from_gmns(
network: Network,
path: str,
origin: str = "o_zone_id",
destination: str = "d_zone_id",
flow: str = "volume",
skip_unknown_zones: bool = False,
) -> Demand
Reads a zone-to-zone demand CSV for a network read with Network.from_gmns.
origin, destination and flow name the columns. A zone's trips are
split equally over its nodes. Rows of zones without a node are an error unless
skip_unknown_zones, in which case they are summed in unknown_zone_flow.
pytraf.TrafficClass ¶
One traffic class: demand plus how its vehicles load and move on the network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
demand
|
Demand
|
The class's trips. |
required |
pce
|
float
|
Passenger-car units one vehicle loads on the network (cars 1.0, trucks 2.5). Link delays depend on the PCE-weighted volume. |
1.0
|
extra_link_cost
|
Optional[NDArray[float64]]
|
Extra cost per link in the same units as travel time, for example a toll divided by the class's value of time. |
None
|
allowed_links
|
Optional[NDArray[bool_]]
|
Bool per link. A turn is usable only if both its links are. |
None
|
name
|
Optional[str]
|
Label for the class in result tables (default: its position). |
None
|
Results¶
assign returns an AssignResult, which groups what it holds into the objects below.
pytraf.AssignResult ¶
The outcome of :func:pytraf.assign; build it with network.assign(...).
Attributes:
| Name | Type | Description |
|---|---|---|
converged |
bool
|
Whether the relative gap reached the requested |
iterations |
int
|
Sweeps over all origins that were run. |
relative_gap |
float
|
The relative gap at the end. |
network |
Network
|
The network the result belongs to. |
class_names |
List[str]
|
One name per class: the |
links |
Flows and times per link. |
|
turns |
Flows and times per turn. |
|
paths |
The paths and their flows. |
|
unrouted |
Demand left out by |
|
diagnostics |
Sweep gaps, phase times and the objective. |
summary ¶
A short readable account of the run: convergence, trips per class, demand left out and the busiest link.
pytraf.results.LinkResults ¶
Bases: _Elements
Flows and times per link, indexed by link id.
voc
cached
property
¶
Volume over capacity: volume plus the preload, divided by the capacity.
volume
cached
property
¶
Flow in car units (vehicles times their PCE), summed over the classes. This is what the delay functions see, without the preload.
preload
cached
property
¶
The fixed volume passed to assign, or None if there was none.
by_class
cached
property
¶
Vehicles per class. Index by position or by class name.
table ¶
One row per link as a pandas DataFrame.
Columns: link_id for GMNS networks, from_node, to_node, flow
(vehicles of all classes), flow_<class> when there are several classes,
volume (in car units), preload if one was given, voc (volume plus
preload over capacity) and time.
pytraf.results.TurnResults ¶
Bases: _Elements
Flows and times per turn, indexed by turn id (see Network.turn_links).
volume
cached
property
¶
Flow in car units (vehicles times their PCE), summed over the classes. This is what the delay functions see, without the preload.
preload
cached
property
¶
The fixed volume passed to assign, or None if there was none.
by_class
cached
property
¶
Vehicles per class. Index by position or by class name.
table ¶
One row per turn as a pandas DataFrame.
Columns: from_link, to_link, node, then the same flow, volume,
preload and time columns as the link table (no voc).
pytraf.results.ClassFlows ¶
Bases: Sequence
Vehicles per class, as one array per class.
Index by position (flows[0]) or by class name (flows["truck"]); iterate for
the arrays in class order.
pytraf.results.PathResults ¶
The paths of the final solution, with the flow and travel time of each.
arrays ¶
Every path of a class as flat arrays.
Returns origin, destination, flow and time (one entry per path),
link_offsets (one more entry) and links (all link ids back to back; the
links of path i are links[link_offsets[i]:link_offsets[i + 1]]).
Raises:
| Type | Description |
|---|---|
IndexError
|
If the class does not exist. |
table ¶
One row per path as a pandas DataFrame.
Columns: class (when there are several), origin, destination,
flow, time and links (a tuple of link ids). class_index limits it
to one class.
pytraf.results.UnroutedDemand ¶
Demand that unreachable="skip" left out because no allowed path serves it.
Empty (len(result.unrouted) == 0) when everything was routable or the
unreachable option is "error".
pytraf.results.Diagnostics
dataclass
¶
Options¶
pytraf.Order ¶
Bases: _Checked
The order in which a sweep visits the origins.
SHUFFLE
class-attribute
instance-attribute
¶
A new random order each sweep, seeded by seed.
ALTERNATE
class-attribute
instance-attribute
¶
Forwards, then backwards, on alternate sweeps.
LARGEST_GAP
class-attribute
instance-attribute
¶
Origins with the largest remaining gap first.
LARGEST_DEMAND
class-attribute
instance-attribute
¶
Origins with the most demand first.
SMALLEST_DEMAND
class-attribute
instance-attribute
¶
Origins with the least demand first.
pytraf.Unreachable ¶
Bases: _Checked
What :func:pytraf.assign does with demand that no allowed path can serve.
Functions¶
pytraf.assign ¶
assign(
network: Network,
classes: Union[
Demand,
TrafficClass,
Sequence[Union[Demand, TrafficClass]],
],
*,
gap: float = 1e-06,
max_iter: int = 200,
order: Union[Order, str] = Order.FIXED,
seed: int = 0,
chunk_size: int = 0,
threads: Optional[int] = None,
link_preload: Optional[NDArray[float64]] = None,
turn_preload: Optional[NDArray[float64]] = None,
unreachable: Union[
Unreachable, str
] = Unreachable.ERROR,
) -> AssignResult
Finds the user equilibrium by path-based gradient projection.
This is also a method of the network: network.assign(classes, ...) is
pytraf.assign(network, classes, ...). Everything after classes is keyword-only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
network
|
Network
|
The network. |
required |
classes
|
Union[Demand, TrafficClass, Sequence[Union[Demand, TrafficClass]]]
|
A |
required |
gap
|
float
|
Stop when the relative gap is at or below this. |
1e-06
|
max_iter
|
int
|
Maximum number of sweeps over all origins. |
200
|
order
|
Union[Order, str]
|
Origin order per sweep, an |
FIXED
|
seed
|
int
|
Seed for |
0
|
chunk_size
|
int
|
Origins whose shortest paths are searched in parallel before their
flow shifts are applied one at a time. |
0
|
threads
|
Optional[int]
|
Number of threads for the parallel parts (default: all cores, or
|
None
|
link_preload
|
Optional[NDArray[float64]]
|
Fixed volume per link in car units, such as buses or through traffic, that is not assigned but adds to the volume the delays see. |
None
|
turn_preload
|
Optional[NDArray[float64]]
|
The same per turn. |
None
|
unreachable
|
Union[Unreachable, str]
|
What to do with demand between nodes that no allowed path joins, an
|
ERROR
|
Returns:
| Type | Description |
|---|---|
AssignResult
|
The flows, paths and convergence information. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For malformed input, an unknown |