diff --git a/ale/base/base.py b/ale/base/base.py index c3febdc0c022e6fa34400a86f72ca0a76f7fbbf0..05423b804ea8b61918cf8ff48adffda73a71a3ea 100644 --- a/ale/base/base.py +++ b/ale/base/base.py @@ -53,25 +53,25 @@ class Driver(ABC): """ pass - @abc.abstractproperty + @property def detector_start_line(self): """ Returns ------- : int - Detector line corresponding to the first image line + Zero based Detector line corresponding to the first image line """ - pass + return 0 - @abc.abstractproperty + @property def detector_start_sample(self): """ Returns ------- : int - Detector sample corresponding to the first image sample + Zero based Detector sample corresponding to the first image sample """ - pass + return 0 @abc.abstractproperty def sample_summing(self): diff --git a/ale/drivers/cassini_drivers.py b/ale/drivers/cassini_drivers.py index f2cecaa5bc64fe00e14d07fd04c05b0dea6b4432..c89816d01dc75e067072c54fddc35c255fa476f2 100644 --- a/ale/drivers/cassini_drivers.py +++ b/ale/drivers/cassini_drivers.py @@ -175,23 +175,3 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis ISIS sensor model version """ return 1 - - @property - def detector_start_sample(self): - """ - Returns - ------- - : int - Detector sample corresponding to the first image sample - """ - return 1 - - @property - def detector_start_line(self): - """ - Returns - ------- - : int - Detector line corresponding to the first image line - """ - return 1 diff --git a/ale/drivers/dawn_drivers.py b/ale/drivers/dawn_drivers.py index f0ea7bf1a83f7f879323ece5a81588d8e5b94dd3..9b46cb92bbe7b76d44728d2052a33838b19404c4 100644 --- a/ale/drivers/dawn_drivers.py +++ b/ale/drivers/dawn_drivers.py @@ -198,26 +198,6 @@ class DawnFcPds3NaifSpiceDriver(Pds3Label, NaifSpice, Framer, Driver): pixel_size = spice.gdpool('INS{}_PIXEL_SIZE'.format(self.ikid), 0, 1)[0] * 0.001 return [0.0, 0.0, 1/pixel_size] - @property - def detector_start_line(self): - """ - Returns - ------- - : int - Detector line corresponding to the first image line - """ - return 1 - - @property - def detector_start_sample(self): - """ - Returns - ------- - : int - Detector sample corresponding to the first image sample - """ - return 1 - @property def sensor_model_version(self): """ diff --git a/ale/drivers/kaguya_drivers.py b/ale/drivers/kaguya_drivers.py index 17c1c23471c1313d8670a82809cbf0e1ddc63464..8a60936587c82c43dbafda5febfb00a3323a291c 100644 --- a/ale/drivers/kaguya_drivers.py +++ b/ale/drivers/kaguya_drivers.py @@ -49,7 +49,7 @@ class KaguyaTcPds3NaifSpiceDriver(Pds3Label,NaifSpice, LineScanner, Driver): Returns corrected utc start time. If no corrected form is found, defaults to the form specified in parent class. - + Returns ------- : str @@ -155,7 +155,7 @@ class KaguyaTcPds3NaifSpiceDriver(Pds3Label,NaifSpice, LineScanner, Driver): No NAIF code exists for the spacecraft name 'SELENE-M.' The NAIF code exists only for 'SELENE' or 'KAGUYA' -- 'SELENE' is captured as 'MISSION_NAME' - + Returns ------- : str @@ -481,16 +481,6 @@ class KaguyaTcPds3NaifSpiceDriver(Pds3Label,NaifSpice, LineScanner, Driver): """ return self.label["FIRST_PIXEL_NUMBER"] - @property - def detector_start_line(self): - """ - Returns - ------- - : int - Detector line corresponding to the first image sample - """ - return 1 - @property def sensor_model_version(self): diff --git a/ale/drivers/lro_drivers.py b/ale/drivers/lro_drivers.py index e4cb5b7b752e0cf3e7ea825054fdb2fb4e757a6f..c49c7e7c985565ae7795d9f607ca84415328c55c 100644 --- a/ale/drivers/lro_drivers.py +++ b/ale/drivers/lro_drivers.py @@ -90,30 +90,6 @@ class LroLrocPds3LabelNaifSpiceDriver(NaifSpice, Pds3Label, LineScanner, Driver) """ return 2 - @property - def detector_start_sample(self): - """ - Returns the starting sample contained in the image - - Returns - ------- - : int - Returns the starting sample - """ - return 1 - - @property - def detector_start_line(self): - """ - Returns the starting line contained in the image - - Returns - ------- - : int - Returns the starting line - """ - return 1 - @property def usgscsm_distortion_model(self): """ diff --git a/ale/drivers/mex_drivers.py b/ale/drivers/mex_drivers.py index e6a1cc49021cda74a993cb8662c053c6da677b31..734aed463041eaa9a41b223b2845b00231c0f957 100644 --- a/ale/drivers/mex_drivers.py +++ b/ale/drivers/mex_drivers.py @@ -18,9 +18,9 @@ from ale.util import find_latest_metakernel FILTER_SPECIFIC_LOOKUP = { # This table contains the filter specific information from the ISIS iak kernel. The format is as follows: - # + # # fikid: [focal_length, ITRANSX, ITRANSY, ITRANSS, ITRANSL] - -41211: [174.80, + -41211: [174.80, [-0.026155499841886, -0.006999999957684, 0.0000007696901985785], [-59.9926971240526, 0.0000007696901985785, 0.006999999957684], [-2.7941368739538, -142.857141993552, 0.015707963236297], @@ -73,12 +73,12 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor NOTES ----- - + * HRSC has 9 different filters. Each has it's own instrument id, as well as the main/"HEAD" camera composing those filters. There is also another "SRC" instrument, making-up a total of 11 distinct sensors. It is very important to understand which code is needed when/where. - + * HRSC is a variable line scanner, and so does not maintain one exposure duration, but rather differing exposure durations per line. This information is stored within the individual records in the image data @@ -87,8 +87,8 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor making up the float containing that line's exposure duration. """ - - + + @property def metakernel(self): """ @@ -104,8 +104,8 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor if not hasattr(self, '_metakernel'): self._metakernel = find_latest_metakernel(self._metakernel_dir, self.utc_start_time.year) return self._metakernel - - + + @property def odtk(self): """ @@ -117,13 +117,13 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor Radial distortion coefficients. There is only one coefficient for LROC NAC l/r """ return [0.0, 0.0, 0.0] - - + + @property def ikid(self): """ Returns the Naif ID code for the HRSC head instrument - + This would be the Naif ID code for the base (or "head") instrument. Returns @@ -132,13 +132,13 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor Naif ID used to for indentifying the instrument in Spice kernels """ return spice.bods2c("MEX_HRSC_HEAD") - - + + @property def fikid(self): """ Naif ID code of the filter dependent instrument codes. - + Expects filter_number to be defined. This should be an integer containing the filter number from the pds3 label. Expects ikid to be defined. This should be the integer Naid ID code for @@ -150,8 +150,8 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor Naif ID code used in calculating focal length """ return spice.bods2c(self.label['DETECTOR_ID']) - - + + # TODO Since HRSC has different frames based on filters, need to check that # this is returning the value needed for all calculations from the base # class and therefor does not need to be reimplemented. @@ -159,23 +159,23 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor # def sensor_frame_id(self): # """ # Returns the Naif ID code for the sensor reference frame - # - # + # + # # This is the frame of the HRSC instrument itself, and is not dependant on filter. - # + # # Returns # ------- # : int # Naif ID code for the sensor frame # """ # return -41210 - - + + @property def instrument_id(self): """ Returns the short name of the instrument - + MEX HRSC has nine different filters each with their own name. Returns @@ -184,8 +184,8 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor Short name of the instrument """ return self.label['DETECTOR_ID'] - - + + @property def spacecraft_name(self): """ @@ -206,10 +206,10 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor def focal_length(self): """ Returns the focal length of the filter-specific sensor - + Expects fikid to be defined. This must be the integer Naif id code of - the filter-specific instrument. - + the filter-specific instrument. + NOTE: These values are pulled from ISIS iak kernels. Returns @@ -218,14 +218,14 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor focal length """ return FILTER_SPECIFIC_LOOKUP[self.fikid][0] - - + + @property def focal2pixel_lines(self): """ Expects fikid to be defined. This must be the integer Naif id code of the filter-sepcific instrument. - + NOTE: These values are pulled from ISIS iak kernels. Returns @@ -234,14 +234,14 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor focal plane to detector lines """ return FILTER_SPECIFIC_LOOKUP[self.fikid][4] - - + + @property def focal2pixel_samples(self): """ Expects fikid to be defined. This must be the integer Naif id code of the filter-sepcific instrument. - + NOTE: These values are pulled from ISIS iak kernels. Returns @@ -250,14 +250,14 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor focal plane to detector samples """ return FILTER_SPECIFIC_LOOKUP[self.fikid][3] - - + + @property def pixel2focal_x(self): """ Expects fikid to be defined. This must be the integer Naif id code of the filter-specific instrument. - + NOTE: These values are pulled from ISIS iak kernels. Returns @@ -266,14 +266,14 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor detector to focal plane x """ return FILTER_SPECIFIC_LOOKUP[self.fikid][1] - - + + @property def pixel2focal_y(self): """ Expects fikid to be defined. This must be the integer Naif id code of the filter-specific instrument. - + NOTE: These values are pulled from ISIS iak kernels. Returns @@ -282,24 +282,13 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor detector to focal plane y """ return FILTER_SPECIFIC_LOOKUP[self.fikid][2] - - - @property - def detector_start_line(self): - """ - Returns - ------- - : int - Detector sample corresponding to the first image sample - """ - return 1 - - + + @property def detector_center_line(self): """ Returns the center detector line. - + For HRSC, we are dealing with a single line, so center line will be 1. Returns @@ -308,8 +297,8 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor Detector line of the principal point """ return 0.0 - - + + @property def detector_start_sample(self): """ @@ -319,34 +308,34 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor Detector line corresponding to the first image sample """ return self.label["SAMPLE_FIRST_PIXEL"] - - + + @property def detector_center_sample(self): """ Returns the center detector sample. - + For HRSC, center sample is consistent regardless of filter. - + Returns ------- : float Detector sample of the principal point """ return 2592.5 - - + + @property def line_scan_rate(self): """ Returns a 2D array of line scan rates. - + For HRSC, this data is actually imbedded in the binary data of the image itself. Each line is stored in what is referred to as a "record" within the image. The label will have the size of each record, the number of records, and the number of records in the label, so the beginning of binary data can be calculated. - + For each line/record of the binary data, the first 8 bytes make up the double presicion value of the ephemeris time, with the next 4 bytes making up the float value of the line exposure duration for the @@ -366,7 +355,7 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor lines = [] times = [] durations = [] - + with open(self._file, 'rb') as image_file: bytes_per_record = self.label['RECORD_BYTES'] num_records = self.label['FILE_RECORDS'] @@ -374,7 +363,7 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor img_start_byte = bytes_per_record * (img_start_record - 1) # Offset by one for zero-based records num_img_records = num_records - img_start_record image_file.seek(img_start_byte) - + for record in range(num_img_records): record_bytes = image_file.read(bytes_per_record) eph_time = struct.unpack('<d', record_bytes[:8])[0] @@ -385,15 +374,15 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor times.append(eph_time) durations.append(exp_dur) # Only add records if exposure duration has changed since the line before - elif exp_dur != durations[-1]: + elif exp_dur != durations[-1]: # Offset for zero-based corrections, and then offest for ISIS pixel definition lines.append(record+1-0.5) times.append(eph_time) durations.append(exp_dur) return lines, times, durations - - + + # TODO We need to confirm that returning nothing here does not affect # calculations elsewhere in code. Or is there possibly just a better way of # doing this? @@ -402,7 +391,7 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor """ Line exposure duration returns the time between the exposures for subsequent lines. - + Since HRSC is a variable line scan camera, it does not make sense to have one exposure duration value. @@ -411,9 +400,9 @@ class MexHrscPds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, RadialDistor : float Returns the line exposure duration in seconds from the PDS3 label. """ - return - - + return + + @property def sensor_model_version(self): """ diff --git a/ale/drivers/mro_drivers.py b/ale/drivers/mro_drivers.py index 48c4b866207f4f8d4a6a4bd1f2ebedce3b3d70fb..c704ead82c47f7d0b6431056b5fd6a3105917ed0 100644 --- a/ale/drivers/mro_drivers.py +++ b/ale/drivers/mro_drivers.py @@ -155,16 +155,6 @@ class MroCtxIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, LineScanner, RadialDi } return name_lookup[super().platform_name] - @property - def detector_start_line(self): - """ - Returns - ------- - : int - The starting detector line of the image - """ - return 1 - @property def detector_start_sample(self): """ @@ -249,16 +239,6 @@ class MroCtxPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, LineScanner, RadialDi } return name_lookup[super().spacecraft_name] - @property - def detector_start_line(self): - """ - Returns - ------- - : int - Starting detector line for the image - """ - return 1 - @property def detector_start_sample(self): """ diff --git a/tests/pytests/test_lro_drivers.py b/tests/pytests/test_lro_drivers.py index cfabb358342fe699097eeb3fa56577ce790df0df..6ce68dac40b703f95137f0a6b28f22c3d4b8b978 100644 --- a/tests/pytests/test_lro_drivers.py +++ b/tests/pytests/test_lro_drivers.py @@ -46,12 +46,6 @@ def test_spacecraft_name(driver): def test_sensor_model_version(driver): assert driver.sensor_model_version == 2 -def test_detector_start_sample(driver): - assert driver.detector_start_sample == 1 - -def test_detector_start_line(driver): - assert driver.detector_start_sample == 1 - @patch('ale.base.data_naif.NaifSpice.ikid', 123) def test_odtk(driver): assert driver.odtk == [1.0] @@ -60,5 +54,3 @@ def test_odtk(driver): def test_usgscsm_distortion_model(driver): distortion_model = driver.usgscsm_distortion_model assert distortion_model['lrolrocnac']['coefficients'] == [1.0] - - diff --git a/tests/pytests/test_mro_drivers.py b/tests/pytests/test_mro_drivers.py index 5f1ee8a0c438ea6c606438ce142b1a9ddd3f320f..453d093c6dfb75a5160f5417545029e153d548e5 100644 --- a/tests/pytests/test_mro_drivers.py +++ b/tests/pytests/test_mro_drivers.py @@ -41,9 +41,6 @@ def test_spacecraft_name_pds3(Pds3NaifDriver): def test_exposure_duration_pds3(Pds3NaifDriver): assert Pds3NaifDriver.exposure_duration == 12.1 -def test_detector_start_line_pds3(Pds3NaifDriver): - assert Pds3NaifDriver.detector_start_line == 1 - def test_detector_start_sample_pds3(Pds3NaifDriver): # I am not sure how to accomplish this with a fixture and # a decorator. Therefore, using a context @@ -67,9 +64,6 @@ def test_ephemeris_start_time_isis(IsisLabelNaifDriver): {'SpacecraftClockCount' : 800}}}) as f: assert IsisLabelNaifDriver.ephemeris_start_time == 0.1 -def test_detector_start_line_isis(IsisLabelNaifDriver): - assert IsisLabelNaifDriver.detector_start_line == 1 - def test_detector_start_sample_isis(IsisLabelNaifDriver): with patch.dict(IsisLabelNaifDriver.label, {'IsisCube' : {'Instrument' : {'SampleFirstPixel' : 0}}}) as f: