コード例 #1
0
def age_equation(j,
                 f,
                 include_decay_error=False,
                 lambda_k=None,
                 arar_constants=None):
    if isinstance(j, tuple):
        j = ufloat(*j)
    elif isinstance(j, str):
        j = ufloat(j)

    if isinstance(f, tuple):
        f = ufloat(*f)
    elif isinstance(f, str):
        f = ufloat(f)

    if not lambda_k:
        if arar_constants is None:
            arar_constants = ArArConstants()
        lambda_k = arar_constants.lambda_k

    if arar_constants is None:
        arar_constants = ArArConstants()

    if not include_decay_error:
        lambda_k = nominal_value(lambda_k)
    try:

        # lambda is defined in years, so age is in years
        age = lambda_k**-1 * umath.log(1 + j * f)

        return arar_constants.scale_age(age, current='a')
    except (ValueError, TypeError):
        return ufloat(0, 0)
コード例 #2
0
def age_equation(j,
                 f,
                 include_decay_error=False,
                 lambda_k=None,
                 scalar=None,
                 arar_constants=None):
    if isinstance(j, tuple):
        j = ufloat(*j)
    elif isinstance(j, str):
        j = ufloat(j)

    if isinstance(f, tuple):
        f = ufloat(*f)
    elif isinstance(f, str):
        f = ufloat(f)

    if not lambda_k:
        if arar_constants is None:
            arar_constants = ArArConstants()
        lambda_k = arar_constants.lambda_k

    if not scalar:
        if arar_constants is None:
            arar_constants = ArArConstants()
        scalar = float(arar_constants.age_scalar)

    if not include_decay_error:
        lambda_k = nominal_value(lambda_k)
    try:
        return (lambda_k**-1 * umath.log(1 + j * f)) / scalar
    except (ValueError, TypeError):
        return ufloat(0, 0)
コード例 #3
0
def interference_corrections(a39, a37, production_ratios, arar_constants=None, fixed_k3739=False):
    if production_ratios is None:
        production_ratios = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    pr = production_ratios
    if arar_constants.k3739_mode.lower() == 'normal' and not fixed_k3739:

        ca3937 = pr.get('Ca3937', 0)
        k3739 = pr.get('K3739', 0)
        k39 = (a39 - ca3937 * a37) / (1 - k3739 * ca3937)
        k37 = pr.get('K3739', 0) * k39

        ca37 = a37 - k37
        ca39 = pr.get('Ca3937', 0) * ca37
    else:
        if not fixed_k3739:
            fixed_k3739 = arar_constants.fixed_k3739

        ca37, ca39, k37, k39 = apply_fixed_k3739(a39, pr, fixed_k3739)

    k38 = pr.get('K3839', 0) * k39

    if not arar_constants.allow_negative_ca_correction:
        ca37 = max(ufloat(0, 0), ca37)

    ca36 = pr.get('Ca3637', 0) * ca37
    ca38 = pr.get('Ca3837', 0) * ca37

    return k37, k38, k39, ca36, ca37, ca38, ca39
コード例 #4
0
    def calculate(self, age, sensitivity, k2o):
        c = ArArConstants()
        xs = np.linspace(self.start, self.end)
        ys = np.array([self._calculate(wi, age, sensitivity, k2o, c) for wi in xs])


#        nxs = np.linspace(max(1e-2, 0), self.end)
#        n40 = np.linspace(max(1, ys[0]), ys[-1])
        n40 = ys[:]
        if ys[0] == 0:
            n40 = n40[1:]

#        r4039 = 7.78
        n39 = n40 / self.r4039
#        nys = ys[:]
#        print nys
#            nys = np.hstack(([1], nys[1:]))
#        print nys
        p = (0.0021435788651550671, -0.48505328994128016)
        e40_scalar = 3
        e39 = powerlaw(p, n39)
        e40 = powerlaw(p, n40) * e40_scalar

        es = (e39 ** 2 + e40 ** 2) ** 0.5
#        es = age * 1e3 * es
#        es = 0.2 * nys ** (-0.5)

        return xs, ys, n40, es * 100
コード例 #5
0
ファイル: argon_calculations.py プロジェクト: sgallet/pychron
def calculate_atmospheric(a38,
                          a36,
                          k38,
                          ca38,
                          ca36,
                          decay_time,
                          production_ratios=None,
                          arar_constants=None):
    """
        McDougall and Harrison
        Roddick 1983
        Foland 1993

        iteratively calculate atm36
    """
    if production_ratios is None:
        production_ratios = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    pr = production_ratios

    m = pr.get('cl3638',
               0) * arar_constants.lambda_Cl36.nominal_value * decay_time
    atm36 = ufloat(0, 1e-20)
    for _ in range(5):
        ar38atm = arar_constants.atm3836.nominal_value * atm36
        cl38 = a38 - ar38atm - k38 - ca38
        cl36 = cl38 * m
        atm36 = a36 - ca36 - cl36
    return atm36, cl36
コード例 #6
0
    def calculate(self, age, sensitivity, k2o):
        c = ArArConstants()
        xs = np.linspace(self.start, self.end)

        def to_weight(d, depth, rho):
            '''
                d== mm
                depth==mm
                rho==kg/m^3
            '''
            # convert dimension to meters
            d = d / 1000.
            depth = depth / 1000.
            if self.shape == 'circle':
                v = math.pi * (d / 2.) ** 2 * depth
            else:
                v = d ** 2 * depth

            m = rho * v
            # convert mass to mg 1e6 mg in 1 kg
            return m * 1e6

        # convert dim to weight
        ws = [to_weight(di, self.depth, self.rho) for di in xs]

        ys = [self._calculate(wi, age, sensitivity, k2o, c) for wi in ws]
        return xs, ys, xs, ws
コード例 #7
0
def calculate_f(isotopes, decay_time, interferences=None, arar_constants=None, fixed_k3739=False):
    """
        isotope values corrected for blank, baseline, (background)
        ic_factor, (discrimination), ar37 and ar39 decay

    """
    a40, a39, a38, a37, a36 = isotopes

    def calc_f(pr):
        k37, k38, k39, ca36, ca37, ca38, ca39 = interference_corrections(a39, a37, pr, arar_constants, fixed_k3739)
        atm36, cl36, cl38 = calculate_atmospheric(a38, a36, k38, ca38, ca36,
                                                  decay_time,
                                                  pr,
                                                  arar_constants)

        # calculate radiogenic
        trapped_4036 = copy(arar_constants.atm4036)
        trapped_4036.tag = 'trapped_4036'
        atm40 = atm36 * trapped_4036

        k4039 = pr.get('K4039', 0)
        k40 = k39 * k4039

        rad40 = a40 - atm40 - k40
        try:
            ff = rad40 / k39
        except ZeroDivisionError:
            ff = ufloat(1.0, 0)

        nar = {'k40': k40, 'ca39': ca39, 'k38': k38, 'ca38': ca38,
               'cl38': cl38, 'k37': k37, 'ca37': ca37, 'ca36': ca36,
               'cl36': cl36}
        try:
            rp = rad40 / a40 * 100
        except ZeroDivisionError:
            rp = ufloat(0, 0)

        comp = {'rad40': rad40, 'a40': a40, 'radiogenic_yield': rp,
                'ca37': ca37, 'ca39': ca39, 'ca36': ca36, 'k39': k39,
                'atm40': atm40}

        ifc = {'Ar40': a40 - k40, 'Ar39': k39, 'Ar38': a38, 'Ar37': a37, 'Ar36': atm36}
        return ff, nar, comp, ifc

    if interferences is None:
        interferences = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    # make local copy of interferences
    pr = {k: ufloat(nominal_value(v), std_dev=0, tag=v.tag) for k, v in interferences.items()}

    f_wo_irrad, _, _, _ = calc_f(pr)
    f, non_ar_isotopes, computed, interference_corrected = calc_f(interferences)

    return f, f_wo_irrad, non_ar_isotopes, computed, interference_corrected
コード例 #8
0
 def __init__(self, *args, **kw):
     super(ArArAge, self).__init__(*args, **kw)
     self.arar_constants = ArArConstants()
     self.isotopes = {}
     self.non_ar_isotopes = {}
     self.computed = {}
     self.corrected_intensities = {}
     self.interference_corrections = {}
     self.production_ratios = {}
     self.temporary_ic_factors = {}
     self.discrimination = ufloat(1, 0)
コード例 #9
0
ファイル: argon_calculations.py プロジェクト: sgallet/pychron
def calculate_error_t(F, ssF, j, ssJ):
    '''
        McDougall and Harrison
        p92 eq. 3.43
    '''
    JJ = j * j
    FF = F * F
    constants = ArArConstants()
    ll = constants().lambdak.nominal_value**2
    sst = (JJ * ssF + FF * ssJ) / (ll * (1 + F * j)**2)
    return sst**0.5
コード例 #10
0
def calculate_atmospheric(a38,
                          a36,
                          k38,
                          ca38,
                          ca36,
                          decay_time,
                          production_ratios=None,
                          arar_constants=None):
    """
        McDougall and Harrison
        Roddick 1983
        Foland 1993

        calculate atm36, cl36, cl38

        # starting with the following equations
        atm36 = a36 - ca36 - cl36

        m = cl3638*lambda_cl36*decay_time
        cl36 = cl38 * m

        cl38 = a38 - k38 - ca38 - ar38atm
        ar38atm = atm3836 * atm36

        # rearranging to solve for atm36
        cl38 = a38  - k38 - c38 - atm3836 * atm36

        cl36 = m * (a38  - k38 - ca38 - atm3836 * atm36)
             = m (a38  - k38 - ca38) - m * atm3836 * atm36
        atm36 = a36 - ca36 - m (a38  - k38 - ca38) + m * atm3836 * atm36
        atm36 - m * atm3836 * atm36 =  a36 - ca36 - m (a38  - k38 - ca38)
        atm36 * (1 - m*atm3836) = a36 - ca36 - m (a38  - k38 - ca38)
        atm36 = (a36 - ca36 - m (a38  - k38 - c38))/(1 - m*atm3836)


    """
    if production_ratios is None:
        production_ratios = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    pr = production_ratios
    m = pr.get('Cl3638', 0) * nominal_value(
        arar_constants.lambda_Cl36) * decay_time
    atm3836 = nominal_value(arar_constants.atm3836)
    atm36 = (a36 - ca36 - m * (a38 - k38 - ca38)) / (1 - m * atm3836)
    ar38atm = atm3836 * atm36
    cl38 = a38 - ar38atm - k38 - ca38
    cl36 = cl38 * m

    return atm36, cl36, cl38
コード例 #11
0
ファイル: argon_calculations.py プロジェクト: sgallet/pychron
def interference_corrections(a40,
                             a39,
                             a38,
                             a37,
                             a36,
                             production_ratios,
                             arar_constants=None):
    if production_ratios is None:
        production_ratios = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    pr = production_ratios

    k37 = ufloat(0, 1e-20)
    if arar_constants.k3739_mode.lower() == 'normal':
        # iteratively calculate 37, 39
        for _ in range(5):
            ca37 = a37 - k37
            ca39 = pr.get('ca3937', 0) * ca37
            k39 = a39 - ca39
            k37 = pr.get('k3739', 0) * k39
    else:
        '''
            x=ca37/k39
            y=ca37/ca39
            T=s39dec_cor

            T=ca39+k39
            T=ca37/y+ca37/x

            ca37=(T*x*y)/(x+y)
        '''
        x = arar_constants.fixed_k3739
        y = 1 / pr.get('ca3937', 1)

        ca37 = (a39 * x * y) / (x + y)
        ca39 = pr.get('ca3937', 0) * ca37
        k39 = a39 - ca39
        k37 = x * k39

    k38 = pr.get('k3839', 0) * k39
    ca36 = pr.get('ca3637', 0) * ca37
    ca38 = pr.get('ca3837', 0) * ca37

    return k37, k38, k39, ca36, ca37, ca38, ca39
コード例 #12
0
ファイル: argon_calculations.py プロジェクト: sgallet/pychron
def age_equation(j, f, include_decay_error=False, arar_constants=None):
    if isinstance(j, (tuple, str)):
        j = ufloat(j)
    if isinstance(f, (tuple, str)):
        f = ufloat(f)
    if arar_constants is None:
        arar_constants = ArArConstants()

    scalar = float(arar_constants.age_scalar)

    lk = arar_constants.lambda_k
    if not include_decay_error:
        lk = lk.nominal_value
    try:
        return (lk**-1 * umath.log(1 + j * f)) / scalar
    except (ValueError, TypeError):
        return ufloat(0, 0)
コード例 #13
0
def interference_corrections(a40,
                             a39,
                             a38,
                             a37,
                             a36,
                             production_ratios,
                             arar_constants=None,
                             fixed_k3739=False):
    if production_ratios is None:
        production_ratios = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    pr = production_ratios
    k37 = ufloat(0, 1e-20)

    if arar_constants.k3739_mode.lower() == 'normal' and not fixed_k3739:
        # iteratively calculate 37, 39
        for _ in range(5):
            ca37 = a37 - k37
            ca39 = pr.get('Ca3937', 0) * ca37
            k39 = a39 - ca39
            k37 = pr.get('K3739', 0) * k39
    else:
        if not fixed_k3739:
            fixed_k3739 = arar_constants.fixed_k3739

        ca37, ca39, k37, k39 = apply_fixed_k3739(a39, pr, fixed_k3739)

    k38 = pr.get('K3839', 0) * k39

    if not arar_constants.allow_negative_ca_correction:
        ca37 = max(ufloat(0, 0), ca37)

    ca36 = pr.get('Ca3637', 0) * ca37
    ca38 = pr.get('Ca3837', 0) * ca37

    return k37, k38, k39, ca36, ca37, ca38, ca39
コード例 #14
0
def calculate_flux(f, age, arar_constants=None):
    """
        #rad40: radiogenic 40Ar
        #k39: 39Ar from potassium
        f: F value rad40Ar/39Ar
        age: age of monitor in years

        solve age equation for J
    """
    if isinstance(f, (list, tuple)):
        f = ufloat(*f)

    if isinstance(age, (list, tuple)):
        age = ufloat(*age)
    try:
        if arar_constants is None:
            arar_constants = ArArConstants()

        j = (umath.exp(age * arar_constants.lambda_k.nominal_value) - 1) / f
        return j.nominal_value, j.std_dev
    except ZeroDivisionError:
        return 1, 0
コード例 #15
0
ファイル: argon_calculations.py プロジェクト: sgallet/pychron
def calculate_flux(rad40, k39, age, arar_constants=None):
    '''
        rad40: radiogenic 40Ar
        k39: 39Ar from potassium
        age: age of monitor in years
        
        solve age equation for J
    '''
    if isinstance(rad40, (list, tuple)):
        rad40 = ufloat(*rad40)
    if isinstance(k39, (list, tuple)):
        k39 = ufloat(*k39)
    if isinstance(age, (list, tuple)):
        age = ufloat(*age)
        #    age = (1 / constants.lambdak) * umath.log(1 + JR)
    try:
        r = rad40 / k39
        if arar_constants is None:
            arar_constants = ArArConstants()
        j = (umath.exp(age * arar_constants.lambda_k) - 1) / r
        return j.nominal_value, j.std_dev
    except ZeroDivisionError:
        return 1, 0
コード例 #16
0
ファイル: argon_calculations.py プロジェクト: sgallet/pychron
def calculate_F(isotopes, decay_time, interferences=None, arar_constants=None):
    """
        isotope values corrected for blank, baseline, (background)
        ic_factor, (discrimination), ar37 and ar39 decay

    """
    a40, a39, a38, a37, a36 = isotopes

    #a37*=113

    if interferences is None:
        interferences = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    #make local copy of interferences
    pr = dict(((k, v.__copy__()) for k, v in interferences.iteritems()))

    #for k,v in pr.iteritems():
    #    print k, v
    k37, k38, k39, ca36, ca37, ca38, ca39 = interference_corrections(
        a40, a39, a38, a37, a36, pr, arar_constants)
    atm36, cl36 = calculate_atmospheric(a38, a36, k38, ca38, ca36, decay_time,
                                        pr, arar_constants)

    # calculate rodiogenic
    # dont include error in 40/36
    atm40 = atm36 * arar_constants.atm4036.nominal_value
    k40 = k39 * pr.get('k4039', 1)

    rad40 = a40 - atm40 - k40
    try:
        f = rad40 / k39
    except ZeroDivisionError:
        f = ufloat(1.0, 0)

    rf = deepcopy(f)
    # f = ufloat(f.nominal_value, f.std_dev, tag='F')

    non_ar_isotopes = dict(k38=k38,
                           k37=k37,
                           ca36=ca36,
                           ca37=ca37,
                           ca38=ca38,
                           ca39=ca39,
                           cl36=cl36)

    try:
        rp = rad40 / a40 * 100
    except ZeroDivisionError:
        rp = ufloat(0, 0)

    computed = dict(rad40=rad40, rad40_percent=rp, k39=k39)
    #print 'Ar40', a40-k40, a40, k40
    #print 'Ar39', a39-k39, a39, k39

    interference_corrected = dict(Ar40=a40 - k40,
                                  Ar39=k39,
                                  Ar38=a38 - k38 - ca38,
                                  Ar37=a37 - ca37 - k37,
                                  Ar36=a36)
    ##clear errors in irrad
    for pp in pr.itervalues():
        pp.std_dev = 0
    f_wo_irrad = f

    return rf, f_wo_irrad, non_ar_isotopes, computed, interference_corrected
コード例 #17
0
def calculate_F(isotopes,
                decay_time,
                interferences=None,
                arar_constants=None,
                fixed_k3739=False):
    """
        isotope values corrected for blank, baseline, (background)
        ic_factor, (discrimination), ar37 and ar39 decay

    """
    a40, a39, a38, a37, a36 = isotopes

    if interferences is None:
        interferences = {}

    if arar_constants is None:
        arar_constants = ArArConstants()

    # make local copy of interferences
    pr = {k: v.__copy__() for k, v in interferences.iteritems()}

    k37, k38, k39, ca36, ca37, ca38, ca39 = interference_corrections(
        a40, a39, a38, a37, a36, pr, arar_constants, fixed_k3739)
    atm36, cl36, cl38 = calculate_atmospheric(a38, a36, k38, ca38, ca36,
                                              decay_time, pr, arar_constants)

    # calculate radiogenic
    # dont include error in 40/36
    atm40 = atm36 * nominal_value(arar_constants.atm4036)

    k4039 = pr.get('K4039', 0)
    k40 = k39 * k4039

    rad40 = a40 - atm40 - k40
    try:
        f = rad40 / k39
    except ZeroDivisionError:
        f = ufloat(1.0, 0)

    rf = deepcopy(f)

    non_ar_isotopes = dict(k40=k40,
                           ca39=ca39,
                           k38=k38,
                           ca38=ca38,
                           cl38=cl38,
                           k37=k37,
                           ca37=ca37,
                           ca36=ca36,
                           cl36=cl36)

    try:
        rp = rad40 / a40 * 100
    except ZeroDivisionError:
        rp = ufloat(0, 0)

    computed = dict(rad40=rad40, rad40_percent=rp, k39=k39, atm40=atm40)

    interference_corrected = dict(Ar40=a40 - k40,
                                  Ar39=k39,
                                  Ar38=a38,
                                  Ar37=a37,
                                  Ar36=atm36)
    # clear errors in irrad
    for pp in pr.itervalues():
        pp.std_dev = 0
    f_wo_irrad = f

    return rf, f_wo_irrad, non_ar_isotopes, computed, interference_corrected
コード例 #18
0
    # fractional error from ar39
    err39 = fe39 * Re * feJR

    errJ = Je * feJR
    errLambdaK = feLambdaK
    # print 'exception', err40, err36, err39, errJ
    # print 'exception', err36 + err40 + err39 + errJ

    # print 'exception', err36 + err37 + err38 + err40 + err39 + errJ + errLambdaK - 1
    assert abs(err36 + err37 + err38 + err40 + err39 + errJ + errLambdaK -
               1) < 1e-10
    return err40, err39, err38, err37, err36, errJ, errLambdaK


if __name__ == '__main__':
    constants = ArArConstants()
    s40 = ufloat(5.50986, 5.50986 * 0.0004)
    s39 = ufloat(3.65491e-1, 3.65491e-1 * 0.0011)
    s38 = ufloat(4.4904e-3, 4.4904e-3 * 0.0117)
    s37 = ufloat(2.47163e-3, 2.47163e-3 * 0.038)
    #    s38 = ufloat((4.4904e-3, 0))
    #    s37 = ufloat((2.47163e-3, 0))
    s36 = ufloat(2.623e-5, 2.623e-5 * 0.5955)

    J = ufloat(1, 0)
    k4039 = 0
    ca3637 = 2.8e-4
    cl3638 = 0
    cl38 = s38

    ar39 = s39
コード例 #19
0
ファイル: analysis.py プロジェクト: ael-noblegas/pychron
 def __init__(self, make_arar_constants=True, *args, **kw):
     super(IdeogramPlotable, self).__init__(*args, **kw)
     if make_arar_constants:
         self.arar_constants = ArArConstants()