From 6169438d8e6f7e1d638edf4c3c48714e7bafc225 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Sat, 29 Sep 2018 22:08:25 +1000 Subject: [PATCH 1/3] Removing blank line --- pocs/utils/db/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pocs/utils/db/__init__.py b/pocs/utils/db/__init__.py index 8b1378917..e69de29bb 100644 --- a/pocs/utils/db/__init__.py +++ b/pocs/utils/db/__init__.py @@ -1 +0,0 @@ - From a82ebb84a7330cd2400e7ed4371e58fa583d6c31 Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Thu, 11 Oct 2018 13:56:18 +1100 Subject: [PATCH 2/3] Add tests of parameters rather than config entries --- pocs/tests/test_observatory.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pocs/tests/test_observatory.py b/pocs/tests/test_observatory.py index 2d1944114..489e8b481 100644 --- a/pocs/tests/test_observatory.py +++ b/pocs/tests/test_observatory.py @@ -267,6 +267,15 @@ def test_cleanup_missing_config_keys(observatory): del observatory.config['pan_id'] observatory.cleanup_observations() + observatory.get_observation() + + # Now use parameters + observatory.cleanup_observations( + upload_images=False, + make_timelapse=False, + keep_jpgs=True + ) + def test_autofocus_disconnected(observatory): # 'Disconnect' simulated cameras which will cause From 28b07cd3205ceddae246564de277438dbf63e9ec Mon Sep 17 00:00:00 2001 From: Wilfred Gee Date: Mon, 12 Oct 2020 13:11:17 -1000 Subject: [PATCH 3/3] * Allow for arbitrary FITS headers. --- CHANGELOG.rst | 3 ++- src/panoptes/pocs/camera/camera.py | 22 ++++++++++++++++------ src/panoptes/pocs/tests/test_camera.py | 22 ++++++++++++++++++++-- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 99b6107f1..54eb1322d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,10 +8,11 @@ Changelog Added ~~~~~ +* Allow for arbitrary FITS headers. Keywords will be added as `HIERARCH` cards if they don't conform to FITS standard (using ``astropy`` machinery). * A "developer" version of the ``panoptes-pocs`` docker image is cloudbuilt automatically on merge with ``develop``. (@wtgee #1010) * Better error checking in cameras, including ability to store error. (@AnthonyHorton #1007) * Added ``error.InvalidConfig`` exception. (@wtgee #1007) -* Config options to control camera processing options and allow for `defaults` in the config that applies to all cameras: (@wtgee #1007) +* Config options to control camera processing options and allow for `defaults` in the config that applies to all cameras: (@wtgee #1007 & #1009) * ``cameras.defaults.compress_fits`` if FITS files should be fpacked. Default True. * ``cameras.defaults.record_observations`` if observation metadata should be recorded. Default True. diff --git a/src/panoptes/pocs/camera/camera.py b/src/panoptes/pocs/camera/camera.py index a1108f3b2..95c8ee018 100644 --- a/src/panoptes/pocs/camera/camera.py +++ b/src/panoptes/pocs/camera/camera.py @@ -965,13 +965,23 @@ def _process_fits(self, file_path, metadata): self.logger.debug(f"Updating FITS headers: {file_path} with {metadata=}") with fits.open(file_path, 'update') as f: hdu = f[0] - for metadata_key, field_info in fields.items(): - fits_key = field_info['keyword'] - fits_comment = field_info.get('comment', '') - # Get the value from either the metadata, the default, or use blank string. - fits_value = metadata.get(metadata_key, field_info.get('default', '')) + for metadata_key, metadata_value in metadata.items(): + try: + field_info = fields[metadata_key] + # for metadata_key, field_info in fields.items(): + fits_key = field_info['keyword'] + fits_comment = field_info.get('comment', '') + # Get the value from either the metadata, the default, or use blank string. + fits_value = metadata.get(metadata_key, field_info.get('default', '')) + + self.logger.trace(f'Setting {fits_key=} = {fits_value=} {fits_comment=}') + except KeyError: + self.logger.trace(f'No mapping found for metadata {metadata_key}' + f', will attempt to add as-is.') + fits_key = metadata_key + fits_comment = '' + fits_value = metadata_value - self.logger.trace(f'Setting {fits_key=} = {fits_value=} {fits_comment=}') hdu.header.set(fits_key, fits_value, fits_comment) self.logger.debug(f"Finished FITS headers: {file_path}") diff --git a/src/panoptes/pocs/tests/test_camera.py b/src/panoptes/pocs/tests/test_camera.py index a2aceb70c..60b9f7128 100644 --- a/src/panoptes/pocs/tests/test_camera.py +++ b/src/panoptes/pocs/tests/test_camera.py @@ -494,20 +494,38 @@ def test_observation(camera, images_dir): assert len(glob.glob(observation_pattern)) == 1 -def test_observation_headers_and_blocking(camera, images_dir): +def test_observation_blocking(camera, images_dir): """ Tests functionality of take_observation() """ field = Field('Test Observation', '20h00m43.7135s +22d42m39.0645s') observation = Observation(field, exptime=1.5 * u.second) observation.seq_time = '19991231T235559' - camera.take_observation(observation, headers={'field_name': 'TESTVALUE'}, blocking=True) + camera.take_observation(observation, blocking=True) + observation_pattern = os.path.join(images_dir, 'TestObservation', + camera.uid, observation.seq_time, '*.fits*') + image_files = glob.glob(observation_pattern) + assert len(image_files) == 1 + + +def test_observation_headers(camera, images_dir): + """ + Tests functionality of take_observation() + """ + field = Field('Test Observation', '20h00m43.7135s +22d42m39.0645s') + observation = Observation(field, exptime=1.5 * u.second) + observation.seq_time = '19991231T235559' + + # Test assigned and arbitrary headers. + headers = {'field_name': 'TESTVALUE', 'non-conforming-header': 'says-hi'} + camera.take_observation(observation, headers=headers, blocking=True) observation_pattern = os.path.join(images_dir, 'TestObservation', camera.uid, observation.seq_time, '*.fits*') image_files = glob.glob(observation_pattern) assert len(image_files) == 1 headers = fits_utils.getheader(image_files[0]) assert fits_utils.getval(image_files[0], 'FIELD') == 'TESTVALUE' + assert fits_utils.getval(image_files[0], 'non-conforming-header') == 'says-hi' def test_observation_nofilter(camera, images_dir):