Skip to content

Commit

Permalink
Random usage upgrades (#52)
Browse files Browse the repository at this point in the history
* add how variable to subgraph on ocnditions

* add set as an option for values in a collection of things

* add set as an option for values in attribute summaries

* update notebook

* swap lat and lon when creating schedule from gtfs

* add test to catch swapped lat,lons in gtps-schedule build

* delete pointless reproject and add test for gtfs-non-empty-schedule read
  • Loading branch information
KasiaKoz authored Feb 1, 2021
1 parent 09d378d commit 8676731
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 80 deletions.
6 changes: 4 additions & 2 deletions genet/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,14 +522,16 @@ def reindex_link(self, link_id, new_link_id, silent: bool = False):
if not silent:
logging.info(f'Changed Link index from {link_id} to {new_link_id}')

def subgraph_on_link_conditions(self, conditions, mixed_dtypes=True):
def subgraph_on_link_conditions(self, conditions, how=any, mixed_dtypes=True):
"""
Gives a subgraph of network.graph based on matching conditions defined in conditions
:param conditions as described in graph_operations.extract_links_on_edge_attributes
:param how as described in graph_operations.extract_links_on_edge_attributes
:param mixed_dtypes as described in graph_operations.extract_links_on_edge_attributes
:return:
"""
links = graph_operations.extract_links_on_edge_attributes(self, conditions, mixed_dtypes=mixed_dtypes)
links = graph_operations.extract_links_on_edge_attributes(
self, conditions=conditions, how=how, mixed_dtypes=mixed_dtypes)
edges_for_sub = [
(self.link_id_mapping[link]['from'],
self.link_id_mapping[link]['to'],
Expand Down
5 changes: 2 additions & 3 deletions genet/schedule_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ def read_gtfs_schedule(self, path, day):
r = Route(
route_short_name=route['route_short_name'],
mode=route['mode'],
stops=[Stop(id=id, x=stops_db[id]['stop_lon'], y=stops_db[id]['stop_lat'], epsg='epsg:4326') for id
stops=[Stop(id=id, x=stops_db[id]['stop_lat'], y=stops_db[id]['stop_lon'], epsg='epsg:4326') for id
in
route['stops']],
trips=route['trips'],
Expand All @@ -920,10 +920,9 @@ def read_gtfs_schedule(self, path, day):
routes_list.append(r)
services.append(Service(id=key, routes=routes_list))

# TODO add services rather than creating new object (in case there are already services present)
# add services rather than creating new object (in case there are already services present)
to_add = self.__class__('epsg:4326', services)
self.add(to_add)
self.reproject(self.epsg)

def write_to_matsim(self, output_dir):
persistence.ensure_dir(output_dir)
Expand Down
6 changes: 3 additions & 3 deletions genet/utils/graph_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def evaluate_condition(self, condition, data_dict):
else:
# value is that value
satisfies = data_dict[key] == val
elif isinstance(val, list):
elif isinstance(val, (list, set)):
if isinstance(data_dict[key], (list, set)) and self.mixed_dtypes:
if set(data_dict[key]) & set(val):
satisfies = True
Expand Down Expand Up @@ -221,7 +221,7 @@ def append_to_tree(d: dict, parent):
append_to_tree(v, twin)
elif not twin:
if data:
if isinstance(v, list):
if isinstance(v, (list, set)):
values = set(v)
else:
values = {v}
Expand All @@ -230,7 +230,7 @@ def append_to_tree(d: dict, parent):
Node(k, parent=parent)
elif data:
node = get_identical_twin_if_exists(parent, k)
if isinstance(v, list):
if isinstance(v, (list, set)):
values = set(v)
else:
values = {v}
Expand Down
86 changes: 43 additions & 43 deletions notebooks/2.1. Reading MATSim data.ipynb

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,34 @@ def correct_schedule_dict():
'departure_offsets': ['0:00:00', '0:02:00'], 's2_stops': [5221390332291192399, 5221390324026756531]}]}


@pytest.fixture()
def correct_schedule_dict_from_test_gtfs():
return {'1001': [
{'route_short_name': 'BTR', 'route_long_name': 'Bus Test Route', 'mode': 'bus', 'route_color': '#CE312D',
'trips': {'BT1': '03:21:00'}, 'stops': ['BSE', 'BSN'], 'arrival_offsets': ['0:00:00', '0:02:00'],
'departure_offsets': ['0:00:00', '0:02:00'], 's2_stops': [5221390325135889957, 5221390684150342605]}],
'1002': [{'route_short_name': 'RTR', 'route_long_name': 'Rail Test Route', 'mode': 'rail',
'route_color': '#CE312D', 'trips': {'RT1': '03:21:00'}, 'stops': ['RSN', 'RSE'],
'arrival_offsets': ['0:00:00', '0:02:00'], 'departure_offsets': ['0:00:00', '0:02:00'],
's2_stops': [5221390332291192399, 5221390324026756531]}]}


@pytest.fixture()
def correct_stopdb_from_test_gtfs():
return {'BSE': {'stop_id': 'BSE', 'stop_code': '', 'stop_name': 'Bus Stop snap to edge', 'stop_lat': '51.5226864',
'stop_lon': '-0.1413621', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G433', 'platform_code': ''},
'BSN': {'stop_id': 'BSN', 'stop_code': '', 'stop_name': 'Bus Stop snap to node', 'stop_lat': '51.5216199',
'stop_lon': '-0.140053', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G432', 'platform_code': ''},
'RSE': {'stop_id': 'RSE', 'stop_code': '', 'stop_name': 'Rail Stop snap to edge', 'stop_lat': '51.5192615',
'stop_lon': '-0.1421595', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G431', 'platform_code': ''},
'RSN': {'stop_id': 'RSN', 'stop_code': '', 'stop_name': 'Rail Stop snap to node', 'stop_lat': '51.5231335',
'stop_lon': '-0.1410946', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G430', 'platform_code': ''}}


@pytest.fixture()
def correct_services_from_test_gtfs():
services = []
Expand Down
94 changes: 93 additions & 1 deletion tests/test_core_schedule_elements.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pytest
from networkx import Graph
from genet.schedule_elements import Schedule, Service, Route, Stop
from tests.fixtures import assert_semantically_equal
from genet.inputs_handler import gtfs_reader
from tests.fixtures import assert_semantically_equal, correct_schedule_dict_from_test_gtfs, \
correct_stopdb_from_test_gtfs


def assert_all_elements_share_graph(elem):
Expand Down Expand Up @@ -202,3 +204,93 @@ def test_schedule_subgraph(schedule):
'y': 182401.37630677427, 'epsg': 'epsg:27700', 'lat': 51.525696033239186,
'lon': -0.13530998708775874, 's2_id': 5221390668020036699,
'additional_attributes': ['linkRefId'], 'linkRefId': '0', 'name': ''}})


def test_reading_gtfs_into_schedule(correct_schedule_dict_from_test_gtfs, correct_stopdb_from_test_gtfs, mocker):
mocker.patch.object(gtfs_reader, 'read_to_dict_schedule_and_stopd_db',
return_value=(correct_schedule_dict_from_test_gtfs, correct_stopdb_from_test_gtfs))
s = Schedule('epsg:27700')
s.read_gtfs_schedule('some_path_to_gtfs', 'day_for_gtfs')

assert_semantically_equal(dict(s.graph().nodes(data=True)),
{'RSN': {'services': ['1002'], 'routes': ['1002_0'], 'id': 'RSN', 'x': 529061.7214134948,
'y': 182106.20208785852, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5231335,
'lon': -0.1410946, 's2_id': 5221390332291192399, 'additional_attributes': []},
'RSE': {'services': ['1002'], 'routes': ['1002_0'], 'id': 'RSE', 'x': 528998.7798063147,
'y': 181673.74458124593, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5192615,
'lon': -0.1421595, 's2_id': 5221390324026756531, 'additional_attributes': []},
'BSE': {'services': ['1001'], 'routes': ['1001_0'], 'id': 'BSE', 'x': 529044.4274520243,
'y': 182056.01144580863, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5226864,
'lon': -0.1413621, 's2_id': 5221390325135889957, 'additional_attributes': []},
'BSN': {'services': ['1001'], 'routes': ['1001_0'], 'id': 'BSN', 'x': 529138.2570252238,
'y': 181939.72009660664, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5216199,
'lon': -0.140053, 's2_id': 5221390684150342605, 'additional_attributes': []}})

assert {r.id for _id, r in s.routes()} == {'1001_0', '1002_0'}

d_1001_0 = s.route('1001_0').__dict__
del d_1001_0['_graph']
assert_semantically_equal(d_1001_0,
{'ordered_stops': ['BSE', 'BSN'], 'route_short_name': 'BTR', 'mode': 'bus',
'trips': {'BT1': '03:21:00'}, 'arrival_offsets': ['0:00:00', '0:02:00'],
'departure_offsets': ['0:00:00', '0:02:00'], 'route_long_name': '', 'id': '1001_0',
'route': [], 'await_departure': [], 'reference_nodes': ['BSE', 'BSN'],
'reference_edges': [('BSE', 'BSN')], 'epsg': 'epsg:4326'})

d_1002_0 = s.route('1002_0').__dict__
del d_1002_0['_graph']
assert_semantically_equal(d_1002_0,
{'ordered_stops': ['RSN', 'RSE'], 'route_short_name': 'RTR', 'mode': 'rail',
'trips': {'RT1': '03:21:00'}, 'arrival_offsets': ['0:00:00', '0:02:00'],
'departure_offsets': ['0:00:00', '0:02:00'], 'route_long_name': '', 'id': '1002_0',
'route': [], 'await_departure': [], 'reference_nodes': ['RSN', 'RSE'],
'reference_edges': [('RSN', 'RSE')], 'epsg': 'epsg:4326'})


def test_reading_gtfs_into_non_empty_schedule_gives_consistently_projected_stops(correct_schedule_dict_from_test_gtfs,
correct_stopdb_from_test_gtfs,
schedule, mocker):
mocker.patch.object(gtfs_reader, 'read_to_dict_schedule_and_stopd_db',
return_value=(correct_schedule_dict_from_test_gtfs, correct_stopdb_from_test_gtfs))
s = schedule
s.read_gtfs_schedule('some_path_to_gtfs', 'day_for_gtfs')

assert_semantically_equal(dict(s.graph().nodes(data=True)),
{'4': {'services': ['service2'], 'routes': ['3', '4'], 'id': '4', 'x': 529350.7866124967,
'y': 182388.0201078112, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.52560003323918,
'lon': -0.13682698708848137, 's2_id': 5221390668558830581,
'additional_attributes': ['linkRefId'], 'linkRefId': '4'},
'5': {'services': ['service2'], 'routes': ['4'], 'id': '5', 'x': 529350.7866124967,
'y': 182388.0201078112, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.52560003323918,
'lon': -0.13682698708848137, 's2_id': 5221390668558830581,
'additional_attributes': ['linkRefId'], 'linkRefId': '5'},
'3': {'services': ['service2'], 'routes': ['3'], 'id': '3', 'x': 529455.7452394223,
'y': 182401.37630677427, 'epsg': 'epsg:27700', 'name': '',
'lat': 51.525696033239186, 'lon': -0.13530998708775874,
's2_id': 5221390668020036699, 'additional_attributes': ['linkRefId'],
'linkRefId': '3'},
'2': {'services': ['service1'], 'routes': ['2'], 'id': '2', 'x': 529350.7866124967,
'y': 182388.0201078112, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.52560003323918,
'lon': -0.13682698708848137, 's2_id': 5221390668558830581,
'additional_attributes': ['linkRefId'], 'linkRefId': '2'},
'0': {'services': ['service1'], 'routes': ['1'], 'id': '0', 'x': 529455.7452394223,
'y': 182401.37630677427, 'epsg': 'epsg:27700', 'name': '',
'lat': 51.525696033239186, 'lon': -0.13530998708775874,
's2_id': 5221390668020036699, 'additional_attributes': ['linkRefId'],
'linkRefId': '0'},
'1': {'services': ['service1'], 'routes': ['2', '1'], 'id': '1', 'x': 529350.7866124967,
'y': 182388.0201078112, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.52560003323918,
'lon': -0.13682698708848137, 's2_id': 5221390668558830581,
'additional_attributes': ['linkRefId'], 'linkRefId': '1'},
'RSN': {'services': ['1002'], 'routes': ['1002_0'], 'id': 'RSN', 'x': 529061.7214134948,
'y': 182106.20208785852, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5231335,
'lon': -0.1410946, 's2_id': 5221390332291192399, 'additional_attributes': []},
'RSE': {'services': ['1002'], 'routes': ['1002_0'], 'id': 'RSE', 'x': 528998.7798063147,
'y': 181673.74458124593, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5192615,
'lon': -0.1421595, 's2_id': 5221390324026756531, 'additional_attributes': []},
'BSE': {'services': ['1001'], 'routes': ['1001_0'], 'id': 'BSE', 'x': 529044.4274520243,
'y': 182056.01144580863, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5226864,
'lon': -0.1413621, 's2_id': 5221390325135889957, 'additional_attributes': []},
'BSN': {'services': ['1001'], 'routes': ['1001_0'], 'id': 'BSN', 'x': 529138.2570252238,
'y': 181939.72009660664, 'epsg': 'epsg:27700', 'name': '', 'lat': 51.5216199,
'lon': -0.140053, 's2_id': 5221390684150342605, 'additional_attributes': []}})
28 changes: 0 additions & 28 deletions tests/test_inputs_handler_gtfs_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,6 @@
gtfs_test_zip_file = os.path.abspath(os.path.join(os.path.dirname(__file__), "test_data", "gtfs.zip"))


@pytest.fixture()
def correct_schedule_dict_from_test_gtfs():
return {'1001': [
{'route_short_name': 'BTR', 'route_long_name': 'Bus Test Route', 'mode': 'bus', 'route_color': '#CE312D',
'trips': {'BT1': '03:21:00'}, 'stops': ['BSE', 'BSN'], 'arrival_offsets': ['0:00:00', '0:02:00'],
'departure_offsets': ['0:00:00', '0:02:00'], 's2_stops': [5221390325135889957, 5221390684150342605]}],
'1002': [{'route_short_name': 'RTR', 'route_long_name': 'Rail Test Route', 'mode': 'rail',
'route_color': '#CE312D', 'trips': {'RT1': '03:21:00'}, 'stops': ['RSN', 'RSE'],
'arrival_offsets': ['0:00:00', '0:02:00'], 'departure_offsets': ['0:00:00', '0:02:00'],
's2_stops': [5221390332291192399, 5221390324026756531]}]}


@pytest.fixture()
def correct_stopdb_from_test_gtfs():
return {'BSE': {'stop_id': 'BSE', 'stop_code': '', 'stop_name': 'Bus Stop snap to edge', 'stop_lat': '51.5226864',
'stop_lon': '-0.1413621', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G433', 'platform_code': ''},
'BSN': {'stop_id': 'BSN', 'stop_code': '', 'stop_name': 'Bus Stop snap to node', 'stop_lat': '51.5216199',
'stop_lon': '-0.140053', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G432', 'platform_code': ''},
'RSE': {'stop_id': 'RSE', 'stop_code': '', 'stop_name': 'Rail Stop snap to edge', 'stop_lat': '51.5192615',
'stop_lon': '-0.1421595', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G431', 'platform_code': ''},
'RSN': {'stop_id': 'RSN', 'stop_code': '', 'stop_name': 'Rail Stop snap to node', 'stop_lat': '51.5231335',
'stop_lon': '-0.1410946', 'wheelchair_boarding': '', 'stop_timezone': '', 'location_type': '0.0',
'parent_station': '210G430', 'platform_code': ''}}


def test_read_services_from_calendar_correct():
services = gtfs_reader.read_services_from_calendar(gtfs_test_file, '20190604')
assert services == ['6630', '6631']
Expand Down

0 comments on commit 8676731

Please sign in to comment.