def _h1_cmp_dist_ ( h1 , h2 , rescale = False ) : """Calculate the norm of difference of scaled histograms/functions |f1-f2|, such |f1|=1 and |f2|=1 >>> h1 = ... ## the first histo >>> h2 = ... ## the second histo >>> diff = h1.cmp_dist ( h2 ) """ if rescale : h1_ = h1.rescale_bins ( 1.0 ) h2_ = h2.rescale_bins ( 1.0 ) res = _h1_cmp_dist_ ( h1_ , h2_ , rescale = False ) del h1_, h2_ return res f1 = h1.asFunc () f2 = h2.asFunc () lims = h1.xminmax() from ostap.math.integral import integral as _integral_ r1 = _integral_ ( lambda x : f1 ( x )**2 , lims[0] , lims[1] , limit = 200 , err = True ) r2 = _integral_ ( lambda x : f2 ( x )**2 , lims[0] , lims[1] , limit = 200 , err = True ) import math sf1 = 1.0 / math.sqrt ( r1.value() ) sf2 = 1.0 / math.sqrt ( r2.value() ) d12 = _integral_ ( lambda x : (sf1*f1(x)-sf2*f2(x))**2 , lims[0] , lims[1] , limit = 200 , err = True ) return d12
def _h1_cmp_costheta_(h1, h2, density=False): """Compare the 1D-historgams (as functions) Calculate scalar product and get ``the angle'' from it >>> h1 = ... ## the first histo >>> h2 = ... ## the second histo >>> cos_theta = h1.cmp_costheta ( h2 ) """ if density: h1_ = h1.density() h2_ = h2.density() cmp = _h1_cmp_costheta_(h1_, h2_, density=False) del h1_ del h2_ return cmp f1 = h1.asFunc() f2 = h2.asFunc() lims = h1.xminmax() from ostap.math.integral import integral as _integral_ vr1 = _integral_(lambda x: f1(x)**2, lims[0], lims[1], limit=200, err=True) vr2 = _integral_(lambda x: f2(x)**2, lims[0], lims[1], limit=200, err=True) vr12 = _integral_(lambda x: f1(x) * f2(x), lims[0], lims[1], limit=200, err=True) return vr12 / (vr1 * vr2)**0.5
def _h1_cmp_dist_(h1, h2, density=False): """Calculate the norm of difference of scaled histograms/functions |f1-f2|, such |f1|=1 and |f2|=1 >>> h1 = ... ## the first histo >>> h2 = ... ## the second histo >>> diff = h1.cmp_dist ( h2 ) """ assert isinstance ( h1 , ROOT.TH1 ) and not isinstance ( h1 , ROOT.TH2 ) , \ "cmp_dist: invalid type of h1 %s/%s" % ( h1 , type ( h1 ) ) assert isinstance ( h2 , ROOT.TH1 ) and not isinstance ( h2 , ROOT.TH2 ) , \ "cmp_dist: invalid type of h2 %s/%s" % ( h2 , type ( h2 ) ) if density: h1_ = h1.density() h2_ = h2.density() cmp = _h1_cmp_dist_(h1_, h2_, density=False) del h1_ del h2_ return cmp f1 = h1.asFunc() f2 = h2.asFunc() lims = h1.xminmax() from ostap.math.integral import integral as _integral_ r1 = _integral_(lambda x: f1(x)**2, lims[0], lims[1], limit=200, err=True) r2 = _integral_(lambda x: f2(x)**2, lims[0], lims[1], limit=200, err=True) import math sf1 = 1.0 / math.sqrt(r1.value()) sf2 = 1.0 / math.sqrt(r2.value()) d12 = _integral_(lambda x: (sf1 * f1(x) - sf2 * f2(x))**2, lims[0], lims[1], limit=200, err=True) volume = (lims[1] - lims[0]) return d12 / volume
def _h1_cmp_dist2_(h1, h2, density=False): """Calculate the norm of difference of scaled histograms/functions |(f1-f2)**2/(f1*f2)|, such |f1|=1 and |f2|=1 >>> h1 = ... ## the first histo >>> h2 = ... ## the second histo >>> diff = h1.cmp_dist2 ( h2 ) """ if density: h1_ = h1.density() h2_ = h2.density() cmp = _h1_cmp_dist2_(h1_, h2_, density=False) del h1_ del h2_ return cmp f1 = h1.asFunc() f2 = h2.asFunc() lims = h1.xminmax() from ostap.math.integral import integral as _integral_ r1 = _integral_(lambda x: f1(x)**2, lims[0], lims[1], limit=200, err=True) r2 = _integral_(lambda x: f2(x)**2, lims[0], lims[1], limit=200, err=True) import math sf1 = 1.0 / math.sqrt(r1.value()) sf2 = 1.0 / math.sqrt(r2.value()) def _func_(x): v1 = sf1 * f1(x) v2 = sf2 * f2(x) v = (v1 - v2) * (v1 - v2) / abs(v1 * v2) return v * v d12 = _integral_(_func_, lims[0], lims[1], limit=200, err=True) return d12
def _h1_chi2_cmp_ ( h1 , func , integral = False , select = lambda x,y,v : True , chi2 = lambda v1,v2 : v1.chi2(v2) ) : """Calculate chi2 for histogram and ``function'' >>> h1 = ... ## the first histo >>> func = ... ## the the function >>> chi2ndf,prob = h1.chi2_cmp ( func , integral = False ) """ c2 = 0 ndf = 0 _func_ = lambda x,xl,xr : func(x) if integral and hasattr ( func , 'integral' ) : _func_ = lambda x,xl,xr : func.integral(xl,xr)/(xr-xl) elif integral and hasattr ( func , 'Integral' ) : _func_ = lambda x,xl,xr : func.Integral(xl,xr)/(xr-xl) elif integral : ## use numerical integration from scipy from ostap.math.intergal import integral as _integral_ _func_ = lambda x,xl,xr : _integral_ ( func , xl , xr )/(xr-xl) for entry in h1.iteritems() : x = entry[1] y1 = entry[2] xv = x.value() xe = x.error() xl = xv - xe xr = xv + xe y2 = _func_ ( x , xl , xr ) if not select ( x, y1 , y2 ) : continue c2 += chi2 ( y1 , y2 ) ndf += 1 c2ndf = c2/ndf return c2ndf, ROOT.TMath.Prob( c2 , ndf )