예제 #1
0
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 
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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 )