Skip to content

Commit

Permalink
Initial swap out of TransitFeed for Partridge. (Fast-Trips#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
Clint Daniels committed Dec 11, 2017
1 parent 354551d commit 161a80c
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 159 deletions.
38 changes: 22 additions & 16 deletions fasttrips/FastTrips.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
limitations under the License.
"""
import os, sys
from operator import attrgetter
import pandas
import transitfeed

import partridge

from .Assignment import Assignment
from .Logger import FastTripsLogger, setupLogging
Expand Down Expand Up @@ -98,7 +97,7 @@ def __init__(self, input_network_dir, input_demand_dir, input_weights, run_confi
Assignment.OUTPUT_DIR = output_dir

#: transitfeed schedule instance. See https://github.com/google/transitfeed
self.gtfs_schedule = None
#self.gtfs_schedule = None

# setup logging
setupLogging(os.path.join(Assignment.OUTPUT_DIR, FastTrips.INFO_LOG % logname_append),
Expand Down Expand Up @@ -127,33 +126,40 @@ def read_input_files(self):

# Read the gtfs files first
FastTripsLogger.info("Reading GTFS schedule")
loader = transitfeed.Loader(Assignment.INPUT_NETWORK_DIR, memory_db=True)
self.gtfs_schedule = loader.Load()

if False:
# Validate the GTFS
FastTripsLogger.info("Validating GTFS schedule")
self.gtfs_schedule.Validate()
FastTripsLogger.info("Done validating GTFS schedule")
service_ids_by_date = partridge.read_service_ids_by_date(os.path.join(Assignment.INPUT_NETWORK_DIR, 'sample_gtfs.zip'))
service_ids = service_ids_by_date[Assignment.NETWORK_BUILD_DATE]
gtfs_feed = partridge.feed(os.path.join(Assignment.INPUT_NETWORK_DIR, 'sample_gtfs.zip'), view={
'trips.txt': {
'service_id': service_ids
},
})
#loader = transitfeed.Loader(Assignment.INPUT_NETWORK_DIR, memory_db=True)
#self.gtfs_schedule = loader.Load()

#if False:
# # Validate the GTFS
# FastTripsLogger.info("Validating GTFS schedule")
# self.gtfs_schedule.Validate()
# FastTripsLogger.info("Done validating GTFS schedule")

# Required: Trips, Routes, Stops, Stop Times, Agency, Calendar
# Optional: Transfers, Shapes, Calendar Dates...

# Read Stops (gtfs-required)
self.stops = Stop(Assignment.INPUT_NETWORK_DIR, Assignment.OUTPUT_DIR,
self.gtfs_schedule, Assignment.NETWORK_BUILD_DATE)
gtfs_feed, Assignment.NETWORK_BUILD_DATE)

# Read routes, agencies, fares
self.routes = Route(Assignment.INPUT_NETWORK_DIR, Assignment.OUTPUT_DIR,
self.gtfs_schedule, Assignment.NETWORK_BUILD_DATE, self.stops)
gtfs_feed, Assignment.NETWORK_BUILD_DATE, self.stops)

# Read Transfers
self.transfers = Transfer(Assignment.INPUT_NETWORK_DIR, Assignment.OUTPUT_DIR,
self.gtfs_schedule)
gtfs_feed)

# Read trips, vehicles, calendar and stoptimes
self.trips = Trip(Assignment.INPUT_NETWORK_DIR, Assignment.OUTPUT_DIR,
self.gtfs_schedule, Assignment.NETWORK_BUILD_DATE,
gtfs_feed, Assignment.NETWORK_BUILD_DATE,
self.stops, self.routes, Assignment.PREPEND_ROUTE_ID_TO_TRIP_ID)

# read the TAZs into a TAZ instance
Expand Down
84 changes: 44 additions & 40 deletions fasttrips/Route.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,29 +153,30 @@ class Route(object):
#: File with mode, mode number correspondence
OUTPUT_MODE_NUM_FILE = "ft_intermediate_supply_mode_id.txt"

def __init__(self, input_dir, output_dir, gtfs_schedule, today, stops):
def __init__(self, input_dir, output_dir, gtfs, today, stops):
"""
Constructor. Reads the gtfs data from the transitfeed schedule, and the additional
fast-trips routes data from the input file in *input_dir*.
"""
self.output_dir = output_dir

# Combine all gtfs Route objects to a single pandas DataFrame
route_dicts = []
for gtfs_route in gtfs_schedule.GetRouteList():
for gtfs_trip in gtfs_route.trips:
if gtfs_trip.service_period.IsActiveOn(today.strftime("%Y%m%d"), date_object=today):
route_dict = {}
for fieldname in gtfs_route._FIELD_NAMES:
if fieldname in gtfs_route.__dict__:
route_dict[fieldname] = gtfs_route.__dict__[fieldname]
route_dicts.append(route_dict)
break

self.routes_df = pandas.DataFrame(data=route_dicts)
#route_dicts = []
#for gtfs_route in gtfs_schedule.GetRouteList():
# for gtfs_trip in gtfs_route.trips:
# if gtfs_trip.service_period.IsActiveOn(today.strftime("%Y%m%d"), date_object=today):
# route_dict = {}
# for fieldname in gtfs_route._FIELD_NAMES:
# if fieldname in gtfs_route.__dict__:
# route_dict[fieldname] = gtfs_route.__dict__[fieldname]
# route_dicts.append(route_dict)
# break
#
#self.routes_df = pandas.DataFrame(data=route_dicts)
self.routes_df = gtfs.routes

FastTripsLogger.info("Read %7d %15s from %25d %25s" %
(len(self.routes_df), 'date valid route', len(gtfs_schedule.routes), 'total routes'))
(len(self.routes_df), 'date valid route', len(gtfs.routes), 'total routes'))

# Read the fast-trips supplemental routes data file
routes_ft_df = pandas.read_csv(os.path.join(input_dir, Route.INPUT_ROUTES_FILE),
Expand Down Expand Up @@ -226,37 +227,39 @@ def __init__(self, input_dir, output_dir, gtfs_schedule, today, stops):
(len(self.routes_df), "routes", "routes.txt", Route.INPUT_ROUTES_FILE))


agency_dicts = []
for gtfs_agency in gtfs_schedule.GetAgencyList():
agency_dict = {}
for fieldname in gtfs_agency._FIELD_NAMES:
if fieldname in gtfs_agency.__dict__:
agency_dict[fieldname] = gtfs_agency.__dict__[fieldname]
agency_dicts.append(agency_dict)
self.agencies_df = pandas.DataFrame(data=agency_dicts)
#agency_dicts = []
#for gtfs_agency in gtfs_schedule.GetAgencyList():
# agency_dict = {}
# for fieldname in gtfs_agency._FIELD_NAMES:
# if fieldname in gtfs_agency.__dict__:
# agency_dict[fieldname] = gtfs_agency.__dict__[fieldname]
# agency_dicts.append(agency_dict)
#self.agencies_df = pandas.DataFrame(data=agency_dicts)
self.agencies_df = gtfs.agency

FastTripsLogger.debug("=========== AGENCIES ===========\n" + str(self.agencies_df.head()))
FastTripsLogger.debug("\n"+str(self.agencies_df.dtypes))
FastTripsLogger.info("Read %7d %15s from %25s" %
(len(self.agencies_df), "agencies", "agency.txt"))

fare_attr_dicts = []
fare_rule_dicts = []
for gtfs_fare_attr in gtfs_schedule.GetFareAttributeList():
fare_attr_dict = {}
for fieldname in gtfs_fare_attr._FIELD_NAMES:
if fieldname in gtfs_fare_attr.__dict__:
fare_attr_dict[fieldname] = gtfs_fare_attr.__dict__[fieldname]
fare_attr_dicts.append(fare_attr_dict)

for gtfs_fare_rule in gtfs_fare_attr.GetFareRuleList():
fare_rule_dict = {}
for fieldname in gtfs_fare_rule._FIELD_NAMES:
if fieldname in gtfs_fare_rule.__dict__:
fare_rule_dict[fieldname] = gtfs_fare_rule.__dict__[fieldname]
fare_rule_dicts.append(fare_rule_dict)

self.fare_attrs_df = pandas.DataFrame(data=fare_attr_dicts)
#fare_attr_dicts = []
#fare_rule_dicts = []
#for gtfs_fare_attr in gtfs_schedule.GetFareAttributeList():
# fare_attr_dict = {}
# for fieldname in gtfs_fare_attr._FIELD_NAMES:
# if fieldname in gtfs_fare_attr.__dict__:
# fare_attr_dict[fieldname] = gtfs_fare_attr.__dict__[fieldname]
# fare_attr_dicts.append(fare_attr_dict)
#
# for gtfs_fare_rule in gtfs_fare_attr.GetFareRuleList():
# fare_rule_dict = {}
# for fieldname in gtfs_fare_rule._FIELD_NAMES:
# if fieldname in gtfs_fare_rule.__dict__:
# fare_rule_dict[fieldname] = gtfs_fare_rule.__dict__[fieldname]
# fare_rule_dicts.append(fare_rule_dict)
#
#self.fare_attrs_df = pandas.DataFrame(data=fare_attr_dicts)
self.fare_attrs_df = gtfs.fare_attributes

FastTripsLogger.debug("=========== FARE ATTRIBUTES ===========\n" + str(self.fare_attrs_df.head()))
FastTripsLogger.debug("\n"+str(self.fare_attrs_df.dtypes))
Expand Down Expand Up @@ -290,7 +293,8 @@ def __init__(self, input_dir, output_dir, gtfs_schedule, today, stops):
self.fare_by_class = False

# Fare rules (map routes to fare_id)
self.fare_rules_df = pandas.DataFrame(data=fare_rule_dicts)
#self.fare_rules_df = pandas.DataFrame(data=fare_rule_dicts)
self.fare_rules_df = gtfs.fare_rules
if len(self.fare_rules_df) > 0:
self.fare_ids_df = Util.add_numeric_column(self.fare_rules_df[[Route.FARE_RULES_COLUMN_FARE_ID]],
id_colname=Route.FARE_RULES_COLUMN_FARE_ID,
Expand Down
27 changes: 14 additions & 13 deletions fasttrips/Stop.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class Stop:
#: File with stop ID, stop ID number correspondence
OUTPUT_STOP_ID_NUM_FILE = 'ft_intermediate_stop_id.txt'

def __init__(self, input_dir, output_dir, gtfs_schedule, today):
def __init__(self, input_dir, output_dir, gtfs, today):
"""
Constructor. Reads the gtfs data from the transitfeed schedule, and the additional
fast-trips stops data from the input files in *input_dir*.
Expand All @@ -81,20 +81,21 @@ def __init__(self, input_dir, output_dir, gtfs_schedule, today):

# Combine all gtfs Stop objects to a single pandas DataFrame
stop_dicts = []
for gtfs_stop in gtfs_schedule.GetStopList():
for gtfs_trip in gtfs_stop.GetTrips():
if gtfs_trip.service_period.IsActiveOn(today.strftime("%Y%m%d"), date_object=today):
stop_dict = {}
for fieldname in gtfs_stop._FIELD_NAMES:
if fieldname in gtfs_stop.__dict__:
stop_dict[fieldname] = gtfs_stop.__dict__[fieldname]
stop_dicts.append(stop_dict)
break

self.stops_df = pandas.DataFrame(data=stop_dicts)
#for gtfs_stop in gtfs_schedule.GetStopList():
# for gtfs_trip in gtfs_stop.GetTrips():
# if gtfs_trip.service_period.IsActiveOn(today.strftime("%Y%m%d"), date_object=today):
# stop_dict = {}
# for fieldname in gtfs_stop._FIELD_NAMES:
# if fieldname in gtfs_stop.__dict__:
# stop_dict[fieldname] = gtfs_stop.__dict__[fieldname]
# stop_dicts.append(stop_dict)
# break

#self.stops_df = pandas.DataFrame(data=stop_dicts)
self.stops_df = gtfs.stops

FastTripsLogger.info("Read %7d %15s from %25d %25s" %
(len(self.stops_df), 'date valid stop', len(gtfs_schedule.stops), 'total stops'))
(len(self.stops_df), 'date valid stop', len(gtfs.stops), 'total stops'))

# Read the fast-trips supplemental stops data file. Make sure stop ID is read as a string.
if os.path.exists(os.path.join(input_dir, Stop.INPUT_STOPS_FILE)):
Expand Down
70 changes: 36 additions & 34 deletions fasttrips/Transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,47 +91,49 @@ class Transfer:
#: initialize_fasttrips_extension() because of the strings involved
OUTPUT_TRANSFERS_FILE = "ft_intermediate_transfers.txt"

def __init__(self, input_dir, output_dir, gtfs_schedule):
def __init__(self, input_dir, output_dir, gtfs_feed):
"""
Constructor. Reads the gtfs data from the transitfeed schedule, and the additional
fast-trips transfers data from the input files in *input_dir*.
"""
self.output_dir = output_dir

# Combine all gtfs Transfer objects to a single pandas DataFrame
transfer_dicts = []
for gtfs_transfer in gtfs_schedule.GetTransferList():
transfer_dict = {}
for fieldname in gtfs_transfer._FIELD_NAMES:
if fieldname in gtfs_transfer.__dict__:
transfer_dict[fieldname] = gtfs_transfer.__dict__[fieldname]
transfer_dicts.append(transfer_dict)
if len(transfer_dicts) > 0:
self.transfers_df = pandas.DataFrame(data=transfer_dicts)

# these are strings - empty string should mean 0 min transfer time
self.transfers_df.replace(to_replace={Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME:{"":"0"}},
inplace=True)
# make it numerical
self.transfers_df[Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME] = \
self.transfers_df[Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME].astype(float)

# make it zero if transfer_type != 2, since that's the only time it applies
self.transfers_df.loc[self.transfers_df[Transfer.TRANSFERS_COLUMN_TRANSFER_TYPE] != 2, \
Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME] = 0

# these are from transfers.txt so they don't involve lots
self.transfers_df[Transfer.TRANSFERS_COLUMN_STOP_TO_STOP] = True

else:
self.transfers_df = pandas.DataFrame(columns=[Transfer.TRANSFERS_COLUMN_FROM_STOP,
Transfer.TRANSFERS_COLUMN_FROM_STOP_NUM,
Transfer.TRANSFERS_COLUMN_TO_STOP,
Transfer.TRANSFERS_COLUMN_TO_STOP_NUM,
Transfer.TRANSFERS_COLUMN_TIME,
Transfer.TRANSFERS_COLUMN_TIME_MIN])
# set this up as a boolean column
self.transfers_df[Transfer.TRANSFERS_COLUMN_STOP_TO_STOP] = True
#transfer_dicts = []
#for gtfs_transfer in gtfs_schedule.GetTransferList():
# transfer_dict = {}
# for fieldname in gtfs_transfer._FIELD_NAMES:
# if fieldname in gtfs_transfer.__dict__:
# transfer_dict[fieldname] = gtfs_transfer.__dict__[fieldname]
# transfer_dicts.append(transfer_dict)
#self.transfers_df = gtfs_feed.transfers
#if len(transfer_dicts) > 0:
# self.transfers_df = pandas.DataFrame(data=transfer_dicts)
self.transfers_df = gtfs_feed.transfers

# these are strings - empty string should mean 0 min transfer time
#self.transfers_df.replace(to_replace={Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME:{"":"0"}},
# inplace=True)
# make it numerical
self.transfers_df[Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME] = \
self.transfers_df[Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME].astype(float)

# make it zero if transfer_type != 2, since that's the only time it applies
self.transfers_df.loc[self.transfers_df[Transfer.TRANSFERS_COLUMN_TRANSFER_TYPE] != 2, \
Transfer.TRANSFERS_COLUMN_MIN_TRANSFER_TIME] = 0

# these are from transfers.txt so they don't involve lots
self.transfers_df[Transfer.TRANSFERS_COLUMN_STOP_TO_STOP] = True

#else:
# self.transfers_df = pandas.DataFrame(columns=[Transfer.TRANSFERS_COLUMN_FROM_STOP,
# Transfer.TRANSFERS_COLUMN_FROM_STOP_NUM,
# Transfer.TRANSFERS_COLUMN_TO_STOP,
# Transfer.TRANSFERS_COLUMN_TO_STOP_NUM,
# Transfer.TRANSFERS_COLUMN_TIME,
# Transfer.TRANSFERS_COLUMN_TIME_MIN])
# # set this up as a boolean column
# self.transfers_df[Transfer.TRANSFERS_COLUMN_STOP_TO_STOP] = True

# Read the fast-trips supplemental transfers data file
transfers_ft_df = pandas.read_csv(os.path.join(input_dir, Transfer.INPUT_TRANSFERS_FILE),
Expand Down
Loading

0 comments on commit 161a80c

Please sign in to comment.