Skip to content

Commit

Permalink
New documentation (#394)
Browse files Browse the repository at this point in the history
* change theme

* Update version_history.rst

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* introduces data model documentation

* Documentation improvement

* Documentation improvement

* updates table docs

* Documentation improvement

* updates documentation

* Update aequilibrae/parameters.py

* documentation and testing of it

* documentation and testing of it

* updates docs

* Cleans docstrings

* Cleans docstrings

* Reorganization and small additions

* Reorganization and small additions

* Reorganization examples

* Example link

* cleans folders

* Removes population and employment from standard zones table

* documentation

* documentation

* documentation

* documentation

* documentation

* documentation

* documentation

* Documentation

* Documentation

* Documentation

* returns missing examples

* fixes docs structure

* add figures

* adds information on ipf

* adds ..code-block:: python to functions

* update docs

* formatting and typos

* fix indexes

* fixes typos

* adds doctest

* doctests

* Documentation

* Bumps up version

* Bumps up version

* documentation build

* doctests

* docstring formatting

* updates docs

* update tables documentation

* adds images

* updates docs

* black

* changes path to validation of history

* updates documentation

* Update conf.py

* Update aequilibrae_matrix.py

* adds switcher

* update docs

* update docs

* Update conf.py

* moves examples to new folder

* updates docs

* cleaning

* update docs

* development updates

* validation and benchmarking

* Graph logic

* Style correction

* removes useless requirement

* Update docs/source/development/softwaredevelopment.rst

Co-authored-by: Jamie Cook <jamie.cook@veitchlister.com.au>

* Apply suggestions from code review

Co-authored-by: Jamie Cook <jamie.cook@veitchlister.com.au>

---------

Co-authored-by: Renata Imai <renataakemii@yahoo.co.uk>
Co-authored-by: pveigadecamargo <pveigadecamargo@anl.gov>
Co-authored-by: Jamie Cook <jamie.cook@veitchlister.com.au>
  • Loading branch information
4 people committed Apr 26, 2023
1 parent 51adcfa commit 7100cb7
Show file tree
Hide file tree
Showing 186 changed files with 4,931 additions and 4,498 deletions.
15 changes: 13 additions & 2 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,21 @@ jobs:
- name: Compile library
run: |
python3 setup.py build_ext --inplace
python setup.py build_ext --inplace
- name: Check history of versions
run: python docs/website/check_documentation_versions.py
run: |
python docs/table_documentation.py
python docs/create_docs_data.py
python docs/website/check_documentation_versions.py
- name: Test docstrings
run: |
echo "DOCUMENTATION TESTING GOES HERE"
python -m doctest -v ./aequilibrae/parameters.py
python -m doctest -v ./aequilibrae/project/about.py
python -m doctest -v ./aequilibrae/project/zoning.py
- name: Build documentation
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ aequilibrae/**/*.html
aequilibrae/**/build/*
docs/build/*
docs/source/_generated/*
docs/source/project_database/*
docs/source/_auto_examples/*
*.cpp

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ What is available
What is available only in QGIS
******************************

Some common resources for transportation modelling are inherently visual, and therefore they make more sense if
Some common resources for transportation modeling are inherently visual, and therefore they make more sense if
available within a GIS platform. For that reason, many resources are available only from AequilibraE's `QGIS plugin
<http://plugins.qgis.org/plugins/AequilibraE/>`_,
which uses AequilibraE as its computational workhorse and also provides GUIs for most of AequilibraE's tools. Said tool
Expand Down Expand Up @@ -85,7 +85,7 @@ Before there was AequilibraE, there was a need for something like AequilibraE ou
The very early days
*******************
It all started when I was a student at `UCI-ITS <www.its.uci.edu>`_ and needed low level access to outputs of standard
algorithms used in transportation modelling (e.g. path files from traffic assignment) and had that denied by the maker
algorithms used in transportation modeling (e.g. path files from traffic assignment) and had that denied by the maker
of the commercial software he normally used. There, the `first scratch of a traffic assignment procedure
<www.xl-optim.com/python-traffic-assignment>`_ was born.
After that, there were a couple of scripts developed to implement synthetic gravity models (calibration and application)
Expand Down
6 changes: 3 additions & 3 deletions __version__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
version = 0.8
minor_version = "4"
release_name = "Rio de Janeiro"
version = 0.9
minor_version = "0"
release_name = "Queluz"

release_version = f"{version}.{minor_version}"
141 changes: 71 additions & 70 deletions aequilibrae/distribution/gravity_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,118 +20,119 @@


class GravityApplication:
"""Applies a synthetic gravity model
"""Applies a synthetic gravity model.
Model is an instance of SyntheticGravityModel class
Impedance is an instance of AequilibraEMatrix
Row and Column vectors are instances of AequilibraeData
Model is an instance of SyntheticGravityModel class.
Impedance is an instance of AequilibraEMatrix.
Row and Column vectors are instances of AequilibraeData.
::
.. code-block:: python
import pandas as pd
import sqlite3
>>> import pandas as pd
>>> from aequilibrae import Project
>>> from aequilibrae.matrix import AequilibraeMatrix, AequilibraeData
>>> from aequilibrae.distribution import SyntheticGravityModel, GravityApplication
from aequilibrae.matrix import AequilibraeMatrix
from aequilibrae.matrix import AequilibraeData
from aequilibrae.distribution import SyntheticGravityModel
from aequilibrae.distribution import GravityApplication
>>> project = Project.from_path("/tmp/test_project_ga")
# We define the model we will use
model = SyntheticGravityModel()
>>> model = SyntheticGravityModel()
# Before adding a parameter to the model, you need to define the model functional form
model.function = "GAMMA" # "EXPO" or "POWER"
>>> model.function = "GAMMA" # "EXPO" or "POWER"
# Only the parameter(s) applicable to the chosen functional form will have any effect
model.alpha = 0.1
model.beta = 0.0001
>>> model.alpha = 0.1
>>> model.beta = 0.0001
# Or you can load the model from a file
model.load('path/to/model/file')
# model.load('path/to/model/file')
# We load the impedance matrix
matrix = AequilibraeMatrix()
matrix.load('path/to/impedance_matrix.aem')
matrix.computational_view(['distance'])
>>> matrix = AequilibraeMatrix()
>>> matrix.load('/tmp/test_project_ga/matrices/skims.omx')
>>> matrix.computational_view(['distance_blended'])
# We create the vectors we will use
conn = sqlite3.connect('path/to/demographics/database')
query = "SELECT zone_id, population, employment FROM demographics;"
df = pd.read_sql_query(query,conn)
index = df.zone_id.values[:]
zones = index.shape[0]
>>> query = "SELECT zone_id, population, employment FROM zones;"
>>> df = pd.read_sql(query, project.conn)
>>> df.sort_values(by="zone_id", inplace=True)
# You create the vectors you would have
df = df.assign(production=df.population * 3.0)
df = df.assign(attraction=df.employment * 4.0)
>>> df = df.assign(production=df.population * 3.0)
>>> df = df.assign(attraction=df.employment * 4.0)
>>> zones = df.index.shape[0]
# We create the vector database
args = {"entries": zones, "field_names": ["productions", "attractions"],
"data_types": [np.float64, np.float64], "memory_mode": True}
vectors = AequilibraeData()
vectors.create_empty(**args)
>>> args = {"entries": zones, "field_names": ["productions", "attractions"],
... "data_types": [np.float64, np.float64], "memory_mode": True}
>>> vectors = AequilibraeData()
>>> vectors.create_empty(**args)
# Assign the data to the vector object
vectors.productions[:] = df.production.values[:]
vectors.attractions[:] = df.attraction.values[:]
vectors.index[:] = zones[:]
>>> vectors.productions[:] = df.production.values[:]
>>> vectors.attractions[:] = df.attraction.values[:]
>>> vectors.index[:] = df.zone_id.values[:]
# Balance the vectors
vectors.attractions[:] *= vectors.productions.sum() / vectors.attractions.sum()
>>> vectors.attractions[:] *= vectors.productions.sum() / vectors.attractions.sum()
# Create the problem object
args = {"impedance": matrix,
"rows": vectors,
"row_field": "productions",
"model": model,
"columns": vectors,
"column_field": "attractions",
"output": 'path/to/output/matrix.aem',
"nan_as_zero":True
}
gravity = GravityApplication(**args)
>>> args = {"impedance": matrix,
... "rows": vectors,
... "row_field": "productions",
... "model": model,
... "columns": vectors,
... "column_field": "attractions",
... "output": '/tmp/test_project_ga/matrices/matrix.aem',
... "nan_as_zero":True
... }
>>> gravity = GravityApplication(**args)
# Solve and save the outputs
gravity.apply()
gravity.output.export('path/to/omx_file.omx')
with open('path.to/report.txt', 'w') as f:
for line in gravity.report:
f.write(f'{line}\n')
>>> gravity.apply()
>>> gravity.output.export('/tmp/test_project_ga/matrices/omx_file.omx')
# To save your report into a file, you can do the following:
# with open('/tmp/test_project_ga/report.txt', 'w') as file:
# for line in gravity.report:
# file.write(f"{line}\\n")
"""

def __init__(self, project=None, **kwargs):
"""
Instantiates the Ipf problem
Args:
model (:obj:`SyntheticGravityModel`): Synthetic gravity model to apply
:Arguments:
**model** (:obj:`SyntheticGravityModel`): Synthetic gravity model to apply
impedance (:obj:`AequilibraeMatrix`): Impedance matrix to be used
**impedance** (:obj:`AequilibraeMatrix`): Impedance matrix to be used
rows (:obj:`AequilibraeData`): Vector object with data for row totals
**rows** (:obj:`AequilibraeData`): Vector object with data for row totals
row_field (:obj:`str`): Field name that contains the data for the row totals
**row_field** (:obj:`str`): Field name that contains the data for the row totals
columns (:obj:`AequilibraeData`): Vector object with data for column totals
**columns** (:obj:`AequilibraeData`): Vector object with data for column totals
column_field (:obj:`str`): Field name that contains the data for the column totals
**column_field** (:obj:`str`): Field name that contains the data for the column totals
project (:obj:`Project`, optional): The Project to connect to. By default, uses the currently active project
**project** (:obj:`Project`, optional): The Project to connect to. By default, uses the currently
active project
core_name (:obj:`str`, optional): Name for the output matrix core. Defaults to "gravity"
**core_name** (:obj:`str`, optional): Name for the output matrix core. Defaults to "gravity"
parameters (:obj:`str`, optional): Convergence parameters. Defaults to those in the parameter file
**parameters** (:obj:`str`, optional): Convergence parameters. Defaults to those in the parameter file
nan_as_zero (:obj:`bool`, optional): If Nan values should be treated as zero. Defaults to True
**nan_as_zero** (:obj:`bool`, optional): If Nan values should be treated as zero. Defaults to True
Results:
output (:obj:`AequilibraeMatrix`): Result Matrix
:Results:
**output** (:obj:`AequilibraeMatrix`): Result Matrix
report (:obj:`list`): Iteration and convergence report
**report** (:obj:`list`): Iteration and convergence report
error (:obj:`str`): Error description
**error** (:obj:`str`): Error description
"""

self.project = project
Expand Down Expand Up @@ -224,10 +225,10 @@ def apply(self):
def save_to_project(self, name: str, file_name: str, project=None) -> None:
"""Saves the matrix output to the project file
Args:
name (:obj:`str`): Name of the desired matrix record
file_name (:obj:`str`): Name for the matrix file name. AEM and OMX supported
project (:obj:`Project`, Optional): Project we want to save the results to. Defaults to the active project
:Arguments:
**name** (:obj:`str`): Name of the desired matrix record
**file_name** (:obj:`str`): Name for the matrix file name. AEM and OMX supported
**project** (:obj:`Project`, Optional): Project we want to save the results to. Defaults to the active project
"""

project = project or get_active_project()
Expand Down
82 changes: 43 additions & 39 deletions aequilibrae/distribution/gravity_calibration.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,71 +8,75 @@

import numpy as np

from .gravity_application import GravityApplication, SyntheticGravityModel
from ..matrix import AequilibraeMatrix, AequilibraeData
from ..parameters import Parameters
from aequilibrae.distribution.gravity_application import GravityApplication, SyntheticGravityModel
from aequilibrae.matrix import AequilibraeMatrix, AequilibraeData
from aequilibrae.parameters import Parameters


class GravityCalibration:
r"""
Calibrate a traditional gravity model
"""Calibrate a traditional gravity model
Available deterrence function forms are: 'EXPO' or 'POWER'. 'GAMMA'
::
Available deterrence function forms are: 'EXPO' or 'POWER'. 'GAMMA'
from aequilibrae.matrix import AequilibraeMatrix
from aequilibrae.distribution import GravityCalibration
.. code-block:: python
>>> from aequilibrae import Project
>>> from aequilibrae.matrix import AequilibraeMatrix
>>> from aequilibrae.distribution import GravityCalibration
>>> project = Project.from_path("/tmp/test_project_gc")
# We load the impedance matrix
matrix = AequilibraeMatrix()
matrix.load('path/to/trip_matrix.aem')
matrix.computational_view(['total_trips'])
>>> matrix = AequilibraeMatrix()
>>> matrix.load('/tmp/test_project_gc/matrices/demand.omx')
>>> matrix.computational_view(['matrix'])
# We load the impedance matrix
impedmatrix = AequilibraeMatrix()
impedmatrix.load('path/to/impedance_matrix.aem')
impedmatrix.computational_view(['traveltime'])
# We load the impedance matrix
>>> impedmatrix = AequilibraeMatrix()
>>> impedmatrix.load('/tmp/test_project_gc/matrices/skims.omx')
>>> impedmatrix.computational_view(['time_final'])
# Creates the problem
args = {"matrix": matrix,
"impedance": impedmatrix,
"row_field": "productions",
"function": 'expo',
"nan_as_zero":True
}
gravity = GravityCalibration(**args)
>>> args = {"matrix": matrix,
... "impedance": impedmatrix,
... "row_field": "productions",
... "function": 'expo',
... "nan_as_zero": True}
>>> gravity = GravityCalibration(**args)
# Solve and save outputs
gravity.calibrate()
gravity.model.save('path/to/dist_expo_model.mod')
with open('path.to/report.txt', 'w') as f:
for line in gravity.report:
f.write(f'{line}\n')
>>> gravity.calibrate()
>>> gravity.model.save('/tmp/test_project_gc/dist_expo_model.mod')
# To save the model report in a file
# with open('/tmp/test_project_gc/report.txt', 'w') as f:
# for line in gravity.report:
# f.write(f'{line}\\n')
"""

def __init__(self, project=None, **kwargs):
"""
Instantiates the Gravity calibration problem
Args:
matrix (:obj:`AequilibraeMatrix`): Seed/base trip matrix
:Arguments:
**matrix** (:obj:`AequilibraeMatrix`): Seed/base trip matrix
impedance (:obj:`AequilibraeMatrix`): Impedance matrix to be used
**impedance** (:obj:`AequilibraeMatrix`): Impedance matrix to be used
function (:obj:`str`): Function name to be calibrated. "EXPO" or "POWER"
**function** (:obj:`str`): Function name to be calibrated. "EXPO" or "POWER"
project (:obj:`Project`, optional): The Project to connect to. By default, uses the currently active project
**project** (:obj:`Project`, optional): The Project to connect to. By default, uses the currently active project
parameters (:obj:`str`, optional): Convergence parameters. Defaults to those in the parameter file
**parameters** (:obj:`str`, optional): Convergence parameters. Defaults to those in the parameter file
nan_as_zero (:obj:`bool`, optional): If Nan values should be treated as zero. Defaults to True
**nan_as_zero** (:obj:`bool`, optional): If Nan values should be treated as zero. Defaults to True
Results:
model (:obj:`SyntheticGravityModel`): Calibrated model
:Results:
**model** (:obj:`SyntheticGravityModel`): Calibrated model
report (:obj:`list`): Iteration and convergence report
**report** (:obj:`list`): Iteration and convergence report
error (:obj:`str`): Error description
**error** (:obj:`str`): Error description
"""

Expand Down

0 comments on commit 7100cb7

Please sign in to comment.