From 1a5cf9b8221bfa3e7e55531464a73fb01673e67b Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Sat, 22 Jan 2022 17:49:53 +0100 Subject: [PATCH] Add feature to export points of interest as a CSV file --- data/settings.yaml | 2 +- src/Export.jl | 34 ++++++++++++++++++++++------------ src/Import.jl | 2 +- src/Input.jl | 14 ++++++++++---- src/TrainRunCalc.jl | 8 +++++++- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/data/settings.yaml b/data/settings.yaml index 1797b86..d573c22 100644 --- a/data/settings.yaml +++ b/data/settings.yaml @@ -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" or "driving course"? + detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"? csvDirectory: "~/Desktop/TrainRun" diff --git a/src/Export.jl b/src/Export.jl index b2470f7..c5858fe 100644 --- a/src/Export.jl +++ b/src/Export.jl @@ -11,18 +11,28 @@ function exportToCsv(output::Dict) if output[:settings][:operationModeMinimumRunningTime] == true operationMode = "minimum running time" - createCsvFile(output[:movingSectionMinimumRunningTime], output[:drivingCourseMinimumRunningTime], operationMode, pathName, trainName, output[:settings]) + if output[:settings][:detailOfOutput] == "points of interest" + dataPointsToExport = output[:pointsOfInterestMinimumRunningTime] + else + dataPointsToExport = output[:drivingCourseMinimumRunningTime] + end + createCsvFile(output[:movingSectionMinimumRunningTime], dataPointsToExport, operationMode, pathName, trainName, output[:settings]) end if output[:settings][:operationModeMinimumEnergyConsumption] == true operationMode = "minimum energy consumption" - createCsvFile(output[:movingSectionMinimumEnergyConsumption], output[:drivingCourseMinimumEnergyConsumption], operationMode, pathName, trainName, output[:settings]) + if output[:settings][:detailOfOutput] == "points of interest" + dataPointsToExport = output[:pointsOfInterestMinimumEnergyConsumption] + else + dataPointsToExport = output[:drivingCourseMinimumEnergyConsumption] + end + createCsvFile(output[:movingSectionMinimumEnergyConsumption], dataPointsToExport, operationMode, pathName, trainName, output[:settings]) end return true end return false end #function exportToCsv -function createCsvFile(movingSection::Dict, drivingCourse::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict) +function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict) detailOfOutput = settings[:detailOfOutput] massModel = settings[:massModel] @@ -31,14 +41,14 @@ function createCsvFile(movingSection::Dict, drivingCourse::Vector{Dict}, operati # create summarized data block summarizedData = Array{Any, 1}[] - if detailOfOutput=="minimal" + if detailOfOutput == "minimal" push!(summarizedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to summarizedData - row=[movingSection[:length], movingSection[:t], movingSection[:E]] + row = [movingSection[:length], movingSection[:t], movingSection[:E]] push!(summarizedData, row) # push row to summarizedData - elseif detailOfOutput=="driving course" + elseif detailOfOutput == "driving course" || detailOfOutput == "points of interest" push!(summarizedData, ["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 summarizedData - for point in drivingCourse - 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]] + 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!(summarizedData, row) # push row to summarizedData end end @@ -61,10 +71,10 @@ function createCsvFile(movingSection::Dict, drivingCourse::Vector{Dict}, operati end # for # combine the columns in a data frame and saving it as a CSV-file at csvDirectory - if detailOfOutput=="minimal" - df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3]) - elseif detailOfOutput=="driving course" - 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]) + if detailOfOutput == "minimal" + df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3]) + elseif 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]) end date = Dates.now() diff --git a/src/Import.jl b/src/Import.jl index 526de89..6702566 100644 --- a/src/Import.jl +++ b/src/Import.jl @@ -157,7 +157,7 @@ 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", "driving course"]) # should the output be "minimal" or "driving course" + 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 diff --git a/src/Input.jl b/src/Input.jl index 6e76e14..59a301e 100644 --- a/src/Input.jl +++ b/src/Input.jl @@ -17,6 +17,10 @@ function checkAndSetInput!(train::Dict, path::Dict, settings::Dict) checkAndSetPath!(path) checkAndSetSettings!(settings) + if settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest) + settings[:detailOfOutput] = "driving course" + println("INFO at checking the input for settings and path: settings[:detailOfOutput] is 'points of interest' but the path does not have a list for pointsOfInterest. Therefore the detailOfOut is changed to 'driving course'.") + end return (train, path, settings) end #function checkAndSetInput! @@ -92,7 +96,7 @@ function checkAndSetSettings!(settings::Dict) # TODO: it could be checked if the path is existing on the pc end # if - checkString(settings, "settings", :detailOfOutput, ["minimal", "driving course"]) # should the output be "minimal" or "driving course" + 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? # TODO: informAboutUnusedKeys(settings, "settings") # inform the user, which Symbols of the input dictionary are not used in this tool @@ -424,7 +428,7 @@ function checkAndSetPOIs!(path::Dict) end # for if errorDetected - error("ERROR at checking the input dictionary for the path: The values of the point of interest have to be corrected.") + error("ERROR at checking the input dictionary for the path: The values of pointsOfInterest have to be corrected.") end if sortingNeeded == true sort!(pointsOfInterest) @@ -439,9 +443,11 @@ function checkAndSetPOIs!(path::Dict) end end # for path[:pointsOfInterest] = copiedPOIs + + else + println("INFO at checking the input dictionary for the path: The key pointsOfInterest exists but without values.") + delete!(path, :pointsOfInterest) end - else - delete!(path, :pointsOfInterest) end return path diff --git a/src/TrainRunCalc.jl b/src/TrainRunCalc.jl index a7af124..d1ef152 100644 --- a/src/TrainRunCalc.jl +++ b/src/TrainRunCalc.jl @@ -32,7 +32,13 @@ julia> calculateDrivingDynamics(trainDict, pathDict, settingsDict) todo !!! ``` """ -function calculateDrivingDynamics(train::Dict, path::Dict, settings::Dict) +function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInput::Dict) + # copy Input data for not changing them + # TODO: or should they be changed? enormally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest) + train = copy(trainInput) + path = copy(pathInput) + settings = copy(settingsInput) + # check the input data (train, path, settings) = checkAndSetInput!(train, path, settings) println("The input has been checked.")