Table Definitions#
The traveler.examples.mtc_mini.tables package contains table definitions
for the MTC Mini example, including classes for households and tours, among
others. These tables are implemented as subclasses of JaxTable and define
the schema for each data table in the model.
from typing import Annotated
from traveler.tables import JaxTable
from traveler import TypeMaker
from traveler.store import from_step
t = TypeMaker("household")
class Households(JaxTable):
"""
A class representing households in the ActivityJAX framework.
"""
household_id: t.Int32 # (3)
"""Unique identifier for the household.""" # (1)
home_zone_id: t.Int32
"""Identifier for the home zone of the household."""
income_in_thousands: t.Float32
hhsize: t.Int8 # (2)
non_family: t.Bool
_household_idx_: t.Int32
Docstrings can be added to each field to describe its purpose and any relevant details.
The data type for
hhsizeis set toInt8, which is a small integer type suitable for household sizes. The validation tool can be set to safely coerce integer values to this type if the underlying data can be represented accurately.Type annotations are used to define the data types of each field in the
Householdsclass. Thet.Int32type is used for 32-bit integers,t.Float32for 32-bit floating-point numbers, andt.Boolfor boolean values. TheTypeMakerutility is used to create type aliases for various numeric types, and also ensures that data arrays added to the table have appropriate dimensions (e.g. match the number of rows in the table, or are a scalar value that can be broadcast to the rows).
from traveler.tables import JaxTable
from traveler.typing import TypeMaker
t = TypeMaker("tour")
time_periods = ["EA", "AM", "MD", "PM", "EV"]
class Tours(JaxTable):
"""
A class representing households in the ActivityJAX framework.
"""
tour_id: t.Int32
person_id: t.Int32
household_id: t.Int32
otaz: t.Int32
dtaz: t.Int32
out_period: t.Categorical(categories=time_periods) # (3)
"""Skims time period for the outbound (first) half of the tour."""
in_period: t.Categorical(categories=time_periods)
"""Skims time period for the inbound (second, return) half of the tour."""
_household_idx_: t.Int32
_person_idx_: t.Int32
@lazy # (1)
def sov_available(self, store: AbstractStore) -> t.Bool:
"""Whether the SOV mode is available for this tour."""
odt_skims = skims_data(store, self.otaz, self.dtaz, self.out_period)
dot_skims = skims_data(store, self.dtaz, self.otaz, self.in_period)
return (odt_skims("SOV_TIME") > 0) & (dot_skims("SOV_TIME") > 0)
is_joint: Annotated[t.Bool, from_step("tour_preprocessor")] # (2)
"""Whether this is a joint tour."""
The
lazydecorator defines a derived property that is computed when demanded. To persist it as a table column, use the store’s functionalpush_down_on()method and keep the returned store; the input table is not modified.The
from_stepmetadata identifies a variable computed by a model step. Data validation does not require the variable until that step has run. Once the step is complete, the variable is required and validated for shape and dtype.The
TypeMaker.Categorical(...)factory creates a categorical annotation with nominal or ordinal categories. This is useful for representing discrete choices such as time periods. Data validation ensures that the runtime categories match those declared by the annotation.