Skip to content

Commit 974fa7b

Browse files
committed
Edit Metadata/Constrains to DataDict object
1 parent 69798e0 commit 974fa7b

2 files changed

Lines changed: 129 additions & 139 deletions

File tree

opus/metadata.py

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import six
44
from datetime import datetime as dt
55

6+
from .data import DataDict
7+
68
def read_time(time):
79
'''Read date time'''
810
try:
@@ -13,45 +15,38 @@ def read_time(time):
1315
except ValueError:
1416
raise ValueError('Time `{}` does not match either `%Y-%m-%dT%H:%M:%S.%f` nor `%Y-%jT%H:%M:%S.%f`'.format(time))
1517

16-
class Metadata(object):
18+
19+
class Metadata(DataDict):
1720
def __init__(self, json):
21+
DataDict.__init__(self)
1822
self._json = json
19-
self.set_general_constraints()
20-
self.set_other_constraints()
23+
for label, constraints in self._json.items():
24+
key = label.upper().replace(' ', '_').replace('_CONSTRAINTS', '')
25+
value = Constraints(key, constraints)
26+
self.append(key, value)
27+
28+
self.ring_obs_id = self['GENERAL']['ring_obs_id']
2129

2230
def __repr__(self):
23-
return 'OPUS API Metadata Ring observation: {}'.format(self.ring_obs_id)
31+
return 'OPUS API Metadata Ring observation: {}\n'.format(self.ring_obs_id) + \
32+
'\n'.join('\n{}'.format(values) for values in self.values())
2433

25-
@property
26-
def general_constraints(self):
27-
return self._json['General Constraints']
2834

29-
def set_general_constraints(self):
30-
'''Save the General Constraints parameter as attributs'''
31-
for key, value in self.general_constraints.items():
35+
class Constraints(DataDict):
36+
def __init__(self, name, constraints={}):
37+
DataDict.__init__(self)
38+
self.name = name
39+
for key, value in constraints.items():
3240
if key == 'is_image':
3341
value = (value == 1)
3442

3543
if 'time' in key and isinstance(value, six.text_type):
3644
value = read_time(value)
3745

38-
if value is not None and value != 'N/A':
39-
setattr(self, key, value)
40-
41-
def set_other_constraints(self):
42-
'''Save other Constraints as sub-attributes'''
43-
for label, constraints in self._json.items():
44-
if label != 'General Constraints':
45-
key = label.lower().replace(' ', '_').replace('_constraints','')
46-
value = Constraints(constraints)
47-
setattr(self, key, value)
48-
49-
50-
class Constraints(object):
51-
def __init__(self, constraints={}):
52-
for key, value in constraints.items():
53-
if value is not None and value != -999:
54-
setattr(self, key, value)
46+
if value is not None and value != 'N/A' and value != -999:
47+
self.append(key, value)
5548

5649
def __repr__(self):
57-
return 'Metadata constraints'
50+
return '=> {} constraints\n' .format(self.name) + \
51+
'\n'.join(' - {}: {}'.format(key, value)
52+
for key, value in self.items())

tests/test_metadata.py

Lines changed: 106 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -20,140 +20,135 @@ def test_read_time():
2020
assert read_time('2004-092T22:42:47.095') == dt(2004, 4, 1, 22, 42, 47, 95000)
2121
assert read_time('2004-04-01T22:42:47.095') == dt(2004, 4, 1, 22, 42, 47, 95000)
2222

23+
def test_read_time_err():
24+
with pytest.raises(ValueError):
25+
read_time('abc')
2326

24-
def test_metadata_repr(metadata):
25-
assert repr(metadata) == 'OPUS API Metadata Ring observation: S_IMG_CO_ISS_1459551972_N'
26-
27-
28-
def test_constraints_repr():
29-
assert repr(Constraints()) == 'Metadata constraints'
3027

28+
def test_metadata_repr(metadata):
29+
r = repr(metadata)
30+
assert 'OPUS API Metadata Ring observation: S_IMG_CO_ISS_1459551972_N' in r
31+
assert '=> GENERAL constraints' in r
32+
assert 'time1: 2004-04-01 22:42:47.095000' in r
3133

3234
def test_metadata_general_constraints(metadata):
33-
assert metadata.is_image == True
34-
assert metadata.planet_id == 'SAT'
35-
assert metadata.target_name == 'SKY'
36-
assert metadata.mission_id == 'CO'
37-
assert metadata.inst_host_id == 'CO'
38-
assert metadata.instrument_id == 'COISS'
39-
assert metadata.time_sec1 == 134174599.095
40-
assert metadata.time_sec2 == 134174600.095
41-
assert metadata.time1 == dt(2004, 4, 1, 22, 42, 47, 95000)
42-
assert metadata.time2 == dt(2004, 4, 1, 22, 42, 48, 95000)
43-
assert metadata.target_class == 'SKY'
44-
assert metadata.quantity == 'REFLECT'
45-
assert metadata.type_id == 'IMG'
46-
assert metadata.ring_obs_id == 'S_IMG_CO_ISS_1459551972_N'
47-
assert metadata.right_asc1 == 66.998507
48-
assert metadata.right_asc2 == 67.400994
49-
assert metadata.declination1 == 15.826958
50-
assert metadata.declination2 == 16.213811
51-
assert metadata.observation_duration == 1.0
52-
assert metadata.volume_id_list == 'COISS_2001'
53-
assert metadata.primary_file_spec == 'COISS_2001/data/1459551663_1459568594/N1459551972_1.IMG'
35+
assert metadata['GENERAL']['is_image'] == True
36+
assert metadata['GENERAL']['planet_id'] == 'SAT'
37+
assert metadata['GENERAL']['target_name'] == 'SKY'
38+
assert metadata['GENERAL']['mission_id'] == 'CO'
39+
assert metadata['GENERAL']['inst_host_id'] == 'CO'
40+
assert metadata['GENERAL']['instrument_id'] == 'COISS'
41+
assert metadata['GENERAL']['time_sec1'] == 134174599.095
42+
assert metadata['GENERAL']['time_sec2'] == 134174600.095
43+
assert metadata['GENERAL']['time1'] == dt(2004, 4, 1, 22, 42, 47, 95000)
44+
assert metadata['GENERAL']['time2'] == dt(2004, 4, 1, 22, 42, 48, 95000)
45+
assert metadata['GENERAL']['target_class'] == 'SKY'
46+
assert metadata['GENERAL']['quantity'] == 'REFLECT'
47+
assert metadata['GENERAL']['type_id'] == 'IMG'
48+
assert metadata['GENERAL']['ring_obs_id'] == 'S_IMG_CO_ISS_1459551972_N'
49+
assert metadata['GENERAL']['right_asc1'] == 66.998507
50+
assert metadata['GENERAL']['right_asc2'] == 67.400994
51+
assert metadata['GENERAL']['declination1'] == 15.826958
52+
assert metadata['GENERAL']['declination2'] == 16.213811
53+
assert metadata['GENERAL']['observation_duration'] == 1.0
54+
assert metadata['GENERAL']['volume_id_list'] == 'COISS_2001'
55+
assert metadata['GENERAL']['primary_file_spec'] == 'COISS_2001/data/1459551663_1459568594/N1459551972_1.IMG'
5456

5557

5658
def test_constraints_saturn_surface_geometry(metadata):
57-
constraints = metadata.saturn_surface_geometry
58-
assert constraints.sub_solar_planetocentric_latitude == -25.081
59-
assert constraints.sub_observer_planetocentric_latitude == -16.319
60-
assert constraints.sub_solar_planetographic_latitude == -29.908
61-
assert constraints.sub_observer_planetographic_latitude == -19.79
62-
assert constraints.sub_solar_IAU_longitude == 35.936
63-
assert constraints.sub_observer_IAU_longitude == 106.634
64-
assert constraints.center_resolution == 268.851
65-
assert constraints.center_phase_angle == 66.02
66-
assert constraints.center_distance == 45067643.997
59+
constraints = metadata['SATURN_SURFACE_GEOMETRY']
60+
assert constraints['sub_solar_planetocentric_latitude'] == -25.081
61+
assert constraints['sub_observer_planetocentric_latitude'] == -16.319
62+
assert constraints['sub_solar_planetographic_latitude'] == -29.908
63+
assert constraints['sub_observer_planetographic_latitude'] == -19.79
64+
assert constraints['sub_solar_IAU_longitude'] == 35.936
65+
assert constraints['sub_observer_IAU_longitude'] == 106.634
66+
assert constraints['center_resolution'] == 268.851
67+
assert constraints['center_phase_angle'] == 66.02
68+
assert constraints['center_distance'] == 45067643.997
6769

6870

6971
def test_constraints_ring_geometry(metadata):
70-
constraints = metadata.ring_geometry
71-
assert constraints.ring_center_distance == 45067643.997
72-
assert constraints.sub_solar_ring_long == 286.798
73-
assert constraints.sub_observer_ring_long == 216.1
74-
assert constraints.ring_center_phase == 66.02
75-
assert constraints.ring_center_incidence == 64.919
76-
assert constraints.ring_center_emission == 73.682
77-
assert constraints.ring_center_north_based_incidence == 115.081
78-
assert constraints.ring_center_north_based_emission == 106.318
79-
assert constraints.solar_ring_opening_angle == -25.081
80-
assert constraints.observer_ring_opening_angle == -16.319
72+
constraints = metadata['RING_GEOMETRY']
73+
assert constraints['ring_center_distance'] == 45067643.997
74+
assert constraints['sub_solar_ring_long'] == 286.798
75+
assert constraints['sub_observer_ring_long'] == 216.1
76+
assert constraints['ring_center_phase'] == 66.02
77+
assert constraints['ring_center_incidence'] == 64.919
78+
assert constraints['ring_center_emission'] == 73.682
79+
assert constraints['ring_center_north_based_incidence'] == 115.081
80+
assert constraints['ring_center_north_based_emission'] == 106.318
81+
assert constraints['solar_ring_opening_angle'] == -25.081
82+
assert constraints['observer_ring_opening_angle'] == -16.319
8183

8284

8385
def test_constraints_wavelength(metadata):
84-
constraints = metadata.wavelength
85-
assert constraints.wavelength1 == 0.451
86-
assert constraints.wavelength2 == 0.451
87-
assert constraints.spec_flag == 'N'
88-
assert constraints.polarization_type == 'NONE'
86+
constraints = metadata['WAVELENGTH']
87+
assert constraints['wavelength1'] == 0.451
88+
assert constraints['wavelength2'] == 0.451
89+
assert constraints['spec_flag'] == 'N'
90+
assert constraints['polarization_type'] == 'NONE'
8991

9092

9193
def test_constraints_image(metadata):
92-
constraints = metadata.image
93-
assert constraints.duration == 1.0
94-
assert constraints.image_type_id == 'FRAM'
95-
assert constraints.greater_pixel_size == 1024.0
96-
assert constraints.lesser_pixel_size == 1024.0
97-
assert constraints.levels == '4096'
94+
constraints = metadata['IMAGE']
95+
assert constraints['duration'] == 1.0
96+
assert constraints['image_type_id'] == 'FRAM'
97+
assert constraints['greater_pixel_size'] == 1024.0
98+
assert constraints['lesser_pixel_size'] == 1024.0
99+
assert constraints['levels'] == '4096'
98100

99101
def test_constraints_cassini_mission(metadata):
100-
constraints = metadata.cassini_mission
101-
assert constraints.cassini_target_name == 'instrument calibration'
102-
assert constraints.rev_no == 'C44'
103-
assert constraints.obs_name == 'ISS_C44IC_CALSTAR2001_PRIME'
104-
assert constraints.activity_name == 'CALSTAR2'
105-
assert constraints.spacecraft_clock_count1 == 1459551971.131
106-
assert constraints.spacecraft_clock_count2 == 1459551972.131
107-
assert constraints.prime == 'Y'
108-
assert constraints.prime_inst_id == 'COISS'
109-
assert constraints.ert_sec1 == 134277636.336
110-
assert constraints.ert_sec2 == 134277720.397
102+
constraints = metadata['CASSINI_MISSION']
103+
assert constraints['cassini_target_name'] == 'instrument calibration'
104+
assert constraints['rev_no'] == 'C44'
105+
assert constraints['obs_name'] == 'ISS_C44IC_CALSTAR2001_PRIME'
106+
assert constraints['activity_name'] == 'CALSTAR2'
107+
assert constraints['spacecraft_clock_count1'] == 1459551971.131
108+
assert constraints['spacecraft_clock_count2'] == 1459551972.131
109+
assert constraints['prime'] == 'Y'
110+
assert constraints['prime_inst_id'] == 'COISS'
111+
assert constraints['ert_sec1'] == 134277636.336
112+
assert constraints['ert_sec2'] == 134277720.397
111113

112114

113115
def test_constraints_cassini_iss(metadata):
114-
constraints = metadata.cassini_iss
115-
assert constraints.FILTER_NAME == 'BL1 ,CL2'
116-
assert constraints.INST_CMPRS_RATE_expected_average == 2.9
117-
assert constraints.INST_CMPRS_RATE_actual_average == 2.135712
118-
assert constraints.VALID_MAXIMUM_minimum_full_well_saturation_level == 4095
119-
assert constraints.VALID_MAXIMUM_maximum_DN_saturation_level == 4095
120-
assert constraints.ANTIBLOOMING_STATE_FLAG == 'ON'
121-
assert constraints.CALIBRATION_LAMP_STATE_FLAG == 'N/A'
122-
assert constraints.DELAYED_READOUT_FLAG == 'NO'
123-
assert constraints.FILTER_TEMPERATURE == -0.468354
124-
assert constraints.LIGHT_FLOOD_STATE_FLAG == 'ON'
125-
assert constraints.MISSING_PACKET_FLAG == 'NO'
126-
assert constraints.camera == 'N'
127-
assert constraints.FILTER == 'BL1'
128-
assert constraints.IMAGE_OBSERVATION_TYPE == 'CALIBRATION'
129-
assert constraints.SHUTTER_MODE_ID == 'NACONLY'
130-
assert constraints.DATA_CONVERSION_TYPE == '12BIT'
131-
assert constraints.GAIN_MODE_ID == '29 ELECTRONS PER DN'
132-
assert constraints.INST_CMPRS_TYPE == 'LOSSLESS'
133-
assert constraints.SHUTTER_STATE_ID == 'ENABLED'
134-
assert constraints.INST_CMPRS_RATIO == 7.491648
135-
assert constraints.TELEMETRY_FORMAT_ID == 'S_N_ER_3'
136-
assert constraints.MISSING_LINES == 0
137-
assert constraints.OPTICS_TEMPERATURE_front == 0.712693
138-
assert constraints.INST_CMPRS_PARAM_QF == -2147483648
139-
assert constraints.INST_CMPRS_PARAM_TB == -2147483648
140-
assert constraints.INST_CMPRS_PARAM_GOB == -2147483648
141-
assert constraints.EXPECTED_MAXIMUM_full_well_DN == 57.5369
142-
assert constraints.OPTICS_TEMPERATURE_rear == 1.905708
143-
assert constraints.EXPECTED_MAXIMUM_max_DN == 63.450699
144-
assert constraints.INST_CMPRS_PARAM_MALGO == -2147483648
145-
146-
147-
def test_read_time_err():
148-
with pytest.raises(ValueError):
149-
read_time('abc')
116+
constraints = metadata['CASSINI_ISS']
117+
assert constraints['FILTER_NAME'] == 'BL1 ,CL2'
118+
assert constraints['INST_CMPRS_RATE_expected_average'] == 2.9
119+
assert constraints['INST_CMPRS_RATE_actual_average'] == 2.135712
120+
assert constraints['VALID_MAXIMUM_minimum_full_well_saturation_level'] == 4095
121+
assert constraints['VALID_MAXIMUM_maximum_DN_saturation_level'] == 4095
122+
assert constraints['ANTIBLOOMING_STATE_FLAG'] == 'ON'
123+
assert constraints['DELAYED_READOUT_FLAG'] == 'NO'
124+
assert constraints['FILTER_TEMPERATURE'] == -0.468354
125+
assert constraints['LIGHT_FLOOD_STATE_FLAG'] == 'ON'
126+
assert constraints['MISSING_PACKET_FLAG'] == 'NO'
127+
assert constraints['camera'] == 'N'
128+
assert constraints['FILTER'] == 'BL1'
129+
assert constraints['IMAGE_OBSERVATION_TYPE'] == 'CALIBRATION'
130+
assert constraints['SHUTTER_MODE_ID'] == 'NACONLY'
131+
assert constraints['DATA_CONVERSION_TYPE'] == '12BIT'
132+
assert constraints['GAIN_MODE_ID'] == '29 ELECTRONS PER DN'
133+
assert constraints['INST_CMPRS_TYPE'] == 'LOSSLESS'
134+
assert constraints['SHUTTER_STATE_ID'] == 'ENABLED'
135+
assert constraints['INST_CMPRS_RATIO'] == 7.491648
136+
assert constraints['TELEMETRY_FORMAT_ID'] == 'S_N_ER_3'
137+
assert constraints['MISSING_LINES'] == 0
138+
assert constraints['OPTICS_TEMPERATURE_front'] == 0.712693
139+
assert constraints['INST_CMPRS_PARAM_QF'] == -2147483648
140+
assert constraints['INST_CMPRS_PARAM_TB'] == -2147483648
141+
assert constraints['INST_CMPRS_PARAM_GOB'] == -2147483648
142+
assert constraints['EXPECTED_MAXIMUM_full_well_DN'] == 57.5369
143+
assert constraints['OPTICS_TEMPERATURE_rear'] == 1.905708
144+
assert constraints['EXPECTED_MAXIMUM_max_DN'] == 63.450699
145+
assert constraints['INST_CMPRS_PARAM_MALGO'] == -2147483648
150146

151147

152148
def test_metadata_err(metadata):
153-
with pytest.raises(AttributeError):
154-
metadata.note
155-
149+
with pytest.raises(KeyError):
150+
metadata['FOO']
156151

157152
def test_constraints_err(metadata):
158-
with pytest.raises(AttributeError):
159-
metadata.ring_geometry_constraints.observer_ring_elevation2
153+
with pytest.raises(KeyError):
154+
metadata['RING_GEOMETRY']['observer_ring_elevation2']

0 commit comments

Comments
 (0)