예제 #1
0
    def create(self, channel_index=None, **kwargs):
        # Azimuth is modified because the convention used by the OCO L1B file is to
        # take both solar and observation angles as viewed from an observer
        # standing in the FOV.  In this convention, the convention for glint
        # would be a relative azimuth difference of 180 degrees, as the
        # spacecraft and sun would be on opposite sides of the sky. However, the
        # radiative transfer convention is that the azimuth angles must be the
        # same for glint (it is "follow the photons" convention). However, we'd
        # like the solar azimuth to not be changed, so as to continue to agree
        # with zenith, so this change of the observation azimuth has the effect
        # of putting everything in a "reverse follow-the-photons" convention,
        # where we look from the satellite to the FOV, then from the FOV to the
        # sun.  Note that because of an old historical reason, however, both
        # zenith angles remain > 0 and < 90, even in the RT convention.

        l1b = self.l1b()
        orig_units = l1b.sounding_azimuth(0).units

        rel_azm_vals = []
        deg_units = rf.Unit("deg")
        for chan_idx in range(l1b.number_spectrometer):
            val = (180 + l1b.sounding_azimuth(chan_idx).convert(deg_units).value) - \
                l1b.solar_azimuth(chan_idx).convert(deg_units).value

            if val > 360:
                val -= 360
            elif val < 0:
                val += 360

            rel_azm_vals.append(val)

        return rf.ArrayWithUnit_double_1(rel_azm_vals, orig_units)
예제 #2
0
    def _as_array_with_unit(self, accessor):

        num_channels = self.l1b().number_spectrometer

        vals = []
        units = None
        for chan_idx in range(num_channels):
            chan_val = accessor(chan_idx)
            vals.append(chan_val.value)
            new_units = chan_val.units
            if units != None and new_units.name != units.name:
                raise param.ParamError(
                    "All units for L1B values must be the same to compact as an array"
                )
            else:
                units = new_units

        val_arr = np.array(vals)

        if len(val_arr.shape) == 1:
            return rf.ArrayWithUnit_double_1(vals, units)
        if len(val_arr.shape) == 2:
            return rf.ArrayWithUnit_double_2(vals, units)
        else:
            raise param.ParamError(
                "Unhandled return value size from L1b class")
예제 #3
0
def test_array_with_unit_param():

    # Check that arrays are correctly handled
    config_def = {
        'creator': ParamReturnCreator(param.ArrayWithUnit),
        'val': rf.ArrayWithUnit_double_1(np.arange(1, 6), "m"),
    }

    config_inst = process_config(config_def)
예제 #4
0
    def spacing(self):
        "Returns the array with unit value for spacing specified regardless if it was specified as an array or scalar value with unit"

        spacing_val = self.high_res_spacing()
        num_channels = self.num_channels()

        if isinstance(spacing_val, rf.DoubleWithUnit):
            # Create an ArrayWithDouble matching the number of channels used
            spacing_used = rf.ArrayWithUnit_double_1(np.full(num_channels, spacing_val.value), spacing_val.units)
        else:
            self.check_num_channels(spacing_val.value.shape[0])
            spacing_used = spacing_val

        return spacing_used
예제 #5
0
    def create(self, **kwargs):

        value = self.value(**kwargs)
        units = self.units()

        num_dims = len(value.shape)
        if num_dims == 3:
            return rf.ArrayWithUnit_double_3(value, units)
        elif num_dims == 2:
            return rf.ArrayWithUnit_double_2(value, units)
        elif num_dims == 1:
            return rf.ArrayWithUnit_double_1(value, units)
        else:
            raise param.ParamError(
                "Unsupported number of dimensions %s for array" % (num_dims))
예제 #6
0
    def create(self, **kwargs):

        import warnings
        warnings.warn("Instead of using this creator use framweork.ArrayWithUnit factory class", DeprecationWarning)

        value = self.value(**kwargs)
        units = self.units()

        num_dims = len(value.shape)
        if num_dims == 3:
            return rf.ArrayWithUnit_double_3(value, units)
        elif num_dims == 2:
            return rf.ArrayWithUnit_double_2(value, units)
        elif num_dims == 1:
            return rf.ArrayWithUnit_double_1(value, units)
        else:
            raise param.ParamError("Unsupported number of dimensions %s for array" % (num_dims))
예제 #7
0
    def create(self, **kwargs):

        coeffs = self.value()
        flags = self.retrieval_flag()
        sounding_number = self.sounding_number()
        order = self.order()
        band_names = self.desc_band_name()
        hdf_group = self.hdf_group()
        scale_uncertainty = self.scale_uncertainty()
        scale_to_stddev = self.scale_to_stddev()
        l1b = self.l1b()

        if scale_uncertainty and scale_to_stddev is None:
            raise param.ParamError(
                "scale_to_stddev must be supplied when scale_uncertainty is True"
            )

        if scale_uncertainty and l1b is None:
            raise param.ParamError(
                "l1b must be supplied when scale_uncertainty is True")

        eof_hdf = rf.HdfFile(self.eof_file())

        eofs = []
        for chan_idx in range(self.num_channels()):
            if (scale_uncertainty):
                chan_rad = l1b.radiance(chan_idx)
                uncert = rf.ArrayWithUnit_double_1(chan_rad.uncertainty,
                                                   chan_rad.units)

                eof_obj = rf.EmpiricalOrthogonalFunction(
                    coeffs[chan_idx], bool(flags[chan_idx]), eof_hdf, uncert,
                    chan_idx, sounding_number, order, band_names[chan_idx],
                    hdf_group, scale_to_stddev)
            else:
                eof_obj = rf.EmpiricalOrthogonalFunction(
                    coeffs[chan_idx], bool(flags[chan_idx]), eof_hdf, chan_idx,
                    sounding_number, order, band_names[chan_idx], hdf_group)

            eofs.append(eof_obj)

        return eofs
예제 #8
0
    def create(self, **kwargs):

        l1b = self.l1b()
        num_channels = l1b.number_spectrometer

        solar_dist_vals = np.empty(num_channels)
        solar_dist_units = None
        for chan_idx in range(num_channels):
            chan_doppler_shift = \
                rf.SolarDopplerShiftPolynomial(l1b.time(chan_idx),
                                               l1b.latitude(chan_idx),
                                               l1b.solar_zenith(chan_idx),
                                               l1b.solar_azimuth(chan_idx),
                                               l1b.altitude(chan_idx),
                                               self.constants(),
                                               self.do_doppler_shift())
            chan_solar_dist = chan_doppler_shift.solar_distance
            solar_dist_vals[chan_idx] = chan_solar_dist.value
            solar_dist_units = chan_solar_dist.units

        return rf.ArrayWithUnit_double_1(solar_dist_vals, solar_dist_units)