def load(filepath): """ :param filepath: fits image path :return: an Image """ data = pyfits.getdata(filepath, hdu=0) primary = Header(pyfits.getheader(filepath, 0)) headers = [primary] extcount = int(primary.get("NEXTEND", 0)) for idx in range(1, extcount): ext = Header(pyfits.getheader(filepath, idx)) headers.append(ext) return Image(array(data), headers)
def test_post_sanitize_header_pc(): test_subject = FITSHelper(io.BytesIO(), io.BytesIO()) data = np.arange(10000).reshape(100, 100) header = Header() wcs = WCS(fix=False) wcs.wcs.pc = [[0.9, 0.8], [0.7, 0.6]] header.set('REMAIN1', 'VALUE1') header.set('DQ1', 'dqvalue1') header.set('NAXIS', 2) header.set('NAXIS1', 88) header.set('NAXIS2', 212) header.set('CRPIX1', 77.0) header.set('WCSAXES', 2) header.set('CTYPE1', 'ctype1value') assert header.get('PC1_1') is None, 'Should not contain PC1_1' assert header.get('PC2_1') is None, 'Should not contain PC2_1' assert header.get('PC1_2') is None, 'Should not contain PC1_2' assert header.get('PC2_2') is None, 'Should not contain PC2_2' result = CutoutResult(data, wcs=wcs) assert header.index('WCSAXES') > header.index('CRPIX1'), \ 'Start with bad indexes...' test_subject._post_sanitize_header(header, result) assert header.get('PC1_1') == 0.9, 'Wrong PC1_1 value.' assert header.get('PC2_1') == 0.7, 'Wrong PC2_1 value.' assert header.get('PC1_2') == 0.8, 'Wrong PC1_2 value.' assert header.get('PC2_2') == 0.6, 'Wrong PC2_2 value.' assert 'VALUE1' == header.get('REMAIN1'), 'REMAIN1 should still be there.'
def __new__(cls, value, unit=None, dtype=None, copy=True, wcs=None, meta=None, mask=None, header=None, spectral_unit=None, fill_value=np.nan, wcs_tolerance=0.0): #log.debug("Creating a OneDSpectrum with __new__") if np.asarray(value).ndim != 1: raise ValueError("value should be a 1-d array") if wcs is not None and wcs.wcs.naxis != 1: raise ValueError("wcs should have two dimension") self = u.Quantity.__new__(cls, value, unit=unit, dtype=dtype, copy=copy).view(cls) self._wcs = wcs self._meta = {} if meta is None else meta self._wcs_tolerance = wcs_tolerance self._initial_set_mask(mask) self._fill_value = fill_value if header is not None: self._header = header else: self._header = Header() self._spectral_unit = spectral_unit if spectral_unit is None: if 'CUNIT1' in self._header: self._spectral_unit = u.Unit(self._header['CUNIT1']) elif self._wcs is not None: self._spectral_unit = u.Unit(self._wcs.wcs.cunit[0]) return self
def get_lightcurve_dataset_from_stingray_Lightcurve(lcurve, header=None, header_comments=None, hduname='RATE', column=CONFIG.TIME_COLUMN): from astropy.io.fits import Header dataset = get_hdu_type_dataset("LIGHTCURVE", [column, hduname], hduname) hdu_table = dataset.tables[hduname] if header is None: if not hasattr(lcurve, 'header'): logging.warn("Light curve has no header") lcurve.header = Header() header = Header.fromstring(lcurve.header) header = dict() for header_column in header: header[header_column] = str(header[header_column]) header_comments[header_column] = \ str(header.comments[header_column]) hdu_table.set_header_info(header, header_comments) hdu_table.columns[column].add_values(lcurve.time) hdu_table.columns[hduname].add_values(lcurve.counts, lcurve.counts_err) dataset.tables["GTI"] = \ DsHelper.get_gti_table_from_stingray_gti(lcurve.gti) return dataset
def from_properties(cls, size, center_pixel, center_sky, pixelscale): """ This fucntion ... :param size: :param center_pixel: :param center_sky: :param pixelscale: :return: """ # TODO: doesn't work # see try below # Construct header header = Header() header["CRPIX1"] = center_pixel.x header["CRVAL1"] = center_sky.ra.to("deg").value header["CDELT1"] = pixelscale.x.to("deg").value header["CRPIX2"] = center_pixel.y header["CRVAL2"] = center_sky.dec.to("deg").value header["CDELT2"] = pixelscale.y.to("deg").value header["NAXIS1"] = size.x header["NAXIS2"] = size.y header["RADESYS"] = "ICRS" header["CTYPE1"] = "RA--TAN" header["CTYPE2"] = "DEC--TAN" # Create and return return cls(header=header)
def __new__(cls, value, unit=None, dtype=None, copy=True, wcs=None, meta=None, mask=None, header=None): if np.asarray(value).ndim != 2: raise ValueError("value should be a 2-d array") if wcs is not None and wcs.wcs.naxis != 2: raise ValueError("wcs should have two dimension") self = u.Quantity.__new__(cls, value, unit=unit, dtype=dtype, copy=copy).view(cls) self._wcs = wcs self._meta = {} if meta is None else meta self._mask = mask if header is not None: self._header = header else: self._header = Header() return self
def __new__(cls, value, unit=None, dtype=None, copy=True, wcs=None, meta=None, mask=None, header=None, spectral_unit=None, fill_value=np.nan, beams=None, wcs_tolerance=0.0): #log.debug("Creating a OneDSpectrum with __new__") if np.asarray(value).ndim != 1: raise ValueError("value should be a 1-d array") if wcs is not None and wcs.wcs.naxis != 1: raise ValueError("wcs should have two dimension") self = u.Quantity.__new__(cls, value, unit=unit, dtype=dtype, copy=copy).view(cls) self._wcs = wcs self._meta = {} if meta is None else meta self._wcs_tolerance = wcs_tolerance if mask is None: mask = BooleanArrayMask(np.ones_like(self.value, dtype=bool), self._wcs, shape=self.value.shape) elif isinstance(mask, np.ndarray): if mask.shape != self.value.shape: raise ValueError("Mask shape must match the spectrum shape.") mask = BooleanArrayMask(mask, self._wcs, shape=self.value.shape) elif isinstance(mask, MaskBase): pass else: raise TypeError("mask of type {} is not a supported mask " "type.".format(type(mask))) # Validate the mask before setting mask._validate_wcs(new_data=self.value, new_wcs=self._wcs, wcs_tolerance=self._wcs_tolerance) self._mask = mask self._fill_value = fill_value if header is not None: self._header = header else: self._header = Header() self._spectral_unit = spectral_unit if spectral_unit is None: if 'CUNIT1' in self._header: self._spectral_unit = u.Unit(self._header['CUNIT1']) elif self._wcs is not None: self._spectral_unit = u.Unit(self._wcs.wcs.cunit[0]) if beams is not None: self.beams = beams # HACK: OneDSpectrum should eventually become not-a-quantity # Maybe it should be a u.Quantity(np.ma)? self._data = self.value return self
def __init__(self, name=None, value=None, comment=None, synonyms=None): self._hdr = Header() self.name = name self.value = value self.comment = comment if synonyms is None: self.synonyms = [] else: self.synonyms = synonyms
def test_wl_to_index(ws, result): "wavelength to index" # header h_dict = {"CRVAL1": 3500, 'CDELT1': 2} h = Header() for k, v in h_dict.items(): h.set(k, v) out = ft.wavelength_to_index(h, ws) assert out == result
def build_position(hdf5_wcs, window, telescope): h = Header() # logging.error(hdf5_wcs) # logging.error(window) h['NAXIS1'] = window['X1'].data[telescope] - window['X0'].data[ telescope] + 1 h['NAXIS2'] = window['Y1'].data[telescope] - window['Y0'].data[ telescope] + 1 h['CRVAL1'] = hdf5_wcs['CRVAL1'].data[telescope] h['CRVAL2'] = hdf5_wcs['CRVAL2'].data[telescope] h['CRPIX1'] = hdf5_wcs['CRPIX1'].data[telescope] h['CRPIX2'] = hdf5_wcs['CRPIX2'].data[telescope] # h['CDELT1'] = 4.0 / 3600.0 # h['CDELT2'] = 4.0 / 3600.0 # # JJK - use only one of CD* or CDELT* - they are either conflicting or # redundant # h['CD1_1'] = hdf5_wcs['CD1_1'].data[telescope] h['CD1_2'] = hdf5_wcs['CD1_2'].data[telescope] h['CD2_1'] = hdf5_wcs['CD2_1'].data[telescope] h['CD2_2'] = hdf5_wcs['CD2_2'].data[telescope] w = wcs.WCS() bounds = CoordPolygon2D() result = w.calc_footprint(header=h) for ii in result: vertex = ValueCoord2D(ii[0], ii[1]) bounds.vertices.append(vertex) # ref_coord_x = RefCoord(mc.to_float(pix1), ra) # ref_coord_y = RefCoord(mc.to_float(pix2), dec) # coord = Coord2D(ref_coord_x, ref_coord_y) # dimension = Dimension2D(2, 2) # pixscale = 4.0 / 3600.0 => 4", per JJK # VLASS takes the cd?? approach shown here # function = CoordFunction2D(dimension=dimension, # ref_coord=coord, # cd11=4.0/3600.0, # cd12=0.0, # cd21=0.0, # cd22=4.0/3600.0) axis = CoordAxis2D(axis1=Axis(ctype='RA---TAN', cunit='deg'), axis2=Axis(ctype='DEC--TAN', cunit='deg'), error1=None, error2=None, range=None, bounds=bounds, function=None) return SpatialWCS(axis=axis, coordsys='FK5', equinox=2000.0, resolution=None)
def fake_header(extver, version, timesys, telescop): return Header({ "SIMPLE": "T", "BITPIX": 8, "NAXIS": 0, "EXTVER": extver, "VERSION": version, 'TIMESYS': f"{timesys}", "TELESCOP": f"{telescop}" })
def fake_header(extver, version, timesys, telescop): return Header({ "SIMPLE": "T", "BITPIX": 8, "NAXIS": 0, "EXTVER": extver, "VERSION": version, 'TIMESYS': "{}".format(timesys), "TELESCOP": "{}".format(telescop) })
def __new__(cls, value, unit=None, dtype=None, copy=True, wcs=None, meta=None, mask=None, header=None, beam=None, fill_value=np.nan, read_beam=False, wcs_tolerance=0.0): if np.asarray(value).ndim != 2: raise ValueError("value should be a 2-d array") if wcs is not None and wcs.wcs.naxis != 2: raise ValueError("wcs should have two dimension") self = u.Quantity.__new__(cls, value, unit=unit, dtype=dtype, copy=copy).view(cls) self._wcs = wcs self._meta = {} if meta is None else meta self._wcs_tolerance = wcs_tolerance self._initial_set_mask(mask) self._fill_value = fill_value if header is not None: self._header = header else: self._header = Header() if beam is None: if "beam" in self.meta: beam = self.meta['beam'] elif read_beam: beam = cube_utils.try_load_beam(header) if beam is None: warnings.warn("Cannot load beam from header.", BeamWarning) if beam is not None: self.beam = beam self.meta['beam'] = beam # TODO: Enable header updating when non-celestial slices are # properly handled in the WCS object. # self._header.update(beam.to_header_keywords()) self._cache = {} return self
def get_eventlist_dataset_from_stingray_Eventlist(evlist, header=None, header_comments=None, hduname='EVENTS', column=CONFIG.TIME_COLUMN): from astropy.io.fits import Header evt_columns = [column, "PI"] if hasattr(evlist, 'energy'): evt_columns = [column, "PI", "E"] dataset = get_hdu_type_dataset("EVENTS", evt_columns, hduname) hdu_table = dataset.tables[hduname] if header is None: if not hasattr(evlist, 'header'): logging.warn("Event list has no header") evlist.header = Header() header = Header.fromstring(evlist.header) header = dict() for header_column in header: header[header_column] = str(header[header_column]) header_comments[header_column] = \ str(header.comments[header_column]) hdu_table.set_header_info(header, header_comments) hdu_table.columns[column].add_values(evlist.time) if hasattr(evlist, 'energy'): if evlist.energy is not None and len(evlist.energy) == len( evlist.time): hdu_table.columns['E'].add_values(evlist.energy) else: logging.warn( "Event list energies differs from event counts, setted all energies as 0" ) hdu_table.columns['E'].add_values(np.zeros_like(evlist.time)) if hasattr(evlist, 'pi') and evlist.pi is not None and len( evlist.pi) == len(evlist.time): hdu_table.columns['PI'].add_values(evlist.pi) else: logging.warn("Event list has no PI values, using np.zeros_like") hdu_table.columns['PI'].add_values(np.zeros_like(evlist.time)) dataset.tables["GTI"] = \ DsHelper.get_gti_table_from_stingray_gti(evlist.gti) return dataset
def test_with_wcs(): data = np.arange(100).reshape(10, 10) header = Header() wcs = WCS(fix=False) wcs.wcs.cd = [[0.9, 0.8], [0.7, 0.6]] header.set('REMAIN1', 'VALUE1') header.set('DQ1', 'dqvalue1') header.set('NAXIS', 2) test_subject = CutoutND(data, wcs=wcs) cutout_result = test_subject.extract([(1, 6, 2), (4, 10, 2)]) result_wcs = cutout_result.wcs np.testing.assert_array_equal([[1.8, 1.6], [1.4, 1.2]], result_wcs.wcs.cd, 'Wrong CD output.')
def set_header_settings(settings, setting_dictionary, fits_header): # type: (object, dict, Header) -> Header """ Add the settings specified in a ``settings`` object to a FITS header, using a ``settings_dictionary`` to determine which attributes are associated with which header keyword to set and what documentation should be associate with the keyword. :param settings: An object containing header settings as attributes. :type settings: object :param setting_dictionary: :type setting_dictionary: dict :param fits_header: :type fits_header: :py:class:`astropy.io.fits.Header` :rtype: :py:class:`astropy.io.fits.Header` """ updated_header = Header(fits_header, copy=True) for key_name in setting_dictionary: value = getattr(settings, key_name) fits_keyword = setting_dictionary[key_name]['standard_fits_keyword'] fits_documentation = setting_dictionary[key_name]['short_documentation'] \ if 'short_documentation' in setting_dictionary[key_name] \ else setting_dictionary[key_name]['documentation'] if isinstance(fits_keyword, str): # if the fits_keyword is a string if fits_keyword in updated_header and updated_header[ fits_keyword] != value: logger.warning( 'FITS keyword "{fits_keyword}" is set to value "{fits_value}", ' 'overriding with value "{new_value}"'.format( fits_keyword=fits_keyword, fits_value=updated_header[fits_keyword], new_value=value)) updated_header[fits_keyword] = value, fits_documentation elif hasattr(fits_keyword, '__iter__'): # if the fits_keyword is a list for k, slice_index, v in zip(fits_keyword, range(len(value)), value): if k in updated_header and updated_header[k] != v: logger.warning( 'FITS keyword "{fits_keyword}" is set to value "{fits_value}", ' 'overriding with value "{new_value}"'.format( fits_keyword=k, fits_value=updated_header[k], new_value=v)) updated_header[ k] = v, "{documentation} Slice: {slice_index}".format( documentation=fits_documentation, slice_index=slice_index) return updated_header
def read_header(filename): """ Reads in dada header block and returns results as a FITS header Parameters ---------- filename : str full path to .dada file Returns ------- header : `~astropy.io.fits.Header` FITS header with appropriate keys """ with open(filename) as f: hdr_size = 4096 header = Header() while f.tell() < hdr_size: lin = f.readline() if lin == '\n': continue try: comment_start = lin.index('#') except ValueError: comment = None else: if comment_start == 0: if "end of header" in lin: break else: continue else: comment = lin[comment_start + 1:].strip() lin = lin[:comment_start] key, value = lin.strip().split() if key in ('FILE_SIZE', 'FILE_NUMBER', 'HDR_SIZE', 'OBS_OFFSET', 'OBS_OVERLAP', 'NBIT', 'NDIM', 'NPOL', 'NCHAN', 'RESOLUTION', 'DSB'): value = int(value) if key == 'HDR_SIZE': hdr_size = value elif key in ('FREQ', 'BW', 'TSAMP'): value = float(value) header[key] = (value, comment) return header
def test_post_sanitize_header(): test_subject = FITSHelper(io.BytesIO(), io.BytesIO()) data = np.arange(10000).reshape(100, 100) header = Header() wcs = WCS(fix=False) header.set('REMAIN1', 'VALUE1') header.set('DQ1', 'dqvalue1') header.set('NAXIS', 2) header.set('NAXIS1', 88) header.set('NAXIS2', 212) result = CutoutResult(data, wcs=wcs) test_subject._post_sanitize_header(header, result) assert 'VALUE1' == header.get('REMAIN1'), 'REMAIN1 should still be there.'
def __init__(self, runtime_context=None, nx=101, ny=103, image_multiplier=1.0, site='elp', camera='kb76', ccdsum='2 2', epoch='20160101', n_amps=1, filter='U', data=None, header=None, **kwargs): self.nx = nx self.ny = ny self.instrument_id = -1 self.site = site self.camera = camera self.ccdsum = ccdsum self.epoch = epoch if data is None: self.data = image_multiplier * np.ones((ny, nx), dtype=np.float32) else: self.data = data if n_amps > 1: self.data = np.stack(n_amps * [self.data]) self.filename = 'test.fits' self.filter = filter self.dateobs = datetime(2016, 1, 1) if header is None: header = Header({'TELESCOP': '1m0-10'}) self.header = header self.caltype = '' self.bpm = np.zeros((ny, nx), dtype=np.uint8) self.request_number = '0000331403' self.readnoise = 11.0 self.block_id = '254478983' self.molecule_id = '544562351' self.exptime = 30.0 self.obstype = 'TEST' self.is_bad = False self.configuration_mode = 'full_frame' for keyword in kwargs: setattr(self, keyword, kwargs[keyword])
def test_get_lightcurve_dataset_from_stingray_Lightcurve(capsys): from stingray.lightcurve import Lightcurve from astropy.io.fits import Header lc = Lightcurve([0, 1], [2, 2]) ds = get_lightcurve_dataset_from_stingray_Lightcurve(lc) out, err = capsys.readouterr() assert err.strip().endswith("Light curve has no header") header = Header() header["Bu"] = "Bu" lc.header = header.tostring() ds = get_lightcurve_dataset_from_stingray_Lightcurve(lc) assert np.allclose(ds.tables["RATE"].columns["TIME"].values, lc.time) assert np.allclose(ds.tables["RATE"].columns["RATE"].values, lc.counts)
def __init__(self, header, *args, **kwargs): super(AutoScaledWCSAxes, self).__init__(*args, aspect=1, **kwargs) h = Header(header, copy=True) naxis1 = h['NAXIS1'] naxis2 = h['NAXIS2'] scale = min(self.bbox.width / naxis1, self.bbox.height / naxis2) h['NAXIS1'] = int(np.ceil(naxis1 * scale)) h['NAXIS2'] = int(np.ceil(naxis2 * scale)) scale1 = h['NAXIS1'] / naxis1 scale2 = h['NAXIS2'] / naxis2 h['CRPIX1'] = (h['CRPIX1'] - 1) * (h['NAXIS1'] - 1) / (naxis1 - 1) + 1 h['CRPIX2'] = (h['CRPIX2'] - 1) * (h['NAXIS2'] - 1) / (naxis2 - 1) + 1 h['CDELT1'] /= scale1 h['CDELT2'] /= scale2 self.reset_wcs(WCS(h)) self.set_xlim(-0.5, h['NAXIS1'] - 0.5) self.set_ylim(-0.5, h['NAXIS2'] - 0.5) self._header = h
def __new__(cls, value, unit=None, dtype=None, copy=True, wcs=None, meta=None, mask=None, header=None, spectral_unit=None, beams=None): if np.asarray(value).ndim != 1: raise ValueError("value should be a 1-d array") if wcs is not None and wcs.wcs.naxis != 1: raise ValueError("wcs should have two dimension") self = u.Quantity.__new__(cls, value, unit=unit, dtype=dtype, copy=copy).view(cls) self._wcs = wcs self._meta = {} if meta is None else meta self._mask = mask if header is not None: self._header = header else: self._header = Header() self._spectral_unit = spectral_unit if spectral_unit is None: if 'CUNIT1' in self._header: self._spectral_unit = u.Unit(self._header['CUNIT1']) elif self._wcs is not None: self._spectral_unit = u.Unit(self._wcs.wcs.cunit[0]) if beams is not None: self.beams = beams return self
def __init__(self, *args, header, obstime=None, **kwargs): super().__init__(*args, aspect=1, **kwargs) h = Header(header, copy=True) naxis1 = h["NAXIS1"] naxis2 = h["NAXIS2"] scale = min(self.bbox.width / naxis1, self.bbox.height / naxis2) h["NAXIS1"] = int(np.ceil(naxis1 * scale)) h["NAXIS2"] = int(np.ceil(naxis2 * scale)) scale1 = h["NAXIS1"] / naxis1 scale2 = h["NAXIS2"] / naxis2 h["CRPIX1"] = (h["CRPIX1"] - 1) * (h["NAXIS1"] - 1) / (naxis1 - 1) + 1 h["CRPIX2"] = (h["CRPIX2"] - 1) * (h["NAXIS2"] - 1) / (naxis2 - 1) + 1 h["CDELT1"] /= scale1 h["CDELT2"] /= scale2 if obstime is not None: h["DATE-OBS"] = Time(obstime).utc.isot self.reset_wcs(WCS(h)) self.set_xlim(-0.5, h["NAXIS1"] - 0.5) self.set_ylim(-0.5, h["NAXIS2"] - 0.5) self._header = h
def test_ignore_hdus_report(self, capsys): a = np.arange(100).reshape(10, 10) b = a.copy() + 1 ha = Header([('A', 1), ('B', 2), ('C', 3)]) phdu_a = PrimaryHDU(header=ha) phdu_b = PrimaryHDU(header=ha) ihdu_a = ImageHDU(data=a, name='SCI') ihdu_b = ImageHDU(data=b, name='SCI') hdulist_a = HDUList([phdu_a, ihdu_a]) hdulist_b = HDUList([phdu_b, ihdu_b]) tmp_a = self.temp('testa.fits') tmp_b = self.temp('testb.fits') hdulist_a.writeto(tmp_a) hdulist_b.writeto(tmp_b) numdiff = fitsdiff.main([tmp_a, tmp_b, "-u", "SCI"]) assert numdiff == 0 out, err = capsys.readouterr() assert "testa.fits" in out assert "testb.fits" in out
def test_cd_pc_header_fix(): test_subject = FITSHelper(io.BytesIO(), io.BytesIO()) data = np.arange(10000).reshape(100, 100) header = Header() wcs = WCS() header.set('NAXIS', 2) header.set('NAXIS1', 88) header.set('NAXIS2', 212) header.set('CD1_1', 44) header.set('CD1_2', 88) header.set('CD2_1', 22) header.set('CD2_2', 33) result = CutoutResult(data, wcs=wcs) test_subject._post_sanitize_header(header, result) assert not header.get('CD1_2'), 'CD1_2 should be renamed.' assert not header.get('CD1_1'), 'CD1_1 should be renamed.' assert 44 == header.get('PC1_1'), 'PC1_1 should be 44.' assert 33 == header.get('PC2_2'), 'PC2_2 should be 33.'
def fits_header(self) -> Header: hdr = Header() hdr.set("INSTRUME", self.camera) hdr.set("EXPTIME", self.exp) hdr.set("GAIN", self.gain) hdr.set("CCD-TEMP", self.temp) if self.image_type == "LIGHT": hdr.set("IMAGETYP", "Light Frame") hdr.set("OBJECT", self.target) hdr.set("FILTER", self.filter) elif self.image_type == "FLAT": hdr.set("IMAGETYP", "Flat Frame") hdr.set("FILTER", self.filter) elif self.image_type == "DARK": hdr.set("IMAGETYP", "Dark Frame") hdr.set("SUBCOUNT", self.subcount) return hdr
def test_pc_leading_zeroes_header_fix(): test_subject = FITSHelper(io.BytesIO(), io.BytesIO()) data = np.arange(10000).reshape(100, 100) header = Header() wcs = WCS() header.set('NAXIS', 2) header.set('NAXIS1', 88) header.set('NAXIS2', 212) header.set('PC01_01', 44) header.set('PC01_02', 88) header.set('PC02_01', 22) header.set('PC02_02', 33) result = CutoutResult(data, wcs=wcs) test_subject._post_sanitize_header(header, result) assert not header.get('PC01_02'), 'PC01_02 should be renamed.' assert not header.get('PC01_01'), 'PC01_01 should be renamed.' assert 22 == header.get('PC2_1'), 'PC2_1 should be 22.' assert 88 == header.get('PC1_2'), 'PC1_2 should be 88.'
def get_eventlist_dataset_from_stingray_Eventlist(evlist, header=None, header_comments=None, hduname='EVENTS', column='TIME'): from astropy.io.fits import Header lc_columns = [column, "PI", "ENERGY"] dataset = get_hdu_type_dataset("EVENTS", lc_columns, hduname) hdu_table = dataset.tables[hduname] if header is None: if not hasattr(evlist, 'header'): logging.warn("Event list has no header") evlist.header = Header() header = Header.fromstring(evlist.header) header = dict() for header_column in header: header[header_column] = str(header[header_column]) header_comments[header_column] = \ str(header.comments[header_column]) hdu_table.set_header_info(header, header_comments) hdu_table.columns[lc_columns[0]].add_values(evlist.time) if hasattr(evlist, 'energy'): hdu_table.columns['ENERGY'].add_values(evlist.energy) else: hdu_table.columns['ENERGY'].add_values(np.zeros_like(evlist.time)) if hasattr(evlist, 'pi'): hdu_table.columns['PI'].add_values(evlist.pi) else: hdu_table.columns['ENERGY'].add_values(np.zeros_like(evlist.time)) dataset.tables["GTI"] = \ DsHelper.get_gti_table_from_stingray_gti(evlist.gti) return dataset
def test_post_sanitize_header_crpix(): test_subject = FITSHelper(io.BytesIO(), io.BytesIO()) data = np.arange(10000).reshape(100, 100) header = Header() wcs = WCS(fix=False) header.set('REMAIN1', 'VALUE1') header.set('DQ1', 'dqvalue1') header.set('NAXIS', 2) header.set('NAXIS1', 88) header.set('NAXIS2', 212) header.set('CRPIX1', 77.0) header.set('WCSAXES', 2) header.set('CTYPE1', 'ctype1value') result = CutoutResult(data, wcs=wcs) assert header.index('WCSAXES') > header.index('CRPIX1'), \ 'Start with bad indexes...' test_subject._post_sanitize_header(header, result) assert 'VALUE1' == header.get('REMAIN1'), 'REMAIN1 should still be there.'
def tr2wcs(tr_eqpos, tr_physical=None): """Convert a pyTransform object to AstroPy WCS object. This is rather hacky, and relies on only having to worry about simple (e.g. WCS-TAN) transforms. It has been created by trial and error, rather than research, dur to time constraints. Hulls - which are tabular - just have a single transform but images have both sky sky and eqpos, so need hacking. """ ctypes = tr_eqpos.get_parameter('CTYPE').get_value() crvals = tr_eqpos.get_parameter('CRVAL').get_value() crpixs = tr_eqpos.get_parameter('CRPIX').get_value() cdelts = tr_eqpos.get_parameter('CDELT').get_value() if tr_physical is not None: if tr_physical.get_parameter('ROTATION').get_value() != 0.0: raise ValueError("Unexpected transform") # convert the origin crpixs = tr_physical.invert([crpixs])[0] # convert the scale scale = tr_physical.get_parameter('SCALE').get_value() cdelts *= scale hdr = Header() hdr['CTYPE1'] = ctypes[0] hdr['CRVAL1'] = crvals[0] hdr['CRPIX1'] = crpixs[0] hdr['CDELT1'] = cdelts[0] hdr['CTYPE2'] = ctypes[1] hdr['CRVAL2'] = crvals[1] hdr['CRPIX2'] = crpixs[1] hdr['CDELT2'] = cdelts[1] return WCS(hdr)