From 2451df9d3a61641c2908ae29515e92c6b1f742d5 Mon Sep 17 00:00:00 2001 From: Elizabeth Sall Date: Mon, 8 May 2017 15:10:58 -0700 Subject: [PATCH] Add tests, test documentation - added tests for user class, multiple processes, feedback, and assignment type. - added script for running the example. - updated documentation on running the tests. - update documentation on running the example. --- .cache/v/cache/lastfailed | 16 +++++++ README.md | 74 +++++++++++++++++++++++--------- scripts/run_example.py | 20 +++++++++ tests/test_assignment_type.py | 52 ++++++++++++++++++++++ tests/test_feedback.py | 50 +++++++++++++++++++++ tests/test_multiple_processes.py | 29 +++++++++++++ tests/test_user_classes.py | 31 +++++++++++++ 7 files changed, 252 insertions(+), 20 deletions(-) create mode 100644 .cache/v/cache/lastfailed create mode 100644 scripts/run_example.py create mode 100644 tests/test_assignment_type.py create mode 100644 tests/test_feedback.py create mode 100644 tests/test_multiple_processes.py create mode 100644 tests/test_user_classes.py diff --git a/.cache/v/cache/lastfailed b/.cache/v/cache/lastfailed new file mode 100644 index 00000000..0de197d7 --- /dev/null +++ b/.cache/v/cache/lastfailed @@ -0,0 +1,16 @@ +{ + "tests/test_assignment_type.py::test_deterministic": true, + "tests/test_assignment_type.py::test_stochastic": true, + "tests/test_dispersion.py::test_dispersion": true, + "tests/test_fares.py::test_fares_nopf": true, + "tests/test_fares.py::test_fares_nopf_nopf": true, + "tests/test_feedback.py::test_fares_nopf_nopf": true, + "tests/test_maxStopProcessCount.py::test_max_stop_process_count": true, + "tests/test_overlap.py::test_overlap_count": true, + "tests/test_overlap.py::test_overlap_count_with_split": true, + "tests/test_overlap.py::test_overlap_distance": true, + "tests/test_overlap.py::test_overlap_distance_with_split": true, + "tests/test_overlap.py::test_overlap_none": true, + "tests/test_overlap.py::test_overlap_time": true, + "tests/test_overlap.py::test_overlap_time_with_split": true +} \ No newline at end of file diff --git a/README.md b/README.md index b812ddb1..d5422cd0 100644 --- a/README.md +++ b/README.md @@ -236,48 +236,82 @@ There are four places where fares factor into fast-trips. 4. During simulation (python), while the path is being adjusted due to vehicle times, the fares are calculated via [`Route.add_fares()`](fasttrips/Route.py). This is unlikely to change anything unless the fare periods changed due to the slow-down of vehicles -- so consider deprecating this in favor of using the pathfinding results? For now, it's a good test that the C++ code is working as expected; running with simulation off should result in identical fare and cost results from pathfinding and the (non-vehicle-updating) python simulation. -## Test Sample Input +## Running the Example + +Sample input files have been provided in `\Examples\test_network` to test the setup and also assist with the creation of new fast-trips runs. The input files include network files created from a small hypothetical network and also example transit demand data. + +To run the example: +* Make sure your `` is in your `PYTHONPATH` environment variable in *Advanced system settings* [Win] or terminal [OSX]. +* Run `python run_example.py` from within `\scripts` in a command prompt [ Win ] or terminal [ OSX ]. -Sample input files have been provided in `\Examples\test_network` to test the setup and also assist with the creation of new fast-trips runs. The input files include network files created from a small hypothetical test network and also example transit demand data. -To quickly test the setup, run fast-trips on sample input using the following steps: -* Add `` to the `PYTHONPATH` environment variable in *Advanced system settings*. -* Run `\scripts\runAllTests.bat` from within `` in a command prompt. This will run several "preset" parameter combinations. The user can alternatively run each parameter combination individually using the commands listed in the batch file. Details about the test runs are provided in subsequent sections. Output files from running fast-trips with the sample input data provided can be found in the `output` directory. -### Test Network -A hypothetical 5-zone test network was developed to help code development. It has a total of three transit routes (one rail and two bus) with two or three stops each. There are also two park-and-ride (PnR) locations. +### Example Network +A hypothetical 5-zone example network was developed to help code development. It has a total of three transit routes (one rail and two bus) with two or three stops each. There are also two park-and-ride (PnR) locations. -![alt text](/Examples/test_network/input/test_network.png "Transit Test Network") +![alt text](/Examples/example_network/input/test_network.png "Transit Example Network") Transit vehicles commence at 3:00 PM and continue until 6:00 PM. There are 152 transit trips that make a total of 384 station stops. `input` folder contains all the supply-side/network input files prepared from the test network. More information about network input file standards can be found in the [GTFS-Plus Data Standards Repository][network-standard-url]. -### Test Demand +### Example Demand Two versions of sample demand have been prepared: * `demand_reg` contains regular demand that consists only of a transit trip list. There are no multiple user classes and all trips use a single set of path weights (`pathweight_ft.txt`). Demand starts at 3:15 PM and ends at 5:15 PM.One trip occurs every 10 seconds. More information is available in [documentation](/Examples/test_network/demand_reg/Readme.md). * `demand_twopaths` represents demand for two user classes that use different sets of path weights. Household and person attribute files are present in addition to the trip list to model user heterogeneity and multiple user classes. Similar to network data standards, there also exists a [Demand Data Standards Repository][demand-standard-url]. -## Test Runs -There are a total of six test runs in `\scripts\runAllTests.bat`. Type of assignment, capacity constraint, and number of iterations are varied in addition to the demand. -| Sno | Demand | Assignment Type | Iterations | Capacity Constraint | -|------:|:-------:|:---------------:|-----------:|:-------------------:| -| 1 | Multi-class | Deterministic | 2 | On | -| 2 | Multi-class | Stochastic | 1 | Off | -| 3 | Multi-class | Stochastic | 2 | On | -| 4 | Regular | Deterministic | 2 | On | -| 5 | Regular | Stochastic | 1 | Off | -| 6 | Regular | Stochastic | 2 | On | +## Tests +There are multiple test runs in `\tests`. They can be run by installing the [PyTest](https://docs.pytest.org/en/latest/) library and executing the command `pytest` from the command line within your ``. + +__Fares:__ `test_maxStopProcessCount.py` + +Tests 10, 50, and 100 for the value of `max stop process count` – the maximum number of times you will re-processe a node (default: None) + + * **Overlap Variable:** `count`, `distance`, `time` + * **Overlap Split:** Boolean + +__Fares:__ `test_fares.py` + +Tests shortcuts in fare calculations + + * **Ignore Pathfinding** + * **Ignore Pathfinding and Path Enumeration** + +__Overlap Functions:__ `test_overlap.py` + +Tests both overlap type and whether or not each transit segment is broken and compared to each of its parts. + + * **Overlap Variable:** `count`, `distance`, `time` + * **Overlap Split:** Boolean + +__Feedback:__ `test_feedback.py` + + * Runs full demand for three iterations with and without capacity constraint + +__Dispersion Levels:__ `test_dispersion.py` + + * Runs dispersion levels 0.1 to 1.0 at 0.1 increments + +__User Classes:__ `test_user_classes.py` + + * Uses multiple user classes as defined in `config_ft.py` + +__Multiple Processes:__ `test_multiple_processes.py` + + * Runs model with two processes. + +__Assignment Type:__ `test_assignment_type.py` -Type of Assignment: * "Deterministic" indicates use of a deterministic trip-based shortest path search algorithm * "Stochastic" indicates use of a stochastic hyperpath-finding algorithm + ## Summarizing Results Fast-Trips will output results in the [dyno-path](https://github.com/osplanning-data-standards/dyno-path) format, which can be used to generate summary dashboards in Tableau or other reports. + ### Creating Tableau Dashboard diff --git a/scripts/run_example.py b/scripts/run_example.py new file mode 100644 index 00000000..465e8b23 --- /dev/null +++ b/scripts/run_example.py @@ -0,0 +1,20 @@ +import os + +from fasttrips import Run + +EXAMPLES_DIR = os.path.join(os.path.dirname(os.getcwd()),"Examples","test_scenario") + +Run.run_fasttrips( + input_net_dir = os.path.join(EXAMPLES_DIR,"network"), + input_demand_dir = os.path.join(EXAMPLES_DIR,"demand_reg"), + run_config = os.path.join(EXAMPLES_DIR,"demand_reg","config_ft.txt"), + input_weights = os.path.join(EXAMPLES_DIR,"demand_reg","pathweight_ft.txt"), + output_dir = os.path.join(EXAMPLES_DIR,"output"), + output_folder = "example", + pathfinding_type = "stochastic", + overlap_variable = "count", + overlap_split_transit = True, + iters = 1, + dispersion = 0.50) + + \ No newline at end of file diff --git a/tests/test_assignment_type.py b/tests/test_assignment_type.py new file mode 100644 index 00000000..f2566fb1 --- /dev/null +++ b/tests/test_assignment_type.py @@ -0,0 +1,52 @@ +import os + +import pytest + +import fasttrips +from fasttrips import Run + + +def test_deterministic(): + + EXAMPLES_DIR = os.path.join(os.getcwd(),"Examples","test_scenario") + + INPUT_NETWORKS = os.path.join(EXAMPLES_DIR,"network") + INPUT_DEMAND = os.path.join(EXAMPLES_DIR,"demand_reg") + OUTPUT_DIR = os.path.join(EXAMPLES_DIR,"output") + + r = Run.run_fasttrips( + input_net_dir = INPUT_NETWORKS, + input_demand_dir = INPUT_DEMAND, + run_config = os.path.join(INPUT_DEMAND,"config_ft.txt"), + input_weights = os.path.join(INPUT_DEMAND,"pathweight_ft.txt"), + output_dir = OUTPUT_DIR, + output_folder = "test_deterministic", + pathfinding_type = "deterministic", + iters = 1, + dispersion = 0.50, + test_size = 100) + + assert r["passengers_arrived"] > 0 + + +def test_stochastic(): + + EXAMPLES_DIR = os.path.join(os.getcwd(),"Examples","test_scenario") + + INPUT_NETWORKS = os.path.join(EXAMPLES_DIR,"network") + INPUT_DEMAND = os.path.join(EXAMPLES_DIR,"demand_reg") + OUTPUT_DIR = os.path.join(EXAMPLES_DIR,"output") + + r = Run.run_fasttrips( + input_net_dir = INPUT_NETWORKS, + input_demand_dir = INPUT_DEMAND, + run_config = os.path.join(INPUT_DEMAND,"config_ft.txt"), + input_weights = os.path.join(INPUT_DEMAND,"pathweight_ft.txt"), + output_dir = OUTPUT_DIR, + output_folder = "test_stochastic", + pathfinding_type = "stochastic", + iters = 1, + dispersion = 0.50, + test_size = 100) + + assert r["passengers_arrived"] > 0 \ No newline at end of file diff --git a/tests/test_feedback.py b/tests/test_feedback.py new file mode 100644 index 00000000..2e6c4101 --- /dev/null +++ b/tests/test_feedback.py @@ -0,0 +1,50 @@ +import os + +import pytest + +from fasttrips import Run + + +def test_feedback_no_cap_const(): + + EXAMPLES_DIR = os.path.join(os.getcwd(),"Examples","test_scenario") + + INPUT_NETWORKS = os.path.join(EXAMPLES_DIR,"network") + INPUT_DEMAND = os.path.join(EXAMPLES_DIR,"demand_reg") + OUTPUT_DIR = os.path.join(EXAMPLES_DIR,"output") + + r = Run.run_fasttrips( + input_net_dir = INPUT_NETWORKS, + input_demand_dir = INPUT_DEMAND, + run_config = os.path.join(INPUT_DEMAND,"config_ft.txt"), + input_weights = os.path.join(INPUT_DEMAND,"pathweight_ft.txt"), + output_dir = OUTPUT_DIR, + output_folder = "test_feedback_no_cap_const", + pathfinding_type = "stochastic", + capacity = False, + iters = 3, + dispersion = 0.50) + + assert r["passengers_arrived"] > 0 + +def test_feedback_with_cap_const(): + + EXAMPLES_DIR = os.path.join(os.getcwd(),"Examples","test_scenario") + + INPUT_NETWORKS = os.path.join(EXAMPLES_DIR,"network") + INPUT_DEMAND = os.path.join(EXAMPLES_DIR,"demand_reg") + OUTPUT_DIR = os.path.join(EXAMPLES_DIR,"output") + + r = Run.run_fasttrips( + input_net_dir = INPUT_NETWORKS, + input_demand_dir = INPUT_DEMAND, + run_config = os.path.join(INPUT_DEMAND,"config_ft.txt"), + input_weights = os.path.join(INPUT_DEMAND,"pathweight_ft.txt"), + output_dir = OUTPUT_DIR, + output_folder = "test_feedback_with_cap_const", + pathfinding_type = "stochastic", + capacity = True, + iters = 3, + dispersion = 0.50) + + assert r["passengers_arrived"] > 0 \ No newline at end of file diff --git a/tests/test_multiple_processes.py b/tests/test_multiple_processes.py new file mode 100644 index 00000000..334cb062 --- /dev/null +++ b/tests/test_multiple_processes.py @@ -0,0 +1,29 @@ +import os + +import pytest + +import fasttrips +from fasttrips import Run + + +def test_multiple_processes(): + + EXAMPLES_DIR = os.path.join(os.getcwd(),"Examples","test_scenario") + + INPUT_NETWORKS = os.path.join(EXAMPLES_DIR,"network") + INPUT_DEMAND = os.path.join(EXAMPLES_DIR,"demand_reg") + OUTPUT_DIR = os.path.join(EXAMPLES_DIR,"output") + + r = Run.run_fasttrips( + input_net_dir = INPUT_NETWORKS, + input_demand_dir = INPUT_DEMAND, + run_config = os.path.join(INPUT_DEMAND,"config_ft.txt"), + input_weights = os.path.join(INPUT_DEMAND,"pathweight_ft.txt"), + output_dir = OUTPUT_DIR, + output_folder = "test_2processes", + pathfinding_type = "stochastic", + number_of_processes = 2, + iters = 1, + dispersion = 0.50 ) + + assert r["passengers_arrived"] > 0 diff --git a/tests/test_user_classes.py b/tests/test_user_classes.py new file mode 100644 index 00000000..37ebaae2 --- /dev/null +++ b/tests/test_user_classes.py @@ -0,0 +1,31 @@ +import os + +import pytest + +import fasttrips +from fasttrips import Run + + +def test_user_classes(): + + EXAMPLES_DIR = os.path.join(os.getcwd(),"Examples","test_scenario") + + INPUT_NETWORKS = os.path.join(EXAMPLES_DIR,"network") + INPUT_DEMAND = os.path.join(EXAMPLES_DIR,"demand_twopaths") + OUTPUT_DIR = os.path.join(EXAMPLES_DIR,"output") + + r = Run.run_fasttrips( + input_net_dir = INPUT_NETWORKS, + input_demand_dir = INPUT_DEMAND, + run_config = os.path.join(INPUT_DEMAND,"config_ft.txt"), + input_weights = os.path.join(INPUT_DEMAND,"pathweight_ft.txt"), + input_functions = os.path.join(INPUT_DEMAND,"config_ft.py"), + output_dir = OUTPUT_DIR, + output_folder = "test_userclasses", + pathfinding_type = "stochastic", + iters = 1, + dispersion = 0.50, + test_size = 100) + + assert r["passengers_arrived"] > 0 +