Skip to content

Commit

Permalink
Ensure always subset stop id during wait time calc (#138)
Browse files Browse the repository at this point in the history
* Update how calc wait time when no dir id

* lint
  • Loading branch information
kuanb committed Apr 30, 2019
1 parent a9ef0bd commit 0c5073d
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 30 deletions.
14 changes: 7 additions & 7 deletions peartree/graph_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class GraphToolNotImported(Exception):
def get_prop_type(value: Any, key: Any=None) -> Tuple[str, Any, str]:
"""
Performs typing and value conversion for the graph_tool PropertyMap class.
If a key is provided, it also ensures the key is in a format that can be
used with the PropertyMap. Returns a tuple, (type name, value, key)
"""
Expand Down Expand Up @@ -102,7 +102,7 @@ def nx_to_gt(nxG: nx.MultiDiGraph):
The converted network graph, instantiated as a graph_tool network graph
"""
# First, attempt to import graph-tool
gt = _import_graph_tool()
gt = _import_graph_tool()

# Phase 0: Create a directed or undirected graph-tool Graph
gtG = gt.Graph(directed=nxG.is_directed())
Expand All @@ -112,14 +112,14 @@ def nx_to_gt(nxG: nx.MultiDiGraph):
# Convert the value and key into a type for graph-tool
tname, value, key = get_prop_type(value, key)

prop = gtG.new_graph_property(tname) # Create the PropertyMap
prop = gtG.new_graph_property(tname) # Create the PropertyMap
gtG.graph_properties[key] = prop # Set the PropertyMap
gtG.graph_properties[key] = value # Set the actual value

# Phase 1: Add the vertex and edge property maps
# Go through all nodes and edges and add seen properties
# Add the node properties first
nprops = set() # cache keys to only add properties once
nprops = set() # cache keys to only add properties once
for node, data in nxG.nodes(data=True):
# Go through all the properties if not seen and add them.
for key, val in data.items():
Expand All @@ -128,7 +128,7 @@ def nx_to_gt(nxG: nx.MultiDiGraph):
continue

# Convert the value and key into a type for graph-tool
tname, _, key = get_prop_type(val, key)
tname, _, key = get_prop_type(val, key)

# Create the PropertyMap, and...
prop = gtG.new_vertex_property(tname)
Expand All @@ -145,7 +145,7 @@ def nx_to_gt(nxG: nx.MultiDiGraph):
gtG.vertex_properties['id'] = gtG.new_vertex_property('string')

# Add the edge properties second
eprops = set() # cache keys to only add properties once
eprops = set() # cache keys to only add properties once
for src, dst, data in nxG.edges(data=True):

# Go through all the edge properties if not seen and add them,
Expand Down Expand Up @@ -190,7 +190,7 @@ def nx_to_gt(nxG: nx.MultiDiGraph):

# Add the edge properties
for key, value in data.items():
gtG.ep[key][e] = value # ep is short for edge_properties
gtG.ep[key][e] = value # ep is short for edge_properties

# Done, finally!
return gtG
20 changes: 11 additions & 9 deletions peartree/parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import numpy as np
import pandas as pd
from peartree.toolkit import nan_helper
from peartree.utilities import log


class RouteProcessorManager(BaseManager):
Expand Down Expand Up @@ -75,7 +74,7 @@ def generate_route_costs(self, route_id: str):
# Check direction_id column value before using
# trips_and_stop_times to generate wait and edge costs
# Note: Advantage to adding handling at route level is that peartree
# avoids tossing direction id if a specific route has all direction
# avoids tossing direction id if specific route has all direction
# id rows filled in (while another does not, which is possible).
if 'direction_id' in trips_and_stop_times:
# If there is such column then check if it contains NaN
Expand All @@ -96,7 +95,7 @@ def generate_route_costs(self, route_id: str):
# Look up wait time for each stop in wait_times for each direction
wait_zero = stop_id_col.apply(lambda x: wait_times[0][x])
trips_and_stop_times['wait_dir_0'] = wait_zero

wait_one = stop_id_col.apply(lambda x: wait_times[1][x])
trips_and_stop_times['wait_dir_1'] = wait_one

Expand All @@ -117,26 +116,29 @@ def generate_wait_times(
stop_cost_method: Any) -> Dict[int, List[float]]:
wait_times = {0: {}, 1: {}}
for stop_id in trips_and_stop_times.stop_id.unique():
constraint_1 = (trips_and_stop_times.stop_id == stop_id)
stop_times_by_stop = trips_and_stop_times[constraint_1]

# Handle both inbound and outbound directions
for direction in [0, 1]:
# Check if direction_id exists in source data
if 'direction_id' in trips_and_stop_times:
constraint_1 = (trips_and_stop_times.direction_id == direction)
constraint_2 = (trips_and_stop_times.stop_id == stop_id)
both_constraints = (constraint_1 & constraint_2)
direction_subset = trips_and_stop_times[both_constraints]
constraint_2 = (trips_and_stop_times.direction_id == direction)
direction_subset = stop_times_by_stop[constraint_2]
else:
direction_subset = trips_and_stop_times.copy()
direction_subset = stop_times_by_stop.copy()

if direction_subset.empty:
# Cannot calculate the average wait time if there are no
# values associated with the specified direction so default NaN
average_wait = np.nan
else:
arrival_times_copy = np.array(direction_subset.arrival_time)
arrival_times_copy.sort()
average_wait = stop_cost_method(
target_time_start,
target_time_end,
direction_subset.arrival_time)
arrival_times_copy)

# Add according to which direction we are working with
wait_times[direction][stop_id] = average_wait
Expand Down
2 changes: 1 addition & 1 deletion peartree/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def get_representative_feed(file_loc: str,
'were identified in GTFS.')

# TODO: Due to partridge's assertion error being raised, this
# check may no longer be needed.
# check may no longer be needed.
if not len(trip_counts_by_date.items()):
# Otherwise, error out
raise InvalidGTFS('No valid trip counts by date '
Expand Down
2 changes: 0 additions & 2 deletions peartree/plot.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os

import networkx as nx

from .utilities import log
Expand Down
2 changes: 1 addition & 1 deletion peartree/summarizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
from peartree.utilities import log



class InvalidParsedWaitTimes(Exception):
pass


def _format_summarized_outputs(summarized: pd.Series) -> pd.DataFrame:
# The output of the group by produces a Series, but we want to extract
# the values from the index and the Series itself and generate a
Expand Down
2 changes: 1 addition & 1 deletion tests/test_convert.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os

import networkx as nx
from peartree.paths import get_representative_feed, load_feed_as_graph
from peartree.convert import convert_to_digraph
from peartree.paths import get_representative_feed, load_feed_as_graph


def fixture(filename):
Expand Down
5 changes: 2 additions & 3 deletions tests/test_graph.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import os
import pytest

import pytest
from peartree.graph import (generate_empty_md_graph,
generate_summary_graph_elements)
from peartree.paths import (FALLBACK_STOP_COST_DEFAULT,
_calculate_means_default,
get_representative_feed)
_calculate_means_default, get_representative_feed)


def fixture(filename):
Expand Down
3 changes: 1 addition & 2 deletions tests/test_graph_assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

from peartree.graph import generate_empty_md_graph, populate_graph
from peartree.paths import (FALLBACK_STOP_COST_DEFAULT,
_calculate_means_default,
get_representative_feed)
_calculate_means_default, get_representative_feed)
from peartree.summarizer import (generate_edge_and_wait_values,
generate_summary_edge_costs,
generate_summary_wait_times)
Expand Down
3 changes: 1 addition & 2 deletions tests/test_graph_tool.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import os
import pytest

from peartree.graph_tool import _import_graph_tool, nx_to_gt
from peartree.paths import load_synthetic_network_as_graph
Expand Down Expand Up @@ -30,7 +29,7 @@ def test_conversion_to_graph_tool():
# Make sure that the result is indeed a graph-tool Graph class object
gt = _import_graph_tool()
assert isinstance(gtG, gt.Graph)

# Also make sure that the attributes for all parameters have been preserved
assert set(gtG.vp.keys()) == set(('boarding_cost', 'id', 'x', 'y'))
assert set(gtG.gp.keys()) == set(('crs', 'name'))
Expand Down
2 changes: 0 additions & 2 deletions tests/test_paths.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import math
import os

import geopandas as gpd
Expand Down Expand Up @@ -319,7 +318,6 @@ def test_synthetic_stop_assignment_adjustment():
# The new graph should now be just (495 - 293) nodes
assert len(G2.nodes()) == 495 - 293


# We will use this as a reference distance limit for checking
# nearest points to ensure there are some adjusted stops matches
dist_limit = target_stop_dist_override * 0.5
Expand Down

0 comments on commit 0c5073d

Please sign in to comment.