コード例 #1
0
ファイル: sgdrfile.py プロジェクト: GAGNHAI/pysiral
 def reform_waveform(self, mds_ra2, mds_wfm18hz):
     # Relevant field names
     wfm_tag = "average_wfm_if_corr_ku"
     tracker_range_tag = "18hz_tracker_range_no_doppler_ku"
     doppler_tag = "18Hz_ku_range_doppler"
     slope_tag = "18Hz_ku_range_doppler_slope"
     # First get the echo power
     n_range_bins = 128
     n = self.n_records * self.n_blocks
     self.power = np.ndarray(shape=(n, n_range_bins), dtype=np.float32)
     for dsd in range(self.n_records):
         for block in range(self.n_blocks):
             i = dsd*self.n_blocks + block
             self.power[i, :] = mds_wfm18hz[dsd].wfm[block][wfm_tag]
     # Calculate the window delay for each 18hz waveform
     range_info = get_structarr_attr(mds_ra2, "range_information")
     range_corr = get_structarr_attr(mds_ra2, "range_correction")
     tracker_range = get_structarr_attr(
         range_info, tracker_range_tag, flat=True)
     doppler_correction = get_structarr_attr(
         range_corr, doppler_tag, flat=True)
     slope_correction = get_structarr_attr(
         range_corr, slope_tag, flat=True)
     # Compute the window delay (range to first range bin)
     # given in meter (not in seconds)
     # XXX: Add the instrumental range correction for ku?
     self.window_delay_m = get_envisat_window_delay(
         tracker_range, doppler_correction, slope_correction)
     # Compute the range value for each range bin of the 18hz waveform
     # XXX: Might want to set the range bins automatically
     self.range = get_envisat_wfm_range(self.window_delay_m, n_range_bins)
コード例 #2
0
ファイル: io_adapter.py プロジェクト: cherishing99/pysiral
    def _transfer_timeorbit(self):

        # Transfer the orbit position
        longitude = get_structarr_attr(self.cs2l1b.time_orbit, "longitude")
        latitude = get_structarr_attr(self.cs2l1b.time_orbit, "latitude")
        altitude = get_structarr_attr(self.cs2l1b.time_orbit, "altitude")
        self.l1b.time_orbit.set_position(longitude, latitude, altitude)

        # Transfer the timestamp
        tai_objects = get_structarr_attr(self.cs2l1b.time_orbit,
                                         "tai_timestamp")
        tai_timestamp = get_tai_datetime_from_timestamp(tai_objects)

        # Convert the TAI timestamp to UTC
        # XXX: Note, the leap seconds are only corrected based on the
        # first timestamp to avoid having identical timestamps.
        # In the unlikely case this will cause problems in orbits that
        # span over a leap seconds change, set check_all=True
        converter = UTCTAIConverter()
        utc_timestamp = converter.tai2utc(tai_timestamp, check_all=False)
        self.l1b.time_orbit.timestamp = utc_timestamp

        # Set antenna pitch, roll, yaw (dummy values for now)
        dummy_val = np.full(longitude.shape, np.nan)
        self.l1b.time_orbit.set_antenna_attitude(dummy_val, dummy_val,
                                                 dummy_val)
コード例 #3
0
ファイル: sgdrfile.py プロジェクト: GAGNHAI/pysiral
 def reform_surface_type_flags(self, mds):
     flag = get_structarr_attr(mds, "flag")
     surface_type = get_structarr_attr(flag, "altimeter_surface_type")
     radiometer_flag = get_structarr_attr(flag, "radiometer_land_ocean")
     sea_ice_flag = get_structarr_attr(flag, "sea_ice")
     self.surface_type = np.repeat(surface_type, self.n_blocks)
     self.radiometer_flag = np.repeat(radiometer_flag, self.n_blocks)
     self.sea_ice_flag = np.repeat(sea_ice_flag, self.n_blocks)
コード例 #4
0
ファイル: io_adapter.py プロジェクト: GAGNHAI/pysiral
 def _transfer_range_corrections(self):
     # Transfer all the correction in the list
     # TODO: This is too complicated. The unification of grc names should be handled in the l1p config files
     for key in self.cs2l1b.corrections[0].keys():
         if key in self._config.CORRECTION_LIST:
             self.l1b.correction.set_parameter(
                 key, get_structarr_attr(self.cs2l1b.corrections, key))
     # CryoSat-2 specific: Two different sources of ionospheric corrections
     options = self._config.get_mission_defaults(self._mission)
     key = options["ionospheric_correction_source"]
     ionospheric = get_structarr_attr(self.cs2l1b.corrections, key)
     self.l1b.correction.set_parameter("ionospheric", ionospheric)
コード例 #5
0
ファイル: sgdrfile.py プロジェクト: GAGNHAI/pysiral
 def reform_geophysical_corrections(self, mds, grc_targets):
     """
     Automatically extract the corrections and replicate 1Hz => 18 Hz
     grc_targets is defined in config/mission_def.yaml
     -> envisat.settings.geophysical_correction_targets
     """
     self.sgdr_geophysical_correction_list = []
     for key in grc_targets.keys():
         mds_group = get_structarr_attr(mds, key)
         for correction_name in grc_targets[key]:
             correction = get_structarr_attr(mds_group, correction_name)
             setattr(self, correction_name,
                     np.repeat(correction, self.n_blocks))
             self.sgdr_geophysical_correction_list.append(correction_name)
コード例 #6
0
ファイル: io_adapter.py プロジェクト: GAGNHAI/pysiral
 def _transfer_surface_type_data(self):
     # L1b surface type flag word
     surface_type = get_structarr_attr(self.cs2l1b.corrections,
                                       "surface_type")
     for key in ESA_SURFACE_TYPE_DICT.keys():
         flag = surface_type == ESA_SURFACE_TYPE_DICT[key]
         self.l1b.surface_type.add_flag(flag, key)
コード例 #7
0
ファイル: sgdrfile.py プロジェクト: GAGNHAI/pysiral
 def reform_timestamp(self, mds):
     """ Creates an array of datetime objects for each 18Hz record """
     # XXX: Current no microsecond correction
     timestamp = np.ndarray(shape=(self.n_records), dtype=object)
     mdsr_timestamp = get_structarr_attr(mds, "utc_timestamp")
     for i in range(self.n_records):
         timestamp[i] = mdsr_timestamp_to_datetime(mdsr_timestamp[i])
     self.timestamp = np.repeat(timestamp, self.n_blocks)
コード例 #8
0
ファイル: sgdrfile.py プロジェクト: GAGNHAI/pysiral
 def reform_position(self, mds):
     # 0) Get the relevant data blocks
     time_orbit = get_structarr_attr(mds, "time_orbit")
     range_block = get_structarr_attr(mds, "range_information")
     # 1) get the 1Hz data from the time_orbit group
     longitude = get_structarr_attr(time_orbit, "longitude")
     latitude = get_structarr_attr(time_orbit, "latitude")
     altitude = get_structarr_attr(time_orbit, "altitude")
     # 2) Get the increments
     lon_inc = get_structarr_attr(range_block, "18hz_longitude_differences")
     lat_inc = get_structarr_attr(range_block, "18hz_latitude_differences")
     alt_inc = get_structarr_attr(time_orbit, "18hz_altitude_differences")
     # 3) Expand the 1Hz position arrays
     self.longitude = np.repeat(longitude, self.n_blocks)
     self.latitude = np.repeat(latitude, self.n_blocks)
     self.altitude = np.repeat(altitude, self.n_blocks)
     # 4) Apply the increments
     # XXX: Current version of get_struct_arr returns datatype objects
     #      for listcontainers => manually set dtype
     self._apply_18Hz_increment(self.longitude, lon_inc.astype(np.float32))
     self._apply_18Hz_increment(self.latitude, lat_inc.astype(np.float32))
     self._apply_18Hz_increment(self.altitude, alt_inc.astype(np.float32))
コード例 #9
0
    def reform_flags(self, mds):
        """
        Retrieves a set of paramaters from the Envisat mds, that are needed
        as flags for waveform flagging and surface type filtering.

        Get the following parameters for the waveform is_valid flag:

        1) MCD flags (time_orbit.measurement_confidence_data)

           mcd[0]: packet_length_error
           mcd[1]: obdh_invalid
           mcd[4]: agc_fault
           mcd[5]: rx_delay_fault
           mcd[6]: waveform_fault

        2) average_ku_chirp_band (must be 0: 320Mhz)

        Get the follwing parameter for surface type classification/filtering

            sea_ice_backscatter: backscatter.18hz_sea_ice_sigma_ku

        """
        time_orbit = get_structarr_attr(mds, "time_orbit")
        mcd = get_structarr_attr(time_orbit, "measurement_confidence_data")
        self.flag_packet_length_error = np.repeat(
            np.array([record.flag[0] for record in mcd], dtype=bool),
            self.n_blocks)
        self.flag_obdh_invalid = np.repeat(
            np.array([record.flag[1] for record in mcd], dtype=bool),
            self.n_blocks)
        self.flag_agc_fault = np.repeat(
            np.array([record.flag[4] for record in mcd], dtype=bool),
            self.n_blocks)
        self.flag_rx_delay_fault = np.repeat(
            np.array([record.flag[5] for record in mcd], dtype=bool),
            self.n_blocks)
        self.flag_waveform_fault = np.repeat(
            np.array([record.flag[6] for record in mcd], dtype=bool),
            self.n_blocks)
        flags = get_structarr_attr(mds, "flag")
        self.ku_chirp_band_id = np.repeat(
            get_structarr_attr(flags, "average_ku_chirp_band"), self.n_blocks)
        # This needed for surface type classifiation
        backscatter = get_structarr_attr(mds, "backscatter")
        self.sea_ice_backscatter = np.array(get_structarr_attr(
            backscatter, "18hz_sea_ice_sigma_ku", flat=True),
                                            dtype=np.float32)
コード例 #10
0
ファイル: io_adapter.py プロジェクト: GAGNHAI/pysiral
    def _transfer_classifiers(self):

        # Add L1b beam parameter group
        beam_parameter_list = [
            "stack_standard_deviation", "stack_centre",
            "stack_scaled_amplitude", "stack_skewness", "stack_kurtosis"
        ]
        for beam_parameter_name in beam_parameter_list:
            recs = get_structarr_attr(self.cs2l1b.waveform, "beam")
            beam_parameter = [rec[beam_parameter_name] for rec in recs]
            self.l1b.classifier.add(beam_parameter, beam_parameter_name)

        # Calculate Parameters from waveform counts
        # XXX: This is a legacy of the CS2AWI IDL processor
        #      Threshold defined for waveform counts not power in dB
        wfm = get_structarr_attr(self.cs2l1b.waveform, "wfm")

        # Calculate the OCOG Parameter (CryoSat-2 notation)
        ocog = CS2OCOGParameter(wfm)
        self.l1b.classifier.add(ocog.width, "ocog_width")
        self.l1b.classifier.add(ocog.amplitude, "ocog_amplitude")

        # Calculate the Peakiness (CryoSat-2 notation)
        pulse = CS2PulsePeakiness(wfm)
        self.l1b.classifier.add(pulse.peakiness, "peakiness")
        self.l1b.classifier.add(pulse.peakiness_r, "peakiness_r")
        self.l1b.classifier.add(pulse.peakiness_l, "peakiness_l")

        # fmi version: Calculate the LTPP
        ltpp = CS2LTPP(wfm)
        self.l1b.classifier.add(ltpp.ltpp, "late_tail_to_peak_power")

        # Add the peak power (in Watts)
        # (use l1b waveform power array that is already in physical units)
        peak_power = get_waveforms_peak_power(self.l1b.waveform.power, dB=True)
        self.l1b.classifier.add(peak_power, "peak_power_db")

        # Compute the leading edge width (requires TFMRA retracking)
        wfm = self.l1b.waveform.power
        rng = self.l1b.waveform.range
        radar_mode = self.l1b.waveform.radar_mode
        is_ocean = self.l1b.surface_type.get_by_name("ocean").flag
        # fmi version: add of LEW
        width = TFMRALeadingEdgeWidth(rng, wfm, radar_mode, is_ocean)
        lew = width.get_width_from_thresholds(0.05, 0.95)
        lew1 = width.get_width_from_thresholds(0.05, 0.5)
        lew2 = width.get_width_from_thresholds(0.5, 0.95)
        self.l1b.classifier.add(lew, "leading_edge_width")
        self.l1b.classifier.add(lew1, "leading_edge_width_first_half")
        self.l1b.classifier.add(lew2, "leading_edge_width_second_half")
        self.l1b.classifier.add(width.fmi, "first_maximum_index")

        # Compute sigma nought
        peak_power = get_waveforms_peak_power(self.l1b.waveform.power)
        tx_power = get_structarr_attr(self.cs2l1b.measurement, "tx_power")
        altitude = self.l1b.time_orbit.altitude
        v = get_structarr_attr(self.cs2l1b.time_orbit, "satellite_velocity")
        vx2, vy2, vz2 = v[:, 0]**2., v[:, 1]**2., v[:, 2]**2
        vx2, vy2, vz2 = vx2.astype(float), vy2.astype(float), vz2.astype(float)
        velocity = np.sqrt(vx2 + vy2 + vz2)
        sigma0 = get_sar_sigma0(peak_power, tx_power, altitude, velocity)
        self.l1b.classifier.add(sigma0, "sigma0")