Permalink
Browse files

Went back to using a class method (get_properties) to parse and norma…

…lize a file's header information; this way headers can be parsed without having to read the entire files
  • Loading branch information...
1 parent 03c7919 commit 584ee7337898c501646fb3ec1f47df4c222cc2d0 @khughitt khughitt committed Apr 17, 2012
Showing with 192 additions and 169 deletions.
  1. +62 −62 sunpy/map/basemap.py
  2. +14 −13 sunpy/map/sources/proba2.py
  3. +23 −19 sunpy/map/sources/rhessi.py
  4. +26 −20 sunpy/map/sources/sdo.py
  5. +37 −30 sunpy/map/sources/soho.py
  6. +30 −25 sunpy/map/sources/stereo.py
View
@@ -3,7 +3,7 @@
"""
from __future__ import absolute_import
-#pylint: disable=E1101,E1121,W0404
+#pylint: disable=E1101,E1121,W0404,W0613
__authors__ = ["Keith Hughitt, Steven Christe"]
__email__ = "keith.hughitt@nasa.gov"
@@ -15,7 +15,7 @@
from copy import copy
from sunpy.wcs import wcs as wcs
from sunpy.util.util import toggle_pylab
-from sunpy.io import read_file
+from sunpy.io import read_file, read_header
from sunpy.sun import constants
from sunpy.time import parse_time
from sunpy.map.header import MapHeader
@@ -120,7 +120,7 @@ class BaseMap(np.ndarray):
| http://www.scipy.org/Subclasses
"""
- def __new__(cls, data): # pylint: disable=W0613
+ def __new__(cls, data, header):
"""Creates a new BaseMap instance"""
if isinstance(data, np.ndarray):
obj = data.view(cls)
@@ -131,61 +131,63 @@ def __new__(cls, data): # pylint: disable=W0613
return obj
- def __init__(self, header):
+ def __init__(self, data, header):
self.fits_header = header
- # Set properties
+ # Parse header and set map attributes
+ for attr, value in list(self.get_properties(header).items()):
+ setattr(self, attr, value)
+
+ # Addition properties based on data
self.byte_scaled = self.dtype == np.uint8
- self.cmap = cm.gray # @UndefinedVariable
- self.date = parse_time(header.get('date-obs'))
- self.detector = header.get('detector')
- self.dsun = header.get('dsun_obs', constants.au)
- self.exposure_time = header.get('exptime')
- self.instrument = header.get('instrume')
- self.measurement = header.get('wavelnth')
- self.observatory = header.get('telescop')
- self.name = header.get('telescop') + " " + str(header.get('wavelnth'))
- self.rsun_meters = header.get('RSUN_REF', constants.radius)
- self.rsun_arcseconds = header.get('rsun_obs', header.get('solar_r',
- header.get('radius',
- constants.average_angular_size)))
-
- self.coordinate_system = {
- 'x': header.get('ctype1'),
- 'y': header.get('ctype2')
- }
- self.carrington_longitude = header.get('crln_obs', 0)
+ # Validate properties
+ self._validate()
- self.heliographic_latitude = header.get('hglt_obs',
+ @classmethod
+ def get_properties(cls, header):
+ """Parses a map header and determines default properties."""
+ return {
+ "cmap": cm.gray, # @UndefinedVariable
+ "date": parse_time(header.get('date-obs')),
+ "detector": header.get('detector'),
+ "dsun": header.get('dsun_obs', constants.au),
+ "exposure_time": header.get('exptime'),
+ "instrument": header.get('instrume'),
+ "measurement": header.get('wavelnth'),
+ "observatory": header.get('telescop'),
+ "name": header.get('telescop') + " " + str(header.get('wavelnth')),
+ "rsun_meters": header.get('RSUN_REF', constants.radius),
+ "rsun_arcseconds": header.get('rsun_obs', header.get('solar_r',
+ header.get('radius',
+ constants.average_angular_size))),
+ "coordinate_system": {
+ 'x': header.get('ctype1'),
+ 'y': header.get('ctype2')
+ },
+ "carrington_longitude": header.get('crln_obs', 0),
+ "heliographic_latitude": header.get('hglt_obs',
header.get('crlt_obs',
- header.get('solar_b0', 0)))
-
- self.heliographic_longitude = header.get('hgln_obs', 0)
-
- self.reference_coordinate = {
- 'x': header.get('crval1', 0),
- 'y': header.get('crval2', 0),
- }
-
- self.reference_pixel = {
- 'x': header.get('crpix1', (self.shape[0] + 1) / 2.),
- 'y': header.get('crpix2', (self.shape[1] + 1) / 2.)
+ header.get('solar_b0', 0))),
+ "heliographic_longitude": header.get('hgln_obs', 0),
+ "reference_coordinate": {
+ 'x': header.get('crval1', 0),
+ 'y': header.get('crval2', 0),
+ },
+ "reference_pixel": {
+ 'x': header.get('crpix1', (header.get('naxis1') + 1) / 2.),
+ 'y': header.get('crpix2', (header.get('naxis2') + 1) / 2.)
+ },
+ "scale": {
+ 'x': header.get('cdelt1'),
+ 'y': header.get('cdelt2'),
+ },
+ "units": {
+ 'x': header.get('cunit1', 'arcsec'),
+ 'y': header.get('cunit2', 'arcsec')
+ }
}
- self.scale = {
- 'x': header.get('cdelt1'),
- 'y': header.get('cdelt2'),
- }
-
- self.units = {
- 'x': header.get('cunit1', 'arcsec'),
- 'y': header.get('cunit2', 'arcsec')
- }
-
- # Validate properties
- self._validate()
-
def __array_finalize__(self, obj):
"""Finishes instantiation of the new map object"""
if obj is None:
@@ -626,19 +628,17 @@ def read(cls, filepath):
return cls(data, header)
raise UnrecognizedDataSouceError("File header not recognized by SunPy")
-# @classmethod
-# def detect_properties(cls, filepath):
-# """Attempts to detect the datasource type and returns meta-information
-# for that particular datasource."""
-# dict_header = read_header(filepath)
-#
-# header = MapHeader(dict_header)
-#
-# for cls in BaseMap.__subclasses__():
-# if cls.is_datasource_for(header):
-# return cls.get_properties(header)
-#
+ @classmethod
+ def detect_properties(cls, filepath):
+ """Attempts to detect the datasource type and returns meta-information
+ for that particular datasource."""
+ dict_header = read_header(filepath)
+
+ header = MapHeader(dict_header)
+ for cls in BaseMap.__subclasses__():
+ if cls.is_datasource_for(header):
+ return cls.get_properties(header)
class UnrecognizedDataSouceError(ValueError):
"""Exception to raise when an unknown datasource is encountered"""
@@ -1,13 +1,11 @@
"""PROBA2 Map subclass definitions"""
-#pylint: disable=W0221,W0222,E1101,E1121,W0613
+#pylint: disable=W0221,W0222,E1101,E1121
__author__ = "Keith Hughitt"
__email__ = "keith.hughitt@nasa.gov"
from sunpy.map.basemap import BaseMap
from sunpy.cm import cm
-from sunpy.time import parse_time
-from matplotlib import colors
class SWAPMap(BaseMap):
"""SWAP Image Map definition
@@ -17,16 +15,19 @@ class SWAPMap(BaseMap):
For a description of SWAP headers
http://proba2.oma.be/index.html/swap/swap-analysis-manual/article/data-products?menu=23
"""
- def __new__(cls, data, header):
- return BaseMap.__new__(cls, data)
-
- def __init__(self, data, header):
- BaseMap.__init__(self, header)
- self.detector = "SWAP"
- self.instrument = "SWAP"
- self.observatory = "PROBA2"
- self.name = "SWAP %s" % header.get('wavelnth')
- self.cmap = cm.get_cmap(name='sdoaia171')
+ @classmethod
+ def get_properties(cls, header):
+ """Parses SWAP image header"""
+ properties = BaseMap.get_properties(header)
+
+ properties.update({
+ "detector": "SWAP",
+ "instrument": "SWAP",
+ "observatory": "PROBA2",
+ "name": "SWAP %s" % header.get('wavelnth'),
+ "cmap": cm.get_cmap(name='sdoaia171')
+ })
+ return properties
@classmethod
def is_datasource_for(cls, header):
@@ -1,5 +1,5 @@
"""RHESSI Map subclass definitions"""
-#pylint: disable=W0221,W0222,E1121,W0613
+#pylint: disable=W0221,W0222,E1121
__author__ = "Steven Christe"
__email__ = "steven.d.christe@nasa.gov"
@@ -19,25 +19,29 @@ class RHESSIMap(BaseMap):
TODO: Currently (8/29/2011), cannot read fits files containing more than one
image (schriste)
"""
- def __new__(cls, data, header):
- return BaseMap.__new__(cls, data)
-
- def __init__(self, data, header):
- BaseMap.__init__(self, header)
+ @classmethod
+ def get_properties(cls, header):
+ """Parses RHESSI image header"""
+ properties = BaseMap.get_properties(header)
- self.date = parse_time(header.get('date_obs'))
- self.detector = header.get('telescop')
- self.instrument = header.get('telescop')
- self.measurement = [header.get('energy_l'), header.get('energy_h')]
- self.name = "RHESSI %d - %d keV" % (header.get('energy_l'),
- header.get('energy_h'))
- self.cmap = cm.get_cmap('rhessi')
- self.exposure_time = (parse_time(header.get('date_end')) -
- parse_time(header.get('date_obs'))).seconds
- self.coordinate_system = {
- 'x': 'HPLN-TAN',
- 'y': 'HPLT-TAN'
- }
+ properties.update({
+ "date": parse_time(header.get('date_obs')),
+
+ "detector": header.get('telescop'),
+ "instrument": header.get('telescop'),
+ "measurement": [header.get('energy_l'), header.get('energy_h')],
+ "observatory": "SDO",
+ "name": "RHESSI %d - %d keV" % (header.get('energy_l'),
+ header.get('energy_h')),
+ "cmap": cm.get_cmap('rhessi'),
+ "exposure_time": (parse_time(header.get('date_end')) -
+ parse_time(header.get('date_obs'))).seconds,
+ "coordinate_system": {
+ 'x': 'HPLN-TAN',
+ 'y': 'HPLT-TAN'
+ }
+ })
+ return properties
@classmethod
def is_datasource_for(cls, header):
View
@@ -1,5 +1,5 @@
"""SDO Map subclass definitions"""
-#pylint: disable=W0221,W0222,E1101,E1121,W0613
+#pylint: disable=W0221,W0222,E1101,E1121
__author__ = "Keith Hughitt"
__email__ = "keith.hughitt@nasa.gov"
@@ -16,16 +16,18 @@ class AIAMap(BaseMap):
For a description of AIA headers
http://jsoc.stanford.edu/doc/keywords/AIA/AIA02840_A_AIA-SDO_FITS_Keyword_Documents.pdf
"""
- def __new__(cls, data, header):
- return BaseMap.__new__(cls, data)
-
- def __init__(self, data, header):
- BaseMap.__init__(self, header)
+ @classmethod
+ def get_properties(cls, header):
+ """Parses AIA image header"""
+ properties = BaseMap.get_properties(header)
- self.detector = "AIA"
- self.instrument = "AIA"
- self.observatory = "SDO"
- self.cmap = cm.get_cmap('sdoaia%d' % header.get('wavelnth'))
+ properties.update({
+ "detector": "AIA",
+ "instrument": "AIA",
+ "observatory": "SDO",
+ "cmap": cm.get_cmap('sdoaia%d' % header.get('wavelnth'))
+ })
+ return properties
def norm(self):
"""Returns a Normalize object to be used with AIA data"""
@@ -48,17 +50,21 @@ def is_datasource_for(cls, header):
class HMIMap(BaseMap):
"""HMI Image Map definition"""
- def __new__(cls, data, header):
- return BaseMap.__new__(cls, data)
-
- def __init__(self, data, header):
- BaseMap.__init__(self, header)
+ @classmethod
+ def get_properties(cls, header):
+ """Parses HMI image header"""
+ properties = BaseMap.get_properties(header)
+
+ measurement = header['content'].split(" ")[0].lower()
- self.detector = "HMI"
- self.instrument = "HMI"
- self.measurement = header['content'].split(" ")[0].lower()
- self.observatory = "SDO"
- self.name = "HMI %s" % self.meas
+ properties.update({
+ "detector": "HMI",
+ "instrument": "HMI",
+ "measurement": measurement,
+ "observatory": "SDO",
+ "name": "HMI %s" % measurement
+ })
+ return properties
@classmethod
def is_datasource_for(cls, header):
Oops, something went wrong.

0 comments on commit 584ee73

Please sign in to comment.