コード例 #1
0
    def _calibrate_ir(radiance, coefs):
        """Convert IR radiance to brightness temperature

        Reference: [IR]

        Args:
            radiance: Radiance [mW m-2 cm-1 sr-1]
            coefs: Dictionary of calibration coefficients. Keys:
                   n: The channel's central wavenumber [cm-1]
                   a: Offset [K]
                   b: Slope [1]
                   btmin: Minimum brightness temperature threshold [K]
                   btmax: Maximum brightness temperature threshold [K]

        Returns:
            Brightness temperature [K]
        """
        logger.debug('Calibrating to brightness temperature')

        # Compute brightness temperature using inverse Planck formula
        n = coefs['n']
        bteff = C2 * n / xu.log(1 + C1 * n**3 / radiance.where(radiance > 0))
        bt = xr.DataArray(bteff * coefs['b'] + coefs['a'])

        # Apply BT threshold
        return bt.where(
            xu.logical_and(bt >= coefs['btmin'], bt <= coefs['btmax']))
コード例 #2
0
ファイル: crefl_utils.py プロジェクト: shepherdmeng/satpy
def get_atm_variables(mus, muv, phi, height, coeffs):
    (ah2o, bh2o, ao3, tau) = coeffs
    # From GetAtmVariables
    tau_step = np.linspace(TAUSTEP4SPHALB, MAXNUMSPHALBVALUES * TAUSTEP4SPHALB,
                           MAXNUMSPHALBVALUES)
    sphalb0 = csalbr(tau_step)

    air_mass = 1.0 / mus + 1 / muv
    air_mass = air_mass.where(air_mass <= MAXAIRMASS, -1.0)

    taur = tau * xu.exp(-height / SCALEHEIGHT)

    rhoray, trdown, trup = chand(phi, muv, mus, taur)

    sphalb = sphalb0[np.int32(taur / TAUSTEP4SPHALB + 0.5)]
    Ttotrayu = ((2 / 3. + muv) + (2 / 3. - muv) * trup) / (4 / 3. + taur)
    Ttotrayd = ((2 / 3. + mus) + (2 / 3. - mus) * trdown) / (4 / 3. + taur)
    tO3 = 1.0
    tO2 = 1.0
    tH2O = 1.0

    if ao3 != 0:
        tO3 = xu.exp(-air_mass * UO3 * ao3)
    if bh2o != 0:
        if bUseV171:
            tH2O = xu.exp(-xu.exp(ah2o + bh2o * xu.log(air_mass * UH2O)))
        else:
            tH2O = xu.exp(-(ah2o * ((air_mass * UH2O)**bh2o)))
    #t02 = exp(-m * aO2)
    TtotraytH2O = Ttotrayu * Ttotrayd * tH2O
    tOG = tO3 * tO2
    return sphalb, rhoray, TtotraytH2O, tOG
コード例 #3
0
ファイル: hdfeos_l1b.py プロジェクト: davidh-ssec/satpy
def calibrate_tb(array, attributes, index, band_name):
    """Calibration for the emissive channels."""
    offset = np.float32(attributes["radiance_offsets"][index])
    scale = np.float32(attributes["radiance_scales"][index])

    array = (array - offset) * scale

    # Planck constant (Joule second)
    h__ = np.float32(6.6260755e-34)

    # Speed of light in vacuum (meters per second)
    c__ = np.float32(2.9979246e+8)

    # Boltzmann constant (Joules per Kelvin)
    k__ = np.float32(1.380658e-23)

    # Derived constants
    c_1 = 2 * h__ * c__ * c__
    c_2 = (h__ * c__) / k__

    # Effective central wavenumber (inverse centimeters)
    cwn = np.array([
        2.641775E+3, 2.505277E+3, 2.518028E+3, 2.465428E+3,
        2.235815E+3, 2.200346E+3, 1.477967E+3, 1.362737E+3,
        1.173190E+3, 1.027715E+3, 9.080884E+2, 8.315399E+2,
        7.483394E+2, 7.308963E+2, 7.188681E+2, 7.045367E+2],
        dtype=np.float32)

    # Temperature correction slope (no units)
    tcs = np.array([
        9.993411E-1, 9.998646E-1, 9.998584E-1, 9.998682E-1,
        9.998819E-1, 9.998845E-1, 9.994877E-1, 9.994918E-1,
        9.995495E-1, 9.997398E-1, 9.995608E-1, 9.997256E-1,
        9.999160E-1, 9.999167E-1, 9.999191E-1, 9.999281E-1],
        dtype=np.float32)

    # Temperature correction intercept (Kelvin)
    tci = np.array([
        4.770532E-1, 9.262664E-2, 9.757996E-2, 8.929242E-2,
        7.310901E-2, 7.060415E-2, 2.204921E-1, 2.046087E-1,
        1.599191E-1, 8.253401E-2, 1.302699E-1, 7.181833E-2,
        1.972608E-2, 1.913568E-2, 1.817817E-2, 1.583042E-2],
        dtype=np.float32)

    # Transfer wavenumber [cm^(-1)] to wavelength [m]
    cwn = 1. / (cwn * 100)

    # Some versions of the modis files do not contain all the bands.
    emmissive_channels = ["20", "21", "22", "23", "24", "25", "27", "28", "29",
                          "30", "31", "32", "33", "34", "35", "36"]
    global_index = emmissive_channels.index(band_name)

    cwn = cwn[global_index]
    tcs = tcs[global_index]
    tci = tci[global_index]
    array = c_2 / (cwn * xu.log(c_1 / (1000000 * array * cwn ** 5) + 1))
    array = (array - tci) / tcs
    return array
コード例 #4
0
ファイル: hdfeos_l1b.py プロジェクト: zhangqrl/satpy
def calibrate_bt(array, attributes, index, band_name):
    """Calibration for the emissive channels."""
    offset = np.float32(attributes["radiance_offsets"][index])
    scale = np.float32(attributes["radiance_scales"][index])

    array = (array - offset) * scale

    # Planck constant (Joule second)
    h__ = np.float32(6.6260755e-34)

    # Speed of light in vacuum (meters per second)
    c__ = np.float32(2.9979246e+8)

    # Boltzmann constant (Joules per Kelvin)
    k__ = np.float32(1.380658e-23)

    # Derived constants
    c_1 = 2 * h__ * c__ * c__
    c_2 = (h__ * c__) / k__

    # Effective central wavenumber (inverse centimeters)
    cwn = np.array([
        2.641775E+3, 2.505277E+3, 2.518028E+3, 2.465428E+3,
        2.235815E+3, 2.200346E+3, 1.477967E+3, 1.362737E+3,
        1.173190E+3, 1.027715E+3, 9.080884E+2, 8.315399E+2,
        7.483394E+2, 7.308963E+2, 7.188681E+2, 7.045367E+2],
        dtype=np.float32)

    # Temperature correction slope (no units)
    tcs = np.array([
        9.993411E-1, 9.998646E-1, 9.998584E-1, 9.998682E-1,
        9.998819E-1, 9.998845E-1, 9.994877E-1, 9.994918E-1,
        9.995495E-1, 9.997398E-1, 9.995608E-1, 9.997256E-1,
        9.999160E-1, 9.999167E-1, 9.999191E-1, 9.999281E-1],
        dtype=np.float32)

    # Temperature correction intercept (Kelvin)
    tci = np.array([
        4.770532E-1, 9.262664E-2, 9.757996E-2, 8.929242E-2,
        7.310901E-2, 7.060415E-2, 2.204921E-1, 2.046087E-1,
        1.599191E-1, 8.253401E-2, 1.302699E-1, 7.181833E-2,
        1.972608E-2, 1.913568E-2, 1.817817E-2, 1.583042E-2],
        dtype=np.float32)

    # Transfer wavenumber [cm^(-1)] to wavelength [m]
    cwn = 1. / (cwn * 100)

    # Some versions of the modis files do not contain all the bands.
    emmissive_channels = ["20", "21", "22", "23", "24", "25", "27", "28", "29",
                          "30", "31", "32", "33", "34", "35", "36"]
    global_index = emmissive_channels.index(band_name)

    cwn = cwn[global_index]
    tcs = tcs[global_index]
    tci = tci[global_index]
    array = c_2 / (cwn * xu.log(c_1 / (1000000 * array * cwn ** 5) + 1))
    array = (array - tci) / tcs
    return array
コード例 #5
0
ファイル: arithmetics.py プロジェクト: TomBlock/cate
def ds_arithmetics(ds: DatasetLike.TYPE,
                   op: str,
                   monitor: Monitor = Monitor.NONE) -> xr.Dataset:
    """
    Do arithmetic operations on the given dataset by providing a list of
    arithmetic operations and the corresponding constant. The operations will
    be applied to the dataset in the order in which they appear in the list.
    For example:
    'log,+5,-2,/3,*2'

    Currently supported arithmetic operations:
    log,log10,log2,log1p,exp,+,-,/,*

    where:
        log - natural logarithm
        log10 - base 10 logarithm
        log2 - base 2 logarithm
        log1p - log(1+x)
        exp - the exponential

    The operations will be applied element-wise to all arrays of the dataset.

    :param ds: The dataset to which to apply arithmetic operations
    :param op: A comma separated list of arithmetic operations to apply
    :param monitor: a progress monitor.
    :return: The dataset with given arithmetic operations applied
    """
    ds = DatasetLike.convert(ds)
    retset = ds
    with monitor.starting('Calculate result', total_work=len(op.split(','))):
        for item in op.split(','):
            with monitor.child(1).observing("Calculate"):
                item = item.strip()
                if item[0] == '+':
                    retset = retset + float(item[1:])
                elif item[0] == '-':
                    retset = retset - float(item[1:])
                elif item[0] == '*':
                    retset = retset * float(item[1:])
                elif item[0] == '/':
                    retset = retset / float(item[1:])
                elif item[:] == 'log':
                    retset = xu.log(retset)
                elif item[:] == 'log10':
                    retset = xu.log10(retset)
                elif item[:] == 'log2':
                    retset = xu.log2(retset)
                elif item[:] == 'log1p':
                    retset = xu.log1p(retset)
                elif item[:] == 'exp':
                    retset = xu.exp(retset)
                else:
                    raise ValueError('Arithmetic operation {} not'
                                     ' implemented.'.format(item[0]))

    return retset
コード例 #6
0
ファイル: xrimage.py プロジェクト: pytroll/trollimage
    def stretch_weber_fechner(self, k, s0):
        """Stretch according to the Weber-Fechner law.

        p = k.ln(S/S0)
        p is perception, S is the stimulus, S0 is the stimulus threshold (the
        highest unpercieved stimulus), and k is the factor.
        """
        attrs = self.data.attrs
        self.data = k * xu.log(self.data / s0)
        self.data.attrs = attrs
コード例 #7
0
    def stretch_weber_fechner(self, k, s0):
        """Stretch according to the Weber-Fechner law.

        p = k.ln(S/S0)
        p is perception, S is the stimulus, S0 is the stimulus threshold (the
        highest unpercieved stimulus), and k is the factor.
        """
        attrs = self.data.attrs
        self.data = k * xu.log(self.data / s0)
        self.data.attrs = attrs
コード例 #8
0
def calculate_dz(domain):
    """Use the hydrostatic relation to get dz from dp."""
    # hydrostatic: dp = -rho g dz
    # ideal gas: rho = p / RT
    # => dz = -RT/g d[lnp]
    T = pfull_to_phalf(domain.temp, domain)
    pfull = (domain.pfull / domain.phalf.max()) * domain.ps
    dlnp = diff_pfull(xruf.log(pfull), domain)
    dz = -R_dry * T / grav * dlnp
    return dz
コード例 #9
0
ファイル: abi_l1b.py プロジェクト: davidh-ssec/satpy
    def _ir_calibrate(self, data):
        """Calibrate IR channels to BT."""
        fk1 = float(self["planck_fk1"])
        fk2 = float(self["planck_fk2"])
        bc1 = float(self["planck_bc1"])
        bc2 = float(self["planck_bc2"])

        res = (fk2 / xu.log(fk1 / data + 1) - bc1) / bc2
        res.attrs = data.attrs
        res.attrs['units'] = 'K'

        return res
コード例 #10
0
ファイル: abi_l1b.py プロジェクト: zhatin/satpy
    def _ir_calibrate(self, data):
        """Calibrate IR channels to BT."""
        fk1 = float(self["planck_fk1"])
        fk2 = float(self["planck_fk2"])
        bc1 = float(self["planck_bc1"])
        bc2 = float(self["planck_bc2"])

        res = (fk2 / xu.log(fk1 / data + 1) - bc1) / bc2
        res.attrs = data.attrs
        res.attrs['units'] = 'K'
        res.attrs['standard_name'] = 'toa_brightness_temperature'
        return res
コード例 #11
0
ファイル: arithmetics.py プロジェクト: acorlyon/cate-core
def ds_arithmetics(ds: xr.Dataset, op: str) -> xr.Dataset:
    """
    Do arithmetic operations on the given dataset by providing a list of
    arithmetic operations and the corresponding constant. The operations will
    be applied to the dataset in the order in which they appear in the list.
    For example:
    'log,+5,-2,/3,*2'

    Currently supported arithmetic operations:
    log,log10,log2,log1p,exp,+,-,/,*

    where:
        log - natural logarithm
        log10 - base 10 logarithm
        log2 - base 2 logarithm
        log1p - log(1+x)
        exp - the exponential

    The operations will be applied element-wise to all arrays of the dataset.

    :param ds: The dataset to which to apply arithmetic operations
    :param op: A comma separated list of arithmetic operations to apply
    :return: The dataset with given arithmetic operations applied
    """
    retset = ds
    for item in op.split(','):
        item = item.strip()
        if item[0] == '+':
            retset = retset + float(item[1:])
        elif item[0] == '-':
            retset = retset - float(item[1:])
        elif item[0] == '*':
            retset = retset * float(item[1:])
        elif item[0] == '/':
            retset = retset / float(item[1:])
        elif item[:] == 'log':
            retset = xu.log(retset)
        elif item[:] == 'log10':
            retset = xu.log10(retset)
        elif item[:] == 'log2':
            retset = xu.log2(retset)
        elif item[:] == 'log1p':
            retset = xu.log1p(retset)
        elif item[:] == 'exp':
            retset = xu.exp(retset)
        else:
            raise ValueError('Arithmetic operation {} not'
                             ' implemented.'.format(item[0]))

    return retset
コード例 #12
0
def logscale_precip(data, varname='tp'):
    """
    log-scale variable "varname" in data

    Parameters
    ----------
    data: xarray dataarray, where varname is the variable that needs to be log-scaled

    Returns
    ----------
    data: data with variable log-scaled
    """
    data.loc[varname] = data.loc[varname].where(data.loc[varname] > 0.000001, -1) # define lower threshold for "no rain"
    data.loc[varname] = xu.log(data.loc[varname])
    data.loc[varname] = data.loc[varname].where(~np.isnan(data.loc[varname]), -20) # all zero precip got -1, all -1 got nan, all nan get -20
    return data
コード例 #13
0
    def read_dataset(self, dataset_key, info):
        h5f = self.h5f
        channel = chans_dict[dataset_key.name]
        chan_dict = dict([(key.split("-")[1], key)
                          for key in h5f["All_Data"].keys()
                          if key.startswith("VIIRS")])

        h5rads = h5f["All_Data"][chan_dict[channel]]["Radiance"]
        chunks = h5rads.chunks or CHUNK_SIZE
        rads = xr.DataArray(da.from_array(h5rads, chunks=chunks),
                            name=dataset_key.name,
                            dims=['y', 'x']).astype(np.float32)
        h5attrs = h5rads.attrs
        scans = h5f["All_Data"]["NumberOfScans"][0]
        rads = rads[:scans * 16, :]
        # if channel in ("M9", ):
        #     arr = rads[:scans * 16, :].astype(np.float32)
        #     arr[arr > 65526] = np.nan
        #     arr = np.ma.masked_array(arr, mask=arr_mask)
        # else:
        #     arr = np.ma.masked_greater(rads[:scans * 16, :].astype(np.float32),
        #                                65526)
        rads = rads.where(rads <= 65526)
        try:
            rads = xr.where(
                rads <= h5attrs['Threshold'],
                rads * h5attrs['RadianceScaleLow'] +
                h5attrs['RadianceOffsetLow'],
                rads * h5attrs['RadianceScaleHigh'] +
                h5attrs['RadianceOffsetHigh'])
        except (KeyError, AttributeError):
            logger.info("Missing attribute for scaling of %s.", channel)
            pass
        unit = "W m-2 sr-1 μm-1"
        if dataset_key.calibration == 'counts':
            raise NotImplementedError("Can't get counts from this data")
        if dataset_key.calibration in [
                'reflectance', 'brightness_temperature'
        ]:
            # do calibrate
            try:
                # First guess: VIS or NIR data
                a_vis = h5attrs['EquivalentWidth']
                b_vis = h5attrs['IntegratedSolarIrradiance']
                dse = h5attrs['EarthSunDistanceNormalised']
                rads *= 100 * np.pi * a_vis / b_vis * (dse**2)
                unit = "%"
            except KeyError:
                # Maybe it's IR data?
                try:
                    a_ir = h5attrs['BandCorrectionCoefficientA']
                    b_ir = h5attrs['BandCorrectionCoefficientB']
                    lambda_c = h5attrs['CentralWaveLength']
                    rads *= 1e6
                    rads = (h * c) / (k * lambda_c *
                                      xu.log(1 + (2 * h * c**2) /
                                             ((lambda_c**5) * rads)))
                    rads *= a_ir
                    rads += b_ir
                    unit = "K"
                except KeyError:
                    logger.warning("Calibration failed.")

        elif dataset_key.calibration != 'radiance':
            raise ValueError("Calibration parameter should be radiance, "
                             "reflectance or brightness_temperature")
        rads = rads.clip(min=0)
        rads.attrs = self.mda
        rads.attrs['units'] = unit
        return rads
コード例 #14
0
ファイル: viirs_compact.py プロジェクト: davidh-ssec/satpy
    def read_dataset(self, dataset_key, info):
        h5f = self.h5f
        channel = chans_dict[dataset_key.name]
        chan_dict = dict([(key.split("-")[1], key)
                          for key in h5f["All_Data"].keys()
                          if key.startswith("VIIRS")])

        h5rads = h5f["All_Data"][chan_dict[channel]]["Radiance"]
        chunks = h5rads.chunks or CHUNK_SIZE
        rads = xr.DataArray(da.from_array(h5rads, chunks=chunks),
                            name=dataset_key.name,
                            dims=['y', 'x']).astype(np.float32)
        h5attrs = h5rads.attrs
        # scans = h5f["All_Data"]["NumberOfScans"][0]
        # if channel in ("M9", ):
        #     arr = rads[:scans * 16, :].astype(np.float32)
        #     arr[arr > 65526] = np.nan
        #     arr = np.ma.masked_array(arr, mask=arr_mask)
        # else:
        #     arr = np.ma.masked_greater(rads[:scans * 16, :].astype(np.float32),
        #                                65526)
        rads = rads.where(rads <= 65526)
        try:
            rads = xr.where(rads <= h5attrs['Threshold'],
                            rads * h5attrs['RadianceScaleLow'] +
                            h5attrs['RadianceOffsetLow'],
                            rads * h5attrs['RadianceScaleHigh'] +
                            h5attrs['RadianceOffsetHigh'])
        except (KeyError, AttributeError):
            logger.info("Missing attribute for scaling of %s.", channel)
            pass
        unit = "W m-2 sr-1 μm-1"
        if dataset_key.calibration == 'counts':
            raise NotImplementedError("Can't get counts from this data")
        if dataset_key.calibration in ['reflectance', 'brightness_temperature']:
            # do calibrate
            try:
                # First guess: VIS or NIR data
                a_vis = h5attrs['EquivalentWidth']
                b_vis = h5attrs['IntegratedSolarIrradiance']
                dse = h5attrs['EarthSunDistanceNormalised']
                rads *= 100 * np.pi * a_vis / b_vis * (dse**2)
                unit = "%"
            except KeyError:
                # Maybe it's IR data?
                try:
                    a_ir = h5attrs['BandCorrectionCoefficientA']
                    b_ir = h5attrs['BandCorrectionCoefficientB']
                    lambda_c = h5attrs['CentralWaveLength']
                    rads *= 1e6
                    rads = (h * c) / (k * lambda_c *
                                      xu.log(1 +
                                             (2 * h * c ** 2) /
                                             ((lambda_c ** 5) * rads)))
                    rads *= a_ir
                    rads += b_ir
                    unit = "K"
                except KeyError:
                    logger.warning("Calibration failed.")

        elif dataset_key.calibration != 'radiance':
            raise ValueError("Calibration parameter should be radiance, "
                             "reflectance or brightness_temperature")
        rads = rads.clip(min=0)
        rads.attrs = self.mda
        rads.attrs['units'] = unit
        return rads
コード例 #15
0
def global_XCO2(datetime):

    execfile('../../rpnenv/bin/activate_this.py',
             dict(__file__='../../rpnenv/bin/activate_this.py'))

    import fstd2nc

    # get the ACOS pressure coefficients and acceleration due to gravity at set pressure levels
    acos_plevs = np.load('../earth_data/ACOS_plevs.npy')
    grav_plevs, grav = np.load('../earth_data/ACOS_grav.npy')

    # get the model files that will be read from
    model_fname = datetime.strftime(_rpn_format)
    model_fname_prev = (datetime - dt.timedelta(days=1)).strftime(_rpn_format)

    model = fstd2nc.Buffer(model_fname,
                           vars='CO2,HU,P0',
                           diag_as_model_level=True).to_xarray()

    try:
        # open files for the day of the observations and the final time step of the previous day
        mprev = fstd2nc.Buffer(model_fname_prev,
                               vars='CO2,HU,P0',
                               diag_as_model_level=True).to_xarray()
        model = xarray.concat([
            mprev.sel(time=datetime.strftime('%Y-%m-%dT00:00:00.000000000')),
            model
        ], 'time').transpose('time', 'level', 'lat', 'lon')

    except:
        # First day - no previous day to get data from, so the first 2 hours will have to be extrapolated
        print("Error due to first day of run ignored")
        pass

    model.load()

    model_interp = model.interp(time=datetime, kwargs={'fill_value': None})

    print(model_interp)

    logp = model_interp.a + model_interp.b * log(model_interp.P0 / 1000.)
    p = exp(logp) / 100.
    p = p.transpose('level', 'lat', 'lon').values

    psurf = model_interp.P0.values

    acos_p = psurf[np.newaxis, ...] * acos_plevs[:, np.newaxis, np.newaxis]

    CO2 = model_interp.CO2.values
    HU = model_interp.CO2.values

    print("interpolating to ACOS algorithm pressure levels")
    u = np.zeros(acos_p.shape)
    q = np.zeros(acos_p.shape)
    g = np.zeros(acos_p.shape)
    for i in range(p.shape[1]):
        for j in range(p.shape[2]):
            u[:, i, j] = np.interp(acos_p[:, i, j], p[:, i, j], CO2[:, i, j])
            q[:, i, j] = np.interp(acos_p[:, i, j], p[:, i, j], HU[:, i, j])
            g[:, i, j] = np.interp(acos_p[:, i, j], grav_plevs, grav)

    c = (1. - q) / mdry / g
    cavg = 0.5 * (c[:-1, ...] + c[1:, ...])
    delp = acos_p[:-1, ...] - acos_p[1:, ...]

    hprime = cavg * delp / np.sum(cavg * delp, axis=0)[np.newaxis, ...]

    f = 0.5 * np.ones(acos_p.shape)
    f[-1,
      ...] = (psurf - acos_p[-2, ...]) / (acos_p[-1, ...] - acos_p[-2, ...])

    h = np.zeros(acos_p.shape)
    h[0, ...] = (1. - f[0, ...]) * hprime[0, ...]
    h[1:-2, ...] = f[:-3, ...] * hprime[:-2, ...] + (
        1. - f[1:-2, ...]) * hprime[1:-1, ...]
    h[-2, ...] = f[-3, ...] * hprime[-2, ...] + (
        1 - f[-2, ...] * f[-1, ...]) * hprime[-1, ...]
    h[-1, ...] = f[-1, ...] * f[-2, ...] * hprime[-1, ...]

    profile = 0.0024141666666666665 * u
    xco2 = np.sum(h * profile, axis=0)

    lats = model_interp.lat.values
    lons = model_interp.lon.values

    lons[lons > 180.] -= 360.

    reorder = np.argsort(lons)

    xco2 = xco2[:, reorder]
    lons = lons[reorder]

    return xco2, lats, lons
コード例 #16
0
def wanninkhof92(T=None,
                 S=None,
                 P=None,
                 u_mean=None,
                 u_var=None,
                 xCO2=None,
                 pCO2_sw=None,
                 iceFrac=None,
                 scale_factor=0.27):
    '''
    Calculate air-sea CO2 flux following Wanninkhof 1992
    
    Inputs
    ============
    T = Temperature [degC]
    S = Salinity  [parts per thousand]
    P = Atmospheric pressure at 10m [atm]
    u_mean = mean wind speed [m/s]
    u_var = variance of wind speed m/s averaged monthly [m/s]
    xcO2 = atmoapheric mixing ratio of CO2 [ppm]
    pCO2_sw = CO2 partial pressure of seawter [uatm]
    scale_factor = gas transfer scale factor (default=0.27)
    
    Output
    ============
    F_co2 = air-sea co2 flux [molC/m2/yr]
    
    References
    ============
    Weiss (1974) [for solubility of CO2]
        Carbon dioxide in water and seawater: the solubility of a non-ideal gas
    Weiss and Price (1980) [for saturation vapor pressure, not used here]
        Nitrous oxide solubility in water and seawater     
    Dickson et al (2007) [for saturation vapor pressure]
        Guide to best practices for Ocean CO2 measurements, Chapter 5 section 3.2
    Wanninkhof (1992) [for gas transfer and Schmidt number]
        Relationship between wind speed and gas exchange over the ocean   
    Sweeney et al. (2007) [for gas transfer scale factor]
        Constraining global air‐sea gas exchange for CO2 with recent bomb 14C measurements
    Sarmiento and Gruber (2007) [for overview and discussion of CO2 flux]
        Ocean biogeochmiecal dynsmics, Ch3 see panel 3.2.1
    
    Notes
    ============
    this code is optimized to work with Xarray
    
    ## Notes on partial pressure moist air
    P_h20/P = saturation vapor pressure (Weiss and Price 1980)
    Water vapor is generally assumed to be at saturation in the vicinity of the air-sea interfae.
        p_moist = X_dry (P - P_h20)
                = x_dry * P (1-P_h20/P)
                = P_dry (1-P_h20/P)

    ## Notes on U2
    Need to add wind speed variance if using Wanninkhof (1992)
    If we don't, then we are underestimating the gas-transfer velocity
    U2 = (U_mean)^2 + (U_prime)^2, (U_prime)^2 is the standard deviation
    See Sarmiento and Gruber (2007) for a discussion of this
    
    ## Test values
    # T = 298.15
    # S = 35
    
    '''

    # ==================================================================
    # 0. Conversions
    # ==================================================================
    # Convert from Celsius to kelvin
    T_kelvin = T + 273.15

    # ==================================================================
    # 1. partial pressure of CO2 in moist air
    #    Units : uatm
    # ==================================================================
    # Weiss and Price (1980) formula
    ## P_sat_vapor = xu.exp(24.4543 - 67.4509*(100/T_kelvin) - 4.8489*xu.log(T_kelvin/100) - 0.000544*S)

    # Following Dickson et al (2007) Chapter 5 section 3.2
    a1 = -7.85951783
    a2 = 1.84408259
    a3 = -11.7866497
    a4 = 22.6807411
    a5 = -15.9618719
    a6 = 1.80122502

    Tc = 647.096
    pc = (22.064 * 10**6) / 101325
    g = (1 - (T_kelvin / Tc))

    # pure water saturation vapor pressure, Wagner and Pruß, 2002
    p_h20 = pc * xu.exp(
        (Tc / T_kelvin) * (a1 * g + a2 * g**(1.5) + a3 * g**(3) + a4 * g**
                           (3.5) + a5 * g**(4) + a6 * g**(7.5)))

    # total molality
    MT = (31.998 * S) / (1000 - 1.005 * S)

    # osmotic coefficient at 25C by Millero (1974)
    b1 = 0.90799
    b2 = -0.08992
    b3 = 0.18458
    b4 = -0.07395
    b5 = -0.00221
    phi = b1 + b2 * (0.5 * MT) + b3 * (0.5 * MT)**2 + b4 * (
        0.5 * MT)**3 + b5 * (0.5 * MT)**4

    # vapor pressure above sea-water, Dickson et al. (2007), Chapter 5, section 3.2
    P_sat_vapor = p_h20 * xu.exp(-0.018 * phi * MT)

    # Partial pressure of CO2 in moist air, Dickson et al. (2007), SOP 4 section 8.3
    P_moist = (P * xCO2) * (1 - P_sat_vapor)

    # ==================================================================
    # 2. Solubility of CO2
    #    Notes : T in degC, S in PSU,
    #            1.0E-6 converts to correct to muatm
    #    Units : to mol.kg^{-1}uatm^{-1}
    #    Reference : Weiss (1974)
    # ==================================================================
    S_co2 = xu.exp( 9345.17 / T_kelvin - 60.2409 + \
                     23.3585 * xu.log( T_kelvin / 100 ) + \
                     S * ( 0.023517 - 0.00023656 * T_kelvin + \
                          0.0047036 * ( T_kelvin / 100 )**2 )) *1.0E-6

    # ==================================================================
    # 3. Gas transfer velocity
    #    Units : cm/hr
    #    Reference : Wanninkhof (1992)
    #                Sweeney et al. (2007)
    #                per.comm with P. Landschutzer Feb. 19 2019
    # ==================================================================
    # Dimensionless Schmidt number (Sc)
    # References Wanninkhof 1992
    A = 2073.1
    B = 125.62
    C = 3.6276
    D = 0.043219

    # Schmidt number
    # units : dimensionless
    Sc = A - B * T + C * T**2 - D * T**3

    # Gas transfer velocity
    # References :  Wanninkhof 1992,
    #               Sweeney et al. 2007 scale factor
    k_w = scale_factor * (Sc / 660)**(-0.5) * (u_mean**2 + u_var)

    # ================================================
    # 4. air-sea CO2 exchange
    #    Units : mol/m2/yr
    #    Reference : Wanninkhof (1992)
    # ================================================
    # Convert from cm*mol/hr/kg to mol/m2/yr
    conversion = (1000 / 100) * 365 * 24

    # Air-sea CO2 flux
    F_co2 = k_w * S_co2 * (1 - iceFrac) * (P_moist - pCO2_sw) * conversion

    return F_co2
コード例 #17
0
ファイル: msg_base.py プロジェクト: davidh-ssec/satpy
    def _tl15(self, data, wavenumber):
        """Compute the L15 temperature."""

        return ((C2 * wavenumber) /
                xu.log((1.0 / data) * C1 * wavenumber ** 3 + 1.0))
コード例 #18
0
ファイル: seviri_base.py プロジェクト: trz228/satpy
    def _tl15(self, data, wavenumber):
        """Compute the L15 temperature."""

        return ((C2 * wavenumber) /
                xu.log((1.0 / data) * C1 * wavenumber**3 + 1.0))