Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update gas mixture example, add CI #6

Merged
merged 10 commits into from
Jul 26, 2024
149 changes: 149 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: xrayAttenuation CI
on:
push:
paths:
- 'tests/**'
- 'src/**'
- 'docs/**'
- 'xrayAttenuation.nimble'
- '.github/workflows/ci.yml'
branches:
- 'master'
pull_request:
paths:
- 'tests/**'
- 'src/**'
- 'docs/**'
- 'xrayAttenuation.nimble'
- '.github/workflows/ci.yml'

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
nim:
#- '1.6.x'
- '2.0.x'
- 'devel'
os:
- ubuntu-latest
- windows-latest
- macOS-latest
name: '${{ matrix.nim }} (${{ matrix.os }})'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: xrayAttenuation

- name: Setup nim
uses: jiro4989/setup-nim-action@v1
with:
nim-version: ${{ matrix.nim }}
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Install dependencies (Ubuntu)
if: ${{matrix.os == 'ubuntu-latest'}}
run: |
sudo apt-get update
sudo apt-get install musl musl-dev musl-tools

- name: Setup nimble & deps
shell: bash
run: |
cd xrayAttenuation
nimble refresh -y
nimble install -y
nimble ciDeps -y

- name: Run tests
shell: bash
run: |
cd xrayAttenuation
nimble -y test

- name: Build docs
if: ${{ matrix.docs == 'true' && matrix.os == 'ubuntu-latest' }}
shell: bash
run: |
cd xrayAttenuation
branch=${{ github.ref }}
branch=${branch##*/}
nimble doc --project --outdir:docs \
'--git.url:https://github.com/${{ github.repository }}' \
'--git.commit:${{ github.sha }}' \
"--git.devel:$branch" \
xrayAttenuation.nim
# Ignore failures for older Nim
cp docs/{the,}index.html || true

- name: Publish docs
if: >
github.event_name == 'push' && github.ref == 'refs/heads/master' &&
matrix.os == 'ubuntu-latest' && matrix.nim == 'devel'
uses: crazy-max/ghaction-github-pages@v1
with:
build_dir: xrayAttenuation/docs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Build examples
if: ${{ matrix.os == 'ubuntu-latest' && matrix.nim == '2.0.x' }}
shell: bash
run: |
cd xrayAttenuation/examples
nim c -d:musl -d:staticBuild -d:release calc_gas_mixtures.nim

- name: Upload example as artifact
uses: actions/upload-artifact@v3
with:
name: calc_gas_mixtures
path: xrayAttenuation/examples/calc_gas_mixtures

release:
runs-on: ${{ matrix.os }}
needs: build
strategy:
fail-fast: false
matrix:
nim:
- '2.0.x'
os:
- ubuntu-latest
name: '${{ matrix.nim }} (${{ matrix.os }})'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: xrayAttenuation

- name: Download binary
uses: actions/download-artifact@v3
with:
name: calc_gas_mixtures
path: ./ # Specify the path to download the binary to

- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
Release notes for version ${{ github.ref }}
draft: false
prerelease: false

- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./calc_gas_mixtures
asset_name: calc_gas_mixtures
asset_content_type: application/octet-stream
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,48 @@ proc getMassFractions(gm: GasMixture): seq[(string, float)] =
let fraction = cFrac * ratio * molarMass(c) / molarMass(gm)
result.add (el, float fraction)

proc gas(elements: seq[string], pressure: mbar, T = 293.15.K) =
proc genOutfile(gm: GasMixture, outfile, outdir: string): string =
if outfile.len > 0: result = outfile
else:
if outdir.len > 0: result = outdir & "/"
result.add "transmission"
for el, frac in gm:
result.add &"_{el}_{frac}"
result.add &"_{gm.pressure}_{gm.temperature}"
result.add ".csv"

proc calcTransmission(gm: GasMixture, length: cm, energyMin, energyMax: keV, num: int, outfile: string) =
let E = linspace(energyMin.float, energyMax.float, num)
let df = toDf({"Energy [keV]" : E})
.mutate(f{float: "Transmission" ~ transmission(gm, length, idx("Energy [keV]").keV).float})
df.writeCsv(outfile)

proc calculateTransmissions(gm: GasMixture, length: cm, energyMin, energyMax: keV, num: int, outfile, outdir: string) =
## Calculates the transmission of the combined gas mixture and all compounds (for their partial
## pressure) and writes a CSV file to `outfile`.
let outfile = genOutfile(gm, outfile, outdir)
calcTransmission(gm, length, energyMin, energyMax, num, outfile)
# 2. split by individual compounds in gas
for el, frac in gm:
# calc partial pressure
let P = gm.pressure * frac
# construct helper gas mixture
let gmP = initGasMixture(gm.temperature, P, @[el], @[1.0])
let outfile = genOutfile(gmP, "", outdir) # always use autogenerated name for partial pressures
calcTransmission(gmP, length, energyMin, energyMax, num, outfile)

proc gas(elements: seq[string], pressure: mbar, T = 293.15.K,
length = -1.cm, energyMin = 0.keV, energyMax = 15.keV, numEnergies = 1000,
outfile = "", outdir = "") =
## Computes the particle fractions for each compound in the gas mixture. For each
## compound it also prints the fraction split by mass fraction of the compound
## (under 'Particle fractions'). And for 'Mass fractions' prints the mass fractions
## of each element of the total masses.
##
## If a `length` is given in centimeter, it will also calculate the transmission of
## of X-rays through such a gas in the energy range `[energyMin, energyMax]` and store
## it `outfile`. In addition extra outfiles derived from `outfile` are produced for each
## gas compound split by their partial pressures.
var gases: seq[Compound]
var frac: seq[float]
for el in elements:
Expand Down Expand Up @@ -79,6 +120,9 @@ proc gas(elements: seq[string], pressure: mbar, T = 293.15.K) =
for fr in getMassFractions(gm):
stdout.styledWriteLine(fgRed, &"\t{fr[0]:<2}: {fr[1]}")

if length > 0.cm:
gm.calculateTransmissions(length, energyMin, energyMax, numEnergies, outfile, outdir)

proc solid(elements: seq[string], ρ = -1.0.g•cm⁻³) =
var elRT: seq[(ElementRT, int)]
for el in elements:
Expand Down
7 changes: 7 additions & 0 deletions examples/nim.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# From Chuck's nim.cfg
@if musl: # Statically links `foo` with musl; --opt:size trades more speed
cc = gcc # NOTE: This seems to work better as a ..
gcc.exe = "musl-gcc" #..per-module foo.nim.cfg than here.
gcc.linkerexe = "musl-gcc"
passL = "-static -s"
@end
10 changes: 10 additions & 0 deletions xrayAttenuation.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ requires "ggplotnim >= 0.5.1"
requires "unchained >= 0.1.9"
requires "numericalnim"
requires "cligen"

task ciDeps, "Install CI dependencies":
exec "nimble install nimhdf5"

task test, "Run the tests":
exec "nim c -r tests/tests.nim"
exec "nim c -r playground/mean_free_path.nim"
# only compile for now
## Does not compile right now due to some weird nimhdf5 regression!
#exec "nim c playground/llnl_telescope_reflectivity.nim"
Loading