From 76ba050278eb6cd0aecdb8d453c37316e8fa1496 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 11:39:01 -0500 Subject: [PATCH 01/11] added LSCFileReader class --- libra_toolbox/tritium/lsc_measurements.py | 46 +++++++++++++++++ test/tritium/TEST_CSV.csv | 62 +++++++++++++++++++++++ test/tritium/test_lsc_reader.py | 33 ++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 libra_toolbox/tritium/lsc_measurements.py create mode 100644 test/tritium/TEST_CSV.csv create mode 100644 test/tritium/test_lsc_reader.py diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py new file mode 100644 index 0000000..7bc274b --- /dev/null +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -0,0 +1,46 @@ +import pandas as pd + + +class LSCFileReader: + def __init__(self, file_path, vial_labels=None): + self.file_path = file_path + self.vial_labels = vial_labels + self.data = None + self.header_content = None + + def read_file(self): + # first read the file without dataframe to find the line starting with S# + header_lines = [] + with open(self.file_path, "r") as file: + lines = file.readlines() + for i, line in enumerate(lines): + if line.startswith("S#"): + start = i + break + header_lines.append(line) + self.header_content = "".join(header_lines) + + # read the file with dataframe starting from the line with S# + self.data = pd.read_csv(self.file_path, skiprows=start) + + def get_bq1_values(self): + return self.data["Bq:1"].tolist() + + def get_bq1_values_with_labels(self): + if self.vial_labels is None: + raise ValueError("Vial labels must be provided") + + assert len(self.vial_labels) == len( + self.get_bq1_values() + ), "Vial labels and Bq:1 values are not equal in length, remember to give None as a label for missing vials" + + values = self.get_bq1_values() + labelled_values = {label: val for label, val in zip(self.vial_labels, values)} + + return labelled_values + + def get_count_times(self): + return self.data["Count Time"].tolist() + + def get_lum(self): + return self.data["LUM"].tolist() diff --git a/test/tritium/TEST_CSV.csv b/test/tritium/TEST_CSV.csv new file mode 100644 index 0000000..4dc4883 --- /dev/null +++ b/test/tritium/TEST_CSV.csv @@ -0,0 +1,62 @@ +Assay Definition + +Assay Description: + +Assay Type: DPM (Single) +Report Name: Report1 +Output Data Path: C:\Packard\Tricarb\Results\Default\NEW_Flibe_Long\20241105_1402\Replay_20241107_164832 +Raw Results Path: C:\Packard\Tricarb\Results\Default\NEW_Flibe_Long\20241105_1402\20241105_1402.results +Comma-Delimited File Name: C:\Packard\Tricarb\Results\Default\NEW_Flibe_Long\20241105_1402\Replay_20241107_164832\TEST_CSV.csv +Assay File Name: C:\Packard\TriCarb\Assays\NEW_Flibe_Long.lsa + +Additional Data Files Generated with this Protocol: +Report1 + [Excel] TEST_CSV.csv + + +Count Conditions + +Nuclide: Low Energy Test + Quench Indicator: tSIE/AEC + External Std Terminator (sec): 0.5 2s% + Pre-Count Delay (min): 0.00 +Quench Set: + Low Energy: 3H-UG +Count Time (min): 120.00 +Count Mode: Normal +Assay Count Cycles: 1 Repeat Sample Count: 1 +Number of Vials/Sample: 1 Calculate % Reference: Off + + +Background Subtract: Off +Low CPM Threshold: Off +2 Sigma % Terminator: Off + +Regions LL UL +A 0.0 18.6 +B 2.0 18.6 +C 4.0 18.6 + + +Count Corrections + +Static Controller: On Luminescence Correction: On GCT: n/a +Colored Samples: Off Heterogeneity Monitor: Off PAC: Disabled +Coincidence Time (nsec): 18 Delay Before Burst (nsec): 75 PAC Strength: n/a Auxiliary Spectrum: n/a + + +S#,Count Time,CPMA,DPM1,SIS,tSIE,MESSAGES,Bq:1,SD:DPM1,LUM +1,120.00,7,25.2,584.14,277.96,,0.420,39 +2,120.00,7,23.6,962.64,284.41,,0.393,1 +3,120.00,7,23.7,975.61,288.98,,0.396,0 +4,120.00,8,25.9,996.56,289.69,,0.431,0 +Missing vial 5. +6,120.00,8,22.6,1054.62,336.32,,0.376,0 +7,120.00,7,22.4,1010.80,292.80,,0.373,0 +8,120.00,13,45.6,860.95,290.08,,0.760,0 +9,120.00,8,26.0,985.48,289.75,,0.434,0 +Missing vial 10. +11,120.00,6,20.0,1039.97,308.57,,0.334,0 +12,120.00,6,19.2,1000.43,290.51,,0.320,0 +13,120.00,28,93.9,682.87,290.16,,1.565,0 +14,120.00,7,22.6,972.41,290.01,,0.376,0 diff --git a/test/tritium/test_lsc_reader.py b/test/tritium/test_lsc_reader.py new file mode 100644 index 0000000..5268332 --- /dev/null +++ b/test/tritium/test_lsc_reader.py @@ -0,0 +1,33 @@ +from libra_toolbox.tritium.lsc_measurements import LSCFileReader + +from pathlib import Path + + +def test_lsc_reader(): + filename = Path(__file__).parent / "TEST_CSV.csv" + + csv_reader = LSCFileReader(filename) + csv_reader.vial_labels = [ + "1-1-1", + "1-1-2", + "1-1-3", + "1-1-4", + None, + "1-2-1", + "1-2-2", + "1-2-3", + "1-2-4", + None, + "1-3-1", + "1-3-2", + "1-3-3", + "1-3-4", + ] + csv_reader.read_file() + bq1_values = csv_reader.get_bq1_values() + print(bq1_values) + bq1_values_with_labels = csv_reader.get_bq1_values_with_labels() + print(bq1_values_with_labels) + + assert len(bq1_values) == 14 + assert len(bq1_values_with_labels) == 13 From afa2a322e4ed4f29950a9872a628c98076c85f59 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 11:40:48 -0500 Subject: [PATCH 02/11] pandas in dependencies --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0a62843..4681be1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ description = "Design and analysis tools for LIBRA project" license = {file = "LICENSE"} requires-python = ">=3.6" dynamic = ["version"] -dependencies = ["numpy", "pint", "scipy", "matplotlib", "sympy"] +dependencies = ["numpy", "pint", "scipy", "matplotlib", "sympy", "pandas"] [project.optional-dependencies] tests = ["pytest>=5.4.3", "pytest-cov"] From f5a3f53dd8774481b5bfaa661ae3f0d21492e239 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 15:05:28 -0500 Subject: [PATCH 03/11] added LSC sample classes --- libra_toolbox/tritium/lsc_measurements.py | 90 +++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py index 7bc274b..bc1e59c 100644 --- a/libra_toolbox/tritium/lsc_measurements.py +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -1,4 +1,8 @@ import pandas as pd +from typing import List +import pint +from libra_toolbox.tritium.model import ureg +from datetime import datetime class LSCFileReader: @@ -44,3 +48,89 @@ def get_count_times(self): def get_lum(self): return self.data["LUM"].tolist() + + +class LSCSample: + def __init__(self, activity: pint.Quantity, name: str): + self.activity = activity + self.name = name + # TODO add other attributes available in LSC file + self.background_substracted = False + + def __str__(self): + return f"Sample {self.name}" + + def substract_background(self, background_sample: "LSCSample"): + if self.background_substracted: + raise ValueError("Background already substracted") + self.activity -= background_sample.activity + self.background_substracted = True + + @staticmethod + def from_file(file_reader: LSCFileReader, vial_name): + values = file_reader.get_bq1_values_with_labels() + activity = values[vial_name] * ureg.Bq + return LSCSample(activity, vial_name) + + +class LIBRASample: + def __init__(self, samples: List[LSCSample], time: str): + self.samples = samples + self._time = time + + def get_relative_time(self, start_time: str): + + start_time = datetime.strptime(start_time, "%m/%d/%Y %I:%M %p") + sample_time = datetime.strptime(self._time, "%m/%d/%Y %I:%M %p") + return sample_time - start_time + + def substract_background(self, background_sample: LSCSample): + for sample in self.samples: + sample.substract_background(background_sample) + + def get_soluble_activity(self): + act = 0 + for sample in self.samples[:2]: + act += sample.activity + + return act + + def get_insoluble_activity(self): + act = 0 + for sample in self.samples[2:]: + act += sample.activity + + return act + + def get_total_activity(self): + return self.get_soluble_activity() + self.get_insoluble_activity() + + +class LIBRARun: + def __init__(self, samples: List[LIBRASample], start_time: str): + self.samples = samples + self.start_time = start_time + + def get_cumulative_activity(self, form: str = "total"): + # check that background has been substracted + for sample in self.samples: + for lsc_sample in sample.samples: + if not lsc_sample.background_substracted: + raise ValueError( + "Background must be substracted before calculating cumulative activity" + ) + cumulative_activity = [] + for sample in self.samples: + if form == "total": + cumulative_activity.append(sample.get_total_activity()) + elif form == "soluble": + cumulative_activity.append(sample.get_soluble_activity()) + elif form == "insoluble": + cumulative_activity.append(sample.get_insoluble_activity()) + cumulative_activity = pint.Quantity.from_list(cumulative_activity) + cumulative_activity = cumulative_activity.cumsum() + return cumulative_activity + + @property + def relative_times(self): + return [sample.get_relative_time(self.start_time) for sample in self.samples] From 87f42aee3671abaa1980dd127962612d1b0f332d Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 15:22:05 -0500 Subject: [PATCH 04/11] use correct registry --- libra_toolbox/tritium/lsc_measurements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py index bc1e59c..8864634 100644 --- a/libra_toolbox/tritium/lsc_measurements.py +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -127,7 +127,7 @@ def get_cumulative_activity(self, form: str = "total"): cumulative_activity.append(sample.get_soluble_activity()) elif form == "insoluble": cumulative_activity.append(sample.get_insoluble_activity()) - cumulative_activity = pint.Quantity.from_list(cumulative_activity) + cumulative_activity = ureg.Quantity.from_list(cumulative_activity) cumulative_activity = cumulative_activity.cumsum() return cumulative_activity From c9858847c05ca3458e9947b052c32aeaa66efc7e Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 15:22:11 -0500 Subject: [PATCH 05/11] type hinting --- libra_toolbox/tritium/lsc_measurements.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py index 8864634..314dd0c 100644 --- a/libra_toolbox/tritium/lsc_measurements.py +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -2,7 +2,7 @@ from typing import List import pint from libra_toolbox.tritium.model import ureg -from datetime import datetime +from datetime import datetime, timedelta class LSCFileReader: @@ -78,8 +78,7 @@ def __init__(self, samples: List[LSCSample], time: str): self.samples = samples self._time = time - def get_relative_time(self, start_time: str): - + def get_relative_time(self, start_time: str) -> timedelta: start_time = datetime.strptime(start_time, "%m/%d/%Y %I:%M %p") sample_time = datetime.strptime(self._time, "%m/%d/%Y %I:%M %p") return sample_time - start_time From 7f8ced2ba4fcae2c0e413b9b7deb405e172e6dee Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 15:48:37 -0500 Subject: [PATCH 06/11] added warning --- libra_toolbox/tritium/lsc_measurements.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py index 314dd0c..ec2b8e3 100644 --- a/libra_toolbox/tritium/lsc_measurements.py +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -3,6 +3,7 @@ import pint from libra_toolbox.tritium.model import ureg from datetime import datetime, timedelta +import warnings class LSCFileReader: @@ -27,6 +28,12 @@ def read_file(self): # read the file with dataframe starting from the line with S# self.data = pd.read_csv(self.file_path, skiprows=start) + # check if last column is all NaN + if self.data[self.data.columns[-1]].isnull().all(): + warnings.warn( + "There seem to be an issue with the last column. Is the format of the file correct?" + ) + def get_bq1_values(self): return self.data["Bq:1"].tolist() From f04c82e468cb820bc5c454873be297db1d2dfb9c Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 15:59:59 -0500 Subject: [PATCH 07/11] added tests --- test/tritium/test_libra_run_samples.py | 83 ++++++++++++++++++++++++++ test/tritium/test_libra_samples.py | 59 ++++++++++++++++++ test/tritium/test_lsc_samples.py | 62 +++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 test/tritium/test_libra_run_samples.py create mode 100644 test/tritium/test_libra_samples.py create mode 100644 test/tritium/test_lsc_samples.py diff --git a/test/tritium/test_libra_run_samples.py b/test/tritium/test_libra_run_samples.py new file mode 100644 index 0000000..135c04c --- /dev/null +++ b/test/tritium/test_libra_run_samples.py @@ -0,0 +1,83 @@ +import pytest +import pint +from datetime import datetime +from libra_toolbox.tritium.lsc_measurements import LIBRARun, LIBRASample, LSCSample +from libra_toolbox.tritium.model import ureg + + +def test_get_cumulative_activity(): + # Create sample activities + activity1 = 10 * ureg.Bq + activity2 = 20 * ureg.Bq + activity3 = 30 * ureg.Bq + activity4 = 40 * ureg.Bq + + # Create LSCSample instances + sample1 = LSCSample(activity1, "Sample1") + sample2 = LSCSample(activity2, "Sample2") + sample3 = LSCSample(activity3, "Sample3") + sample4 = LSCSample(activity4, "Sample4") + + # Mark background as subtracted + sample1.background_substracted = True + sample2.background_substracted = True + sample3.background_substracted = True + sample4.background_substracted = True + + # Create LIBRASample instances + libra_sample1 = LIBRASample([sample1, sample2], "01/01/2023 12:00 PM") + libra_sample2 = LIBRASample([sample3, sample4], "01/02/2023 12:00 PM") + + # Create LIBRARun instance + libra_run = LIBRARun([libra_sample1, libra_sample2], "01/01/2023 12:00 PM") + + # Test cumulative activity + cumulative_activity = libra_run.get_cumulative_activity() + assert cumulative_activity.magnitude.tolist() == [30, 100] + assert cumulative_activity.units == ureg.Bq + + +def test_get_cumulative_activity_without_background_subtracted(): + # Create sample activities + activity1 = 10 * ureg.Bq + activity2 = 20 * ureg.Bq + + # Create LSCSample instances + sample1 = LSCSample(activity1, "Sample1") + sample2 = LSCSample(activity2, "Sample2") + + # Create LIBRASample instance + libra_sample = LIBRASample([sample1, sample2], "01/01/2023 12:00 PM") + + # Create LIBRARun instance + libra_run = LIBRARun([libra_sample], "01/01/2023 12:00 PM") + + # Test cumulative activity without background subtracted + with pytest.raises( + ValueError, + match="Background must be substracted before calculating cumulative activity", + ): + libra_run.get_cumulative_activity() + + +def test_relative_times(): + # Create LSCSample instances + sample1 = LSCSample(10 * ureg.Bq, "Sample1") + sample2 = LSCSample(20 * ureg.Bq, "Sample2") + + # Create LIBRASample instances + libra_sample1 = LIBRASample([sample1], "01/02/2023 12:00 PM") + libra_sample2 = LIBRASample([sample2], "01/03/2023 12:00 PM") + + # Create LIBRARun instance + start_time = "01/01/2023 12:00 PM" + libra_run = LIBRARun([libra_sample1, libra_sample2], start_time) + + # Test relative times + relative_times = libra_run.relative_times + assert relative_times == [ + datetime.strptime("01/02/2023 12:00 PM", "%m/%d/%Y %I:%M %p") + - datetime.strptime(start_time, "%m/%d/%Y %I:%M %p"), + datetime.strptime("01/03/2023 12:00 PM", "%m/%d/%Y %I:%M %p") + - datetime.strptime(start_time, "%m/%d/%Y %I:%M %p"), + ] diff --git a/test/tritium/test_libra_samples.py b/test/tritium/test_libra_samples.py new file mode 100644 index 0000000..432542c --- /dev/null +++ b/test/tritium/test_libra_samples.py @@ -0,0 +1,59 @@ +import pytest +from datetime import datetime, timedelta +from pint import UnitRegistry +from libra_toolbox.tritium.lsc_measurements import LIBRASample, LSCSample + +ureg = UnitRegistry() + + +def test_get_relative_time(): + sample_time = "01/01/2023 12:00 PM" + start_time = "01/01/2023 10:00 AM" + sample = LIBRASample([], sample_time) + expected_relative_time = timedelta(hours=2) + assert sample.get_relative_time(start_time) == expected_relative_time + + +def test_substract_background(): + activity1 = 10 * ureg.Bq + activity2 = 5 * ureg.Bq + sample1 = LSCSample(activity1, "Sample1") + sample2 = LSCSample(activity2, "Sample2") + background_sample = LSCSample(2 * ureg.Bq, "Background") + sample = LIBRASample([sample1, sample2], "01/01/2023 12:00 PM") + sample.substract_background(background_sample) + assert sample1.activity == 8 * ureg.Bq + assert sample2.activity == 3 * ureg.Bq + assert sample1.background_substracted + assert sample2.background_substracted + + +def test_get_soluble_activity(): + activity1 = 10 * ureg.Bq + activity2 = 5 * ureg.Bq + sample1 = LSCSample(activity1, "Sample1") + sample2 = LSCSample(activity2, "Sample2") + sample = LIBRASample([sample1, sample2], "01/01/2023 12:00 PM") + assert sample.get_soluble_activity() == 15 * ureg.Bq + + +def test_get_insoluble_activity(): + activity1 = 10 * ureg.Bq + activity2 = 5 * ureg.Bq + activity3 = 3 * ureg.Bq + sample1 = LSCSample(activity1, "Sample1") + sample2 = LSCSample(activity2, "Sample2") + sample3 = LSCSample(activity3, "Sample3") + sample = LIBRASample([sample1, sample2, sample3], "01/01/2023 12:00 PM") + assert sample.get_insoluble_activity() == 3 * ureg.Bq + + +def test_get_total_activity(): + activity1 = 10 * ureg.Bq + activity2 = 5 * ureg.Bq + activity3 = 3 * ureg.Bq + sample1 = LSCSample(activity1, "Sample1") + sample2 = LSCSample(activity2, "Sample2") + sample3 = LSCSample(activity3, "Sample3") + sample = LIBRASample([sample1, sample2, sample3], "01/01/2023 12:00 PM") + assert sample.get_total_activity() == 18 * ureg.Bq diff --git a/test/tritium/test_lsc_samples.py b/test/tritium/test_lsc_samples.py new file mode 100644 index 0000000..1fe6577 --- /dev/null +++ b/test/tritium/test_lsc_samples.py @@ -0,0 +1,62 @@ +from libra_toolbox.tritium.lsc_measurements import ( + LSCSample, + LIBRASample, + LIBRARun, + LSCFileReader, +) +from libra_toolbox.tritium.model import ureg + +from pathlib import Path +import pytest + + +def test_lscsample_init(): + activity = 1.0 * ureg.Bq + name = "Sample1" + sample = LSCSample(activity, name) + assert sample.activity == activity + assert sample.name == name + assert not sample.background_substracted + + +def test_lscsample_str(): + sample = LSCSample(1.0 * ureg.Bq, "Sample1") + assert str(sample) == "Sample Sample1" + + +def test_lscsample_substract_background(): + sample = LSCSample(1.0 * ureg.Bq, "Sample1") + background_sample = LSCSample(0.5 * ureg.Bq, "Background") + sample.substract_background(background_sample) + assert sample.activity == 0.5 * ureg.Bq + assert sample.background_substracted + + with pytest.raises(ValueError, match="Background already substracted"): + sample.substract_background(background_sample) + + +def test_lscsample_from_file(): + file_reader = LSCFileReader( + Path(__file__).parent / "TEST_CSV.csv", + vial_labels=[ + "1L-OV-1-0-1", + "1L-OV-1-0-2", + "1L-OV-1-0-3", + "1L-OV-1-0-4", + None, + "1L-IV-1-0-1", + "1L-IV-1-0-2", + "1L-IV-1-0-3", + "1L-IV-1-0-4", + None, + "Sample1", + "1L-IV-1-1-2", + "1L-IV-1-1-3", + "1L-IV-1-1-4", + ], + ) + + file_reader.read_file() + sample = LSCSample.from_file(file_reader, "Sample1") + assert sample.activity == 0.334 * ureg.Bq + assert sample.name == "Sample1" From df9c90942233c66e3fe26e5cc4ef87208bf8a990 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 16:02:20 -0500 Subject: [PATCH 08/11] error message if vial name not found --- libra_toolbox/tritium/lsc_measurements.py | 2 ++ test/tritium/test_lsc_samples.py | 28 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py index ec2b8e3..3511d93 100644 --- a/libra_toolbox/tritium/lsc_measurements.py +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -76,6 +76,8 @@ def substract_background(self, background_sample: "LSCSample"): @staticmethod def from_file(file_reader: LSCFileReader, vial_name): values = file_reader.get_bq1_values_with_labels() + if vial_name not in values: + raise ValueError(f"Vial {vial_name} not found in the file reader.") activity = values[vial_name] * ureg.Bq return LSCSample(activity, vial_name) diff --git a/test/tritium/test_lsc_samples.py b/test/tritium/test_lsc_samples.py index 1fe6577..c3a2760 100644 --- a/test/tritium/test_lsc_samples.py +++ b/test/tritium/test_lsc_samples.py @@ -60,3 +60,31 @@ def test_lscsample_from_file(): sample = LSCSample.from_file(file_reader, "Sample1") assert sample.activity == 0.334 * ureg.Bq assert sample.name == "Sample1" + + +def test_lscsample_from_file_when_not_found(): + file_reader = LSCFileReader( + Path(__file__).parent / "TEST_CSV.csv", + vial_labels=[ + "1L-OV-1-0-1", + "1L-OV-1-0-2", + "1L-OV-1-0-3", + "1L-OV-1-0-4", + None, + "1L-IV-1-0-1", + "1L-IV-1-0-2", + "1L-IV-1-0-3", + "1L-IV-1-0-4", + None, + "Sample1", + "1L-IV-1-1-2", + "1L-IV-1-1-3", + "1L-IV-1-1-4", + ], + ) + + file_reader.read_file() + with pytest.raises( + ValueError, match="Vial coucoucou not found in the file reader." + ): + LSCSample.from_file(file_reader, "coucoucou") From 31fc722b0f4b4408d114cf4cf536348ab2cc75be Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 16:03:55 -0500 Subject: [PATCH 09/11] moved ureg to tritium --- libra_toolbox/tritium/__init__.py | 6 ++++++ libra_toolbox/tritium/lsc_measurements.py | 2 +- libra_toolbox/tritium/model.py | 4 +--- libra_toolbox/tritium/plotting.py | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libra_toolbox/tritium/__init__.py b/libra_toolbox/tritium/__init__.py index 9186ee3..f93ceb2 100644 --- a/libra_toolbox/tritium/__init__.py +++ b/libra_toolbox/tritium/__init__.py @@ -1 +1,7 @@ +import pint + +ureg = pint.UnitRegistry() +ureg.setup_matplotlib() +ureg.define("neutron = 1 * particle = n") + from . import model diff --git a/libra_toolbox/tritium/lsc_measurements.py b/libra_toolbox/tritium/lsc_measurements.py index 3511d93..d699c6c 100644 --- a/libra_toolbox/tritium/lsc_measurements.py +++ b/libra_toolbox/tritium/lsc_measurements.py @@ -1,7 +1,7 @@ import pandas as pd from typing import List import pint -from libra_toolbox.tritium.model import ureg +from libra_toolbox.tritium import ureg from datetime import datetime, timedelta import warnings diff --git a/libra_toolbox/tritium/model.py b/libra_toolbox/tritium/model.py index 1078086..e5f6bc5 100644 --- a/libra_toolbox/tritium/model.py +++ b/libra_toolbox/tritium/model.py @@ -3,9 +3,7 @@ from scipy.integrate import cumulative_trapezoid from scipy.integrate import solve_ivp -ureg = pint.UnitRegistry() -ureg.setup_matplotlib() -ureg.define("neutron = 1 * particle = n") +from libra_toolbox.tritium import ureg SPECIFIC_ACT = 3.57e14 * ureg.Bq * ureg.g**-1 MOLAR_MASS = 6.032 / 2 * ureg.g * ureg.mol**-1 diff --git a/libra_toolbox/tritium/plotting.py b/libra_toolbox/tritium/plotting.py index 1bfc41f..306e30f 100644 --- a/libra_toolbox/tritium/plotting.py +++ b/libra_toolbox/tritium/plotting.py @@ -1,7 +1,8 @@ import matplotlib.pyplot as plt import numpy as np -from libra_toolbox.tritium.model import Model, ureg, quantity_to_activity +from libra_toolbox.tritium import ureg +from libra_toolbox.tritium.model import Model, quantity_to_activity COLLECTION_VOLUME = 10 * ureg.ml From b58455c6ef2dd530dff39e21be364f24e7738828 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 16:07:39 -0500 Subject: [PATCH 10/11] fixed example --- docs/examples/tritium_model.ipynb | 77 +++++++++++-------------------- 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/docs/examples/tritium_model.ipynb b/docs/examples/tritium_model.ipynb index aa00fd0..0f4b0f4 100644 --- a/docs/examples/tritium_model.ipynb +++ b/docs/examples/tritium_model.ipynb @@ -47,7 +47,7 @@ "metadata": {}, "outputs": [], "source": [ - "from libra_toolbox.tritium import model" + "from libra_toolbox.tritium import model, ureg" ] }, { @@ -65,8 +65,7 @@ "source": [ "import numpy as np\n", "\n", - "ureg = model.ureg\n", - "\n", + "# geometry\n", "baby_diameter = 1.77 * ureg.inches - 2 * 0.06 * ureg.inches # from CAD drawings\n", "baby_volume = 0.100 * ureg.L\n", "\n", @@ -75,54 +74,30 @@ "\n", "baby_height = baby_volume / baby_cross_section\n", "\n", - "my_model = model.Model(\n", - " radius=baby_radius,\n", - " height=baby_height,\n", - " TBR=5.4e-4 * ureg.particle * ureg.neutron**-1,\n", - ")\n", + "# neutron rate\n", + "P383_neutron_rate = 4.95e8 / 2 * ureg.neutron * ureg.s**-1\n", + "A325_neutron_rate = 2.13e8 / 2 * ureg.neutron * ureg.s**-1\n", + "\n", + "neutron_rate = P383_neutron_rate + A325_neutron_rate\n", + "\n", + "# irradiation schedule\n", "\n", - "my_model.k_top = 1.6905e-6 * ureg.m * ureg.s**-1\n", - "my_model.k_wall = 5.0715e-8 * ureg.m * ureg.s**-1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is possible to add a series of irradiations as a list of tuples:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ "exposure_time = 12 * ureg.hour\n", "\n", - "my_model.irradiations = [\n", + "irradiations = [\n", " [0 * ureg.hour, 0 + exposure_time],\n", " [24 * ureg.hour, 24 * ureg.hour + exposure_time],\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We also provide the neutron rate:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "P383_neutron_rate = 4.95e8 / 2 * ureg.neutron * ureg.s**-1\n", - "A325_neutron_rate = 2.13e8 / 2 * ureg.neutron * ureg.s**-1\n", + "]\n", "\n", - "my_model.neutron_rate = P383_neutron_rate + A325_neutron_rate" + "my_model = model.Model(\n", + " radius=baby_radius,\n", + " height=baby_height,\n", + " TBR=5.4e-4 * ureg.particle * ureg.neutron**-1,\n", + " neutron_rate=neutron_rate,\n", + " k_top=1.6905e-6 * ureg.m * ureg.s**-1,\n", + " k_wall=5.0715e-8 * ureg.m * ureg.s**-1,\n", + " irradiations=irradiations,\n", + ")" ] }, { @@ -134,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -168,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -219,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -257,7 +232,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -297,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -328,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, "outputs": [ { From 3b15684a3bdaea80c864d9c5f61f8f8271cb5f71 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Fri, 8 Nov 2024 16:10:12 -0500 Subject: [PATCH 11/11] fixed other example --- docs/examples/fit_tritium_release.ipynb | 47 +++++++++++++------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/docs/examples/fit_tritium_release.ipynb b/docs/examples/fit_tritium_release.ipynb index f7237ab..a146d36 100644 --- a/docs/examples/fit_tritium_release.ipynb +++ b/docs/examples/fit_tritium_release.ipynb @@ -24,7 +24,7 @@ "metadata": {}, "outputs": [], "source": [ - "from libra_toolbox.tritium.model import ureg\n", + "from libra_toolbox.tritium import ureg\n", "from libra_toolbox.tritium.helpers import substract_background_from_measurements\n", "\n", "background_activity = 0.334 * ureg.Bq\n", @@ -207,35 +207,34 @@ "from libra_toolbox.tritium.model import Model\n", "import numpy as np\n", "\n", + "P383_neutron_rate = 4.95e8 / 2 * ureg.neutron * ureg.s**-1\n", + "A325_neutron_rate = 2.13e8 / 2 * ureg.neutron * ureg.s**-1\n", + "\n", + "baby_diameter = 1.77 * ureg.inches - 2 * 0.06 * ureg.inches # from CAD drawings\n", + "baby_radius = 0.5 * baby_diameter\n", + "baby_volume = 100 * ureg.mL\n", + "baby_cross_section = np.pi * baby_radius**2\n", + "baby_height = baby_volume / baby_cross_section\n", + "\n", + "exposure_time = 12 * ureg.hour\n", + "\n", + "irradiations = [\n", + " [0 * ureg.hour, 0 + exposure_time],\n", + " [24 * ureg.hour, 24 * ureg.hour + exposure_time],\n", + "]\n", "\n", "def make_model(k_top, k_wall):\n", - " baby_diameter = 1.77 * ureg.inches - 2 * 0.06 * ureg.inches # from CAD drawings\n", - " baby_radius = 0.5 * baby_diameter\n", - " baby_volume = 100 * ureg.mL\n", - " baby_cross_section = np.pi * baby_radius**2\n", - " baby_height = baby_volume / baby_cross_section\n", "\n", " baby_model = Model(\n", " radius=baby_radius,\n", " height=baby_height,\n", " TBR=5.4e-4 * ureg.particle * ureg.neutron**-1,\n", + " k_top=k_top,\n", + " k_wall=k_wall,\n", + " irradiations=irradiations,\n", + " neutron_rate=P383_neutron_rate + A325_neutron_rate,\n", " )\n", "\n", - " baby_model.k_top = k_top\n", - " baby_model.k_wall = k_wall\n", - "\n", - " exposure_time = 12 * ureg.hour\n", - "\n", - " baby_model.irradiations = [\n", - " [0 * ureg.hour, 0 + exposure_time],\n", - " [24 * ureg.hour, 24 * ureg.hour + exposure_time],\n", - " ]\n", - "\n", - " P383_neutron_rate = 4.95e8 / 2 * ureg.neutron * ureg.s**-1\n", - " A325_neutron_rate = 2.13e8 / 2 * ureg.neutron * ureg.s**-1\n", - "\n", - " baby_model.neutron_rate = P383_neutron_rate + A325_neutron_rate\n", - "\n", " return baby_model" ] }, @@ -582,7 +581,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -599,7 +598,9 @@ "source": [ "from libra_toolbox.tritium.plotting import plot_sample_activity_top\n", "\n", - "plot_sample_activity_top(model, replacement_times=sampling_times, color=\"black\", label=\"From model\")\n", + "plot_sample_activity_top(\n", + " model, replacement_times=sampling_times, color=\"black\", label=\"From model\"\n", + ")\n", "plot_bars(measurements_after_background_sub, index=sampling_times)\n", "\n", "plt.legend(reverse=True)\n",