diff --git a/docs/code/pyaurorax_api_reference/index.js b/docs/code/pyaurorax_api_reference/index.js index 62cac7f..d4a8fa2 100644 --- a/docs/code/pyaurorax_api_reference/index.js +++ b/docs/code/pyaurorax_api_reference/index.js @@ -1616,7 +1616,7 @@ INDEX=[ { "ref":"pyaurorax.tools.scale_intensity", "url":33, -"doc":"Scale all values of an array that lie in the range min<=x<=max in to the range 0<=x<=high. Args: data (numpy.ndarray): data array, can be 2, 3, or 4-dimensional. Assumed to be an image, or array of images. Also assumed that the first 2 dimensions are the image's x and y coordinates, and the following dimensions are some combination of the number of images, and/or the colour channel. min (float): minimum value of array to be considered max (float): maximum value of array to be considered top (float): maximum value of the scaled result. If not supplied, the max value of the data array's dtype is used. Returns: A new numpy.ndarray that is the same dimensions as the inputted data array, with the scaling applied. Raises: ValueError: Issues with the supplied min, max, or top", +"doc":"Scale all values of an array that lie in the range min<=x<=max in to the range 0<=x<=high. Args: data (numpy.ndarray): Data array, can be 2, 3, or 4-dimensional. Assumed to be an image, or array of images. Also assumed that the first 2 dimensions are the image's x and y coordinates, and the following dimensions are some combination of the number of images, and/or the colour channel. min (float): Minimum value of array to be considered max (float): Maximum value of array to be considered top (float): Maximum value of the scaled result. If not supplied, the max value of the data array's dtype is used. memory_saver (bool): Utilize less RAM when scaling a set of images. Defaults to True . If set to False then the scaling routine will be faster, but will utilize significantly more RAM. Returns: A new numpy.ndarray that is the same dimensions as the inputted data array, with the scaling applied. Raises: ValueError: Issues with the supplied min, max, or top", "func":1 }, { @@ -1682,19 +1682,19 @@ INDEX=[ { "ref":"pyaurorax.tools.Mosaic.plot", "url":33, -"doc":"Generate a plot of the mosaic data. Either display it (default behaviour), save it to disk (using the savefig parameter), or return the matplotlib plot object for further usage (using the returnfig parameter). Args: map_extent (List[int]): Latitude/longitude range to be visible on the rendered map. This is a list of 4 integers and/or floats, in the order of [min_lon, max_lon, min_lat, max_lat]. figsize (tuple): The matplotlib figure size to use when plotting. For example figsize=(14,4) . rayleighs (bool): Set to True if the data being plotted is in Rayleighs. Defaults to False . max_rayleighs (int): Max intensity scale for Rayleighs. Defaults to 20000 . ocean_color (str): Colour of the ocean. Default is cartopy's default shade of blue. Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 55AADD ). land_color (str): Colour of the land. Default is grey . Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 41BB87 ). land_edgecolor (str): Color of the land edges. Default is 8A8A8A . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_color (str): Color of the country borders. Default is AEAEAE . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_disable (bool): Disbale rendering of the borders. Default is False . cbar_colorcmap (str): The matplotlib colormap to use for the plotted color bar. Default is grey . Commonly used colormaps are: - REGO: gist_heat - THEMIS ASI: gray - TREx Blue: Blues_r - TREx NIR: gray - TREx RGB: None A list of all available colormaps can be found on the [matplotlib documentation](https: matplotlib.org/stable/gallery/color/colormap_reference.html). returnfig (bool): Instead of displaying the image, return the matplotlib figure object. This allows for further plot manipulation, for example, adding labels or a title in a different location than the default. Remember - if this parameter is supplied, be sure that you close your plot after finishing work with it. This can be achieved by doing plt.close(fig) . Note that this method cannot be used in combination with savefig . savefig (bool): Save the displayed image to disk instead of displaying it. The parameter savefig_filename is required if this parameter is set to True. Defaults to False . savefig_filename (str): Filename to save the image to. Must be specified if the savefig parameter is set to True. savefig_quality (int): Quality level of the saved image. This can be specified if the savefig_filename is a JPG image. If it is a PNG, quality is ignored. Default quality level for JPGs is matplotlib/Pillow's default of 75%. Returns: The displayed montage, by default. If savefig is set to True, nothing will be returned. If returnfig is set to True, the plotting variables (fig, ax) will be returned. Raises:", +"doc":"Generate a plot of the mosaic data. Either display it (default behaviour), save it to disk (using the savefig parameter), or return the matplotlib plot object for further usage (using the returnfig parameter). Args: map_extent (List[int]): Latitude/longitude range to be visible on the rendered map. This is a list of 4 integers and/or floats, in the order of [min_lon, max_lon, min_lat, max_lat]. figsize (tuple): The matplotlib figure size to use when plotting. For example figsize=(14,4) . rayleighs (bool): Set to True if the data being plotted is in Rayleighs. Defaults to False . max_rayleighs (int): Max intensity scale for Rayleighs. Defaults to 20000 . ocean_color (str): Colour of the ocean. Default is cartopy's default shade of blue. Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 55AADD ). land_color (str): Colour of the land. Default is gray . Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 41BB87 ). land_edgecolor (str): Color of the land edges. Default is 8A8A8A . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_color (str): Color of the country borders. Default is AEAEAE . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_disable (bool): Disbale rendering of the borders. Default is False . cbar_colorcmap (str): The matplotlib colormap to use for the plotted color bar. Default is gray . Commonly used colormaps are: - REGO: gist_heat - THEMIS ASI: gray - TREx Blue: Blues_r - TREx NIR: gray - TREx RGB: None A list of all available colormaps can be found on the [matplotlib documentation](https: matplotlib.org/stable/gallery/color/colormap_reference.html). returnfig (bool): Instead of displaying the image, return the matplotlib figure object. This allows for further plot manipulation, for example, adding labels or a title in a different location than the default. Remember - if this parameter is supplied, be sure that you close your plot after finishing work with it. This can be achieved by doing plt.close(fig) . Note that this method cannot be used in combination with savefig . savefig (bool): Save the displayed image to disk instead of displaying it. The parameter savefig_filename is required if this parameter is set to True. Defaults to False . savefig_filename (str): Filename to save the image to. Must be specified if the savefig parameter is set to True. savefig_quality (int): Quality level of the saved image. This can be specified if the savefig_filename is a JPG image. If it is a PNG, quality is ignored. Default quality level for JPGs is matplotlib/Pillow's default of 75%. Returns: The displayed montage, by default. If savefig is set to True, nothing will be returned. If returnfig is set to True, the plotting variables (fig, ax) will be returned. Raises:", "func":1 }, { "ref":"pyaurorax.tools.Mosaic.add_geo_contours", "url":33, -"doc":"Add geographic contours to a mosaic. Args: lats (ndarray or list): Sequence of geographic latitudes defining a contour. lons (ndarray or list): Sequence of geographic longitudes defining a contour. constant_lats (float, int, or Sequence): Geographic Latitude(s) at which to add line(s) of constant latitude. constant_lons (float, int, or Sequence): Geographic Longitude(s) at which to add line(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", +"doc":"Add geographic contours to a mosaic. Args: lats (ndarray or list): Sequence of geographic latitudes defining a contour. lons (ndarray or list): Sequence of geographic longitudes defining a contour. constant_lats (float, int, or Sequence): Geographic Latitude(s) at which to add line(s) of constant latitude. constant_lons (float, int, or Sequence): Geographic Longitude(s) at which to add line(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). marker (str): The matplotlib marker used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", "func":1 }, { "ref":"pyaurorax.tools.Mosaic.add_mag_contours", "url":33, -"doc":"Add geomagnetic contours to a mosaic. Args: timestamp (datetime.datetime): The timestamp used in computing AACGM coordinates. lats (ndarray or list): Sequence of geomagnetic latitudes defining a contour. lons (ndarray or list): Sequence of geomagnetic longitudes defining a contour. constant_lats (float, int, Sequence): Geomagnetic latitude(s) at which to add contour(s) of constant latitude. constant_lons (float, int, Sequence): Geomagnetic longitude(s) at which to add contours(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", +"doc":"Add geomagnetic contours to a mosaic. Args: timestamp (datetime.datetime): The timestamp used in computing AACGM coordinates. lats (ndarray or list): Sequence of geomagnetic latitudes defining a contour. lons (ndarray or list): Sequence of geomagnetic longitudes defining a contour. constant_lats (float, int, Sequence): Geomagnetic latitude(s) at which to add contour(s) of constant latitude. constant_lons (float, int, Sequence): Geomagnetic longitude(s) at which to add contours(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). marker (str): The matplotlib marker used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", "func":1 }, { @@ -1771,31 +1771,31 @@ INDEX=[ { "ref":"pyaurorax.tools.bounding_box.extract_metric.geo", "url":36, -"doc":"Compute a metric of image data within a geographic lat/lon boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. altitude_km (int or float): The altitude of the image data in kilometers. lonlat_bounds (Sequence): A 4-element sequence specifying the lat/lon bounds from which to extract the metric. Anticipated order is [lon_0, lon_1, lat_0, lat_1]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. Returns: A numpy.ndarray containing the metrics computed within elevation range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", +"doc":"Compute a metric of image data within a geographic lat/lon boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. altitude_km (int or float): The altitude of the image data in kilometers. lonlat_bounds (Sequence): A 4-element sequence specifying the lat/lon bounds from which to extract the metric. Anticipated order is [lon_0, lon_1, lat_0, lat_1]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. show_preview (bool): Plot a preview of the bounded area. Returns: A numpy.ndarray containing the metrics computed within elevation range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", "func":1 }, { "ref":"pyaurorax.tools.bounding_box.extract_metric.ccd", "url":36, -"doc":"Compute a metric of image data within a CCD boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. ccd_bounds (List[int]): A 4-element sequence specifying the (inclusive) CCD bounds from which to extract the metric. Anticipated order is [y_0, y_1, x_0, x_1]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Defaults to median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. Returns: A numpy.ndarray containing the metrics computed within CCD bounds, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", +"doc":"Compute a metric of image data within a CCD boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. ccd_bounds (List[int]): A 4-element sequence specifying the (inclusive) CCD bounds from which to extract the metric. Anticipated order is [x_0, x_1, y_0, y_1]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Defaults to median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. show_preview (bool): Plot a preview of the bounded area. Returns: A numpy.ndarray containing the metrics computed within CCD bounds, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", "func":1 }, { "ref":"pyaurorax.tools.bounding_box.extract_metric.mag", "url":36, -"doc":"Compute a metric of image data within a magnetic lat/lon boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. altitude_km (int or float): The altitude of the image data in kilometers. lonlat_bounds (Sequence): A 4-element sequence specifying the magnetic lat/lon bounds from which to extract the metric. Anticipated order is [lon_0, lon_1, lat_0, lat_1]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. Returns: A numpy.ndarray containing the metrics computed within elevation range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", +"doc":"Compute a metric of image data within a magnetic lat/lon boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. altitude_km (int or float): The altitude of the image data in kilometers. lonlat_bounds (Sequence): A 4-element sequence specifying the magnetic lat/lon bounds from which to extract the metric. Anticipated order is [lon_0, lon_1, lat_0, lat_1]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. show_preview (bool): Plot a preview of the bounded area. Returns: A numpy.ndarray containing the metrics computed within elevation range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", "func":1 }, { "ref":"pyaurorax.tools.bounding_box.extract_metric.elevation", "url":36, -"doc":"Compute a metric of image data within an elevation boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. elevation_bounds (Sequence): A 2-element sequence specifying the elevation bounds from which to extract the metric. Anticipated order is [el_min, el_max]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. Returns: A numpy.ndarray containing the metrics computed within elevation range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", +"doc":"Compute a metric of image data within an elevation boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. elevation_bounds (Sequence): A 2-element sequence specifying the elevation bounds from which to extract the metric. Anticipated order is [el_min, el_max]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. show_preview (bool): Plot a preview of the bounded area. Returns: A numpy.ndarray containing the metrics computed within elevation range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", "func":1 }, { "ref":"pyaurorax.tools.bounding_box.extract_metric.azimuth", "url":36, -"doc":"Compute a metric of image data within an azimuthal boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. azimuth_bounds (Sequence[int | float]: A 2-element sequence specifying the azimuthal bounds from which to extract the metric. Anticipated order is [az_min, az_max]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. Returns: A numpy.ndarray containing the metrics computed within azimuth range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", +"doc":"Compute a metric of image data within an azimuthal boundary. Args: images (numpy.ndarray): A set of images. Normally this would come directly from a data read call, but can also be any arbitrary set of images. It is anticipated that the order of axes is [rows, cols, num_images] or [row, cols, channels, num_images]. skymap (pyaurorax.data.ucalgary.Skymap): The skymap corresponding to the image data. azimuth_bounds (Sequence[int | float]: A 2-element sequence specifying the azimuthal bounds from which to extract the metric. Anticipated order is [az_min, az_max]. metric (str): The name of the metric that is to be computed for the bounded area. Valid metrics are mean , median , sum . Default is median . n_channels (int): By default, function will assume the type of data passed as input - this argument can be used to manually specify the number of channels contained in image data. show_preview (bool): Plot a preview of the bounded area. Returns: A numpy.ndarray containing the metrics computed within azimuth range, for all image frames. Raises: ValueError: issue encountered with value supplied in parameter", "func":1 }, { @@ -1818,7 +1818,7 @@ INDEX=[ { "ref":"pyaurorax.tools.mosaic.create", "url":37, -"doc":"Create a mosaic object. Args: prepped_data (pyaurorax.tools.MosaicData): The prepared mosaic data. Generated from a prior prep_images() function call. prepped_skymap (pyaurorax.tools.MosaicSkymap): The prepared skymap data. Generated from a prior prep_skymaps() function call. frame_idx (int): The frame number to generate a mosaic for. cartopy_projection (cartopy.crs.Projection): The cartopy projection to use when creating the mosaic. min_elevation (int): The minimum elevation cutoff when projecting images on the map, in degrees. Default is 5 . cbar_colorcmap (str): The matplotlib colormap to use for the rendered image data. Default is grey . Commonly used colormaps are: - REGO: gist_heat - THEMIS ASI: gray - TREx Blue: Blues_r - TREx NIR: gray - TREx RGB: None A list of all available colormaps can be found on the [matplotlib documentation](https: matplotlib.org/stable/gallery/color/colormap_reference.html). image_intensity_scaled (List or Dict): Ranges for scaling images. Either a a list with 2 elements which will scale all sites with the same range, or as a dictionary which can be used for scaling each site differently. Example of uniform scaling across all sites: image_intensity_scales = [2000, 8000] Example of scaling each site differently: image_intensity_scales = {\"fsmi\": [1000, 10000], \"gill\": [2000, 8000]} Returns: The generated pyaurorax.tools.Mosaic object. Raises: ValueError: issues with supplied parameters.", +"doc":"Create a mosaic object. Args: prepped_data (pyaurorax.tools.MosaicData): The prepared mosaic data. Generated from a prior prep_images() function call. prepped_skymap (pyaurorax.tools.MosaicSkymap): The prepared skymap data. Generated from a prior prep_skymaps() function call. frame_idx (int): The frame number to generate a mosaic for. cartopy_projection (cartopy.crs.Projection): The cartopy projection to use when creating the mosaic. min_elevation (int): The minimum elevation cutoff when projecting images on the map, in degrees. Default is 5 . cbar_colorcmap (str): The matplotlib colormap to use for the rendered image data. Default is gray . Commonly used colormaps are: - REGO: gist_heat - THEMIS ASI: gray - TREx Blue: Blues_r - TREx NIR: gray - TREx RGB: None A list of all available colormaps can be found on the [matplotlib documentation](https: matplotlib.org/stable/gallery/color/colormap_reference.html). image_intensity_scaled (List or Dict): Ranges for scaling images. Either a a list with 2 elements which will scale all sites with the same range, or as a dictionary which can be used for scaling each site differently. Example of uniform scaling across all sites: image_intensity_scales = [2000, 8000] Example of scaling each site differently: image_intensity_scales = {\"fsmi\": [1000, 10000], \"gill\": [2000, 8000]} Returns: The generated pyaurorax.tools.Mosaic object. Raises: ValueError: issues with supplied parameters.", "func":1 }, { @@ -1846,13 +1846,13 @@ INDEX=[ { "ref":"pyaurorax.tools.calibration.rego", "url":39, -"doc":"Apply various calibration adjustments to a single or set of images raw images. Args: images (numpy.ndarray): Raw images to perform calibration procedures on. cal_flatfield (pyaurorax.data.ucalgary.Calibration): Calibration object containing the flatfield data to utilize. This field is required if the step_flatfield_corection is set to True. cal_rayleighs (pyaurorax.data.ucalgary.Calibration): Calibration object containing the Rayleighs data to utilize. This field is required if the step_rayleighs_conversion is set to True. step_dark_frame_correction (bool): Perform the dark frame correction step. Defaults to True . step_flatfield_correction (bool): Perform the flatfield correction step. Defaults to True . Note that the cal_flatfield parameter must be supplied if this is True. step_rayleighs_conversion (bool): Perform the Rayleighs conversion step. Defaults to True. Note that the cal_rayleighs parameter must be supplied if this is True. exposure_length_sec (float): Force the exposure length to be a certain value. Default is TREx NIR's nominal operating mode exposure length of 2.0 seconds . Adjusting this field should be done with caution. Returns: The calibrated images. The shape of the calibrated data will be same as the input images. The dtype of the calibrated data will depend on if the Rayleighs conversion was performed. If it was, a float32 array will be returned. If it wasn't, the dtype will be the same as input images' dtype. Raises: ValueError: issues encountered with supplied parameters.", +"doc":"Apply various calibration adjustments to a single or set of images raw images. Args: images (numpy.ndarray): Raw images to perform calibration procedures on. cal_flatfield (pyaurorax.data.ucalgary.Calibration): Calibration object containing the flatfield data to utilize. This field is required if the step_flatfield_corection is set to True. cal_rayleighs (pyaurorax.data.ucalgary.Calibration): Calibration object containing the Rayleighs data to utilize. This field is required if the step_rayleighs_calibration is set to True. step_dark_frame_correction (bool): Perform the dark frame correction step. Defaults to True . step_flatfield_calibration (bool): Perform the flatfield correction step. Defaults to True . Note that the cal_flatfield parameter must be supplied if this is True. step_rayleighs_calibration (bool): Perform the Rayleighs conversion step. Defaults to True. Note that the cal_rayleighs parameter must be supplied if this is True. exposure_length_sec (float): Force the exposure length to be a certain value. Default is TREx NIR's nominal operating mode exposure length of 2.0 seconds . Adjusting this field should be done with caution. Returns: The calibrated images. The shape of the calibrated data will be same as the input images. The dtype of the calibrated data will depend on if the Rayleighs conversion was performed. If it was, a float32 array will be returned. If it wasn't, the dtype will be the same as input images' dtype. Raises: ValueError: issues encountered with supplied parameters.", "func":1 }, { "ref":"pyaurorax.tools.calibration.trex_nir", "url":39, -"doc":"Apply various calibration adjustments to a single or set of images raw images. Args: images (numpy.ndarray): Raw images to perform calibration procedures on. cal_flatfield (pyaurorax.data.ucalgary.Calibration): Calibration object containing the flatfield data to utilize. This field is required if the step_flatfield_corection is set to True. cal_rayleighs (pyaurorax.data.ucalgary.Calibration): Calibration object containing the Rayleighs data to utilize. This field is required if the step_rayleighs_conversion is set to True. step_dark_frame_correction (bool): Perform the dark frame correction step. Defaults to True . step_flatfield_correction (bool): Perform the flatfield correction step. Defaults to True . Note that the cal_flatfield parameter must be supplied if this is True. step_rayleighs_conversion (bool): Perform the Rayleighs conversion step. Defaults to True. Note that the cal_rayleighs parameter must be supplied if this is True. exposure_length_sec (float): Force the exposure length to be a certain value. Default is TREx NIR's nominal operating mode exposure length of 5.0 seconds . Adjusting this field should be done with caution. Returns: The calibrated images. The shape of the calibrated data will be same as the input images. The dtype of the calibrated data will depend on if the Rayleighs conversion was performed. If it was, a float32 array will be returned. If it wasn't, the dtype will be the same as input images' dtype. Raises: ValueError: issues encountered with supplied parameters.", +"doc":"Apply various calibration adjustments to a single or set of images raw images. Args: images (numpy.ndarray): Raw images to perform calibration procedures on. cal_flatfield (pyaurorax.data.ucalgary.Calibration): Calibration object containing the flatfield data to utilize. This field is required if the step_flatfield_corection is set to True. cal_rayleighs (pyaurorax.data.ucalgary.Calibration): Calibration object containing the Rayleighs data to utilize. This field is required if the step_rayleighs_calibration is set to True. step_dark_frame_correction (bool): Perform the dark frame correction step. Defaults to True . step_flatfield_calibration (bool): Perform the flatfield correction step. Defaults to True . Note that the cal_flatfield parameter must be supplied if this is True. step_rayleighs_calibration (bool): Perform the Rayleighs conversion step. Defaults to True. Note that the cal_rayleighs parameter must be supplied if this is True. exposure_length_sec (float): Force the exposure length to be a certain value. Default is TREx NIR's nominal operating mode exposure length of 5.0 seconds . Adjusting this field should be done with caution. Returns: The calibrated images. The shape of the calibrated data will be same as the input images. The dtype of the calibrated data will depend on if the Rayleighs conversion was performed. If it was, a float32 array will be returned. If it wasn't, the dtype will be the same as input images' dtype. Raises: ValueError: issues encountered with supplied parameters.", "func":1 }, { @@ -1967,19 +1967,19 @@ INDEX=[ { "ref":"pyaurorax.tools.classes.mosaic.Mosaic.plot", "url":42, -"doc":"Generate a plot of the mosaic data. Either display it (default behaviour), save it to disk (using the savefig parameter), or return the matplotlib plot object for further usage (using the returnfig parameter). Args: map_extent (List[int]): Latitude/longitude range to be visible on the rendered map. This is a list of 4 integers and/or floats, in the order of [min_lon, max_lon, min_lat, max_lat]. figsize (tuple): The matplotlib figure size to use when plotting. For example figsize=(14,4) . rayleighs (bool): Set to True if the data being plotted is in Rayleighs. Defaults to False . max_rayleighs (int): Max intensity scale for Rayleighs. Defaults to 20000 . ocean_color (str): Colour of the ocean. Default is cartopy's default shade of blue. Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 55AADD ). land_color (str): Colour of the land. Default is grey . Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 41BB87 ). land_edgecolor (str): Color of the land edges. Default is 8A8A8A . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_color (str): Color of the country borders. Default is AEAEAE . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_disable (bool): Disbale rendering of the borders. Default is False . cbar_colorcmap (str): The matplotlib colormap to use for the plotted color bar. Default is grey . Commonly used colormaps are: - REGO: gist_heat - THEMIS ASI: gray - TREx Blue: Blues_r - TREx NIR: gray - TREx RGB: None A list of all available colormaps can be found on the [matplotlib documentation](https: matplotlib.org/stable/gallery/color/colormap_reference.html). returnfig (bool): Instead of displaying the image, return the matplotlib figure object. This allows for further plot manipulation, for example, adding labels or a title in a different location than the default. Remember - if this parameter is supplied, be sure that you close your plot after finishing work with it. This can be achieved by doing plt.close(fig) . Note that this method cannot be used in combination with savefig . savefig (bool): Save the displayed image to disk instead of displaying it. The parameter savefig_filename is required if this parameter is set to True. Defaults to False . savefig_filename (str): Filename to save the image to. Must be specified if the savefig parameter is set to True. savefig_quality (int): Quality level of the saved image. This can be specified if the savefig_filename is a JPG image. If it is a PNG, quality is ignored. Default quality level for JPGs is matplotlib/Pillow's default of 75%. Returns: The displayed montage, by default. If savefig is set to True, nothing will be returned. If returnfig is set to True, the plotting variables (fig, ax) will be returned. Raises:", +"doc":"Generate a plot of the mosaic data. Either display it (default behaviour), save it to disk (using the savefig parameter), or return the matplotlib plot object for further usage (using the returnfig parameter). Args: map_extent (List[int]): Latitude/longitude range to be visible on the rendered map. This is a list of 4 integers and/or floats, in the order of [min_lon, max_lon, min_lat, max_lat]. figsize (tuple): The matplotlib figure size to use when plotting. For example figsize=(14,4) . rayleighs (bool): Set to True if the data being plotted is in Rayleighs. Defaults to False . max_rayleighs (int): Max intensity scale for Rayleighs. Defaults to 20000 . ocean_color (str): Colour of the ocean. Default is cartopy's default shade of blue. Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 55AADD ). land_color (str): Colour of the land. Default is gray . Colours can be supplied as a word, or hexcode prefixed with a ' ' character (ie. 41BB87 ). land_edgecolor (str): Color of the land edges. Default is 8A8A8A . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_color (str): Color of the country borders. Default is AEAEAE . Colours can be supplied as a word, or hexcode prefixed with a ' ' character. borders_disable (bool): Disbale rendering of the borders. Default is False . cbar_colorcmap (str): The matplotlib colormap to use for the plotted color bar. Default is gray . Commonly used colormaps are: - REGO: gist_heat - THEMIS ASI: gray - TREx Blue: Blues_r - TREx NIR: gray - TREx RGB: None A list of all available colormaps can be found on the [matplotlib documentation](https: matplotlib.org/stable/gallery/color/colormap_reference.html). returnfig (bool): Instead of displaying the image, return the matplotlib figure object. This allows for further plot manipulation, for example, adding labels or a title in a different location than the default. Remember - if this parameter is supplied, be sure that you close your plot after finishing work with it. This can be achieved by doing plt.close(fig) . Note that this method cannot be used in combination with savefig . savefig (bool): Save the displayed image to disk instead of displaying it. The parameter savefig_filename is required if this parameter is set to True. Defaults to False . savefig_filename (str): Filename to save the image to. Must be specified if the savefig parameter is set to True. savefig_quality (int): Quality level of the saved image. This can be specified if the savefig_filename is a JPG image. If it is a PNG, quality is ignored. Default quality level for JPGs is matplotlib/Pillow's default of 75%. Returns: The displayed montage, by default. If savefig is set to True, nothing will be returned. If returnfig is set to True, the plotting variables (fig, ax) will be returned. Raises:", "func":1 }, { "ref":"pyaurorax.tools.classes.mosaic.Mosaic.add_geo_contours", "url":42, -"doc":"Add geographic contours to a mosaic. Args: lats (ndarray or list): Sequence of geographic latitudes defining a contour. lons (ndarray or list): Sequence of geographic longitudes defining a contour. constant_lats (float, int, or Sequence): Geographic Latitude(s) at which to add line(s) of constant latitude. constant_lons (float, int, or Sequence): Geographic Longitude(s) at which to add line(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", +"doc":"Add geographic contours to a mosaic. Args: lats (ndarray or list): Sequence of geographic latitudes defining a contour. lons (ndarray or list): Sequence of geographic longitudes defining a contour. constant_lats (float, int, or Sequence): Geographic Latitude(s) at which to add line(s) of constant latitude. constant_lons (float, int, or Sequence): Geographic Longitude(s) at which to add line(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). marker (str): The matplotlib marker used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", "func":1 }, { "ref":"pyaurorax.tools.classes.mosaic.Mosaic.add_mag_contours", "url":42, -"doc":"Add geomagnetic contours to a mosaic. Args: timestamp (datetime.datetime): The timestamp used in computing AACGM coordinates. lats (ndarray or list): Sequence of geomagnetic latitudes defining a contour. lons (ndarray or list): Sequence of geomagnetic longitudes defining a contour. constant_lats (float, int, Sequence): Geomagnetic latitude(s) at which to add contour(s) of constant latitude. constant_lons (float, int, Sequence): Geomagnetic longitude(s) at which to add contours(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", +"doc":"Add geomagnetic contours to a mosaic. Args: timestamp (datetime.datetime): The timestamp used in computing AACGM coordinates. lats (ndarray or list): Sequence of geomagnetic latitudes defining a contour. lons (ndarray or list): Sequence of geomagnetic longitudes defining a contour. constant_lats (float, int, Sequence): Geomagnetic latitude(s) at which to add contour(s) of constant latitude. constant_lons (float, int, Sequence): Geomagnetic longitude(s) at which to add contours(s) of constant longitude. color (str): The matplotlib color used for the contour(s). linewidth (float or int): The contour thickness. linestyle (str): The matplotlib linestyle used for the contour(s). marker (str): The matplotlib marker used for the contour(s). Returns: The object's contour_data parameter is populated appropriately. Raises: ValueError: issues encountered with supplied parameters.", "func":1 }, { diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/index.html b/docs/code/pyaurorax_api_reference/pyaurorax/index.html index 805f08d..89a73af 100644 --- a/docs/code/pyaurorax_api_reference/pyaurorax/index.html +++ b/docs/code/pyaurorax_api_reference/pyaurorax/index.html @@ -73,7 +73,7 @@
pyaurorax
pyaurorax.tools.bounding_box.extract_metric
Functions
-def azimuth(images: numpy.ndarray, skymap: pyucalgarysrs.data.classes.Skymap, azimuth_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None) ‑> numpy.ndarray
+def azimuth(images: numpy.ndarray, skymap: pyucalgarysrs.data.classes.Skymap, azimuth_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None, show_preview: bool = False) ‑> numpy.ndarray
Compute a metric of image data within an azimuthal boundary.
@@ -91,6 +91,8 @@show_preview (bool): +Plot a preview of the bounded area.
A numpy.ndarray containing the metrics computed within azimuth range, for all image frames.
-def ccd(images: numpy.ndarray, ccd_bounds: Sequence[int], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None) ‑> numpy.ndarray
+def ccd(images: numpy.ndarray, ccd_bounds: Sequence[int], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None, show_preview: bool = False) ‑> numpy.ndarray
Compute a metric of image data within a CCD boundary.
@@ -213,7 +236,7 @@ccd_bounds
: List[int]
metric
: str
mean
,
median
, sum
. Defaults to median
.show_preview (bool): +Plot a preview of the bounded area.
A numpy.ndarray containing the metrics computed within CCD bounds, for all image frames.
def ccd(images: np.ndarray,
ccd_bounds: Sequence[int],
metric: Literal["mean", "median", "sum"] = "median",
- n_channels: Optional[int] = None) -> np.ndarray:
+ n_channels: Optional[int] = None,
+ show_preview: bool = False) -> np.ndarray:
"""
Compute a metric of image data within a CCD boundary.
@@ -247,7 +273,7 @@ Raises
ccd_bounds (List[int]):
A 4-element sequence specifying the (inclusive) CCD bounds from which to extract the metric.
- Anticipated order is [y_0, y_1, x_0, x_1].
+ Anticipated order is [x_0, x_1, y_0, y_1].
metric (str):
The name of the metric that is to be computed for the bounded area. Valid metrics are `mean`,
@@ -256,6 +282,9 @@ Raises
n_channels (int):
By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+
+ show_preview (bool):
+ Plot a preview of the bounded area.
Returns:
A numpy.ndarray containing the metrics computed within CCD bounds, for all image frames.
@@ -309,8 +338,25 @@ Raises
# Slice out the bounded data
if n_channels == 1:
bound_data = images[y_0:y_1, x_0:x_1, :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, 0], top=230)
+ preview_img[y_0:y_1, x_0:x_1] = 255
+ plt.figure()
+ plt.imshow(preview_img, cmap="grey", origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
elif n_channels == 3:
bound_data = images[y_0:y_1, x_0:x_1, :, :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, :, 0], top=230)
+ preview_img[y_0:y_1, x_0:x_1, 0] = 255
+ preview_img[y_0:y_1, x_0:x_1, 1:] = 0
+ plt.figure()
+ plt.imshow(preview_img, origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
else:
raise ValueError("Unrecognized image format with shape: " + str(images.shape))
@@ -328,7 +374,7 @@ Raises
-def elevation(images: numpy.ndarray, skymap: pyucalgarysrs.data.classes.Skymap, elevation_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None) ‑> numpy.ndarray
+def elevation(images: numpy.ndarray, skymap: pyucalgarysrs.data.classes.Skymap, elevation_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None, show_preview: bool = False) ‑> numpy.ndarray
-
Compute a metric of image data within an elevation boundary.
@@ -350,6 +396,8 @@ Args
- By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+show_preview (bool):
+Plot a preview of the bounded area.
Returns
A numpy.ndarray containing the metrics computed within elevation range, for all image frames.
Raises
@@ -365,7 +413,8 @@ Raises
skymap: Skymap,
elevation_bounds: Sequence[Union[int, float]],
metric: Literal["mean", "median", "sum"] = "median",
- n_channels: Optional[int] = None) -> np.ndarray:
+ n_channels: Optional[int] = None,
+ show_preview: bool = False) -> np.ndarray:
"""
Compute a metric of image data within an elevation boundary.
@@ -389,6 +438,10 @@ Raises
n_channels (int):
By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+
+ show_preview (bool):
+ Plot a preview of the bounded area.
+
Returns:
A numpy.ndarray containing the metrics computed within elevation range, for all image frames.
@@ -432,17 +485,34 @@ Raises
elev = np.squeeze(skymap.full_elevation)
# Obtain indices into skymap within elevation range
- bound_idx = np.where(np.logical_and(elev > float(elev_0), elev < float(elev_1)))
+ bound_idx = np.where(np.logical_and(elev >= float(elev_0), elev <= float(elev_1)))
# If boundaries contain no data, raise error
if len(bound_idx[0]) == 0 or len(bound_idx[1]) == 0:
- raise ValueError("No data within desired bounds.")
+ raise ValueError("No data within desired bounds. Try a larger area.")
# Slice out the bounded data
if n_channels == 1:
bound_data = images[bound_idx[0], bound_idx[1], :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, 0], top=230)
+ preview_img[bound_idx[0], bound_idx[1]] = 255
+ plt.figure()
+ plt.imshow(preview_img, cmap="grey", origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
elif n_channels == 3:
bound_data = images[bound_idx[0], bound_idx[1], :, :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, :, 0], top=230)
+ preview_img[bound_idx[0], bound_idx[1], 0] = 255
+ preview_img[bound_idx[0], bound_idx[1], 1:] = 0
+ plt.figure()
+ plt.imshow(preview_img, origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
else:
raise ValueError("Unrecognized image format with shape: " + str(images.shape))
@@ -460,7 +530,7 @@ Raises
-def geo(images: numpy.ndarray, skymap: pyucalgarysrs.data.classes.Skymap, altitude_km: Union[float, int], lonlat_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None) ‑> numpy.ndarray
+def geo(images: numpy.ndarray, skymap: pyucalgarysrs.data.classes.Skymap, altitude_km: Union[float, int], lonlat_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None, show_preview: bool = False) ‑> numpy.ndarray
-
Compute a metric of image data within a geographic lat/lon boundary.
@@ -484,6 +554,8 @@ Args
- By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+show_preview (bool):
+Plot a preview of the bounded area.
Returns
A numpy.ndarray containing the metrics computed within elevation range, for all image frames.
Raises
@@ -500,7 +572,8 @@ Raises
altitude_km: Union[int, float],
lonlat_bounds: Sequence[Union[int, float]],
metric: Literal["mean", "median", "sum"] = "median",
- n_channels: Optional[int] = None) -> np.ndarray:
+ n_channels: Optional[int] = None,
+ show_preview: bool = False) -> np.ndarray:
"""
Compute a metric of image data within a geographic lat/lon boundary.
@@ -527,6 +600,9 @@ Raises
n_channels (int):
By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+
+ show_preview (bool):
+ Plot a preview of the bounded area.
Returns:
A numpy.ndarray containing the metrics computed within elevation range, for all image frames.
@@ -581,8 +657,9 @@ Raises
raise ValueError("Polygon defined with zero area.")
# Obtain lat/lon arrays from skymap
- if (altitude_km * 1000.0 in skymap.full_map_altitude):
- altitude_idx = np.where(altitude_km * 1000.0 == skymap.full_map_altitude)
+ interp_alts = skymap.full_map_altitude / 1000.0
+ if (altitude_km in interp_alts):
+ altitude_idx = np.where(altitude_km == interp_alts)
lats = np.squeeze(skymap.full_map_latitude[altitude_idx, :, :])
lons = np.squeeze(skymap.full_map_longitude[altitude_idx, :, :])
@@ -590,28 +667,41 @@ Raises
else:
# Make sure altitude is in range that can be interpolated
- if (altitude_km * 1000.0 < skymap.full_map_altitude[0]) or (altitude_km * 1000.0 > skymap.full_map_altitude[2]):
- raise ValueError("Altitude " + str(altitude_km) + " outside valid range of " +
- str((skymap.full_map_altitude[0] / 1000.0, skymap.full_map_altitude[2] / 1000.0)))
+ if (altitude_km < interp_alts[0]) or (altitude_km > interp_alts[2]):
+ raise ValueError("Altitude " + str(altitude_km) + " outside valid range of " + str((interp_alts[0], interp_alts[2])))
# Initialze empty lat/lon arrays
lats = np.full(np.squeeze(skymap.full_map_latitude[0, :, :]).shape, np.nan, dtype=skymap.full_map_latitude[0, :, :].dtype)
- lons = lats.copy()
+ lons = np.full(np.squeeze(skymap.full_map_latitude[0, :, :]).shape, np.nan, dtype=skymap.full_map_latitude[0, :, :].dtype)
# Interpolate lats and lons at desired altitude
for i in range(skymap.full_map_latitude.shape[1]):
for j in range(skymap.full_map_latitude.shape[2]):
- lats[i, j] = np.interp(altitude_km * 1000.0, skymap.full_map_altitude, skymap.full_map_latitude[:, i, j])
- lons[i, j] = np.interp(altitude_km * 1000.0, skymap.full_map_altitude, skymap.full_map_longitude[:, i, j])
+ pixel_lats = skymap.full_map_latitude[:, i, j]
+ pixel_lons = skymap.full_map_longitude[:, i, j]
+ if np.isnan(pixel_lats).any() or np.isnan(pixel_lons).any():
+ continue
+ lats[i, j] = np.interp(altitude_km, interp_alts, pixel_lats)
+ lons[i, j] = np.interp(altitude_km, interp_alts, pixel_lons)
lons[np.where(lons > 180)] -= 360.0 # Fix skymap to be in (-180,180) format
+ # Check that lat/lon range is reasonable
+ min_skymap_lat = np.nanmin(lats)
+ max_skymap_lat = np.nanmax(lats)
+ min_skymap_lon = np.nanmin(lons)
+ max_skymap_lon = np.nanmax(lons)
+ if (lat_0 <= min_skymap_lat) or (lat_1 >= max_skymap_lat):
+ raise ValueError(f"Latitude range supplied is outside the valid range for this skymap {(min_skymap_lat,max_skymap_lat)}.")
+ if (lon_0 <= min_skymap_lon) or (lon_1 >= max_skymap_lon):
+ raise ValueError(f"Longitude range supplied is outside the valid range for this skymap {(min_skymap_lon,max_skymap_lon)}.")
+
# Obtain indices into skymap within lat/lon range
- bound_idx = np.where(np.logical_and.reduce((lats > float(lat_0), lats < float(lat_1), lons > float(lon_0), lons < float(lon_1))))
+ bound_idx = np.where(np.logical_and.reduce((lats >= float(lat_0), lats <= float(lat_1), lons >= float(lon_0), lons <= float(lon_1))))
# If boundaries contain no data, raise error
if len(bound_idx[0]) == 0 or len(bound_idx[1]) == 0:
- raise ValueError("No data within desired bounds.")
+ raise ValueError("No data within desired bounds. Try a larger area.")
# Convert from skymap coords to image coords
bound_idx = tuple(i - 1 for i in bound_idx)
@@ -620,8 +710,25 @@ Raises
# Slice out the bounded data
if n_channels == 1:
bound_data = images[bound_idx[0], bound_idx[1], :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, 0], top=230)
+ preview_img[bound_idx[0], bound_idx[1]] = 255
+ plt.figure()
+ plt.imshow(preview_img, cmap="grey", origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
elif n_channels == 3:
bound_data = images[bound_idx[0], bound_idx[1], :, :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, :, 0], top=230)
+ preview_img[bound_idx[0], bound_idx[1], 0] = 255
+ preview_img[bound_idx[0], bound_idx[1], 1:] = 0
+ plt.figure()
+ plt.imshow(preview_img, origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
else:
raise ValueError("Unrecognized image format with shape: " + str(images.shape))
@@ -639,7 +746,7 @@ Raises
-def mag(images: numpy.ndarray, timestamp: datetime.datetime, skymap: pyucalgarysrs.data.classes.Skymap, altitude_km: Union[float, int], lonlat_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None) ‑> numpy.ndarray
+def mag(images: numpy.ndarray, timestamp: datetime.datetime, skymap: pyucalgarysrs.data.classes.Skymap, altitude_km: Union[float, int], lonlat_bounds: Sequence[Union[float, int]], metric: Literal['mean', 'median', 'sum'] = 'median', n_channels: Optional[int] = None, show_preview: bool = False) ‑> numpy.ndarray
-
Compute a metric of image data within a magnetic lat/lon boundary.
@@ -663,6 +770,8 @@ Args
- By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+show_preview (bool):
+Plot a preview of the bounded area.
Returns
A numpy.ndarray containing the metrics computed within elevation range, for all image frames.
Raises
@@ -680,7 +789,8 @@ Raises
altitude_km: Union[int, float],
lonlat_bounds: Sequence[Union[int, float]],
metric: Literal["mean", "median", "sum"] = "median",
- n_channels: Optional[int] = None) -> np.ndarray:
+ n_channels: Optional[int] = None,
+ show_preview: bool = False) -> np.ndarray:
"""
Compute a metric of image data within a magnetic lat/lon boundary.
@@ -708,6 +818,9 @@ Raises
By default, function will assume the type of data passed as input - this argument can be used
to manually specify the number of channels contained in image data.
+ show_preview (bool):
+ Plot a preview of the bounded area.
+
Returns:
A numpy.ndarray containing the metrics computed within elevation range, for all image frames.
@@ -761,28 +874,32 @@ Raises
raise ValueError("Polygon defined with zero area.")
# Obtain lat/lon arrays from skymap
- if (altitude_km * 1000.0 in skymap.full_map_altitude):
- altitude_idx = np.where(altitude_km * 1000.0 == skymap.full_map_altitude)
+ interp_alts = skymap.full_map_altitude / 1000.0
+ if (altitude_km in interp_alts):
+ altitude_idx = np.where(altitude_km == interp_alts)
lats = np.squeeze(skymap.full_map_latitude[altitude_idx, :, :])
lons = np.squeeze(skymap.full_map_longitude[altitude_idx, :, :])
- lons[np.where(lons > 180)] -= 360.0
+ lons[np.where(lons > 180)] -= 360.0 # Fix skymap to be in (-180,180) format
else:
# Make sure altitude is in range that can be interpolated
- if (altitude_km * 1000.0 < skymap.full_map_altitude[0]) or (altitude_km * 1000.0 > skymap.full_map_altitude[2]):
- raise ValueError("Altitude " + str(altitude_km) + " outside valid range of " +
- str((skymap.full_map_altitude[0] / 1000.0, skymap.full_map_altitude[2] / 1000.0)))
+ if (altitude_km < interp_alts[0]) or (altitude_km > interp_alts[2]):
+ raise ValueError("Altitude " + str(altitude_km) + " outside valid range of " + str((interp_alts[0], interp_alts[2])))
# Initialze empty lat/lon arrays
lats = np.full(np.squeeze(skymap.full_map_latitude[0, :, :]).shape, np.nan, dtype=skymap.full_map_latitude[0, :, :].dtype)
- lons = lats.copy()
+ lons = np.full(np.squeeze(skymap.full_map_latitude[0, :, :]).shape, np.nan, dtype=skymap.full_map_latitude[0, :, :].dtype)
# Interpolate lats and lons at desired altitude
for i in range(skymap.full_map_latitude.shape[1]):
for j in range(skymap.full_map_latitude.shape[2]):
- lats[i, j] = np.interp(altitude_km * 1000.0, skymap.full_map_altitude, skymap.full_map_latitude[:, i, j])
- lons[i, j] = np.interp(altitude_km * 1000.0, skymap.full_map_altitude, skymap.full_map_longitude[:, i, j])
+ pixel_lats = skymap.full_map_latitude[:, i, j]
+ pixel_lons = skymap.full_map_longitude[:, i, j]
+ if np.isnan(pixel_lats).any() or np.isnan(pixel_lons).any():
+ continue
+ lats[i, j] = np.interp(altitude_km, interp_alts, pixel_lats)
+ lons[i, j] = np.interp(altitude_km, interp_alts, pixel_lons)
lons[np.where(lons > 180)] -= 360.0 # Fix skymap to be in (-180,180) format
@@ -791,12 +908,28 @@ Raises
mag_lats = np.reshape(mag_lats, lats.shape)
mag_lons = np.reshape(mag_lons, lons.shape)
+ # Check that lat/lon range is reasonable
+ min_skymap_lat = np.nanmin(mag_lats)
+ max_skymap_lat = np.nanmax(mag_lats)
+ min_skymap_lon = np.nanmin(mag_lons)
+ max_skymap_lon = np.nanmax(mag_lons)
+ if (lat_0 <= min_skymap_lat) or (lat_1 >= max_skymap_lat):
+ raise ValueError(f"Latitude range supplied is outside the valid range for this skymap {(min_skymap_lat,max_skymap_lat)}.")
+ if (lon_0 <= min_skymap_lon) or (lon_1 >= max_skymap_lon):
+ raise ValueError(f"Latitude range supplied is outside the valid range for this skymap {(min_skymap_lon,max_skymap_lon)}.")
+
# Obtain indices into skymap within lat/lon range
- bound_idx = np.where(np.logical_and.reduce((mag_lats > float(lat_0), mag_lats < float(lat_1), mag_lons > float(lon_0), mag_lons < float(lon_1))))
+ bound_idx = np.where(
+ np.logical_and.reduce((
+ mag_lats >= float(lat_0),
+ mag_lats <= float(lat_1),
+ mag_lons >= float(lon_0),
+ mag_lons <= float(lon_1),
+ )))
# If boundaries contain no data, raise error
if len(bound_idx[0]) == 0 or len(bound_idx[1]) == 0:
- raise ValueError("No data within desired bounds.")
+ raise ValueError("No data within desired bounds. Try a larger area.")
# Convert from skymap coords to image coords
bound_idx = tuple(i - 1 for i in bound_idx)
@@ -805,8 +938,25 @@ Raises
# Slice out the bounded data
if n_channels == 1:
bound_data = images[bound_idx[0], bound_idx[1], :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, 0], top=230)
+ preview_img[bound_idx[0], bound_idx[1]] = 255
+ plt.figure()
+ plt.imshow(preview_img, cmap="grey", origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
elif n_channels == 3:
bound_data = images[bound_idx[0], bound_idx[1], :, :]
+ if show_preview:
+ preview_img = scale_intensity(images[:, :, :, 0], top=230)
+ preview_img[bound_idx[0], bound_idx[1], 0] = 255
+ preview_img[bound_idx[0], bound_idx[1], 1:] = 0
+ plt.figure()
+ plt.imshow(preview_img, origin="lower")
+ plt.title("Bounded Area Preview")
+ plt.axis("off")
+ plt.show()
else:
raise ValueError("Unrecognized image format with shape: " + str(images.shape))
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/calibration/index.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/calibration/index.html
index 98f201f..be252e2 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/calibration/index.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/calibration/index.html
@@ -61,7 +61,7 @@ Module pyaurorax.tools.calibration
Functions
-def rego(images: numpy.ndarray, cal_flatfield: Optional[pyucalgarysrs.data.classes.Calibration] = None, cal_rayleighs: Optional[pyucalgarysrs.data.classes.Calibration] = None, step_dark_frame_correction: bool = True, step_flatfield_correction: bool = True, step_rayleighs_conversion: bool = True, exposure_length_sec: float = 2.0) ‑> numpy.ndarray
+def rego(images: numpy.ndarray, cal_flatfield: Optional[pyucalgarysrs.data.classes.Calibration] = None, cal_rayleighs: Optional[pyucalgarysrs.data.classes.Calibration] = None, step_dark_frame_correction: bool = True, step_flatfield_calibration: bool = True, step_rayleighs_calibration: bool = True, exposure_length_sec: float = 2.0) ‑> numpy.ndarray
-
Apply various calibration adjustments to a single or set of images raw images.
@@ -74,13 +74,13 @@ Args
the step_flatfield_corection
is set to True.
cal_rayleighs
: Calibration
- Calibration object containing the Rayleighs data to utilize. This field is required if
-the
step_rayleighs_conversion
is set to True.
+the step_rayleighs_calibration
is set to True.
step_dark_frame_correction
: bool
- Perform the dark frame correction step. Defaults to
True
.
-step_flatfield_correction
: bool
+step_flatfield_calibration
: bool
- Perform the flatfield correction step. Defaults to
True
. Note that the cal_flatfield
parameter
must be supplied if this is True.
-step_rayleighs_conversion
: bool
+step_rayleighs_calibration
: bool
- Perform the Rayleighs conversion step. Defaults to
True.
Note that the cal_rayleighs
parameter
must be supplied if this is True.
exposure_length_sec
: float
@@ -106,8 +106,8 @@ Raises
cal_flatfield: Optional[Calibration] = None,
cal_rayleighs: Optional[Calibration] = None,
step_dark_frame_correction: bool = True,
- step_flatfield_correction: bool = True,
- step_rayleighs_conversion: bool = True,
+ step_flatfield_calibration: bool = True,
+ step_rayleighs_calibration: bool = True,
exposure_length_sec: float = 2.0,
) -> np.ndarray:
"""
@@ -121,13 +121,13 @@ Raises
the `step_flatfield_corection` is set to True.
cal_rayleighs (pyaurorax.data.ucalgary.Calibration):
Calibration object containing the Rayleighs data to utilize. This field is required if
- the `step_rayleighs_conversion` is set to True.
+ the `step_rayleighs_calibration` is set to True.
step_dark_frame_correction (bool):
Perform the dark frame correction step. Defaults to `True`.
- step_flatfield_correction (bool):
+ step_flatfield_calibration (bool):
Perform the flatfield correction step. Defaults to `True`. Note that the `cal_flatfield` parameter
must be supplied if this is True.
- step_rayleighs_conversion (bool):
+ step_rayleighs_calibration (bool):
Perform the Rayleighs conversion step. Defaults to `True.` Note that the `cal_rayleighs` parameter
must be supplied if this is True.
exposure_length_sec (float):
@@ -145,9 +145,9 @@ Raises
ValueError: issues encountered with supplied parameters.
"""
# verify that we have everything we need for each requested step
- if (step_flatfield_correction is True and cal_flatfield is None):
+ if (step_flatfield_calibration is True and cal_flatfield is None):
raise ValueError("The cal_flatfield parameter must be supplied to perform the flatfield correction step")
- if (step_rayleighs_conversion is True and cal_rayleighs is None):
+ if (step_rayleighs_calibration is True and cal_rayleighs is None):
raise ValueError("The cal_rayleighs parameter must be supplied to perform the rayleighs conversion step")
# init
@@ -160,11 +160,11 @@ Raises
calibrated_images = perform_dark_frame_correction(images, 5)
# apply the flatfield correction
- if (step_flatfield_correction is True and cal_flatfield is not None):
- calibrated_images = perform_flatfield_correction(calibrated_images, cal_flatfield)
+ if (step_flatfield_calibration is True and cal_flatfield is not None):
+ calibrated_images = perform_flatfield_calibration(calibrated_images, cal_flatfield)
# apply the rayleighs conversion
- if (step_rayleighs_conversion is True and cal_rayleighs is not None):
+ if (step_rayleighs_calibration is True and cal_rayleighs is not None):
calibrated_images = perform_rayleighs_correction(calibrated_images, cal_rayleighs, exposure_length_sec)
# return
@@ -172,7 +172,7 @@ Raises
-def trex_nir(images: numpy.ndarray, cal_flatfield: Optional[pyucalgarysrs.data.classes.Calibration] = None, cal_rayleighs: Optional[pyucalgarysrs.data.classes.Calibration] = None, step_dark_frame_correction: bool = True, step_flatfield_correction: bool = True, step_rayleighs_conversion: bool = True, exposure_length_sec: float = 5.0) ‑> numpy.ndarray
+def trex_nir(images: numpy.ndarray, cal_flatfield: Optional[pyucalgarysrs.data.classes.Calibration] = None, cal_rayleighs: Optional[pyucalgarysrs.data.classes.Calibration] = None, step_dark_frame_correction: bool = True, step_flatfield_calibration: bool = True, step_rayleighs_calibration: bool = True, exposure_length_sec: float = 5.0) ‑> numpy.ndarray
-
Apply various calibration adjustments to a single or set of images raw images.
@@ -185,13 +185,13 @@ Args
the step_flatfield_corection
is set to True.
cal_rayleighs
: Calibration
- Calibration object containing the Rayleighs data to utilize. This field is required if
-the
step_rayleighs_conversion
is set to True.
+the step_rayleighs_calibration
is set to True.
step_dark_frame_correction
: bool
- Perform the dark frame correction step. Defaults to
True
.
-step_flatfield_correction
: bool
+step_flatfield_calibration
: bool
- Perform the flatfield correction step. Defaults to
True
. Note that the cal_flatfield
parameter
must be supplied if this is True.
-step_rayleighs_conversion
: bool
+step_rayleighs_calibration
: bool
- Perform the Rayleighs conversion step. Defaults to
True.
Note that the cal_rayleighs
parameter
must be supplied if this is True.
exposure_length_sec
: float
@@ -217,8 +217,8 @@ Raises
cal_flatfield: Optional[Calibration] = None,
cal_rayleighs: Optional[Calibration] = None,
step_dark_frame_correction: bool = True,
- step_flatfield_correction: bool = True,
- step_rayleighs_conversion: bool = True,
+ step_flatfield_calibration: bool = True,
+ step_rayleighs_calibration: bool = True,
exposure_length_sec: float = 5.0,
) -> np.ndarray:
"""
@@ -232,13 +232,13 @@ Raises
the `step_flatfield_corection` is set to True.
cal_rayleighs (pyaurorax.data.ucalgary.Calibration):
Calibration object containing the Rayleighs data to utilize. This field is required if
- the `step_rayleighs_conversion` is set to True.
+ the `step_rayleighs_calibration` is set to True.
step_dark_frame_correction (bool):
Perform the dark frame correction step. Defaults to `True`.
- step_flatfield_correction (bool):
+ step_flatfield_calibration (bool):
Perform the flatfield correction step. Defaults to `True`. Note that the `cal_flatfield` parameter
must be supplied if this is True.
- step_rayleighs_conversion (bool):
+ step_rayleighs_calibration (bool):
Perform the Rayleighs conversion step. Defaults to `True.` Note that the `cal_rayleighs` parameter
must be supplied if this is True.
exposure_length_sec (float):
@@ -256,9 +256,9 @@ Raises
ValueError: issues encountered with supplied parameters.
"""
# verify that we have everything we need for each requested step
- if (step_flatfield_correction is True and cal_flatfield is None):
+ if (step_flatfield_calibration is True and cal_flatfield is None):
raise ValueError("The cal_flatfield parameter must be supplied to perform the flatfield correction step")
- if (step_rayleighs_conversion is True and cal_rayleighs is None):
+ if (step_rayleighs_calibration is True and cal_rayleighs is None):
raise ValueError("The cal_rayleighs parameter must be supplied to perform the rayleighs conversion step")
# init
@@ -271,11 +271,11 @@ Raises
calibrated_images = perform_dark_frame_correction(images, 5)
# apply the flatfield correction
- if (step_flatfield_correction is True and cal_flatfield is not None):
- calibrated_images = perform_flatfield_correction(calibrated_images, cal_flatfield)
+ if (step_flatfield_calibration is True and cal_flatfield is not None):
+ calibrated_images = perform_flatfield_calibration(calibrated_images, cal_flatfield)
# apply the rayleighs conversion
- if (step_rayleighs_conversion is True and cal_rayleighs is not None):
+ if (step_rayleighs_calibration is True and cal_rayleighs is not None):
calibrated_images = perform_rayleighs_correction(calibrated_images, cal_rayleighs, exposure_length_sec)
# return
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/montage.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/montage.html
index 554f49e..1b036d3 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/montage.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/montage.html
@@ -66,11 +66,14 @@ Module pyaurorax.tools.classes.montage
Timestamps corresponding to each montage image.
"""
- def __init__(self, data: np.ndarray, timestamp: List[datetime.datetime]):
+ def __init__(self, data: np.ndarray, timestamp: List[datetime.datetime], n_channels: int):
# public vars
self.data = data
self.timestamp = timestamp
+ # private vars
+ self.__n_channels = n_channels
+
def __str__(self) -> str:
return self.__repr__()
@@ -160,12 +163,12 @@ Module pyaurorax.tools.classes.montage
# for each image
for ax, i in zip(axs.flat, range(0, len(self.timestamp))):
- if (len(self.data.shape) == 3):
+ if (self.__n_channels == 1):
# single channel
ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
- elif (len(self.data.shape) == 4):
+ elif (self.__n_channels == 3):
# single channel
- ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
+ ax.imshow(self.data[:, :, :, i], cmap=cmap, origin="lower", interpolation="nearest")
else:
raise ValueError("Can only plot 3 or 4 dimensional data (series of single-channel or RGB mages), but found data of shape %s" %
(self.data.shape))
@@ -176,7 +179,7 @@ Module pyaurorax.tools.classes.montage
if (timestamps_display is True):
ax.text(
int(np.floor(self.data.shape[1] / 2.)),
- 0.5,
+ 5,
self.timestamp[i].strftime(timestamps_format),
ha="center",
fontsize=timestamps_fontsize,
@@ -232,7 +235,7 @@ Classes
class Montage
-(data: numpy.ndarray, timestamp: List[datetime.datetime])
+(data: numpy.ndarray, timestamp: List[datetime.datetime], n_channels: int)
-
Class representation for a montage
@@ -260,11 +263,14 @@ Attributes
Timestamps corresponding to each montage image.
"""
- def __init__(self, data: np.ndarray, timestamp: List[datetime.datetime]):
+ def __init__(self, data: np.ndarray, timestamp: List[datetime.datetime], n_channels: int):
# public vars
self.data = data
self.timestamp = timestamp
+ # private vars
+ self.__n_channels = n_channels
+
def __str__(self) -> str:
return self.__repr__()
@@ -354,12 +360,12 @@ Attributes
# for each image
for ax, i in zip(axs.flat, range(0, len(self.timestamp))):
- if (len(self.data.shape) == 3):
+ if (self.__n_channels == 1):
# single channel
ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
- elif (len(self.data.shape) == 4):
+ elif (self.__n_channels == 3):
# single channel
- ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
+ ax.imshow(self.data[:, :, :, i], cmap=cmap, origin="lower", interpolation="nearest")
else:
raise ValueError("Can only plot 3 or 4 dimensional data (series of single-channel or RGB mages), but found data of shape %s" %
(self.data.shape))
@@ -370,7 +376,7 @@ Attributes
if (timestamps_display is True):
ax.text(
int(np.floor(self.data.shape[1] / 2.)),
- 0.5,
+ 5,
self.timestamp[i].strftime(timestamps_format),
ha="center",
fontsize=timestamps_fontsize,
@@ -550,12 +556,12 @@ Raises
# for each image
for ax, i in zip(axs.flat, range(0, len(self.timestamp))):
- if (len(self.data.shape) == 3):
+ if (self.__n_channels == 1):
# single channel
ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
- elif (len(self.data.shape) == 4):
+ elif (self.__n_channels == 3):
# single channel
- ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
+ ax.imshow(self.data[:, :, :, i], cmap=cmap, origin="lower", interpolation="nearest")
else:
raise ValueError("Can only plot 3 or 4 dimensional data (series of single-channel or RGB mages), but found data of shape %s" %
(self.data.shape))
@@ -566,7 +572,7 @@ Raises
if (timestamps_display is True):
ax.text(
int(np.floor(self.data.shape[1] / 2.)),
- 0.5,
+ 5,
self.timestamp[i].strftime(timestamps_format),
ha="center",
fontsize=timestamps_fontsize,
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/mosaic.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/mosaic.html
index 1b229ef..db84593 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/mosaic.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/classes/mosaic.html
@@ -156,7 +156,7 @@ Module pyaurorax.tools.classes.mosaic
contour_data (Dict[str, List[Any]]):
Generated contour data.
"""
- polygon_data: PolyCollection
+ polygon_data: Union[PolyCollection, List[PolyCollection]]
cartopy_projection: Projection
contour_data: Optional[Dict[str, List[Any]]] = None
@@ -164,13 +164,18 @@ Module pyaurorax.tools.classes.mosaic
return self.__repr__()
def __repr__(self) -> str:
+ if isinstance(self.polygon_data, list):
+ polycollection_str = "[PolyCollection(...), ...]"
+ else:
+ polycollection_str = "PolyCollection(...)"
+
if self.contour_data is not None:
return "Mosaic(polygon_data=PolyCollection(...), cartopy_projection=Projection(%s), %s Contours)" % (
self.cartopy_projection.to_string(),
len(self.contour_data.get("x", [])),
)
else:
- return "Mosaic(polygon_data=PolyCollection(...), cartopy_projection=Projection(%s))" % (self.cartopy_projection.to_string())
+ return "Mosaic(polygon_data="+polycollection_str+", cartopy_projection=Projection(%s))" % (self.cartopy_projection.to_string())
def plot(self,
map_extent: Sequence[Union[float, int]],
@@ -179,11 +184,11 @@ Module pyaurorax.tools.classes.mosaic
max_rayleighs: int = 20000,
title: Optional[str] = None,
ocean_color: Optional[str] = None,
- land_color: str = "grey",
+ land_color: str = "gray",
land_edgecolor: str = "#8A8A8A",
borders_color: str = "#AEAEAE",
borders_disable: bool = False,
- cbar_colormap: str = "grey",
+ cbar_colormap: str = "gray",
returnfig: bool = False,
savefig: bool = False,
savefig_filename: Optional[str] = None,
@@ -213,7 +218,7 @@ Module pyaurorax.tools.classes.mosaic
as a word, or hexcode prefixed with a '#' character (ie. `#55AADD`).
land_color (str):
- Colour of the land. Default is `grey`. Colours can be supplied as a word, or hexcode
+ Colour of the land. Default is `gray`. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. `#41BB87`).
land_edgecolor (str):
@@ -228,7 +233,7 @@ Module pyaurorax.tools.classes.mosaic
Disbale rendering of the borders. Default is `False`.
cbar_colorcmap (str):
- The matplotlib colormap to use for the plotted color bar. Default is `grey`.
+ The matplotlib colormap to use for the plotted color bar. Default is `gray`.
Commonly used colormaps are:
@@ -303,7 +308,11 @@ Module pyaurorax.tools.classes.mosaic
#
# NOTE: it seems that when running this function a second time, the polygon
# data is not too happy. So to handle this, we plot a copy of the polygon data
- ax.add_collection(copy(self.polygon_data))
+ if isinstance(self.polygon_data, list):
+ for polygon_data in self.polygon_data:
+ ax.add_collection(copy(polygon_data))
+ else:
+ ax.add_collection(copy(self.polygon_data))
if self.contour_data is not None:
for i in range(len(self.contour_data["x"])):
@@ -312,6 +321,7 @@ Module pyaurorax.tools.classes.mosaic
color=self.contour_data["color"][i],
linewidth=self.contour_data["linewidth"][i],
linestyle=self.contour_data["linestyle"][i],
+ marker=self.contour_data["marker"][i],
zorder=self.contour_data["zorder"][i])
# set title
@@ -320,6 +330,9 @@ Module pyaurorax.tools.classes.mosaic
# add text
if (rayleighs is True):
+ if isinstance(self.polygon_data, list):
+ raise ValueError("Rayleighs Keyword is currently not available for mosaics with multiple sets of data.")
+
# Create a colorbar, in Rayleighs, that accounts for the scaling limit we applied
cbar_ticks = [float(j) / 5. for j in range(0, 6)]
cbar_ticknames = [str(int(max_rayleighs / 5) * j) for j in range(0, 6)]
@@ -384,6 +397,7 @@ Module pyaurorax.tools.classes.mosaic
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geographic contours to a mosaic.
@@ -410,6 +424,9 @@ Module pyaurorax.tools.classes.mosaic
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -436,6 +453,10 @@ Module pyaurorax.tools.classes.mosaic
if linewidth <= 0:
raise ValueError("Linewidth must be greater than zero.")
+ # Check that marker is valid
+ if marker not in ["", "o", ".", "p", "*", "x", "+", "X"]:
+ raise ValueError(f"Marker '{marker}' is not currently supported.")
+
# Convert numerics to lists if necessary
if constant_lats is not None:
if isinstance(constant_lats, (float, int)):
@@ -446,7 +467,7 @@ Module pyaurorax.tools.classes.mosaic
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -472,6 +493,7 @@ Module pyaurorax.tools.classes.mosaic
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -493,6 +515,7 @@ Module pyaurorax.tools.classes.mosaic
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -515,6 +538,7 @@ Module pyaurorax.tools.classes.mosaic
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
def add_mag_contours(self,
@@ -526,6 +550,7 @@ Module pyaurorax.tools.classes.mosaic
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geomagnetic contours to a mosaic.
@@ -555,6 +580,9 @@ Module pyaurorax.tools.classes.mosaic
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -591,7 +619,7 @@ Module pyaurorax.tools.classes.mosaic
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -618,6 +646,7 @@ Module pyaurorax.tools.classes.mosaic
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -641,6 +670,7 @@ Module pyaurorax.tools.classes.mosaic
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -664,6 +694,7 @@ Module pyaurorax.tools.classes.mosaic
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
@@ -678,7 +709,7 @@ Classes
class Mosaic
-(polygon_data: matplotlib.collections.PolyCollection, cartopy_projection: cartopy.crs.Projection, contour_data: Optional[Dict[str, List[Any]]] = None)
+(polygon_data: Union[matplotlib.collections.PolyCollection, List[matplotlib.collections.PolyCollection]], cartopy_projection: cartopy.crs.Projection, contour_data: Optional[Dict[str, List[Any]]] = None)
-
Class representation for a generated mosaic.
@@ -708,7 +739,7 @@ Attributes
contour_data (Dict[str, List[Any]]):
Generated contour data.
"""
- polygon_data: PolyCollection
+ polygon_data: Union[PolyCollection, List[PolyCollection]]
cartopy_projection: Projection
contour_data: Optional[Dict[str, List[Any]]] = None
@@ -716,13 +747,18 @@ Attributes
return self.__repr__()
def __repr__(self) -> str:
+ if isinstance(self.polygon_data, list):
+ polycollection_str = "[PolyCollection(...), ...]"
+ else:
+ polycollection_str = "PolyCollection(...)"
+
if self.contour_data is not None:
return "Mosaic(polygon_data=PolyCollection(...), cartopy_projection=Projection(%s), %s Contours)" % (
self.cartopy_projection.to_string(),
len(self.contour_data.get("x", [])),
)
else:
- return "Mosaic(polygon_data=PolyCollection(...), cartopy_projection=Projection(%s))" % (self.cartopy_projection.to_string())
+ return "Mosaic(polygon_data="+polycollection_str+", cartopy_projection=Projection(%s))" % (self.cartopy_projection.to_string())
def plot(self,
map_extent: Sequence[Union[float, int]],
@@ -731,11 +767,11 @@ Attributes
max_rayleighs: int = 20000,
title: Optional[str] = None,
ocean_color: Optional[str] = None,
- land_color: str = "grey",
+ land_color: str = "gray",
land_edgecolor: str = "#8A8A8A",
borders_color: str = "#AEAEAE",
borders_disable: bool = False,
- cbar_colormap: str = "grey",
+ cbar_colormap: str = "gray",
returnfig: bool = False,
savefig: bool = False,
savefig_filename: Optional[str] = None,
@@ -765,7 +801,7 @@ Attributes
as a word, or hexcode prefixed with a '#' character (ie. `#55AADD`).
land_color (str):
- Colour of the land. Default is `grey`. Colours can be supplied as a word, or hexcode
+ Colour of the land. Default is `gray`. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. `#41BB87`).
land_edgecolor (str):
@@ -780,7 +816,7 @@ Attributes
Disbale rendering of the borders. Default is `False`.
cbar_colorcmap (str):
- The matplotlib colormap to use for the plotted color bar. Default is `grey`.
+ The matplotlib colormap to use for the plotted color bar. Default is `gray`.
Commonly used colormaps are:
@@ -855,7 +891,11 @@ Attributes
#
# NOTE: it seems that when running this function a second time, the polygon
# data is not too happy. So to handle this, we plot a copy of the polygon data
- ax.add_collection(copy(self.polygon_data))
+ if isinstance(self.polygon_data, list):
+ for polygon_data in self.polygon_data:
+ ax.add_collection(copy(polygon_data))
+ else:
+ ax.add_collection(copy(self.polygon_data))
if self.contour_data is not None:
for i in range(len(self.contour_data["x"])):
@@ -864,6 +904,7 @@ Attributes
color=self.contour_data["color"][i],
linewidth=self.contour_data["linewidth"][i],
linestyle=self.contour_data["linestyle"][i],
+ marker=self.contour_data["marker"][i],
zorder=self.contour_data["zorder"][i])
# set title
@@ -872,6 +913,9 @@ Attributes
# add text
if (rayleighs is True):
+ if isinstance(self.polygon_data, list):
+ raise ValueError("Rayleighs Keyword is currently not available for mosaics with multiple sets of data.")
+
# Create a colorbar, in Rayleighs, that accounts for the scaling limit we applied
cbar_ticks = [float(j) / 5. for j in range(0, 6)]
cbar_ticknames = [str(int(max_rayleighs / 5) * j) for j in range(0, 6)]
@@ -936,6 +980,7 @@ Attributes
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geographic contours to a mosaic.
@@ -962,6 +1007,9 @@ Attributes
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -988,6 +1036,10 @@ Attributes
if linewidth <= 0:
raise ValueError("Linewidth must be greater than zero.")
+ # Check that marker is valid
+ if marker not in ["", "o", ".", "p", "*", "x", "+", "X"]:
+ raise ValueError(f"Marker '{marker}' is not currently supported.")
+
# Convert numerics to lists if necessary
if constant_lats is not None:
if isinstance(constant_lats, (float, int)):
@@ -998,7 +1050,7 @@ Attributes
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -1024,6 +1076,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -1045,6 +1098,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -1067,6 +1121,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
def add_mag_contours(self,
@@ -1078,6 +1133,7 @@ Attributes
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geomagnetic contours to a mosaic.
@@ -1107,6 +1163,9 @@ Attributes
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -1143,7 +1202,7 @@ Attributes
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -1170,6 +1229,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -1193,6 +1253,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -1216,6 +1277,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
Class variables
@@ -1228,7 +1290,7 @@ Class variables
-
-var polygon_data : matplotlib.collections.PolyCollection
+var polygon_data : Union[matplotlib.collections.PolyCollection, List[matplotlib.collections.PolyCollection]]
-
@@ -1236,7 +1298,7 @@ Class variables
Methods
-def add_geo_contours(self, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', bring_to_front: bool = False)
+def add_geo_contours(self, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', marker: str = '', bring_to_front: bool = False)
-
Add geographic contours to a mosaic.
@@ -1255,6 +1317,8 @@ Args
The contour thickness.
linestyle (str):
The matplotlib linestyle used for the contour(s).
+marker (str):
+The matplotlib marker used for the contour(s).
Returns
The object's contour_data parameter is populated appropriately.
Raises
@@ -1274,6 +1338,7 @@ Raises
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geographic contours to a mosaic.
@@ -1300,6 +1365,9 @@ Raises
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -1326,6 +1394,10 @@ Raises
if linewidth <= 0:
raise ValueError("Linewidth must be greater than zero.")
+ # Check that marker is valid
+ if marker not in ["", "o", ".", "p", "*", "x", "+", "X"]:
+ raise ValueError(f"Marker '{marker}' is not currently supported.")
+
# Convert numerics to lists if necessary
if constant_lats is not None:
if isinstance(constant_lats, (float, int)):
@@ -1336,7 +1408,7 @@ Raises
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -1362,6 +1434,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -1383,6 +1456,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -1405,11 +1479,12 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
-def add_mag_contours(self, timestamp: datetime.datetime, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', bring_to_front: bool = False)
+def add_mag_contours(self, timestamp: datetime.datetime, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', marker: str = '', bring_to_front: bool = False)
-
Add geomagnetic contours to a mosaic.
@@ -1430,6 +1505,8 @@ Args
The contour thickness.
linestyle (str):
The matplotlib linestyle used for the contour(s).
+marker (str):
+The matplotlib marker used for the contour(s).
Returns
The object's contour_data parameter is populated appropriately.
Raises
@@ -1450,6 +1527,7 @@ Raises
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geomagnetic contours to a mosaic.
@@ -1479,6 +1557,9 @@ Raises
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -1515,7 +1596,7 @@ Raises
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -1542,6 +1623,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -1565,6 +1647,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -1588,11 +1671,12 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
-def plot(self, map_extent: Sequence[Union[float, int]], figsize: Optional[Tuple[int, int]] = None, rayleighs: bool = False, max_rayleighs: int = 20000, title: Optional[str] = None, ocean_color: Optional[str] = None, land_color: str = 'grey', land_edgecolor: str = '#8A8A8A', borders_color: str = '#AEAEAE', borders_disable: bool = False, cbar_colormap: str = 'grey', returnfig: bool = False, savefig: bool = False, savefig_filename: Optional[str] = None, savefig_quality: Optional[int] = None) ‑> Any
+def plot(self, map_extent: Sequence[Union[float, int]], figsize: Optional[Tuple[int, int]] = None, rayleighs: bool = False, max_rayleighs: int = 20000, title: Optional[str] = None, ocean_color: Optional[str] = None, land_color: str = 'gray', land_edgecolor: str = '#8A8A8A', borders_color: str = '#AEAEAE', borders_disable: bool = False, cbar_colormap: str = 'gray', returnfig: bool = False, savefig: bool = False, savefig_filename: Optional[str] = None, savefig_quality: Optional[int] = None) ‑> Any
-
Generate a plot of the mosaic data.
@@ -1613,7 +1697,7 @@ Args
- Colour of the ocean. Default is cartopy's default shade of blue. Colours can be supplied
as a word, or hexcode prefixed with a '#' character (ie.
#55AADD
).
land_color
: str
-- Colour of the land. Default is
grey
. Colours can be supplied as a word, or hexcode
+- Colour of the land. Default is
gray
. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. #41BB87
).
land_edgecolor
: str
- Color of the land edges. Default is
#8A8A8A
. Colours can be supplied as a word, or
@@ -1625,7 +1709,7 @@ Args
- Disbale rendering of the borders. Default is
False
.
cbar_colorcmap
: str
-
-
The matplotlib colormap to use for the plotted color bar. Default is grey
.
+The matplotlib colormap to use for the plotted color bar. Default is gray
.
Commonly used colormaps are:
- REGO:
gist_heat
@@ -1669,11 +1753,11 @@ Returns
max_rayleighs: int = 20000,
title: Optional[str] = None,
ocean_color: Optional[str] = None,
- land_color: str = "grey",
+ land_color: str = "gray",
land_edgecolor: str = "#8A8A8A",
borders_color: str = "#AEAEAE",
borders_disable: bool = False,
- cbar_colormap: str = "grey",
+ cbar_colormap: str = "gray",
returnfig: bool = False,
savefig: bool = False,
savefig_filename: Optional[str] = None,
@@ -1703,7 +1787,7 @@ Returns
as a word, or hexcode prefixed with a '#' character (ie. `#55AADD`).
land_color (str):
- Colour of the land. Default is `grey`. Colours can be supplied as a word, or hexcode
+ Colour of the land. Default is `gray`. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. `#41BB87`).
land_edgecolor (str):
@@ -1718,7 +1802,7 @@ Returns
Disbale rendering of the borders. Default is `False`.
cbar_colorcmap (str):
- The matplotlib colormap to use for the plotted color bar. Default is `grey`.
+ The matplotlib colormap to use for the plotted color bar. Default is `gray`.
Commonly used colormaps are:
@@ -1793,7 +1877,11 @@ Returns
#
# NOTE: it seems that when running this function a second time, the polygon
# data is not too happy. So to handle this, we plot a copy of the polygon data
- ax.add_collection(copy(self.polygon_data))
+ if isinstance(self.polygon_data, list):
+ for polygon_data in self.polygon_data:
+ ax.add_collection(copy(polygon_data))
+ else:
+ ax.add_collection(copy(self.polygon_data))
if self.contour_data is not None:
for i in range(len(self.contour_data["x"])):
@@ -1802,6 +1890,7 @@ Returns
color=self.contour_data["color"][i],
linewidth=self.contour_data["linewidth"][i],
linestyle=self.contour_data["linestyle"][i],
+ marker=self.contour_data["marker"][i],
zorder=self.contour_data["zorder"][i])
# set title
@@ -1810,6 +1899,9 @@ Returns
# add text
if (rayleighs is True):
+ if isinstance(self.polygon_data, list):
+ raise ValueError("Rayleighs Keyword is currently not available for mosaics with multiple sets of data.")
+
# Create a colorbar, in Rayleighs, that accounts for the scaling limit we applied
cbar_ticks = [float(j) / 5. for j in range(0, 6)]
cbar_ticknames = [str(int(max_rayleighs / 5) * j) for j in range(0, 6)]
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/index.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/index.html
index 16a4a15..0e7509b 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/index.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/index.html
@@ -487,7 +487,7 @@ Raises
-def scale_intensity(data: numpy.ndarray, min: Optional[float] = None, max: Optional[float] = None, top: Optional[float] = None) ‑> numpy.ndarray
+def scale_intensity(data: numpy.ndarray, min: Optional[float] = None, max: Optional[float] = None, top: Optional[float] = None, memory_saver: bool = True) ‑> numpy.ndarray
-
Scale all values of an array that lie in the range min<=x<=max in to
@@ -495,17 +495,20 @@
Raises
Args
data
: numpy.ndarray
-- data array, can be 2, 3, or 4-dimensional. Assumed
-to be an image, or array of images. Also assumed that the first 2 dimensions
-are the image's x and y coordinates, and the following dimensions are some
-combination of the number of images, and/or the colour channel.
+- Data array, can be 2, 3, or 4-dimensional. Assumed to be an image, or array of
+images. Also assumed that the first 2 dimensions are the image's x and y
+coordinates, and the following dimensions are some combination of the number of
+images, and/or the colour channel.
min
: float
-- minimum value of array to be considered
+- Minimum value of array to be considered
max
: float
-- maximum value of array to be considered
+- Maximum value of array to be considered
top
: float
-- maximum value of the scaled result. If not supplied, the max value
+
- Maximum value of the scaled result. If not supplied, the max value
of the data array's dtype is used.
+ memory_saver
: bool
+- Utilize less RAM when scaling a set of images. Defaults to
True
. If set to False
then
+the scaling routine will be faster, but will utilize significantly more RAM.
Returns
A new numpy.ndarray
that is the same dimensions as the inputted data array,
@@ -524,21 +527,33 @@
Raises
min: Optional[float] = None,
max: Optional[float] = None,
top: Optional[float] = None,
+ memory_saver: bool = True,
) -> np.ndarray:
"""
Scale all values of an array that lie in the range min<=x<=max in to
the range 0<=x<=high.
Args:
- data (numpy.ndarray): data array, can be 2, 3, or 4-dimensional. Assumed
- to be an image, or array of images. Also assumed that the first 2 dimensions
- are the image's x and y coordinates, and the following dimensions are some
- combination of the number of images, and/or the colour channel.
- min (float): minimum value of array to be considered
- max (float): maximum value of array to be considered
- top (float): maximum value of the scaled result. If not supplied, the max value
+ data (numpy.ndarray):
+ Data array, can be 2, 3, or 4-dimensional. Assumed to be an image, or array of
+ images. Also assumed that the first 2 dimensions are the image's x and y
+ coordinates, and the following dimensions are some combination of the number of
+ images, and/or the colour channel.
+
+ min (float):
+ Minimum value of array to be considered
+
+ max (float):
+ Maximum value of array to be considered
+
+ top (float):
+ Maximum value of the scaled result. If not supplied, the max value
of the data array's dtype is used.
+ memory_saver (bool):
+ Utilize less RAM when scaling a set of images. Defaults to `True`. If set to `False` then
+ the scaling routine will be faster, but will utilize significantly more RAM.
+
Returns:
A new `numpy.ndarray` that is the same dimensions as the inputted data array,
with the scaling applied.
@@ -546,51 +561,34 @@ Raises
Raises:
ValueError: Issues with the supplied min, max, or top
"""
- # init
- bottom = 0
-
- # set top val
- #
- # NOTE: we only care about this if it's a uint array. If it's a double array, then we
- # check to make sure that a top was specified.
- if ("float" in str(data.dtype)):
- # this is float type, check that the top was specified
- if (top is None):
- raise ValueError("The top parameter must be specified when a float array is supplied")
- else:
- dtype_maxval = np.iinfo(data.dtype).max
- if (top is None):
- # derive values using dtype of data array
- top = dtype_maxval
-
- # check top
- if (top > dtype_maxval):
- raise ValueError("The top value must be less than or equal to %s" % (dtype_maxval))
-
- # set min and max
- if (min is None):
- cmin = data.min()
- else:
- cmin = float(min)
- if (max is None):
- cmax = data.max()
- else:
- cmax = float(max)
+ if (memory_saver is True):
+ # determine if we are single or 3 channel
+ n_channels = 1
+ if (len(data.shape) == 3):
+ # single channel
+ n_channels = 1
+ elif (len(data.shape) == 4):
+ # three channel
+ n_channels = 3
+ else:
+ ValueError("Unable to determine number of channels based on the supplied images. Make sure you are supplying a " +
+ "[rows,cols,images] or [rows,cols,channels,images] sized array.")
- # set scaling factor
- cscale = cmax - cmin
- if cscale < 0:
- raise ValueError("The max value must be larger than the min value")
- elif cscale == 0:
- cscale = 1
+ # init destination array
+ images_scaled = np.empty((data.shape), dtype=data.dtype)
- # do scaling
- scale = float(top - bottom) / cscale
- byte_data = (data - cmin) * scale + bottom
- scaled_data = (byte_data.clip(bottom, top) + 0.5).astype(data.dtype)
+ # cycle through each image
+ for i in range(0, data.shape[-1]):
+ if (n_channels == 1):
+ images_scaled[:, :, i] = __scale_data(data[:, :, i], min, max, top)
+ else:
+ images_scaled[:, :, :, i] = __scale_data(data[:, :, :, i], min, max, top)
- # return
- return scaled_data
+ # return
+ return images_scaled
+ else:
+ # scale and return
+ return __scale_data(data, min, max, top)
@@ -1588,7 +1586,7 @@ Raises
class Montage
-(data: numpy.ndarray, timestamp: List[datetime.datetime])
+(data: numpy.ndarray, timestamp: List[datetime.datetime], n_channels: int)
-
Class representation for a montage
@@ -1616,11 +1614,14 @@ Attributes
Timestamps corresponding to each montage image.
"""
- def __init__(self, data: np.ndarray, timestamp: List[datetime.datetime]):
+ def __init__(self, data: np.ndarray, timestamp: List[datetime.datetime], n_channels: int):
# public vars
self.data = data
self.timestamp = timestamp
+ # private vars
+ self.__n_channels = n_channels
+
def __str__(self) -> str:
return self.__repr__()
@@ -1710,12 +1711,12 @@ Attributes
# for each image
for ax, i in zip(axs.flat, range(0, len(self.timestamp))):
- if (len(self.data.shape) == 3):
+ if (self.__n_channels == 1):
# single channel
ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
- elif (len(self.data.shape) == 4):
+ elif (self.__n_channels == 3):
# single channel
- ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
+ ax.imshow(self.data[:, :, :, i], cmap=cmap, origin="lower", interpolation="nearest")
else:
raise ValueError("Can only plot 3 or 4 dimensional data (series of single-channel or RGB mages), but found data of shape %s" %
(self.data.shape))
@@ -1726,7 +1727,7 @@ Attributes
if (timestamps_display is True):
ax.text(
int(np.floor(self.data.shape[1] / 2.)),
- 0.5,
+ 5,
self.timestamp[i].strftime(timestamps_format),
ha="center",
fontsize=timestamps_fontsize,
@@ -1906,12 +1907,12 @@ Raises
# for each image
for ax, i in zip(axs.flat, range(0, len(self.timestamp))):
- if (len(self.data.shape) == 3):
+ if (self.__n_channels == 1):
# single channel
ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
- elif (len(self.data.shape) == 4):
+ elif (self.__n_channels == 3):
# single channel
- ax.imshow(self.data[:, :, i], cmap=cmap, origin="lower", interpolation="nearest")
+ ax.imshow(self.data[:, :, :, i], cmap=cmap, origin="lower", interpolation="nearest")
else:
raise ValueError("Can only plot 3 or 4 dimensional data (series of single-channel or RGB mages), but found data of shape %s" %
(self.data.shape))
@@ -1922,7 +1923,7 @@ Raises
if (timestamps_display is True):
ax.text(
int(np.floor(self.data.shape[1] / 2.)),
- 0.5,
+ 5,
self.timestamp[i].strftime(timestamps_format),
ha="center",
fontsize=timestamps_fontsize,
@@ -1971,7 +1972,7 @@ Raises
class Mosaic
-(polygon_data: matplotlib.collections.PolyCollection, cartopy_projection: cartopy.crs.Projection, contour_data: Optional[Dict[str, List[Any]]] = None)
+(polygon_data: Union[matplotlib.collections.PolyCollection, List[matplotlib.collections.PolyCollection]], cartopy_projection: cartopy.crs.Projection, contour_data: Optional[Dict[str, List[Any]]] = None)
-
Class representation for a generated mosaic.
@@ -2001,7 +2002,7 @@ Attributes
contour_data (Dict[str, List[Any]]):
Generated contour data.
"""
- polygon_data: PolyCollection
+ polygon_data: Union[PolyCollection, List[PolyCollection]]
cartopy_projection: Projection
contour_data: Optional[Dict[str, List[Any]]] = None
@@ -2009,13 +2010,18 @@ Attributes
return self.__repr__()
def __repr__(self) -> str:
+ if isinstance(self.polygon_data, list):
+ polycollection_str = "[PolyCollection(...), ...]"
+ else:
+ polycollection_str = "PolyCollection(...)"
+
if self.contour_data is not None:
return "Mosaic(polygon_data=PolyCollection(...), cartopy_projection=Projection(%s), %s Contours)" % (
self.cartopy_projection.to_string(),
len(self.contour_data.get("x", [])),
)
else:
- return "Mosaic(polygon_data=PolyCollection(...), cartopy_projection=Projection(%s))" % (self.cartopy_projection.to_string())
+ return "Mosaic(polygon_data="+polycollection_str+", cartopy_projection=Projection(%s))" % (self.cartopy_projection.to_string())
def plot(self,
map_extent: Sequence[Union[float, int]],
@@ -2024,11 +2030,11 @@ Attributes
max_rayleighs: int = 20000,
title: Optional[str] = None,
ocean_color: Optional[str] = None,
- land_color: str = "grey",
+ land_color: str = "gray",
land_edgecolor: str = "#8A8A8A",
borders_color: str = "#AEAEAE",
borders_disable: bool = False,
- cbar_colormap: str = "grey",
+ cbar_colormap: str = "gray",
returnfig: bool = False,
savefig: bool = False,
savefig_filename: Optional[str] = None,
@@ -2058,7 +2064,7 @@ Attributes
as a word, or hexcode prefixed with a '#' character (ie. `#55AADD`).
land_color (str):
- Colour of the land. Default is `grey`. Colours can be supplied as a word, or hexcode
+ Colour of the land. Default is `gray`. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. `#41BB87`).
land_edgecolor (str):
@@ -2073,7 +2079,7 @@ Attributes
Disbale rendering of the borders. Default is `False`.
cbar_colorcmap (str):
- The matplotlib colormap to use for the plotted color bar. Default is `grey`.
+ The matplotlib colormap to use for the plotted color bar. Default is `gray`.
Commonly used colormaps are:
@@ -2148,7 +2154,11 @@ Attributes
#
# NOTE: it seems that when running this function a second time, the polygon
# data is not too happy. So to handle this, we plot a copy of the polygon data
- ax.add_collection(copy(self.polygon_data))
+ if isinstance(self.polygon_data, list):
+ for polygon_data in self.polygon_data:
+ ax.add_collection(copy(polygon_data))
+ else:
+ ax.add_collection(copy(self.polygon_data))
if self.contour_data is not None:
for i in range(len(self.contour_data["x"])):
@@ -2157,6 +2167,7 @@ Attributes
color=self.contour_data["color"][i],
linewidth=self.contour_data["linewidth"][i],
linestyle=self.contour_data["linestyle"][i],
+ marker=self.contour_data["marker"][i],
zorder=self.contour_data["zorder"][i])
# set title
@@ -2165,6 +2176,9 @@ Attributes
# add text
if (rayleighs is True):
+ if isinstance(self.polygon_data, list):
+ raise ValueError("Rayleighs Keyword is currently not available for mosaics with multiple sets of data.")
+
# Create a colorbar, in Rayleighs, that accounts for the scaling limit we applied
cbar_ticks = [float(j) / 5. for j in range(0, 6)]
cbar_ticknames = [str(int(max_rayleighs / 5) * j) for j in range(0, 6)]
@@ -2229,6 +2243,7 @@ Attributes
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geographic contours to a mosaic.
@@ -2255,6 +2270,9 @@ Attributes
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -2281,6 +2299,10 @@ Attributes
if linewidth <= 0:
raise ValueError("Linewidth must be greater than zero.")
+ # Check that marker is valid
+ if marker not in ["", "o", ".", "p", "*", "x", "+", "X"]:
+ raise ValueError(f"Marker '{marker}' is not currently supported.")
+
# Convert numerics to lists if necessary
if constant_lats is not None:
if isinstance(constant_lats, (float, int)):
@@ -2291,7 +2313,7 @@ Attributes
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -2317,6 +2339,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -2338,6 +2361,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -2360,6 +2384,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
def add_mag_contours(self,
@@ -2371,6 +2396,7 @@ Attributes
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geomagnetic contours to a mosaic.
@@ -2400,6 +2426,9 @@ Attributes
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -2436,7 +2465,7 @@ Attributes
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -2463,6 +2492,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -2486,6 +2516,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -2509,6 +2540,7 @@ Attributes
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
Class variables
@@ -2521,7 +2553,7 @@ Class variables
-
-var polygon_data : matplotlib.collections.PolyCollection
+var polygon_data : Union[matplotlib.collections.PolyCollection, List[matplotlib.collections.PolyCollection]]
-
@@ -2529,7 +2561,7 @@ Class variables
Methods
-def add_geo_contours(self, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', bring_to_front: bool = False)
+def add_geo_contours(self, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', marker: str = '', bring_to_front: bool = False)
-
Add geographic contours to a mosaic.
@@ -2548,6 +2580,8 @@ Args
The contour thickness.
linestyle (str):
The matplotlib linestyle used for the contour(s).
+marker (str):
+The matplotlib marker used for the contour(s).
Returns
The object's contour_data parameter is populated appropriately.
Raises
@@ -2567,6 +2601,7 @@ Raises
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geographic contours to a mosaic.
@@ -2593,6 +2628,9 @@ Raises
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -2619,6 +2657,10 @@ Raises
if linewidth <= 0:
raise ValueError("Linewidth must be greater than zero.")
+ # Check that marker is valid
+ if marker not in ["", "o", ".", "p", "*", "x", "+", "X"]:
+ raise ValueError(f"Marker '{marker}' is not currently supported.")
+
# Convert numerics to lists if necessary
if constant_lats is not None:
if isinstance(constant_lats, (float, int)):
@@ -2629,7 +2671,7 @@ Raises
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -2655,6 +2697,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -2676,6 +2719,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -2698,11 +2742,12 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
-def add_mag_contours(self, timestamp: datetime.datetime, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', bring_to_front: bool = False)
+def add_mag_contours(self, timestamp: datetime.datetime, constant_lats: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, constant_lons: Union[float, int, Sequence[Union[float, int]], numpy.ndarray, ForwardRef(None)] = None, lats: Union[numpy.ndarray, list, ForwardRef(None)] = None, lons: Union[numpy.ndarray, list, ForwardRef(None)] = None, color: str = 'black', linewidth: Union[float, int] = 1, linestyle: str = 'solid', marker: str = '', bring_to_front: bool = False)
-
Add geomagnetic contours to a mosaic.
@@ -2723,6 +2768,8 @@ Args
The contour thickness.
linestyle (str):
The matplotlib linestyle used for the contour(s).
+marker (str):
+The matplotlib marker used for the contour(s).
Returns
The object's contour_data parameter is populated appropriately.
Raises
@@ -2743,6 +2790,7 @@ Raises
color: str = "black",
linewidth: Union[float, int] = 1,
linestyle: str = "solid",
+ marker: str = "",
bring_to_front: bool = False):
"""
Add geomagnetic contours to a mosaic.
@@ -2772,6 +2820,9 @@ Raises
linestyle (str):
The matplotlib linestyle used for the contour(s).
+ marker (str):
+ The matplotlib marker used for the contour(s).
+
Returns:
The object's contour_data parameter is populated appropriately.
@@ -2808,7 +2859,7 @@ Raises
# Initialize contour data dict if it doesn't exist yet
if self.contour_data is None:
- self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "zorder": []}
+ self.contour_data = {"x": [], "y": [], "color": [], "linewidth": [], "linestyle": [], "marker": [], "zorder": []}
# Obtain the mosaic's projection
source_proj = pyproj.CRS.from_user_input(cartopy.crs.Geodetic())
@@ -2835,6 +2886,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Next handling lines of constant latitude
@@ -2858,6 +2910,7 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
# Now handling lines of constant longitude
@@ -2881,11 +2934,12 @@ Raises
self.contour_data["color"].append(color)
self.contour_data["linewidth"].append(linewidth)
self.contour_data["linestyle"].append(linestyle)
+ self.contour_data["marker"].append(marker)
self.contour_data["zorder"].append(int(bring_to_front))
-def plot(self, map_extent: Sequence[Union[float, int]], figsize: Optional[Tuple[int, int]] = None, rayleighs: bool = False, max_rayleighs: int = 20000, title: Optional[str] = None, ocean_color: Optional[str] = None, land_color: str = 'grey', land_edgecolor: str = '#8A8A8A', borders_color: str = '#AEAEAE', borders_disable: bool = False, cbar_colormap: str = 'grey', returnfig: bool = False, savefig: bool = False, savefig_filename: Optional[str] = None, savefig_quality: Optional[int] = None) ‑> Any
+def plot(self, map_extent: Sequence[Union[float, int]], figsize: Optional[Tuple[int, int]] = None, rayleighs: bool = False, max_rayleighs: int = 20000, title: Optional[str] = None, ocean_color: Optional[str] = None, land_color: str = 'gray', land_edgecolor: str = '#8A8A8A', borders_color: str = '#AEAEAE', borders_disable: bool = False, cbar_colormap: str = 'gray', returnfig: bool = False, savefig: bool = False, savefig_filename: Optional[str] = None, savefig_quality: Optional[int] = None) ‑> Any
-
Generate a plot of the mosaic data.
@@ -2906,7 +2960,7 @@ Args
- Colour of the ocean. Default is cartopy's default shade of blue. Colours can be supplied
as a word, or hexcode prefixed with a '#' character (ie.
#55AADD
).
land_color
: str
-- Colour of the land. Default is
grey
. Colours can be supplied as a word, or hexcode
+- Colour of the land. Default is
gray
. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. #41BB87
).
land_edgecolor
: str
- Color of the land edges. Default is
#8A8A8A
. Colours can be supplied as a word, or
@@ -2918,7 +2972,7 @@ Args
- Disbale rendering of the borders. Default is
False
.
cbar_colorcmap
: str
-
-
The matplotlib colormap to use for the plotted color bar. Default is grey
.
+The matplotlib colormap to use for the plotted color bar. Default is gray
.
Commonly used colormaps are:
- REGO:
gist_heat
@@ -2962,11 +3016,11 @@ Returns
max_rayleighs: int = 20000,
title: Optional[str] = None,
ocean_color: Optional[str] = None,
- land_color: str = "grey",
+ land_color: str = "gray",
land_edgecolor: str = "#8A8A8A",
borders_color: str = "#AEAEAE",
borders_disable: bool = False,
- cbar_colormap: str = "grey",
+ cbar_colormap: str = "gray",
returnfig: bool = False,
savefig: bool = False,
savefig_filename: Optional[str] = None,
@@ -2996,7 +3050,7 @@ Returns
as a word, or hexcode prefixed with a '#' character (ie. `#55AADD`).
land_color (str):
- Colour of the land. Default is `grey`. Colours can be supplied as a word, or hexcode
+ Colour of the land. Default is `gray`. Colours can be supplied as a word, or hexcode
prefixed with a '#' character (ie. `#41BB87`).
land_edgecolor (str):
@@ -3011,7 +3065,7 @@ Returns
Disbale rendering of the borders. Default is `False`.
cbar_colorcmap (str):
- The matplotlib colormap to use for the plotted color bar. Default is `grey`.
+ The matplotlib colormap to use for the plotted color bar. Default is `gray`.
Commonly used colormaps are:
@@ -3086,7 +3140,11 @@ Returns
#
# NOTE: it seems that when running this function a second time, the polygon
# data is not too happy. So to handle this, we plot a copy of the polygon data
- ax.add_collection(copy(self.polygon_data))
+ if isinstance(self.polygon_data, list):
+ for polygon_data in self.polygon_data:
+ ax.add_collection(copy(polygon_data))
+ else:
+ ax.add_collection(copy(self.polygon_data))
if self.contour_data is not None:
for i in range(len(self.contour_data["x"])):
@@ -3095,6 +3153,7 @@ Returns
color=self.contour_data["color"][i],
linewidth=self.contour_data["linewidth"][i],
linestyle=self.contour_data["linestyle"][i],
+ marker=self.contour_data["marker"][i],
zorder=self.contour_data["zorder"][i])
# set title
@@ -3103,6 +3162,9 @@ Returns
# add text
if (rayleighs is True):
+ if isinstance(self.polygon_data, list):
+ raise ValueError("Rayleighs Keyword is currently not available for mosaics with multiple sets of data.")
+
# Create a colorbar, in Rayleighs, that accounts for the scaling limit we applied
cbar_ticks = [float(j) / 5. for j in range(0, 6)]
cbar_ticknames = [str(int(max_rayleighs / 5) * j) for j in range(0, 6)]
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/keogram/index.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/keogram/index.html
index 06bb011..6797ba2 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/keogram/index.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/keogram/index.html
@@ -310,7 +310,24 @@ Returns
x_max = images.shape[1] - 1
y_max = images.shape[0] - 1
- # Make sure all supplied points are within image bounds
+ # Remove any points that are not within the image CCD
+ parsed_x_locs = []
+ parsed_y_locs = []
+ for i in range(x_locs.shape[0]):
+ x = x_locs[i]
+ y = y_locs[i]
+
+ if x < 0 or x > x_max:
+ continue
+ if y < 0 or y > y_max:
+ continue
+
+ parsed_x_locs.append(x)
+ parsed_y_locs.append(y)
+ x_locs = np.array(parsed_x_locs)
+ y_locs = np.array(parsed_y_locs)
+
+ # Make sure all supplied points are within image bounds # NOTE: This should be good to remove as it shouldn't hit, testing needed
if len(np.where(np.logical_or(x_locs < 0, x_locs > x_max))[0]) != 0:
raise ValueError("The following CCD coordinates passed in through x_locs are outside of the CCD image range: " +
str(x_locs[np.where(np.logical_or(x_locs < 0, x_locs > x_max))]))
@@ -319,6 +336,7 @@ Returns
str(y_locs[np.where(np.logical_or(y_locs < 0, y_locs > y_max))]))
# Iterate points in pairs of two
+ path_counter = 0
for i in range(x_locs.shape[0] - 1):
# Points of concern for this iteration
@@ -332,7 +350,8 @@ Returns
dy = y_1 - y_0
length = np.sqrt(dx**2 + dy**2)
if length == 0:
- raise ValueError(f"Successive points (x_locs[{i}], y_locs[{i}]) and (x_locs[{i+1}], y_locs[{i+1}]) may not be the same.")
+ continue
+
dx /= length
dy /= length
@@ -359,7 +378,8 @@ Returns
indices_inside = __indices_in_polygon(vertices, (images.shape[0], images.shape[1]))
if np.any(np.array(indices_inside.shape) == 0):
- raise ValueError("Could not form keogram path... Try increasing 'width' or decreasing number of points in input coordinates.")
+ continue
+
row_idx, col_idx = zip(*indices_inside)
if n_channels == 1:
@@ -396,12 +416,19 @@ Returns
keo_arr[i, :, 1] = g_pixel_keogram
keo_arr[i, :, 2] = b_pixel_keogram
+ path_counter += 1
+
+ if path_counter == 0:
+ raise ValueError(
+ "Could not form keogram path... First ensure that coordinates are within image range. Then try increasing 'width' or decreasing number of points in input coordinates."
+ )
+
# Create keogram object
keo_obj = Keogram(data=keo_arr, timestamp=timestamp)
if preview:
plt.figure()
- plt.imshow(preview_img, cmap='grey', origin='lower')
+ plt.imshow(preview_img, cmap='gray', origin='lower')
plt.axis("off")
plt.title("Keogram Domain Preview")
plt.show()
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/montage/index.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/montage/index.html
index 96dec7a..eb3570d 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/montage/index.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/montage/index.html
@@ -94,12 +94,24 @@ Returns
Returns:
A `pyaurorax.tools.Montage` object.
"""
+ # determine if we are single or 3 channel
+ n_channels = 1
+ if (len(images.shape) == 3):
+ # single channel
+ n_channels = 1
+ elif (len(images.shape) == 4):
+ # three channel
+ n_channels = 3
+ else:
+ ValueError("Unable to determine number of channels based on the supplied images. Make sure you are supplying a " +
+ "[rows,cols,images] or [rows,cols,channels,images] sized array.")
+
# create the montage object
#
# NOTE: we presently do nothing more than repackage the data. This logic for create()
# is here in case we need to further expand functionality and need it. It's also good
# for consistency.
- montage_obj = Montage(data=images, timestamp=timestamp)
+ montage_obj = Montage(data=images, timestamp=timestamp, n_channels=n_channels)
# return
return montage_obj
diff --git a/docs/code/pyaurorax_api_reference/pyaurorax/tools/mosaic/index.html b/docs/code/pyaurorax_api_reference/pyaurorax/tools/mosaic/index.html
index 6aeeefa..48c42cc 100644
--- a/docs/code/pyaurorax_api_reference/pyaurorax/tools/mosaic/index.html
+++ b/docs/code/pyaurorax_api_reference/pyaurorax/tools/mosaic/index.html
@@ -63,7 +63,7 @@ Module pyaurorax.tools.mosaic
Functions
-def create(prepped_data: MosaicData, prepped_skymap: MosaicSkymap, frame_idx: int, cartopy_projection: cartopy.crs.Projection, min_elevation: int = 5, colormap: Optional[str] = 'gray', image_intensity_scales: Union[List, Dict, ForwardRef(None)] = None) ‑> Mosaic
+def create(prepped_data: Union[MosaicData, List[MosaicData]], prepped_skymap: Union[MosaicSkymap, List[MosaicSkymap]], frame_idx: int, cartopy_projection: cartopy.crs.Projection, min_elevation: Union[int, List[int]] = 5, colormap: Union[str, List[str], ForwardRef(None)] = None, image_intensity_scales: Union[List, Dict, ForwardRef(None)] = None) ‑> Mosaic
-
Create a mosaic object.
@@ -81,7 +81,7 @@ Args
- The minimum elevation cutoff when projecting images on the map, in degrees. Default is
5
.
cbar_colorcmap
: str
-
-
The matplotlib colormap to use for the rendered image data. Default is grey
.
+The matplotlib colormap to use for the rendered image data. Default is gray
.
Commonly used colormaps are:
- REGO:
gist_heat
@@ -114,12 +114,12 @@ Raises
Expand source code
-
def create(prepped_data: MosaicData,
- prepped_skymap: MosaicSkymap,
+def create(prepped_data: Union[MosaicData, List[MosaicData]],
+ prepped_skymap: Union[MosaicSkymap, List[MosaicSkymap]],
frame_idx: int,
cartopy_projection: cartopy.crs.Projection,
- min_elevation: int = 5,
- colormap: Optional[str] = "gray",
+ min_elevation: Union[int, List[int]] = 5,
+ colormap: Optional[Union[str, List[str]]] = None,
image_intensity_scales: Optional[Union[List, Dict]] = None) -> Mosaic:
"""
Create a mosaic object.
@@ -141,7 +141,7 @@ Raises
The minimum elevation cutoff when projecting images on the map, in degrees. Default is `5`.
cbar_colorcmap (str):
- The matplotlib colormap to use for the rendered image data. Default is `grey`.
+ The matplotlib colormap to use for the rendered image data. Default is `gray`.
Commonly used colormaps are:
@@ -178,176 +178,213 @@ Raises
pyproj_des_proj = pyproj.CRS.from_user_input(cartopy_projection)
transformer = pyproj.Transformer.from_crs(pyproj_src_proj, pyproj_des_proj, always_xy=True)
- # get sites
- site_list = prepped_data.site_uid_list
-
- # set image intensity scales
- if (image_intensity_scales is None):
- # defaults to scaling all sites between 0-20000
- image_intensity_scales = {}
- for site_uid in prepped_skymap.site_uid_list:
- image_intensity_scales[site_uid] = [__DEFAULT_SCALE_MIN, __DEFAULT_SCALE_MAX]
- elif (isinstance(image_intensity_scales, list) is True):
- image_intensity_scales_dict = {}
- for site_uid in site_list:
- image_intensity_scales_dict[site_uid] = image_intensity_scales
- image_intensity_scales = image_intensity_scales_dict
- elif (isinstance(image_intensity_scales, dict) is True):
- # no action needed
- pass
- else:
- raise ValueError("Invalid image_intensity_scales format. Please refer to the documentation for this function.")
-
- # We need a numpy array of the sites requested, that will be used to make sure any sites
- # that don't have data for the requested frame are not plotted. Also empty dict for images..
- site_list_arr = np.array(site_list)
- # all_images = np.zeros([len(site_list), width * height, __N_CHANNELS], dtype=np.int32)
- all_images = {}
-
- # Grab the elevation, and filling lats/lons
- elev = prepped_skymap.elevation
- polyfill_lon = prepped_skymap.polyfill_lon
- polyfill_lat = prepped_skymap.polyfill_lat
-
- # Now we begin to fill in the above arrays, one site at a time. Before doing so
- # we need lists to keep track of which sites actually have data for this frame.
- sites_with_data = []
- sites_with_data_idx = []
-
- # We also define a list that will hold all unique timestamps pulled from each
- # frame's metadata. This should be of length 1, and we can check that to make
- # sure all images being plotted correspond to the same time.
- unique_timestamps = []
- n_channels_dict = {}
- for site in site_list:
+ # Convert data, skymaps, colormap indicators to lists for iteration purposed
+ if not isinstance(prepped_data, list):
+ prepped_data = [prepped_data]
+ if not isinstance(prepped_skymap, list):
+ prepped_skymap = [prepped_skymap]
+ if not isinstance(colormap, list):
+ if colormap is None:
+ colormap = []
+ for _ in range(len(prepped_data)):
+ colormap.append('gray')
+ else:
+ colormap = [colormap]
+ if not isinstance(min_elevation, list):
+ tmp = []
+ for _ in range(len(prepped_data)):
+ tmp.append(min_elevation)
+ min_elevation = tmp
+
+ # Make sure all lists are same length
+ if (len(prepped_data) != len(prepped_skymap)):
+ raise ValueError("When passing lists of prepped data and prepped skymap, they must be of the same length.")
+ if (len(prepped_data) != len(colormap)) or (len(prepped_skymap) != len(colormap)):
+ raise ValueError("List of colormaps must have same length as lists of prepped data and prepped skymaps.")
+
+ # Itarate through each set of prepped data, prepped skymap
+ img_poly_list = []
+ for mosaic_data_idx in range(len(prepped_data)):
+ data = prepped_data[mosaic_data_idx]
+ skymap = prepped_skymap[mosaic_data_idx]
+ iter_cmap = colormap[mosaic_data_idx]
+ min_el = min_elevation[mosaic_data_idx]
+
+ # get sites
+ site_list = data.site_uid_list
+
+ # set image intensity scales
+ if (image_intensity_scales is None):
+ # defaults to scaling all sites between 0-20000
+ image_intensity_scales = {}
+ for site_uid in skymap.site_uid_list:
+ image_intensity_scales[site_uid] = [__DEFAULT_SCALE_MIN, __DEFAULT_SCALE_MAX]
+ elif (isinstance(image_intensity_scales, list) is True):
+ image_intensity_scales_dict = {}
+ for site_uid in site_list:
+ image_intensity_scales_dict[site_uid] = image_intensity_scales
+ image_intensity_scales = image_intensity_scales_dict
+ elif (isinstance(image_intensity_scales, dict) is True):
+ # no action needed
+ pass
+ else:
+ raise ValueError("Invalid image_intensity_scales format. Please refer to the documentation for this function.")
+
+ # We need a numpy array of the sites requested, that will be used to make sure any sites
+ # that don't have data for the requested frame are not plotted. Also empty dict for images..
+ site_list_arr = np.array(site_list)
+ # all_images = np.zeros([len(site_list), width * height, __N_CHANNELS], dtype=np.int32)
+ all_images = {}
+
+ # Grab the elevation, and filling lats/lons
+ elev = skymap.elevation
+ polyfill_lon = skymap.polyfill_lon
+ polyfill_lat = skymap.polyfill_lat
+
+ # Now we begin to fill in the above arrays, one site at a time. Before doing so
+ # we need lists to keep track of which sites actually have data for this frame.
+ sites_with_data = []
+ sites_with_data_idx = []
+
+ # We also define a list that will hold all unique timestamps pulled from each
+ # frame's metadata. This should be of length 1, and we can check that to make
+ # sure all images being plotted correspond to the same time.
+ unique_timestamps = []
+ n_channels_dict = {}
+ for site in site_list:
+
+ # set image dimensions
+ height = data.images_dimensions[site][0]
+ width = data.images_dimensions[site][1]
+
+ # Grab the timestamp for this frame/site
+ meta_timestamp = data.timestamps[frame_idx]
+
+ # Determine whether current image is single or multi-channel, and add to dictionary for reference
+ if len(data.images[site].shape) == 4:
+ n_channels = data.images[site].shape[2]
+ else:
+ n_channels = 1
+ n_channels_dict[site] = n_channels
- # set image dimensions
- height = prepped_data.images_dimensions[site][0]
- width = prepped_data.images_dimensions[site][1]
+ # Now, obtain the frame of interest, for this site, from the image data and flatten it
+ if n_channels == 1:
+ img = data.images[site][:, :, frame_idx]
+ flattened_img = np.reshape(img, (width * height))
+ else:
+ img = data.images[site][:, :, :, frame_idx]
+ flattened_img = np.reshape(img, (width * height, n_channels))
- # Grab the timestamp for this frame/site
- meta_timestamp = prepped_data.timestamps[frame_idx]
+ tmp = flattened_img
- # Determine whether current image is single or multi-channel, and add to dictionary for reference
- if len(prepped_data.images[site].shape) == 4:
- n_channels = prepped_data.images[site].shape[2]
- else:
- n_channels = 1
- n_channels_dict[site] = n_channels
+ if (np.sum(tmp) == 0.0):
+ # If it's sum is zero, we know there is no data so we can simply continue.
+ continue
- # Now, obtain the frame of interest, for this site, from the image data and flatten it
- if n_channels == 1:
- img = prepped_data.images[site][:, :, frame_idx]
- flattened_img = np.reshape(img, (width * height))
- else:
- img = prepped_data.images[site][:, :, :, frame_idx]
- flattened_img = np.reshape(img, (width * height, n_channels))
+ # Scale this site's data based on previously defined scaling bounds
+ tmp = scale_intensity(tmp, min=image_intensity_scales[site][0], max=image_intensity_scales[site][1], top=255) # type: ignore
- tmp = flattened_img
+ # Add the timestamp to tracking list if it's unique
+ if meta_timestamp not in unique_timestamps:
+ unique_timestamps.append(meta_timestamp)
- if (np.sum(tmp) == 0.0):
- # If it's sum is zero, we know there is no data so we can simply continue.
- continue
+ # Append sites to respective lists, and add image data to master list
+ sites_with_data.append(site)
+ sites_with_data_idx.append(np.where(site_list_arr == site)[0][0])
+ all_images[site] = tmp.astype(np.int32)
- # Scale this site's data based on previously defined scaling bounds
- tmp = scale_intensity(tmp, min=image_intensity_scales[site][0], max=image_intensity_scales[site][1], top=255) # type: ignore
+ # This checks to make sure all images have the same timestamps
+ if len(unique_timestamps) != 1:
+ raise Exception("Error: Images have different timestamps.")
- # Add the timestamp to tracking list if it's unique
- if meta_timestamp not in unique_timestamps:
- unique_timestamps.append(meta_timestamp)
+ # Create empty lists for tracking the pixel polygons and their values
+ lon_list = []
+ lat_list = []
+ cmap_vals = []
- # Append sites to respective lists, and add image data to master list
- sites_with_data.append(site)
- sites_with_data_idx.append(np.where(site_list_arr == site)[0][0])
- all_images[site] = tmp.astype(np.int32)
+ # Set up elevation increment for plotting. We start at the min elevation
+ # and plot groups of elevations until reaching 90 deg.
+ elev_delta = 0.1
+ el = min_el
- # This checks to make sure all images have the same timestamps
- if len(unique_timestamps) != 1:
- raise Exception("Error: Images have different timestamps.")
+ # Iterate through all elevation ranges
+ while el < 90:
- # Create empty lists for tracking the pixel polygons and their values
- lon_list = []
- lat_list = []
- cmap_vals = []
+ # Only iterate through the sites that actually have data
+ for site_id, site_idx in zip(sites_with_data, sites_with_data_idx):
+ # Get this sites number of channels
+ n_channels = n_channels_dict[site_id]
- # Set up elevation increment for plotting. We start at the min elevation
- # and plot groups of elevations until reaching 90 deg.
- elev_delta = 0.1
- el = min_elevation
+ # Get all pixels within current elevation threshold
+ el_idx = np.nonzero(np.logical_and(elev[site_idx] > el, elev[site_idx] <= el + elev_delta))[0]
+ if len(el_idx) == 0:
+ continue
- # Iterate through all elevation ranges
- while el < 90:
+ # Grab this level's filling lat/lons
+ el_lvl_fill_lats = polyfill_lat[site_idx][:, el_idx]
+ el_lvl_fill_lons = polyfill_lon[site_idx][:, el_idx]
- # Only iterate through the sites that actually have data
- for site_id, site_idx in zip(sites_with_data, sites_with_data_idx):
- # Get this sites number of channels
- n_channels = n_channels_dict[site_id]
+ # Grab this level's data values
+ if n_channels == 1:
+ el_lvl_cmap_vals = all_images[site_id][el_idx]
+ else:
+ el_lvl_cmap_vals = all_images[site_id][el_idx, :]
- # Get all pixels within current elevation threshold
- el_idx = np.nonzero(np.logical_and(elev[site_idx] > el, elev[site_idx] <= el + elev_delta))[0]
- if len(el_idx) == 0:
- continue
+ # # Mask any nans that may have slipped through - done as a precaution
+ nan_mask = ~np.isnan(el_lvl_fill_lats).any(axis=0) & ~np.isnan(el_lvl_fill_lons).any(axis=0)
- # Grab this level's filling lat/lons
- el_lvl_fill_lats = polyfill_lat[site_idx][:, el_idx]
- el_lvl_fill_lons = polyfill_lon[site_idx][:, el_idx]
+ el_lvl_fill_lats = el_lvl_fill_lats[:, nan_mask]
+ el_lvl_fill_lons = el_lvl_fill_lons[:, nan_mask]
+ if n_channels == 1:
+ el_lvl_cmap_vals = el_lvl_cmap_vals[nan_mask]
+ else:
+ el_lvl_cmap_vals = el_lvl_cmap_vals[nan_mask, :]
+
+ # Convert pixel values to a normalized float
+ el_lvl_colors = el_lvl_cmap_vals.astype(np.float32) / 255.0
+
+ # Append polygon lat/lons and values to master lists
+ if n_channels == 1:
+ # print(1, len(el_lvl_fill_lats), len(el_lvl_colors))
+ cmap = plt.get_cmap(iter_cmap)
+ for k in range(len(el_lvl_fill_lats[0, :])):
+ lon_list.append(el_lvl_fill_lons[:, k])
+ lat_list.append(el_lvl_fill_lats[:, k])
+ cmap_vals.append(cmap(el_lvl_colors[k]))
+ else:
+ for k in range(len(el_lvl_fill_lats[0, :])):
+ lon_list.append(el_lvl_fill_lons[:, k])
+ lat_list.append(el_lvl_fill_lats[:, k])
+ cmap_vals.append(el_lvl_colors[k, :])
- # Grab this level's data values
- if n_channels == 1:
- el_lvl_cmap_vals = all_images[site_id][el_idx]
- else:
- el_lvl_cmap_vals = all_images[site_id][el_idx, :]
+ el += elev_delta
- # # Mask any nans that may have slipped through - done as a precaution
- nan_mask = ~np.isnan(el_lvl_fill_lats).any(axis=0) & ~np.isnan(el_lvl_fill_lons).any(axis=0)
+ # Use our transformer object to convert the lat/lon polygons into projection coordinates.
+ lons, lats = transformer.transform(np.array(lon_list), np.array(lat_list))
- el_lvl_fill_lats = el_lvl_fill_lats[:, nan_mask]
- el_lvl_fill_lons = el_lvl_fill_lons[:, nan_mask]
- if n_channels == 1:
- el_lvl_cmap_vals = el_lvl_cmap_vals[nan_mask]
- else:
- el_lvl_cmap_vals = el_lvl_cmap_vals[nan_mask, :]
+ # Format polygons for creation of PolyCollection object
+ lonlat_polygons = np.empty((lons.shape[0], 5, 2))
+ lonlat_polygons[:, :, 0] = lons
+ lonlat_polygons[:, :, 1] = lats
- # Convert pixel values to a normalized float
- el_lvl_colors = el_lvl_cmap_vals.astype(np.float32) / 255.0
+ # generate a PolyCollection object, containing all of the Polygons shaded with
+ # their corresponding RGB value
- # Append polygon lat/lons and values to master lists
- if n_channels == 1:
- # print(1, len(el_lvl_fill_lats), len(el_lvl_colors))
- cmap = plt.get_cmap(colormap)
- for k in range(len(el_lvl_fill_lats[0, :])):
- lon_list.append(el_lvl_fill_lons[:, k])
- lat_list.append(el_lvl_fill_lats[:, k])
- cmap_vals.append(cmap(el_lvl_colors[k]))
- else:
- for k in range(len(el_lvl_fill_lats[0, :])):
- lon_list.append(el_lvl_fill_lons[:, k])
- lat_list.append(el_lvl_fill_lats[:, k])
- cmap_vals.append(el_lvl_colors[k, :])
-
- el += elev_delta
-
- # Use our transformer object to convert the lat/lon polygons into projection coordinates.
- lons, lats = transformer.transform(np.array(lon_list), np.array(lat_list))
-
- # Format polygons for creation of PolyCollection object
- lonlat_polygons = np.empty((lons.shape[0], 5, 2))
- lonlat_polygons[:, :, 0] = lons
- lonlat_polygons[:, :, 1] = lats
-
- # generate a PolyCollection object, containing all of the Polygons shaded with
- # their corresponding RGB value
-
- img_data_poly = matplotlib.collections.PolyCollection(
- lonlat_polygons, # type: ignore
- facecolors=cmap_vals,
- array=None,
- clim=[0.0, 1.0],
- edgecolors="face",
- )
+ img_data_poly = matplotlib.collections.PolyCollection(
+ lonlat_polygons, # type: ignore
+ facecolors=cmap_vals,
+ array=None,
+ clim=[0.0, 1.0],
+ edgecolors="face",
+ )
+
+ img_poly_list.append(img_data_poly)
# cast into mosaic object
- mosaic = Mosaic(polygon_data=img_data_poly, cartopy_projection=cartopy_projection)
+ if len(img_poly_list) == 1:
+ mosaic = Mosaic(polygon_data=img_poly_list[0], cartopy_projection=cartopy_projection)
+ else:
+ mosaic = Mosaic(polygon_data=img_poly_list, cartopy_projection=cartopy_projection)
# return
return mosaic
@@ -482,9 +519,11 @@ Raises
# We don't attempt to handle the same site being passed in for multiple networks
if site_uid in images_dict.keys():
- print("Warning: Same site between differing networks detected. Omitting " + site_uid)
+ warnings.warn(
+ "Same site between differing networks detected. Omitting additional '%s' data" % (site_uid),
+ stacklevel=1,
+ )
continue
-
site_uid_list.append(site_uid)
# initialize this site's data destination variables
diff --git a/pyaurorax b/pyaurorax
index 82600ad..1eb04fc 160000
--- a/pyaurorax
+++ b/pyaurorax
@@ -1 +1 @@
-Subproject commit 82600ad12a2a34828b0c34b6ae92634c111b8caa
+Subproject commit 1eb04fc860ea42e067b8fee4e045f4a0a22ce20f