junocam_projection package#
Submodules#
junocam_projection.camera_funcs module#
- class junocam_projection.camera_funcs.CameraModel(filt: int)[source]#
Bases:
objectHolds the camera model and filter specific variables
- distort(c: list[float]) tuple[float][source]#
Adds barrel distortion to the image
- Parameters:
c – x and y position of undistorted pixel centers in the camera
- Returns:
x- and y- position of the pixel after adding barrel distortion
- pix2vec(px: list[float]) ndarray[source]#
Convert from pixel coordinate to vector in the JUNO_JUNOCAM reference frame. See: https://naif.jpl.nasa.gov/pub/naif/JUNO/kernels/ik/juno_junocam_v03.ti
- Parameters:
px – x and y position of pixel centers in the camera
- Returns:
vector in the JUNO_JUNOCAM reference frame
junocam_projection.cython_utils module#
junocam_projection.frameletdata module#
- class junocam_projection.frameletdata.Framelet(start_et: float, frame_delay: float, frame_no: int, color: int, img: ndarray)[source]#
Bases:
objectHolds information and methods for a single framelet in the JunoCam image
- property et: float#
Get the observation time for this framelet
- class junocam_projection.frameletdata.FrameletData(metadata: dict, imgfolder: str)[source]#
Bases:
objectHolds information and methods pertaining to all the framelets in the image
- property coords: ndarray#
The concatenated coordinate of each pixel in the mid-plane frame for each pixel in the camera frame
- property emission: ndarray#
The concatenated emission angles for each pixel in the mid-plane frame
- classmethod from_file(start_et: float, sclat: float, sclon: float, frame_delay: float, exposure: float, rawimg: ndarray, latitude: ndarray, longitude: ndarray, incidence: ndarray, emission: ndarray, fluxcal: ndarray, coords: ndarray)[source]#
Load the frame data from input array
- Parameters:
start_et – the start of the observation in spacecraft ET
sclat – the sub-spacecraft latitude
sclon – the sub-spacecraft longitude
frame_delay – the inter-frame delay in seconds
exposure – the exposure time in seconds
rawimg – the raw, decompanded image (shape: nframes, 3, 1648, 128)
latitude – the planetographic latitude for each pixel (degrees, shape: nframes, 3, 1648, 128)
longitude – the Sys III longitude for each pixel (degrees, shape: nframes, 3, 1648, 128)
incidence – the solar incidence angle (radians, shape: nframes, 3, 1648, 128)
emission – the surface emission angle wrt the spacecraft (radians, shape: nframes, 3, 1648, 128)
fluxcal – the geometric calibration for the flux for each pixel (radians, shape: nframes, 3, 1648, 128)
coords – the coordinate of the pixel in the mid-plane frame (radians, shape: nframes, 3, 1648, 128, 2)
- get_backplane(num_procs: int) None[source]#
Retrieve backplane information for all framelets (i.e., get pixel coordinates in the mid-plane frame and also incidence/emission angles)
- Parameters:
num_procs – number of processors to use for multi-threaded processing
- property image: ndarray#
The concatenated illumination-corrected image in all the framelets
- property incidence: ndarray#
The concatenated incidence angles for each pixel in the mid-plane frame
- property latitude: ndarray#
The concatenated planetographic latitude value for each pixel in the mid-plane frame
- property longitude: ndarray#
The concatenated Sys III longitude values for each pixel in the mid-plane frame
- property rawimage: ndarray#
The raw, decompanded image in all the framelets
- property tmid: float#
The mid-plane clock time
junocam_projection.globals module#
junocam_projection.mosaic module#
- junocam_projection.mosaic.blend_maps(maps: ndarray, sigma_luminance: float = 50, sigma_filter: float = 40, sigma_cut: float = 50) ndarray[source]#
Combine the images using the USGS/ISIS no-seam technique. This works by applying a low-pass filter on a mosaic, and then combining the low-pass mosaic with a mosaic of the high-pass filtered data, which tends to remove seams efficiently.
- Parameters:
maps – input array of maps (shape: [nfiles, height, width, 3])
sigma_filter – filter width for the high-pass/low-pass filter
sigma_cut – filter width for edge detection (to truncate high frequency signal at the image edges)
- junocam_projection.mosaic.get_footprint(Ls: ndarray, sigma_cut: float)[source]#
Truncates the edges by applying a low-pass filter on the image footprint and trimming at 95% level
- Parameters:
Ls – input brightness channel of the image (essentially grayscale version of image)
sigma_cut – filter width for edge detection (to truncate high frequency signal at the image edges)
- Returns:
footprint of the image with the edges truncated
- junocam_projection.mosaic.highpass(mapi: ndarray, sigma_filter: float)[source]#
Apply a high pass filter by subtracting a Gaussian blurred image.
- Parameters:
mapi – input map (must be RGB)
sigma_filter – filter width for high-pass filter
- Returns:
high pass filtered image
- junocam_projection.mosaic.highpass_luminance_correction(mapi: ndarray, sigma_filter: float = 50)[source]#
Flatten the illumination geometry by applying a high-pass filter on the luminance data
- Parameters:
mapi – input map (must be RGB)
sigma_cut – filter width for edge detection (to truncate high frequency signal at the image edges)
- Returns:
high-pass filtered image
- junocam_projection.mosaic.lowpass(data: ndarray, sigma: float)[source]#
Simple uniform filter with a size of sigma pixels. Accounts for zonal and meridional boundaries
- Parameters:
data – input data to be filtered (must be 2D)
sigma – filter size in pixels
- Returns:
low-pass filtered image (blurred image)
- junocam_projection.mosaic.mosaic_median(maps: ndarray) ndarray[source]#
Mosaic a set of maps by median-combining the data. Applies a percentile filter to remove regions with no data
- Parameters:
maps – an array of cylindrically projected maps (shape: [nfiles, height, width, 3])
- Returns:
mosaic
- junocam_projection.mosaic.nanmedian_axis0(arr)[source]#
Faster implementation of np.nanpercentile
This implementation always takes the percentile along axis 0. Uses numba to speed up the calculation by more than 7x.
Function is equivalent to np.nanpercentile(arr, <percentiles>, axis=0)
- Parameters:
arr – Array to calculate percentiles for
- Returns:
Array with median data
junocam_projection.project module#
junocam_projection.projector module#
- class junocam_projection.projector.Projector(imagefolder: str, meta: str, kerneldir: str = './kernels/', find_jitter: bool = True)[source]#
Bases:
objectThe main projector class that determines the surface intercept points of each pixel in a JunoCam image
- apply_correction(correction_type: str, minnaert_k: float = 1.05) None[source]#
Apply the requested illumination correction
This function updates the framelet’s image variable in-place and does not return a value
- Parameters:
apply_correction – the choice of lightning correction to apply. Choose betwen ‘ls’ for Lommel-Seeliger, ‘minnaert’ for Minnaert and ‘none’ for no correction, defaults to ‘ls’
minnaert_k – the index for Minnaert correction. Only used when apply_correction=’minnaert’, defaults to 1.25
- find_jitter(jitter_max: float = 25, threshold: float = 80, plot: bool = False) None[source]#
Find the best jitter value to the spacecraft camera time
- Parameters:
jitter_max – Maximum value to search for the jitter [millseconds], defaults to 25
threshold – percentile value to use to find the planet’s limb, defaults to 80
plot – boolean flag for whether to plot the intermediate steps for debugging, defaults to False
- property framecoords: ndarray#
Get the coordinates of each pixel in the current camera frame in the midplane frame
- get_limb(eti: float, cami: CameraModel) ndarray[source]#
Find the pixel positions of the planet’s limb for a given camera frame at a specific time
- Parameters:
eti – spacecraft clock time in seconds
cami – the camera which is used for observing
- Returns:
the pixel positions of the limb of the planet in the camera frame (shape: (npix, 2))
- property imagevalues: ndarray#
Get the illumination corrected image values from each frame
- classmethod load(infile: str, kerneldir: str = './', offline=False)[source]#
Load the object from a netCDF file
- Parameters:
infile – path to the input .nc file
kerneldir – Path to folder where SPICE kernels will be stored, defaults to “./”
offline – use the kernels stored locally (saves time by not scraping the NAIF servers)
- Returns:
the Projector object with the loaded data and backplane information
- load_kernels(KERNEL_DATAFOLDER: str, offline: bool = False) None[source]#
Get the kernels for the current spacecraft time and load them
- Parameters:
KERNEL_DATAFOLDER – path to the folder where kernels are stored
offline – use the kernels stored locally (saves time by not scraping the NAIF servers)
- process(num_procs: int = 8, apply_correction: str = 'ls', minnaert_k: float = 1.05) None[source]#
Processes the current image into a HEALPix map of a given resolution. Also applies lightning correction as needed.
- Parameters:
num_proces – number of cores to use for projection. Set to 1 to disable multithreading, defaults to 8
apply_correction – the choice of lightning correction to apply. Choose betwen ‘ls’ for Lommel-Seeliger, ‘minnaert’ for Minnaert and ‘none’ for no correction, defaults to ‘ls’
minnaert_k – the index for Minnaert correction. Only used when apply_correction=’minnaert’, defaults to 1.25
- project_to_az_eqdist(resolution: float = 100, n_neighbor: int = 10, max_dist: float = 25) SpatialData[source]#
Convert the image to a Azimuthal Equidistant Projection centered at the sub-spacecraft location. Note that we have to convert to a positive-east Sys III longitude so that PROJ does the right calculations
- Parameters:
resolution – the resolution of the final image in km/pixel
n_neighbor – the number of nearest neighbours to use for interpolating. Increase to get more details at the cost of performance, defaults to 5
max_dist – the largest distance between neighbours to use for interpolation, defaults to 25 pixels
- Returns:
the image in Azimuthal Equidistant projection (shape: ny, nx, 3)
- project_to_cylindrical(resolution: float = 50, n_neighbor: int = 10, max_dist: float = 25) SpatialData[source]#
Convert the image to a Cylindrical projection Note that we have to convert to a positive-east Sys III longitude so that PROJ does the right calculations
- Parameters:
resolution – the resolution of the final image in pixels/degree
n_neighbor – the number of nearest neighbours to use for interpolating. Increase to get more details at the cost of performance, defaults to 5
max_dist – the largest distance between neighbours to use for interpolation, defaults to 25 pixels
- Returns:
the image in cylindrical projection (shape: nlat, nlon, 3)
- project_to_cylindrical_fullglobe(resolution: float = 50, n_neighbor: int = 10, max_dist: float = 25) SpatialData[source]#
- project_to_laea(resolution: float = 100, n_neighbor: int = 10, max_dist: float = 25) SpatialData[source]#
Convert the image to a Lambert Azimuthal Equal Area projection centered at the sub-spacecraft location. Note that we have to convert to a positive-east Sys III longitude so that PROJ does the right calculations
- Parameters:
resolution – the resolution of the final image in km/pixel
n_neighbor – the number of nearest neighbours to use for interpolating. Increase to get more details at the cost of performance, defaults to 5
max_dist – the largest distance between neighbours to use for interpolation, defaults to 25 pixels
- Returns:
the image in LAEA projection (shape: ny, nx, 3)
- project_to_mercator(resolution: float = 100, n_neighbor: int = 10, max_dist: float = 25) SpatialData[source]#
Convert the image to a Transverse Mercator projection centered at the sub-spacecraft location. Note that we have to convert to a positive-east Sys III longitude so that PROJ does the right calculations
- Parameters:
resolution – the resolution of the final image in km/pixel
n_neighbor – the number of nearest neighbours to use for interpolating. Increase to get more details at the cost of performance, defaults to 5
max_dist – the largest distance between neighbours to use for interpolation, defaults to 25 pixels
- Returns:
the image in Tranverse Mercator projection (shape: ny, nx, 3)
- project_to_pyproj(projection: CoordinateOperation, resolution: float = 50, n_neighbor: int = 10, max_dist: float = 25)[source]#
Convert the image to an arbitrary PyProj projection Note that we have to convert to a positive-east Sys III longitude so that PROJ does the right calculations
- Parameters:
resolution – the resolution of the final image in km/pixel
n_neighbor – the number of nearest neighbours to use for interpolating. Increase to get more details at the cost of performance, defaults to 5
max_dist – the largest distance between neighbours to use for interpolation, defaults to 25 pixels
- Returns:
the image in LAEA projection (shape: ny, nx, 3)
- junocam_projection.projector.apply_lommel_seeliger(imgvals: ndarray, incidence: ndarray, emission: ndarray) ndarray[source]#
Apply the Lommel-Seeliger correction for incidence
- Parameters:
imgvals – the raw image values
incidence – the incidence angles (in radians) for each pixel in imgvals
emission – the emission angles (in radians) for each pixel in imgvals
- Returns:
the corrected image values with the same shape as imgvals
- junocam_projection.projector.apply_minnaert(imgvals: ndarray, incidence: ndarray, emission: ndarray, k: float = 1.05, trim=-8) ndarray[source]#
Apply the Minnaert illumination correction
- Parameters:
imgvals – the raw image values
incidence – the incidence angles (in radians) for each pixel in imgvals
emission – the emission angles (in radians) for each pixel in imgvals
minnaert_k – the index for Minnaert correction, defaults to 0.95
- Returns:
the corrected image values with the same shape as imgvals
- junocam_projection.projector.create_image_from_grid(coords: ndarray, imgvals: ndarray, inds: ndarray, pix: ndarray, img_shape: tuple[int], n_neighbor: int = 5, max_dist: float = 25.0)[source]#
Reproject an irregular spaced image onto a regular grid from a list of coordinate locations and corresponding image values. This uses an inverse lookup-table defined by pix, where pix gives the coordinates in the original image where the corresponding pixel coordinate on the new image should be. The coordinate on the new image is given by the inds.
- Parameters:
coords – the pixel coordinates in the original image
imgvals – the image values corresponding to coords
inds – the coordinate on the new image where we need to interpolate
pix – the coordinate in the original image corresponding to each pixel in inds
img_shape – the shape of the new image
n_neighbor – the number of nearest neighbours to use for interpolating. Increase to get more details at the cost of performance, defaults to 5
max_dist – the largest distance between neighbours to use for interpolation, defaults to 25 pixels
- Returns:
the interpolated new image of shape img_shape where every pixel at inds has corresponding values interpolated from imgvals
junocam_projection.spatial module#
- class junocam_projection.spatial.SpatialData(id: str, image: numpy.ndarray, crs: pyproj.crs.crs.CRS, x: numpy.ndarray, y: numpy.ndarray, lon: numpy.ndarray, lat: numpy.ndarray)[source]#
Bases:
object- property cartopy_crs#
Get the CRS for cartopy for plotting
- Returns:
the Cartopy CRS object
- crs: CRS#
- id: str#
- image: ndarray#
- lat: ndarray#
- lon: ndarray#
- to_GeoTIFF(fname)[source]#
Save the data to GeoTIFF with the right extents
- Parameters:
fname – path to the GeoTIFF
- x: ndarray#
- y: ndarray#
junocam_projection.spice_utils module#
- junocam_projection.spice_utils.check_and_download_kernels(kernels: list[str], KERNEL_DATAFOLDER: str) list[str][source]#
Check whether the list of kernels are in the local directory and download them if needed.
- Parameters:
kernels – list of kernel filenames (relative to the root URL)
KERNEL_DATAFOLDER – path to the local kernel directory to store downloaded kernels
- Returns:
list of local paths to the kernels
- junocam_projection.spice_utils.download_kernel(kernel: str, KERNEL_DATAFOLDER: str) None[source]#
Download a given kernel to the local folder
- Parameters:
kernel – URL path to the kernel
KERNEL_DATAFOLDER – root folder to store the downloaded kernel
- junocam_projection.spice_utils.fetch_kernels_from_disk(path: str, pattern: str) list[str][source]#
Fetch kernels from local path matching a given pattern
- Parameters:
path – path to the folder at which to search for kernels
pattern – file-name pattern to search for relevant links
- Returns:
list of files that match the given pattern
- junocam_projection.spice_utils.fetch_kernels_from_https(path: str, pattern: str) list[str][source]#
Fetch kernels from URL matching a given pattern
- Parameters:
path – URL at which to search for kernels (will parse HTML links in this URL)
pattern – file-name pattern to search for relevant links
- Returns:
list of files that match the given pattern
- junocam_projection.spice_utils.get_kernels(KERNEL_DATAFOLDER: str, start_utc: float, offline: bool = False) list[str][source]#
Fetch all relevant kernels for JunoCam at a given time
- Parameters:
KERNEL_DATAFOLDER – path to the local kernel directory to store downloaded kernels
start_utc – the spacecraft clock time in start_utc
offline – use the kernels stored locally (saves time by not scraping the NAIF servers)
- Returns:
list of local paths to the kernels