From 4790917a1fff0fcc24d67eb1a410057e278c5fa9 Mon Sep 17 00:00:00 2001 From: Adeel Hassan Date: Wed, 28 Dec 2022 18:32:02 +0500 Subject: [PATCH 1/4] improve docstrings for main classes plus light refactoring - use a more succinct cross referencing syntax --- .../core/analyzer/stats_analyzer.py | 2 +- rastervision_core/rastervision/core/box.py | 2 +- .../data/crs_transformer/crs_transformer.py | 2 +- .../core/data/label_store/label_store.py | 3 +- .../semantic_segmentation_label_store.py | 4 +- .../data/raster_source/multi_raster_source.py | 32 ++++--- .../core/data/raster_source/raster_source.py | 58 ++++++------- .../data/raster_source/rasterio_source.py | 85 ++++++++++++++----- .../data/raster_source/rasterized_source.py | 50 +++++++---- .../raster_source/rasterized_source_config.py | 2 +- .../raster_transformer/cast_transformer.py | 2 +- .../raster_transformer/nan_transformer.py | 3 +- .../raster_transformer/reclass_transformer.py | 3 +- .../raster_transformer/stats_transformer.py | 5 +- .../rastervision/core/data/scene.py | 2 +- .../rastervision/core/data/utils/geojson.py | 2 +- .../vector_source/geojson_vector_source.py | 18 +++- .../core/data/vector_source/vector_source.py | 12 +++ .../dataset/classification_dataset.py | 6 +- .../dataset/object_detection_dataset.py | 16 ++-- .../dataset/semantic_segmentation_dataset.py | 10 +-- .../rastervision/pytorch_learner/learner.py | 4 +- 22 files changed, 194 insertions(+), 129 deletions(-) diff --git a/rastervision_core/rastervision/core/analyzer/stats_analyzer.py b/rastervision_core/rastervision/core/analyzer/stats_analyzer.py index 01e2bac8e..ecf8c4da5 100644 --- a/rastervision_core/rastervision/core/analyzer/stats_analyzer.py +++ b/rastervision_core/rastervision/core/analyzer/stats_analyzer.py @@ -6,7 +6,7 @@ class StatsAnalyzer(Analyzer): - """Computes RasterStats against the entire scene set.""" + """Compute imagery statistics of scenes.""" def __init__(self, stats_uri: Optional[str] = None, diff --git a/rastervision_core/rastervision/core/box.py b/rastervision_core/rastervision/core/box.py index 396fd0f8e..54a87646f 100644 --- a/rastervision_core/rastervision/core/box.py +++ b/rastervision_core/rastervision/core/box.py @@ -19,7 +19,7 @@ class BoxSizeError(ValueError): class Box(): - """A multi-purpose box (ie. rectangle).""" + """A multi-purpose box (ie. rectangle) representation .""" def __init__(self, ymin, xmin, ymax, xmax): """Construct a bounding box. diff --git a/rastervision_core/rastervision/core/data/crs_transformer/crs_transformer.py b/rastervision_core/rastervision/core/data/crs_transformer/crs_transformer.py index 15bbfbfa2..07bada140 100644 --- a/rastervision_core/rastervision/core/data/crs_transformer/crs_transformer.py +++ b/rastervision_core/rastervision/core/data/crs_transformer/crs_transformer.py @@ -14,7 +14,7 @@ class CRSTransformer(ABC): """Transforms map points in some CRS into pixel coordinates. - Each transformer is associated with a particular RasterSource. + Each transformer is associated with a particular :class:`.RasterSource`. """ def __init__(self, diff --git a/rastervision_core/rastervision/core/data/label_store/label_store.py b/rastervision_core/rastervision/core/data/label_store/label_store.py index 5b0e71164..1f98f2595 100644 --- a/rastervision_core/rastervision/core/data/label_store/label_store.py +++ b/rastervision_core/rastervision/core/data/label_store/label_store.py @@ -2,8 +2,7 @@ class LabelStore(ABC): - """This defines how to store prediction labels are stored for a scene. - """ + """This defines how to store prediction labels for a scene.""" @abstractmethod def save(self, labels): diff --git a/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store.py b/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store.py index c32d00fc7..2019496d6 100644 --- a/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store.py +++ b/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store.py @@ -28,8 +28,8 @@ class SemanticSegmentationLabelStore(LabelStore): """Storage for semantic segmentation predictions. - Stores class raster as GeoTIFF, and can optionally vectorizes predictions and stores - them in GeoJSON files. + Can store predicted class ID raster and class scores raster as GeoTIFFs, + and can optionally vectorize predictions and store them as GeoJSON files. """ def __init__( diff --git a/rastervision_core/rastervision/core/data/raster_source/multi_raster_source.py b/rastervision_core/rastervision/core/data/raster_source/multi_raster_source.py index 2363f66f9..e353fa63a 100644 --- a/rastervision_core/rastervision/core/data/raster_source/multi_raster_source.py +++ b/rastervision_core/rastervision/core/data/raster_source/multi_raster_source.py @@ -10,14 +10,8 @@ from rastervision.core.data.utils import all_equal -class MultiRasterSourceError(Exception): - pass - - class MultiRasterSource(RasterSource): - """A RasterSource that combines multiple RasterSources by concatenting - their output along the channel dimension (assumed to be the last dimension). - """ + """Merge multiple ``RasterSources`` by concatenating along channel dim.""" def __init__(self, raster_sources: Sequence[RasterSource], @@ -70,9 +64,18 @@ def __init__(self, self.validate_raster_sources() def validate_raster_sources(self) -> None: + """Validate sub-``RasterSources``. + + Checks if: + + - dtypes are same or ``force_same_dtype`` is True. + - each sub-``RasterSource`` is a :class:`.RasterioSource` if extents + not identical. + + """ dtypes = [rs.dtype for rs in self.raster_sources] if not self.force_same_dtype and not all_equal(dtypes): - raise MultiRasterSourceError( + raise ValueError( 'dtypes of all sub raster sources must be the same. ' f'Got: {dtypes} ' '(Use force_same_dtype to cast all to the dtype of the ' @@ -81,18 +84,13 @@ def validate_raster_sources(self) -> None: all_rasterio_sources = all( isinstance(rs, RasterioSource) for rs in self.raster_sources) if not all_rasterio_sources: - raise MultiRasterSourceError( - 'Non-identical extents are only supported ' - 'for RasterioSource raster sources.') - - sub_num_channels = sum(rs.num_channels for rs in self.raster_sources) - if sub_num_channels != self.num_channels: - raise MultiRasterSourceError( - f'num_channels ({self.num_channels}) != sum of num_channels ' - f'of sub raster sources ({sub_num_channels})') + raise NotImplementedError( + 'Non-identical extents are only ' + 'supported for RasterioSource raster sources.') @property def primary_source(self) -> RasterSource: + """Primary sub-``RasterSource``""" return self.raster_sources[self.primary_source_idx] @property diff --git a/rastervision_core/rastervision/core/data/raster_source/raster_source.py b/rastervision_core/rastervision/core/data/raster_source/raster_source.py index 9675dfae7..543224c41 100644 --- a/rastervision_core/rastervision/core/data/raster_source/raster_source.py +++ b/rastervision_core/rastervision/core/data/raster_source/raster_source.py @@ -9,21 +9,14 @@ class ChannelOrderError(Exception): - def __init__(self, channel_order: List[int], num_channels: int): + def __init__(self, channel_order: List[int], num_channels_raw: int): self.channel_order = channel_order - self.num_channels = num_channels - msg = (f'The channel_order={str(channel_order)} contains a ' - f'channel index >= num_channels={num_channels}') + self.num_channels_raw = num_channels_raw + msg = (f'The channel_order ({channel_order}) contains an' + f'index >= num_channels_raw ({num_channels_raw}).') super().__init__(msg) -def validate_channel_order(channel_order: List[int], - num_channels: int) -> None: - for c in channel_order: - if c >= num_channels: - raise ChannelOrderError(channel_order, num_channels) - - class RasterSource(ABC): """A source of raster data. @@ -36,21 +29,24 @@ def __init__(self, num_channels_raw: int, raster_transformers: List['RasterTransformer'] = [], extent: Optional[Box] = None): - """Construct a new RasterSource. + """Constructor. Args: - channel_order: list of channel indices to use when extracting chip from - raw imagery. - num_channels_raw: Number of channels in the raw imagery before applying - channel_order. - raster_transformers: RasterTransformers used to transform chips - whenever they are retrieved. - extent (Optional[Box], optional): Use-specified extent. If None, - the full extent of the raster source is used. + channel_order: list of channel indices to use when extracting chip + from raw imagery. + num_channels_raw: Number of channels in the raw imagery before + applying channel_order. + raster_transformers: ``RasterTransformers`` for transforming chips + whenever they are retrieved. Defaults to ``[]``. + extent: Use-specified extent. If None, the full extent of the + raster source is used. """ if channel_order is None: channel_order = list(range(num_channels_raw)) - validate_channel_order(channel_order, num_channels_raw) + + if any(c >= num_channels_raw for c in channel_order): + raise ChannelOrderError(channel_order, num_channels_raw) + self.channel_order = channel_order self.num_channels_raw = num_channels_raw self.raster_transformers = raster_transformers @@ -58,35 +54,33 @@ def __init__(self, @property def num_channels(self) -> int: + """Number of channels in the chips read from this source.""" return len(self.channel_order) @property def shape(self) -> Tuple[int, int, int]: + """Shape of the raster as a (height, width, num_channels) tuple.""" ymin, xmin, ymax, xmax = self.extent return ymax - ymin, xmax - xmin, self.num_channels @abstractproperty def dtype(self) -> 'np.dtype': - """Return the numpy.dtype of this scene""" + """``numpy.dtype`` of the chips read from this source.""" pass @property def extent(self) -> 'Box': - """Return the extent of the RasterSource. - - Returns: - Box in pixel coordinates with extent - """ + """Extent of the RasterSource.""" return self._extent @abstractproperty def crs_transformer(self) -> 'CRSTransformer': - """Return the associated CRSTransformer.""" + """Associated :class:`.CRSTransformer`.""" pass @abstractmethod def _get_chip(self, window: 'Box') -> 'np.ndarray': - """Return the raw chip located in the window. + """Return raw chip without applying channel_order or transforms. Args: window: Box @@ -155,7 +149,7 @@ def get_chip(self, window: 'Box') -> 'np.ndarray': return chip def get_raw_chip(self, window: 'Box') -> 'np.ndarray': - """Return raw chip without using channel_order or applying transforms. + """Return raw chip without applying channel_order or transforms. Args: window (Box): The window for which to get the chip. @@ -168,7 +162,7 @@ def get_raw_chip(self, window: 'Box') -> 'np.ndarray': def get_image_array(self) -> 'np.ndarray': """Return entire transformed image array. - Not safe to call on very large RasterSources. + .. warning:: Not safe to call on very large RasterSources. Returns: np.ndarray: Array of shape (height, width, channels). @@ -178,7 +172,7 @@ def get_image_array(self) -> 'np.ndarray': def get_raw_image_array(self) -> 'np.ndarray': """Return raw image for the full extent. - Not safe to call on very large RasterSources. + .. warning:: Not safe to call on very large RasterSources. Returns: np.ndarray: Array of shape (height, width, channels). diff --git a/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py b/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py index 7700ea90a..fea6d1c3b 100644 --- a/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py +++ b/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py @@ -20,17 +20,33 @@ log = logging.getLogger(__name__) -def build_vrt(vrt_path: str, image_paths: List[str]) -> None: - """Build a VRT for a set of TIFF files.""" +def build_vrt(vrt_path: str, image_uris: List[str]) -> None: + """Build a VRT for a set of TIFF files. + + Args: + vrt_path (str): Local path for the VRT to be created. + image_uris (List[str]): Image URIs. + """ log.info('Building VRT...') cmd = ['gdalbuildvrt', vrt_path] - cmd.extend(image_paths) + cmd.extend(image_uris) subprocess.run(cmd) def download_and_build_vrt(image_uris: List[str], vrt_dir: str, stream: bool = False) -> str: + """Download images (if needed) and build a VRT for a set of TIFF files. + + Args: + image_uris (List[str]): Image URIs. + vrt_dir (str): Dir where the VRT will be created. + stream (bool, optional): If true, do not download images. + Defaults to False. + + Returns: + str: The path to the created VRT file. + """ if not stream: image_uris = [download_if_needed(uri) for uri in image_uris] vrt_path = os.path.join(vrt_dir, 'index.vrt') @@ -60,8 +76,7 @@ def load_window( chip. If None, no resizing is done. Defaults to None. Returns: - np.ndarray of shape (height, width, channels) where channels is the - number of channels in the image_dataset. + np.ndarray: array of shape (height, width, channels). """ if bands is not None: bands = tuple(bands) @@ -94,26 +109,45 @@ def load_window( def fill_overflow(extent: Box, window: Box, - arr: np.ndarray, + chip: np.ndarray, fill_value: int = 0) -> np.ndarray: - """Given a window and corresponding array of values, if the window - overflows the extent, fill the overflowing regions with fill_value. + """Where ``chip``'s ``window`` overflows extent, fill with ``fill_value``. + + Args: + extent (Box): Extent. + window (Box): Window from which ``chip`` was read. + chip (np.ndarray): (H, W, C) array. + fill_value (int, optional): Value to set oveflowing pixels to. + Defaults to 0. + + Returns: + np.ndarray: Chip with overflowing regions filled with ``fill_value``. """ top_overflow = max(0, extent.ymin - window.ymin) bottom_overflow = max(0, window.ymax - extent.ymax) left_overflow = max(0, extent.xmin - window.xmin) right_overflow = max(0, window.xmax - extent.xmax) - h, w = arr.shape[:2] - arr[:top_overflow] = fill_value - arr[h - bottom_overflow:] = fill_value - arr[:, :left_overflow] = fill_value - arr[:, w - right_overflow:] = fill_value - return arr + h, w = chip.shape[:2] + chip[:top_overflow] = fill_value + chip[h - bottom_overflow:] = fill_value + chip[:, :left_overflow] = fill_value + chip[:, w - right_overflow:] = fill_value + return chip def get_channel_order_from_dataset( image_dataset: 'DatasetReader') -> List[int]: + """Get channel order from rasterio image dataset. + + Accounts for dataset's ``colorinterp`` if defined. + + Args: + image_dataset (DatasetReader): Rasterio image dataset. + + Returns: + List[int]: List of channel indices. + """ colorinterp = image_dataset.colorinterp if colorinterp: channel_order = [ @@ -126,7 +160,7 @@ def get_channel_order_from_dataset( class RasterioSource(RasterSource): - """A rasterio-based RasterSource. + """A rasterio-based :class:`.RasterSource`. This RasterSource can read any file that can be opened by `Rasterio/GDAL `_. @@ -224,11 +258,14 @@ def __init__(self, @property def num_channels(self) -> int: - """Needed since transformers can change output channels. + """Number of channels in the chips read from this source. + + .. note:: - Unlike the parent class, RasterioSource applies channel_order (via - bands_to_read) before raster_transformers. So the number of output - channels is not guaranteed to be equal to len(channel_order). + Unlike the parent class, ``RasterioSource`` applies channel_order + (via ``bands_to_read``) before ``raster_transformers``. So the + number of output channels is not guaranteed to be equal to + ``len(channel_order)``. """ if self._num_channels is None: self._set_info_from_chip() @@ -250,8 +287,10 @@ def _set_info_from_chip(self): self._dtype = test_chip.dtype self._num_channels = test_chip.shape[-1] - def download_data(self, tmp_dir: str, stream: bool = False) -> str: - """Download any data needed for this Raster Source. + def download_data(self, + vrt_dir: Optional[str] = None, + stream: bool = False) -> str: + """Download any data needed for this raster source. Return a single local path representing the image or a VRT of the data. """ @@ -261,7 +300,9 @@ def download_data(self, tmp_dir: str, stream: bool = False) -> str: else: return download_if_needed(self.uris[0]) else: - return download_and_build_vrt(self.uris, tmp_dir, stream=stream) + if vrt_dir is None: + raise ValueError('vrt_dir is required if using >1 image URIs.') + return download_and_build_vrt(self.uris, vrt_dir, stream=stream) def _get_chip(self, window: Box, diff --git a/rastervision_core/rastervision/core/data/raster_source/rasterized_source.py b/rastervision_core/rastervision/core/data/raster_source/rasterized_source.py index d796f4a9e..ad30aa30d 100644 --- a/rastervision_core/rastervision/core/data/raster_source/rasterized_source.py +++ b/rastervision_core/rastervision/core/data/raster_source/rasterized_source.py @@ -15,9 +15,23 @@ def geoms_to_raster(df: gpd.GeoDataFrame, window: 'Box', - background_class_id: int, all_touched: bool, - extent: 'Box') -> np.ndarray: - """Rasterize geometries that intersect with the window.""" + background_class_id: int, all_touched: bool) -> np.ndarray: + """Rasterize geometries that intersect with the window. + + Args: + df (gpd.GeoDataFrame): All label geometries in the scene. + window (Box): The part of the scene to rasterize. + background_class_id (int): Class ID to use for pixels that don't + fall under any label geometry. + all_touched (bool): If True, all pixels touched by geometries will be + burned in. If false, only pixels whose center is within the + polygon or that are selected by Bresenham's line algorithm will be + burned in. (See :func:`.rasterize` for more details). + Defaults to False. + + Returns: + np.ndarray: A raster. + """ if len(df) == 0: return np.full(window.size, background_class_id, dtype=np.uint8) @@ -44,7 +58,7 @@ def geoms_to_raster(df: gpd.GeoDataFrame, window: 'Box', class RasterizedSource(RasterSource): - """A RasterSource based on the rasterization of a VectorSource.""" + """A :class:`.RasterSource` based on the rasterization of a VectorSource.""" def __init__(self, vector_source: 'VectorSource', @@ -63,8 +77,8 @@ def __init__(self, geometries will be burned in. If false, only pixels whose center is within the polygon or that are selected by Bresenham's line algorithm will be burned in. - (See rasterio.features.rasterize for more details). Defaults - to False. + (See :func:`~rasterio.features.rasterize` for more details). + Defaults to False. """ self.vector_source = vector_source self.background_class_id = background_class_id @@ -81,38 +95,44 @@ def __init__(self, @property def dtype(self) -> np.dtype: - """Return the numpy.dtype of this scene""" return np.uint8 @property def crs_transformer(self): return self.vector_source.crs_transformer - def _get_chip(self, window): + def _get_chip(self, window: 'Box') -> np.ndarray: """Return the chip located in the window. - Polygons falling within the window are rasterized using the class_id, and - the background is filled with background_class_id. Also, any pixels in the - window outside the extent are zero, which is the don't-care class for - segmentation. + Polygons falling within the window are rasterized using their + ``class_id`` property and the background is filled with + ``background_class_id``. Args: - window: Box + window (Box): Window to read. Returns: - [height, width, channels] numpy array + np.ndarray: [height, width, channels] numpy array """ log.debug(f'Rasterizing window: {window}') chip = geoms_to_raster( self.df, window, background_class_id=self.background_class_id, - extent=self.extent, all_touched=self.all_touched) # Add third singleton dim since rasters must have >=1 channel. return np.expand_dims(chip, 2) def validate_labels(self, df: gpd.GeoDataFrame) -> None: + """Validate label geometries. + + Args: + df (gpd.GeoDataFrame): Label geometries. + + Raises: + ValueError: If ``Point`` or ``LineString`` geometries found. + ValueError: If geometries are missing class IDs. + """ geom_types = set(df.geom_type) if 'Point' in geom_types or 'LineString' in geom_types: raise ValueError('LineStrings and Points are not supported ' diff --git a/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py b/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py index 968f4fb0d..a2b5e7d42 100644 --- a/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py +++ b/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py @@ -16,7 +16,7 @@ class RasterizerConfig(Config): False, description='If True, all pixels touched by geometries will be burned ' 'in. If false, only pixels whose center is within the polygon or that ' - 'are selected by Bresenham’s line algorithm will be burned in. ' + 'are selected by Bresenham\'s line algorithm will be burned in. ' '(See rasterio.features.rasterize for more details).') diff --git a/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer.py b/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer.py index edbf2d861..e3f9dcc9e 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer.py @@ -7,7 +7,7 @@ class CastTransformer(RasterTransformer): - """ Casts chips to the specified dtype. """ + """Casts chips to the specified dtype.""" def __init__(self, to_dtype: str): """Constructor. diff --git a/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer.py b/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer.py index f4c161a6a..f8b69ae1c 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer.py @@ -5,8 +5,7 @@ class NanTransformer(RasterTransformer): - """Removes NaN values from float raster - """ + """Removes NaN values from float raster.""" def __init__(self, to_value: float = 0.0): """Construct a new NanTransformer. diff --git a/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer.py b/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer.py index 16ceb866c..97c2d8c58 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer.py @@ -6,8 +6,7 @@ class ReclassTransformer(RasterTransformer): - """Reclassifies label raster - """ + """Maps class IDs in a label raster to other values.""" def __init__(self, mapping: Dict[int, int]): """Construct a new ReclassTransformer. diff --git a/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer.py b/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer.py index 6a9920d5b..ecf2dd3e1 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer.py @@ -12,10 +12,11 @@ class StatsTransformer(RasterTransformer): """Transforms non-uint8 to uint8 values using channel statistics. This works as follows: + - Convert pixel values to z-scores using channel means and standard - deviations. + deviations. - Clip z-scores to the specified number of standard deviations (default 3) - on each side. + on each side. - Scale values to 0-255 and cast to uint8. This transformation is not applied to NODATA pixels (assumed to be pixels diff --git a/rastervision_core/rastervision/core/data/scene.py b/rastervision_core/rastervision/core/data/scene.py index 487592755..f125942c4 100644 --- a/rastervision_core/rastervision/core/data/scene.py +++ b/rastervision_core/rastervision/core/data/scene.py @@ -34,7 +34,7 @@ def __init__(self, @property def extent(self) -> 'Box': - """Extent of the associated RasterSource.""" + """Extent of the associated :class:`.RasterSource`.""" return self.raster_source.extent def __getitem__(self, key: Any) -> Tuple[Any, Any]: diff --git a/rastervision_core/rastervision/core/data/utils/geojson.py b/rastervision_core/rastervision/core/data/utils/geojson.py index 471b80d97..c7af19be4 100644 --- a/rastervision_core/rastervision/core/data/utils/geojson.py +++ b/rastervision_core/rastervision/core/data/utils/geojson.py @@ -254,7 +254,7 @@ def simplify_polygons(geojson: dict) -> dict: 1. *Sometimes* break up a polygon with "bowties" into multiple polygons. (See https://github.com/shapely/shapely/issues/599.) 2. *Sometimes* "simplify" polygons. See shapely documentation for - :function:``buffer``. + :meth:`.BaseGeometry.buffer`. Args: geojson (dict): A GeoJSON-like mapping of a FeatureCollection. diff --git a/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source.py b/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source.py index 533eef5d7..6572f5698 100644 --- a/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source.py +++ b/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source.py @@ -8,11 +8,27 @@ class GeoJSONVectorSource(VectorSource): + """A :class:`.VectorSource` for reading GeoJSON files.""" + def __init__(self, uri: str, crs_transformer: 'CRSTransformer', vector_transformers: List['VectorTransformer'] = [], ignore_crs_field: bool = False): + """Constructor. + + Args: + uri (str): URI of the GeoJSON file. + crs_transformer: A ``CRSTransformer`` to convert + between map and pixel coords. Normally this is obtained from a + :class:`.RasterSource`. + vector_transformers: ``VectorTransformers`` for transforming + geometries. Defaults to ``[]``. + ignore_crs_field (bool): Ignore the CRS specified in the file and + assume WGS84 (EPSG:4326) coords. Only WGS84 is supported + currently. If False, and the file contains a CRS, will throw an + exception on read. Defaults to False. + """ self.uri = uri self.ignore_crs_field = ignore_crs_field super().__init__( @@ -22,7 +38,7 @@ def _get_geojson(self): # download first so that it gets cached geojson = file_to_json(download_if_needed(self.uri)) if not self.ignore_crs_field and 'crs' in geojson: - raise Exception( + raise NotImplementedError( f'The GeoJSON file at {self.uri} contains a CRS field which ' 'is not allowed by the current GeoJSON standard or by ' 'Raster Vision. All coordinates are expected to be in ' diff --git a/rastervision_core/rastervision/core/data/vector_source/vector_source.py b/rastervision_core/rastervision/core/data/vector_source/vector_source.py index 8b17cd774..a5e00f7cd 100644 --- a/rastervision_core/rastervision/core/data/vector_source/vector_source.py +++ b/rastervision_core/rastervision/core/data/vector_source/vector_source.py @@ -23,6 +23,15 @@ class VectorSource(ABC): def __init__(self, crs_transformer: 'CRSTransformer', vector_transformers: List['VectorTransformer'] = []): + """Constructor. + + Args: + crs_transformer: A ``CRSTransformer`` to convert + between map and pixel coords. Normally this is obtained from a + :class:`.RasterSource`. + vector_transformers: ``VectorTransformers`` for transforming + geometries. Defaults to ``[]``. + """ self.crs_transformer = crs_transformer self.vector_transformers = vector_transformers self._geojson = None @@ -32,6 +41,7 @@ def get_geojson(self, to_map_coords: bool = False) -> dict: """Return transformed GeoJSON. This makes the following transformations to the raw geojson: + - converts to pixels coords (by default) - removes empty features - splits apart multi-geoms and geom collections into single geometries @@ -77,6 +87,7 @@ def _get_geojson(self) -> dict: pass def get_dataframe(self, to_map_coords: bool = False) -> gpd.GeoDataFrame: + """Return geometries as a :class:`~geopandas.GeoDataFrame`.""" geojson = self.get_geojson(to_map_coords=to_map_coords) df = gpd.GeoDataFrame.from_features(geojson) if len(df) == 0 and 'geometry' not in df.columns: @@ -85,6 +96,7 @@ def get_dataframe(self, to_map_coords: bool = False) -> gpd.GeoDataFrame: @property def extent(self) -> Box: + """Envelope of union of all geoms.""" if self._extent is None: envelope = unary_union(self.get_geoms()).envelope self._extent = Box.from_shapely(envelope).to_int() diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/classification_dataset.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/classification_dataset.py index e338b6eac..8897f3df4 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/classification_dataset.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/classification_dataset.py @@ -24,14 +24,12 @@ def __init__(self, data_dir: str, class_names: Optional[Iterable[str]], *args, **kwargs): """Constructor. - .. currentmodule:: rastervision.pytorch_learner.dataset.dataset - Args: data_dir (str): Root directory containing class dirs. class_names (Optional[Iterable[str]]): Class names. Should match class dir names. - *args: See :meth:`ImageDataset.__init__`. - **kwargs: See :meth:`ImageDataset.__init__`. + *args: See :meth:`.ImageDataset.__init__`. + **kwargs: See :meth:`.ImageDataset.__init__`. """ ds = make_image_folder_dataset(data_dir, classes=class_names) super().__init__( diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/object_detection_dataset.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/object_detection_dataset.py index c99789956..1dbb3a7c2 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/object_detection_dataset.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/object_detection_dataset.py @@ -68,23 +68,19 @@ def __len__(self): class ObjectDetectionImageDataset(ImageDataset): """Read Object Detection data in the COCO format. - .. currentmodule:: rastervision.pytorch_learner.dataset.object_detection_dataset - - Uses :class:`CocoDataset` to read the data. + Uses :class:`.CocoDataset` to read the data. """ def __init__(self, img_dir: str, annotation_uri: str, *args, **kwargs): """Constructor. - .. currentmodule:: rastervision.pytorch_learner.dataset.dataset - Args: img_dir (str): Directory containing the images. Image filenames must match the image IDs in the annotations file. annotation_uri (str): URI to a JSON file containing annotations in the COCO format. - *args: See :meth:`ImageDataset.__init__`. - **kwargs: See :meth:`ImageDataset.__init__`. + *args: See :meth:`.ImageDataset.__init__`. + **kwargs: See :meth:`.ImageDataset.__init__`. """ ds = CocoDataset(img_dir, annotation_uri) super().__init__( @@ -167,10 +163,8 @@ class ObjectDetectionRandomWindowGeoDataset(RandomWindowGeoDataset): def __init__(self, *args, **kwargs): """Constructor. - .. currentmodule:: rastervision.pytorch_learner.dataset.dataset - Args: - *args: See :meth:`RandomWindowGeoDataset.__init__`. + *args: See :meth:`.RandomWindowGeoDataset.__init__`. Keyword Args: bbox_params (Optional[A.BboxParams], optional): Optional @@ -190,7 +184,7 @@ def __init__(self, *args, **kwargs): neg_ioa_thresh (float, optional): A window will be considered negative if its max IoA with any bounding box is less than this threshold. Defaults to 0.2. - **kwargs: See :meth:`RandomWindowGeoDataset.__init__`. + **kwargs: See :meth:`.RandomWindowGeoDataset.__init__`. """ self.bbox_params: Optional[A.BboxParams] = kwargs.pop( 'bbox_params', None) diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/semantic_segmentation_dataset.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/semantic_segmentation_dataset.py index 22cf220ef..352b677e7 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/semantic_segmentation_dataset.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/dataset/semantic_segmentation_dataset.py @@ -64,21 +64,17 @@ def __len__(self): class SemanticSegmentationImageDataset(ImageDataset): """Reads semantic segmentatioin images and labels from files. - .. currentmodule:: rastervision.pytorch_learner.dataset.semantic_segmentation_dataset - - Uses :class:`SemanticSegmentationDataReader` to read the data. + Uses :class:`.SemanticSegmentationDataReader` to read the data. """ def __init__(self, img_dir: str, label_dir: str, *args, **kwargs): """Constructor. - .. currentmodule:: rastervision.pytorch_learner.dataset.dataset - Args: img_dir (str): Directory containing images. label_dir (str): Directory containing segmentation masks. - *args: See :meth:`ImageDataset.__init__`. - **kwargs: See :meth:`ImageDataset.__init__`. + *args: See :meth:`.ImageDataset.__init__`. + **kwargs: See :meth:`.ImageDataset.__init__`. """ ds = SemanticSegmentationDataReader(img_dir, label_dir) diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/learner.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/learner.py index 548b2891b..3ddca944b 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/learner.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/learner.py @@ -929,8 +929,6 @@ def from_model_bundle(cls: Type, This is the bundle saved in ``train/model-bundle.zip`` and not ``bundle/model-bundle.zip``. - .. currentmodule:: rastervision.pytorch_learner.learner - Args: model_bundle_uri (str): URI of the model bundle. tmp_dir (Optional[str], optional): Optional temporary directory. @@ -944,7 +942,7 @@ def from_model_bundle(cls: Type, model will be put into eval mode. If True, the training apparatus will be set up and the model will be put into training mode. Defaults to True. - **kwargs: See :meth:`Learner.__init__`. + **kwargs: See :meth:`.Learner.__init__`. Raises: FileNotFoundError: If using custom Albumentations transforms and From 8b2da168a17d2f673f42d6d2872ed5cd3029c8fe Mon Sep 17 00:00:00 2001 From: Adeel Hassan Date: Wed, 28 Dec 2022 18:39:18 +0500 Subject: [PATCH 2/4] improve config docstrings - add link to corresponding class in docstring --- .../core/analyzer/analyzer_config.py | 2 ++ .../core/analyzer/stats_analyzer_config.py | 6 +++++- .../core/backend/backend_config.py | 2 +- .../rastervision/core/data/class_config.py | 3 ++- .../rastervision/core/data/dataset_config.py | 2 +- ...chip_classification_label_source_config.py | 6 +++--- .../data/label_source/label_source_config.py | 2 ++ .../object_detection_label_source_config.py | 3 ++- ...mantic_segmentation_label_source_config.py | 3 ++- ...hip_classification_geojson_store_config.py | 2 +- .../data/label_store/label_store_config.py | 2 ++ .../object_detection_geojson_store_config.py | 2 +- ...emantic_segmentation_label_store_config.py | 2 +- .../multi_raster_source_config.py | 2 ++ .../raster_source/raster_source_config.py | 2 ++ .../raster_source/rasterio_source_config.py | 2 ++ .../raster_source/rasterized_source_config.py | 4 ++++ .../cast_transformer_config.py | 2 ++ .../min_max_transformer_config.py | 2 +- .../nan_transformer_config.py | 2 ++ .../raster_transformer_config.py | 2 ++ .../reclass_transformer_config.py | 2 ++ .../rgb_class_transformer_config.py | 2 ++ .../stats_transformer_config.py | 2 ++ .../rastervision/core/data/scene_config.py | 4 +++- .../geojson_vector_source_config.py | 2 ++ .../vector_source/vector_source_config.py | 2 ++ .../buffer_transformer_config.py | 2 +- .../class_inference_transformer_config.py | 2 ++ .../shift_transformer_config.py | 2 +- .../vector_transformer_config.py | 2 ++ .../chip_classification_evaluator_config.py | 2 ++ .../classification_evaluator_config.py | 2 ++ .../core/evaluation/evaluator_config.py | 2 ++ .../object_detection_evaluator_config.py | 2 ++ .../semantic_segmentation_evaluator_config.py | 2 ++ .../rv_pipeline/chip_classification_config.py | 2 ++ .../rv_pipeline/object_detection_config.py | 2 ++ .../core/rv_pipeline/rv_pipeline_config.py | 3 ++- .../semantic_segmentation_config.py | 2 ++ .../rastervision/pipeline/pipeline_config.py | 2 +- .../pytorch_chip_classification_config.py | 2 ++ .../pytorch_learner_backend_config.py | 2 ++ .../pytorch_object_detection_config.py | 2 ++ .../pytorch_semantic_segmentation_config.py | 2 ++ .../classification_learner_config.py | 11 ++++++++++ .../pytorch_learner/learner_config.py | 10 +++++++++ .../learner_pipeline_config.py | 2 ++ .../object_detection_learner_config.py | 15 +++++++++++++ .../regression_learner_config.py | 11 ++++++++++ .../semantic_segmentation_learner_config.py | 21 ++++++++++++------- 51 files changed, 151 insertions(+), 25 deletions(-) diff --git a/rastervision_core/rastervision/core/analyzer/analyzer_config.py b/rastervision_core/rastervision/core/analyzer/analyzer_config.py index 0d44e8f93..40291938b 100644 --- a/rastervision_core/rastervision/core/analyzer/analyzer_config.py +++ b/rastervision_core/rastervision/core/analyzer/analyzer_config.py @@ -8,6 +8,8 @@ @register_config('analyzer') class AnalyzerConfig(Config): + """Configure an :class:`.Analyzer`.""" + def build(self, scene_group: Optional[Tuple[str, Iterable[str]]] = None ) -> 'Analyzer': pass diff --git a/rastervision_core/rastervision/core/analyzer/stats_analyzer_config.py b/rastervision_core/rastervision/core/analyzer/stats_analyzer_config.py index 6636f3355..ab507f5a7 100644 --- a/rastervision_core/rastervision/core/analyzer/stats_analyzer_config.py +++ b/rastervision_core/rastervision/core/analyzer/stats_analyzer_config.py @@ -10,7 +10,11 @@ @register_config('stats_analyzer') class StatsAnalyzerConfig(AnalyzerConfig): - """Config for an Analyzer that computes imagery statistics of scenes.""" + """Configure a :class:`.StatsAnalyzer`. + + A :class:`.StatsAnalyzer` computes imagery statistics of scenes which can + be used to normalize chips read from them. + """ output_uri: Optional[str] = Field( None, diff --git a/rastervision_core/rastervision/core/backend/backend_config.py b/rastervision_core/rastervision/core/backend/backend_config.py index d5c44d927..1770b3f73 100644 --- a/rastervision_core/rastervision/core/backend/backend_config.py +++ b/rastervision_core/rastervision/core/backend/backend_config.py @@ -9,7 +9,7 @@ @register_config('backend') class BackendConfig(Config): - """Configuration for Backend.""" + """Configure a :class:`.Backend`.""" def build(self, pipeline: 'RVPipeline', tmp_dir: str) -> 'Backend': raise NotImplementedError() diff --git a/rastervision_core/rastervision/core/data/class_config.py b/rastervision_core/rastervision/core/data/class_config.py index a31146546..d0381b3e4 100644 --- a/rastervision_core/rastervision/core/data/class_config.py +++ b/rastervision_core/rastervision/core/data/class_config.py @@ -10,7 +10,8 @@ @register_config('class_config') class ClassConfig(Config): - """Configures the class names that are being predicted.""" + """Configure class information for a machine learning task.""" + names: List[str] = Field( ..., description='Names of classes. The i-th class in this list will have ' diff --git a/rastervision_core/rastervision/core/data/dataset_config.py b/rastervision_core/rastervision/core/data/dataset_config.py index 72b8fe88e..0fd7e12d3 100644 --- a/rastervision_core/rastervision/core/data/dataset_config.py +++ b/rastervision_core/rastervision/core/data/dataset_config.py @@ -19,7 +19,7 @@ def dataset_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config('dataset', upgrader=dataset_config_upgrader) class DatasetConfig(Config): - """Config for a Dataset comprising the scenes for train, valid, and test splits.""" + """Configure train, validation, and test splits for a dataset.""" class_config: ClassConfig train_scenes: List[SceneConfig] validation_scenes: List[SceneConfig] diff --git a/rastervision_core/rastervision/core/data/label_source/chip_classification_label_source_config.py b/rastervision_core/rastervision/core/data/label_source/chip_classification_label_source_config.py index 735758253..4b834491f 100644 --- a/rastervision_core/rastervision/core/data/label_source/chip_classification_label_source_config.py +++ b/rastervision_core/rastervision/core/data/label_source/chip_classification_label_source_config.py @@ -20,10 +20,10 @@ def cc_label_source_config_upgrader(cfg_dict: dict, version: int) -> dict: 'chip_classification_label_source', upgrader=cc_label_source_config_upgrader) class ChipClassificationLabelSourceConfig(LabelSourceConfig): - """Config for a source of labels for chip classification. + """Configure a :class:`.ChipClassificationLabelSource`. - This can be provided explicitly as a grid of cells, or a grid of cells can be - inferred from arbitrary polygons. + This can be provided explicitly as a grid of cells, or a grid of cells can + be inferred from arbitrary polygons. """ vector_source: Optional[VectorSourceConfig] = None ioa_thresh: float = Field( diff --git a/rastervision_core/rastervision/core/data/label_source/label_source_config.py b/rastervision_core/rastervision/core/data/label_source/label_source_config.py index f7ee595ab..10790722d 100644 --- a/rastervision_core/rastervision/core/data/label_source/label_source_config.py +++ b/rastervision_core/rastervision/core/data/label_source/label_source_config.py @@ -3,6 +3,8 @@ @register_config('label_source') class LabelSourceConfig(Config): + """Configure a :class:`.LabelSource`.""" + def build(self, class_config, crs_transformer, extent, tmp_dir): raise NotImplementedError() diff --git a/rastervision_core/rastervision/core/data/label_source/object_detection_label_source_config.py b/rastervision_core/rastervision/core/data/label_source/object_detection_label_source_config.py index f2b9b5102..6b6b5f577 100644 --- a/rastervision_core/rastervision/core/data/label_source/object_detection_label_source_config.py +++ b/rastervision_core/rastervision/core/data/label_source/object_detection_label_source_config.py @@ -8,7 +8,8 @@ @register_config('object_detection_label_source') class ObjectDetectionLabelSourceConfig(LabelSourceConfig): - """Config for a read-only label source for object detection.""" + """Configure an :class:`.ObjectDetectionLabelSource`.""" + vector_source: VectorSourceConfig @validator('vector_source') diff --git a/rastervision_core/rastervision/core/data/label_source/semantic_segmentation_label_source_config.py b/rastervision_core/rastervision/core/data/label_source/semantic_segmentation_label_source_config.py index c4de4341d..16648933b 100644 --- a/rastervision_core/rastervision/core/data/label_source/semantic_segmentation_label_source_config.py +++ b/rastervision_core/rastervision/core/data/label_source/semantic_segmentation_label_source_config.py @@ -21,7 +21,8 @@ def ss_label_source_config_upgrader(cfg_dict: dict, version: int) -> dict: 'semantic_segmentation_label_source', upgrader=ss_label_source_config_upgrader) class SemanticSegmentationLabelSourceConfig(LabelSourceConfig): - """Config for a read-only label source for semantic segmentation.""" + """Configure a :class:`.SemanticSegmentationLabelSource`.""" + raster_source: Union[RasterSourceConfig, RasterizedSourceConfig] = Field( ..., description='The labels in the form of rasters.') diff --git a/rastervision_core/rastervision/core/data/label_store/chip_classification_geojson_store_config.py b/rastervision_core/rastervision/core/data/label_store/chip_classification_geojson_store_config.py index 7c1266e25..9df9b553c 100644 --- a/rastervision_core/rastervision/core/data/label_store/chip_classification_geojson_store_config.py +++ b/rastervision_core/rastervision/core/data/label_store/chip_classification_geojson_store_config.py @@ -8,7 +8,7 @@ @register_config('chip_classification_geojson_store') class ChipClassificationGeoJSONStoreConfig(LabelStoreConfig): - """Config for storage for chip classification predictions.""" + """Configure a :class:`.ChipClassificationGeoJSONStore`.""" uri: Optional[str] = Field( None, diff --git a/rastervision_core/rastervision/core/data/label_store/label_store_config.py b/rastervision_core/rastervision/core/data/label_store/label_store_config.py index 7ff6727bd..7b1dc5bcd 100644 --- a/rastervision_core/rastervision/core/data/label_store/label_store_config.py +++ b/rastervision_core/rastervision/core/data/label_store/label_store_config.py @@ -3,6 +3,8 @@ @register_config('label_store') class LabelStoreConfig(Config): + """Configure a :class:`.LabelStore`.""" + def build(self, class_config, crs_transformer, extent, tmp_dir): pass diff --git a/rastervision_core/rastervision/core/data/label_store/object_detection_geojson_store_config.py b/rastervision_core/rastervision/core/data/label_store/object_detection_geojson_store_config.py index ab89b6647..da7233099 100644 --- a/rastervision_core/rastervision/core/data/label_store/object_detection_geojson_store_config.py +++ b/rastervision_core/rastervision/core/data/label_store/object_detection_geojson_store_config.py @@ -8,7 +8,7 @@ @register_config('object_detection_geojson_store') class ObjectDetectionGeoJSONStoreConfig(LabelStoreConfig): - """Config for storage for object detection predictions.""" + """Configure an :class:`.ObjectDetectionGeoJSONStore`.""" uri: Optional[str] = Field( None, diff --git a/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store_config.py b/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store_config.py index 38d4d0c76..7351abfbd 100644 --- a/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store_config.py +++ b/rastervision_core/rastervision/core/data/label_store/semantic_segmentation_label_store_config.py @@ -91,7 +91,7 @@ def get_mode(self) -> str: @register_config('semantic_segmentation_label_store') class SemanticSegmentationLabelStoreConfig(LabelStoreConfig): - """Config for storage for semantic segmentation predictions. + """Configure a :class:`.SemanticSegmentationLabelStore`. Stores class raster as GeoTIFF, and can optionally vectorizes predictions and stores them in GeoJSON files. diff --git a/rastervision_core/rastervision/core/data/raster_source/multi_raster_source_config.py b/rastervision_core/rastervision/core/data/raster_source/multi_raster_source_config.py index f6608e4ae..8e1575fee 100644 --- a/rastervision_core/rastervision/core/data/raster_source/multi_raster_source_config.py +++ b/rastervision_core/rastervision/core/data/raster_source/multi_raster_source_config.py @@ -18,6 +18,8 @@ def multi_rs_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config('multi_raster_source', upgrader=multi_rs_config_upgrader) class MultiRasterSourceConfig(RasterSourceConfig): + """Configure a :class:`.MultiRasterSource`.""" + raster_sources: conlist( RasterSourceConfig, min_items=1) = Field( ..., description='List of RasterSourceConfig to combine.') diff --git a/rastervision_core/rastervision/core/data/raster_source/raster_source_config.py b/rastervision_core/rastervision/core/data/raster_source/raster_source_config.py index 9e6ad4509..f25d10d03 100644 --- a/rastervision_core/rastervision/core/data/raster_source/raster_source_config.py +++ b/rastervision_core/rastervision/core/data/raster_source/raster_source_config.py @@ -20,6 +20,8 @@ def rs_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config('raster_source', upgrader=rs_config_upgrader) class RasterSourceConfig(Config): + """Configure a :class:`.RasterSource`.""" + channel_order: Optional[List[int]] = Field( None, description= diff --git a/rastervision_core/rastervision/core/data/raster_source/rasterio_source_config.py b/rastervision_core/rastervision/core/data/raster_source/rasterio_source_config.py index bf56cc16e..eefc18cb6 100644 --- a/rastervision_core/rastervision/core/data/raster_source/rasterio_source_config.py +++ b/rastervision_core/rastervision/core/data/raster_source/rasterio_source_config.py @@ -22,6 +22,8 @@ def rasterio_source_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config('rasterio_source', upgrader=rasterio_source_config_upgrader) class RasterioSourceConfig(RasterSourceConfig): + """Configure a :class:`.RasterioSource`.""" + uris: Union[str, List[str]] = Field( ..., description='One or more image URIs that comprise the imagery for a ' diff --git a/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py b/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py index a2b5e7d42..2a0be152e 100644 --- a/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py +++ b/rastervision_core/rastervision/core/data/raster_source/rasterized_source_config.py @@ -8,6 +8,8 @@ @register_config('rasterizer') class RasterizerConfig(Config): + """Configure rasterization params for a :class:`.RasterizedSource`.""" + background_class_id: int = Field( ..., description='The class_id to use for any background pixels, i.e. ' @@ -22,6 +24,8 @@ class RasterizerConfig(Config): @register_config('rasterized_source') class RasterizedSourceConfig(Config): + """Configure a :class:`.RasterizedSource`.""" + vector_source: VectorSourceConfig rasterizer_config: RasterizerConfig diff --git a/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer_config.py index 53c7b6b0b..e01c3efcb 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/cast_transformer_config.py @@ -7,6 +7,8 @@ @register_config('cast_transformer') class CastTransformerConfig(RasterTransformerConfig): + """Configure a :class:`.CastTransformer`.""" + to_dtype: str = Field( ..., description='dtype to cast raster to. Must be a valid Numpy dtype ' diff --git a/rastervision_core/rastervision/core/data/raster_transformer/min_max_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/min_max_transformer_config.py index 16933671c..de8a3a20b 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/min_max_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/min_max_transformer_config.py @@ -5,7 +5,7 @@ @register_config('min_max_transformer') class MinMaxTransformerConfig(RasterTransformerConfig): - """Transforms chips by scaling values in each channel to span 0-255.""" + """Configure a :class:`.MinMaxTransformer`.""" def build(self): return MinMaxTransformer() diff --git a/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer_config.py index 6a21149a4..cf36bbc19 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/nan_transformer_config.py @@ -9,6 +9,8 @@ @register_config('nan_transformer') class NanTransformerConfig(RasterTransformerConfig): + """Configure a :class:`.NanTransformer`.""" + to_value: Optional[float] = Field( 0.0, description=('Turn all NaN values into this value.')) diff --git a/rastervision_core/rastervision/core/data/raster_transformer/raster_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/raster_transformer_config.py index 1f370af42..dcfbb710f 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/raster_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/raster_transformer_config.py @@ -3,6 +3,8 @@ @register_config('raster_transformer') class RasterTransformerConfig(Config): + """Configure a :class:`.RasterTransformer`.""" + def update(self, pipeline=None, scene=None): pass diff --git a/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer_config.py index f6db80d9b..3ed94785c 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/reclass_transformer_config.py @@ -7,6 +7,8 @@ @register_config('reclass_transformer') class ReclassTransformerConfig(RasterTransformerConfig): + """Configure a :class:`.ReclassTransformer`.""" + mapping: Dict[int, int] = Field( ..., description=('The reclassification mapping.')) diff --git a/rastervision_core/rastervision/core/data/raster_transformer/rgb_class_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/rgb_class_transformer_config.py index 1f5536836..0bfad3a2a 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/rgb_class_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/rgb_class_transformer_config.py @@ -6,6 +6,8 @@ @register_config('rgb_class_transformer') class RGBClassTransformerConfig(RasterTransformerConfig): + """Configure a :class:`.RGBClassTransformer`.""" + class_config: ClassConfig = Field( ..., description=('The class config defining the mapping between ' diff --git a/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer_config.py b/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer_config.py index 19e314ebd..d4e9a983c 100644 --- a/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer_config.py +++ b/rastervision_core/rastervision/core/data/raster_transformer/stats_transformer_config.py @@ -24,6 +24,8 @@ def stats_transformer_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config( 'stats_transformer', upgrader=stats_transformer_config_upgrader) class StatsTransformerConfig(RasterTransformerConfig): + """Configure a :class:`.StatsTransformer`.""" + stats_uri: Optional[str] = Field( None, description='The URI of the output of the StatsAnalyzer. ' diff --git a/rastervision_core/rastervision/core/data/scene_config.py b/rastervision_core/rastervision/core/data/scene_config.py index 3d1747d43..c38e98a95 100644 --- a/rastervision_core/rastervision/core/data/scene_config.py +++ b/rastervision_core/rastervision/core/data/scene_config.py @@ -26,7 +26,9 @@ def scene_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config('scene', upgrader=scene_config_upgrader) class SceneConfig(Config): - """Config for Scene which comprises raster data and labels for an AOI.""" + """Configure a :class:`.Scene` comprising raster data & labels for an AOI. + """ + id: str raster_source: RasterSourceConfig label_source: Optional[LabelSourceConfig] = None diff --git a/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source_config.py b/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source_config.py index 77db233f0..24d40466a 100644 --- a/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source_config.py +++ b/rastervision_core/rastervision/core/data/vector_source/geojson_vector_source_config.py @@ -9,6 +9,8 @@ @register_config('geojson_vector_source') class GeoJSONVectorSourceConfig(VectorSourceConfig): + """Configure a :class:`.GeoJSONVectorSource`.""" + uri: str = Field(..., description='The URI of a GeoJSON file.') ignore_crs_field: bool = False diff --git a/rastervision_core/rastervision/core/data/vector_source/vector_source_config.py b/rastervision_core/rastervision/core/data/vector_source/vector_source_config.py index 51c0f3a1a..09ff2d84d 100644 --- a/rastervision_core/rastervision/core/data/vector_source/vector_source_config.py +++ b/rastervision_core/rastervision/core/data/vector_source/vector_source_config.py @@ -44,6 +44,8 @@ def vector_source_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config('vector_source', upgrader=vector_source_config_upgrader) class VectorSourceConfig(Config): + """Configure a :class:`.VectorSource`.""" + transformers: List[VectorTransformerConfig] = Field( [], description='List of VectorTransformers.') diff --git a/rastervision_core/rastervision/core/data/vector_transformer/buffer_transformer_config.py b/rastervision_core/rastervision/core/data/vector_transformer/buffer_transformer_config.py index f9c5e79dd..b3ba9815d 100644 --- a/rastervision_core/rastervision/core/data/vector_transformer/buffer_transformer_config.py +++ b/rastervision_core/rastervision/core/data/vector_transformer/buffer_transformer_config.py @@ -10,7 +10,7 @@ @register_config('buffer_transformer') class BufferTransformerConfig(VectorTransformerConfig): - """Configure the conversion of non-polygon geometries into polygons. + """Configure a :class:`.BufferTransformer`. This is useful, for example, for buffering lines representing roads so that their width roughly matches the width of roads in the imagery. diff --git a/rastervision_core/rastervision/core/data/vector_transformer/class_inference_transformer_config.py b/rastervision_core/rastervision/core/data/vector_transformer/class_inference_transformer_config.py index 5c19d4db2..36f192793 100644 --- a/rastervision_core/rastervision/core/data/vector_transformer/class_inference_transformer_config.py +++ b/rastervision_core/rastervision/core/data/vector_transformer/class_inference_transformer_config.py @@ -10,6 +10,8 @@ @register_config('class_inference_transformer') class ClassInferenceTransformerConfig(VectorTransformerConfig): + """Configure a :class:`.ClassInferenceTransformer`.""" + default_class_id: Optional[int] = Field( None, description='The default class_id to use if class cannot be inferred ' diff --git a/rastervision_core/rastervision/core/data/vector_transformer/shift_transformer_config.py b/rastervision_core/rastervision/core/data/vector_transformer/shift_transformer_config.py index c1ba5596a..d78c7fe35 100644 --- a/rastervision_core/rastervision/core/data/vector_transformer/shift_transformer_config.py +++ b/rastervision_core/rastervision/core/data/vector_transformer/shift_transformer_config.py @@ -10,7 +10,7 @@ @register_config('shift_transformer') class ShiftTransformerConfig(VectorTransformerConfig): - """Shift geometries by some distance specified in meters.""" + """Configure a :class:`.ShiftTransformer`.""" x_shift: float = Field( 0.0, diff --git a/rastervision_core/rastervision/core/data/vector_transformer/vector_transformer_config.py b/rastervision_core/rastervision/core/data/vector_transformer/vector_transformer_config.py index 2a7e0fa1e..686add279 100644 --- a/rastervision_core/rastervision/core/data/vector_transformer/vector_transformer_config.py +++ b/rastervision_core/rastervision/core/data/vector_transformer/vector_transformer_config.py @@ -11,6 +11,8 @@ @register_config('vector_transformer') class VectorTransformerConfig(Config): + """Configure a :class:`.VectorTransformer`.""" + def update(self, pipeline: Optional['RVPipelineConfig'] = None, scene: Optional['SceneConfig'] = None) -> None: diff --git a/rastervision_core/rastervision/core/evaluation/chip_classification_evaluator_config.py b/rastervision_core/rastervision/core/evaluation/chip_classification_evaluator_config.py index a92e0f88e..98d926aec 100644 --- a/rastervision_core/rastervision/core/evaluation/chip_classification_evaluator_config.py +++ b/rastervision_core/rastervision/core/evaluation/chip_classification_evaluator_config.py @@ -11,6 +11,8 @@ @register_config('chip_classification_evaluator') class ChipClassificationEvaluatorConfig(ClassificationEvaluatorConfig): + """Configure a :class:`.ChipClassificationEvaluator`.""" + def build(self, class_config: 'ClassConfig', scene_group: Optional[Tuple[str, Iterable[str]]] = None diff --git a/rastervision_core/rastervision/core/evaluation/classification_evaluator_config.py b/rastervision_core/rastervision/core/evaluation/classification_evaluator_config.py index 88c1110fc..33b28fb9b 100644 --- a/rastervision_core/rastervision/core/evaluation/classification_evaluator_config.py +++ b/rastervision_core/rastervision/core/evaluation/classification_evaluator_config.py @@ -4,4 +4,6 @@ @register_config('classification_evaluator') class ClassificationEvaluatorConfig(EvaluatorConfig): + """Configure a :class:`.ClassificationEvaluator`.""" + pass diff --git a/rastervision_core/rastervision/core/evaluation/evaluator_config.py b/rastervision_core/rastervision/core/evaluation/evaluator_config.py index 5e37fa86a..511a71c7b 100644 --- a/rastervision_core/rastervision/core/evaluation/evaluator_config.py +++ b/rastervision_core/rastervision/core/evaluation/evaluator_config.py @@ -11,6 +11,8 @@ @register_config('evaluator') class EvaluatorConfig(Config): + """Configure an :class:`.Evaluator`.""" + output_uri: Optional[str] = Field( None, description='URI of directory where evaluator output will be saved. ' diff --git a/rastervision_core/rastervision/core/evaluation/object_detection_evaluator_config.py b/rastervision_core/rastervision/core/evaluation/object_detection_evaluator_config.py index d8ac38e4a..11a7dd013 100644 --- a/rastervision_core/rastervision/core/evaluation/object_detection_evaluator_config.py +++ b/rastervision_core/rastervision/core/evaluation/object_detection_evaluator_config.py @@ -12,6 +12,8 @@ @register_config('object_detection_evaluator') class ObjectDetectionEvaluatorConfig(ClassificationEvaluatorConfig): + """Configure an :class:`.ObjectDetectionEvaluator`.""" + def build(self, class_config: 'ClassConfig', scene_group: Optional[Tuple[str, Iterable[str]]] = None diff --git a/rastervision_core/rastervision/core/evaluation/semantic_segmentation_evaluator_config.py b/rastervision_core/rastervision/core/evaluation/semantic_segmentation_evaluator_config.py index 8164abfa4..9731c7e04 100644 --- a/rastervision_core/rastervision/core/evaluation/semantic_segmentation_evaluator_config.py +++ b/rastervision_core/rastervision/core/evaluation/semantic_segmentation_evaluator_config.py @@ -23,6 +23,8 @@ def ss_evaluator_config_upgrader(cfg_dict: dict, version: int) -> dict: @register_config( 'semantic_segmentation_evaluator', upgrader=ss_evaluator_config_upgrader) class SemanticSegmentationEvaluatorConfig(ClassificationEvaluatorConfig): + """Configure a :class:`.SemanticSegmentationEvaluator`.""" + def build(self, class_config: 'ClassConfig', scene_group: Optional[Tuple[str, Iterable[str]]] = None diff --git a/rastervision_core/rastervision/core/rv_pipeline/chip_classification_config.py b/rastervision_core/rastervision/core/rv_pipeline/chip_classification_config.py index dc325cee5..013440233 100644 --- a/rastervision_core/rastervision/core/rv_pipeline/chip_classification_config.py +++ b/rastervision_core/rastervision/core/rv_pipeline/chip_classification_config.py @@ -7,6 +7,8 @@ @register_config('chip_classification') class ChipClassificationConfig(RVPipelineConfig): + """Configure a :class:`.ChipClassification` pipeline.""" + def build(self, tmp_dir): from rastervision.core.rv_pipeline.chip_classification import ChipClassification return ChipClassification(self, tmp_dir) diff --git a/rastervision_core/rastervision/core/rv_pipeline/object_detection_config.py b/rastervision_core/rastervision/core/rv_pipeline/object_detection_config.py index e96178972..7a6274949 100644 --- a/rastervision_core/rastervision/core/rv_pipeline/object_detection_config.py +++ b/rastervision_core/rastervision/core/rv_pipeline/object_detection_config.py @@ -59,6 +59,8 @@ class ObjectDetectionPredictOptions(PredictOptions): @register_config('object_detection') class ObjectDetectionConfig(RVPipelineConfig): + """Configure an :class:`.ObjectDetection` pipeline.""" + chip_options: ObjectDetectionChipOptions = ObjectDetectionChipOptions() predict_options: ObjectDetectionPredictOptions = ObjectDetectionPredictOptions( ) diff --git a/rastervision_core/rastervision/core/rv_pipeline/rv_pipeline_config.py b/rastervision_core/rastervision/core/rv_pipeline/rv_pipeline_config.py index cc2a2e182..20f18e9ba 100644 --- a/rastervision_core/rastervision/core/rv_pipeline/rv_pipeline_config.py +++ b/rastervision_core/rastervision/core/rv_pipeline/rv_pipeline_config.py @@ -23,7 +23,8 @@ class PredictOptions(Config): @register_config('rv_pipeline') class RVPipelineConfig(PipelineConfig): - """Config for RVPipeline.""" + """Configure an :class:`.RVPipeline`.""" + dataset: DatasetConfig = Field( ..., description= diff --git a/rastervision_core/rastervision/core/rv_pipeline/semantic_segmentation_config.py b/rastervision_core/rastervision/core/rv_pipeline/semantic_segmentation_config.py index e1ea78e19..962dfb705 100644 --- a/rastervision_core/rastervision/core/rv_pipeline/semantic_segmentation_config.py +++ b/rastervision_core/rastervision/core/rv_pipeline/semantic_segmentation_config.py @@ -104,6 +104,8 @@ def validate_crop_sz(cls, @register_config('semantic_segmentation', upgrader=ss_config_upgrader) class SemanticSegmentationConfig(RVPipelineConfig): + """Configure a :class:`.SemanticSegmentation` pipeline.""" + chip_options: SemanticSegmentationChipOptions = \ SemanticSegmentationChipOptions() predict_options: SemanticSegmentationPredictOptions = \ diff --git a/rastervision_pipeline/rastervision/pipeline/pipeline_config.py b/rastervision_pipeline/rastervision/pipeline/pipeline_config.py index d6ac71002..c62fa255a 100644 --- a/rastervision_pipeline/rastervision/pipeline/pipeline_config.py +++ b/rastervision_pipeline/rastervision/pipeline/pipeline_config.py @@ -10,7 +10,7 @@ @register_config('pipeline') class PipelineConfig(Config): - """Base class for configuring Pipelines. + """Base class for configuring :class:`Pipelines <.Pipeline>`. This should be subclassed to configure new Pipelines. """ diff --git a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_chip_classification_config.py b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_chip_classification_config.py index 4c6007b50..276a5ab2c 100644 --- a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_chip_classification_config.py +++ b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_chip_classification_config.py @@ -41,6 +41,8 @@ def clf_learner_backend_config_upgrader(cfg_dict, version): 'pytorch_chip_classification_backend', upgrader=clf_learner_backend_config_upgrader) class PyTorchChipClassificationConfig(PyTorchLearnerBackendConfig): + """Configure a :class:`.PyTorchChipClassification` backend.""" + model: ClassificationModelConfig def get_learner_config(self, pipeline): diff --git a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_learner_backend_config.py b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_learner_backend_config.py index ffdb98e8e..3d7351ba1 100644 --- a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_learner_backend_config.py +++ b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_learner_backend_config.py @@ -13,6 +13,8 @@ @register_config('pytorch_learner_backend') class PyTorchLearnerBackendConfig(BackendConfig): + """Configure a :class:`.PyTorchLearnerBackend`.""" + model: ModelConfig solver: SolverConfig data: DataConfig diff --git a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_object_detection_config.py b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_object_detection_config.py index 1d3b9a5a2..7f885fae4 100644 --- a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_object_detection_config.py +++ b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_object_detection_config.py @@ -41,6 +41,8 @@ def objdet_learner_backend_config_upgrader(cfg_dict, version): 'pytorch_object_detection_backend', upgrader=objdet_learner_backend_config_upgrader) class PyTorchObjectDetectionConfig(PyTorchLearnerBackendConfig): + """Configure a :class:`.PyTorchObjectDetection` backend.""" + model: ObjectDetectionModelConfig def get_learner_config(self, pipeline): diff --git a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_semantic_segmentation_config.py b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_semantic_segmentation_config.py index b7f7becea..318648704 100644 --- a/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_semantic_segmentation_config.py +++ b/rastervision_pytorch_backend/rastervision/pytorch_backend/pytorch_semantic_segmentation_config.py @@ -41,6 +41,8 @@ def ss_learner_backend_config_upgrader(cfg_dict, version): 'pytorch_semantic_segmentation_backend', upgrader=ss_learner_backend_config_upgrader) class PyTorchSemanticSegmentationConfig(PyTorchLearnerBackendConfig): + """Configure a :class:`.PyTorchSemanticSegmentation` backend.""" + model: SemanticSegmentationModelConfig def get_learner_config(self, pipeline): diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/classification_learner_config.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/classification_learner_config.py index bc47802a9..cb3891a62 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/classification_learner_config.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/classification_learner_config.py @@ -35,6 +35,8 @@ class ClassificationDataConfig(Config): @register_config('classification_image_data') class ClassificationImageDataConfig(ClassificationDataConfig, ImageDataConfig): + """Configure :class:`ClassificationImageDatasets <.ClassificationImageDataset>`.""" + data_format: ClassificationDataFormat = ClassificationDataFormat.image_folder def dir_to_dataset(self, data_dir: str, transform: A.BasicTransform @@ -46,6 +48,11 @@ def dir_to_dataset(self, data_dir: str, transform: A.BasicTransform @register_config('classification_geo_data') class ClassificationGeoDataConfig(ClassificationDataConfig, GeoDataConfig): + """Configure classification :class:`GeoDatasets <.GeoDataset>`. + + See :mod:`rastervision.pytorch_learner.dataset.classification_dataset`. + """ + def build_scenes(self, tmp_dir: str): for s in self.scene_dataset.all_scenes: if s.label_source is not None: @@ -89,6 +96,8 @@ def scene_to_dataset(self, @register_config('classification_model') class ClassificationModelConfig(ModelConfig): + """Configure a classification model.""" + def build_default_model(self, num_classes: int, in_channels: int) -> nn.Module: from torchvision import models @@ -125,6 +134,8 @@ def build_default_model(self, num_classes: int, @register_config('classification_learner') class ClassificationLearnerConfig(LearnerConfig): + """Configure a :class:`.ClassificationLearner`.""" + data: Union[ClassificationImageDataConfig, ClassificationGeoDataConfig] model: Optional[ClassificationModelConfig] diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_config.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_config.py index 1b2e3abcb..46620b93d 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_config.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_config.py @@ -1057,6 +1057,11 @@ class GeoDataWindowMethod(Enum): @register_config('geo_data_window') class GeoDataWindowConfig(Config): + """Configure a :class:`.GeoDataset`. + + See :mod:`rastervision.pytorch_learner.dataset.dataset`. + """ + method: GeoDataWindowMethod = Field( GeoDataWindowMethod.sliding, description='') size: Union[PosInt, Tuple[PosInt, PosInt]] = Field( @@ -1142,6 +1147,11 @@ def validate_options(cls, values: dict) -> dict: @register_config('geo_data') class GeoDataConfig(DataConfig): + """Configure :class:`GeoDatasets <.GeoDataset>`. + + See :mod:`rastervision.pytorch_learner.dataset.dataset`. + """ + scene_dataset: Optional['SceneDatasetConfig'] = Field(None, description='') window_opts: Union[GeoDataWindowConfig, Dict[str, GeoDataWindowConfig]] = Field( diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_pipeline_config.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_pipeline_config.py index 786515780..f7ed04293 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_pipeline_config.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/learner_pipeline_config.py @@ -5,6 +5,8 @@ @register_config('learner_pipeline') class LearnerPipelineConfig(PipelineConfig): + """Configure a :class:`.LearnerPipeline`.""" + learner: LearnerConfig def update(self): diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/object_detection_learner_config.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/object_detection_learner_config.py index 9fe44918b..169ebabb4 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/object_detection_learner_config.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/object_detection_learner_config.py @@ -47,6 +47,8 @@ def get_bbox_params(self): @register_config('object_detection_image_data') class ObjectDetectionImageDataConfig(ObjectDetectionDataConfig, ImageDataConfig): + """Configure :class:`ObjectDetectionImageDatasets <.ObjectDetectionImageDataset>`.""" + data_format: ObjectDetectionDataFormat = ObjectDetectionDataFormat.coco def dir_to_dataset(self, data_dir: str, transform: A.BasicTransform @@ -60,6 +62,10 @@ def dir_to_dataset(self, data_dir: str, transform: A.BasicTransform @register_config('object_detection_geo_data_window') class ObjectDetectionGeoDataWindowConfig(GeoDataWindowConfig): + """Configure an object detection :class:`.GeoDataset`. + + See :mod:`rastervision.pytorch_learner.dataset.object_detection_dataset`. + """ ioa_thresh: float = Field( 0.8, description='When a box is partially outside of a training chip, it ' @@ -87,6 +93,11 @@ class ObjectDetectionGeoDataWindowConfig(GeoDataWindowConfig): @register_config('object_detection_geo_data') class ObjectDetectionGeoDataConfig(ObjectDetectionDataConfig, GeoDataConfig): + """Configure object detection :class:`GeoDatasets <.GeoDataset>`. + + See :mod:`rastervision.pytorch_learner.dataset.object_detection_dataset`. + """ + def scene_to_dataset( self, scene: Scene, @@ -131,6 +142,8 @@ def scene_to_dataset( @register_config('object_detection_model') class ObjectDetectionModelConfig(ModelConfig): + """Configure an object detection model.""" + backbone: Backbone = Field( Backbone.resnet50, description= @@ -203,6 +216,8 @@ def build_default_model(self, num_classes: int, in_channels: int, @register_config('object_detection_learner') class ObjectDetectionLearnerConfig(LearnerConfig): + """Configure an :class:`.ObjectDetectionLearner`.""" + data: Union[ObjectDetectionImageDataConfig, ObjectDetectionGeoDataConfig] model: Optional[ObjectDetectionModelConfig] diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/regression_learner_config.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/regression_learner_config.py index 916a455b1..5b7ac05d0 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/regression_learner_config.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/regression_learner_config.py @@ -48,6 +48,8 @@ class RegressionDataConfig(Config): @register_config('regression_image_data') class RegressionImageDataConfig(RegressionDataConfig, ImageDataConfig): + """Configure :class:`RegressionImageDatasets <.RegressionImageDataset>`.""" + data_format: RegressionDataFormat = RegressionDataFormat.csv plot_options: Optional[RegressionPlotOptions] = Field( RegressionPlotOptions(), description='Options to control plotting.') @@ -61,6 +63,11 @@ def dir_to_dataset(self, data_dir: str, @register_config('regression_geo_data') class RegressionGeoDataConfig(RegressionDataConfig, GeoDataConfig): + """Configure regression :class:`GeoDatasets <.GeoDataset>`. + + See :mod:`rastervision.pytorch_learner.dataset.regression_dataset`. + """ + plot_options: Optional[RegressionPlotOptions] = Field( RegressionPlotOptions(), description='Options to control plotting.') @@ -126,6 +133,8 @@ def forward(self, x): @register_config('regression_model') class RegressionModelConfig(ModelConfig): + """Configure a regression model.""" + output_multiplier: List[float] = None def update(self, learner=None): @@ -185,6 +194,8 @@ def build_default_model( @register_config('regression_learner') class RegressionLearnerConfig(LearnerConfig): + """Configure a :class:`.RegressionLearner`.""" + model: Optional[RegressionModelConfig] data: Union[RegressionImageDataConfig, RegressionGeoDataConfig] diff --git a/rastervision_pytorch_learner/rastervision/pytorch_learner/semantic_segmentation_learner_config.py b/rastervision_pytorch_learner/rastervision/pytorch_learner/semantic_segmentation_learner_config.py index 7f0ad9965..858ffc973 100644 --- a/rastervision_pytorch_learner/rastervision/pytorch_learner/semantic_segmentation_learner_config.py +++ b/rastervision_pytorch_learner/rastervision/pytorch_learner/semantic_segmentation_learner_config.py @@ -61,14 +61,11 @@ class SemanticSegmentationDataConfig(Config): 'semantic_segmentation_image_data', upgrader=ss_image_data_config_upgrader) class SemanticSegmentationImageDataConfig(SemanticSegmentationDataConfig, ImageDataConfig): - """Configure reading of a semnatic segmentation image dataset. + """Configure :class:`SemanticSegmentationImageDatasets <.SemanticSegmentationImageDataset>`. - .. currentmodule:: rastervision.pytorch_learner.dataset.semantic_segmentation_dataset + This assumes the following file structure: - This is used to instantiate a :class:`SemanticSegmentationImageDataset` - and assumes the following file structure: - - .. code-block:: txt + .. code-block:: text / img/ @@ -82,7 +79,7 @@ class SemanticSegmentationImageDataConfig(SemanticSegmentationDataConfig, ... . - """ + """ # noqa data_format: SemanticSegmentationDataFormat = ( SemanticSegmentationDataFormat.default) @@ -104,6 +101,12 @@ def dir_to_dataset(self, data_dir: str, @register_config('semantic_segmentation_geo_data') class SemanticSegmentationGeoDataConfig(SemanticSegmentationDataConfig, GeoDataConfig): + """Configure semantic segmentation :class:`GeoDatasets <.GeoDataset>`. + + See + :mod:`rastervision.pytorch_learner.dataset.semantic_segmentation_dataset`. + """ + def update(self, *args, **kwargs): SemanticSegmentationDataConfig.update(self) GeoDataConfig.update(self, *args, **kwargs) @@ -144,6 +147,8 @@ def scene_to_dataset(self, @register_config('semantic_segmentation_model') class SemanticSegmentationModelConfig(ModelConfig): + """Configure a semantic segmentation model.""" + backbone: Backbone = Field( Backbone.resnet50, description=( @@ -193,6 +198,8 @@ def build_default_model(self, num_classes: int, @register_config('semantic_segmentation_learner') class SemanticSegmentationLearnerConfig(LearnerConfig): + """Configure a :class:`.SemanticSegmentationLearner`.""" + data: Union[SemanticSegmentationImageDataConfig, SemanticSegmentationGeoDataConfig] model: Optional[SemanticSegmentationModelConfig] From 74e0ac7612392e73941a37a8fe74c2848ad90f8d Mon Sep 17 00:00:00 2001 From: Adeel Hassan Date: Fri, 23 Dec 2022 20:10:47 +0500 Subject: [PATCH 3/4] remove trailing whitespaces --- docs/conf.py | 2 +- docs/framework/pipelines.rst | 10 +++++----- docs/framework/quickstart.rst | 6 +++--- .../core/data/raster_source/rasterio_source.py | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1eb1c1124..ecc3b8e43 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -163,7 +163,7 @@ def setup(app: 'Sphinx') -> None: os.environ['GDAL_DATA'] = check_output('pip show rasterio | grep Location | awk \'{print $NF"/rasterio/gdal_data/"}\'', shell=True).decode().strip() os.environ['AWS_NO_SIGN_REQUEST'] = 'YES' - + See this `Colab notebook `__ for an example. """ # noqa diff --git a/docs/framework/pipelines.rst b/docs/framework/pipelines.rst index 65867cf54..2c159a83c 100644 --- a/docs/framework/pipelines.rst +++ b/docs/framework/pipelines.rst @@ -131,7 +131,7 @@ The following table shows the corresponding ``Configs`` for various commonly use - :class:`~data.raster_source.multi_raster_source_config.MultiRasterSourceConfig` - :class:`~data.raster_source.rasterized_source_config.RasterizedSourceConfig` - - + - * - :class:`~data.raster_transformer.raster_transformer.RasterTransformer` - :class:`~data.raster_transformer.cast_transformer.CastTransformer` @@ -150,7 +150,7 @@ The following table shows the corresponding ``Configs`` for various commonly use - :class:`~data.raster_transformer.rgb_class_transformer_config.RGBClassTransformerConfig` - :class:`~data.raster_transformer.stats_transformer_config.StatsTransformerConfig` - - + - * - :class:`~data.vector_source.vector_source.VectorSource` - :class:`~data.vector_source.geojson_vector_source.GeoJSONVectorSource` @@ -159,7 +159,7 @@ The following table shows the corresponding ``Configs`` for various commonly use - :class:`~data.vector_source.geojson_vector_source_config.GeoJSONVectorSourceConfig` - - + - * - :class:`~data.vector_transformer.vector_transformer.VectorTransformer` - :class:`~data.vector_transformer.buffer_transformer.BufferTransformer` @@ -172,7 +172,7 @@ The following table shows the corresponding ``Configs`` for various commonly use - :class:`~data.vector_transformer.class_inference_transformer_config.ClassInferenceTransformerConfig` - :class:`~data.vector_transformer.shift_transformer_config.ShiftTransformerConfig` - - + - * - :class:`~data.label_source.label_source.LabelSource` - :class:`~data.label_source.chip_classification_label_source.ChipClassificationLabelSource` @@ -185,7 +185,7 @@ The following table shows the corresponding ``Configs`` for various commonly use - :class:`~data.label_source.semantic_segmentation_label_source_config.SemanticSegmentationLabelSourceConfig` - :class:`~data.label_source.object_detection_label_source_config.ObjectDetectionLabelSourceConfig` - - + - * - :class:`~data.label_store.label_store.LabelStore` - :class:`~data.label_store.chip_classification_geojson_store.ChipClassificationGeoJSONStore` diff --git a/docs/framework/quickstart.rst b/docs/framework/quickstart.rst index 5a182a091..b9c1a9ec3 100644 --- a/docs/framework/quickstart.rst +++ b/docs/framework/quickstart.rst @@ -38,9 +38,9 @@ The Data .. raw:: html
-
diff --git a/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py b/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py index fea6d1c3b..1b5d96cfc 100644 --- a/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py +++ b/rastervision_core/rastervision/core/data/raster_source/rasterio_source.py @@ -164,7 +164,7 @@ class RasterioSource(RasterSource): This RasterSource can read any file that can be opened by `Rasterio/GDAL `_. - + If there are multiple image files that cover a single scene, you can pass the corresponding list of URIs, and read them as if it were a single stitched-together image. From d6f1a41d30a9ea904dad67f3819d78c67face928 Mon Sep 17 00:00:00 2001 From: Adeel Hassan Date: Fri, 23 Dec 2022 20:10:57 +0500 Subject: [PATCH 4/4] add missing cross references --- docs/framework/quickstart.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework/quickstart.rst b/docs/framework/quickstart.rst index b9c1a9ec3..202ebab84 100644 --- a/docs/framework/quickstart.rst +++ b/docs/framework/quickstart.rst @@ -48,7 +48,7 @@ The Data Configuring a semantic segmentation pipeline ---------------------------------------------- -Create a Python file in the ``${RV_QUICKSTART_CODE_DIR}`` named ``tiny_spacenet.py``. Inside, you're going to write a function called ``get_config`` that returns a ``SemanticSegmentationConfig`` object. This object's type is a subclass of ``PipelineConfig``, and configures a semantic segmentation pipeline which (optionally) analyzes the imagery, (optionally) creates training chips, trains a model, makes predictions on validation scenes, evaluates the predictions, and saves a model bundle. +Create a Python file in the ``${RV_QUICKSTART_CODE_DIR}`` named ``tiny_spacenet.py``. Inside, you're going to write a function called ``get_config`` that returns a :class:`~rastervision.core.rv_pipeline.semantic_segmentation_config.SemanticSegmentationConfig` object. This object's type is a subclass of :class:`~rastervision.pipeline.pipeline_config.PipelineConfig`, and configures a semantic segmentation pipeline which (optionally) analyzes the imagery, (optionally) creates training chips, trains a model, makes predictions on validation scenes, evaluates the predictions, and saves a model bundle. .. literalinclude:: /../rastervision_pytorch_backend/rastervision/pytorch_backend/examples/tiny_spacenet.py :language: python