LabTools3 1.1.3.14__tar.gz → 1.1.3.16__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.
@@ -456,8 +456,10 @@ class histo:
456
456
  Keyword Meaning
457
457
  ============ =====================================================
458
458
  scale True: the original bin number is not a multiple of n
459
- and the last bin content will be scaled
460
- use_mean True: the new bin content is the mean of the bin_content
459
+ and the last bin content will be scaled accordingly
460
+
461
+ use_mean True: the new bin content is the mean of the bin_content
462
+ of n bins
461
463
 
462
464
  replace True: replace the current histogram with the
463
465
  rebinned version
@@ -1138,7 +1140,7 @@ class histo:
1138
1140
  # mean value of the slices
1139
1141
  mean_sl = np.array([np.mean(x[sl]) for sl in slices[:-1]])
1140
1142
  # factor to correct the sum for slices that are shorter than n
1141
- fact = np.array([np.float(n)/len(x[sl]) for sl in slices[:-1]])
1143
+ fact = np.array([float(n)/len(x[sl]) for sl in slices[:-1]])
1142
1144
  # return the values
1143
1145
  return sum_sl, mean_sl, slices[:-1], fact
1144
1146
 
@@ -39,6 +39,9 @@ Possible data types (dtype) are:
39
39
  If ``var_type`` keyword agrument is not used, the function tries to convert to float or bool. If both fails it
40
40
  returns the string value.
41
41
 
42
+ An input line can be continued (will be concatenated) by adding a backslash as the last character or
43
+ a comma. The comma will be included in the data while the backslash is removed.
44
+
42
45
  Variable names are also called keys.
43
46
  """
44
47
 
@@ -58,7 +61,7 @@ class pfile:
58
61
  >>> pf=pfile('my_datafile')
59
62
 
60
63
  """
61
- def __init__(self, filename, data = None):
64
+ def __init__(self, filename = 'no_file_provided', data = None):
62
65
  """
63
66
  open a parameter file, scan for name=value pairs
64
67
  and return a dictionary with name value pairs
@@ -119,10 +122,13 @@ class pfile:
119
122
  # check for continuation
120
123
  if do_add :
121
124
  # add new line to end of last one and reset do_add flag
122
- l_l = l_old[:-1] + l_l
125
+ if l_old[-1] == ',' : # preserve the comma as continuation character
126
+ l_l = l_old[:] + l_l
127
+ else:
128
+ l_l = l_old[:-1] + l_l
123
129
  do_add = False
124
- # check for continuation character at the end of the line
125
- do_cont = (l_l[-1] == '\\')
130
+ # check for continuation character at the end of the line (backslash or comma)
131
+ do_cont = (l_l[-1] == '\\' or l_l[-1] == ',')
126
132
  if do_cont:
127
133
  # found a continuation flag it and save the current line
128
134
  do_add = True
@@ -10,23 +10,36 @@ Depending on the outcome, one might need to change the initial values of the par
10
10
  decide to change which parameters are fixed and which are to be fitted.
11
11
 
12
12
  1. Setting up the parameters::
13
-
13
+
14
+ >>> import numpy as np
14
15
  >>> import LT_Fit.parameters as P # get the parameter module
15
- >>> import LT_fit.gen_fit as G # load the genfit module
16
+ >>> import LT_Fit.gen_fit as G # load the genfit module
16
17
  >>> a = P.Parameter(1., 'amp') # parameter a, called 'amp', initialized to 1.
17
18
  >>> b = P.Parameter(3., 'omega') # parameter b, called 'omega', intialized to 3.
18
19
  >>> c = P.Parameter(1.5, 'phase') # parameter c, called 'phase', initialize to 1.5
19
20
 
21
+
22
+
23
+
20
24
  2. Define the fitting function::
21
25
 
22
26
  >>> def f(x):
23
- .... return a()*sin(b() * x + c() )
27
+ .... return a()*np.sin(b() * x + c() )
28
+
29
+
30
+ 3. Setup pseudo data::
31
+
32
+ >>> xval = np.linspace(0,2,20) # generate pseudo data
33
+ >>> y = f(xval)
34
+ >>> y_exp = y + np.random.normal(loc = 0, scale = 0.05, size = len(y))
35
+ >>> sig_y = np.ones_like(y)*0.05
36
+
24
37
 
25
- 3. Now do the fit::
38
+ 4. Now do the fit::
26
39
 
27
40
  >>> F = G.genfit( f, [a, b, c], x = xval, y = y_exp) # the list [a,b,c] defines which parameters are fitted
28
- >>> F = G.genfit( f, [a], x = xval, y = y_exp, yerr = sigy) # only a is fitted, but take the exp. error into account
29
- >>> F = G.genfit( f, [a, c], x = xval, y = y_exp, yerr = sigy) # a and c are fitted b is kept constant
41
+ >>> F = G.genfit( f, [a], x = xval, y = y_exp, y_err = sig_y) # only a is fitted, but take the exp. error into account
42
+ >>> F = G.genfit( f, [a, c], x = xval, y = y_exp, y_err = sig_y) # a and c are fitted b is kept constant
30
43
 
31
44
  To change the initial values and repeat the fit::
32
45
 
@@ -34,11 +47,21 @@ To change the initial values and repeat the fit::
34
47
  >>> b.set(3.2)
35
48
  >>> c.set(2.0)
36
49
  >>> F = G.genfit( f, [a, b, c], x = xval, y = y_exp)
50
+
51
+ Calculate parameter derivatives analytically::
52
+
53
+ >>> dfda = lambda x : np.sin(b() * x + c() ) # derivative wrsp a
54
+ >>> dfdb = lambda x : a()*np.cos(b() * x + c() )*x # derivative wrsp b
55
+ >>> dfdc = lambda x : a()*np.cos(b() * x + c() ) # derivative wrsp c
56
+ >>> deriv_list = [dfda, dfdb, dfdc] # list of derivative functions
57
+ >>> # do the fit using analytically calculated derivatives
58
+ >>> F = G.genfit( f, [a, b, c], x = x, y = y_exp, y_err = sig_y, func_deriv=deriv_list)
59
+
37
60
 
38
61
  Finally plot the data and the fit::
39
62
 
40
63
  >>> import LT.box as B
41
- >>> B.plot_exp(xval, y_exp, sigy) # plot the data with errorbars
64
+ >>> B.plot_exp(xval, y_exp, sig_y) # plot the data with errorbars
42
65
  >>> F.plot() # plot the fitted function as a line
43
66
  >>> B.plot_line(F.xpl, F.ypl) # old version of plotting the fitted function as a line
44
67
  >>> F(x) # evaluate the fitted function at x
@@ -56,9 +79,9 @@ import scipy.stats as SS
56
79
  import matplotlib.pyplot as pl
57
80
 
58
81
  import copy as C
59
- from .parameters import *
82
+ # from LT_Fit.parameters import *
60
83
  import numpy as np
61
- import pdb
84
+ # import pdb
62
85
 
63
86
 
64
87
  class genfit:
@@ -76,11 +99,16 @@ class genfit:
76
99
  y_err (:func:`numpy.array`) array of errors
77
100
  nplot number of points to be used for plotting the fit
78
101
  ftol minimal change in chi square to determine if the fit has converged
102
+ diff_step step size used to the numerical calculation of derivetives with respect to the
103
+ fit parameters (default = 0.001), h = diff_step * par
79
104
  kwargs additional keywords are passes to scipy.optimize.least_squares, examples below
80
105
  bounds an array for upper and lower bounds for the parameter
81
106
  loss alternative loss function to handle outliers e.g. 'huber'
82
107
  f_scale outliers with a residual more the f_scale should be not affect the result
83
108
  plot_fit (default True) plot the fitted function automatically
109
+ func_deriv list of functions corresponding to the fit parameter list (parameters)
110
+ that calculate the derivative of the fit function with respect to each
111
+ of the fit parameters. (default = None)
84
112
  ========== ===================================================================
85
113
 
86
114
  Additional keyword arguments are passed on to :func:`scipy.optimize.leastsq`
@@ -93,10 +121,12 @@ class genfit:
93
121
  nplot = 100, \
94
122
  full_output = 1, \
95
123
  ftol = 0.001, \
124
+ diff_step = 0.001, \
96
125
  print_results = True, \
97
126
  plot_fit = True, \
127
+ func_deriv = None, \
98
128
  **kwargs):
99
- # print('gen_fit kwargs = ', kwargs)
129
+ print('gen_fit kwargs = ', kwargs)
100
130
  self.plot_fit = plot_fit
101
131
  self.print_results = print_results
102
132
  self.y = y
@@ -111,18 +141,19 @@ class genfit:
111
141
  self.nplot = nplot
112
142
  self.parameters = parameters # the array stores the addresses of the parameter objects
113
143
  self.func = function
144
+ self.func_deriv = func_deriv
114
145
  # carry out the fit
115
146
  if y is None:
116
147
  print('No values to fit, use set_yval to set them before fitting !')
117
148
  return
118
149
  return self.fit(full_output = full_output, \
119
150
  ftol = ftol, \
151
+ diff_step = diff_step, \
120
152
  **kwargs)
121
153
 
122
154
  def f(self, params):
123
- # define minimzation function for least square i = 0
124
- i = 0
125
- for p in self.parameters:
155
+ # define minimzation function for least square
156
+ for i,p in enumerate(self.parameters):
126
157
  # store the current values in the array p back into the parameter
127
158
  # classes to be used by the user defined function
128
159
  # check if there is only 1 parameter
@@ -131,7 +162,6 @@ class genfit:
131
162
  p.set(params[i])
132
163
  else:
133
164
  p.set(params)
134
- i += 1
135
165
  # now calculate the difference between data and fit function
136
166
  # and return it to the optimization routine
137
167
  if self.y_err is None:
@@ -140,6 +170,24 @@ class genfit:
140
170
  return (self.y - self.func(self.x))/self.y_err
141
171
  # end of the minimization function
142
172
 
173
+ def f_jac(self, params):
174
+ # calculate the jacobian analytically for a list of derivative functions if available
175
+ # define minimzation function for least square i = 0
176
+ for i,p in enumerate(self.parameters):
177
+ # store the current values in the array p back into the parameter
178
+ # classes to be used by the user defined function
179
+ # check if there is only 1 parameter
180
+ ps = params.shape
181
+ if len(ps) > 0:
182
+ p.set(params[i])
183
+ else:
184
+ p.set(params)
185
+ if self.y_err is None:
186
+ jac = np.array([-f(self.x) for f in self.func_deriv]).T
187
+ else:
188
+ jac = np.array([-f(self.x)/self.y_err for f in self.func_deriv]).T
189
+ return jac
190
+
143
191
  def plot(self, xv = None, **kwargs):
144
192
  """
145
193
  Plot the fitting function
@@ -162,7 +210,7 @@ class genfit:
162
210
  else:
163
211
  pl.plot(xv, self.func(xv), **kwargs)
164
212
 
165
- def fit(self, full_output = 1, ftol = 0.001, **kwargs):
213
+ def fit(self, full_output = 1, ftol = 0.001, diff_step = 0.001, **kwargs):
166
214
  # this is the minimzation routine
167
215
  # store the current parameter values in a list to be passed to the fitting function
168
216
  # this is an implicit loop, it is equivalent to
@@ -170,6 +218,7 @@ class genfit:
170
218
  # for param in parameters:
171
219
  # p.append(param())
172
220
  # clear the parameter errors:
221
+ print('gen_fit.fit kwargs = ', kwargs)
173
222
  for p in self.parameters:
174
223
  p.err = 0.
175
224
  p = [param() for param in self.parameters]
@@ -178,12 +227,35 @@ class genfit:
178
227
  # full_output = full_output, \
179
228
  # ftol = ftol, \
180
229
  # **kwargs)
181
- self.fit_result = optimize.least_squares( self.f, p,\
182
- ftol = ftol, \
183
- **kwargs)
230
+ if self.func_deriv is None:
231
+ print(f'Calculate numerical parameter derivatives with diff_step = {diff_step}')
232
+ self.fit_result = optimize.least_squares( self.f, p,\
233
+ ftol = ftol, \
234
+ diff_step = diff_step, \
235
+ **kwargs)
236
+ else:
237
+ print('Calculate analytical parameter derivatives ')
238
+ self.fit_result = optimize.least_squares( self.f, p,\
239
+ ftol = ftol, \
240
+ jac = self.f_jac, \
241
+ **kwargs)
242
+
243
+
184
244
  # estimate covariance matrix
185
- J = self.fit_result.jac
186
- self.covar = np.linalg.inv(J.T.dot(J))
245
+ J = self.fit_result.jac
246
+ try:
247
+ self.covar = np.linalg.inv(J.T.dot(J))
248
+ except Exception as err:
249
+ print(f'Cannot calculate covariance matrix, reason: {err}')
250
+ print(f'jacobian = {J}')
251
+ self.stat = {}
252
+ self.covar = []
253
+ self.xpl = []
254
+ self.ypl = []
255
+ self.chi2 = -1.
256
+ self.chi2_red = -1.
257
+ self.CL = -1.
258
+ return
187
259
  # now calculate the fitted values
188
260
  fit_func = self.func(self.x)
189
261
  # final total chi square
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: LabTools3
3
- Version: 1.1.3.14
3
+ Version: 1.1.3.16
4
4
  Summary: Python 3 Package of modules for typical analysis tasks analyzing physics data
5
5
  Home-page: http://wanda.fiu.edu/LabTools3
6
6
  Author: Werner Boeglin
7
7
  Author-email: boeglinw@fiu.edu
8
8
  License: MIT
9
9
  Keywords: Data Analysis
10
- Classifier: Programming Language :: Python :: 3.6
11
- Requires-Python: >=3.6
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
 
@@ -50,3 +50,7 @@ Version 1.1.3.12: bug fixes, peak and background functions are available for his
50
50
  Version 1.1.3.13: fitting of only one parameters enabled for linear fits
51
51
 
52
52
  Version 1.1.3.14: error calcualtion for filling histograms with weights include sum of weight**2
53
+
54
+ Version 1.1.3.15: contination lines enabled in parameter file by endine line with "\" or ",""
55
+
56
+ Version 1.1.3.16: Corrected bug in histo.rebin. gen_fit allows control of relative step size using the diff_step keyword. It is also possible to supply a list of functions to calculate the parameter derivatives. This helps with numerical accuracy in the minimization process (see gen_fit documentation)
@@ -1,3 +1,17 @@
1
+ Metadata-Version: 2.1
2
+ Name: LabTools3
3
+ Version: 1.1.3.16
4
+ Summary: Python 3 Package of modules for typical analysis tasks analyzing physics data
5
+ Home-page: http://wanda.fiu.edu/LabTools3
6
+ Author: Werner Boeglin
7
+ Author-email: boeglinw@fiu.edu
8
+ License: MIT
9
+ Keywords: Data Analysis
10
+ Classifier: Programming Language :: Python :: 3.8
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+
1
15
  # LabTools3
2
16
  Set of Python analysis tools for physics labs. It contains the "package" directory which is the Python package with a setup.py script for installation and
3
17
  a "doc" directory containing the Sphinx documentation. The repository starts with version 0.2.9 of LabTools.
@@ -35,4 +49,8 @@ Version 1.1.3.12: bug fixes, peak and background functions are available for his
35
49
 
36
50
  Version 1.1.3.13: fitting of only one parameters enabled for linear fits
37
51
 
38
- Version 1.1.3.14: error calcualtion for filling histograms with weights include sum of weight**2
52
+ Version 1.1.3.14: error calcualtion for filling histograms with weights include sum of weight**2
53
+
54
+ Version 1.1.3.15: contination lines enabled in parameter file by endine line with "\" or ",""
55
+
56
+ Version 1.1.3.16: Corrected bug in histo.rebin. gen_fit allows control of relative step size using the diff_step keyword. It is also possible to supply a list of functions to calculate the parameter derivatives. This helps with numerical accuracy in the minimization process (see gen_fit documentation)
@@ -1,17 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: LabTools3
3
- Version: 1.1.3.14
4
- Summary: Python 3 Package of modules for typical analysis tasks analyzing physics data
5
- Home-page: http://wanda.fiu.edu/LabTools3
6
- Author: Werner Boeglin
7
- Author-email: boeglinw@fiu.edu
8
- License: MIT
9
- Keywords: Data Analysis
10
- Classifier: Programming Language :: Python :: 3.6
11
- Requires-Python: >=3.6
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
-
15
1
  # LabTools3
16
2
  Set of Python analysis tools for physics labs. It contains the "package" directory which is the Python package with a setup.py script for installation and
17
3
  a "doc" directory containing the Sphinx documentation. The repository starts with version 0.2.9 of LabTools.
@@ -50,3 +36,7 @@ Version 1.1.3.12: bug fixes, peak and background functions are available for his
50
36
  Version 1.1.3.13: fitting of only one parameters enabled for linear fits
51
37
 
52
38
  Version 1.1.3.14: error calcualtion for filling histograms with weights include sum of weight**2
39
+
40
+ Version 1.1.3.15: contination lines enabled in parameter file by endine line with "\" or ",""
41
+
42
+ Version 1.1.3.16: Corrected bug in histo.rebin. gen_fit allows control of relative step size using the diff_step keyword. It is also possible to supply a list of functions to calculate the parameter derivatives. This helps with numerical accuracy in the minimization process (see gen_fit documentation)
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name = "LabTools3",
8
- version = "1.1.3.14",
8
+ version = "1.1.3.16",
9
9
  packages = find_packages(),
10
10
  # add additional files
11
11
  package_data = {'':['*.bat','*.command']},
@@ -20,7 +20,7 @@ setup(
20
20
  keywords = "Data Analysis",
21
21
  url = "http://wanda.fiu.edu/LabTools3", # project home page, if any
22
22
  classifiers=[
23
- "Programming Language :: Python :: 3.6",
23
+ "Programming Language :: Python :: 3.8",
24
24
  ],
25
- python_requires='>=3.6'
25
+ python_requires='>=3.8'
26
26
  )
File without changes
File without changes
File without changes