Refactor output and export for four different detail levels

development
Max Kannenberg 2022-04-02 00:02:39 +02:00
parent 2983b2c2e1
commit 5c9541775d
14 changed files with 298 additions and 35 deletions

View File

@ -8,5 +8,5 @@ settings:
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -7,6 +7,6 @@ settings:
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
typeOfOutput: "CSV" # output as "julia dictionary" or as "CSV"
detailOfOutput: "everything" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -0,0 +1,12 @@
%YAML 1.2
---
settings:
# settings for the simulation
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
typeOfOutput: "CSV" # output as "julia dictionary" or as "CSV"
detailOfOutput: "running time" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -8,5 +8,5 @@ settings:
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -8,5 +8,5 @@ settings:
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -8,5 +8,5 @@ settings:
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -14,7 +14,6 @@ push!(allPaths, importYamlFile(:path, "data/paths/path_2_10km_nVar_vConst.yaml")
push!(allPaths, importYamlFile(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
push!(allPaths, importYamlFile(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
allSettings=[]
push!(allSettings, importYamlFile(:settings, "data/settings/settings_distanceStep_massPoint.yaml"))
@ -29,7 +28,7 @@ for path in allPaths
for train in allTrains
# println("train: ", train)
for settings in allSettings
resultsDict=calculateDrivingDynamics(train, path, settings)
resultsDict = calculateDrivingDynamics(train, path, settings)
exportToCsv(resultsDict)
sleep(2)
# println("")

View File

@ -10,11 +10,10 @@ using .TrainRun
train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
running_path_directory = "data/paths/path_1_10km_nConst_vConst.yaml"
setting_directory = "data/settings/settings_distanceStep_massPoint.yaml"
setting_directory = "data/settings/settings_distanceStep_massPoint_runningTime.yaml"
(train, running_path, settings) = importYamlFiles(train_directory, running_path_directory, setting_directory)
train_run = calculateDrivingDynamics(train, running_path, settings)
runtime = train_run[:movingSectionMinimumRunningTime][:t]
runtime = calculateDrivingDynamics(train, running_path, settings)
exportToCsv(train_run)
exportToCsv(runtime, settings)
println("The V 90 with 10 ore wagons needs $runtime seconds for 10 km with no gradient.")

View File

@ -25,12 +25,24 @@ function plotResults(output::Dict)
elseif opModeMinEnergy == true
plotDrivingCourse(output[:drivingCourseMinimumEnergyConsumption])
else
println("No Output was demanded. So no plot is created.")
output[:settings][:detailOfOutput] == "everything" && println("No Output was demanded. So no plot is created.")
end
return true
end #function plotResults
function plotResults(drivingCourse::Vector{Dict})
plotDrivingCourse(drivingCourse)
return true
end #function plotResults
function plotResults(singleValue::AbstractFloat)
println("Not able to plot the single value ",singleValue)
return false
end #function plotResults
function plotDrivingCourse(drivingCourse::Vector{Dict})
a=[]
E=[]
@ -55,11 +67,19 @@ function plotDrivingCourse(drivingCourse::Vector{Dict})
# p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
#p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
p5=plot([s/1000], [E], title = "E in Ws", label = ["E"], xlabel = "s in km")
p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
#p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
p6=plot([t/60], [E], title = "E in Ws", label = ["E"], xlabel = "t in min")
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
#=
# p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
# p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
all=plot(p1, p2, layout = (1, 2), legend = false)=#
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
display(all)
println("Plots for different variables have been created.")
@ -146,17 +166,44 @@ function printSectionInformation(movingSection::Dict)
CSs::Vector{Dict} = movingSection[:characteristicSections]
println("MS with length=", movingSection[:length]," with t=", movingSection[:t])
allBs=[:breakFree, :clearing, :accelerating, :clearing2, :accelerating2, :clearing3, :accelerating3, :cruising, :downhillBraking, :diminishing, :coasting, :braking, :standstill]
#allBSs=[:breakFree, :clearing, :accelerating, :clearing2, :accelerating2, :clearing3, :accelerating3, :cruising, :downhillBraking, :diminishing, :coasting, :braking, :standstill]
for csId in 1:length(CSs)
println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t])
for bs in 1: length(allBs)
if haskey(CSs[csId][:behaviorSections], allBs[bs])
println("BS ",allBs[bs], " with s_entry=", CSs[csId][:behaviorSections][allBs[bs]][:s_entry], " and length=",CSs[csId][:behaviorSections][allBs[bs]][:length]) # and t=", CSs[csId][:behaviorSections][allBs[bs]][:t])
# for point in 1:length(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints])
# println(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints][point])
# end
end #if
end #for
# for bs in 1: length(allBSs)
# if haskey(CSs[csId][:behaviorSections], allBSs[bs])
# println("BS ",allBSs[bs], " with s_entry=", CSs[csId][:behaviorSections][allBSs[bs]][:s_entry], " and length=",CSs[csId][:behaviorSections][allBSs[bs]][:length]) # and t=", CSs[csId][:behaviorSections][allBSs[bs]][:t])
# # for point in 1:length(CSs[csId][:behaviorSections][allBSs[bs]][:dataPoints])
# # println(CSs[csId][:behaviorSections][allBSs[bs]][:dataPoints][point])
# # end
# end #if
# end #for
tempBSs = collect(keys(CSs[csId][:behaviorSections]))
while length(tempBSs) > 0
currentBS = :default
for bs in 1: length(tempBSs)
if currentBS == :default
currentBS = tempBSs[bs]
else
if CSs[csId][:behaviorSections][currentBS][:s_entry] > CSs[csId][:behaviorSections][tempBSs[bs]][:s_entry]
currentBS = tempBSs[bs]
end
end
end #for
println("BS ",currentBS, " with s_entry=", CSs[csId][:behaviorSections][currentBS][:s_entry], " and length=",CSs[csId][:behaviorSections][currentBS][:length]) # and t=", CSs[csId][:behaviorSections][currentBS][:t])
# for point in 1:length(CSs[csId][:behaviorSections][currentBS][:dataPoints])
# println(CSs[csId][:behaviorSections][currentBS][:dataPoints][point])
# end
newTempBSs = []
for bs in 1: length(tempBSs)
if currentBS != tempBSs[bs]
push!(newTempBSs, tempBSs[bs])
end #if
end #for
tempBSs = newTempBSs
end #while
end #for
end #function printSectionInformation

View File

@ -11,6 +11,18 @@ using CSV, DataFrames, Dates
export exportToCsv
function exportToCsv(runningTime::AbstractFloat, settings::Dict)
createCsvFile(runningTime, settings)
return true
end
function exportToCsv(dataPointsToExport::Vector{Dict}, settings::Dict)
createCsvFile(dataPointsToExport, settings)
return true
end
function exportToCsv(output::Dict)
if output[:settings][:typeOfOutput] == "CSV"
pathName = output[:path][:name]
@ -23,7 +35,7 @@ function exportToCsv(output::Dict)
else
dataPointsToExport = output[:drivingCourseMinimumRunningTime]
end
createCsvFile(output[:movingSectionMinimumRunningTime], dataPointsToExport, operationMode, pathName, trainName, output[:settings])
createCsvFile(dataPointsToExport, operationMode, pathName, trainName, output[:settings])
end
if output[:settings][:operationModeMinimumEnergyConsumption] == true
operationMode = "minimum energy consumption"
@ -32,13 +44,118 @@ function exportToCsv(output::Dict)
else
dataPointsToExport = output[:drivingCourseMinimumEnergyConsumption]
end
createCsvFile(output[:movingSectionMinimumEnergyConsumption], dataPointsToExport, operationMode, pathName, trainName, output[:settings])
createCsvFile(dataPointsToExport, operationMode, pathName, trainName, output[:settings])
end
return true
end
return false
end #function exportToCsv
function createCsvFile(runningTime::AbstractFloat, settings::Dict)
# create DataFrame with running time information
df = DataFrame(column1=["t (in s)", runningTime])
# save DataFrame as a CSV-file at csvDirectory
date = Dates.now()
dateString = Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
csvFilePath = settings[:csvDirectory]*"/"*dateString*"_RunningTime.csv"
CSV.write(csvFilePath, df, header=false)
println("The output CSV file has been created at ",csvFilePath)
return true
end #function createCsvFile
function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Dict)
detailOfOutput = settings[:detailOfOutput]
header = ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]
columnSymbols = [:i, :behavior, :Δs, :s, :Δt, :t, :Δv, :v, :F_T, :F_R, :R_path, :R_train, :R_traction, :R_wagons, :ΔW, :W, :ΔE, :E, :a]
allColumns = Array{Any,1}[]
for column in 1:length(header)
currentColumn = Any[]
push!(currentColumn, header[column])
for point in dataPointsToExport
push!(currentColumn, point[columnSymbols[column]])
end
push!(allColumns, currentColumn)
end # for
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
if detailOfOutput == "driving course" || detailOfOutput == "points of interest"
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
else
println("")
end
date = Dates.now()
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_DataPoints.csv"
CSV.write(csvFilePath, df, header=false)
println("The output CSV file has been created at ",csvFilePath)
return true
end #function createCsvFile
function createCsvFile(dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict)
detailOfOutput = settings[:detailOfOutput]
massModel = settings[:massModel]
stepVariable = settings[:stepVariable]
stepSize = string(settings[:stepSize])
# create accumulated data block
accumulatedData = Array{Any, 1}[]
push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData
for point in dataPointsToExport
row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]]
push!(accumulatedData, row) # push row to accumulatedData
end
#create information block
allColumns=Array{Any,1}[]
push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""])
for column in 3:length(accumulatedData[1])
push!(allColumns, ["", "", "", "", "", "", ""])
end # for
# add driving data to the array
header = accumulatedData[1]
for column in 1:length(accumulatedData[1])
push!(allColumns[column], header[column])
for row in accumulatedData[2:end]
push!(allColumns[column], row[column])
end
end # for
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
date = Dates.now()
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
if operationMode == "minimum running time"
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumRunningTime.csv"
elseif operationMode == "minimum energy consumption"
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumEnergyConsumption.csv"
else
# should not be possible
end
CSV.write(csvFilePath, df, header=false)
println("The output CSV file has been created for ",operationMode," at ",csvFilePath)
return true
end #function createCsvFile
#=
function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict)
detailOfOutput = settings[:detailOfOutput]
@ -98,5 +215,6 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
return true
end #function createCsvFile
=#
end #module Export

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module Import
import YAML
@ -157,7 +164,8 @@ function importSettingsFromYaml(settingsDirectory::String)
# TODO: it could be checked if the path is existing on the pc
end # if
settings[:detailOfOutput] = getString!(data, "settings", "detailOfOutput", ["minimal", "points of interest", "driving course"]) # should the output be "minimal" or are "points of interest" or the complete "driving course" required?
settings[:detailOfOutput] = getString!(data, "settings", "detailOfOutput", ["running time", "points of interest", "driving course", "everything"]) # should the output be only the value of the "running time", or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
# 30/31 old: settings[:detailOfOutput] = getString!(data, "settings", "detailOfOutput", ["minimal", "points of interest", "driving course"]) # should the output be "minimal" or are "points of interest" or the complete "driving course" required?
informAboutUnusedKeys(data, "settings") # inform the user, which keywords of the imported data are not used in this tool

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2022"
# __license__ = "ISC"
# TODO: >>if train[:type] == freight::trainType<< does not work only in checkTrainType(train::Dict). because ::Main.TrainRun.Import.trainType != ::Main.TrainRun.Input.trainType -> why? checkTrainType ist therefore deactivated.
# TODO: adapt function informAboutUnusedKeys for Input.jl
module Input
@ -96,7 +103,8 @@ function checkAndSetSettings!(settings::Dict)
# TODO: it could be checked if the path is existing on the pc
end # if
checkString(settings, "settings", :detailOfOutput, ["minimal", "points of interest", "driving course"]) # should the output be "minimal" or are "points of interest" or the complete "driving course" required?
checkString(settings, "settings", :detailOfOutput, ["running time", "points of interest", "driving course", "everything"]) # should the output be only the value of the "running time", or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
# 30/31 old: checkString(settings, "settings", :detailOfOutput, ["minimal", "points of interest", "driving course"]) # should the output be "minimal" or are "points of interest" or the complete "driving course" required or also all the information about the different sections?
# TODO: informAboutUnusedKeys(settings, "settings") # inform the user, which Symbols of the input dictionary are not used in this tool

View File

@ -1,7 +1,76 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module Output
export createOutputDict
export createOutput
function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
if settings[:detailOfOutput] == "running time"
output = movingSection[:t] # TODO: or use drivingCourse[end][:t]
elseif settings[:detailOfOutput] == "points of interest"
# add points of interest
if haskey(path, :pointsOfInterest)
output = Vector{Dict}()
POI = 1
i = 1
while POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i]
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
push!(output, drivingCourse[i])
POI = POI+1
end
i = i+1
end
end
elseif settings[:detailOfOutput] == "driving course"
output = drivingCourse
elseif settings[:detailOfOutput] == "everything"
output = Dict{Symbol,Any}()
merge!(output, Dict(:train => train, :path => path, :settings => settings))
# add moving section and driving courses
if settings[:operationModeMinimumRunningTime] == true
merge!(output, Dict(:movingSectionMinimumRunningTime => movingSection,
:drivingCourseMinimumRunningTime => drivingCourse))
elseif settings[:operationModeMinimumEnergyConsumption] == true
merge!(output, Dict(:movingSectionMinimumEnergyConsumption => movingSection,
:drivingCourseMinimumEnergyConsumption => drivingCourse))
end
# add points of interest
if haskey(path, :pointsOfInterest)
pointsOfInterest = Vector{Dict}()
POI = 1
i = 1
while POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i]
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
push!(pointsOfInterest, drivingCourse[i])
POI = POI+1
end
i = i+1
end
if settings[:operationModeMinimumRunningTime] == true
merge!(output, Dict(:pointsOfInterestMinimumRunningTime => pointsOfInterest))
elseif settings[:operationModeMinimumEnergyConsumption] == true
merge!(output, Dict(:pointsOfInterestMinimumEnergyConsumption => pointsOfInterest))
end
end
else
output = nothing
end
return output
end
#=
function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
outputDict = Dict{Symbol,Any}()
merge!(outputDict, Dict(:train => train, :path => path, :settings => settings))
@ -21,7 +90,7 @@ function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection
pointsOfInterest = Vector{Dict}()
POI = 1
i = 1
while(POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i])
while POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i]
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
push!(pointsOfInterest, drivingCourse[i])
POI = POI+1
@ -38,5 +107,6 @@ function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection
return outputDict
end # function createOutputDict
=#
end # module Output

View File

@ -48,21 +48,23 @@ function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInp
# check the input data
(train, path, settings) = checkAndSetInput!(train, path, settings)
println("The input has been checked.")
settings[:detailOfOutput] == "everything" && println("The input has been checked.")
# prepare the input data
movingSection = determineCharacteristics(path, train, settings)
println("The moving section has been prepared.")
settings[:detailOfOutput] == "everything" && println("The moving section has been prepared.")
# calculate the train run for oparation mode "minimum running time"
if settings[:operationModeMinimumRunningTime] || settings[:operationModeMinimumEnergyConsumption]
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
println("The driving course for the shortest running time has been calculated.")
settings[:detailOfOutput] == "everything" && println("The driving course for the shortest running time has been calculated.")
# accumulate data and create an output dictionary
output = createOutputDict(train, settings, path, movingSection, drivingCourse)
output = createOutput(train, settings, path, movingSection, drivingCourse)
# 30/31 old: output = createOutputDict(train, settings, path, movingSection, drivingCourse)
else
output = Dict()
output = nothing
# 30/31 old: output = Dict()
end #if
return output