Source code for aequilibrae.project.network.modes
from sqlite3 import IntegrityError
from aequilibrae.project.field_editor import FieldEditor
from aequilibrae.project.network.mode import Mode
from aequilibrae.utils.db_utils import commit_and_close
from aequilibrae.utils.spatialite_utils import connect_spatialite
[docs]
class Modes:
"""
Access to the API resources to manipulate the modes table in the network
.. code-block:: python
>>> project = create_example(project_path)
>>> modes = project.network.modes
# We can get a dictionary of all modes in the model
>>> all_modes = modes.all_modes()
# And do a bulk change and save it
>>> for mode_id, mode_obj in all_modes.items():
... mode_obj.beta = 1
... mode_obj.save()
# or just get one mode in specific
>>> car_mode = modes.get('c')
# or just get this same mode by name
>>> car_mode = modes.get_by_name('car')
# We can change the description of the mode
>>> car_mode.description = 'personal autos only'
# Let's say we are using alpha to store the PCE for a future year with much smaller cars
>>> car_mode.alpha = 0.95
# To save this mode we can simply
>>> car_mode.save()
# We can also create a completely new mode and add to the model
>>> new_mode = modes.new('k')
>>> new_mode.mode_name = 'flying_car' # Only ASCII letters and *_* allowed # other fields are not mandatory
# We then explicitly add it to the network
>>> modes.add(new_mode)
# we can even keep editing and save it directly once we have added it to the project
>>> new_mode.description = 'this is my new description'
>>> new_mode.save()
"""
[docs]
def __init__(self, net):
self.__all_modes = []
self.__items = {}
self.project = net.project
self.logger = net.logger
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
self.__update_list_of_modes(conn)
[docs]
def add(self, mode: Mode) -> None:
"""We add a mode to the project"""
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
self.__update_list_of_modes(conn)
if mode.mode_id in self.__all_modes:
raise ValueError("Mode already exists in the model")
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
conn.execute("insert into 'modes'(mode_id, mode_name) Values(?,?)", [mode.mode_id, mode.mode_name])
self.logger.info(f"mode {mode.mode_name}({mode.mode_id}) was added to the project")
conn.commit()
mode.save()
self.__update_list_of_modes(conn)
[docs]
def delete(self, mode_id: str) -> None:
"""Removes the mode with *mode_id* from the project"""
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
try:
conn.execute(f'delete from modes where mode_id="{mode_id}"')
except IntegrityError as e:
self.logger.error(f"Failed to remove mode {mode_id}. {e.args}")
raise e
self.logger.warning(f"Mode {mode_id} was successfully removed from the database")
self.__update_list_of_modes(conn)
@property
def fields(self) -> FieldEditor:
"""Returns a FieldEditor class instance to edit the Modes table fields and their metadata"""
return FieldEditor(self.project, "modes")
[docs]
def get(self, mode_id: str) -> Mode:
"""Get a mode from the network by its *mode_id*"""
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
self.__update_list_of_modes(conn)
if mode_id not in self.__all_modes:
raise ValueError(f"Mode {mode_id} does not exist in the model")
return Mode(mode_id, self.project)
[docs]
def get_by_name(self, mode: str) -> Mode:
"""Get a mode from the network by its *mode_name*"""
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
self.__update_list_of_modes(conn)
found = conn.execute(f"select mode_id from 'modes' where mode_name='{mode}'").fetchone()
if len(found) == 0:
raise ValueError(f"Mode {mode} does not exist in the model")
return Mode(found[0], self.project)
[docs]
def all_modes(self) -> dict:
"""Returns a dictionary with all mode objects available in the model. mode_id as key"""
with commit_and_close(connect_spatialite(self.project.path_to_file)) as conn:
self.__update_list_of_modes(conn)
return {x: Mode(x, self.project) for x in self.__all_modes}
[docs]
def new(self, mode_id: str) -> Mode:
"""Returns a new mode with *mode_id* that can be added to the model later"""
if mode_id in self.__all_modes:
raise ValueError("Mode already exists in the model. Creating a new one does not make sense")
return Mode(mode_id, self.project)
def __update_list_of_modes(self, conn) -> None:
self.__all_modes = [x[0] for x in conn.execute("select mode_id from 'modes'").fetchall()]
def __copy__(self):
raise Exception("Modes object cannot be copied")
def __deepcopy__(self, memodict=None):
raise Exception("Modes object cannot be copied")
def __del__(self):
self.__items.clear()