Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ release.
- ISIS-SPICE and NAIF-SPICE drivers: subtract 0.5 from the detector center (ISIS 0.5-based to CSM 0-based).
- NAIF-SPICE driver: `focal_length` no longer raises `AttributeError` when `INS_FOCAL_LENGTH` is defined.
- NAIF-SPICE driver: `ephemeris_start_time` uses the scalar from `utcToEt` (was a tuple). [#739](https://github.com/DOI-USGS/ale/pull/739)
- `isd_generate` now fails with an error instead of writing an ISD with null required fields. [#754](https://github.com/DOI-USGS/ale/pull/754)
- Fixed kernel quality check to allow quality keys from different missions [#758](https://github.com/DOI-USGS/ale/pull/758)


### Changed
- `isd_generate`: default `--reduction` to `linear` (sampling every 10th line for line-scan images with >= 1000 lines). This avoids creating oversized ISDs (tens of thousands of pose samples) for long line-scan sensors such as LRO NAC, MRO CTX, and HRSC. Pass `--reduction none` to disable reduction and restore per-line sampling. [#744](https://github.com/DOI-USGS/ale/pull/744)

Expand Down
8 changes: 8 additions & 0 deletions ale/base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ class WrongLabelTypeException(Exception):
"""
pass

class InvalidISDError(Exception):
"""
Exception raised when a driver matches the label but the generated ISD is
invalid, for example a required field is null. Unlike a wrong-driver
exception, this is not retried against other drivers.
"""
pass


spiceql_mission_map = {
"APOLLO_METRIC" : "apollo15_metric",
Expand Down
12 changes: 11 additions & 1 deletion ale/drivers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import os
import os.path
import traceback
from ale.base import WrongInstrumentException, WrongLabelTypeException
from ale.base import WrongInstrumentException, WrongLabelTypeException, InvalidISDError
import logging

from ale.formatters.formatter import to_isd
Expand Down Expand Up @@ -197,6 +197,7 @@ def load_from_label(label, props={}, formatter='ale', verbose=False, only_isis_s

parsed_label = pre_parse_label(label)

invalid_isd_error = None
for driver in drivers:
if verbose:
logger.info(f'Trying {driver.__name__}')
Expand All @@ -220,13 +221,22 @@ def load_from_label(label, props={}, formatter='ale', verbose=False, only_isis_s
except WrongInstrumentException as e:
if verbose:
logger.info(f"Wrong instrument id for driver {driver.__class__.__name__}: {e}. Skipping driver.")
except InvalidISDError as e:
# the driver produced an invalid ISD (a required field was null).
# Keep trying other drivers, but remember this so that if none
# succeed we surface this real error instead of a generic one.
invalid_isd_error = e
if verbose:
logger.info(f"Invalid ISD from driver {driver.__class__.__name__}: {e}. Skipping driver.")
except Exception as e:
if verbose:
traceback.print_exc()
if verbose:
logger.info(f'End {driver}\n')
if verbose:
logger.setLevel(logger_level)
if invalid_isd_error is not None:
raise invalid_isd_error
raise Exception('No viable Driver for Label.')


Expand Down
9 changes: 9 additions & 0 deletions ale/formatters/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging

from ale.base.type_sensor import LineScanner, Framer, Radar, PushFrame
from ale.base import InvalidISDError
from ale import logger

def to_isd(driver):
Expand Down Expand Up @@ -170,6 +171,14 @@ def to_isd(driver):
isd['starting_detector_line'] = driver_data["detector_start_line"]
isd['starting_detector_sample'] = driver_data["detector_start_sample"]

# these interior-orientation fields are required for any CSM model
io_required = ['focal_length', 'detector_center_line', 'detector_center_sample',
'focal2pixel_lines', 'focal2pixel_samples']
io_null = [k for k in io_required if driver_data.get(k) is None]
if io_null:
raise InvalidISDError("Could not generate a valid ISD. Required field(s) "
"are null: " + ", ".join(io_null))

j2000_rotation = frame_chain.compute_rotation(target_frame, J2000)

instrument_position = {}
Expand Down
Loading