dgm-dayabay-dev 0.2__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/LICENSE +1 -1
  2. {dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info → dgm_dayabay_dev-0.2.2}/PKG-INFO +9 -6
  3. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/README.md +1 -1
  4. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/pyproject.toml +6 -6
  5. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/bundles/refine_detector_data.py +46 -0
  6. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/bundles/refine_lsnl_data.py +24 -10
  7. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/bundles/refine_reactor_data.py +304 -0
  8. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/__init__.py +31 -7
  9. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0.py +5 -3
  10. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0b.py +5 -3
  11. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0c.py +6 -4
  12. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0d.py +6 -4
  13. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0e.py +7 -4
  14. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/models/dayabay_v0f.py +3562 -0
  15. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/models/dayabay_v0f_labels.yaml +1262 -0
  16. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/models/dayabay_v1.py +3566 -0
  17. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/models/dayabay_v1_labels.yaml +1262 -0
  18. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/models/dayabay_v1a.py +3532 -0
  19. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/models/dayabay_v1a_labels.yaml +1283 -0
  20. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/nodes/AxisDistortionMatrixLinearLegacy.py +1 -1
  21. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/tools/__init__.py +1 -0
  22. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/tools/auto_detect_source_type.py +13 -0
  23. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev.egg-info}/PKG-INFO +9 -6
  24. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev.egg-info/SOURCES.txt +12 -22
  25. dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev.egg-info/requires.txt +14 -0
  26. dgm_dayabay_dev-0.2.2/tests/test_data_formats.py +44 -0
  27. dgm_dayabay_dev-0.2.2/tests/test_detector_relative_parameters_correlation.py +102 -0
  28. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/__init__.py +0 -662
  29. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/check_global_normalization.py +0 -198
  30. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/cmp_models_v0.py +0 -266
  31. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/covmatrix_dayabay_v0.py +0 -142
  32. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/covmatrix_mc.py +0 -391
  33. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/covmatrix_plot.py +0 -621
  34. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/cross_fit_config.yaml +0 -12
  35. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/crosscheck_dayabay_nuisance_v0.py +0 -627
  36. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/crosscheck_dayabay_v0.py +0 -596
  37. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_contour.py +0 -374
  38. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_cross_model.py +0 -260
  39. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_model.py +0 -225
  40. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_v0.py +0 -273
  41. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_dayabay_v0_data_detector_time_dependent.py +0 -207
  42. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_dayabay_v0_data_reactor_time_dependent.py +0 -196
  43. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_fit_2d.py +0 -124
  44. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_fit_article.py +0 -324
  45. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_fit_dayabay.py +0 -345
  46. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/run_dayabay_v0.py +0 -419
  47. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/run_profiling_v0.py +0 -365
  48. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/run_profiling_v0e.py +0 -288
  49. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/test_lsnl_curves.py +0 -230
  50. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info/requires.txt +0 -11
  51. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/setup.cfg +0 -0
  52. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/__init__.py +0 -0
  53. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/bundles/__init__.py +0 -0
  54. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/bundles/cross_check_refine_lsnl_data.py +0 -0
  55. /dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/refine_detector_data.py → /dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/bundles/refine_detector_data_v0ae.py +0 -0
  56. /dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/refine_reactor_data.py → /dgm_dayabay_dev-0.2.2/src/dgm_dayabay_dev/bundles/refine_reactor_data_v0ae.py +0 -0
  57. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/bundles/sync_reactor_detector_data.py +0 -0
  58. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_labels.py +0 -0
  59. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0_labels.yaml +0 -0
  60. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0b_labels.yaml +0 -0
  61. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0c_labels.yaml +0 -0
  62. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0d_labels.yaml +0 -0
  63. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/models/dayabay_v0e_labels.yaml +0 -0
  64. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/nodes/Monotonize.py +0 -0
  65. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev/nodes/__init__.py +0 -0
  66. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev.egg-info/dependency_links.txt +0 -0
  67. {dgm_dayabay_dev-0.2 → dgm_dayabay_dev-0.2.2}/src/dgm_dayabay_dev.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Gonchar Maxim, Tsegelnik Nikita
3
+ Copyright (c) 2025 Gonchar Maxim, Vitalii Zavadskyi
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dgm-dayabay-dev
3
- Version: 0.2
4
- Summary: Implementation of the Daya Bay modelfor dag-modelling framework. Development version.
3
+ Version: 0.2.2
4
+ Summary: Implementation of the Daya Bay model for dag-modelling framework. Development version.
5
5
  Author-email: DAGModelling Team <dagflow@jinr.ru>
6
6
  Maintainer-email: DAGModelling Team <dagflow@jinr.ru>
7
7
  License-Expression: MIT
@@ -17,9 +17,9 @@ Classifier: Programming Language :: Python :: 3.13
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: dag-modelling
21
- Requires-Dist: dgm-fit
22
- Requires-Dist: dgm-reactor-neutrino
20
+ Requires-Dist: dag-modelling>=0.14
21
+ Requires-Dist: dgm-fit>=0.2
22
+ Requires-Dist: dgm-reactor-neutrino>=0.2.1
23
23
  Requires-Dist: more-itertools
24
24
  Provides-Extra: test
25
25
  Requires-Dist: coverage; extra == "test"
@@ -27,6 +27,9 @@ Requires-Dist: nbconvert; extra == "test"
27
27
  Requires-Dist: parameterized; extra == "test"
28
28
  Requires-Dist: pytest; extra == "test"
29
29
  Requires-Dist: pytest-cov; extra == "test"
30
+ Requires-Dist: ipython; extra == "test"
31
+ Requires-Dist: ipykernel; extra == "test"
32
+ Requires-Dist: ipywidgets; extra == "test"
30
33
  Dynamic: license-file
31
34
 
32
35
  # dgm-dayabay-dev
@@ -39,7 +42,7 @@ Dynamic: license-file
39
42
  [![pages](https://img.shields.io/badge/pages-link-white.svg)](http://dagflow-team.pages.jinr.ru/dgm-dayabay-dev)
40
43
  -->
41
44
 
42
- Implementation of the Daya Bay modelfor `dag-modelling` framework. Development version.
45
+ Implementation of the Daya Bay model for `dag-modelling` framework. Development version.
43
46
 
44
47
  ## Repositories
45
48
 
@@ -8,7 +8,7 @@
8
8
  [![pages](https://img.shields.io/badge/pages-link-white.svg)](http://dagflow-team.pages.jinr.ru/dgm-dayabay-dev)
9
9
  -->
10
10
 
11
- Implementation of the Daya Bay modelfor `dag-modelling` framework. Development version.
11
+ Implementation of the Daya Bay model for `dag-modelling` framework. Development version.
12
12
 
13
13
  ## Repositories
14
14
 
@@ -5,8 +5,8 @@ requires = [ "packaging", "setuptools", "wheel" ]
5
5
 
6
6
  [project]
7
7
  name = "dgm-dayabay-dev"
8
- version = "0.2"
9
- description = "Implementation of the Daya Bay modelfor dag-modelling framework. Development version."
8
+ version = "0.2.2"
9
+ description = "Implementation of the Daya Bay model for dag-modelling framework. Development version."
10
10
  readme = "README.md"
11
11
  license = "MIT"
12
12
  maintainers = [ { name = "DAGModelling Team", email = "dagflow@jinr.ru" } ]
@@ -19,13 +19,13 @@ classifiers = [
19
19
  "Programming Language :: Python :: 3.13",
20
20
  ]
21
21
  dependencies = [
22
- "dag-modelling",
23
- "dgm-fit",
24
- "dgm-reactor-neutrino",
22
+ "dag-modelling>=0.14",
23
+ "dgm-fit>=0.2",
24
+ "dgm-reactor-neutrino>=0.2.1",
25
25
  "more-itertools",
26
26
  ]
27
27
 
28
- optional-dependencies.test = [ "coverage", "nbconvert", "parameterized", "pytest", "pytest-cov" ]
28
+ optional-dependencies.test = [ "coverage", "nbconvert", "parameterized", "pytest", "pytest-cov", "ipython", "ipykernel", "ipywidgets" ]
29
29
 
30
30
  urls."Bug Tracker" = "https://github.com/dagflow-team/dgm-dayabay-dev/issues"
31
31
  urls."DAGModelling Team" = "https://github.com/dagflow-team"
@@ -0,0 +1,46 @@
1
+ from collections.abc import Sequence
2
+
3
+ from nested_mapping import NestedMapping
4
+
5
+
6
+ def refine_detector_data(
7
+ source: NestedMapping,
8
+ target: NestedMapping,
9
+ *,
10
+ detectors: Sequence[str],
11
+ periods: Sequence[str] = ("6AD", "8AD", "7AD"),
12
+ clean_source: bool = True,
13
+ columns=("livetime", "eff", "efflivetime"),
14
+ skip: Sequence[set[str]] | None = None,
15
+ ) -> None:
16
+ """Read arrays with detector data for the whole data taking period, write detector
17
+ data for each period in separate array.
18
+ """
19
+ target["days"] = (days_storage := {})
20
+ for det in detectors:
21
+ day = source["day", det]
22
+ step = day[1:] - day[:-1]
23
+ assert (step == 1).all(), "Expect detector data for each day"
24
+
25
+ ndet = source["n_det", det]
26
+ for periodname in periods:
27
+ period_ndet = int(periodname[0])
28
+ mask_period = ndet == period_ndet
29
+
30
+ for field in columns:
31
+ data = source[field, det]
32
+
33
+ key = (field, periodname, det)
34
+ if skip is not None and any(skipkey.issubset(key) for skipkey in skip):
35
+ continue
36
+
37
+ target[key] = data[mask_period]
38
+
39
+ days = source["day", det][mask_period]
40
+ days_stored = days_storage.setdefault(periodname, days)
41
+ if days is not days_stored:
42
+ assert all(days == days_stored)
43
+
44
+ if clean_source:
45
+ for key in tuple(source.walkkeys()):
46
+ source.delete_with_parents(key)
@@ -1,13 +1,12 @@
1
+ from typing import Literal
2
+
3
+ from nested_mapping.nested_mapping import NestedMapping
1
4
  from numpy import arange, concatenate, linspace
2
5
  from numpy.typing import NDArray
3
6
  from scipy.interpolate import interp1d
4
7
 
5
- from nested_mapping.nested_mapping import NestedMapping
6
8
 
7
-
8
- def refine_lsnl_data(
9
- storage: NestedMapping, *, xname: str, nominalname: str, **kwargs
10
- ) -> None:
9
+ def refine_lsnl_data(storage: NestedMapping, *, xname: str, nominalname: str, **kwargs) -> None:
11
10
  xcoarse = storage[xname]
12
11
 
13
12
  refiner = RefineGraph(xcoarse, **kwargs)
@@ -32,6 +31,7 @@ class RefineGraph:
32
31
  "newmin",
33
32
  "newmax",
34
33
  "savgol_filter_smoothen",
34
+ "extrapolation_mode",
35
35
  )
36
36
  xcoarse: NDArray
37
37
  xfine_bound: NDArray
@@ -41,6 +41,7 @@ class RefineGraph:
41
41
  newmin: float
42
42
  newmax: float
43
43
  savgol_filter_smoothen: tuple[int, int] | None
44
+ extrapolation_mode: Literal["absolute", "relative"]
44
45
 
45
46
  def __init__(
46
47
  self,
@@ -50,12 +51,14 @@ class RefineGraph:
50
51
  newmin: float,
51
52
  newmax: float,
52
53
  savgol_filter_smoothen: tuple[int, int] | None = None,
54
+ extrapolation_mode: Literal["absolute", "relative"] = "absolute",
53
55
  ):
54
56
  self.xcoarse = xcoarse
55
57
  self.refine_times = refine_times
56
58
  self.newmin = newmin
57
59
  self.newmax = newmax
58
60
  self.savgol_filter_smoothen = savgol_filter_smoothen
61
+ self.extrapolation_mode = extrapolation_mode
59
62
 
60
63
  self._process_x()
61
64
 
@@ -83,9 +86,9 @@ class RefineGraph:
83
86
 
84
87
  if self.newmax is not None:
85
88
  stepright = self.xfine_bound[-1] - self.xfine_bound[-2]
86
- xstack[-1] = arange(
87
- self.xfine_bound[-1], self.newmax + stepright * 1.0e-6, stepright
88
- )[1:]
89
+ xstack[-1] = arange(self.xfine_bound[-1], self.newmax + stepright * 1.0e-6, stepright)[
90
+ 1:
91
+ ]
89
92
 
90
93
  self.xfine_extended = concatenate(xstack)
91
94
  self.xfine_extended_stack = tuple(xstack)
@@ -100,9 +103,20 @@ class RefineGraph:
100
103
  nominal: NDArray,
101
104
  ) -> NDArray:
102
105
  skip_diff = y is nominal
106
+
103
107
  yabs = self._method_reltoabs(y)
104
- yfine = self._method_interpolate(yabs)
105
- yunbound = self._method_extrapolate(yfine)
108
+ yfine_abs = self._method_interpolate(yabs)
109
+ match self.extrapolation_mode:
110
+ case "absolute":
111
+ yunbound = self._method_extrapolate(yfine_abs)
112
+
113
+ case "relative":
114
+ yfine_rel = yfine_abs / self.xfine_bound
115
+ yunbound_rel = self._method_extrapolate(yfine_rel)
116
+ yunbound = yunbound_rel * self.xfine_extended
117
+
118
+ case _:
119
+ raise RuntimeError(f"Invalid extrapolation mode {self.extrapolation_mode}")
106
120
 
107
121
  if skip_diff:
108
122
  return yunbound
@@ -0,0 +1,304 @@
1
+ from collections.abc import Sequence
2
+
3
+ from numba import njit
4
+ from numpy import empty, isnan
5
+ from numpy.typing import NDArray
6
+
7
+ from nested_mapping import NestedMapping
8
+
9
+
10
+ @njit
11
+ def weekly_to_daily(array: NDArray) -> NDArray:
12
+ ret = empty(array.shape[0] * 7)
13
+
14
+ for i in range(7):
15
+ ret[i::7] = array
16
+
17
+ return ret
18
+
19
+
20
+ @njit
21
+ def inperiod_to_daily(array: NDArray, ndays: int) -> NDArray:
22
+ ret = empty(array.shape[0] * ndays)
23
+
24
+ for i in range(ndays):
25
+ ret[i::ndays] = array
26
+
27
+ return ret
28
+
29
+
30
+ @njit
31
+ def periods_to_days(array: NDArray, ndays: int) -> NDArray:
32
+ ret = empty(array.shape[0] * ndays)
33
+
34
+ for i in range(ndays):
35
+ ret[i::ndays] = array
36
+ ret[i::ndays] += i
37
+
38
+ return ret
39
+
40
+
41
+ @njit
42
+ def weeks_to_days(array: NDArray) -> NDArray:
43
+ ret = empty(array.shape[0] * 7)
44
+
45
+ for i in range(7):
46
+ ret[i::7] = array
47
+ ret[i::7] += i
48
+
49
+ return ret
50
+
51
+
52
+ def refine_reactor_data(
53
+ source: NestedMapping,
54
+ target: NestedMapping,
55
+ *,
56
+ reactors: Sequence[str],
57
+ isotopes: Sequence[str],
58
+ periods: Sequence[int] = (6, 8, 7),
59
+ clean_source: bool = True,
60
+ ) -> None:
61
+ """Refine reactor reactor data.
62
+
63
+ Does the following items:
64
+ - checks input consistency
65
+ - split arrays based on isotope number and period name
66
+ - provides similar data on a daily basis
67
+ - splits into multiple arrays based on the reactor index
68
+
69
+ Source should contain the following fields:
70
+ - period : int
71
+ period number
72
+ - day : int
73
+ number of the first day of the period, relative to some common day.
74
+ - ndays : int
75
+ length of the period in days. This function can deal only with periods of
76
+ equal length and with no gaps.
77
+ - core : int
78
+ number of the current reactor (1 to 6).
79
+ - ndet : int
80
+ number of active detectors during the period (6, 8 or 7).
81
+ - power : dict[str, NDArray]
82
+ thermal power as a fraction to nominal value (0 to 1) for each reactor
83
+ core.
84
+ - u235 : dict[str, NDArray]
85
+ fission fraction for the ²³⁵U ("U235" should be contained in isotopes) for
86
+ each reactor core.
87
+ - <isotope> : dict[str, NDArray]
88
+ fission fraction for the <isotope> according to isotopes for each reactor
89
+ core.
90
+
91
+ The target dictionary will be populated as follows:
92
+ ```python
93
+ target = {
94
+ "days": array(),
95
+ "power": {
96
+ "period_name": {
97
+ "reactor_name": array(),
98
+ ...
99
+ },
100
+ ...
101
+ },
102
+ "fission_fraction": {
103
+ "isotope_name": {
104
+ "period_name": {
105
+ "reactor_name": array(),
106
+ ...
107
+ },
108
+ ...
109
+ },
110
+ }
111
+ }
112
+ ```
113
+ with all the arrays of same lengths.
114
+
115
+ Parameters
116
+ ----------
117
+ source : NestedMapping
118
+ storage/record/mapping with source data.
119
+ target : NestedMapping
120
+ storage to write target arrays to.
121
+ reactors : Sequence[str]
122
+ reactor names to use when writing data.
123
+ isotopes : Sequence[str]
124
+ names of the isotopes to read and write fission fractions.
125
+ periods : Sequence[int], default=(6, 8, 7)
126
+ periods (number of active detectors) to select.
127
+ clean_source : bool, default=True
128
+ if True, remove used data from source.
129
+ """
130
+ for corename in reactors:
131
+ period = source["period", corename]
132
+ day = source["day", corename]
133
+ ndays = source["n_days", corename]
134
+ ndet = source["n_det", corename]
135
+
136
+ ndays0 = ndays[0]
137
+ if not (ndays[:-1] == ndays0).all():
138
+ raise ValueError(
139
+ "refine_reactor_data expects information with constant periodicity"
140
+ )
141
+
142
+ power = source["power"][corename]
143
+ fission_fractions = {key: source[key.lower(), corename] for key in isotopes}
144
+
145
+ step = period[1:] - period[:-1]
146
+ assert (
147
+ step == 1
148
+ ).all(), "Expect reactor data for with distinct period, no gaps"
149
+
150
+ target["days"] = (days_storage := {})
151
+ for period in periods:
152
+ mask_period = ndet == period
153
+ periodname = f"{period}AD"
154
+
155
+ mask = mask_period
156
+ key = (
157
+ periodname,
158
+ corename,
159
+ )
160
+ target[("power",) + key] = inperiod_to_daily(power[mask], ndays0)
161
+ for isotope in isotopes:
162
+ target[("fission_fraction",) + key + (isotope,)] = inperiod_to_daily(
163
+ fission_fractions[isotope][mask], ndays0
164
+ )
165
+
166
+ days = periods_to_days(day[mask], ndays0)
167
+ days_stored = days_storage.setdefault(periodname, days)
168
+ if days is not days_stored:
169
+ assert all(days == days_stored)
170
+
171
+ for key, array in target.walkjoineditems():
172
+ if isnan(array).any():
173
+ raise ValueError(f"Invalid refined reactor data for {key}")
174
+
175
+ if clean_source:
176
+ for key in tuple(source.walkkeys()):
177
+ source.delete_with_parents(key)
178
+
179
+
180
+ def split_refine_reactor_data(
181
+ source: NestedMapping,
182
+ target: NestedMapping,
183
+ *,
184
+ reactors: Sequence[str],
185
+ isotopes: Sequence[str],
186
+ periods: Sequence[int] = (6, 8, 7),
187
+ reactor_number_start: int = 1,
188
+ clean_source: bool = True,
189
+ ) -> None:
190
+ """Filter/split and refine reactor reactor data.
191
+
192
+ Does the following items:
193
+ - checks input consistency
194
+ - split arrays based on reactor number, isotope number and period name
195
+ - provides similar data on a daily basis
196
+ - splits into multiple arrays based on the reactor index
197
+
198
+ Source should contain the following fields:
199
+ - week : int
200
+ week/period number
201
+ - day : int
202
+ number of the first day of the period, relative to some common day.
203
+ - ndays : int
204
+ length of the period in days. This function can deal only with periods of
205
+ equal length and with no gaps.
206
+ - core : int
207
+ number of the current reactor (1 to 6).
208
+ - ndet : int
209
+ number of active detectors during the period (6, 8 or 7).
210
+ - power : float
211
+ thermal power as a fraction to nominal value (0 to 1).
212
+ - u235 : float
213
+ fission fraction for the ²³⁵U ("U235" should be contained in isotopes).
214
+ - <isotope> : float
215
+ fission fraction for the <isotope> according to isotopes.
216
+
217
+ The target dictionary will be populated as follows:
218
+ ```python
219
+ target = {
220
+ "days": array(),
221
+ "power": {
222
+ "period_name": {
223
+ "reactor_name": array(),
224
+ ...
225
+ },
226
+ ...
227
+ },
228
+ "fission_fraction": {
229
+ "isotope_name": {
230
+ "period_name": {
231
+ "reactor_name": array(),
232
+ ...
233
+ },
234
+ ...
235
+ },
236
+ }
237
+ }
238
+ ```
239
+ with all the arrays of same lengths.
240
+
241
+ Parameters
242
+ ----------
243
+ source : NestedMapping
244
+ storage/record/mapping with source data.
245
+ target : NestedMapping
246
+ storage to write target arrays to.
247
+ reactors : Sequence[str]
248
+ reactor names to use when writing data.
249
+ isotopes : Sequence[str]
250
+ names of the isotopes to read and write fission fractions.
251
+ periods : Sequence[int], default=(6, 8, 7)
252
+ periods (number of active detectors) to select.
253
+ reactor_number_start : int, default=1
254
+ number of the first reactor in the input data.
255
+ clean_source : bool, default=True
256
+ if True, remove used data from source.
257
+ """
258
+ week = source["week"]
259
+ day = source["day"]
260
+ ndays = source["ndays"]
261
+ core = source["core"]
262
+ ndet = source["n_det"]
263
+
264
+ if not (ndays == 7).all():
265
+ raise ValueError("refine_reactor_data expects weekly information")
266
+
267
+ power = source["power"]
268
+ fission_fractions = {key: source[key.lower()] for key in isotopes}
269
+
270
+ ncores = 6
271
+ for i in range(ncores):
272
+ rweek = week[i::ncores]
273
+ step = rweek[1:] - rweek[:-1]
274
+ assert (step == 1).all(), "Expect reactor data for each week, no gaps"
275
+
276
+ target["days"] = (days_storage := {})
277
+ for period in periods:
278
+ mask_period = ndet == period
279
+ periodname = f"{period}AD"
280
+
281
+ for icore, corename in enumerate(reactors, reactor_number_start):
282
+ mask = mask_period * (core == icore)
283
+ key = (
284
+ periodname,
285
+ corename,
286
+ )
287
+ target[("power",) + key] = weekly_to_daily(power[mask])
288
+ for isotope in isotopes:
289
+ target[("fission_fraction",) + key + (isotope,)] = weekly_to_daily(
290
+ fission_fractions[isotope][mask]
291
+ )
292
+
293
+ days = weeks_to_days(day[mask])
294
+ days_stored = days_storage.setdefault(periodname, days)
295
+ if days is not days_stored:
296
+ assert all(days == days_stored)
297
+
298
+ for key, array in target.walkjoineditems():
299
+ if isnan(array).any():
300
+ raise ValueError(f"Invalid refined reactor data for {key}")
301
+
302
+ if clean_source:
303
+ for key in tuple(source.walkkeys()):
304
+ source.delete_with_parents(key)
@@ -2,14 +2,15 @@ from typing import Mapping
2
2
 
3
3
  from dag_modelling.tools.logger import logger
4
4
 
5
+ from .dayabay_labels import LATEX_SYMBOLS
5
6
  from .dayabay_v0 import model_dayabay_v0
6
7
  from .dayabay_v0b import model_dayabay_v0b
7
8
  from .dayabay_v0c import model_dayabay_v0c
8
9
  from .dayabay_v0d import model_dayabay_v0d
9
10
  from .dayabay_v0e import model_dayabay_v0e
10
-
11
- from .dayabay_labels import LATEX_SYMBOLS
12
-
11
+ from .dayabay_v0f import model_dayabay_v0f
12
+ from .dayabay_v1 import model_dayabay_v1
13
+ from .dayabay_v1a import model_dayabay_v1a
13
14
 
14
15
  AD_TO_EH = {
15
16
  "AD11": "EH1",
@@ -28,8 +29,11 @@ _dayabay_models = {
28
29
  "v0c": model_dayabay_v0c,
29
30
  "v0d": model_dayabay_v0d,
30
31
  "v0e": model_dayabay_v0e,
32
+ "v0f": model_dayabay_v0f,
33
+ "v1": model_dayabay_v1,
34
+ "v1a": model_dayabay_v1a,
31
35
  }
32
- _dayabay_models["latest"] = _dayabay_models["v0e"]
36
+ _dayabay_models["latest"] = _dayabay_models["v1a"]
33
37
 
34
38
  _available_sources = ("tsv", "hdf5", "root", "npz")
35
39
 
@@ -37,9 +41,31 @@ _available_sources = ("tsv", "hdf5", "root", "npz")
37
41
  def available_models() -> tuple[str, ...]:
38
42
  return tuple(_dayabay_models.keys())
39
43
 
44
+
45
+ def available_models_limited(*, first: str, last: str | None = None) -> tuple[str,...]:
46
+ names = tuple(_dayabay_models.keys())
47
+ assert names
48
+ i = 0
49
+ for i, name in enumerate(names):
50
+ if name == first:
51
+ break
52
+
53
+ if last is None:
54
+ return names[i:]
55
+
56
+ ret = []
57
+ for i in range(i, len(names)):
58
+ ret.append(name := names[i])
59
+ if name == last:
60
+ break
61
+
62
+ return tuple(ret)
63
+
64
+
40
65
  def available_sources() -> tuple[str, ...]:
41
66
  return _available_sources
42
67
 
68
+
43
69
  def load_model(version, model_options: Mapping | str = {}, **kwargs):
44
70
  if isinstance(model_options, str):
45
71
  from yaml import Loader, load
@@ -47,9 +73,7 @@ def load_model(version, model_options: Mapping | str = {}, **kwargs):
47
73
  model_options = load(model_options, Loader)
48
74
 
49
75
  if not isinstance(model_options, dict):
50
- raise RuntimeError(
51
- "model_options expects a python dictionary or yaml dictionary"
52
- )
76
+ raise RuntimeError("model_options expects a python dictionary or yaml dictionary")
53
77
 
54
78
  model_options = dict(model_options, **kwargs)
55
79
 
@@ -94,13 +94,14 @@ class model_dayabay_v0:
94
94
  concatenation_mode: Literal["detector", "detector_period"] = "detector_period",
95
95
  merge_integration: bool = False,
96
96
  parameter_values: dict[str, float | str] = {},
97
+ path_data: str | Path = "data/dayabay-v0",
97
98
  ):
98
99
  self._strict = strict
99
100
  self._close = close
100
101
 
101
102
  self.graph = None
102
103
  self.storage = NodeStorage()
103
- self._path_data = Path("data/dayabay-v0")
104
+ self._path_data = Path(path_data)
104
105
  self._source_type = source_type
105
106
  self._override_indices = override_indices
106
107
  self._spectrum_correction_mode = spectrum_correction_mode
@@ -410,6 +411,7 @@ class model_dayabay_v0:
410
411
  NueSurvivalProbability.replicate(
411
412
  name="oscprob",
412
413
  distance_unit="m",
414
+ leading_mass_splitting_3l_name="DeltaMSq32",
413
415
  replicate_outputs=combinations["reactor.detector"],
414
416
  surprobArgConversion = True
415
417
  )
@@ -728,7 +730,7 @@ class model_dayabay_v0:
728
730
  columns = ("day", "ndet", "livetime", "eff", "efflivetime"),
729
731
  skip = self.inactive_detectors
730
732
  )
731
- from ..bundles.refine_detector_data import \
733
+ from ..bundles.refine_detector_data_v0ae import \
732
734
  refine_detector_data
733
735
  refine_detector_data(
734
736
  data("daily_data.detector_all"),
@@ -743,7 +745,7 @@ class model_dayabay_v0:
743
745
  columns = ("week", "day", "ndet", "ndays", "core", "power") + index["isotope_lower"],
744
746
  output_key_order = (("week", "core_data"), ("week",))
745
747
  )
746
- from ..bundles.refine_reactor_data import split_refine_reactor_data
748
+ from ..bundles.refine_reactor_data_v0ae import split_refine_reactor_data
747
749
  split_refine_reactor_data(
748
750
  data("daily_data.reactor_all"),
749
751
  data.create_child("daily_data.reactor"),
@@ -118,6 +118,7 @@ class model_dayabay_v0b:
118
118
  concatenation_mode: Literal["detector", "detector_period"] = "detector_period",
119
119
  merge_integration: bool = False,
120
120
  parameter_values: dict[str, float | str] = {},
121
+ path_data: str | Path = "data/dayabay-v0b",
121
122
  future: Collection[
122
123
  Literal[
123
124
  "all", "pdg", "xsec", "conversion", "hm-spectra",
@@ -135,7 +136,7 @@ class model_dayabay_v0b:
135
136
 
136
137
  self.graph = None
137
138
  self.storage = NodeStorage()
138
- self._path_data = Path("data/dayabay-v0b")
139
+ self._path_data = Path(path_data)
139
140
  self._source_type = source_type
140
141
  self._override_indices = override_indices
141
142
  self._spectrum_correction_mode = spectrum_correction_mode
@@ -476,6 +477,7 @@ class model_dayabay_v0b:
476
477
  NueSurvivalProbability.replicate(
477
478
  name="oscprob",
478
479
  distance_unit="m",
480
+ leading_mass_splitting_3l_name="DeltaMSq32",
479
481
  replicate_outputs=combinations["reactor.detector"],
480
482
  surprobArgConversion = True
481
483
  )
@@ -820,7 +822,7 @@ class model_dayabay_v0b:
820
822
  columns = ("day", "ndet", "livetime", "eff", "efflivetime"),
821
823
  skip = self.inactive_detectors
822
824
  )
823
- from ..bundles.refine_detector_data import \
825
+ from ..bundles.refine_detector_data_v0ae import \
824
826
  refine_detector_data
825
827
  refine_detector_data(
826
828
  data("daily_data.detector_all"),
@@ -835,7 +837,7 @@ class model_dayabay_v0b:
835
837
  columns = ("week", "day", "ndet", "ndays", "core", "power") + index["isotope_lower"],
836
838
  output_key_order = (("week", "core_data"), ("week",))
837
839
  )
838
- from ..bundles.refine_reactor_data import split_refine_reactor_data
840
+ from ..bundles.refine_reactor_data_v0ae import split_refine_reactor_data
839
841
  split_refine_reactor_data(
840
842
  data("daily_data.reactor_all"),
841
843
  data.create_child("daily_data.reactor"),