Ejemplo n.º 1
0
def fmt_pretty_float(value, width=8, precision=6):
    """Format for nice printout of the floating number
    - return format for nice string and the separate exponent 
    >>> fmt , n = fmt_pretty_float ( number ) 
    """
    from ostap.core.ostap_types import integer_types, num_types

    assert isinstance ( value     , num_types     ),\
           'Invalid value parameter %s/%s'   % ( value , type ( value ) )

    ## not finite?
    from ostap.math.base import isfinite
    if not isfinite(value): return "%s", 0

    assert isinstance ( width     , integer_types ) and \
           isinstance ( precision , integer_types ) and 2 <= precision < width, \
           "Invalid width/precision parameters %s/%s" % ( width , precision )

    v = value
    av = abs(v)
    if 100 <= av < 1000:
        fmt2 = '%%+%d.%df' % (width, precision - 2)
        return fmt2, 0
    elif 10 <= av < 100:
        fmt1 = '%%+%d.%df' % (width, precision - 1)
        return fmt1, 0
    elif 1 <= av < 10:
        fmt0 = '%%+%d.%df' % (width, precision)
        return fmt0, 0
    elif 0.1 <= av < 1:
        fmt0 = '%%+%d.%df' % (width, precision)
        return fmt0, 0

    from ostap.math.base import frexp10, iszero
    if iszero(av):
        fmt0 = '%%+%d.%df' % (width, precision)
        return fmt0, 0

    v_a, v_e = frexp10(v)
    if 0 == v_e and iszero(v_a):
        fmt0 = '%%+0%d.%df' % (width, precision)
        return fmt0, 0

    v_a *= 10
    v_e -= 1

    n, r = divmod(v_e, 3)

    ra = v_a * (10**r)

    fmt, p = fmt_pretty_float(ra, width, precision)

    return fmt, p + 3 * n
Ejemplo n.º 2
0
def pdg_round__ ( value , error ) :
    """Make a rounding according to PDG prescription
    - see http://pdg.lbl.gov/2010/reviews/rpp2010-rev-rpp-intro.pdf
    - see section 5.3 of doi:10.1088/0954-3899/33/1/001
    
    Quote: 
    The basic rule states that if the three highest order digits of the error
    lie between 100 and 354, we round to two significant digits. If they lie between
    355 and 949, we round to one significant digit. Finally,
    if they lie between 950 and 999, we round up to 1000 and keep two significant digits.
    In all cases, the central value is given with a precision that matches that of the error.
    
    >>> val , err , exponent , err_case = pdg_round__ ( value , error )    
    >>> print ( ' Rounded value +/- error is  (%s +/- %s)' % ( val , err ) ) 
    """

    ecase , err = pdg_case ( error )

    assert -2 <= ecase <= 3 ,\
           'pdg_round: invalid error case %s/%s' %  ( ecase , error ) 

    ## irregular casses :
    if ecase <= 0 or not isfinite ( value ) : 
        return value , error , 0 , ecase

    ## regular error 
    ee , be = _frexp10_ ( error )
    
    if   1 == ecase : q = be + 1 - 2
    elif 2 == ecase : q = be + 1 - 1
    elif 3 == ecase : q = be + 1 - 2

    r   = 10 ** q 
    val = round ( float ( value ) / r ) * r * 1.0 

    return val , err , q , ecase
Ejemplo n.º 3
0
def pdg_format3( value , error1 , error2 , error3 , latex = False , mode = 'total' ) :
    """Round value/error accoridng to PDG prescription and format it for print
    @see http://pdg.lbl.gov/2010/reviews/rpp2010-rev-rpp-intro.pdf
    @see section 5.3 of doi:10.1088/0954-3899/33/1/001
      
    Quote:
    
    The basic rule states that
    - if the three highest order digits of the error lie between 100 and 354, we round to two significant digits.
    - If they lie between 355 and 949, we round to one significant digit.
    - Finally, if they lie between 950 and 999, we round up to 1000 and keep two significant digits.
    In all cases, the central value is given with a precision that matches that of the error.
    
    >>> value, error1, error2 = ...
    >>> print ' Rounded value/error is %s ' % pdg_format2 ( value , error1 , error2 , True ) 
    """

    error = ref_error ( mode , error1 , error2 , error3 ) 

    val , err , q , ecase = pdg_round__ ( value , error )  
   
    if ecase <= 0 or  ( not isfinite ( error1 ) ) or ( not isfinite ( error2 ) ) or ( not isfinite ( error3 ) ) :
        
        if not isfinite ( val ) : 
            return ( '%+g \\pm %-g \\pm %-g \\pm %-g ' % ( val , error1 , error2 , error3 ) ) if latex else \
                   ( '%+g +/- %-g +/- %-g +/- %-g'     % ( val , error1 , error2 , error3 ) ) 
        
        else :

            qv , bv = _frexp10_ ( val )
            if 0 != bv :
                scale = 1.0 / 10**bv 
                if latex : return '(%+.2f \\pm %-s \\pm %-s)\\times 10^{%d}' % ( qv , error1 * scale , error2 * scale , error3 * scale , bv )
                else     : return ' %+.2f +/- %-s +/ %-s +/- %-s )*10^{%d} ' % ( qv , error1 * scale , error2 * scale , error3 * scale , bv )
            else :  
                if latex : return ' %+.2f \\pm %-s \\pm %-s \\pm %-s ' % ( qv , error1 , error2 , error3 )
                else     : return ' %+.2f +/- %-s +/- %-s +/- %-s '    % ( qv , error1 , error2 , error3 )



    qe , be = _frexp10_ ( error )                
    a , b = divmod ( be , 3 ) 
        

    if   1 == ecase :

        err1 = round_N ( error1 , 2 ) if isclose ( error1 , error , 1.e-2 ) else err  
        err2 = round_N ( error2 , 2 ) if isclose ( error2 , error , 1.e-2 ) else err  
        err3 = round_N ( error3 , 2 ) if isclose ( error3 , error , 1.e-2 ) else err  
        
        if   0 == b :
            nd = 1
        elif 1 == b :
            nd  = 3
            a  += 1 
        elif 2 == b :
            a  += 1 
            nd = 2

    elif 2 == ecase :

        err1 = round_N ( error1 , 1 ) if isclose ( error1 , error , 1.e-2 ) else err  
        err2 = round_N ( error2 , 1 ) if isclose ( error2 , error , 1.e-2 ) else err  
        err3 = round_N ( error3 , 1 ) if isclose ( error3 , error , 1.e-2 ) else err  

        if   0 == b :
            nd = 0
            
            if 2 == a % 3 :
                nd = 3
                a  = a + 1 
                
        elif 1 == b :            
            nd = 2
            a += 1
            
        elif 2 == b :
            nd = 1
            a += 1

    elif 3 == ecase :
        
        err1 = round_N ( error1 , 2 ) if isclose ( error1 , error , 1.e-2 ) else err  
        err2 = round_N ( error2 , 2 ) if isclose ( error2 , error , 1.e-2 ) else err  
        err3 = round_N ( error3 , 2 ) if isclose ( error3 , error , 1.e-2 ) else err  

        if   0 == b :
            nd = 0
            
            if 2 == a % 3 :
                nd = 3 
                a  = a + 1
                
        elif 1 == b :
            nd = 2
            a += 1 
        elif 2 == b :
            nd = 1
            a += 1 

    if 0 == a :
        
        if latex: fmt = '(%%+.%df \\pm %%.%df \\pm %%.%df \\pm %%.%df)' %  ( nd , nd , nd , nd ) 
        else    : fmt = ' %%+.%df +/- %%.%df +/- %%.%df +/- %%.%df '    %  ( nd , nd , nd . nd )

        return fmt % ( val , err )

        
    if latex: fmt = '(%%+.%df \\pm %%.%df \\pm %%.%df \\pm %%.%df)\\times 10^{%%d}' %  ( nd , nd , nd , nd ) 
    else    : fmt = '(%%+.%df +/- %%.%df +/- %%.%df +/- %%.%df)*10^{%%d}'          %  ( nd , nd , nd , nd ) 
        
        
    scale = 1.0/10**(3*a)

    return fmt % ( val * scale , err1 * scale , err2 * scale , err3 * scale , 3 * a )