


                   TRIP DATA ANALYIS SCRIPT FOR SUMO simulations
                 *************************************************

 Author:                   Maximilian Sievers, B.Sc.
 Start of development:     29-05-2023
 Latest update:            01-08-2023

 This Python 3 script works with SUMO simulation data created with and without SUMOPy.
 (tested with Python 3.7)

 It analyzes the trip data and calculates several KPIs (key performance indicators),
 plots the data and saves it to a .csv file.


 a) HOW to CREATE the PROPER xml file for this script TO ANALYZE TRIP DATA:

    I)   If you are launching SUMO simulations from SUMOPy:
         In order for SUMOPy to generate the correct SUMO files, you MUST select the options:
          - Output Trip Data
          - Include Unifinished Trip Data
         After the SUMO simulation launched via SUMOPy has finished,
         the file containing the necessary trip data xml-file will have been generated
         in the same folder as your SUMOPy scenario
         ( SUMOPy scenarios are stored as  .obj  files)
         With SUMOPy, this tripdata file has the file-ending  .tripdata.xml 

    II)  If you are running SUMO simulation created WIHOUT SUMOPy:
         Before running the simulation, ensure the following parameters are included in
         the main SUMO config file. This file usually ends with .sumocfg 
         The .sumocfg file should contain the following lines of code:
        
         <configuration ...>
             ...
             <output>
	                <tripinfo-output value="output\tripinfo_output.xml"/>
	                <tripinfo-output.write-unfinished value="true"/>
             </output>
             ...
         </configuration>
        
         Note: the name of the .xml file containing the trip data is arbitrary wrt to this script.
              However: SUMO and SUMOPy name this same file differently.
              The SUMO website refers to it as: tripinfo file    or  tripinfo_output.xml
              https://sumo.dlr.de/docs/Simulation/Output/TripInfo.html
        
         Note: SUMOPy, on the other hand, names it the file:                    .out.tripdata.xml
               Given a SUMOPy scenario file named myscenario.obj,
               the tripdata file will be named:                       myscenario.out.tripdata.xml

         NAMING CONVENTION FOR THIS SCRIPT:
         The file containing the tripdata/tripinfo is REFERRRED TO AS THE TRIPDATA(.XML) FILE.
        
    III) Info for running SUMO simulations generated by SUMOPy scenarios on PCs without SUMOPy:
         If you have a (powertful) computer for running SUMO simulations,
         and you want to run a SUMOPy simulation on it, but SUMOPy is not installed there:
         you can run SUMO simulation files generated by SUMOPy without needing to install SUMOPy.
         This workaround does give access to many SUMOPy-specific-simulation features,
         but it can be a useful if SUMOPy is not installed.v
         Note: Usually, the main file you run with SUMO has the file ending .sumocfg
               When SUMOPy generates SUMO files, this same file has the file ending .netc
               E.g., the sumopy scenario myscenario.obj will generate the file myscenario.netc
               The .sumocfg and .netc files are exactly the same xml file type.
               Both can be opened and run with SUMO.
         
     IV) In addition to the tripdata.xml file (1st argument), containing the executed trips,
         this script also requires the xml file with all the planned trips (2nd argument).
         This second file is one of the SUMO simulation input files, required for SUMO to run.
         When generating SUMO scenarios via SUMOPy (e.g. using the SUMOPy scenario myscenario.obj),
         this xml file has the ending .rou.xml (e.g. myscenario.rou.xml).
         If you are not generating SUMO files via SUMOPy,
         this file may be called .rou.xml, .trips.xml, .demand.xml, etc., 
         dpending on local/team/company conventions.
         This .rou.xml file is necessary because the vehicle id of unfinished ride stages
         of a person trip is often listed as "NULL".
         If this is the case, the .tripdata.xml file provides no information
         on what vehicle this is.
         By using the person id from the tripdata.xml file
         and looking up that id in the .rou.xml file,
         the originally intended vehicle can be retrieved,
         which is essential for calculating the modal split.
         
      V) SUMO XML common file endings and names recap:
         No binding SUMO conventions exist, file names and file endings fully customizable.
         The following table merely contains common file names and endings.
         ( --> If in doubt, check xml file contents to be sure.)
         (     Example .tripdata.xml and .rou.xml file included in this /scripts folder)
         
                                              |          SUMO         |       SUMOPy
         _______________________________________________________________________________
          File containing executed trip data: |  tripinfo_output.xml, |   .tripdata.xml
           (1st argument to run this script)  |         etc.          |
         _______________________________________________________________________________
          File containing planned trip data:  | .rou.xml, .trips.xml, |    .rou.xml
           (2nd argument to run this script)  |    .demand.xml,  etc. |
         _______________________________________________________________________________
           SUMO simulation config file:       |      .sumocfg         |     .netc
           (main file to run the SUMO sim)    |                       |

 ***************************************************************************************************

 b) IN GENERAL, ONLY the INTERNAL DEMAND is ANALYZED by this script,
     
    i.e. data saved in personinfo objects in the tripdata.xml file created by SUMO.
    A personinfo object contains all trip stages,of member of the virtual population.
    Of course, external demand may affect the trips of the internal demand,
    e.g. through traffic jams.
    However, since these external trips are only passing through the network,
    values such as door-door-travel times cannot be calculated for them.
    Furthermore, since the modal split of the external demand cannot be influenced by SUMOPy,
    the modal split of the external demand is not accounted for in the modal split
    calcuted by this script.
    Only the modal split of the internal demand
    can be adjusted by SUMOPy optimization algorithms,
    e.g. by iterating the simulation and subsequently reselecting the mode
    for each virtual person after each simulation iteration,
    e.g., based on the shortes executed travel time.
    Use the script runSimulation.py to find the optimum mode choice
    for the virtual population/internal demand
    by iterating SUMOPy simulations with the following script:
    runSimulation.
    The runSimulation.py script uses python 2.7 (like SUMOPy).
    It is located in this git repository under:
    Simulation/runSimulation.py
     
    RECAP: MODAL SPLIT = modal split OF INTERNAL DEMAND (= from virtual population),
    ******************   BASED ON the MODE OF transport
                         from the FIRST RIDE STAGE
                         OR LACK OF RIDE STAGES
                         of each personinfo object in the tripdata.xml file.
                         If there are no ride stages,
                         the trip is counted as a walk trip in the modal split
                         Both finished and unfinished trips are used
                         for calculating the model split.
                         (unfinished trips explained in part d) )
     
    IMPORTANT INFO regarding UNEXPECTED TAXIS / SAVs (SUMOPy only):
    Even if NO SAVs (shared autonomous vehicles) and/or NO PRIVATE TAXIS
    have been added to a SUMOPy scenario,
    SOME SAV or PRIVATE TAXI trips may still appear in the modal split.
    This is due to a backup-transport-mode feature of SUMOPy:
    If the selected mode of transport of a virtual person
    is passenger vehicle (a normal private car),
    but a normal passenger vehicle cannot access the origin or destination,
    the backup mode of tranport is chosen: the taxi mode.
    Since private taxis and SAVs are each a separate taxi fleet,
    either an SAV or a private Taxi may spawn in the simulation as the backup vehicle,
    parked in the virtual persons home or place of work like a private passenger vehicle.
    This private Taxi or SAV acts entirely like a private passenger vehicle
    belonging to that person, except that the vehicle looks
    like a private Taxi or SAV. No other persons are picked up.
    These backup private taxis / SAVs are quite rare, but they may appear.
    If the person makes use of such a backup taxi,
    their trip is accounted for as any normal private Taxi or SAV trip 
    in the modal split calculated by this script.

 ***************************************************************************************************

 c) The EXTERNAL DEMAND, however, is INCLUDED IN the analysis of the TOTAL TRAVELLED KM PER MODE.
     
    In the tripdata.xml,
    data of members of the virtual population (internal demand) is stored in personinfo objects.
    Vehicle-related data is stored in tripinfo objects.
    These tripinfo objects exist for all vehicles,
    regardless if they represent internal or external demand.
    Therefore, if you want to analyze vehicle data which is independent of the persons
    using the vehicle, you need to analyze the tripinfo objects.
    This is the case for all data related to traffic from the external demand
    (no virtual persons are riding in vehicles from the external demand)
    This also applies for all non-private vehicles, e.g., public transportation (PT), 
    private taxis and shared-autonomous vehicles (SAVs).

 ***************************************************************************************************

 d) Info regarding (UN-)FINISHED TRIPs and STAGES:
     
    I)   This script has only been tested on 1-way-trips without return-trips.
         (e.g., morning rush hour simulation with every virt. person heading from home to work)
         It should be able to calculate most values accurately for return trips as well.
         (such as average speed, travel time or travelled distance)
         BUT: since the modal split is based on the mode of the first ride stage 
         (or lack thereof) of a personinfo object,
         the modal split may not be accurate
         if the mode(s) selected for the outbound trip stages
         differ from the mode(s) of the return trip stages.
         (trips and stages explained below)
     
    II)  In general, 1 personinfo object = 1 trip by a virtual person
         A trip is always started if the start time of the trip lies
         between the start time end time of the simulation.
         Not-yet-started trips create no personinfo object and
         do not appear in the tripdata.xml file.

    III) 1 trip may consist of several stages: walk, stop or ride.
         Each stage type may appear several times, once or not at all.

    IV)  If any of the walk or ride stages include negative data (for times and distance),
         this means the stage, and therefore the whole trip, is unfinished.
         If all walk and ride stages have only positive data, that means the trip is finished
         and the destination has been reached before the end of the simulation.
         Stop stages represent planned stationary activities, e.g. being at work.
         Given that the standstill time during a stop stage is desired 
         in order to complete the activity,
         stop stages do not influence any traffic KPIs calculated by this script.
         The aforementioned logic (trips only count as finished if all non-stop stages finished)
         means that if you have virtual persons with a ride or walk stages after a stop stage,
         if the stop stage has not reached its planned end-point before the end of the simulation.
         If the simulation is only conducted from, e.g., 6 to 8 a.m.,
         but the stop stage lasts until 10 a.m., and there are walk or ride stages afterwards,
         these walk or ride stages can never be finished, no matter how well traffic flows.
         The whole trip will be unfinished and no trip data can be analyzed.
         Therefore, one of the following options must be fulfilled
         in order for this script to analyze the trip data of the virtual population:
         - either have no stop stages (e.g. for 1-way rush hour simulations)
         - make sure the stop stage is the last stage
         - or be sure that all stop stages end well before the end of the simulation,
           so the virutal population has a chance to complete
           the other stages under the expected traffic

    V)   Only already-started trips exist in the tripdata.xml file
         all trips by the virtual population (stored in personinfo objects)
         in the tripdata.xml file
         are taken into account for calculating the modal split,
         both finished and unfinished trips.

    VI) Unfinished trips are only taken into account for 2 purposes:
         - calculating the modal split
         - calculating the total kilometers driven per mode
         The unfinished trips must be taken into account for the total kilometers driven,
         since taxi and SAV are never finished.
         Since vehicles are removed from a SUMO simulation once their trip has finished,
         a taxi/SAV which has finished its trip would not be able to exist without passengers.
         Thanks to their never-finishing trips, taxis and SAVs can stay idle 
         and move around the simulation without passengers by being assigned to them.
         The negative values inherent to unfinished trips are irrevelant to total km driven,
         since for vehicle data (stored in tripinfo objects),
         the driven distance (routeLength) is always positive
         (others values may be negative).
 
    VII) Since unfinished virtual person trips have stages with negative trip data
         (e.g., negative arrival times),
         they are ignored for the calculation of all other KPIs
         in this tripdata analysis script.
         Given that the route length of walk stages lies within personinfo objects,
         which only have negative data for unfinished stages,
         it is not possible to calculate the total km walked
         during all finished and unfinished walk stages.
         Therefore, only the total km driven by vehicles is calculated (see VI)
         Unfinished person trips are only relevant for the modal split.

 ***************************************************************************************************

 e) Suggestions for IMPROVING SIMULATIONS based on the KPIs determined by this script:
     
    In this script, the tripinfo objects are analyzed to determine
    the total kilometers driven per mode of transport.
    This can be a useful KPI,
    especially when evaluating the efficiency of SAVs (shared autonomous vehicles).
    With SAVs, there almost certainly will be trips that SAVs must take with no passengers,
    e.g. while idling or while driving to a passenger pickup point while empty vehicle
    While having a very large fleet of SAVs might improve the door-door travel time KPI,
    adding too many SAVs may the increase total kilometers driven
    without significantly reducing travel times.
    To reduce operating costs and city traffic, the optimum number of SAVs
    may be found by determining the optimum combination of minimum door-door travel times 
    and minimal kilometers driven in the SAV mode.
    Introducing an SAV service may reduce the total kilometers driven 
    by private passenger vehicles (from the internal demand),
    but it may also reduce the mode share of walking or PT users.

    On the other hand,
    using only an SAV service instead of a private Taxi service could result
    in slower average travel times.
    However, since the capacity of private taxis (in SUMOPy)
    is set to only 1 passenger, wile the default for SUMOPy SAVs is 8 passengers, 
     a private taxi fleet should have a much lower transportation
    than an SAV fleet with the same number of vehicles.
    The percentage of finished private taxi stages (calcuted in this script)
    may be much lower than the percentage of finish SAV stages.
     Therefore, while the average travel time KPIs are important, they are everything.
     A high percentage of SAV passengers arriving within a given timeframe
    with moderate travel times may be more desireable
    than a low percentage of private taxi passengers arriving quickly,
    while the rest do not arrive at all before the end of the simulation.
    These were just some thought experiments to show how the various KPIs in this script
    could be used and interpreted to improve simulations.
        
        



 There are 2 ways this script can be run:
 - interactive mode (script asks user step-by-step what options they want
 - non-interactive mode (run script with all options selected via launch arguments
 The entire range of functions is available in both modes.


 To launch interactive mode: 2 launch arguments required:
 --------------------------------------------------------

 Please provide the name of the file containing executed trip data
 as the 1st agument. Common names: tripdata.xml, tripinfo_output.xml 

 Please provide the name of the file containing planned trip data
 as the 2nd agument. Common names: rou.xml, trips.xml, demand.xml

 No binding SUMO conventions exist, file names and file endings fully customizable.
 If in doubt, check xml file contents to be sure. Compare with the example files)
 of tripdata.xml and rou.xml included in this /scripts folder.

 Example launch command (tested with Python 3.7):
 python tripdata_analysis_without_sumopy_py3.py 230627_with_SAV_TAXI_PT.out.tripdata.xml 230627_with_SAV_TAXI_PT.rou.xml


 To launch non-interactive mode: 1 to 3 additional launch arguments required:
 ---------------------------------------------------------

 If you want to run this file as a non-interactive script,
 you must provide additional arguments at at launch.

 If you want to run the script with all print-outs, graphs, and exports, add:
         ni                
 (ni = non-interactive) as an additional argument.

 If you want to run the script, but want to omit some print-outs, graphs
 or exports, instead of  ni , add 1 to 4 of the following arguments:
         nd                      (nd = no print-out of script description)
         np                      (np = no print-outs to console at all)
         nc                      (nc = no .csv file creation)
         ngs                     (ngs = no graphs shown, e.g. for systems with no GUI)
         nge                     (nge = no graphs exported)
 Note: you cannot combine these 4 arguments:  np nc ngs nge
 Doing so would have the script run uselessly without producing any kind of output.

 Example launch command to only create the tripdata_analyzed.csv file
 with no graphs and no console print-outs (tested with Python 3.7):
 python tripdata_analysis_without_sumopy_py3.py 230627_with_SAV_TAXI_PT.out.tripdata.xml 230627_with_SAV_TAXI_PT.rou.xml ngs np

 Tip: If you want save the printed console text to a .txt file, type
           > logfilename.txt
      after all the launch arguments.
      Since all console prints are saved to the .txt file,
      without printing anything to the console itself,
      this option is only recommended for non-interactive mode.
      (interactive mode would request user inputs without showing prompts)


 Data analysis steps:
 *********************

 Required:   1 Vehicle data analysis
             2 Virtual population data analysis
             3 Calculation of KPIs
             4 Displaying results on console

 Optional:   5 Exporting to tripdata_analyzed.csv
             6 Plotting graphs

 (KPI = key performance indicator, e.g., speed, travel time, etc.)



 Preparing data analysis...


 Step 1: Starting analysis of vehicle data
 100 % of vehicle data analyzed



 Step 2: Starting analysis of virtual population data
            
        l
            o
                a
                    d
                        i
                            n
                                g

  10 % of virtual population data analyzed
            
                                l
                            o
                        a
                    d
                i
            n
        g

  20 % of virtual population data analyzed
            
        l
            o
                a
                    d
                        i
                            n
                                g

  30 % of virtual population data analyzed
            
                                l
                            o
                        a
                    d
                i
            n
        g

  40 % of virtual population data analyzed
            
        l
            o
                a
                    d
                        i
                            n
                                g

  50 % of virtual population data analyzed
            
                                l
                            o
                        a
                    d
                i
            n
        g

  60 % of virtual population data analyzed
            
        l
            o
                a
                    d
                        i
                            n
                                g

  70 % of virtual population data analyzed
            
                                l
                            o
                        a
                    d
                i
            n
        g

  80 % of virtual population data analyzed
            
        l
            o
                a
                    d
                        i
                            n
                                g

  90 % of virtual population data analyzed
            
                                l
                            o
                        a
                    d
                i
            n
        g

 100 % of virtual population data analyzed



 Step 3: Calculation of KPIs



 Step 4: Displaying KPI results on console


 Section 1: internal and external demand, finished and unfinished trips
 *************************************************************************************************
 *************************************************************************************************

 Total distance travelled by vehicles
 *************************************************************************************************
 (sum of all route lengths in all tripinfo objects)
 (internal + external demand combined, finished and unfinished vehicle trips)

 SUM of ALL DISTANCES travelled BY ALL VEHICLES:                                9229.187 km
 Per vehicle type:
    passenger1                                                                  6267.706 km
    bus                                                                          172.357 km
    tram1                                                                         14.323 km
    motorcycle                                                                    60.156 km
    taxi1                                                                       1339.193 km
    SAV                                                                         1375.452 km




 Section 2: only internal demand (generated by virutal population), finished and unfinished trips
 *************************************************************************************************
 *************************************************************************************************

 Finished and unfinished trips of virtual population
 *************************************************************************************************
 (if any value == -1: no finished trips for this mode)
                                              
 NUMBER of STARTED TRIPS of virtual population:                                18412 trips
 NUMBER of FINISHED TRIPS of virtual population:                                2325 trips

 Total PERCENTAGE of FINISHED TRIPS of virtual population:                        12.628 %
 Per primary mode of travel:
    walk                                                                          19.089 %
    passenger1                                                                    35.746 %
    SAV                                                                            3.590 %
    taxi1                                                                          3.834 %
    motorcycle                                                                    60.870 %
    bus                                                                            6.535 %
    tram1                                                                         16.667 %


 MODAL SPLIT of all started trips of virtual population
 *************************************************************************************************
 (including finished and unfinished person trips based on vtype of first ride stage)
 (mode = walk if no ride stages in trip)
 (see section b) at the start of the script for calculation method)

    SAV                                                                           24.359 %
    bus                                                                            5.236 %
    motorcycle                                                                     0.125 %
    passenger1                                                                     9.831 %
    taxi1                                                                         24.365 %
    tram1                                                                          0.065 %
    walk                                                                          36.020 %




 Section 3: only internal demand (generated by virutal population), only finished trips
 *************************************************************************************************
 *************************************************************************************************

 Average trip data of internal demand (based on finished trips)
 *************************************************************************************************
 (if any value == -1: no finished trips for this mode <--> no data for this KPI for this mode)

 Average DOOR-DOOR travel TIME WITH WALK stages INCLUDING WAITING times:         502.81 seconds
 Per primary mode of travel:
    walk                                                                         289.42 seconds
    passenger1                                                                   642.40 seconds
    SAV                                                                          930.68 seconds
    taxi1                                                                        976.81 seconds
    motorcycle                                                                   556.75 seconds
    bus                                                                          946.05 seconds
    tram1                                                                        878.50 seconds


 Average RIDE TIME WITHOUT WALK stages INCLUDING WAITING times:                  757.92 seconds
 Per primary mode of travel:
    passenger1                                                                   642.40 seconds
    SAV                                                                          930.68 seconds
    taxi1                                                                        976.81 seconds
    motorcycle                                                                   556.75 seconds
    bus                                                                          946.05 seconds
    tram1                                                                        878.50 seconds


 Average DOOR-DOOR travel TIME WITH WALK stages EXCLUDING WAITING times:         419.04 seconds
 Per primary mode of travel:
    walk                                                                         289.42 seconds
    passenger1                                                                   618.49 seconds
    SAV                                                                          494.22 seconds
    taxi1                                                                        431.59 seconds
    motorcycle                                                                   531.75 seconds
    bus                                                                          718.33 seconds
    tram1                                                                        600.00 seconds


 Average RIDE TIME WITHOUT WALK stages EXCLUDING WAITING times:                  358.73 seconds
 Per primary mode of travel:
    passenger1                                                                   342.47 seconds
    SAV                                                                          437.61 seconds
    taxi1                                                                        398.97 seconds
    motorcycle                                                                   427.93 seconds
    bus                                                                          206.51 seconds
    tram1                                                                        116.25 seconds


 Average DOOR-DOOR travel DISTANCE:                                             1409.33 meters
 Per primary mode of travel:
    walk                                                                         266.38 meters
    passenger1                                                                  2741.02 meters
    SAV                                                                         3181.97 meters
    taxi1                                                                       2935.43 meters
    motorcycle                                                                  3317.59 meters
    bus                                                                         1588.78 meters
    tram1                                                                       1149.29 meters


 Average RIDE DISTANCE WITHOUT WALK stages:                                     2586.10 meters
 Per primary mode of travel:
    passenger1                                                                  2502.90 meters
    SAV                                                                         3118.29 meters
    taxi1                                                                       2896.68 meters
    motorcycle                                                                  3209.25 meters
    bus                                                                         1152.89 meters
    tram1                                                                        736.55 meters


 Average DOOR-DOOR travel SPEED m/s WITH WALK stages INCLUDING WAITING times:      2.80 m/s
 Per primary mode of travel:
    walk                                                                           0.92 m/s
    passenger1                                                                     4.27 m/s
    SAV                                                                            3.42 m/s
    taxi1                                                                          3.01 m/s
    motorcycle                                                                     5.96 m/s
    bus                                                                            1.68 m/s
    tram1                                                                          1.31 m/s


 Average RIDE SPEED m/s WITHOUT WALK stages INCLUDING WAITING times:               3.41 m/s
 Per primary mode of travel:
    passenger1                                                                     3.90 m/s
    SAV                                                                            3.35 m/s
    taxi1                                                                          2.97 m/s
    motorcycle                                                                     5.76 m/s
    bus                                                                            1.22 m/s
    tram1                                                                          0.84 m/s


 Average DOOR-DOOR travel SPEED m/s WITH WALK stages EXCLUDING WAITING times:      3.36 m/s
 Per primary mode of travel:
    walk                                                                           0.92 m/s
    passenger1                                                                     4.43 m/s
    SAV                                                                            6.44 m/s
    taxi1                                                                          6.80 m/s
    motorcycle                                                                     6.24 m/s
    bus                                                                            2.21 m/s
    tram1                                                                          1.92 m/s


 Average RIDE SPEED m/s WITHOUT WALK stages EXCLUDING WAITING times:               7.21 m/s
 Per primary mode of travel:
    passenger1                                                                     7.31 m/s
    SAV                                                                            7.13 m/s
    taxi1                                                                          7.26 m/s
    motorcycle                                                                     7.50 m/s
    bus                                                                            5.58 m/s
    tram1                                                                          6.34 m/s


 Average DOOR-DOOR travel SPEED km/h WITH WALK stages INCLUDING WAITING times:    10.09 km/h
 Per primary mode of travel:
    walk                                                                           3.31 km/h
    passenger1                                                                    15.36 km/h
    SAV                                                                           12.31 km/h
    taxi1                                                                         10.82 km/h
    motorcycle                                                                    21.45 km/h
    bus                                                                            6.05 km/h
    tram1                                                                          4.71 km/h


 Average RIDE SPEED km/h WITHOUT WALK stages INCLUDING WAITING times:             12.28 km/h
 Per primary mode of travel:
    passenger1                                                                    14.03 km/h
    SAV                                                                           12.06 km/h
    taxi1                                                                         10.68 km/h
    motorcycle                                                                    20.75 km/h
    bus                                                                            4.39 km/h
    tram1                                                                          3.02 km/h


 Average DOOR-DOOR travel SPEED km/h WITH WALK stages EXCLUDING WAITING times:    12.11 km/h
 Per primary mode of travel:
    walk                                                                           3.31 km/h
    passenger1                                                                    15.95 km/h
    SAV                                                                           23.18 km/h
    taxi1                                                                         24.49 km/h
    motorcycle                                                                    22.46 km/h
    bus                                                                            7.96 km/h
    tram1                                                                          6.90 km/h


 Average RIDE SPEED km/h WITHOUT WALK stages EXCLUDING WAITING times:             25.95 km/h
 Per primary mode of travel:
    passenger1                                                                    26.31 km/h
    SAV                                                                           25.65 km/h
    taxi1                                                                         26.14 km/h
    motorcycle                                                                    27.00 km/h
    bus                                                                           20.10 km/h
    tram1                                                                         22.81 km/h




 Step 5: Exporting KPI results to tripdata_analyzed.csv



 Step 6: Plotting and exporting graphs of KPI results to .png files, then displaying graphs



 Data analysis complete.
