Skip to content

Commit

Permalink
Merge pull request #18 from LIBRA-project/plotting-lsc
Browse files Browse the repository at this point in the history
Plotting for new LSC classes
  • Loading branch information
RemDelaporteMathurin authored Nov 8, 2024
2 parents 920f3e6 + e5cfb1c commit 223de54
Show file tree
Hide file tree
Showing 6 changed files with 378 additions and 126 deletions.
13 changes: 8 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
name: CI
on: [pull_request, push]


jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v2
with:
Expand All @@ -17,12 +16,16 @@ jobs:
- name: Install dependencies
run: |
pip install .[tests]
- name: Run tests
run: |
python -m pytest test/ --cov libra_toolbox --cov-report xml --cov-report term
- name: Run notebook examples
run: |
jupyter nbconvert --to python --execute docs/examples/*.ipynb
# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v4
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# token: ${{ secrets.CODECOV_TOKEN }}
265 changes: 146 additions & 119 deletions docs/examples/fit_tritium_release.ipynb

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions libra_toolbox/tritium/lsc_measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def get_lum(self):


class LSCSample:
activity: pint.Quantity

def __init__(self, activity: pint.Quantity, name: str):
self.activity = activity
self.name = name
Expand All @@ -83,6 +85,8 @@ def from_file(file_reader: LSCFileReader, vial_name):


class LIBRASample:
samples: List[LSCSample]

def __init__(self, samples: List[LSCSample], time: str):
self.samples = samples
self._time = time
Expand Down Expand Up @@ -115,6 +119,8 @@ def get_total_activity(self):


class LIBRARun:
samples: List[LIBRASample]

def __init__(self, samples: List[LIBRASample], start_time: str):
self.samples = samples
self.start_time = start_time
Expand Down Expand Up @@ -142,3 +148,8 @@ def get_cumulative_activity(self, form: str = "total"):
@property
def relative_times(self):
return [sample.get_relative_time(self.start_time) for sample in self.samples]

@property
def relative_times_as_pint(self):
times = [t.total_seconds() * ureg.s for t in self.relative_times]
return ureg.Quantity.from_list(times).to(ureg.day)
119 changes: 118 additions & 1 deletion libra_toolbox/tritium/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,130 @@

from libra_toolbox.tritium import ureg
from libra_toolbox.tritium.model import Model, quantity_to_activity
from libra_toolbox.tritium.lsc_measurements import LIBRASample, LIBRARun

import pint
from typing import List

COLLECTION_VOLUME = 10 * ureg.ml
LSC_SAMPLE_VOLUME = 10 * ureg.ml


def plot_bars(measurements, index=None, bar_width=0.35, stacked=True):
def plot_bars(
measurements: List[LIBRASample] | LIBRARun | dict,
index=None,
bar_width=0.35,
stacked=True,
):
if isinstance(measurements, dict):
return plot_bars_old(measurements, index, bar_width, stacked)

if isinstance(measurements, LIBRARun):
measurements = measurements.samples

vial_1_vals = ureg.Quantity.from_list(
[sample.samples[0].activity for sample in measurements]
)
vial_2_vals = ureg.Quantity.from_list(
[sample.samples[1].activity for sample in measurements]
)
vial_3_vals = ureg.Quantity.from_list(
[sample.samples[2].activity for sample in measurements]
)
vial_4_vals = ureg.Quantity.from_list(
[sample.samples[3].activity for sample in measurements]
)

if index is None:
if stacked:
index = np.arange(len(measurements))
else:
group_spacing = 1 # Adjust this value to control spacing between groups
index = (
np.arange(len(measurements)) * (group_spacing / 2 + 1) * bar_width * 4
)

if stacked:
vial_3_bar = plt.bar(
index,
vial_3_vals,
bar_width,
label="Vial 3",
color="#FB8500",
)
vial_4_bar = plt.bar(
index,
vial_4_vals,
bar_width,
label="Vial 4",
color="#FFB703",
bottom=vial_3_vals,
)
vial_1_bar = plt.bar(
index,
vial_1_vals,
bar_width,
label="Vial 1",
color="#219EBC",
bottom=vial_3_vals + vial_4_vals,
)
vial_2_bar = plt.bar(
index,
vial_2_vals,
bar_width,
label="Vial 2",
color="#8ECAE6",
bottom=vial_3_vals + vial_4_vals + vial_1_vals,
)
else:
if isinstance(index, pint.Quantity) and not isinstance(
bar_width, pint.Quantity
):
raise TypeError(
f"index and bar_width must be of the same type, got {index=}, {bar_width=}"
)

vial_1_bar = plt.bar(
index - 1.5 * bar_width,
vial_1_vals,
bar_width,
linewidth=2,
edgecolor="white",
label="Vial 1",
color="#219EBC",
)
vial_2_bar = plt.bar(
index - 0.5 * bar_width,
vial_2_vals,
bar_width,
linewidth=2,
edgecolor="white",
label="Vial 2",
color="#8ECAE6",
)
vial_3_bar = plt.bar(
index + 0.5 * bar_width,
vial_3_vals,
bar_width,
linewidth=2,
edgecolor="white",
label="Vial 3",
color="#FB8500",
)
vial_4_bar = plt.bar(
index + 1.5 * bar_width,
vial_4_vals,
bar_width,
linewidth=2,
edgecolor="white",
label="Vial 4",
color="#FFB703",
)

return index


def plot_bars_old(measurements, index=None, bar_width=0.35, stacked=True):
vial_1_vals = (
np.array([sample[1].magnitude for sample in measurements.values()]) * ureg.Bq
)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dynamic = ["version"]
dependencies = ["numpy", "pint", "scipy", "matplotlib", "sympy", "pandas"]

[project.optional-dependencies]
tests = ["pytest>=5.4.3", "pytest-cov"]
tests = ["pytest>=5.4.3", "pytest-cov", "nbconvert", "ipykernel"]

[tool.setuptools_scm]
write_to = "libra_toolbox/_version.py"
94 changes: 94 additions & 0 deletions test/tritium/test_plotting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import pytest
import numpy as np
from libra_toolbox.tritium.plotting import plot_bars
from libra_toolbox.tritium.lsc_measurements import LIBRASample, LIBRARun, LSCSample
from libra_toolbox.tritium import ureg

import matplotlib.pyplot as plt


@pytest.fixture
def sample_measurements():
samples = [
LIBRASample(
samples=[
LSCSample(activity=1 * ureg.Bq, name="Sample 1A"),
LSCSample(activity=1.1 * ureg.Bq, name="Sample 1B"),
LSCSample(activity=1.2 * ureg.Bq, name="Sample 1C"),
LSCSample(activity=1.3 * ureg.Bq, name="Sample 1D"),
],
time="11/8/2024 4:20 PM",
),
LIBRASample(
samples=[
LSCSample(activity=2 * ureg.Bq, name="Sample 2A"),
LSCSample(activity=2.1 * ureg.Bq, name="Sample 2B"),
LSCSample(activity=2.2 * ureg.Bq, name="Sample 2C"),
LSCSample(activity=2.3 * ureg.Bq, name="Sample 2D"),
],
time="11/8/2024 4:21 PM",
),
LIBRASample(
samples=[
LSCSample(activity=3 * ureg.Bq, name="Sample 3A"),
LSCSample(activity=3.1 * ureg.Bq, name="Sample 3B"),
LSCSample(activity=3.2 * ureg.Bq, name="Sample 3C"),
LSCSample(activity=3.3 * ureg.Bq, name="Sample 3D"),
],
time="11/8/2024 4:22 PM",
),
LIBRASample(
samples=[
LSCSample(activity=4 * ureg.Bq, name="Sample 4A"),
LSCSample(activity=4.1 * ureg.Bq, name="Sample 4B"),
LSCSample(activity=4.2 * ureg.Bq, name="Sample 4C"),
LSCSample(activity=4.3 * ureg.Bq, name="Sample 4D"),
],
time="11/8/2024 4:23 PM",
),
]
return samples


@pytest.fixture
def sample_run(sample_measurements):
return LIBRARun(samples=sample_measurements, start_time="11/7/2024 4:20 PM")


def test_plot_bars_with_samples(sample_measurements):
plt.figure()
index = plot_bars(sample_measurements)
assert len(index) == len(sample_measurements)
plt.close()


def test_plot_bars_with_run(sample_run):
plt.figure()
index = plot_bars(sample_run)
assert len(index) == len(sample_run.samples)
plt.close()


def test_plot_bars_with_dict():
measurements = {
"sample1": [0, 1 * ureg.Bq, 2 * ureg.Bq, 3 * ureg.Bq, 4 * ureg.Bq],
"sample2": [0, 2 * ureg.Bq, 3 * ureg.Bq, 4 * ureg.Bq, 5 * ureg.Bq],
}
plt.figure()
index = plot_bars(measurements)
assert len(index) == len(measurements)
plt.close()


def test_plot_bars_stacked(sample_measurements):
plt.figure()
index = plot_bars(sample_measurements, stacked=True)
assert len(index) == len(sample_measurements)
plt.close()


def test_plot_bars_not_stacked(sample_measurements):
plt.figure()
index = plot_bars(sample_measurements, stacked=False)
assert len(index) == len(sample_measurements)
plt.close()

0 comments on commit 223de54

Please sign in to comment.