def test_constpdf(tmpdir): ''' Test a fit with a constant PDF. ''' pdf = helpers.default_add_pdfs(extended=False) # 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_sourcepdf(tmpdir): ''' Test the "SourcePDF" class. ''' # Test the construction of a normal PDF m = minkit.Parameter('m', bounds=(-5, +5)) c = minkit.Parameter('c', 0., bounds=(-2, +2)) s = minkit.Parameter('s', 1., bounds=(-3, +3)) g = minkit.Gaussian('gaussian', m, c, s) # Test the construction of a PDF with variable number of arguments m = minkit.Parameter('m', bounds=(-5, +5)) p1 = minkit.Parameter('p1', 1.) p2 = minkit.Parameter('p2', 2.) pol0 = minkit.Polynomial('pol0', m) pol1 = minkit.Polynomial('pol1', m, p1) pol2 = minkit.Polynomial('pol2', m, p1, p2) # Test the JSON conversion with open(os.path.join(tmpdir, 'pdf.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(pol0), fi) with open(os.path.join(tmpdir, 'pdf.json'), 'rt') as fi: s = minkit.pdf_from_json(json.load(fi)) check_pdfs(s, pol0)
def test_convpdfs(tmpdir): ''' Test the "ConvPDFs" class. ''' m = minkit.Parameter('m', bounds=(-20, +20)) # Create two Gaussians c1 = minkit.Parameter('c1', 0, bounds=(-2, +2)) s1 = minkit.Parameter('s1', 3, bounds=(0.5, +10)) g1 = minkit.Gaussian('g1', m, c1, s1) c2 = minkit.Parameter('c2', 0, bounds=(-2, +2)) s2 = minkit.Parameter('s2', 4, bounds=(0.5, +10)) g2 = minkit.Gaussian('g2', m, c2, s2) pdf = minkit.ConvPDFs('convolution', g1, g2) data = pdf.generate(10000) # Check that the output is another Gaussian with bigger standard deviation mean = minkit.core.aop.sum(data[m.name]) / len(data) var = minkit.core.aop.sum((data[m.name] - mean)**2) / len(data) assert np.allclose(var, s1.value**2 + s2.value**2, rtol=0.1) # Check that the normalization is correct with pdf.bind() as proxy: assert np.allclose(proxy.integral(), 1.) assert np.allclose(proxy.norm(), 1.) assert np.allclose(proxy.numerical_normalization(), 1.) # Ordinary check for PDFs values, edges = np.histogram(minkit.as_ndarray(data[m.name]), bins=100, range=m.bounds) centers = minkit.DataSet.from_array(0.5 * (edges[1:] + edges[:-1]), m) pdf_values = minkit.plotting.scaled_pdf_values(pdf, centers, values, edges) assert np.allclose(np.sum(pdf_values), np.sum(values), rtol=0.01) # Test a fit 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_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_formulapdf(tmpdir): ''' Test the "FormulaPDF" class. ''' x = minkit.Parameter('x', bounds=(-2. * np.pi, +2 * np.pi)) a = minkit.Parameter('a', 1., bounds=(0.9, 1.1)) b = minkit.Parameter('b', 0., bounds=(-0.1, 0.1)) pdf = minkit.FormulaPDF.unidimensional('pdf', 'pow(sin(a * x + b), 2)', x, [a, b]) norm = pdf.norm() data = pdf.generate(10000) with helpers.fit_test(pdf) as test: with minkit.minimizer('uml', pdf, data) as minimizer: test.result = minimizer.migrad() # Include the integral pdf = minkit.FormulaPDF.unidimensional( 'pdf', 'pow(sin(a * x + b), 2)', x, [a, b], primitive='- sin(2 * (a * x + b)) -2 * (a * x + b) / (4 * a)') assert np.allclose(norm, pdf.norm()) with helpers.fit_test(pdf) as test: with minkit.minimizer('uml', pdf, data) as minimizer: test.result = minimizer.migrad() # In two dimensions x = minkit.Parameter('x', bounds=(0, 10)) y = minkit.Parameter('y', bounds=(0, 10)) ax = minkit.Parameter('ax', -0.01, bounds=(-1, 0)) ay = minkit.Parameter('ay', -0.01, bounds=(-1, 0)) pdf = minkit.FormulaPDF('pdf', 'exp(ax * x) * exp(ay * y)', [x, y], [ax, ay]) data = pdf.generate(10000) with helpers.fit_test(pdf) as test: with minkit.minimizer('uml', pdf, data) as minimizer: test.result = minimizer.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: p = minkit.pdf_from_json(json.load(fi)) check_pdfs(p, pdf)
def test_prodpdfs(tmpdir): ''' Test the "ProdPDFs" class. ''' # Create two Gaussians mx = minkit.Parameter('mx', bounds=(-5, +5)) cx = minkit.Parameter('cx', 0., bounds=(-2, +2)) sx = minkit.Parameter('sx', 1., bounds=(0.1, +3)) gx = minkit.Gaussian('gx', mx, cx, sx) my = minkit.Parameter('my', bounds=(-5, +5)) cy = minkit.Parameter('cy', 0., bounds=(-2, +2)) sy = minkit.Parameter('sy', 2., bounds=(0.5, +3)) gy = minkit.Gaussian('gy', my, cy, sy) pdf = minkit.ProdPDFs('pdf', [gx, gy]) # Test integration helpers.check_numerical_normalization(pdf) # Test consteness of the PDFs for p in gx.all_args: p.constant = True assert gx.constant and not pdf.constant for p in gy.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() # Do a simple fit for p in pdf.all_real_args: p.constant = False data = pdf.generate(10000) with fit_test(pdf) as test: with minkit.minimizer('uml', pdf, data) as minimizer: test.result = minimizer.migrad()
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_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_formula(tmpdir): ''' Test the "Formula" class. ''' a = minkit.Parameter('a', 1) b = minkit.Parameter('b', 2) c = minkit.Formula('c', 'a * b', [a, b]) assert np.allclose(c.value, a.value * b.value) # Test its use on a PDF m = minkit.Parameter('m', bounds=(10, 20)) c = minkit.Parameter('c', 15, bounds=(10, 20)) s = minkit.Formula('s', '0.1 + c / 10', [c]) g = minkit.Gaussian('gaussian', m, c, s) data = g.generate(10000) nd = np.random.normal(c.value, s.value, 10000) compare_with_numpy(g, nd, m) with helpers.fit_test(g) as test: with minkit.minimizer('uml', g, data, minimizer='minuit') as minuit: test.result = minuit.migrad() # Test the JSON (only for formula) with open(os.path.join(tmpdir, 'r.json'), 'wt') as fi: json.dump(s.to_json_object(), fi) with open(os.path.join(tmpdir, 'r.json'), 'rt') as fi: s = minkit.Formula.from_json_object(json.load(fi), g.all_real_args) # Test the JSON (whole PDF) with open(os.path.join(tmpdir, 'pdf.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(g), fi) with open(os.path.join(tmpdir, 'pdf.json'), 'rt') as fi: s = minkit.pdf_from_json(json.load(fi))
def test_prodpdfs(tmpdir): ''' Test the "ProdPDFs" class. ''' # Create two Gaussians mx = minkit.Parameter('mx', bounds=(-5, +5)) cx = minkit.Parameter('cx', 0., bounds=(-2, +2)) sx = minkit.Parameter('sx', 1., bounds=(-3, +3)) gx = minkit.Gaussian('gx', mx, cx, sx) my = minkit.Parameter('my', bounds=(-5, +5)) cy = minkit.Parameter('cy', 0., bounds=(-2, +2)) sy = minkit.Parameter('sy', 1., bounds=(-3, +3)) gy = minkit.Gaussian('gy', my, cy, sy) pdf = minkit.ProdPDFs('pdf', [gx, gy]) # Test integration assert np.allclose(pdf.norm(), pdf.numerical_normalization()) # Test consteness of the PDFs for p in gx.all_args: p.constant = True assert gx.constant and not pdf.constant for p in gy.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)
def test_formula(tmpdir): ''' Test the "Formula" class. ''' a = minkit.Parameter('a', 1) b = minkit.Parameter('b', 2) c = minkit.Formula('c', '{a} * {b}', [a, b]) assert np.allclose(c.value, a.value * b.value) # Test its use on a PDF m = minkit.Parameter('m', bounds=(10, 20)) c = minkit.Parameter('c', 15, bounds=(10, 20)) s = minkit.Formula('s', '0.1 + {c} / 10', [c]) g = minkit.Gaussian('gaussian', m, c, s) data = g.generate(10000) nd = rndm_gen.normal(c.value, s.value, 10000) compare_with_numpy(g, nd, m) with helpers.fit_test(g) as test: with minkit.minimizer('uml', g, data, minimizer='minuit') as minuit: test.result = minuit.migrad() # Test the JSON (only for formula) with open(os.path.join(tmpdir, 'r.json'), 'wt') as fi: json.dump(s.to_json_object(), fi) with open(os.path.join(tmpdir, 'r.json'), 'rt') as fi: s = minkit.Formula.from_json_object(json.load(fi), g.all_real_args) # Test the JSON (whole PDF) with open(os.path.join(tmpdir, 'pdf.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(g), fi) with open(os.path.join(tmpdir, 'pdf.json'), 'rt') as fi: minkit.pdf_from_json(json.load(fi)) # Test the copy of a formula new_args = s.args.copy() assert all(not o is p for o, p in zip(s.args, s.copy(new_args).args)) # Test for a formula depending on another formula m = minkit.Parameter('m', bounds=(10, 20)) c = minkit.Parameter('c', 15, bounds=(10, 20)) d = minkit.Formula('d', '0.1 + {c} / 10', [c]) s = minkit.Formula('s', '2 * {d}', [d]) g = minkit.Gaussian('gaussian', m, c, s) assert s.value == 3.2 data = g.generate(10000) with helpers.fit_test(g) as test: with minkit.minimizer('uml', g, data, minimizer='minuit') as minuit: test.result = minuit.migrad() # Test the JSON (only for formula) with open(os.path.join(tmpdir, 'r.json'), 'wt') as fi: json.dump(s.to_json_object(), fi) with open(os.path.join(tmpdir, 'r.json'), 'rt') as fi: s = minkit.Formula.from_json_object(json.load(fi), g.all_args) # Test the copy of a formula depending on another formula new_args = s.args.copy() assert all(not o is p for o, p in zip(s.args, s.copy(new_args).args)) # Test the JSON (whole PDF) with open(os.path.join(tmpdir, 'pdf.json'), 'wt') as fi: json.dump(minkit.pdf_to_json(g), fi) with open(os.path.join(tmpdir, 'pdf.json'), 'rt') as fi: minkit.pdf_from_json(json.load(fi))
def test_convpdfs(tmpdir): ''' Test the "ConvPDFs" class. ''' m = minkit.Parameter('m', bounds=(-20, +20)) # Create two Gaussians c1 = minkit.Parameter('c1', 0, bounds=(-2, +2)) s1 = minkit.Parameter('s1', 3, bounds=(0.5, +10)) g1 = minkit.Gaussian('g1', m, c1, s1) c2 = minkit.Parameter('c2', 0, bounds=(-2, +2)) s2 = minkit.Parameter('s2', 4, bounds=(0.5, +10)) g2 = minkit.Gaussian('g2', m, c2, s2) pdf = minkit.ConvPDFs('convolution', g1, g2) data = pdf.generate(10000) # Check that the output is another Gaussian with bigger standard deviation mean = aop.sum(data[m.name]) / len(data) var = aop.sum((data[m.name] - mean)**2) / len(data) assert np.allclose(var, s1.value**2 + s2.value**2, rtol=0.1) # Ordinary check for PDFs values, edges = np.histogram(data[m.name].as_ndarray(), 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), rtol=0.01) # Test a fit s2.constant = True # otherwise the minimization is undefined 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) # Check copying the PDF pdf.copy() # Test for binned data samples bdata = data.make_binned(20) with fit_test(pdf) as test: with minkit.minimizer('bml', pdf, bdata, minimizer='minuit') as minuit: test.result = minuit.migrad()