Example #1
0
    def __init__( self, nbins, arg, **kwargs ):
        ''' To initialize the class one has to provide the number of bins that will be used
        in the transformed distribution < nbins > and an argument, that can be a set of
        values or a histogram. If it is a set of values, the option to use the adaptive
        binning technique is set by the < adaptbin > parameter. If no such technique is used,
        one can control the number of bin for the input sample with the input parameter
        < ntrbins >. '''
        
        verbose = kwargs.get( 'verbose', True )

        self.AdaptBin = kwargs.get( 'adaptbin', False )
        if isinstance( arg, TH1 ):
            if verbose:
                print ( 'INFO: After the transformation, all the values greater than one will be ' +
                        'attached to the last bin' )
            if self.AdaptBin:
                print 'WARNING: Adaptive binned method not available with a TH1 object as input'
            self.AdaptBin = False
            self.MainHist = arg
            self.Nbins    = nbins
        else:
            if self.AdaptBin:
                if verbose:
                    print ( 'INFO: The output histogram comes from an adaptive binned transformation. ' +
                            'Is constructed as: x in bin if x > min and x <= max.' )
                
                length = len( arg )
                self.MainHist = MakeAdaptiveBinnedHist( '', length/nbins, arg )
                self.Nbins    = nbins
            
                for val in arg:
                    self.MainHist.Fill( val )
            else:
                ntrbins = kwargs.get( 'ntrbins', 100 )
                self.__init__( nbins, MakeHistogram( arg, nbins = ntrbins ) )
                
        self.CumulativeHist = MakeCumulative( self.MainHist )
Example #2
0
class IntegralTransformer:
    
    def __init__( self, nbins, arg, **kwargs ):
        ''' To initialize the class one has to provide the number of bins that will be used
        in the transformed distribution < nbins > and an argument, that can be a set of
        values or a histogram. If it is a set of values, the option to use the adaptive
        binning technique is set by the < adaptbin > parameter. If no such technique is used,
        one can control the number of bin for the input sample with the input parameter
        < ntrbins >. '''
        
        verbose = kwargs.get( 'verbose', True )

        self.AdaptBin = kwargs.get( 'adaptbin', False )
        if isinstance( arg, TH1 ):
            if verbose:
                print ( 'INFO: After the transformation, all the values greater than one will be ' +
                        'attached to the last bin' )
            if self.AdaptBin:
                print 'WARNING: Adaptive binned method not available with a TH1 object as input'
            self.AdaptBin = False
            self.MainHist = arg
            self.Nbins    = nbins
        else:
            if self.AdaptBin:
                if verbose:
                    print ( 'INFO: The output histogram comes from an adaptive binned transformation. ' +
                            'Is constructed as: x in bin if x > min and x <= max.' )
                
                length = len( arg )
                self.MainHist = MakeAdaptiveBinnedHist( '', length/nbins, arg )
                self.Nbins    = nbins
            
                for val in arg:
                    self.MainHist.Fill( val )
            else:
                ntrbins = kwargs.get( 'ntrbins', 100 )
                self.__init__( nbins, MakeHistogram( arg, nbins = ntrbins ) )
                
        self.CumulativeHist = MakeCumulative( self.MainHist )
    
    def Transform( self, name, arg, **kwargs ):
        ''' Transforms the distribution from the given set of values using the class
        distribution. One must provide the name of the output histogram and an argument.
        This argument can be a histogram or an iterable. The title and the type of histogram
        are set using the < title > and < htype > parameters. '''

        title    = kwargs.get( 'title', name )
        histcall = HistFromType( kwargs.get( 'htype', 'double' ) )
        
        transf = histcall( name, title, self.Nbins, 0, 1 )
        
        '''
        If the argument is an histogram, it creates the list with the values and
        associated weights.
        '''
        if isinstance( arg, TH1 ):
            values = [ ( arg.GetBinCenter( ib ), arg.GetBinContent( ib ) )
                       for ib in xrange( 1, arg.GetNbinsX() + 1 ) ]
        else:
            values = zip( arg, len( arg )*[ 1. ] )

        if self.AdaptBin:
            nbins  = self.MainHist.GetNbinsX()
            blist  = [ self.MainHist.GetBinLowEdge( ib ) for ib in xrange( 1, nbins + 2 ) ]
            bins   = array( 'd', blist )
            abhist = self.MainHist.__class__( '', '', nbins, bins )
            for val, wgt in values:
                abhist.Fill( val, wgt )
            sw = abhist.GetSumOfWeights()
            for ib in xrange( 1, self.MainHist.GetNbinsX() + 1 ):
                cont = abhist.GetBinContent( ib )
                transf.SetBinContent( ib, cont/sw )
                transf.SetBinError( ib, sqrt( cont/sw**2 + sw*cont**2/sw**4 ) )
        else:
            addifone = 1 - transf.GetBinWidth( 1 )/2.
            for val, wgt in values:
                fval = self.CumulativeHist.Interpolate( val )
                if fval != 1:
                    transf.Fill( fval, wgt )
                else:
                    transf.Fill( addifone, wgt )
        
        return transf

    def DeTransfValue( self, value, retallinfo = False ):
        '''
        Returns the de-transformated value associated to that given. If the option
        < retallinfo > is set to True, it will return the bin center and the bin width
        associated with that value.
        '''
        hist    = self.CumulativeHist
        binvals = [ hist.GetBinContent( ib ) for ib in xrange( 1, hist.GetNbinsX() + 1 ) ]
        pos     = bisect( binvals, value ) - 1
        if retallinfo:
            return hist.GetBinCenter( pos ), hist.GetBinWidth( pos )
        else:
            return hist.GetBinCenter( pos )