def split_at_large_non_ocean_segments(self, l1): """ Identify larger segments that are not ocean (land, land ice) and split the segments if necessary. The return value will always be a list of Level-1 object instances, even if no non-ocean data segment is present in the input data file :param l1: Input Level-1 object :return: a list of Level-1 objects. """ # Identify connected non-ocean segments within the orbit ocean = l1.surface_type.get_by_name("ocean") not_ocean_flag = np.logical_not(ocean.flag) segments_len, segments_start, not_ocean = rle(not_ocean_flag) landseg_index = np.where(not_ocean)[0] # no non-ocean segments, return full segment if len(landseg_index) == 0: return [l1] # Test if non-ocean segments above the size threshold that will require a split of the segment. # The motivation behind this step to keep l1p data files as small as possible, while tolerating # smaller non-ocean sections treshold = self.cfg.polar_ocean.allow_nonocean_segment_nrecords large_landsegs_index = np.where( segments_len[landseg_index] > treshold)[0] large_landsegs_index = landseg_index[large_landsegs_index] # no segment split necessary, return full segment if len(large_landsegs_index) == 0: return [l1] # Split of orbit segment required, generate individual Level-1 segments from the ocean segments l1_segments = [] start_index = 0 for index in large_landsegs_index: stop_index = segments_start[index] subset_list = np.arange(start_index, stop_index) l1_segments.append(l1.extract_subset(subset_list)) start_index = segments_start[index + 1] # Extract the last subset last_subset_list = np.arange(start_index, len(ocean.flag)) l1_segments.append(l1.extract_subset(last_subset_list)) # Return a list of segments return l1_segments
def split_at_large_non_ocean_segments(self, l1b): """ Identify larger segments that are not ocean (land, land ice) and split the segments if necessary """ # Find connected nonocean segments self.log.info("- test for inner larger landmasses") ocean = l1b.surface_type.get_by_name("ocean") not_ocean_flag = np.logical_not(ocean.flag) segments_len, segments_start, not_ocean = rle(not_ocean_flag) landseg_index = np.where(not_ocean)[0] self.log.info("- number of landmasses: %g" % len(landseg_index)) # no land segements, return segment if len(landseg_index) == 0: return [l1b] # Test if nonocean segments above threshold treshold = self._mdef.max_inner_nonocean_segment_nrecords large_landsegs_index = np.where( segments_len[landseg_index] > treshold)[0] large_landsegs_index = landseg_index[large_landsegs_index] self.log.info("- number of large landmasses: %g" % len( large_landsegs_index)) # no large land segments, return segment if len(large_landsegs_index) == 0: return [l1b] # Large land segments exist, split the l1b data object l1b_segments = [] start_index = 0 for index in large_landsegs_index: stop_index = segments_start[index] subset_list = np.arange(start_index, stop_index) l1b_segments.append(l1b.extract_subset(subset_list)) start_index = segments_start[index+1] # extract the last subset last_subset_list = np.arange(start_index, len(ocean.flag)) l1b_segments.append(l1b.extract_subset(last_subset_list)) # Return a list of segments return l1b_segments
def filter_small_ocean_segments(self, l1): """ This method sets the surface type flag of very small ocean segments to land. This action should prevent large portions of land staying in the l1 segment is a small fjord etc is crossed. It should also filter out smaller ocean segments that do not have a realistic chance of freeboard retrieval. :param l1: A pysiral.l1bdata.Level1bData instance :return: filtered l1 object """ # Minimum size for valid ocean segments ocean_mininum_size_nrecords = self.cfg.polar_ocean.ocean_mininum_size_nrecords # Get the clusters of ocean parts in the l1 object ocean_flag = l1.surface_type.get_by_name("ocean").flag land_flag = l1.surface_type.get_by_name("land").flag segments_len, segments_start, not_ocean = rle(ocean_flag) # Find smaller than threshold ocean segments small_cluster_indices = np.where( segments_len < ocean_mininum_size_nrecords)[0] # Do not mess with the l1 object if not necessary if len(small_cluster_indices == 0): return l1 # Set land flag -> True for small ocean segments for small_cluster_index in small_cluster_indices: i0 = segments_start[small_cluster_index] i1 = i0 + segments_len[small_cluster_index] land_flag[i0:i1] = True # Update the l1 surface type flag by re-setting the land flag l1.surface_type.add_flag(land_flag, "land") # All done return l1