next up previous index
Next: OPUS Indicators Up: Introduction to Programming in Previous: OPUS Variables   Index


OPUS Expressions

OPUS uses Python and Numpy to create variables to be used in models. These are generally coded in Python modules as described in the preceding section. However, in order to make the use of variables simpler for users to access, a new expression language has been created for OPUS that allows variables to be defined with a relatively simple and concise syntax.

The syntax consists of using Numpy operations and methods, operating on OPUS variables and primary data. All of the Numpy operators are available, and work in the same way for expressions, including + - * / **, where ** is an exponential function: a**3 returns a to the power of 3.

Expressions allow an alias, or name, to be assigned to the expression, in order to use it by this reference in a model specification or indicator function. The standard syntax in Opus uses short names, with lower case letters. If two or more words are used in a name, we usually separate the components with an underscore to make the name more readable. Some examples will illustrate key aspects of the expression syntax:

Two very useful methods in the expression language are aggregation and disaggregation. Aggregation allows an expression to compute a result on one dataset and aggregate the results to assign to another dataset, such as summing the population in households that live in a gridcell. Using this expression approach, we could replace the long population.py module in the preceding section with the following expression:

population = gridcell.aggregate(household.persons)

That is quite a lot easier to understand and to code! We are aggregating to the gridcell dataset, from the household dataset, the number of persons. However, in the time since the variable in the preceding section was implemented, we have changed the data structure for the gridcell and parcel based models to use buildings. So now, households and jobs are associated with buildings, and buildings are associated with gridcells (or parcels). This means that in order to compute the population of a gridcell, we need to first aggregate it to building, and then from building to gridcell. That is not hard to do, either, by simply adding an intermediated argument to the aggregation function. There can be multiple levels of intermediates, if needed:

population = gridcell.aggregate(household.persons, intermediates = [building])

The default method for aggregation is to sum, but there are several other aggregation methods available also:

$ \bullet$
sum
$ \bullet$
mean
$ \bullet$
maximum
$ \bullet$
mininim
$ \bullet$
variance
$ \bullet$
standard_deviation
$ \bullet$
center_of_mass

To use any of these functions, we simply add function = mean (or another function) in the expression. Here is an example to determine the average household size per gridcell:

avg_hhs = gridcell.aggregate(households.persons, intermediates = [building], function = mean)

The disaggregate method for expressions assigns values from one dataset to another, in a one to many relationship. In other words, it works in the opposite direction from the aggregate method, which is many to one. An example would be to assign the zonal population density to all households living the zone. In this example, we use the population_density variable in the zone dataset of the urbansim_parcel package, and assign it to households, which are connected to zones indirectly through buildings and then parcels: household -$ >$ building -$ >$ parcel -$ >$ zone. So the expression would be:

density = household.disaggregate(urbansim_parcel.zone.population_density, intermediates = [building, parcel])

Note that for both aggregate and disaggregate methods, the first element, preceding the method name, is the name of the dataset to which the result should be assigned. zone.aggregate... should generate some result and assign it to zone, whereas gridcell.disaggregate... should assign some value from a larger geography to the gridcell dataset.

A list of expressions can be stores in an aliases.py file within a package and dataset directory. This provides an efficient means to organize and store many expressions in a single location. Below are some of the aliases in the urbansim_parcel/parcel/aliases.py module that demonstrate some of the expressions in actual use in the model system.


\begin{lstlisting}
''used_land_area = (parcel.aggregate(building.land_area, func...
...e_to_cbd = parcel.disaggregate(gridcell.travel_time_to_cbd)'',
\end{lstlisting}


next up previous index
Next: OPUS Indicators Up: Introduction to Programming in Previous: OPUS Variables   Index
info (at) urbansim.org