data-manipulation-utilities 0.2.7__py3-none-any.whl → 0.2.8.dev720__py3-none-any.whl

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 (70) hide show
  1. {data_manipulation_utilities-0.2.7.dist-info → data_manipulation_utilities-0.2.8.dev720.dist-info}/METADATA +669 -42
  2. data_manipulation_utilities-0.2.8.dev720.dist-info/RECORD +45 -0
  3. {data_manipulation_utilities-0.2.7.dist-info → data_manipulation_utilities-0.2.8.dev720.dist-info}/WHEEL +1 -2
  4. data_manipulation_utilities-0.2.8.dev720.dist-info/entry_points.txt +8 -0
  5. dmu/generic/hashing.py +34 -8
  6. dmu/generic/utilities.py +164 -11
  7. dmu/logging/log_store.py +34 -2
  8. dmu/logging/messages.py +96 -0
  9. dmu/ml/cv_classifier.py +3 -3
  10. dmu/ml/cv_diagnostics.py +3 -0
  11. dmu/ml/cv_performance.py +58 -0
  12. dmu/ml/cv_predict.py +149 -46
  13. dmu/ml/train_mva.py +482 -100
  14. dmu/ml/utilities.py +29 -10
  15. dmu/pdataframe/utilities.py +28 -3
  16. dmu/plotting/fwhm.py +2 -2
  17. dmu/plotting/matrix.py +1 -1
  18. dmu/plotting/plotter.py +23 -3
  19. dmu/plotting/plotter_1d.py +96 -32
  20. dmu/plotting/plotter_2d.py +5 -0
  21. dmu/rdataframe/utilities.py +54 -3
  22. dmu/rfile/ddfgetter.py +102 -0
  23. dmu/stats/fit_stats.py +129 -0
  24. dmu/stats/fitter.py +55 -22
  25. dmu/stats/gof_calculator.py +7 -0
  26. dmu/stats/model_factory.py +153 -62
  27. dmu/stats/parameters.py +100 -0
  28. dmu/stats/utilities.py +443 -12
  29. dmu/stats/wdata.py +187 -0
  30. dmu/stats/zfit.py +17 -0
  31. dmu/stats/zfit_plotter.py +147 -36
  32. dmu/testing/utilities.py +102 -24
  33. dmu/workflow/__init__.py +0 -0
  34. dmu/workflow/cache.py +266 -0
  35. data_manipulation_utilities-0.2.7.data/scripts/publish +0 -89
  36. data_manipulation_utilities-0.2.7.dist-info/RECORD +0 -69
  37. data_manipulation_utilities-0.2.7.dist-info/entry_points.txt +0 -6
  38. data_manipulation_utilities-0.2.7.dist-info/top_level.txt +0 -3
  39. dmu_data/ml/tests/diagnostics_from_file.yaml +0 -13
  40. dmu_data/ml/tests/diagnostics_from_model.yaml +0 -10
  41. dmu_data/ml/tests/diagnostics_multiple_methods.yaml +0 -10
  42. dmu_data/ml/tests/diagnostics_overlay.yaml +0 -33
  43. dmu_data/ml/tests/train_mva.yaml +0 -58
  44. dmu_data/ml/tests/train_mva_with_diagnostics.yaml +0 -82
  45. dmu_data/plotting/tests/2d.yaml +0 -24
  46. dmu_data/plotting/tests/fig_size.yaml +0 -13
  47. dmu_data/plotting/tests/high_stat.yaml +0 -22
  48. dmu_data/plotting/tests/legend.yaml +0 -12
  49. dmu_data/plotting/tests/name.yaml +0 -14
  50. dmu_data/plotting/tests/no_bounds.yaml +0 -12
  51. dmu_data/plotting/tests/normalized.yaml +0 -9
  52. dmu_data/plotting/tests/plug_fwhm.yaml +0 -24
  53. dmu_data/plotting/tests/plug_stats.yaml +0 -19
  54. dmu_data/plotting/tests/simple.yaml +0 -9
  55. dmu_data/plotting/tests/stats.yaml +0 -9
  56. dmu_data/plotting/tests/styling.yaml +0 -11
  57. dmu_data/plotting/tests/title.yaml +0 -14
  58. dmu_data/plotting/tests/weights.yaml +0 -13
  59. dmu_data/text/transform.toml +0 -4
  60. dmu_data/text/transform.txt +0 -6
  61. dmu_data/text/transform_set.toml +0 -8
  62. dmu_data/text/transform_set.txt +0 -6
  63. dmu_data/text/transform_trf.txt +0 -12
  64. dmu_scripts/git/publish +0 -89
  65. dmu_scripts/physics/check_truth.py +0 -121
  66. dmu_scripts/rfile/compare_root_files.py +0 -299
  67. dmu_scripts/rfile/print_trees.py +0 -35
  68. dmu_scripts/ssh/coned.py +0 -168
  69. dmu_scripts/text/transform_text.py +0 -46
  70. {dmu_data → dmu}/__init__.py +0 -0
@@ -2,6 +2,7 @@
2
2
  Module storing ZModel class
3
3
  '''
4
4
  # pylint: disable=too-many-lines, import-error, too-many-positional-arguments, too-many-arguments
5
+ # pylint: disable=too-many-instance-attributes
5
6
 
6
7
  from typing import Callable, Union
7
8
 
@@ -10,6 +11,7 @@ import zfit
10
11
  from zfit.core.interfaces import ZfitSpace as zobs
11
12
  from zfit.core.basepdf import BasePDF as zpdf
12
13
  from zfit.core.parameter import Parameter as zpar
14
+ from dmu.stats.parameters import ParameterLibrary as PL
13
15
  from dmu.stats.zfit_models import HypExp
14
16
  from dmu.stats.zfit_models import ModExp
15
17
  from dmu.logging.log_store import LogStore
@@ -69,7 +71,13 @@ class ModelFactory:
69
71
  l_shr = ['mu']
70
72
  l_flt = ['mu', 'sg']
71
73
  d_rep = {'mu' : 'scale', 'sg' : 'reso'}
72
- mod = ModelFactory(preffix = 'signal', obs = obs, l_pdf = l_pdf, l_shared = l_shr, d_rep = d_rep)
74
+ mod = ModelFactory(
75
+ preffix = 'signal',
76
+ obs = obs,
77
+ l_pdf = l_pdf,
78
+ l_shared= l_shr,
79
+ d_rep = d_rep)
80
+
73
81
  pdf = mod.get_pdf()
74
82
  ```
75
83
 
@@ -81,23 +89,26 @@ class ModelFactory:
81
89
  '''
82
90
  #-----------------------------------------
83
91
  def __init__(self,
84
- preffix : str,
85
- obs : zobs,
86
- l_pdf : list[str],
87
- l_shared : list[str],
88
- l_float : list[str],
89
- d_fix : dict[str:float] = None,
90
- d_rep : dict[str:str] = None):
92
+ preffix : str,
93
+ obs : zobs,
94
+ l_pdf : list[str],
95
+ l_shared : list[str],
96
+ l_float : list[str],
97
+ l_reuse : None | list[zpar] = None,
98
+ d_fix : None | dict[str,float] = None,
99
+ d_rep : None | dict[str,str] = None):
91
100
  '''
92
101
  preffix: used to identify PDF, will be used to name every parameter
93
102
  obs: zfit obserbable
94
103
  l_pdf: List of PDF nicknames which are registered below
95
104
  l_shared: List of parameter names that are shared
96
105
  l_float: List of parameter names to allow to float
106
+ l_reuse: Optional. List of parameters that if given will be used instead of built by factory
97
107
  d_fix: Dictionary with keys as the beginning of the name of a parameter and value as the number
98
108
  to which it has to be fixed. If not one and only one parameter is found, ValueError is raised
99
109
  d_rep: Dictionary with keys as variables that will be reparametrized
100
110
  '''
111
+ l_reuse = [] if l_reuse is None else l_reuse
101
112
 
102
113
  self._preffix = preffix
103
114
  self._l_pdf = l_pdf
@@ -105,6 +116,7 @@ class ModelFactory:
105
116
  self._l_flt = l_float
106
117
  self._d_fix = d_fix
107
118
  self._d_rep = d_rep
119
+ self._d_reuse = { par.name : par for par in l_reuse }
108
120
  self._obs = obs
109
121
 
110
122
  self._d_par : dict[str,zpar] = {}
@@ -112,6 +124,13 @@ class ModelFactory:
112
124
  self._check_reparametrization()
113
125
  #-----------------------------------------
114
126
  def _check_reparametrization(self) -> None:
127
+ '''
128
+ This method:
129
+
130
+ - Returns if no reparametrization has been requested
131
+ - Raises if reparametrization is on any fixed parameter
132
+ - Raises if trying to reparametrize anything that is not scales and resolutions
133
+ '''
115
134
  if self._d_rep is None:
116
135
  return
117
136
 
@@ -119,6 +138,8 @@ class ModelFactory:
119
138
  s_par_2 = set(self._l_flt)
120
139
 
121
140
  if not s_par_1.isdisjoint(s_par_2):
141
+ log.info(f'Found : {s_par_1}')
142
+ log.info(f'Allowed: {s_par_2}')
122
143
  raise ValueError('Non empty intersection between floating and reparametrization parameters')
123
144
 
124
145
  s_kind = set(self._d_rep.values())
@@ -133,41 +154,109 @@ class ModelFactory:
133
154
  return pname, xname
134
155
  #-----------------------------------------
135
156
  def _get_parameter_name(self, name : str, suffix : str) -> str:
157
+ '''
158
+ Parameters
159
+ ---------------
160
+ name : Name of pdf and physical name, e.g mu_gauss
161
+ suffix: Identifies this PDF, e.g. index of 3rd gaussian
162
+
163
+ Returns
164
+ ---------------
165
+ Name of parameter which:
166
+
167
+ - mu if parameter is meant to be reused, e.g. same mu for all PDFs
168
+ - mu_preffix, if parameter is shared
169
+ - mu_preffix3 if not shared but not floating
170
+ - mu_preffix3_flt if not shared and floating
171
+ '''
172
+ # pname = physical name, is something like mu or sg
136
173
  pname, xname = self._split_name(name)
137
-
138
174
  log.debug(f'Using physical name: {pname}')
139
175
 
176
+ if pname in self._l_flt:
177
+ # If reused parameter is floating
178
+ # find it with flt
179
+ reuse_name = f'{pname}_flt'
180
+ else:
181
+ reuse_name = pname
182
+
183
+ if reuse_name in self._d_reuse:
184
+ log.debug(f'Picking name {reuse_name} for reused parameter')
185
+ return self._add_float(pname=pname, name=pname)
186
+
140
187
  if pname in self._l_shr:
141
188
  name = f'{pname}_{self._preffix}'
189
+ log.debug(f'Using model specific parameter name {name}')
142
190
  else:
143
191
  name = f'{pname}_{xname}_{self._preffix}{suffix}'
192
+ log.debug(f'Using component specific parameter name {name}')
144
193
 
145
- if pname in self._l_flt:
146
- return f'{name}_flt'
194
+ return self._add_float(pname=pname, name=name)
195
+ #-----------------------------------------
196
+ def _add_float(self, pname : str, name : str) -> str:
197
+ '''
198
+ Parameters
199
+ -------------
200
+ pname : Physical name, e.g. mu
201
+ name : Actual parameter name, e.g. mu_cbl_3
202
+
203
+ Returns
204
+ -------------
205
+ Actual parameter name with _flt appended if the physical version is meant to float
206
+ '''
207
+ if pname not in self._l_flt:
208
+ return name
147
209
 
148
- return name
210
+ return f'{name}_flt'
149
211
  #-----------------------------------------
150
212
  def _get_parameter(
151
213
  self,
214
+ kind : str,
152
215
  name : str,
153
- suffix : str,
154
- val : float,
155
- low : float,
156
- high : float) -> zpar:
216
+ suffix : str) -> zpar:
217
+ '''
218
+ Parameters
219
+ ----------------
220
+ kind : Identifies PDF, e.g. gaus
221
+ name : Physical name of parameter, e.g. mu
222
+ suffix: If multiple PDFs of this kind, it will be some sort of index, e.g. gaus(1), gaus(2)
223
+
224
+ Returns
225
+ ----------------
226
+ Parameter, if it was :
227
+
228
+ - Provided as part of l_reuse (e.g. mu), it will pick it up instead of building it
229
+ - Specified as shared, it will build it once and then reuse that one.
230
+ - Otherwise, it will make a new one, with a suffix to diferentiate it from whatever was already created
231
+ '''
157
232
 
158
- par_name = self._get_parameter_name(name, suffix)
233
+ par_name = self._get_parameter_name(f'{name}_{kind}', suffix)
159
234
  log.debug(f'Assigning name: {par_name}')
160
235
 
236
+ if par_name in self._d_reuse:
237
+ log.info(f'Reusing {par_name}')
238
+ return self._d_reuse[par_name]
239
+
161
240
  if par_name in self._d_par:
241
+ log.info(f'Picking already made parameter {par_name}')
162
242
  return self._d_par[par_name]
163
243
 
164
244
  is_reparametrized = self._is_reparametrized(name)
165
245
 
246
+ val, low, high = PL.get_values(kind=kind, parameter=name)
247
+
166
248
  if is_reparametrized:
167
249
  init_name, _ = self._split_name(par_name)
250
+ log.info(f'Reparametrizing {par_name}')
168
251
  par = self._get_reparametrization(par_name, init_name, val, low, high)
169
252
  else:
170
- par = zfit.param.Parameter(par_name, val, low, high)
253
+ if val == low == high:
254
+ log.warning(f'Upper and lower edges agree, fixing parameter to: {low}')
255
+ par = zfit.param.Parameter(par_name, val, low - 1 , high + 1)
256
+ par.floating = False
257
+ else:
258
+ log.debug(f'Creating new parameter {par_name}')
259
+ par = zfit.param.Parameter(par_name, val, low, high)
171
260
 
172
261
  self._d_par[par_name] = par
173
262
 
@@ -204,16 +293,16 @@ class ModelFactory:
204
293
  #-----------------------------------------
205
294
  @MethodRegistry.register('exp')
206
295
  def _get_exponential(self, suffix : str = '') -> zpdf:
207
- c = self._get_parameter('c_exp', suffix, -0.010, -0.020, -0.0001)
296
+ c = self._get_parameter('exp', 'c', suffix)
208
297
  pdf = zfit.pdf.Exponential(c, self._obs, name=f'exp{suffix}')
209
298
 
210
299
  return pdf
211
300
  # ---------------------------------------------
212
301
  @MethodRegistry.register('hypexp')
213
302
  def _get_hypexp(self, suffix : str = '') -> zpdf:
214
- mu = zfit.Parameter('mu_hypexp', 5000, 4000, 6000)
215
- ap = zfit.Parameter('ap_hypexp', 0.020, 0, 0.10)
216
- bt = zfit.Parameter('bt_hypexp', 0.002, 0.0001, 0.003)
303
+ mu = self._get_parameter('hypexp', 'mu', suffix)
304
+ ap = self._get_parameter('hypexp', 'ap', suffix)
305
+ bt = self._get_parameter('hypexp', 'bt', suffix)
217
306
 
218
307
  pdf= HypExp(obs=self._obs, mu=mu, alpha=ap, beta=bt, name=f'hypexp{suffix}')
219
308
 
@@ -221,9 +310,9 @@ class ModelFactory:
221
310
  # ---------------------------------------------
222
311
  @MethodRegistry.register('modexp')
223
312
  def _get_modexp(self, suffix : str = '') -> zpdf:
224
- mu = zfit.Parameter('mu_modexp', 4250, 4250, 4500)
225
- ap = zfit.Parameter('ap_modexp', 0.002, 0.002, 0.026)
226
- bt = zfit.Parameter('bt_modexp', 0.002, 0.002, 0.020)
313
+ mu = self._get_parameter('modexp', 'mu', suffix)
314
+ ap = self._get_parameter('modexp', 'ap', suffix)
315
+ bt = self._get_parameter('modexp', 'bt', suffix)
227
316
 
228
317
  pdf= ModExp(obs=self._obs, mu=mu, alpha=ap, beta=bt, name=f'modexp{suffix}')
229
318
 
@@ -231,34 +320,35 @@ class ModelFactory:
231
320
  #-----------------------------------------
232
321
  @MethodRegistry.register('pol1')
233
322
  def _get_pol1(self, suffix : str = '') -> zpdf:
234
- a = self._get_parameter('a_pol1', suffix, -0.005, -0.95, 0.00)
323
+ a = self._get_parameter('pol1', 'a', suffix)
235
324
  pdf = zfit.pdf.Chebyshev(obs=self._obs, coeffs=[a], name=f'pol1{suffix}')
236
325
 
237
326
  return pdf
238
327
  #-----------------------------------------
239
328
  @MethodRegistry.register('pol2')
240
329
  def _get_pol2(self, suffix : str = '') -> zpdf:
241
- a = self._get_parameter('a_pol2', suffix, -0.005, -0.95, 0.00)
242
- b = self._get_parameter('b_pol2', suffix, 0.000, -0.95, 0.95)
330
+ a = self._get_parameter('pol2', 'a', suffix)
331
+ b = self._get_parameter('pol2', 'b', suffix)
243
332
  pdf = zfit.pdf.Chebyshev(obs=self._obs, coeffs=[a, b ], name=f'pol2{suffix}')
244
333
 
245
334
  return pdf
246
335
  # ---------------------------------------------
247
336
  @MethodRegistry.register('pol3')
248
337
  def _get_pol3(self, suffix : str = '') -> zpdf:
249
- a = zfit.Parameter('a_pol3', -0.005, -0.95, 0.00)
250
- b = zfit.Parameter('b_pol3', 0.000, -0.95, 0.95)
251
- c = zfit.Parameter('c_pol3', 0.000, -0.95, 0.95)
338
+ a = self._get_parameter('pol3', 'a', suffix)
339
+ b = self._get_parameter('pol3', 'b', suffix)
340
+ c = self._get_parameter('pol3', 'c', suffix)
341
+
252
342
  pdf = zfit.pdf.Chebyshev(obs=self._obs, coeffs=[a, b, c], name=f'pol3{suffix}')
253
343
 
254
344
  return pdf
255
345
  #-----------------------------------------
256
346
  @MethodRegistry.register('cbr')
257
347
  def _get_cbr(self, suffix : str = '') -> zpdf:
258
- mu = self._get_parameter('mu_cbr', suffix, 5300, 5100, 5500)
259
- sg = self._get_parameter('sg_cbr', suffix, 10, 2, 300)
260
- ar = self._get_parameter('ac_cbr', suffix, -2, -14., -0.1)
261
- nr = self._get_parameter('nc_cbr', suffix, 1, 0.5, 150)
348
+ mu = self._get_parameter('cbr', 'mu', suffix)
349
+ sg = self._get_parameter('cbr', 'sg', suffix)
350
+ ar = self._get_parameter('cbr', 'ac', suffix)
351
+ nr = self._get_parameter('cbr', 'nc', suffix)
262
352
 
263
353
  pdf = zfit.pdf.CrystalBall(mu, sg, ar, nr, self._obs, name=f'cbr{suffix}')
264
354
 
@@ -266,10 +356,10 @@ class ModelFactory:
266
356
  #-----------------------------------------
267
357
  @MethodRegistry.register('suj')
268
358
  def _get_suj(self, suffix : str = '') -> zpdf:
269
- mu = self._get_parameter('mu_suj', suffix, 5300, 5000, 6000)
270
- sg = self._get_parameter('sg_suj', suffix, 10, 2, 5000)
271
- gm = self._get_parameter('gm_suj', suffix, 1, -10, 10)
272
- dl = self._get_parameter('dl_suj', suffix, 1, 0.1, 40)
359
+ mu = self._get_parameter('suj', 'mu', suffix)
360
+ sg = self._get_parameter('suj', 'sg', suffix)
361
+ gm = self._get_parameter('suj', 'gm', suffix)
362
+ dl = self._get_parameter('suj', 'dl', suffix)
273
363
 
274
364
  pdf = zfit.pdf.JohnsonSU(mu, sg, gm, dl, self._obs, name=f'suj{suffix}')
275
365
 
@@ -277,10 +367,10 @@ class ModelFactory:
277
367
  #-----------------------------------------
278
368
  @MethodRegistry.register('cbl')
279
369
  def _get_cbl(self, suffix : str = '') -> zpdf:
280
- mu = self._get_parameter('mu_cbl', suffix, 5300, 5100, 5500)
281
- sg = self._get_parameter('sg_cbl', suffix, 10, 2, 300)
282
- al = self._get_parameter('ac_cbl', suffix, 2, 0.0, 14.)
283
- nl = self._get_parameter('nc_cbl', suffix, 1, 0.5, 150)
370
+ mu = self._get_parameter('cbl', 'mu', suffix)
371
+ sg = self._get_parameter('cbl', 'sg', suffix)
372
+ al = self._get_parameter('cbl', 'ac', suffix)
373
+ nl = self._get_parameter('cbl', 'nc', suffix)
284
374
 
285
375
  pdf = zfit.pdf.CrystalBall(mu, sg, al, nl, self._obs, name=f'cbl{suffix}')
286
376
 
@@ -288,8 +378,8 @@ class ModelFactory:
288
378
  #-----------------------------------------
289
379
  @MethodRegistry.register('gauss')
290
380
  def _get_gauss(self, suffix : str = '') -> zpdf:
291
- mu = self._get_parameter('mu_gauss', suffix, 5300, 5100, 5500)
292
- sg = self._get_parameter('sg_gauss', suffix, 10, 2, 300)
381
+ mu = self._get_parameter('gauss', 'mu', suffix)
382
+ sg = self._get_parameter('gauss', 'sg', suffix)
293
383
 
294
384
  pdf = zfit.pdf.Gauss(mu, sg, self._obs, name=f'gauss{suffix}')
295
385
 
@@ -297,12 +387,12 @@ class ModelFactory:
297
387
  #-----------------------------------------
298
388
  @MethodRegistry.register('dscb')
299
389
  def _get_dscb(self, suffix : str = '') -> zpdf:
300
- mu = self._get_parameter('mu_dscb', suffix, 5300, 5000, 5400)
301
- sg = self._get_parameter('sg_dscb', suffix, 10, 2, 500)
302
- ar = self._get_parameter('ar_dscb', suffix, 1, 0, 5)
303
- al = self._get_parameter('al_dscb', suffix, 1, 0, 5)
304
- nr = self._get_parameter('nr_dscb', suffix, 2, 1, 150)
305
- nl = self._get_parameter('nl_dscb', suffix, 2, 0, 150)
390
+ mu = self._get_parameter('dscb', 'mu', suffix)
391
+ sg = self._get_parameter('dscb', 'sg', suffix)
392
+ ar = self._get_parameter('dscb', 'ar', suffix)
393
+ al = self._get_parameter('dscb', 'al', suffix)
394
+ nr = self._get_parameter('dscb', 'nr', suffix)
395
+ nl = self._get_parameter('dscb', 'nl', suffix)
306
396
 
307
397
  pdf = zfit.pdf.DoubleCB(mu, sg, al, nl, ar, nr, self._obs, name=f'dscb{suffix}')
308
398
 
@@ -310,9 +400,9 @@ class ModelFactory:
310
400
  #-----------------------------------------
311
401
  @MethodRegistry.register('voigt')
312
402
  def _get_voigt(self, suffix : str = '') -> zpdf:
313
- mu = zfit.Parameter('mu_voigt', 5280, 5040, 5500)
314
- sg = zfit.Parameter('sg_voigt', 20, 10, 400)
315
- gm = zfit.Parameter('gm_voigt', 4, 0.1, 100)
403
+ mu = self._get_parameter('voigt', 'mu', suffix)
404
+ sg = self._get_parameter('voigt', 'sg', suffix)
405
+ gm = self._get_parameter('voigt', 'gm', suffix)
316
406
 
317
407
  pdf = zfit.pdf.Voigt(m=mu, sigma=sg, gamma=gm, obs=self._obs, name=f'voigt{suffix}')
318
408
 
@@ -320,9 +410,9 @@ class ModelFactory:
320
410
  #-----------------------------------------
321
411
  @MethodRegistry.register('qgauss')
322
412
  def _get_qgauss(self, suffix : str = '') -> zpdf:
323
- mu = zfit.Parameter('mu_qgauss', 5280, 5040, 5500)
324
- sg = zfit.Parameter('sg_qgauss', 20, 10, 400)
325
- q = zfit.Parameter( 'q_qgauss', 1, 1, 3)
413
+ mu = self._get_parameter('qgauss', 'mu', suffix)
414
+ sg = self._get_parameter('qgauss', 'sg', suffix)
415
+ q = self._get_parameter('qgauss', 'q', suffix)
326
416
 
327
417
  pdf = zfit.pdf.QGauss(q=q, mu=mu, sigma=sg, obs=self._obs, name =f'qgauss{suffix}')
328
418
 
@@ -330,8 +420,8 @@ class ModelFactory:
330
420
  #-----------------------------------------
331
421
  @MethodRegistry.register('cauchy')
332
422
  def _get_cauchy(self, suffix : str = '') -> zpdf:
333
- mu = zfit.Parameter('mu', 5280, 5040, 5500)
334
- gm = zfit.Parameter('gm', 150, 50, 500)
423
+ mu = self._get_parameter('cauchy', 'mu', suffix)
424
+ gm = self._get_parameter('cauchy', 'gm', suffix)
335
425
 
336
426
  pdf = zfit.pdf.Cauchy(obs=self._obs, m=mu, gamma=gm, name=f'cauchy{suffix}')
337
427
 
@@ -357,7 +447,7 @@ class ModelFactory:
357
447
  def _get_pdf(self, kind : str, preffix : str) -> zpdf:
358
448
  fun = MethodRegistry.get_method(kind)
359
449
  if fun is None:
360
- raise NotImplementedError(f'PDF of type {kind} is not implemented')
450
+ raise NotImplementedError(f'PDF of type \"{kind}\" with preffix \"{preffix}\" is not implemented')
361
451
 
362
452
  return fun(self, preffix)
363
453
  #-----------------------------------------
@@ -375,12 +465,13 @@ class ModelFactory:
375
465
  #-----------------------------------------
376
466
  def _find_par(self, s_par : set[zpar], name_start : str) -> zpar:
377
467
  l_par_match = [ par for par in s_par if par.name.startswith(name_start) ]
468
+ npar = len(l_par_match)
378
469
 
379
- if len(l_par_match) != 1:
470
+ if npar!= 1:
380
471
  for par in s_par:
381
472
  log.info(par.name)
382
473
 
383
- raise ValueError(f'Not found one and only one parameter starting with: {name_start}')
474
+ raise ValueError(f'Found {npar} parameters starting with: {name_start}')
384
475
 
385
476
  return l_par_match[0]
386
477
  #-----------------------------------------
@@ -0,0 +1,100 @@
1
+ '''
2
+ Module with ParameterLibrary class
3
+ '''
4
+ from importlib.resources import files
5
+
6
+ import yaml
7
+ import pandas as pnd
8
+
9
+ from dmu.logging.log_store import LogStore
10
+
11
+ log=LogStore.add_logger('dmu:parameters')
12
+ # --------------------------------
13
+ class ParameterLibrary:
14
+ '''
15
+ Class meant to:
16
+
17
+ - Connect to database (YAML file) with parameter values and make them available
18
+ - Allow parameter values to be overriden
19
+ '''
20
+ df_parameters : pnd.DataFrame
21
+ # --------------------------------
22
+ @staticmethod
23
+ def _load_data() -> None:
24
+ if hasattr(ParameterLibrary, 'df_parameters'):
25
+ return
26
+
27
+ data_path = files('dmu_data').joinpath('stats/parameters/data.yaml')
28
+ data_path = str(data_path)
29
+
30
+ d_data = {'parameter' : [], 'kind' : [], 'val' : [], 'low' : [], 'high' : []}
31
+ with open(data_path, encoding='utf-8') as ifile:
32
+ data = yaml.safe_load(ifile)
33
+ for kind, d_par in data.items():
34
+ for parameter, d_kind in d_par.items():
35
+ val = d_kind['val' ]
36
+ low = d_kind['low' ]
37
+ high= d_kind['high']
38
+
39
+ d_data['parameter'].append(parameter)
40
+ d_data['kind' ].append(kind )
41
+ d_data['val' ].append(val )
42
+ d_data['low' ].append(low )
43
+ d_data['high' ].append(high )
44
+
45
+ df = pnd.DataFrame(d_data)
46
+
47
+ ParameterLibrary.df_parameters = df
48
+ # --------------------------------
49
+ @staticmethod
50
+ def print_parameters(kind : str) -> None:
51
+ '''
52
+ Method taking the kind of PDF to which the parameters are associated
53
+ and printing the values.
54
+ '''
55
+ df = ParameterLibrary.df_parameters
56
+ df = df[ df['kind'] == kind ]
57
+
58
+ print(df)
59
+ # --------------------------------
60
+ @staticmethod
61
+ def get_values(kind : str, parameter : str) -> tuple[float,float,float]:
62
+ '''
63
+ Takes PDF and parameter names and returns default value, low value and high value
64
+ '''
65
+ df = ParameterLibrary.df_parameters
66
+
67
+ df = df[df['kind'] == kind]
68
+ df = df[df['parameter']==parameter]
69
+
70
+ if len(df) != 1:
71
+ log.info(df)
72
+ raise ValueError(f'Could not find one and only one row for: {kind}/{parameter}')
73
+
74
+ val = df['val'].iloc[0]
75
+ low = df['low'].iloc[0]
76
+ high= df['high'].iloc[0]
77
+
78
+ return val, low, high
79
+ # --------------------------------
80
+ @staticmethod
81
+ def set_values(
82
+ parameter : str,
83
+ kind : str,
84
+ val : float,
85
+ low : float,
86
+ high : float) -> None:
87
+ '''
88
+ This function will override the value and range for the given parameter
89
+ It should be typically used before using the ModelFactory class
90
+ '''
91
+
92
+ df = ParameterLibrary.df_parameters
93
+
94
+ location = (df['parameter'] == parameter) & (df['kind'] == kind)
95
+
96
+ df.loc[location, 'val' ] = val
97
+ df.loc[location, 'low' ] = low
98
+ df.loc[location, 'high'] = high
99
+ # --------------------------------
100
+ ParameterLibrary._load_data()