diff --git a/glue_solar/__init__.py b/glue_solar/__init__.py index 7998d0e..23088bd 100644 --- a/glue_solar/__init__.py +++ b/glue_solar/__init__.py @@ -13,5 +13,6 @@ def setup(): ImageViewer.tools.append('solar:pixel_extraction') + ImageViewer.tools.append('timestamp_button') for name, ctable in sorted(cmlist.items()): colormaps.add(ctable.name, ctable) diff --git a/glue_solar/instruments/__init__.py b/glue_solar/instruments/__init__.py index 7deae2d..01a556e 100644 --- a/glue_solar/instruments/__init__.py +++ b/glue_solar/instruments/__init__.py @@ -1 +1,2 @@ from .iris import * +from .timestamp_button import * diff --git a/glue_solar/instruments/iris.py b/glue_solar/instruments/iris.py new file mode 100644 index 0000000..49dcf47 --- /dev/null +++ b/glue_solar/instruments/iris.py @@ -0,0 +1,30 @@ +""" +A reader for IRIS data. +""" +from glue.config import qglue_parser, data_factory +from glue.core import Data, Component +from glue.core.coordinates import WCSCoordinates +from irispy.spectrograph import (IRISSpectrograph, + read_iris_spectrograph_level2_fits) + + +@qglue_parser(IRISSpectrograph) +def _parse_iris_raster(data, label): + result = [] + for window, window_data in data.data.items(): + for i, scan_data in enumerate(window_data): + w_data = Data(label=f"{window.replace(' ', '_')}-scan-{i}") + w_data.coords = WCSCoordinates(wcs=scan_data.wcs) + w_data.add_component(Component(scan_data.data), + f"{window}-scan-{i}") + w_data.meta = scan_data.meta + result.append(w_data) + return result + +def is_fits(filename, **kwargs): + return filename.endswith('.fits') + +@data_factory('IRIS Spectrograph', is_fits) +def read_iris_raster(raster_file): + raster_data = _parse_iris_raster(read_iris_spectrograph_level2_fits(raster_file), 'iris') + return raster_data diff --git a/glue_solar/instruments/timestamp_button.py b/glue_solar/instruments/timestamp_button.py new file mode 100644 index 0000000..05542c0 --- /dev/null +++ b/glue_solar/instruments/timestamp_button.py @@ -0,0 +1,48 @@ +from glue.config import viewer_tool +from glue.viewers.common.tool import CheckableTool +import datetime + +@viewer_tool +class TimestampButton(CheckableTool): + + icon = 'app_icon' + tool_id = 'timestamp_button' + action_text = '' + tool_tip = 'Activate Timestamp' + status_tip = 'Timestamp Active' + shortcut = '' + + def __init__(self, viewer): + super(TimestampButton, self).__init__(viewer) + self.activate() + + def activate(self): + self.viewer.state.add_callback('slices', self.update_label) + + def deactivate(self): + pass + + def update_label(self, slices): + data = self.viewer.state.reference_data + meta = data.meta + base_time = meta.get("DATE-OBS", meta.get("DATE_OBS", None)) + + world = data.coords.pixel2world(*slices[::-1]) + + if isinstance(base_time, str): + timestamp = datetime.datetime.strptime(base_time, '%Y-%m-%dT%H:%M:%S.%f') + elif isinstance(base_time, datetime.datetime): + timestamp = base_time + else: + return + + if 'CUNIT3' in meta.keys(): + if data.meta['CUNIT3'] == 'seconds': + timestamp = datetime.timedelta(0, float(world[2])) + timestamp + + elif ('STARTOBS' in meta and 'ENDOBS' in meta): + date_obs = meta['STARTOBS'] + obs_delt = meta['ENDOBS'] - date_obs + timestamp = timestamp + obs_delt*float(world[2]) + + self.viewer.set_status(timestamp.strftime('%Y-%m-%dT%H:%M:%S.%f'))