241 lines
8.2 KiB
Julia
241 lines
8.2 KiB
Julia
# approach 2: deviation is analyzed for time between the registration points
|
|
# time between two stations and time between arrival and departure
|
|
|
|
module betweenRegistrationPoints
|
|
|
|
include("./output.jl")
|
|
|
|
using Statistics, CSV, Dates, DataFrames
|
|
using .output
|
|
|
|
export getDifferences
|
|
|
|
function getDifferences(modPerfData, settings)
|
|
df1, perfDataDirection1, df2, perfDataDirection2 =
|
|
prepareData(modPerfData, settings)
|
|
plotData1 = calculateDeviation(df1, perfDataDirection1, settings)
|
|
plotData2 = calculateDeviation(df2, perfDataDirection2, settings)
|
|
return plotData1, plotData2
|
|
end
|
|
|
|
"""
|
|
Function is preparing the data if necesary and calling another function
|
|
to prepare DataFrames to save the results of the following analyses.
|
|
"""
|
|
|
|
function prepareData(modPerfData, settings)
|
|
|
|
# determine current line and its station list
|
|
if settings.objectInFocus == "single line"
|
|
lineNr = 1
|
|
else
|
|
lineNr = findall(x -> x == settings.analyzedLine, settings.allLines)
|
|
lineNr = lineNr[1]
|
|
end
|
|
|
|
stationList1 = settings.stationLists[lineNr]
|
|
stationList2 = reverse(stationList1)
|
|
|
|
df1 = createDataFrame(stationList1, settings)
|
|
df2 = createDataFrame(stationList2, settings)
|
|
|
|
select!(modPerfData, Not(:rownumber))
|
|
modPerfData =
|
|
filter(row -> row[:ZUGEREIGNIS_DS100] in stationList1, modPerfData)
|
|
modPerfData[!, :rownumber] = axes(modPerfData, 1)
|
|
df = modPerfData[modPerfData[:, :rownumber].!=0, :]
|
|
|
|
# the station data of TSS has to be changed (somtimes wrong order)
|
|
if stationList1[1] == "TSS" || stationList2[1] == "TSS"
|
|
for row in eachrow(modPerfData)
|
|
if row.rownumber > 1 && row.ZUGEREIGNIS_DS100 == "TSS"
|
|
if modPerfData.ZUGEREIGNIS_DS100[row.rownumber-1] == "TSS" && (
|
|
modPerfData.ZUGEREIGNIS_TYP[row.rownumber-1] == 10 ||
|
|
modPerfData.ZUGEREIGNIS_TYP[row.rownumber-1] == 50
|
|
)
|
|
row1 = modPerfData[row.rownumber-1, :]
|
|
row2 = modPerfData[row.rownumber, :]
|
|
df[row.rownumber, :] = row1
|
|
df[row.rownumber-1, :] = row2
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
perfDataDirection1 = df[df[:, :ZUGEREIGNIS_RICHTUNG].==stationList2[1], :]
|
|
perfDataDirection2 = df[df[:, :ZUGEREIGNIS_RICHTUNG].==stationList1[1], :]
|
|
|
|
return df1, perfDataDirection1, df2, perfDataDirection2
|
|
end
|
|
|
|
function createDataFrame(stationList, settings)
|
|
|
|
df = DataFrame()
|
|
point1 = Any[]
|
|
point2 = Any[]
|
|
counter = 0
|
|
|
|
if settings.objectInFocus != "Stuttgarter Stammstrecke"
|
|
if stationList[1] == "TSS"
|
|
pushfirst!(stationList, stationList[1])
|
|
counter = convert(Int, (length(stationList) - 1) / 2)
|
|
sequence = repeat(["station", "section"], counter)
|
|
elseif stationList[size(stationList, 1)] == "TSS"
|
|
push!(stationList, stationList[size(stationList, 1)])
|
|
counter = convert(Int, (length(stationList) - 1) / 2)
|
|
sequence = repeat(["section", "station"], counter)
|
|
else
|
|
counter = convert(Int, (length(stationList) - 1) / 2 + 0.5)
|
|
sequence = repeat(["section", "station"], counter)
|
|
pop!(sequence)
|
|
end
|
|
else
|
|
push!(stationList, stationList[length(stationList)])
|
|
pushfirst!(stationList, stationList[1])
|
|
counter = convert(Int, (length(stationList) - 1) / 2 + 0.5)
|
|
sequence = repeat(["station", "section"], counter)
|
|
pop!(sequence)
|
|
end
|
|
|
|
#create station list for differences
|
|
for i = 2:length(stationList)
|
|
push!(point1, stationList[i-1])
|
|
push!(point2, stationList[i])
|
|
end
|
|
|
|
|
|
|
|
df[!, :point1] = point1
|
|
df[!, :point2] = point2
|
|
df[!, :sequence] = sequence
|
|
|
|
|
|
return df
|
|
end
|
|
|
|
"""
|
|
Function is calculating the deviation for each section and stop. Selected
|
|
quantiles are being created.
|
|
"""
|
|
|
|
function calculateDeviation(df1, perfData, settings)
|
|
|
|
deviationArray = Any[]
|
|
perfData[!, :row] = axes(perfData, 1)
|
|
for row in eachrow(df1)
|
|
deviationSequence = Any[]
|
|
for rowData in eachrow(perfData)
|
|
if rowData.row != 1 &&
|
|
perfData.ZUGEREIGNIS_DS100[rowData.row-1] == row.point1 &&
|
|
rowData.ZUGEREIGNIS_DS100 == row.point2
|
|
if (
|
|
rowData.ZUGEREIGNIS_TYP == 10 ||
|
|
rowData.ZUGEREIGNIS_TYP == 40
|
|
) && (
|
|
perfData.ZUGEREIGNIS_TYP[rowData.row-1] == 20 ||
|
|
perfData.ZUGEREIGNIS_TYP[rowData.row-1] == 50
|
|
)
|
|
actual = Second(
|
|
convert(
|
|
Dates.Second,
|
|
Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_ISTZEIT[rowData.row],
|
|
"dd.mm.yyyy HH:MM",
|
|
) - Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_ISTZEIT[rowData.row-1],
|
|
"dd.mm.yyyy HH:MM",
|
|
),
|
|
),
|
|
)
|
|
estimated = Second(
|
|
convert(
|
|
Dates.Second,
|
|
Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_SOLLZEIT[rowData.row],
|
|
"dd.mm.yyyy HH:MM",
|
|
) - Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_SOLLZEIT[rowData.row-1],
|
|
"dd.mm.yyyy HH:MM",
|
|
),
|
|
),
|
|
)
|
|
deviation = Dates.value(actual - estimated)
|
|
push!(deviationSequence, deviation)
|
|
elseif (
|
|
rowData.ZUGEREIGNIS_TYP == 20 ||
|
|
rowData.ZUGEREIGNIS_TYP == 50
|
|
) && (
|
|
perfData.ZUGEREIGNIS_TYP[rowData.row-1] == 10 ||
|
|
perfData.ZUGEREIGNIS_TYP[rowData.row-1] == 40
|
|
)
|
|
actual = Second(
|
|
convert(
|
|
Dates.Second,
|
|
Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_ISTZEIT[rowData.row],
|
|
"dd.mm.yyyy HH:MM",
|
|
) - Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_ISTZEIT[rowData.row-1],
|
|
"dd.mm.yyyy HH:MM",
|
|
),
|
|
),
|
|
)
|
|
estimated = Second(
|
|
convert(
|
|
Dates.Second,
|
|
Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_SOLLZEIT[rowData.row],
|
|
"dd.mm.yyyy HH:MM",
|
|
) - Dates.DateTime(
|
|
perfData.ZUGEREIGNIS_SOLLZEIT[rowData.row-1],
|
|
"dd.mm.yyyy HH:MM",
|
|
),
|
|
),
|
|
)
|
|
deviation = Dates.value(actual - estimated)
|
|
push!(deviationSequence, deviation)
|
|
end
|
|
end
|
|
end
|
|
if length(deviationSequence) == 0
|
|
deviationSequence = [10]
|
|
row.sequence = "noData"
|
|
end
|
|
push!(deviationArray, deviationSequence)
|
|
end
|
|
quantile = ""
|
|
quantile = settings.quantile[1]
|
|
quantArray = Any[]
|
|
average = Any[]
|
|
meridian = Float64[]
|
|
for row in deviationArray
|
|
x = quantile!(row, parse(Float64, quantile) / 100)
|
|
y = mean(row)
|
|
z = median(row)
|
|
push!(quantArray, x)
|
|
push!(average, y)
|
|
push!(meridian, z)
|
|
end
|
|
nameColumn = "deviation_" * quantile
|
|
df1[!, nameColumn] = quantArray
|
|
df1[!, :averageDeviation] = average
|
|
df1[!, :median] = meridian
|
|
|
|
points = String[]
|
|
for row in eachrow(df1)
|
|
if row.point1 != row.point2
|
|
push!(points, row.point1 * "-" * row.point2)
|
|
else
|
|
push!(points, row.point1)
|
|
end
|
|
end
|
|
select!(df1, Not(:point1))
|
|
df1[!, :points] = points
|
|
df1 = df1[df1[:, :sequence].!="noData", :]
|
|
|
|
return df1
|
|
|
|
end
|
|
|
|
end
|