def dOmega(theta_lab, n): """ function to find dΩlab/dΩcm Arguments --------- theta_lab : scattering angle in the lab system [rad] n : A_t / A_i; A_t, A_i means mass number of target particle or incident particle Return ------ dΩlab/dΩcm : factor to convert differential cross-section in the lab system to differential cross-section in the center-of-mass system Notice ------ This function do not consider relativity """ if isinstance(theta_lab, uncertainties.core.AffineScalarFunc): return umath.pow( 2.0 * umath.cos(theta_lab) / n + (1.0 + umath.cos(2.0 * theta_lab) / (n**2.0)) / umath.sqrt(1.0 - umath.pow(umath.sin(theta_lab) / n, 2.0)), -1.0) elif isinstance(theta_lab, np.ndarray) and isinstance( theta_lab[0], uncertainties.core.AffineScalarFunc): return unp.pow( 2.0 * unp.cos(theta_lab) / n + (1.0 + unp.cos(2.0 * theta_lab) / (n**2.0)) / unp.sqrt(1.0 - unp.pow(unp.sin(theta_lab) / n, 2.0)), -1.0) else: return np.power( 2.0 * np.cos(theta_lab) / n + (1.0 + np.cos(2.0 * theta_lab) / (n**2.0)) / np.sqrt(1.0 - np.power(np.sin(theta_lab) / n, 2.0)), -1.0)
def rutherford(theta, T, Zi, Zt, which="inc"): """ Rutherford Scattering in the center-of-mass system Arguments --------- theta : scattering angle in the center-of-mass system T : kinetic energy of incident particle in the center-of-mass system Zi : atomic number of incident particle; charge in units of e Zt : atomic number of target particle; charge in units of e which : if which="inc", calc dσ/dΩ(θ) of incident particle. if which="tar", calc dσ/dΩ(θ) of target particle. if which="sum", calc dσ/dΩ(θ) of incident particle + dσ/dΩ(θ) of target particle. Return ------ dσ/dΩ(θ) in the center-of-mass system [mb/str] """ # dσ/dΩ[mb/str] # 10.0 : fm^2 --> mb if which == "inc": # incident particle if isinstance(theta, uncertainties.core.AffineScalarFunc): return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * umath.pow(umath.sin(theta / 2.0), -4.0) elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc): return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * unp.pow(unp.sin(theta / 2.0), -4.0) else: return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * np.power(np.sin(theta / 2.0), -4.0) elif which == "tar": # target particle if isinstance(theta, uncertainties.core.AffineScalarFunc): return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * umath.pow(umath.cos(theta / 2.0), -4.0) elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc): return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * unp.pow(unp.cos(theta / 2.0), -4.0) else: return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * np.power(np.cos(theta / 2.0), -4.0) elif which == "sum": # incident particle + target particle if isinstance(theta, uncertainties.core.AffineScalarFunc): return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 \ * (umath.pow(umath.sin(theta / 2.0), -4.0) + umath.pow(umath.cos(theta / 2.0), -4.0)) elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc): return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 \ * (unp.pow(unp.sin(theta / 2.0), -4.0) + unp.power(unp.cos(theta / 2.0), -4.0)) else: return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 \ * (np.power(np.sin(theta / 2.0), -4.0) + np.power(np.cos(theta / 2.0), -4.0)) else: raise ValueError( f"Unrecognized which option:{which}. which must be inc/tar/sum.")
def dOmega(theta_cm, n): """ function to find dΩcm/dΩlab Arguments --------- theta_cm : scattering angle in the center-of-mass system [rad] n : A_t / A_i; A_t, A_i means mass number of target particle or incident particle Return ------ dΩcm/dΩlab : factor to convert differential cross-section in the center-of-mass system to one in the lab system Notice ------ This function does not consider relativity """ if isinstance(theta_cm, uncertainties.core.AffineScalarFunc): return umath.pow(1.0 + 2.0 * umath.cos(theta_cm) / n + 1.0 / n**2.0, 3 / 2) \ / (1.0 + umath.cos(theta_cm) / n) elif isinstance(theta_cm, np.ndarray) and isinstance( theta_cm[0], uncertainties.core.AffineScalarFunc): return unp.pow(1.0 + 2.0 * unp.cos(theta_cm) / n + 1.0 / n**2.0, 3 / 2) \ / (1.0 + unp.cos(theta_cm) / n) else: return np.power(1.0 + 2.0 * np.cos(theta_cm) / n + 1.0 / n**2.0, 3 / 2) \ / (1.0 + np.cos(theta_cm) / n)
def quotient_calculator(self, attr): """Return the reaction quotient based on the reactant attribute passed. Parameters ---------- attr : str activity-like attribute of reagent Notes ---------- Recognised attrs include: "conc", "molal", "activity". """ multiplier = 1. A = 1. a = 1. for p, mr in self.products.items(): if p.phase_ss == False: try: A = float(getattr(p, attr)) if A != 0.: a = float(mr) multiplier = multiplier * math.pow(A, a) except: if attr == 'activity': A = p.activity.n # print(p, A) if A != 0.: a = float(mr) multiplier = multiplier * umath.pow(A, a) for r, mr in self.reactants.items(): if r.phase_ss == False: try: A = float(getattr(r, attr)) if A != 0.: a = float(mr) multiplier = multiplier / math.pow(A, a) except: if attr == 'activity': A = r.activity.n # print(r, A) if A != 0.: a = float(mr) multiplier = multiplier * umath.pow(A, a) return multiplier
def get_tigerstripe_CO2(self, logform=False): """ Return the CO2 activity as estimated by the tiger stripe temperature. (Glein and Waite 2020) """ if logform: return umath.log10(self.mixingratios['CO2']/100)+9.429-(2574/self.tigerstripeT) else: return umath.pow(10, (umath.log10(self.mixingratios['CO2']/100)+9.429-(2574/self.tigerstripeT)))
def test_power_special_cases(): ''' Checks special cases of umath.pow(). ''' test_uncertainties.power_special_cases(umath.pow) # We want the same behavior for numbers with uncertainties and for # math.pow() at their nominal values: positive = ufloat(0.3, 0.01) negative = ufloat(-0.3, 0.01) # http://stackoverflow.com/questions/10282674/difference-between-the-built-in-pow-and-math-pow-for-floats-in-python try: umath.pow(ufloat(0, 0.1), negative) except (ValueError, OverflowError), err: # Python 2.6+ "as err" err_type = type(err) # For Python 3: err is destroyed after except
def test_power_special_cases(): ''' Checks special cases of umath.pow(). ''' test_uncertainties.power_special_cases(umath.pow) # We want the same behavior for numbers with uncertainties and for # math.pow() at their nominal values: positive = ufloat(0.3, 0.01) negative = ufloat(-0.3, 0.01) # http://stackoverflow.com/questions/10282674/difference-between-the-built-in-pow-and-math-pow-for-floats-in-python try: umath.pow(ufloat(0, 0.1), negative) except (ValueError, OverflowError), err: # Python 2.6+ "as err" err_class = err.__class__ # For Python 3: err is destroyed after except
def task_6(): m_W = ufloat(80.46, 0.06) m_Z = ufloat(91.1876, 0.0021) theta_W = umath.acos(m_W/m_Z) print("W mass:", m_W, "GeV") print("Z mass:", m_W, "GeV") print("weinberg:", umath.degrees(theta_W), "degrees") sin_theta_W_2 = 1 - umath.pow(m_W/m_Z, 2) print("sin(weinberg)^2:", sin_theta_W_2)
def test_power_special_cases(): ''' Checks special cases of umath.pow(). ''' test_uncertainties.power_special_cases(umath.pow) # We want the same behavior for numbers with uncertainties and for # math.pow() at their nominal values: positive = ufloat(0.3, 0.01) negative = ufloat(-0.3, 0.01) # http://stackoverflow.com/questions/10282674/difference-between-the-built-in-pow-and-math-pow-for-floats-in-python try: umath.pow(ufloat(0, 0.1), negative) except (ValueError, OverflowError) as err: err_class = err.__class__ # For Python 3: err is destroyed after except else: err_class = None err_msg = 'A proper exception should have been raised' # An exception must have occurred: assert err_class == ValueError, err_msg try: result = umath.pow(negative, positive) except ValueError: # The reason why it should also fail in Python 3 is that the # result of Python 3 is a complex number, which uncertainties # does not handle (no uncertainties on complex numbers). In # Python 2, this should always fail, since Python 2 does not # know how to calculate it. pass else: raise Exception('A proper exception should have been raised')
def theta(theta_lab, n): """ function to convert θ in the lab system to θ in the center-of-mass system Arguments --------- theta_lab : scattering angle in the lab system [rad] n : A_t / A_i; A_t, A_i means mass number of target particle or incident particle Return ------ theta_cm : scattering angle in the center-of-mass system [rad] Notice ------ This function do not consider relativity """ if isinstance(theta_lab, uncertainties.core.AffineScalarFunc): coslab2 = umath.pow(umath.cos(theta_lab), 2.0) coscm = (coslab2 - 1.0) / n \ + umath.sqrt((1.0 - 1.0 / n**2.0) * coslab2 + umath.pow(coslab2 / n, 2.0)) return np.sign(theta_lab) * umath.acos(coscm) elif isinstance(theta_lab, np.ndarray) and isinstance( theta_lab[0], uncertainties.core.AffineScalarFunc): coslab2 = unp.pow(unp.cos(theta_lab), 2.0) coscm = (coslab2 - 1.0) / n \ + unp.sqrt((1.0 - 1.0 / n**2.0) * coslab2 + unp.pow(coslab2 / n, 2.0)) return np.sign(theta_lab) * unp.arccos(coscm) else: coslab2 = np.power(np.cos(theta_lab), 2.0) coscm = (coslab2 - 1.0) / n \ + np.sqrt((1.0 - 1.0 / n**2.0) * coslab2 + np.power(coslab2 / n, 2.0)) return np.sign(theta_lab) * np.arccos(coscm)
umath.pow(ufloat(0, 0.1), negative) except (ValueError, OverflowError), err: # Python 2.6+ "as err" err_type = type(err) # For Python 3: err is destroyed after except else: err_type = None err_msg = 'A proper exception should have been raised' # An exception must have occurred: if sys.version_info >= (2, 6): assert err_type == ValueError, err_msg else: assert err_type == OverflowError, err_msg try: result = umath.pow(negative, positive) except ValueError: # The reason why it should also fail in Python 3 is that the # result of Python 3 is a complex number, which uncertainties # does not handle (no uncertainties on complex numbers). In # Python 2, this should always fail, since Python 2 does not # know how to calculate it. pass else: if sys.version_info >= (2, 6): raise Exception('A proper exception should have been raised') else: assert test_uncertainties.isnan(result.nominal_value) assert test_uncertainties.isnan(result.std_dev)
umath.pow(ufloat(0, 0.1), negative) except (ValueError, OverflowError), err: # Python 2.6+ "as err" err_class = err.__class__ # For Python 3: err is destroyed after except else: err_class = None err_msg = 'A proper exception should have been raised' # An exception must have occurred: if sys.version_info >= (2, 6): assert err_class == ValueError, err_msg else: assert err_class == OverflowError, err_msg try: result = umath.pow(negative, positive) except ValueError: # The reason why it should also fail in Python 3 is that the # result of Python 3 is a complex number, which uncertainties # does not handle (no uncertainties on complex numbers). In # Python 2, this should always fail, since Python 2 does not # know how to calculate it. pass else: if sys.version_info >= (2, 6): raise Exception('A proper exception should have been raised') else: assert test_uncertainties.isnan(result.nominal_value) assert test_uncertainties.isnan(result.std_dev) def test_power_wrt_ref():
a = ufloat(a_value, a_value * 0.02) b = ufloat(b_value, b_value * 0.02) print(a) print(b) a_log = umath.log10(a) b_log = umath.log10(b) print(a_log) print(b_log) print('Umath: a ->', a_log.nominal_value, a_log.std_dev) print('Umath: b ->', b_log.nominal_value, b_log.std_dev) a_conv = umath.pow(10, a_log) b_conv = umath.pow(10, b_log) print(a_conv) print(b_conv) a_mine = [np.log10(a_value), np.log10(1.0 + (a_value * 0.02) / a_value)] b_mine = [np.log10(b_value), np.log10(1.0 + (b_value * 0.02) / b_value)] print('a_mine', a_mine) print('b_mine', b_mine) a_form1 = [np.log10(a_value), 0.434 * (a_value * 0.02) / a_value] b_form1 = [np.log10(b_value), 0.434 * (b_value * 0.02) / b_value] print(a_form1)
def mott(theta, T, Z, A, S): """ Mott Scattering in the center-of-mass system Arguments --------- theta : scattering angle in the center-of-mass system T : kinetic energy of incident particle in the center-of-mass system Z : atomic number; charge in units of e A : mass number S : spin Return ------ dσ/dΩ(θ) in the center-of-mass system [mb/str] """ # rest energy mc2 = A * AMU # total energy of incident/target particle in the center-of-mass system Ecm = (T + 2.0 * mc2) / 2.0 # gamma (= gamma_cm in this situattion) gamma = Ecm / mc2 # beta (= beta_cm in this situattion) beta = np.sqrt(1.0 - 1.0 / gamma**2.0) # relative beta in the center-of-mass system brel = 2.0 * beta / (1.0 + beta**2.0) # dσ/dΩ[mb/str] # 10.0 : fm^2 --> mb if isinstance(theta, uncertainties.core.AffineScalarFunc): return 10.0 * (Z**2 * E2 / (4.0 * T))**2.0 * ( umath.pow(umath.sin(theta / 2.0), -4.0) + umath.pow(umath.cos(theta / 2.0), -4.0) + (-1.0)**(2.0 * S) * 2.0 / (2.0 * S + 1.0) * umath.pow(umath.sin(theta / 2.0), -2.0) * umath.pow(umath.cos(theta / 2.0), -2.0) * umath.cos(Z**2.0 * E2 / (HBARC * brel) * umath.log(umath.pow(umath.tan(theta / 2.0), 2.0)) ) ) elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc): return 10.0 * (Z**2 * E2 / (4.0 * T))**2.0 * ( unp.pow(unp.sin(theta / 2.0), -4.0) + unp.pow(unp.cos(theta / 2.0), -4.0) + (-1.0)**(2.0 * S) * 2.0 / (2.0 * S + 1.0) * unp.pow(unp.sin(theta / 2.0), -2.0) * unp.pow(unp.cos(theta / 2.0), -2.0) * unp.cos(Z**2.0 * E2 / (HBARC * brel) * unp.log(unp.pow(unp.tan(theta / 2.0), 2.0)) ) ) else: return 10.0 * (Z**2 * E2 / (4.0 * T))**2.0 * ( np.power(np.sin(theta / 2.0), -4.0) + np.power(np.cos(theta / 2.0), -4.0) + (-1.0)**(2.0 * S) * 2.0 / (2.0 * S + 1.0) * np.power(np.sin(theta / 2.0), -2.0) * np.power(np.cos(theta / 2.0), -2.0) * np.cos(Z**2.0 * E2 / (HBARC * brel) * np.log(np.power(np.tan(theta / 2.0), 2.0)) ) )
def plot_strontium(): m = { 0: 0, 5: 0.03, 6: 0.04, 7: 0.05, 8: 0.08, 9: 0.10, 10: 0.17, 11: 0.25, 12: 0.37, 13: 0.50, 14: 0.64, 15: 0.83, 16: 1.01, 17: 1.23, 18: 1.39, 19: 1.57, 20: 1.88, 21: 2.29, 22: 2.79, 23: 3.46, } nr, count = np.loadtxt("data/strontium_alu.txt", unpack=True) absorb = np.zeros_like(nr) for i, x in enumerate(nr): absorb[i] = m[x] / 10 scale = 1 / count[0] error_count = np.sqrt(count + 1) error_absorb = 0.01 / 10 count *= scale error_count *= scale func = lambda x, A, mu, offset: A * np.exp(-x * mu) + offset fit = Fit(func) fit.set_data(xdata=absorb, ydata=count, xerrors=error_absorb, yerrors=error_count) fit.set_params(A=1, mu=1, offset=0) fit.set_labels(xlabel="Dicke / cm", ylabel="Anteil") fit.iterative_fit(5) plt.clf() plt.minorticks_on() plt.xlim(0, .35) fit.plot(box="tr", units={"mu": "1/cm"}) plt.savefig("out/strontium_fit." + SAVETYPE) plt.clf() plt.minorticks_on() fit.plot_residual(box="tr") plt.savefig("out/strontium_residual." + SAVETYPE) rho = ufloat(2.7, 0.1) mu = fit.uvalue("mu") print("Absorptionskoeffizient:", mu, "1/cm") mu1 = mu / rho print("Massenabsorptionskoeffizient:", mu1, "cm^2/g") E = umath.pow(17 / mu1, 1 / 1.14) print("Maximalenergie:", E, "MeV") R1 = 0.412 * umath.pow(E, 1.265 - 0.0954 * umath.log(E)) R = R1 / rho print("Reichweite:", R1, "g/cm^2") print("Reichweite:", R, "cm")