Compare commits

...

15 Commits

Author SHA1 Message Date
Martin Scheidt 7cc6031a8d
Merge pull request #27 from railtoolkit/development
updated README.md
2022-12-21 16:08:34 +01:00
Martin Scheidt 2949d3c401 updated CHANGELOG.md 2022-12-21 16:05:25 +01:00
Martin Scheidt de24a23f3d removed aarch64 from CI 2022-12-21 15:45:54 +01:00
Martin Scheidt fcf6a16b82 updated README.md with tutorials and documentation 2022-12-21 15:43:23 +01:00
Martin Scheidt 77db3c616a added debug action to ignore list 2022-12-21 14:44:31 +01:00
Martin Scheidt f77fd8b197
Merge pull request #25 from railtoolkit/github-action
GitHub action for automated CHANGELOG.md update upon new release
2022-12-21 14:30:25 +01:00
Martin Scheidt dc8c7c8f5e added semantic versioning checking 2022-12-21 14:28:58 +01:00
Martin Scheidt e754220e79 added automatic version bump for CHANGELOG.md 2022-12-20 23:04:20 +01:00
Martin Scheidt e8e9df9877 debug action 2022-12-20 19:20:40 +01:00
Martin Scheidt 1c643379e8 Merge branch 'main' of github.com:railtoolkit/TrainRun.jl 2022-12-20 15:14:06 +01:00
Martin Scheidt d7118213b4 updated github actions 2022-12-20 13:19:21 +01:00
Martin Scheidt 93942417b5
Merge pull request #24 from railtoolkit/development
fixing Path() load from railtoolkit schema
2022-12-20 12:42:12 +01:00
Martin Scheidt 787d66165a updated github actions 2022-12-19 22:02:19 +01:00
Martin Scheidt b276270ea6 fixed schema validation including test 2022-12-19 21:41:30 +01:00
Martin Scheidt 2ffdcb1fb9 Updated contribution ideas 2022-12-19 13:44:41 +01:00
10 changed files with 230 additions and 101 deletions

View File

@ -11,6 +11,7 @@ on:
- 'README.md'
- '.github/workflows/cffvalidation.yml'
- '.github/workflows/CompatHelper.yml'
- '.github/workflows/debug.yml'
- '.github/workflows/JuliaRegister.yml'
- '.github/workflows/release.yml'
- '.github/workflows/TagBot.yml'
@ -26,6 +27,7 @@ on:
- 'README.md'
- '.github/workflows/cffvalidation.yml'
- '.github/workflows/CompatHelper.yml'
- '.github/workflows/debug.yml'
- '.github/workflows/JuliaRegister.yml'
- '.github/workflows/release.yml'
- '.github/workflows/TagBot.yml'
@ -45,9 +47,9 @@ jobs:
fail-fast: false
matrix:
version:
- '1.6'
- '1.7'
- 'nightly'
- '1.6' # oldest
- '1.8' # current
- 'nightly' # dev
os:
- ubuntu-latest
- macOS-latest

View File

@ -1,7 +1,7 @@
name: CompatHelper
on:
schedule:
- cron: 0 0 * * *
- cron: 23 5 * * 5
workflow_dispatch:
jobs:
CompatHelper:

32
.github/workflows/debug.yml vendored Normal file
View File

@ -0,0 +1,32 @@
### github action to publish a debug
##
name: "debug"
## Controls when the workflow will run
on:
push:
branches: [ github-action ]
## Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
## A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
debug:
# needs: create_package
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: "checkout"
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
uses: actions/checkout@v3
## opening a debug console
- name: Setup upterm session
env:
ZENODO_SANDBOX_ACCESS_TOKEN: ${{ secrets.ZENODO_SANDBOX_ACCESS_TOKEN }}
uses: lhotari/action-upterm@v1
with:
limit-access-to-actor: true

View File

@ -4,52 +4,121 @@ on:
workflow_dispatch:
inputs:
version:
description: "Version to register or component to bump (without leading 'v' e.g. '1.0.1')"
description: "Version to register (without leading 'v' and semantic versioning schema, e.g. '1.0.1')"
required: true
jobs:
create_package:
name: "create package"
runs-on: ubuntu-latest
outputs:
previous_version: ${{ steps.version_test.outputs.previous_version }}
steps:
# 1. checkout the repo
- name: "checkout"
uses: actions/checkout@v3
# 2. create release notes
- name: "create release notes"
# 2. test if provided version number fits in semantic versioning schema
- name: "test version number"
id: version_test
run: |
VERSION=${{ github.event.inputs.version }}
echo "check if version follows the semantic version pattern"
SEM_VER_REGEX="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$"
STATUS=0
grep -qs "Version \[$VERSION\]" CHANGELOG.md || STATUS=1
if [[ ! $VERSION =~ $SEM_VER_REGEX ]]; then
STATUS=1
fi
if [ $STATUS = 1 ]; then
echo "Version $VERSION is not present in CHANGELOG.md."
echo "Version $VERSION does not follow the semantic versioning schema."
echo "Please see https://semver.org/ for further information."
exit 1
fi
TOP=$(grep -n "Version \[$VERSION\]" CHANGELOG.md | cut -d: -f1)
awk "NR>$TOP" CHANGELOG.md > release-note.tmp.md
BOTTOM=$(grep -n -m 1 "## Version\|[Unreleased]:" release-note.tmp.md | cut -d: -f1)
BOTTOM=$(( $TOP + $BOTTOM ))
BOTTOM=$(( $BOTTOM - 2 ))
echo "check if version was already used"
grep -qs "Version \[$VERSION\]" CHANGELOG.md && STATUS=1
if [ $STATUS = 1 ]; then
echo "Version $VERSION is already present in CHANGELOG.md."
exit 1
fi
echo "check if version is an increment"
VERSION_MAJOR=$(echo $VERSION | cut -d. -f1 )
VERSION_MINOR=$(echo $VERSION | cut -d. -f2 )
VERSION_PATCH=$(echo $VERSION | cut -d. -f3 )
PREVIOUS_VERSION=$(grep -n -m 1 "## Version \[*.*.*\]" CHANGELOG.md | cut -d[ -f2 | cut -d] -f1)
PREVIOUS_VERSION_MAJOR=$(echo $PREVIOUS_VERSION | cut -d. -f1 )
PREVIOUS_VERSION_MINOR=$(echo $PREVIOUS_VERSION | cut -d. -f2 )
PREVIOUS_VERSION_PATCH=$(echo $PREVIOUS_VERSION | cut -d. -f3 )
if [[ $VERSION_MAJOR -eq PREVIOUS_VERSION_MAJOR ]]; then
if [[ $VERSION_MINOR -eq PREVIOUS_VERSION_MINOR ]]; then
if [[ $(($VERSION_PATCH - 1)) -ne PREVIOUS_VERSION_PATCH ]]; then
STATUS=1
fi
else
if [[ $(($VERSION_MINOR - 1)) -eq PREVIOUS_VERSION_MINOR ]]; then
if [[ $VERSION_PATCH -ne 0 ]]; then
STATUS=1
fi
else
STATUS=1
fi
fi
else
if [[ $(($VERSION_MAJOR - 1)) -eq PREVIOUS_VERSION_MAJOR ]]; then
if [[ $VERSION_MINOR -ne 0 ]]; then
STATUS=1
fi
if [[ $VERSION_PATCH -ne 0 ]]; then
STATUS=1
fi
else
STATUS=1
fi
fi
if [ $STATUS = 1 ]; then
echo "Version $VERSION skipped steps from the previous version $PREVIOUS_VERSION and thus does not follow the semantic versioning schema."
echo "Please see https://semver.org/ for further information."
exit 1
fi
echo "::set-output name=previous_version::$(version_test deposition show prereserved $PREVIOUS_VERSION)"
# 3. create release note
- name: "create release note"
run: |
VERSION=${{ github.event.inputs.version }}
PREVIOUS_VERSION=${{ needs.create_package.outputs.previous_version }}
STATUS=0
echo "create release note"
TOP=$(grep -n "## \[Unreleased\]" CHANGELOG.md | cut -d: -f1)
TOP=$(( $TOP + 1 ))
BOTTOM=$(grep -n -m 1 "## Version \[$PREVIOUS_VERSION\]" CHANGELOG.md | cut -d: -f1)
BOTTOM=$(( $BOTTOM - 1 ))
awk "NR>$TOP&&NR<$BOTTOM" CHANGELOG.md > release-note-v$VERSION.md
sed -i -- "s/###/##/g" release-note-v$VERSION.md
rm release-note.tmp.md
echo "check if release note is empty"
WORD_COUNT=$(wc -w release-note-v$VERSION.md | awk '{print $1}')
if [[ $WORD_COUNT -lt 4 ]]; then
STATUS=1
fi
if [ $STATUS = 1 ]; then
echo "Please provide a meaningful CHANGELOG.md for the new version $VERSION"
exit 1
fi
# 3. Update metadata.json
- name: "Update metadata.json"
# 4. Update zenodo metadata.json
- name: "Update zenodo metadata.json"
run: |
VERSION=${{ github.event.inputs.version }}
sed -i".backup" -e"s/\"version\": \"%%\[SCRIPT\]\"/\"version\": \"$VERSION\"/g" .github/zenodo/metadata.json
# 4. create release archive
- uses: papeloto/action-zip@v1
# 5. create release archive
- name: "create release archive"
uses: papeloto/action-zip@v1
with:
files: docs src test README.md LICENSE Project.toml
recursive: false
dest: TrainRuns.jl-v${{ github.event.inputs.version }}.zip
# 5. upload artifact to share it with other jobs
# 6. upload artifact to share it with other jobs
- uses: actions/upload-artifact@v3
with:
path: |
@ -130,9 +199,9 @@ jobs:
zenodraft deposition publish $ID
echo "::set-output name=doi::$(zenodraft deposition show prereserved $ID)"
update_citation:
update_repo:
needs: publish_zenodo
name: "updating CITATION.cff"
name: "updating CITATION.cff and CHANGELOG.md"
runs-on: ubuntu-latest
steps:
# 1. checkout the repo
@ -140,12 +209,13 @@ jobs:
uses: actions/checkout@v3
# 2. update CITATION.cff
- run: |
- name: "update CITATION.cff"
run: |
DATE=$(date "+%Y-%m-%d")
VERSION=${{ github.event.inputs.version }}
DOI=${{needs.publish_zenodo.outputs.doi}}
DOI=${{ needs.publish_zenodo.outputs.doi }}
echo "find lines in CITATION.cff"
VERSION_LINE=$(grep -n 'version: [0-9][0-9][0-9][0-9].[0-1][0-9]' CITATION.cff | cut -d: -f1)
VERSION_LINE=$(grep -n '^version:' CITATION.cff | cut -d: -f1)
DATE_LINE=$(grep -n 'date-released:' CITATION.cff | cut -d: -f1)
echo "select the second DOI"
DOI_LINE=$(grep -n 'type: doi' CITATION.cff | cut -d: -f1 | awk "NR==2")
@ -155,18 +225,28 @@ jobs:
sed -i -- "${DATE_LINE}s|.*|date-released: ${DATE}|" CITATION.cff
sed -i -- "${DOI_LINE}s|.*| value: $DOI|" CITATION.cff
# 3. push the change back to main
# 3. update CHANGELOG.md
- name: "update CHANGELOG.md"
run: |
DATE=$(date "+%Y-%m-%d")
VERSION=${{ github.event.inputs.version }}
URL="https://github.com/railtoolkit/TrainRuns.jl/compare"
PREVIOUS_VERSION=${{ needs.create_package.outputs.previous_version }}
echo "increment CHANGELOG.md"
sed -i -- "/## \[Unreleased\]/a\\\n\n## Version [$VERSION] $DATE" CHANGELOG.md
sed -i -- "s|^\[Unreleased\]: .*$|\[Unreleased\]: $URL/v$VERSION...main\n\[$VERSION\]: $URL/v$PREVIOUS_VERSION...v$VERSION|" CHANGELOG.md
# 4. push the change back to main
- name: push
uses: stefanzweifel/git-auto-commit-action@v4
uses: EndBug/add-and-commit@v9
with:
commit_message: "DOI updated to ${{needs.create_package.outputs.version}} (via github action)"
branch: main
file_pattern: CITATION.cff
commit_user_name: railtoolkit
commit_user_email: railtoolkit@ownx.net
message: "DOI updated to ${{ github.event.inputs.version }} (via github action)"
add: CITATION.cff CHANGELOG.md
author_name: railtoolkit
author_email: railtoolkit@ownx.net
register:
needs: update_citation
needs: update_repo
name: "publish in JuliaRegistries"
runs-on: ubuntu-latest
steps:
@ -175,15 +255,15 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
publish_twitter:
publish_mastodon:
needs: publish_zenodo
name: "tweet about it"
name: "Send toot about it to railtoolkit@fosstodon.org"
runs-on: ubuntu-latest
steps:
- uses: devigned/go-twitter-action@v1
with:
message: "The new version ${{ github.event.inputs.version }} of TrainRuns.jl is available! DOI: https://doi.org/${{needs.publish_zenodo.outputs.doi}}"
apiKey: ${{ secrets.TWITTER_API_KEY }}
apiKeySecret: ${{ secrets.TWITTER_API_SECRET }}
accessToken: ${{ secrets.TWITTER_ACCESS_TOKEN }}
accessTokenSecret: ${{ secrets.TWITTER_ACCESS_SECRET }}
- uses: cbrgm/mastodon-github-action@v1
with:
message: "The new version ${{ github.event.inputs.version }} of TrainRuns.jl is available! DOI: https://doi.org/${{needs.publish_zenodo.outputs.doi}}"
visibility: "public" # default: public
env:
MASTODON_URL: "https://fosstodon.org/"
MASTODON_ACCESS_TOKEN: ${{ secrets.MASTODON_ACCESS_TOKEN }} # access token

View File

@ -9,6 +9,12 @@ Categories: Added, Changed, Deprecated, Removed, Fixed, and Security.
## [Unreleased]
### Added
* documentation strings for functions in formulary.jl, output.jl, and behavior.jl
### Fixed
* loading errors with ill-structured path file
## Version [1.0.2] 2022-09-01

View File

@ -92,21 +92,21 @@ Models for:
* Breakaway (currently simple like acceleration)
* braking (currently constant braking with a certain value)
* inhomogeneous mass band (consider non-uniform mass distribution (cf. Wende, 2003 p. 96f.))
* double traction
More exact calculation of resistances for:
* the track (e.g. including curves, switches, tunnels)
* for the train (e.g. there are vehicle resistance equations especially for high-speed trains, which are not yet considered in the tool (cf. Wende, 2003 p. 152 f.))
Input/calculation of tractive force (currently only tractive force-speed pairs. This could be extended to include tractive force functions that apply to specific velocity ranges (cf. Brünger, et al., 2014 p. 69).
* Input/calculation of tractive force (currently only tractive force-speed pairs. This could be extended to include tractive force functions that apply to specific velocity ranges (cf. Brünger, et al., 2014 p. 69).
Calculation of energy, cf. (Wende, 2003 p. 324).
* Calculation of energy, cf. (Wende, 2003 p. 324).
* Energy-saving driving: https://doi.org/10.1016/j.ejor.2016.09.044
switching between different step variables in one train run or implementation of variable step size (currently it is necessary to choose between s, t and v and to specify a step size that becomes smaller at intersections, but is otherwise constant)
* switching between different step variables in one train run or implementation of variable step size (currently it is necessary to choose between s, t and v and to specify a step size that becomes smaller at intersections, but is otherwise constant)
Driver behaviour, in order to be able to determine the driving behavior of the vehicles more realistically.
* introduce a driving regime in trainrun() with a velocity > 0 at the starting point and a milage != 0 for the starting point
i.e. trainrun(train::Train, path::Path, regime=Regime()::Regime, settings=Settings()::Settings)
e.g. Regime((v1,milage1),(v2,milage2),...,(vX,milageX)) v=(Int,v_max,coasting,halt)
Energy-saving driving.
good plots would be nice
Pluto notebook show case
* good plots would be nice

View File

@ -12,7 +12,7 @@ TrainRuns.jl is a step towards open science and open data in railway engineering
# Installation
Use the package manager provided by julia:
Use the package manager provided by [julia](https://julialang.org):
```julia
julia> # use the ] key
(@v1.x) pkg> add TrainRuns
@ -42,6 +42,14 @@ println("The train needs $runtime seconds for the running path.")
------------
# Further Information
Visit the repository [TrainRuns.jl-Tutorials](https://github.com/railtoolkit/TrainRuns.jl-Tutorials) for tutorials in either Jupyther Notebooks or Pluto Notebooks. There you can find, for instance, a [basic tutorial](https://github.com/railtoolkit/TrainRuns.jl-Tutorials/blob/main/basic.ipynb).
Please refer to the automated [documentation](https://www.railtoolkit.org/TrainRuns.jl/) for technical details of the used functions.
------------
# Acknowledgement
This work was supervised by South Westphalia University of Applied Sciences and Technical University Braunschweig.

View File

@ -64,9 +64,7 @@ function Settings(
settings = YAML.load(open(file))["settings"]
## validate the loaded file
try
validate(schema, settings)
catch err
if !isvalid(schema, settings)
println("Could not load settings file '$file'.\n Format is not recognized - using default as fall back.")
settings = Dict()
end
@ -112,17 +110,8 @@ function Path(file, type = :YAML)
## load from file
if type == :YAML
data = YAML.load(open(file))
if data["schema"] != "https://railtoolkit.org/schema/running-path.json"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
if data["schema_version"] != "2022.05"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
## error messages
format_error = "\n\tCould not parse file '$file'.\n\tNot a valide railtoolkit/schema format.\n\tCurrently supported version: 2022.05\n\tFor the format see: https://github.com/railtoolkit/schema"
## JSON schema for YAML-file validation
railtoolkit_schema = Schema("""{
@ -206,18 +195,13 @@ function Path(file, type = :YAML)
}
}""")
paths = data["paths"]
try
validate(railtoolkit_schema, paths)
catch err
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
if length(paths) > 1
println("WARNING: the loaded file contains more than one path. Using only the first!")
end
path = paths[1]
data = YAML.load(open(file))
data["schema"] == "https://railtoolkit.org/schema/running-path.json" ? nothing : throw(DomainError(data["schema"],format_error))
data["schema_version"] == "2022.05" ? nothing : throw(DomainError(data["schema_version"],format_error))
isvalid(railtoolkit_schema, data["paths"]) ? nothing : throw(DomainError(data["paths"],format_error))
length(data["paths"]) > 1 ? println("WARNING: the loaded file contains more than one path. Using only the first!") : nothing
path = data["paths"][1]
## set the variables in "path"
# required
@ -230,7 +214,7 @@ function Path(file, type = :YAML)
haskey(path, "points_of_interest") ? tmp_points = path["points_of_interest"] : nothing
else
error("Unknown file type '$type'")
throw(DomainError("Unknown file type '$type'"))
end #if type
## process characteristic sections
@ -313,17 +297,8 @@ function Train(file, type = :YAML)
## load from file
if type == :YAML
data = YAML.load(open(file))
if data["schema"] != "https://railtoolkit.org/schema/rolling-stock.json"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/rolling-stock (2022.05)")
end
if data["schema_version"] != "2022.05"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/rolling-stock (2022.05)")
end
## error messages
format_error = "\n\tCould not parse file '$file'.\n\tNot a valide railtoolkit/schema format.\n\tCurrently supported version: 2022.05\n\tFor the format see: https://github.com/railtoolkit/schema"
## JSON schema for YAML-file validation
railtoolkit_schema = Schema("""{
@ -474,21 +449,19 @@ function Train(file, type = :YAML)
}
}""")
try
validate(railtoolkit_schema, data)
catch err
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/rolling-stock (2022.05)")
end
## validation
data = YAML.load(open(file))
data["schema"] == "https://railtoolkit.org/schema/rolling-stock.json" ? nothing : throw(DomainError(data["schema"],format_error))
data["schema_version"] == "2022.05" ? nothing : throw(DomainError(data["schema_version"],format_error))
isvalid(railtoolkit_schema, data) ? nothing : throw(DomainError(data,format_error))
else
error("Unknown file type '$type'")
throw(DomainError("Unknown file type '$type'"))
end #if type
trains = data["trains"]
Base.length(trains) > 1 ? println("WARNING: the loaded file contains more than one train. Using only the first!") : nothing
Base.length(trains) == 0 ? error("No train present in file '$file'") : nothing
Base.length(trains) == 0 ? throw(DomainError("No train present in file '$file'")) : nothing
train = trains[1]
used_vehicles = unique(train["formation"])
@ -499,7 +472,7 @@ function Train(file, type = :YAML)
## test if all vehicles of the formation are avilable
for vehicle in used_vehicles
vehicle included_vehicles ? error("'$vehicle' is not present in '$file'") : nothing
vehicle included_vehicles ? throw(DomainError("'$vehicle' is not present in '$file'")) : nothing
end
## gather the count of vehicles and usage in the formation
@ -544,7 +517,7 @@ function Train(file, type = :YAML)
end
Base.length(loco) > 1 ? println("WARNING: the loaded file contains more than one traction unit or multiple unit. Using only the first!") : nothing
loco[1].n > 1 ? println("WARNING: the loaded file contains more than one traction unit or multiple unit. Using only one!") : nothing
Base.length(loco) == 0 ? error("No traction unit or multiple unit present in file '$file'") : nothing
Base.length(loco) == 0 ? throw(DomainError("No traction unit or multiple unit present in file '$file'")) : nothing
loco = loco[1].data
cars = vehicles

View File

@ -0,0 +1,27 @@
%YAML 1.2
---
schema: https://railtoolkit.org/schema/running-path.json
schema_version: "2022.05"
paths:
id: broken
UUID: 53778d7d-ee4f-4edb-9d17-5341dbd517f6
name: "broken test"
points_of_interest:
-
- 850.00
- view_point
- front
characteristic_sections:
-
- 0.00
- 200.0
- 0.00
-
- 855.84
- 200.0
- -0.44
-
- 968.06
- 200.0
- -0.44

View File

@ -36,6 +36,7 @@ settings = Dict()
@test typeof(first(paths)[2]) == Path
@test typeof(first(settings)[2]) == Settings
@test_throws DomainError Path("data/paths/broken.yaml")
end
println("====================")