def sigma_r(refprs, press, temp, salty): '''Calculate density using international equation of state From text furnished by J. Gieskes Args: press -- pressure in decibars temp -- temperature in celsius degrees salty -- salinity PSS 78 refprs -- reference pressure refprs = 0. : sigma theta refprs = press: sigma z Return: kg/m*3 - 1000.0 ''' # check for missing data if _any_missing(temp, press, salty): return CDMISS # calculate potential temperature if press != refprs: potemp = potential_temperature(press, temp, salty, refprs) else: potemp = temp # sigma theta kg/m**3 sigma = (rho_w(potemp) + kw(potemp, salty) + k_st0(salty, potemp) + _decimal(4.8314e-4) * salty ** 2) if equal_with_epsilon(refprs, 0.0): return sigma - _decimal(1000.0) # Calculate pressure effect # # rho(s,t,0)/(1.0-p/k(s,t,p)) # kst0 = secant_bulk_modulus(abs(salty), potemp, 0) # reference pressure in bars bars = refprs * 0.1 # Calculate pressure terms terma = polynomial(potemp, (3.239908, 0.00143713, 1.16092e-4, -5.77905e-7)) + \ polynomial(potemp, (0.0022838, -1.0981e-5, -1.6078e-6)) * salty + \ 1.91075e-4 * abs(salty) ** 1.5 termb = polynomial(potemp, (8.50935e-5, -6.12293e-6, 5.2787e-8)) + \ polynomial(potemp, (-9.9348e-7, 2.0816e-8, 9.1697e-10)) * salty # Secant bulk modulus k(s,t,p) */ kstp = polynomial(bars, (kst0, terma, termb)) return sigma / (1.0 - bars / kstp) - 1000.0
def potential_temperature(p, t, s, rp): '''Calculate potential temperature for an arbitrary reference pressure. Ref: N.P. Fofonoff Deep Sea Research in press Nov 1976 Args: press-- pressure in decibars temp -- temperature in celsius degrees s -- salinity PSS 78 rp -- reference pressure in decibars (0.0 for standard potential temperature) Return: potential temperature ''' s1 = s - 35.0 if _any_missing(s, p, t): return CDMISS dp = rp - p n = int(abs(dp) / 1.0e3) + 1 dp /= float(n) for i in range(1, n): for j in range(1, 4): r1 = polynomial(t, (-4.6206e-13, 1.8676e-14, -2.1687e-16)) * p r2 = polynomial(t, (-1.1351e-10, 2.7759e-12)) * s1 r3 = polynomial(t, (0, -6.7795e-10, 8.733e-12, -5.4481e-13)) r4 = (r1 + (r2 + r3 + 1.8741e-8)) * p + \ polynomial(t, (1.8932e-6, -4.2393e-8)) * s1 r5 = r4 + polynomial( t, (3.5803e-5, 8.5258e-6, -6.836e-8, 6.6228e-10)) x = dp * r5 if j == 1: t = t + 0.5 * x q = x p += 0.5 * dp elif j == 2: t += 0.29289322 * (x - q) q = 0.58578644 * x + 0.121320344 * q elif j == 3: t += 1.707106781 * (x - q) q = 3.414213562 * x - 4.121320344 * q p += 0.5 * dp elif j == 4: t += (x - 2.0 * q) / 6.0 return t
def pressure(z): '''Calculates pressure from depth. Args: z - depth ''' if _missing(z): return CDMISS return polynomial(z, COEFF_PRESSURE)
def oxycal(pt, s, o2): '''Routine to calculate precent oxygen saturation. Args: -> ptx potential temperature. -> salx salinity -> o2x observed oxygen (ml/l) Return: percent oxygen saturation. Ref: Weiss, R.F. (1970) The Solubility of Nitrogen, Oxygen, and Argon in Water and Seawater. Deep-Sea Res., Vol 17, 721-735. Note: two other values can be calculated using returned value. o2c == oxygen saturation of parcel of water moved to surface and exposed to the atmosphere for an infinite amount of time. o2c = (o2x*100.)/oxypct apparent oxygen utilization: o2x - o2c ''' if _any_missing(pt, s, o2): return CDMISS a1 = -173.4292 a2 = 249.6339 a3 = 143.3483 a4 = -21.8492 b = (-0.033096, 0.014259, -0.0017) pt += 273.15 ptpc = pt / 100.0 o2c = exp(a1 + a2 * (100.0 / pt) + a3 * log(ptpc) + a4 * ptpc + s * polynomial(ptpc, b)) return (o2 / o2c) * 100.0
def k_st0(salinity, potential_temperature): return polynomial(potential_temperature, COEFF_K_ST0) * \ abs(salinity) ** _decimal(1.5)
def kw_1(potential_temperature): return polynomial(potential_temperature, COEFF_KW_1)
def rho_w(potential_temperature): '''density of pure water kg/m**3''' return polynomial(potential_temperature, COEFF_RHO_W)
def test_polynomial(self): self.assertEqual(0, fns.polynomial(5, [])) self.assertEqual(1, fns.polynomial(5, [1])) self.assertEqual(5, fns.polynomial(5, [0, 1])) self.assertEqual(30, fns.polynomial(5, [0, 1, 1])) self.assertEqual(50, fns.polynomial(5, [0, 5, 1]))