dgm-dayabay-dev 0.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 (54) hide show
  1. dgm_dayabay_dev-0.2/LICENSE +21 -0
  2. dgm_dayabay_dev-0.2/PKG-INFO +49 -0
  3. dgm_dayabay_dev-0.2/README.md +18 -0
  4. dgm_dayabay_dev-0.2/pyproject.toml +51 -0
  5. dgm_dayabay_dev-0.2/setup.cfg +4 -0
  6. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/__init__.py +0 -0
  7. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/__init__.py +0 -0
  8. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/cross_check_refine_lsnl_data.py +77 -0
  9. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/refine_detector_data.py +46 -0
  10. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/refine_lsnl_data.py +161 -0
  11. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/refine_reactor_data.py +304 -0
  12. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/bundles/sync_reactor_detector_data.py +39 -0
  13. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/__init__.py +64 -0
  14. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_labels.py +102 -0
  15. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0.py +1689 -0
  16. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0_labels.yaml +635 -0
  17. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0b.py +1841 -0
  18. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0b_labels.yaml +644 -0
  19. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0c.py +2130 -0
  20. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0c_labels.yaml +644 -0
  21. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0d.py +2781 -0
  22. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0d_labels.yaml +773 -0
  23. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0e.py +3748 -0
  24. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/models/dayabay_v0e_labels.yaml +1284 -0
  25. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/nodes/AxisDistortionMatrixLinearLegacy.py +191 -0
  26. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/nodes/Monotonize.py +172 -0
  27. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/nodes/__init__.py +0 -0
  28. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/__init__.py +662 -0
  29. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/check_global_normalization.py +198 -0
  30. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/cmp_models_v0.py +266 -0
  31. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/covmatrix_dayabay_v0.py +142 -0
  32. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/covmatrix_mc.py +391 -0
  33. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/covmatrix_plot.py +621 -0
  34. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/cross_fit_config.yaml +12 -0
  35. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/crosscheck_dayabay_nuisance_v0.py +627 -0
  36. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/crosscheck_dayabay_v0.py +596 -0
  37. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_contour.py +374 -0
  38. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_cross_model.py +260 -0
  39. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_model.py +225 -0
  40. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/fit_dayabay_v0.py +273 -0
  41. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_dayabay_v0_data_detector_time_dependent.py +207 -0
  42. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_dayabay_v0_data_reactor_time_dependent.py +196 -0
  43. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_fit_2d.py +124 -0
  44. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_fit_article.py +324 -0
  45. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/plot_fit_dayabay.py +345 -0
  46. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/run_dayabay_v0.py +419 -0
  47. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/run_profiling_v0.py +365 -0
  48. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/run_profiling_v0e.py +288 -0
  49. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev/scripts/test_lsnl_curves.py +230 -0
  50. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info/PKG-INFO +49 -0
  51. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info/SOURCES.txt +52 -0
  52. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info/dependency_links.txt +1 -0
  53. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info/requires.txt +11 -0
  54. dgm_dayabay_dev-0.2/src/dgm_dayabay_dev.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Gonchar Maxim, Tsegelnik Nikita
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: dgm-dayabay-dev
3
+ Version: 0.2
4
+ Summary: Implementation of the Daya Bay modelfor dag-modelling framework. Development version.
5
+ Author-email: DAGModelling Team <dagflow@jinr.ru>
6
+ Maintainer-email: DAGModelling Team <dagflow@jinr.ru>
7
+ License-Expression: MIT
8
+ Project-URL: Bug Tracker, https://github.com/dagflow-team/dgm-dayabay-dev/issues
9
+ Project-URL: DAGModelling Team, https://github.com/dagflow-team
10
+ Project-URL: documentation, https://github.com/dagflow-team/dgm-dayabay-dev/wiki
11
+ Project-URL: homepage, https://github.com/dagflow-team/dgm-dayabay-dev
12
+ Project-URL: repository, https://github.com/dagflow-team/dgm-dayabay-dev
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: dag-modelling
21
+ Requires-Dist: dgm-fit
22
+ Requires-Dist: dgm-reactor-neutrino
23
+ Requires-Dist: more-itertools
24
+ Provides-Extra: test
25
+ Requires-Dist: coverage; extra == "test"
26
+ Requires-Dist: nbconvert; extra == "test"
27
+ Requires-Dist: parameterized; extra == "test"
28
+ Requires-Dist: pytest; extra == "test"
29
+ Requires-Dist: pytest-cov; extra == "test"
30
+ Dynamic: license-file
31
+
32
+ # dgm-dayabay-dev
33
+
34
+ [![python](https://img.shields.io/badge/python-3.11-purple.svg)](https://www.python.org/)
35
+ [![pipeline](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/badges/main/pipeline.svg)](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/commits/main)
36
+ [![coverage report](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/badges/main/coverage.svg)](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/-/commits/main)
37
+
38
+ <!--- Uncomment here after adding docs!
39
+ [![pages](https://img.shields.io/badge/pages-link-white.svg)](http://dagflow-team.pages.jinr.ru/dgm-dayabay-dev)
40
+ -->
41
+
42
+ Implementation of the Daya Bay modelfor `dag-modelling` framework. Development version.
43
+
44
+ ## Repositories
45
+
46
+ - Main repo:
47
+ - Development/CI: https://git.jinr.ru/dagflow-team/dgm-dayabay-dev
48
+ - Contact/pypi/mirror: https://github.com/dagflow-team/dgm-dayabay-dev
49
+ - PYPI: https://pypi.org/project/dgm-dayabay-dev
@@ -0,0 +1,18 @@
1
+ # dgm-dayabay-dev
2
+
3
+ [![python](https://img.shields.io/badge/python-3.11-purple.svg)](https://www.python.org/)
4
+ [![pipeline](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/badges/main/pipeline.svg)](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/commits/main)
5
+ [![coverage report](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/badges/main/coverage.svg)](https://git.jinr.ru/dagflow-team/dgm-dayabay-dev/-/commits/main)
6
+
7
+ <!--- Uncomment here after adding docs!
8
+ [![pages](https://img.shields.io/badge/pages-link-white.svg)](http://dagflow-team.pages.jinr.ru/dgm-dayabay-dev)
9
+ -->
10
+
11
+ Implementation of the Daya Bay modelfor `dag-modelling` framework. Development version.
12
+
13
+ ## Repositories
14
+
15
+ - Main repo:
16
+ - Development/CI: https://git.jinr.ru/dagflow-team/dgm-dayabay-dev
17
+ - Contact/pypi/mirror: https://github.com/dagflow-team/dgm-dayabay-dev
18
+ - PYPI: https://pypi.org/project/dgm-dayabay-dev
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ build-backend = "setuptools.build_meta"
3
+
4
+ requires = [ "packaging", "setuptools", "wheel" ]
5
+
6
+ [project]
7
+ name = "dgm-dayabay-dev"
8
+ version = "0.2"
9
+ description = "Implementation of the Daya Bay modelfor dag-modelling framework. Development version."
10
+ readme = "README.md"
11
+ license = "MIT"
12
+ maintainers = [ { name = "DAGModelling Team", email = "dagflow@jinr.ru" } ]
13
+ authors = [ { name = "DAGModelling Team", email = "dagflow@jinr.ru" } ]
14
+ requires-python = ">=3.11"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ ]
21
+ dependencies = [
22
+ "dag-modelling",
23
+ "dgm-fit",
24
+ "dgm-reactor-neutrino",
25
+ "more-itertools",
26
+ ]
27
+
28
+ optional-dependencies.test = [ "coverage", "nbconvert", "parameterized", "pytest", "pytest-cov" ]
29
+
30
+ urls."Bug Tracker" = "https://github.com/dagflow-team/dgm-dayabay-dev/issues"
31
+ urls."DAGModelling Team" = "https://github.com/dagflow-team"
32
+ urls.documentation = "https://github.com/dagflow-team/dgm-dayabay-dev/wiki"
33
+ urls.homepage = "https://github.com/dagflow-team/dgm-dayabay-dev"
34
+ urls.repository = "https://github.com/dagflow-team/dgm-dayabay-dev"
35
+
36
+ [tool.setuptools.package-data]
37
+ "*" = [ "*.yaml" ]
38
+
39
+ [tool.setuptools.packages.find]
40
+ where = [ "src" ]
41
+ exclude = [
42
+ "tests*",
43
+ ]
44
+
45
+ [tool.black]
46
+ line-length = 100
47
+
48
+ [tool.isort]
49
+ profile = "black"
50
+ line_length = 100
51
+ multi_line_output = 5
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,77 @@
1
+ from numpy import arange
2
+ from numpy.typing import NDArray
3
+ from scipy.interpolate import interp1d
4
+
5
+ from nested_mapping.nested_mapping import NestedMapping
6
+
7
+
8
+ def cross_check_refine_lsnl_data(
9
+ storage: NestedMapping, *, xname: str, nominalname: str, **kwargs
10
+ ) -> None:
11
+ xcoarse = storage[xname]
12
+
13
+ refiner = RefineGraph(xcoarse, **kwargs)
14
+
15
+ for key, ycoarse in storage.walkitems():
16
+ if ycoarse is xcoarse:
17
+ continue
18
+
19
+ nominal = storage[nominalname]
20
+ storage[key] = refiner.process(ycoarse, nominal)
21
+
22
+ storage[xname] = refiner.xfine
23
+
24
+
25
+ class RefineGraph:
26
+ __slots__ = (
27
+ "xcoarse",
28
+ "xfine",
29
+ "newmin",
30
+ "newmax",
31
+ )
32
+ xcoarse: NDArray
33
+ xfine: NDArray
34
+ newmin: float
35
+ newmax: float
36
+
37
+ def __init__(
38
+ self,
39
+ xcoarse: NDArray,
40
+ *,
41
+ newmin: float,
42
+ newmax: float,
43
+ ):
44
+ self.xcoarse = xcoarse
45
+ self.newmin = newmin
46
+ self.newmax = newmax
47
+
48
+ self._process_x()
49
+
50
+ def make_x(self) -> None:
51
+ self.xfine = arange(0.0, 12.0000001, 0.05)
52
+
53
+ def _process_x(self) -> None:
54
+ self.make_x()
55
+
56
+ def process(self, y: NDArray, nominal: NDArray) -> NDArray:
57
+ skip_diff = y is nominal
58
+ yfine = self._method_interpolate(y)
59
+ yabs = self._method_reltoabs(yfine)
60
+
61
+ return yabs if skip_diff else self._method_diff(nominal, yabs)
62
+
63
+ def _method_reltoabs(self, yrel: NDArray) -> NDArray:
64
+ return yrel * self.xfine
65
+
66
+ def _method_interpolate(self, ycoarse) -> NDArray:
67
+ fcn = interp1d(
68
+ self.xcoarse,
69
+ ycoarse,
70
+ kind="linear",
71
+ bounds_error=False,
72
+ fill_value="extrapolate",
73
+ )
74
+ return fcn(self.xfine)
75
+
76
+ def _method_diff(self, nominal: NDArray, y: NDArray) -> NDArray:
77
+ return nominal if nominal is y else y - nominal
@@ -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["ndet", 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)
@@ -0,0 +1,161 @@
1
+ from numpy import arange, concatenate, linspace
2
+ from numpy.typing import NDArray
3
+ from scipy.interpolate import interp1d
4
+
5
+ from nested_mapping.nested_mapping import NestedMapping
6
+
7
+
8
+ def refine_lsnl_data(
9
+ storage: NestedMapping, *, xname: str, nominalname: str, **kwargs
10
+ ) -> None:
11
+ xcoarse = storage[xname]
12
+
13
+ refiner = RefineGraph(xcoarse, **kwargs)
14
+
15
+ for key, ycoarse in storage.walkitems():
16
+ if ycoarse is xcoarse:
17
+ continue
18
+
19
+ nominal = storage[nominalname]
20
+ storage[key] = refiner.process(ycoarse, nominal)
21
+
22
+ storage[xname] = refiner.xfine_extended
23
+
24
+
25
+ class RefineGraph:
26
+ __slots__ = (
27
+ "xcoarse",
28
+ "xfine_bound",
29
+ "xfine_extended",
30
+ "xfine_extended_stack",
31
+ "refine_times",
32
+ "newmin",
33
+ "newmax",
34
+ "savgol_filter_smoothen",
35
+ )
36
+ xcoarse: NDArray
37
+ xfine_bound: NDArray
38
+ xfine_extended: NDArray
39
+ xfine_extended_stack: tuple[NDArray | None, NDArray | None, NDArray | None]
40
+ refine_times: int
41
+ newmin: float
42
+ newmax: float
43
+ savgol_filter_smoothen: tuple[int, int] | None
44
+
45
+ def __init__(
46
+ self,
47
+ xcoarse: NDArray,
48
+ *,
49
+ refine_times: int,
50
+ newmin: float,
51
+ newmax: float,
52
+ savgol_filter_smoothen: tuple[int, int] | None = None,
53
+ ):
54
+ self.xcoarse = xcoarse
55
+ self.refine_times = refine_times
56
+ self.newmin = newmin
57
+ self.newmax = newmax
58
+ self.savgol_filter_smoothen = savgol_filter_smoothen
59
+
60
+ self._process_x()
61
+
62
+ def make_finer_x(self) -> None:
63
+ assert self.refine_times % 1 == 0 and self.refine_times > 0
64
+
65
+ if self.refine_times == 1:
66
+ self.xfine_bound = self.xcoarse.copy()
67
+ return
68
+
69
+ shape_fine = (self.xcoarse.size - 1) * self.refine_times + 1
70
+ self.xfine_bound = linspace(self.xcoarse[0], self.xcoarse[-1], shape_fine)
71
+
72
+ def make_extended_x(self):
73
+ if self.newmin is None and self.newmax is None:
74
+ return
75
+
76
+ xstack = [None, self.xfine_bound, None]
77
+ if self.newmin is not None:
78
+ xstack[0] = arange(
79
+ self.newmin,
80
+ self.xfine_bound[0],
81
+ self.xfine_bound[1] - self.xfine_bound[0],
82
+ )
83
+
84
+ if self.newmax is not None:
85
+ 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
+
90
+ self.xfine_extended = concatenate(xstack)
91
+ self.xfine_extended_stack = tuple(xstack)
92
+
93
+ def _process_x(self):
94
+ self.make_finer_x()
95
+ self.make_extended_x()
96
+
97
+ def process(
98
+ self,
99
+ y: NDArray,
100
+ nominal: NDArray,
101
+ ) -> NDArray:
102
+ skip_diff = y is nominal
103
+ yabs = self._method_reltoabs(y)
104
+ yfine = self._method_interpolate(yabs)
105
+ yunbound = self._method_extrapolate(yfine)
106
+
107
+ if skip_diff:
108
+ return yunbound
109
+
110
+ ydiff = self._method_diff(nominal, yunbound)
111
+ if self.savgol_filter_smoothen is None:
112
+ return ydiff
113
+
114
+ ydiff_smooth = self._method_filter(ydiff)
115
+ return ydiff_smooth
116
+
117
+ def _method_reltoabs(self, yrel: NDArray) -> NDArray:
118
+ return yrel * self.xcoarse
119
+
120
+ def _method_interpolate(self, ycoarse) -> NDArray:
121
+ if self.refine_times == 1:
122
+ return ycoarse.copy()
123
+
124
+ fcn = interp1d(
125
+ self.xcoarse,
126
+ ycoarse,
127
+ kind="cubic",
128
+ bounds_error=False,
129
+ fill_value="extrapolate",
130
+ )
131
+ return fcn(self.xfine_bound)
132
+
133
+ def _method_extrapolate(self, ybound: NDArray) -> NDArray:
134
+ fcn = interp1d(
135
+ self.xfine_bound,
136
+ ybound,
137
+ kind="linear",
138
+ bounds_error=False,
139
+ fill_value="extrapolate",
140
+ )
141
+
142
+ xleft, _, xright = self.xfine_extended_stack
143
+ ystack = [None, ybound, None]
144
+ if xleft is not None:
145
+ ystack[0] = fcn(xleft)
146
+ if xright is not None:
147
+ ystack[-1] = fcn(xright)
148
+
149
+ return concatenate(ystack)
150
+
151
+ def _method_diff(self, nominal: NDArray, y: NDArray) -> NDArray:
152
+ return nominal if nominal is y else y - nominal
153
+
154
+ def _method_filter(self, y: NDArray) -> NDArray:
155
+ if self.savgol_filter_smoothen is None:
156
+ return y.copy()
157
+
158
+ from scipy.signal import savgol_filter
159
+
160
+ npoints_coarse, deg = self.savgol_filter_smoothen
161
+ return savgol_filter(y, npoints_coarse * self.refine_times, deg)