Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10664174
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
29 KB
Subscribers
None
View Options
diff --git a/debinningMath/dataGen.py b/debinningMath/dataGen.py
index dfce2dc..79857db 100644
--- a/debinningMath/dataGen.py
+++ b/debinningMath/dataGen.py
@@ -1,255 +1,267 @@
'''
dataGen.py
Functions to generate fake test data.
Copyright (C) 2015 Abram Krislock
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the, 110., 1.5, 50., 140.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0.txt.
'''
from __future__ import division
import numpy as np
import bisect
import debinningMath.orderStatistics as oStat
class MyRandom(np.random.RandomState):
def __init__(self, seedIn):
np.random.RandomState.__init__(self)
self.setSeed(seedIn)
def setSeed(self, seedIn):
if type(seedIn) in (int, long):
self.seed(abs(seedIn) % (2**32 - 1))
else:
self.seed(abs(hash(str(seedIn))) % (2**32 - 1))
randomGenerator = MyRandom('default')
class DataGenContainer(object):
''' Generates a data sample given an input probability distribution function.
Arguments for initialization:
pdf: The probability distribution function used to generate data.
WARNING: There is no default. pdf must be provided as a function
with call signature 'pdf(x, pars)' (with x as a numpy array).
Keyword arguments for initialization:
pars [=None]: A list of parameters to pass to the pdf.
nPoints [=100]: The number of points to generate in the sample.
domain [=np.arange(0., 200., 0.5)]: The discretized x values which
may be generated.
rng [=dataGen.randomGenerator]: A flat random number generator with
call signature 'rng.rand(n)'. It must return a numpy array of
length n, containing flat random numbers in the range (0, 1).
'''
def __init__(self, pdf, **kwargs):
# Set generating probability distribution function
self.pdf = pdf
self.pars = kwargs.get('pars', None)
# Set data generation parameters
self.n = kwargs.get('nPoints', 100)
self.x = np.array(kwargs.get('domain', np.arange(0., 200., 0.5)))
self.rng = kwargs.get('rng', randomGenerator)
# initial calculations...
self.f_unnormed = self.pdf(self.x, self.pars)
self.F_unnormed = oStat.A(self.f_unnormed, oStat.forwardDiff(self.x))
self.f = self.f_unnormed / self.F_unnormed[-1]
self.F = self.F_unnormed / self.F_unnormed[-1]
def changeFunction(self, f_unnormed_in):
''' Changes self.f_unnormed to a new numerical function, based upon the same
x domain as the original. '''
self.f_unnormed = f_unnormed_in
# reinitialize
self.F_unnormed = oStat.A(self.f_unnormed, oStat.forwardDiff(self.x))
self.f = self.f_unnormed / self.F_unnormed[-1]
self.F = self.F_unnormed / self.F_unnormed[-1]
def changeDomain(self, x=0):
''' Changes the x domain to a given numpy array. If x is an integer,
chooses a new domain for which the pdf is non-zero, with x points
discarded at both the beginning and end of the domain. '''
if type(x) == np.ndarray:
self.x = x
else:
nonzero = self.x[self.f.nonzero()]
self.x = np.linspace(nonzero[x], nonzero[-1-x], len(self.x))
# reinitialize
self.f_unnormed = self.pdf(self.x, self.pars)
self.F_unnormed = oStat.A(self.f_unnormed, oStat.forwardDiff(self.x))
self.f = self.f_unnormed / self.F_unnormed[-1]
self.F = self.F_unnormed / self.F_unnormed[-1]
def generate(self, sort=False):
# bisect_left(F, p) locates the left-most entry in F which is >= p
# Use the unnormed cdf, F_unnormed, to avoid tiny number roundoff error.
self.data = np.array([self.x[bisect.bisect_left(self.F_unnormed, p)]
for p in (self.rng.rand(self.n) * self.F_unnormed[-1])])
if sort:
self.data.sort()
return self.data
class DataGen2dContainer(object):
''' Generates a data sample given an input probability distribution function.
Arguments for initialization:
pdf: The probability distribution function used to generate data.
WARNING: There is no default. pdf must be provided as a function
with call signature 'pdf(x, y, pars)' (with x,y as numpy arrays).
Keyword arguments for initialization:
pars [=None]: A list of parameters to pass to the pdf.
nPoints [=100]: The number of points to generate in the sample.
domain [=( np.arange(0., 200., 0.5), np.arange(0., 200., 0.5) )]:
The domain of discretized (x,y) values which may be generated.
rng [=dataGen.randomGenerator]: A flat random number generator with
call signature 'rng.rand(n)'. It must return a numpy array of
length n, containing flat random numbers in the range (0, 1).
'''
def __init__(self, pdf, **kwargs):
# Set generating probability distribution function
self.pdf = pdf
self.pars = kwargs.get('pars', None)
# Set data generation parameters
self.n = kwargs.get('nPoints', 100)
self.x, self.y = kwargs.get('domain', (np.arange(0., 200., 0.5),
np.arange(0., 200., 0.5)))
self.x = np.array(self.x)
self.y = np.array(self.y)
self.dx = self.x[1] - self.x[0]
self.dy = self.y[1] - self.y[0]
self.xx, self.yy = np.meshgrid(self.x, self.y, indexing='ij')
self.rng = kwargs.get('rng', randomGenerator)
# initial calculations...
self.f_unnormed = self.pdf(self.x, self.y, self.pars)
self.F_Hunnormed = oStat.A_H(self.f_unnormed, self.dx, self.dy)
self.F_Vunnormed = oStat.A_V(self.f_unnormed, self.dx, self.dy)
self.f_H = self.f_unnormed / self.F_Hunnormed[-1][-1]
self.f_V = self.f_unnormed / self.F_Vunnormed[-1][-1]
self.F_H = self.F_Hunnormed / self.F_Hunnormed[-1][-1]
self.F_V = self.F_Vunnormed / self.F_Vunnormed[-1][-1]
def changeFunction(self, f_unnormed_in):
''' Changes self.f_unnormed to a new numerical function, based upon the same
x domain as the original. '''
self.f_unnormed = f_unnormed_in
# reinitialize
self.F_Hunnormed = oStat.A_H(self.f_unnormed, self.dx, self.dy)
self.F_Vunnormed = oStat.A_V(self.f_unnormed, self.dx, self.dy)
self.f_H = self.f_unnormed / self.F_Hunnormed[-1][-1]
self.f_V = self.f_unnormed / self.F_Vunnormed[-1][-1]
self.F_H = self.F_Hunnormed / self.F_Hunnormed[-1][-1]
self.F_V = self.F_Vunnormed / self.F_Vunnormed[-1][-1]
- def generate(self):
- ''' Generate a data sample from the stored PDF. '''
+ def generate(self, sort=False):
+ ''' Generate a data sample from the stored PDF. If sort=True, argsortH and
+ argsortV are both automatically called. '''
# bisect_left(F, p) locates the left-most entry in F which is >= p
# Use the unnormed cdf, F_Vunnormed, to avoid tiny number roundoff error.
self.data = []
for p in (self.rng.rand(self.n) * self.F_Vunnormed[-1][-1]):
i = bisect.bisect_left(self.F_Vunnormed.T[-1], p)
j = bisect.bisect_left(self.F_Vunnormed[i], p)
self.data.append((self.x[i], self.y[j]))
- self.data = np.array(self.data)
+ self.data = np.array(self.data, dtype=[('x', float), ('y', float)])
+ if 'r_Harray' in dir(self):
+ del self.r_Harray
+ if 'r_Varray' in dir(self):
+ del self.r_Varray
+ if sort:
+ self.argsortH()
+ self.argsortV()
return self.data
- def sortH(self):
- ''' Return a "horizontally" sorted copy of the generated data. '''
+ def argsortH(self):
+ ''' Return an array of indices which would "horizontally" sort the data. '''
if 'data' not in dir(self):
self.generate()
+ self.r_Harray = self.data.argsort(order=['y','x']).argsort()
+ return self.r_Harray
- def sortV(self):
- ''' Return a "vertically" sorted copy of the generated data. '''
+ def argsortV(self):
+ ''' Return an array of indices which would "vertically" sort the data. '''
if 'data' not in dir(self):
self.generate()
+ self.r_Varray = self.data.argsort(order=['x','y']).argsort()
+ return self.r_Varray
class DataPlusBGContainer(DataGenContainer):
''' Generates a data sample given signal and background probability
distribution functions, using the formula:
pdf(x) = (1 - alpha) * b_pdf + alpha * s_pdf
Arguments for initialization:
s_pdf: The "signal" probability distribution function.
b_pdf: The "background" probability distribution function.
alpha: The signal-background mixing.
Keyword arguments for initialization:
pars [=None]: A list of parameters to pass to the pdf.
nPoints [=100]: The number of points to generate in the sample.
domain [=np.arange(0., 200., 0.5)]: The discretized x values which
may be generated.
rng [=dataGen.randomGenerator]: A flat random number generator with
call signature 'rng.rand(n)'. It must return a numpy array of
length n, containing flat random numbers in the range (0, 1).
'''
def __init__(self, s_pdf, b_pdf, alpha, **kwargs):
# Set generating probability distribution function
self.s_pdf = s_pdf
self.b_pdf = b_pdf
if alpha < 0 or alpha > 1:
raise ValueError('alpha should be between 0 and 1')
self.alpha = alpha
self.pars = kwargs.get('pars', None)
# Set data generation parameters
self.n = kwargs.get('nPoints', 100)
self.x = np.array(kwargs.get('domain', np.arange(0., 200., 0.5)))
if not type(self.x) == np.ndarray:
raise TypeError('Use a list or array to specify the x domain')
self.rng = kwargs.get('rng', randomGenerator)
# initial calculations...
# signal
self.fs_unnormed = self.s_pdf(self.x, self.pars)
self.Fs_unnormed = oStat.A(self.fs_unnormed, oStat.forwardDiff(self.x))
self.fs = self.fs_unnormed / self.Fs_unnormed[-1]
# background
self.fb_unnormed = self.b_pdf(self.x, self.pars)
self.Fb_unnormed = oStat.A(self.fb_unnormed, oStat.forwardDiff(self.x))
self.fb = self.fb_unnormed / self.Fb_unnormed[-1]
# combined
self.f_unnormed = (1. - self.alpha) * self.fb + self.alpha * self.fs
self.F_unnormed = oStat.A(self.f_unnormed, oStat.forwardDiff(self.x))
# normed
self.f = self.f_unnormed / self.F_unnormed[-1]
self.F = self.F_unnormed / self.F_unnormed[-1]
def changeDomain(self, x=0):
''' Changes the x domain to a given numpy array. If x is an integer,
chooses a new domain for which the pdf is non-zero, with x points
discarded at both the beginning and end of the domain. '''
if type(x) == np.ndarray:
self.x = x
else:
nonzero = self.x[self.f.nonzero()]
self.x = np.linspace(nonzero[x], nonzero[-1-x], len(self.x))
# reinitialize
# signal
self.fs_unnormed = self.s_pdf(self.x, self.pars)
self.Fs_unnormed = oStat.A(self.fs_unnormed, oStat.forwardDiff(self.x))
self.fs = self.fs_unnormed / self.Fs_unnormed[-1]
# background
self.fb_unnormed = self.b_pdf(self.x, self.pars)
self.Fb_unnormed = oStat.A(self.fb_unnormed, oStat.forwardDiff(self.x))
self.fb = self.fb_unnormed / self.Fb_unnormed[-1]
# combined
self.f_unnormed = (1. - self.alpha) * self.fb + self.alpha * self.fs
self.F_unnormed = oStat.A(self.f_unnormed, oStat.forwardDiff(self.x))
# normed
self.f = self.f_unnormed / self.F_unnormed[-1]
self.F = self.F_unnormed / self.F_unnormed[-1]
diff --git a/debinningMath/plotting.py b/debinningMath/plotting.py
index 4ce9ebb..aaf41a2 100644
--- a/debinningMath/plotting.py
+++ b/debinningMath/plotting.py
@@ -1,247 +1,256 @@
'''
plotting.py
Handy utilities for debinning plots with matplotlib.
Copyright (C) 2015 Abram Krislock
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0.txt.
'''
import numpy as np
import bisect
from matplotlib import pyplot as plt
import debinningMath.orderStatistics as oStat
from debinningCore import settings
class HistoContainer(object):
''' A histogram as a container.
Arguments:
binEdges: A numpy array containing the locations of the bin edges.
data: Initial data to fill the histogram. Data values may also be
added one at a time with addValue(value).
normed: Whether or not to normalize the histogram when plotting.
'''
def __init__(self, binEdges, data=None, normed=False):
self.binEdges = binEdges
self.binContents = np.zeros(len(binEdges)-1)
self.area = None
self.maxi = None
if type(data) in [list, tuple, np.ndarray]:
for value in data:
self.addValue(value)
self.normed = normed
def __len__(self):
return len(self.binContents)
def __call__(self, value):
self.addValue(value)
def integral(self):
''' Returns the total integration over the entire histogram. '''
if self.area == None:
self.area = np.sum(self.binContents * oStat.forwardDiff(self.binEdges))
return self.area
def maximum(self):
''' Returns the content of the histogram bin with maximum content. '''
if self.maxi == None:
self.maxi = np.max(self.binContents)
if self.maxi > 0:
return self.maxi
else:
return np.infty
def normalize(self, norm=np.infty):
''' Normalize the histogram contents. '''
if norm == 'fwhm':
self.binContents /= (self.maximum() / 2)
elif norm < np.infty:
self.binContents /= norm
else:
self.binContents /= self.integral()
# demand that integral() and maximum() must recalculate
self.maxi = None
self.area = None
def fwhm(self):
''' Obtain the Full Width at Half Maximum for this histogram. '''
self.normalize('fwhm')
if self.maximum() == np.infty:
return (-np.infty, np.infty)
lower = np.infty
upper = -np.infty
for bindex in xrange(len(self)):
if self.binContents[bindex] >= 1.:
if self.binEdges[bindex+1] > upper:
upper = self.binEdges[bindex+1]
if self.binEdges[bindex] < lower:
lower = self.binEdges[bindex]
return (lower, upper)
def plot(self, **kwargs):
''' Plots the result, filling under the 'histogram'.
Passes **kwargs on to the matplotlib.pyplot.fill_between function.
Returns a proxy matplotlib.patches.Rectangle for legend control.
'''
if self.normed:
self.normalize()
x = np.sort(np.concatenate((self.binEdges, self.binEdges)))
y = np.array([[value, value] for value in self.binContents / self.integral()])
y = np.concatenate(([1e-6], y.flatten(), [1e-6]))
plt.fill_between(x, y, 1e-6, **kwargs)
return Rectangle((0, 0), 1, 1, fill=True, **kwargs)
def addValue(self, value):
''' Insert a value, or set of values, into the histogram. '''
if type(value) in [list, tuple, np.ndarray]:
for v in value:
self.addValue(v)
else:
# demand that integral() and maximum() must recalculate
self.area = None
self.maxi = None
# bisect_left(x, datum) locates the left-most entry in x which is >= datum
index = bisect.bisect_left(self.binEdges, value) - 1
if index == -1:
if settings.debug:
raise ValueError('HistoContainer warning: Underflow')
elif index >= len(self.binContents):
if settings.debug:
raise ValueError('HistoContainer warning: Overflow')
else:
self.binContents[index] += 1
class Histo2dContainer(object):
''' A 2d histogram as a container.
Arguments:
binEdgesX: A numpy array containing the x-values of the bin edges.
binEdgesY: A numpy array containing the y-values of the bin edges.
normed: Whether or not to normalize the histogram when plotting.
Data may be added one ordered pair at a time with "addValue((x,y))".
'''
def __init__(self, binEdgesX, binEdgesY, normed=False):
self.binEdgesX = binEdgesX
self.binEdgesY = binEdgesY
self.binContents = np.zeros((len(binEdgesX)-1, len(binEdgesY)-1))
self.volume = None
self.maxi = None
self.normed = normed
def __len__(self):
return len(self.binContents)
def __call__(self, orderedPair):
self.addValue(orderedPair)
def integral(self):
''' Returns the total integration over the entire histogram. '''
if self.volume == None:
dx, dy = np.meshgrid(np.diff(self.binEdgesX), np.diff(self.binEdgesY),
indexing='ij')
self.volume = np.sum(self.binContents * dx * dy)
return self.volume
def maximum(self):
''' Returns the content of the histogram bin with maximum content. '''
if self.maxi == None:
self.maxi = np.max(self.binContents)
if self.maxi > 0:
return self.maxi
else:
return np.infty
def normalize(self, norm=np.infty):
''' Normalize the histogram contents. '''
if norm == 'fwhm':
self.binContents /= (self.maximum() / 2)
elif norm < np.infty:
self.binContents /= norm
else:
self.binContents /= self.integral()
# demand that integral() and maximum() must recalculate
self.maxi = None
self.volume = None
def plot(self, axis, **kwargs):
''' Plots the result, filling under the 'histogram'.
Arguments:
axis: An existing matplotlib 3d axis object on which to plot.
Passes **kwargs on to the matplotlib.pyplot.plot_surface function.
Returns a proxy matplotlib.patches.Rectangle for legend control.
'''
if self.normed:
self.normalize()
+ cmap = kwargs.pop('cmap', None)
+ if cmap != None:
+ plotmax = np.max(self.binContents)
+ plotmin = np.min(self.binContents)
for i in np.arange(len(self.binEdgesX)-1):
for j in np.arange(len(self.binEdgesY)-1):
x = np.linspace(self.binEdgesX[i], self.binEdgesX[i+1], 10)
y = np.linspace(self.binEdgesY[j], self.binEdgesY[j+1], 10)
xx, yy = np.meshgrid(x, y, indexing='ij')
zz = np.ones_like(xx) * self.binContents[i,j]
- axis.plot_surface(xx, yy, zz, **kwargs)
+ if cmap != None:
+ kwargs.pop('color', None)
+ colorfloat = (self.binContents[i,j] - plotmin) / (plotmax - plotmin)
+ axis.plot_surface(xx, yy, zz, color=cmap(colorfloat), **kwargs)
+ else:
+ axis.plot_surface(xx, yy, zz, **kwargs)
def addValue(self, orderedPair):
''' Insert an ordered pair, (x,y), into the histogram. '''
# demand that integral() and maximum() must recalculate
self.volume = None
self.maxi = None
# bisect_left(x, datum) locates the left-most entry in x which is >= datum
i = bisect.bisect_left(self.binEdgesX, orderedPair[0]) - 1
j = bisect.bisect_left(self.binEdgesY, orderedPair[1]) - 1
if i == -1:
if settings.debug:
raise ValueError('HistoContainer warning: X Underflow')
if j == -1:
if settings.debug:
raise ValueError('HistoContainer warning: Y Underflow')
if i >= len(self.binEdgesX)-1:
if settings.debug:
raise ValueError('HistoContainer warning: X Overflow')
if j >= len(self.binEdgesY)-1:
if settings.debug:
raise ValueError('HistoContainer warning: Y Overflow')
if all([i >= 0, j >= 0, i < len(self.binEdgesX)-1, i < len(self.binEdgesY)-1]):
self.binContents[i,j] += 1
def verticalColorBand(histo, x, dx, colors=None):
''' Plot the result of a debinning Monte Carlo as colored uncertainty bands:
This function adds one histogram, painted as a vertical band of color.
The band is a rectangle of width [x-0.5dx, x+0.5dx].
'''
if not type(histo) == HistoContainer:
raise TypeError('Please provide a HistoContainer instance for "histo"')
if colors == None:
colors = np.array([(1.,1.,0.), (1.,0.,0.), (1.,1.,1.), (0.,0.,1.)])
# Special normalization to show FWHM transition.
histo.normalize('fwhm')
# Horizontal width of the band.
base = np.array([x-dx/2, x+dx/2])
for bindex in xrange(len(histo)):
upper = np.array([histo.binEdges[bindex+1], histo.binEdges[bindex+1]])
lower = np.array([histo.binEdges[bindex], histo.binEdges[bindex]])
value = histo.binContents[bindex]
if value >= 1.:
color = tuple((value - 1.) * colors[0] + (2. - value) * colors[1])
alp = 1.
else:
color = tuple((value) * colors[2] + (1. - value) * colors[3])
alp = 0.35
if value > 0.1:
plt.fill_between(base, upper, lower,
edgecolor='none', facecolor=color, alpha=alp, zorder=2)
diff --git a/examples/nfrDemo.py b/examples/nfrDemo.py
index d4abc1a..ba66997 100644
--- a/examples/nfrDemo.py
+++ b/examples/nfrDemo.py
@@ -1,89 +1,89 @@
'''
nfrDemo.py
Demonstration of the "rth of n" probability distribution.
Copyright (C) 2015 Abram Krislock
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0.txt.
'''
### Imports
from __future__ import division
import numpy as np
from debinningCore import settings
import debinningMath.dataGen as dataGen
import debinningMath.sampleFunctions as funcs
import debinningMath.orderStatistics as oStat
from matplotlib import pyplot as plt
###
nPulls = settings.nfrDemoPulls
gen = dataGen.DataGenContainer(funcs.endpointPlusBG, nPoints=nPulls)
fit = dataGen.DataGenContainer(funcs.endpointBG, nPoints=nPulls)
bgf_plot = fit.f_unnormed / gen.F_unnormed[-1]
pullData = {index:[] for index in xrange(nPulls)}
for iteration in xrange(2000):
for i,v in enumerate(gen.generate(True)):
pullData[i].append(v)
ithPDF = {}
for i in xrange(1, nPulls+1):
- ithPDF[i-1] = np.array([gen.f[j] * gen.F[j]**(i-1) * (1 - gen.F[j])**(nPulls-i)
- * oStat.nKr(nPulls, i) for j in xrange(len(gen.x))])
+ ithPDF[i-1] = (gen.f * gen.F**(i-1) * (1 - gen.F)**(nPulls-i)
+ * oStat.nKr(nPulls, i))
def nfrPlot(i=0):
fig, axes = plt.subplots(figsize=(9,5), facecolor='#ffffff')
plot_f, = plt.plot(gen.x, gen.f, '--', color='#0088ff', alpha=0.6,
label=r's+bg PDF', linewidth=3)
plot_bgf, = plt.plot(gen.x, bgf_plot, '-.', color='#0088ff', alpha=0.6,
label=r'bg PDF', linewidth=3)
plot_hist = ( plt.hist(pullData[i], bins=np.arange(0, 201, 5), color='#66a61e',
alpha=0.4, normed=True,
label=r'$%i$ of $%i$ data' % (i+1, nPulls)) )[2][0]
plot_nfr, = plt.plot(gen.x, ithPDF[i], '#964a01', linewidth=3,
label=r'${}_{%i} f_{%i}$' % (nPulls, i+1))
axes.set_xticks(np.arange(0, 201, 50))
axes.set_xticks(np.arange(0, 201, 10), minor=True)
axes.set_xticklabels([r'$%i$' % int(num) for num in np.arange(0, 201, 50)],
fontsize=20)
axes.set_ylim(bottom=-0.0001, top=0.0401)
axes.set_yticks(np.arange(0, 0.04, 0.01))
axes.set_yticklabels([r'$%0.3f$' % num for num in np.arange(0, 0.04, 0.01)],
fontsize=20)
axes.set_yticks(np.arange(0, 0.04, 0.01/5), minor=True)
axes.set_xlabel('Physical Observable', labelpad=5, fontsize=22)
axes.set_ylabel('Probability', labelpad=5, fontsize=22)
axes.tick_params(length=10, width=1.2, labelsize=22, zorder=10, pad=10)
axes.tick_params(which='minor', length=5, width=1.2, zorder=11)
axes.minorticks_on()
plt.legend((plot_hist, plot_nfr, plot_f, plot_bgf),
(plot_hist.get_label(), plot_nfr.get_label(), plot_f.get_label(),
plot_bgf.get_label()),
shadow=True, loc='best', prop={'size':26},
labelspacing=0.25, handlelength=1.2, handletextpad=0.35)
if __name__ == '__main__':
print 'Now running the "Being rth of n" demonstration...'
plt.ion()
for i in xrange(nPulls):
nfrPlot(i)
print 'Done.\n\n'
diff --git a/examples/nfrVrHDemo.py b/examples/nfrVrHDemo.py
new file mode 100644
index 0000000..2d55baf
--- /dev/null
+++ b/examples/nfrVrHDemo.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+'''
+nfrVrHDemo.py
+Demonstration of the 2d "r_V and r_H of n" probability distribution.
+
+Copyright (C) 2015 Abram Krislock
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0.txt.
+'''
+
+### Imports
+from __future__ import division
+import numpy as np
+from mpl_toolkits.mplot3d import axes3d
+from matplotlib import pyplot as plt
+from matplotlib import cm
+from time import time
+import argparse
+
+from debinningCore import settings
+import debinningMath.dataGen as dataGen
+import debinningMath.sampleFunctions as funcs
+import debinningMath.orderStatistics as oStat
+from debinningMath.plotting import Histo2dContainer as Hist2d
+###
+
+def nfrVrHPlot(r_V, r_H):
+ t = time()
+ nPulls = settings.nfrDemoPulls
+ gen = dataGen.DataGen2dContainer(funcs.footballBumpBG, nPoints=nPulls,
+ domain=(np.arange(0, 200.1, 1), np.arange(0, 200.1, 1)))
+
+ hist = Hist2d(np.arange(0, 200.1, 10.), np.arange(0, 200.1, 10.), True)
+ for iteration in xrange(2000000):
+ for i,v in enumerate(gen.generate(True)):
+ if gen.r_Varray[i] == r_V-1 and gen.r_Harray[i] == r_H-1:
+ hist.addValue(v)
+
+ nfrVrH = (oStat.nKr(nPulls, r_V) * oStat.nKr(nPulls, r_H) * gen.F_V**(r_V-1)
+ * gen.F_H**(r_H-1) * (1 - gen.F_V)**(nPulls-r_V)
+ * (1 - gen.F_H)**(nPulls-r_H) * gen.f_V)
+ print 'Calculations finished after', (time() - t), 'seconds.\n'
+
+ fig = plt.figure(figsize=(22,14))
+ ax = fig.add_subplot(111, projection='3d')
+ ax.plot_wireframe(gen.xx, gen.yy, nfrVrH, rstride=5, cstride=5, cmap=cm.jet)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+ hist.plot(ax, cmap=cm.jet, alpha=0.4)
+ plt.show()
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Being r_V and r_H of n')
+ parser.add_argument('r_V', help='r_V is an integer between 1 and n', type=int)
+ parser.add_argument('r_H', help='r_H is an integer between 1 and n', type=int)
+ args = parser.parse_args()
+ nfrVrHPlot(args.r_V, args.r_H)
+ print 'Done.\n\n'
diff --git a/examples/test2d.py b/examples/test2d.py
deleted file mode 100644
index b2103ae..0000000
--- a/examples/test2d.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from debinningMath import dataGen
-from debinningMath import sampleFunctions
-from debinningMath import plotting
-
-from mpl_toolkits.mplot3d import axes3d
-import matplotlib.pyplot as plt
-import numpy as np
-
-gen = dataGen.DataGen2dContainer( sampleFunctions.footballBumpBG, nPoints=10000,
- domain=(np.arange(0, 200.1, 1),
- np.arange(0, 200.1, 1)) )
-
-fig = plt.figure(figsize=(22,14))
-ax = fig.add_subplot(111, projection='3d')
-ax.plot_wireframe(gen.xx, gen.yy, gen.f_V, rstride=5, cstride=5)
-ax.set_xlabel('X')
-ax.set_ylabel('Y')
-ax.set_zlabel('Z')
-
-gen.generate()
-hist = plotting.Histo2dContainer(np.arange(0, 200.1, 10.),
- np.arange(0, 200.1, 10.), True)
-for orderedPair in gen.data:
- hist.addValue(orderedPair)
-hist.plot(ax, color='r', alpha=0.4, edgecolors='r')
-
-plt.show()
-
-# YAY! This works. I can verify that data generation is now working as expected
-# using my current A_H and A_V operators. However, they are slow, so I should
-# rethink what they actually do, and try to optimize them.
-#
-# Once they are optimized for a decent amount of speed, I will test my nfrVrH idea.
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Apr 24, 6:31 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4881375
Default Alt Text
(29 KB)
Attached To
rDEBINNINGGIT debinninggit
Event Timeline
Log In to Comment