def test_range(): ''' Test for disjointed ranges. ''' # Do calculations in a range m = minkit.Parameter('m', bounds=(0, 10)) k = minkit.Parameter('k', -0.5, bounds=(-0.8, -0.3)) e = minkit.Exponential('exponential', m, k) m.set_range('sides', [(0, 4), (6, 10)]) helpers.check_numerical_normalization(e, range='sides') data = e.generate(10000) with helpers.fit_test(e) as test: with minkit.minimizer('uml', e, data, minimizer='minuit', range='sides') as minuit: test.result = minuit.migrad() # Test generation of data only in the range data = e.generate(10000, range='sides') with helpers.fit_test(e) as test: with minkit.minimizer('uml', e, data, minimizer='minuit', range='sides') as minuit: test.result = minuit.migrad()
def test_display_pdfs(): ''' Test that the PDFs are displayed correctly as strings. ''' # Define the model x = minkit.Parameter('x', bounds=(-5, +5)) y = minkit.Parameter('y', bounds=(-5, +5)) c = minkit.Parameter('c', 0, bounds=(-5, +5)) k = minkit.Parameter('k', -0.1) sx = minkit.Parameter('sx', 2, bounds=(1, 3)) sy = minkit.Parameter('sy', 1, bounds=(0.5, 3)) gx = minkit.Gaussian('gx', x, c, sx) ex = minkit.Exponential('exp', x, k) gy = minkit.Gaussian('gy', y, c, sy) # Print a single PDF print(gx) # Print AddPDFs y = minkit.Parameter('y', 0.5) pdf = minkit.AddPDFs.two_components('pdf', gx, ex, y) print(pdf) # Print ProdPDFs pdf = minkit.ProdPDFs('pdf', [gx, gy]) print(pdf) # Print ConvPDFs pdf = minkit.ConvPDFs('pdf', gx, gy) print(pdf)
def test_unbinned_extended_maximum_likelihood(): ''' Test the "unbinned_extended_maximum_likelihood" FCN. ''' m = minkit.Parameter('m', bounds=(-5, +15)) # Create an Exponential PDF k = minkit.Parameter('k', -0.1, bounds=(-0.2, 0)) e = minkit.Exponential('exponential', m, k) # Create a Gaussian PDF c = minkit.Parameter('c', 10., bounds=(8, 12)) s = minkit.Parameter('s', 1., bounds=(0.5, 2)) g = minkit.Gaussian('gaussian', m, c, s) # Add them together ng = minkit.Parameter('ng', 10000, bounds=(0, 100000)) ne = minkit.Parameter('ne', 1000, bounds=(0, 100000)) pdf = minkit.AddPDFs.two_components('model', g, e, ng, ne) data = pdf.generate(int(ng.value + ne.value)) with helpers.fit_test(pdf) as test: with minkit.minimizer('ueml', pdf, data, minimizer='minuit') as minuit: test.result = minuit.migrad() # Add constraints cc = minkit.Parameter('cc', 10) sc = minkit.Parameter('sc', 1) gc = minkit.Gaussian('constraint', c, cc, sc) with helpers.fit_test(pdf) as test: with minkit.minimizer('ueml', pdf, data, minimizer='minuit', constraints=[gc]) as minuit: test.result = minuit.migrad()
def test_range(): ''' Test the "Range" class. ''' # Simple constructor v = [(1, 2), (5, 6)] r = minkit.Range(v) assert np.allclose(r.bounds, v) # Do calculations in a range m = minkit.Parameter('m', bounds=(0, 10)) k = minkit.Parameter('k', -0.5, bounds=(-0.8, -0.3)) e = minkit.Exponential('exponential', m, k) m.set_range('sides', [(0, 4), (6, 10)]) assert np.allclose(e.norm(range='sides'), e.numerical_normalization(range='sides')) data = e.generate(10000) with helpers.fit_test(e) as test: with minkit.minimizer('uml', e, data, minimizer='minuit', range='sides') as minuit: test.result = minuit.migrad() # Test generation of data only in the range data = e.generate(10000, range='sides') with helpers.fit_test(e) as test: with minkit.minimizer('uml', e, data, minimizer='minuit', range='sides') as minuit: test.result = minuit.migrad()
def default_add_pdfs(center='c', sigma='s', k='k', extended=False, yields=None): ''' Create a combination of a Gaussian and an exponential. ''' # Simple fit to a Gaussian x = minkit.Parameter('x', bounds=(0, 20)) # bounds to generate data later c = minkit.Parameter(center, 10, bounds=(8, 12)) s = minkit.Parameter(sigma, 2, bounds=(1, 3)) g = minkit.Gaussian('gaussian', x, c, s) # Test for a composed PDF k = minkit.Parameter(k, -0.1, bounds=(-1, 0)) e = minkit.Exponential('exponential', x, k) if extended: ng_name, ne_name = tuple(yields if yields is not None else ('ng', 'ne')) ng = minkit.Parameter(ng_name, 9000, bounds=(0, 10000)) ne = minkit.Parameter(ne_name, 1000, bounds=(0, 10000)) return minkit.AddPDFs.two_components('pdf', g, e, ng, ne) else: y_name = yields if yields is not None else 'y' y = minkit.Parameter(y_name, 0.5, bounds=(0, 1)) return minkit.AddPDFs.two_components('pdf', g, e, y)
def test_addpdfs(tmpdir): ''' Test the "AddPDFs" class. ''' m = minkit.Parameter('m', bounds=(-5, +5)) # Create an Exponential PDF k = minkit.Parameter('k', -0.05, bounds=(-0.1, 0)) e = minkit.Exponential('exponential', m, k) # Create a Gaussian PDF c = minkit.Parameter('c', 0., bounds=(-2, +2)) s = minkit.Parameter('s', 1., bounds=(-3, +3)) g = minkit.Gaussian('gaussian', m, c, s) # Add them together g2e = minkit.Parameter('g2e', 0.5, bounds=(0, 1)) pdf = minkit.AddPDFs.two_components('model', g, e, g2e) assert len(pdf.all_args) == (1 + len(g.args) + len(e.args)) gdata = helpers.rndm_gen.normal(c.value, s.value, 100000) edata = helpers.rndm_gen.exponential(-1. / k.value, 100000) data = np.concatenate([gdata, edata]) values, edges = np.histogram(data, bins=100, range=m.bounds) centers = minkit.DataSet.from_ndarray(0.5 * (edges[1:] + edges[:-1]), m) pdf_values = minkit.utils.core.scaled_pdf_values(pdf, centers, values, edges) assert np.allclose(np.sum(pdf_values), np.sum(values)) # Test consteness of the PDFs k.constant = True assert e.constant and not pdf.constant g2e.constant = True assert not pdf.constant for p in pdf.all_args: p.constant = True assert pdf.constant # Test the JSON conversion with open(os.path.join(tmpdir, 'pdf.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(pdf), fi) with open(os.path.join(tmpdir, 'pdf.json'), 'rt') as fi: s = minkit.pdf_from_json(json.load(fi)) check_multi_pdfs(s, pdf) # Check copying the PDF pdf.copy()
def test_sweights(): ''' Test the "sweights" function. ''' m = minkit.Parameter('m', bounds=(0, +20)) # Create an Exponential PDF k = minkit.Parameter('k', -0.1, bounds=(-0.2, 0)) e = minkit.Exponential('exponential', m, k) # Create a Gaussian PDF c = minkit.Parameter('c', 10., bounds=(0, 20)) s = minkit.Parameter('s', 1., bounds=(0.1, 2)) g = minkit.Gaussian('gaussian', m, c, s) # Add them together ng = minkit.Parameter('ng', 10000, bounds=(0, 100000)) ne = minkit.Parameter('ne', 1000, bounds=(0, 100000)) pdf = minkit.AddPDFs.two_components('model', g, e, ng, ne) data = pdf.generate(int(ng.value + ne.value)) with minkit.minimizer('ueml', pdf, data, minimizer='minuit') as minuit: r = minuit.migrad() print(r) # Now we fix the parameters that are not yields, and we re-run the fit for p in (e, g): for a in p.args: a.constant = True with minkit.minimizer('ueml', pdf, data, minimizer='minuit') as minuit: r = minuit.migrad() print(r) result = minkit.minuit_to_registry(r.params) # Calculate the s-weights (first comes from the Gaussian, second from the exponential) sweights, V = minkit.sweights(pdf.pdfs, result.reduce(['ng', 'ne']), data, return_covariance=True) # The s-weights are normalized assert np.allclose(minkit.core.aop.sum(sweights[0]), result.get(ng.name).value) assert np.allclose(minkit.core.aop.sum(sweights[1]), result.get(ne.name).value) # The uncertainty on the yields is reflected in the s-weights assert np.allclose(minkit.core.aop.sum(sweights[0]**2), V[0][0]) assert np.allclose(minkit.core.aop.sum(sweights[1]**2), V[1][1])
def test_exponential(): ''' Test the "Exponential" PDF ''' m = minkit.Parameter('m', bounds=(-5, +5)) k = minkit.Parameter('k', -0.05, bounds=(-0.1, 0)) e = minkit.Exponential('exponential', m, k) data = np.random.exponential(-1. / k.value, 100000) compare_with_numpy(e, data, m) assert np.allclose(e.numerical_normalization(), e.norm())
def test_exponential(): ''' Test the "Exponential" PDF ''' m = minkit.Parameter('m', bounds=(-5, +5)) k = minkit.Parameter('k', -0.05, bounds=(-0.1, 0)) e = minkit.Exponential('exponential', m, k) data = helpers.rndm_gen.exponential(-1. / k.value, 100000) compare_with_numpy(e, data, m) helpers.check_numerical_normalization(e)
def test_interppdf(tmpdir): ''' Test the InterpPDF class. ''' m = minkit.Parameter('m', bounds=(-3, +3)) centers = np.linspace(*m.bounds, 100) values = np.exp(-0.5 * centers**2) ip = minkit.InterpPDF.from_ndarray('ip', m, centers, values) ip.max() # check that we can calculate the maximum # Test the JSON conversion with open(os.path.join(tmpdir, 'ip.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(ip), fi) with open(os.path.join(tmpdir, 'ip.json'), 'rt') as fi: p = minkit.pdf_from_json(json.load(fi)) check_pdfs(p, ip) # Check copying the PDF ip.copy() # Combine the PDF with another k = minkit.Parameter('k', -0.1, bounds=(-1, +1)) e = minkit.Exponential('exp', m, k) y = minkit.Parameter('y', 0.5, bounds=(0, 1)) pdf = minkit.AddPDFs.two_components('pdf', ip, e, y) data = pdf.generate(10000) with fit_test(pdf) as test: with minkit.minimizer('uml', pdf, data, minimizer='minuit') as minimizer: test.result = minimizer.migrad() bdata = data.make_binned(20) with fit_test(pdf) as test: with minkit.minimizer('bml', pdf, bdata, minimizer='minuit') as minimizer: test.result = minimizer.migrad() # Test the construction from a binned data set minkit.InterpPDF.from_binned_dataset('pdf', bdata)
def test_binned_chisquare(): ''' Test the "binned_chisquare" FCN. ''' # Single PDF m = minkit.Parameter('m', bounds=(0, 20)) c = minkit.Parameter('c', 10., bounds=(8, 12)) # all bins must be highly populated s = minkit.Parameter('s', 3., bounds=(2, 7)) g = minkit.Gaussian('gaussian', m, c, s) data = g.generate(10000) values, edges = np.histogram( data[m.name].as_ndarray(), range=m.bounds, bins=100) data = minkit.BinnedDataSet.from_ndarray(edges, m, values) with helpers.fit_test(g) as test: with minkit.minimizer('chi2', g, data) as minimizer: test.result = minimizer.migrad() # Many PDfs k = minkit.Parameter('k', -0.1, bounds=(-1, 0)) e = minkit.Exponential('exponential', m, k) ng = minkit.Parameter('ng', 10000, bounds=(0, 100000)) ne = minkit.Parameter('ne', 1000, bounds=(0, 100000)) pdf = minkit.AddPDFs.two_components('pdf', g, e, ng, ne) data = pdf.generate(int(ng.value + ne.value)) values, edges = np.histogram( data[m.name].as_ndarray(), range=m.bounds, bins=100) data = minkit.BinnedDataSet.from_ndarray(edges, m, values) with helpers.fit_test(pdf) as test: with minkit.minimizer('chi2', pdf, data) as minimizer: test.result = minimizer.migrad()
def intermediate(): ''' Intermediate model, with a Crystal-ball and an exponential. ''' # Signal m = minkit.Parameter('m', bounds=(5, 25)) c = minkit.Parameter('c', 15, bounds=(10, 20)) s = minkit.Parameter('s', 1, bounds=(0.1, 5)) a = minkit.Parameter('a', 1.5, bounds=(0.1, 5)) n = minkit.Parameter('n', 10, bounds=(1, 30)) sig = minkit.CrystalBall('sig', m, c, s, a, n) # Background k = minkit.Parameter('k', -1e-6, bounds=(-1e-4, 0)) bkg = minkit.Exponential('bkg', m, k) # Model y = minkit.Parameter('y', 0.5, bounds=(0, 1)) pdf = minkit.AddPDFs.two_components('pdf', sig, bkg, y) return pdf
def test_constpdf(tmpdir): ''' Test a fit with a constant PDF. ''' m = minkit.Parameter('m', bounds=(0, 10)) # Create an Exponential PDF k = minkit.Parameter('k', -0.05) e = minkit.Exponential('exponential', m, k) # Create a Gaussian PDF c = minkit.Parameter('c', 5., bounds=(0, 10)) s = minkit.Parameter('s', 1., bounds=(0.5, 3)) g = minkit.Gaussian('gaussian', m, c, s) # Add them together g2e = minkit.Parameter('g2e', 0.5, bounds=(0, 1)) pdf = minkit.AddPDFs.two_components('model', g, e, g2e) # Check for "get_values" and "set_values" p = pdf.norm() pdf.set_values(**pdf.get_values()) assert np.allclose(p, pdf.norm()) # Test a simple fit data = pdf.generate(10000) with fit_test(pdf) as test: with minkit.minimizer('uml', pdf, data, minimizer='minuit') as minuit: test.result = minuit.migrad() # Test the JSON conversion with open(os.path.join(tmpdir, 'pdf.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(pdf), fi) with open(os.path.join(tmpdir, 'pdf.json'), 'rt') as fi: s = minkit.pdf_from_json(json.load(fi)) check_multi_pdfs(s, pdf)
def test_binned_maximum_likelihood(): ''' Tets the "binned_maximum_likelihood" FCN. ''' # Simple fit to a Gaussian m = minkit.Parameter('m', bounds=(5, 15)) c = minkit.Parameter('c', 10., bounds=(8, 12)) s = minkit.Parameter('s', 1., bounds=(0.5, 2)) g = minkit.Gaussian('gaussian', m, c, s) values, edges = np.histogram(np.random.normal(c.value, s.value, 10000), bins=100) data = minkit.BinnedDataSet.from_array(edges, m, values) with helpers.fit_test(g) as test: with minkit.minimizer('bml', g, data, minimizer='minuit') as minuit: test.result = minuit.migrad() # Add constraints cc = minkit.Parameter('cc', 10) sc = minkit.Parameter('sc', 0.1) gc = minkit.Gaussian('constraint', c, cc, sc) with helpers.fit_test(g) as test: with minkit.minimizer('bml', g, data, minimizer='minuit', constraints=[gc]) as minuit: test.result = minuit.migrad() # Test for a composed PDF k = minkit.Parameter('k', -0.1, bounds=(-1, 0)) e = minkit.Exponential('e', m, k) y = minkit.Parameter('y', 0.5, bounds=(0, 1)) pdf = minkit.AddPDFs.two_components('pdf', g, e, y) data = pdf.generate(10000) values, edges = np.histogram(minkit.as_ndarray(data[m.name]), bins=100) data = minkit.BinnedDataSet.from_array(edges, m, values) with helpers.fit_test(pdf) as test: with minkit.minimizer('bml', pdf, data) as minimizer: test.result = minimizer.migrad() # Test for a PDF with no "evaluate_binned" function defined m = minkit.Parameter('m', bounds=(0, 10)) a = minkit.Parameter('a', 0) theta = minkit.Parameter('theta', 2, bounds=(0, 3)) alpha = minkit.Parameter('alpha', 0.5) beta = minkit.Parameter('beta', 2) pdf = minkit.Amoroso('amoroso', m, a, theta, alpha, beta) data = pdf.generate(1000) values, edges = np.histogram(minkit.as_ndarray(data[m.name]), range=m.bounds, bins=100) data = minkit.BinnedDataSet.from_array(edges, m, values) with helpers.fit_test(pdf) as test: with minkit.minimizer('bml', pdf, data) as minimizer: test.result = minimizer.migrad()