def header_to_fits(header): """ Convert a header dict to a `~astropy.io.fits.Header`. """ # Copy the header to avoid modifying it in place header = header.copy() # The comments need to be added to the header separately from the normal # kwargs. Find and deal with them: fits_header = fits.Header() # Check Header key_comments = header.pop('KEYCOMMENTS', False) for k, v in header.items(): # Drop any keys that have non-ascii characters if not fits.Card._ascii_text_re.match(str(v)): warn_metadata( f'The meta key {k} is not valid ascii, dropping from the FITS header' ) continue # Drop any keys which are too long to save into FITS if len(k) > 8: warn_metadata( f"The meta key {k} is too long, dropping from the FITS header " "(maximum allowed key length is 8 characters).") continue if isinstance(v, float) and math.isnan(v): warn_metadata( f'The meta key {k} has a NaN value, which is not valid in a FITS ' 'header, dropping from the FITS header') continue if k.upper() in ('COMMENT', 'HV_COMMENT'): comments = str(v).split('\n') for com in comments: fits_header.add_comment(com) elif k.upper() == 'HISTORY': hists = str(v).split('\n') for hist in hists: fits_header.add_history(hist) elif isinstance(v, fits.header._HeaderCommentaryCards): if k != '': fits_header.append(fits.Card(k, str(v).split('\n'))) else: # For some horrific reason, we save a list to the wavelnth key in # sources/rhessi.py. This is the least invasive fix for that stupidity. if isinstance(v, list): v = str(v) fits_header.append(fits.Card(k, v)) if isinstance(key_comments, dict): for k, v in key_comments.items(): # Check that the Card for the comment exists before trying to write to it. if k in fits_header: fits_header.comments[k] = v elif key_comments: raise TypeError("KEYCOMMENTS must be a dictionary") return fits_header
def put_zeropt(file, zeropt, photo='yes'): ''' Currently not used. ''' # Open thr child info, update mode f = fits.open(file, mode="update") # open a FITS file hdr = f[0].header # the primary HDU header print("# Updating %s with ZP=%s as in SExtractor, photo:%s" % (file, zeropt, photo), file=sys.stderr) after = "DATE" c = {} if photo == 'yes': c['ZEROPT'] = fits.Card("ZEROPT", zeropt, "Computed ZEROPOINT AB mags/sec") c['PHOTOM'] = fits.Card("PHOTOM", 1, "Photometric quality 1=photo/0=not") else: c['ZEROPT'] = fits.Card("ZEROPT", zeropt, "Non-photo ZEROPOINT AB mags/sec") c['PHOTOM'] = fits.Card("PHOTOM", 0, "Photometric quality 1=photo/0=not") for key in list(c.keys()): c[key].verify() hdr.update(key, c[key].value, c[key].comment, after=after) # Close the file #f.verify('silentfix') f.verify('fix') #f.verify('ignore') f.close() return
def _add_keyword(hdrlist, name, val): """Add the name,val pair to hdulist.""" name = str(name).upper() if name in ['', 'COMMENT', 'HISTORY']: # The values are assumed to be an array of strings for v in val: hdrlist.append(fits.Card(name, v)) else: hdrlist.append(fits.Card(name, val))
def write(fname, data, header, **kwargs): """ Take a data header pair and write a FITS file. Parameters ---------- fname : `str` File name, with extension data : `numpy.ndarray` n-dimensional data array header : `dict` A header dictionary """ # Copy header so the one in memory is left alone while changing it for # write. header = header.copy() # The comments need to be added to the header separately from the normal # kwargs. Find and deal with them: fits_header = fits.Header() # Check Header key_comments = header.pop('KEYCOMMENTS', False) for k, v in header.items(): if isinstance(v, fits.header._HeaderCommentaryCards): if k == 'comments': comments = str(v).split('\n') for com in comments: fits_header.add_comments(com) elif k == 'history': hists = str(v).split('\n') for hist in hists: fits_header.add_history(hist) elif k != '': fits_header.append(fits.Card(k, str(v).split('\n'))) else: fits_header.append(fits.Card(k, v)) if isinstance(key_comments, dict): for k, v in key_comments.items(): # Check that the Card for the comment exists before trying to write to it. if k in fits_header: fits_header.comments[k] = v elif key_comments: raise TypeError("KEYCOMMENTS must be a dictionary") if isinstance(fname, str): fname = os.path.expanduser(fname) fitskwargs = {'output_verify': 'fix'} fitskwargs.update(kwargs) fits.writeto(fname, data, header=fits_header, **fitskwargs)
def setRelativeWCS(hdr, xcenter, ycenter, pxlScale): # remove anything but the basic header hdr.append(fits.Card('BOTTOM', 'END', 'End of header'), end=True) i = 5 while hdr[i] != 'END': del hdr[i] del hdr['BOTTOM'] # add relative coordinate info hdr.append(fits.Card('CRPIX1', xcenter, 'Reference pixel on this axis'), end=True) hdr.append(fits.Card('CDELT1', pxlScale, 'Coordinate increment along this axis'), end=True) hdr.append(fits.Card('CRVAL1', 0., 'World coordinate on this axis'), end=True) hdr.append(fits.Card('CTYPE1', 'LINEAR', 'WCS projection type for this axis'), end=True) hdr.append(fits.Card('CRPIX2', ycenter, 'Reference pixel on this axis'), end=True) hdr.append(fits.Card('CDELT2', pxlScale, 'Coordinate increment along this axis'), end=True) hdr.append(fits.Card('CRVAL2', 0., 'World coordinate on this axis'), end=True) hdr.append(fits.Card('CTYPE2', 'LINEAR', 'WCS projection type for this axis'), end=True) return hdr
def dict2fitsHeader(d): hList = [] headerDef = config.headerDef for k, v in d.items(): try: vDef = headerDef[k] except KeyError: hList.append(fits.Card(k, v)) else: hList.append(fits.Card(vDef[0], vDef[1](v), vDef[2])) return fits.Header(hList)
def add_beam_information_to_higal_header(fn, wavelength=None, clobber=True, name_to_um=higal_beams.name_to_um, **kwargs): """ Given a Hi-Gal FITS file name, attempt to add beam information to its header. The beams are assumed to be symmetric using the larger of the two beam axes given in `Traficante et al 2011 <http://adsabs.harvard.edu/abs/2011MNRAS.416.2932T>`_. This is not a valid assumption in general, but without knowing the scan position angle you can't really do better. Parameters ---------- fn : str A filename corresponding to a Hi-Gal FITS file. MUST have one of the standard HiGal strings in the name: blue, red, PSW, PMW, or PLW clobber : bool Overwrite existing file? (has to be "True" to work!) name_to_um : dict A dictionary identifying the translation between the string that will be inserted into the file template and the wavelength. There are two built in: `higal_sedfitter.higal_beams.name_to_um` and `higal_sedfitter.higal_beams.num_to_um`. """ f = fits.open(fn) if wavelength is None: wl_names = [x for x in name_to_um if x in fn] if len(wl_names) != 1: raise ValueError("Found too few or too many matches!") wl_name = wl_names[0] else: wl_name = wavelength f[0].header.append(fits.Card(keyword='BMAJ', value=beams[name_to_um[wl_name]].to(u.deg).value, comment='From Traficante 2011')) f[0].header.append(fits.Card(keyword='BMIN', value=beams[name_to_um[wl_name]].to(u.deg).value, comment='Assumed equal to BMAJ')) f[0].header.append(fits.Card(keyword='BPA', value=0)) f[0].header.append(fits.Card(keyword='BEAMNOTE', value='2011MNRAS.416.2932T', comment='Source paper for beam')) f.writeto(fn, clobber=clobber, **kwargs)
def mkcards_hist(cmd_list): """ Return a list of HISTORY Card, which record the tool and parameters used in this process. """ tool_card = fits.Card( "HISTORY", "TOOL: %(tool)s (%(time)s)" % { 'tool': cmd_list[0], 'time': datetime.datetime.today().strftime("%Y-%m-%dT%H:%M:%S") }, "by Weitian LI (c) 2015") parm = "PARM: " + " ".join(cmd_list[1:]) parm_card = fits.Card("HISTORY", parm) return [tool_card, parm_card]
def add_nonstructural_headers(fromhdr, tohdr): for card in fromhdr.ascardlist(): if ((card.key in [ 'SIMPLE', 'XTENSION', 'BITPIX', 'END', 'PCOUNT', 'GCOUNT', 'TFIELDS', ]) or card.key.startswith('NAXIS') or card.key.startswith('TTYPE') or card.key.startswith('TFORM')): #card.key.startswith('TUNIT') or #card.key.startswith('TDISP')): #print 'skipping card', card.key continue #if tohdr.has_key(card.key): # #print 'skipping existing card', card.key # continue #print 'adding card', card.key #tohdr.update(card.key, card.value, card.comment, before='END') #tohdr.ascardlist().append( cl = tohdr.ascardlist() if 'END' in cl.keys(): i = cl.index_of('END') else: i = len(cl) cl.insert(i, pyfits.Card(card.key, card.value, card.comment))
def read_echelle(pyfits_hdu): """ Read an IRAF Echelle spectrum http://iraf.noao.edu/iraf/ftp/iraf/docs/specwcs.ps.Z """ hdr = pyfits_hdu.header WAT1_dict, specaxdict = _get_WATS(hdr) x_axes = [] for specnum, axstring in specaxdict.items(): axsplit = axstring.replace('"','').split() if specnum != int(axsplit[0]): raise ValueError("Mismatch in IRAF Echelle specification") num,beam,dtype,crval,cdelt,naxis,z,aplow,aphigh = axsplit[:9] if hdr['CTYPE1'] == 'LINEAR': xax,naxis,headerkws = make_linear_axis(hdr, axsplit, WAT1_dict) elif hdr['CTYPE1'] == 'MULTISPE': xax,naxis,headerkws = make_multispec_axis(hdr, axsplit, WAT1_dict) cards = [pyfits.Card(k,v) for (k,v) in headerkws.items()] header = pyfits.Header(cards) xarr = make_axis(xax,header) x_axes.append(xarr) data = pyfits_hdu.data with np.errstate(invalid='ignore'): data[np.isnan(data)] = np.nan return data, np.zeros_like(data), units.EchelleAxes(x_axes), hdr
def spectral_table(self): column = pyfits.Column(name=self.name, format='{}E'.format(len(self.el)), unit=self.unit, array=self.sc) table = pyfits.BinTableHDU.from_columns([column]) table.name = 'SKYMAP' # add HEALPix and energy info to the header nside = self.nside emin, deltae = self.el[0], np.log(self.el[1] / self.el[0]) cards = [ pyfits.Card(*pars) for pars in [ ( 'PIXTYPE', 'HEALPIX', 'Pixel algorithm', ), ('ORDERING', 'RING', 'Ordering scheme'), ('NSIDE', nside, 'Resolution Parameter'), #('NPIX', 12*nside**2, '# of pixels'), ('FIRSTPIX', 0, 'First pixel (0 based)'), ('LASTPIX', 12 * nside**2 - 1, 'Last pixel (0 based)'), ('NRBINS', len(self.el), 'Number of energy bins'), ('EMIN', emin, 'Minimum energy'), ('DELTAE', deltae, 'Step in energy (log)'), ] ] for card in cards: table.header.append(card) return table
def _header_from_dict(self, fit_data): c_list = [self._divcmt] for dkey, fkey, cmnt in _trace_hkey_spec: if dkey in fit_data.keys(): c_list.append(pf.Card(fkey, fit_data[dkey], comment=cmnt)) c_list.append(self._divcmt) return pf.Header(c_list)
def write(fname, data, header, **kwargs): """ Take a data header pair and write a fits file Parameters ---------- fname: str File name, with extension data: ndarray n-dimensional data array header: dict A header dictionary """ #Copy header so the one in memory is left alone while changing it for write header = header.copy() #The comments need to be added to the header seperately from the normal # kwargs. Find and deal with them: fits_header = fits.Header() # Check Header key_comments = header.pop('KEYCOMMENTS', False) for k, v in header.items(): if isinstance(v, fits.header._HeaderCommentaryCards): if k is 'comments': fits_header.add_comments(str(v)) elif k in 'history': fits_header.add_history(str(v)) else: fits_header.append(fits.Card(k, str(v))) else: fits_header.append(fits.Card(k, v)) if isinstance(key_comments, dict): for k, v in key_comments.items(): fits_header.comments[k] = v elif key_comments: raise TypeError("KEYCOMMENTS must be a dictionary") fitskwargs = {'output_verify': 'fix'} fitskwargs.update(kwargs) fits.writeto(os.path.expanduser(fname), data, header=fits_header, **fitskwargs)
def _sip2hdr(self, k): """ Get a set of SIP coefficients in the form of an array and turn them into a `astropy.io.fits.Cardlist`. k - one of 'a', 'b', 'ap', 'bp' """ cards = [] #fits.CardList() korder = self.sip.__getattribute__(k+'_order') cards.append(fits.Card(keyword=k.upper()+'_ORDER', value=korder)) coeffs = self.sip.__getattribute__(k) ind = coeffs.nonzero() for i in range(len(ind[0])): card = fits.Card(keyword=k.upper()+'_'+str(ind[0][i])+'_'+str(ind[1][i]), value=coeffs[ind[0][i], ind[1][i]]) cards.append(card) return cards
def classification_to_fits(self, hdulist): classification = [ fits.Card('CLASS', self.get_classification_type(), "Spectro classification: GALAXY, QSO, STAR"), fits.Card('P_GALAXY', self.drp1d_output.get_classification()["galaxyProba"], "Probability to be a galaxy"), fits.Card('P_QSO', self.drp1d_output.get_classification()["qsoProba"], "Probability to be a QSO"), fits.Card('P_STAR', self.drp1d_output.get_classification()["starProba"], "Probability to be a star") ] hdr = fits.Header(classification) hdu = fits.BinTableHDU(header=hdr, name="CLASSIFICATION") hdulist.append(hdu)
def header_to_fits(header): """ Convert a header dict to a `~astropy.fits.Header`. """ # The comments need to be added to the header separately from the normal # kwargs. Find and deal with them: fits_header = fits.Header() # Check Header key_comments = header.pop('KEYCOMMENTS', False) for k, v in header.items(): # Drop any keys which are too long to save into FITS if len(k) > 8: warnings.warn( f"The meta key {k} is too long, dropping from the FITS header.", SunpyUserWarning) continue if k.upper() in ('COMMENT', 'HV_COMMENT'): comments = str(v).split('\n') for com in comments: fits_header.add_comment(com) elif k.upper() == 'HISTORY': hists = str(v).split('\n') for hist in hists: fits_header.add_history(hist) elif isinstance(v, fits.header._HeaderCommentaryCards): if k != '': fits_header.append(fits.Card(k, str(v).split('\n'))) else: # For some horrific reason, we save a list to the wavelnth key in # sources/rhessi.py. This is the least invasive fix for that stupidity. if isinstance(v, list): v = str(v) fits_header.append(fits.Card(k, v)) if isinstance(key_comments, dict): for k, v in key_comments.items(): # Check that the Card for the comment exists before trying to write to it. if k in fits_header: fits_header.comments[k] = v elif key_comments: raise TypeError("KEYCOMMENTS must be a dictionary") return fits_header
def statusAsCards(self, useCache=False): if useCache is False: self.getAllStatus() cards = [] for k, v in self.status.items(): c = fits.Card('HIERARCH %s' % (k), v) cards.append(c) return cards
def create_header(coord, radius, proj='ZEA', npix=30): """ Create a header a new image """ gal = coord.name == 'galactic' values = [ [ "NAXIS", 2, ], [ "NAXIS1", npix, ], [ "NAXIS2", npix, ], ["CTYPE1", 'GLON-%s' % proj if gal else 'RA---%s' % proj], ["CTYPE2", 'GLAT-%s' % proj if gal else 'DEC--%s' % proj], [ "CRPIX1", npix / 2. + 0.5, ], [ "CRPIX2", npix / 2. + 0.5, ], [ "CRVAL1", coord.l.deg if gal else coord.ra.deg, ], [ "CRVAL2", coord.b.deg if gal else coord.dec.deg, ], [ "CDELT1", -3. * radius / npix, ], [ "CDELT2", 3. * radius / npix, ], ] if not gal: values += [ ['RADECSYS', 'FK5'], ['EQUINOX', 2000], ] cards = [pyfits.Card(*i) for i in values] header = pyfits.Header(cards=cards) return header
def _idc2hdr(self): # save some of the idc coefficients coeffs = ['ocx10', 'ocx11', 'ocy10', 'ocy11', 'idcscale'] cards = [] for c in coeffs: try: val = self.__getattribute__(c) except AttributeError: continue if val: cards.append(fits.Card(keyword=c, value=val)) return cards
def read_echelle(pyfits_hdu): """ Read an IRAF Echelle spectrum http://iraf.noao.edu/iraf/ftp/iraf/docs/specwcs.ps.Z """ hdr = pyfits_hdu.header WAT1_dict, specaxdict = _get_WATS(hdr) x_axes = [] for specnum, axstring in specaxdict.iteritems(): axsplit = axstring.replace('"', '').split() if specnum != int(axsplit[0]): raise ValueError("Mismatch in IRAF Echelle specification") num, beam, dtype, crval, cdelt, naxis, z, aplow, aphigh = axsplit[:9] # this is a hack for cropped spectra... #print "header naxis: %i, WAT naxis: %i" % (hdr['NAXIS1'], int(naxis)) if hdr['NAXIS1'] != int(naxis): naxis = hdr['NAXIS1'] crpix = hdr.get('CRPIX1') warn("Treating as cropped echelle spectrum.") else: crpix = 0 if len(axsplit) > 9: functions = axsplit[9:] warn("Found but did not use functions %s" % str(functions)) if int(dtype) == 0: xax = (float(crval) + float(cdelt) * (np.arange(int(naxis)) + 1 - crpix)) / (1. + float(z)) headerkws = { 'CRPIX1': 1, 'CRVAL1': crval, 'CDELT1': cdelt, 'NAXIS1': naxis, 'NAXIS': 1, 'REDSHIFT': z, 'CTYPE1': 'wavelength', 'CUNIT1': WAT1_dict['units'] } cards = [pyfits.Card(k, v) for (k, v) in headerkws.iteritems()] header = pyfits.Header(cards) xarr = make_axis(xax, header) x_axes.append(xarr) return pyfits_hdu.data, pyfits_hdu.data * 0, units.EchelleAxes(x_axes), hdr
def get_wat2_spec_cards(wat_list): wat = "wtype=multispec " + " ".join(wat_list) char_per_line = 68 num_line, remainder = divmod(len(wat), char_per_line) cards = [] for i in range(num_line): k = "WAT2_%03d" % (i+1,) v = wat[char_per_line*i:char_per_line*(i+1)] #print k, v c = pyfits.Card(k, v) cards.append(c) if remainder > 0: i = num_line k = "WAT2_%03d" % (i+1,) v = wat[char_per_line*i:] #print k, v c = pyfits.Card(k, v) cards.append(c) return cards
def generate(self, fitsfiles, error_collector, state): header = self.create_header(fitsfiles, error_collector, state) for card in self: if isinstance(card, Card): state.card = card.name card.generate(header, fitsfiles, error_collector, state) state.card = None elif isinstance(card, str): card_obj = pyfits.Card(' ', card) header.append(card_obj, useblanks=False) return header
def makeHead(dset): # ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ """ Construct a header out of a set of HDF5 dataset attributes. """ cards = [] for ihdr in range(len(dset.attrs.keys())): aCard = pf.Card(keyword=dset.attrs.keys()[ihdr], value=dset.attrs.values()[ihdr]) cards.append(aCard) hdr = pf.Header(cards=cards) return hdr
def make_table(self, unit=None): makecol = lambda v: pyfits.Column(name=v.name, format='E', unit=unit, array=v.getcol()) cols = map(makecol, self) nside = self.nside cards = [pyfits.Card(*pars) for pars in [ ('PIXTYPE', 'HEALPIX', 'Pixel algorithm',), ('ORDERING', 'RING', 'Ordering scheme'), ('NSIDE' , nside, 'Resolution Parameter'), ('NPIX', 12*nside**2, '# of pixels'), ('FIRSTPIX', 0, 'First pixel (0 based)'), ('LASTPIX', 12*nside**2-1, 'Last pixel (0 based)')]] table = pyfits.BinTableHDU.from_columns(cols, header=pyfits.Header(cards)) table.name = 'SKYMAP' return table
def header_to_fits(header): """ Convert a header dict to a `~astropy.fits.Header`. """ # The comments need to be added to the header separately from the normal # kwargs. Find and deal with them: fits_header = fits.Header() # Check Header key_comments = header.pop('KEYCOMMENTS', False) for k, v in header.items(): if isinstance(v, fits.header._HeaderCommentaryCards): if k.upper() == 'COMMENT': comments = str(v).split('\n') for com in comments: fits_header.add_comment(com) elif k.upper() == 'HISTORY': hists = str(v).split('\n') for hist in hists: fits_header.add_history(hist) elif k != '': fits_header.append(fits.Card(k, str(v).split('\n'))) else: fits_header.append(fits.Card(k, v)) if isinstance(key_comments, dict): for k, v in key_comments.items(): # Check that the Card for the comment exists before trying to write to it. if k in fits_header: fits_header.comments[k] = v elif key_comments: raise TypeError("KEYCOMMENTS must be a dictionary") return fits_header
def get_pyfits(self): """ Create and return a pyfits object that corresponds to the ROIImage object. The fits file created is supposed to be consistent with the internal representation that SkyImage/SkyProj uses. """ if self.galactic: ctype1="GLON-%s" % self.proj ctype2="GLAT-%s" % self.proj # for some reason, SkyDir(0,0,SkyDir.GALACTIC).l() = 360 crval1,crval2=self.center.l() % 360,self.center.b() else: ctype1="RA-%s" % self.proj ctype2="DEC-%s" % self.proj crval1,crval2=self.center.ra(),self.center.dec() cdelt1,cdelt2=-self.pixelsize,self.pixelsize # from SkyImage.cxx like 92: # "center pixel; WCS convention is that center of a pixel is a half-integer" crpix1,crpix2=(self.skyimage.naxis1()+1)/2.0,(self.skyimage.naxis2()+1)/2.0 values = [ ["TELESCOP", "GLAST"], ["INSTRUME", "LAT"], ["DATE-OBS", ""], ["DATE-END", ""], ["EQUINOX", 2000.0, "Equinox of RA & DEC specifications"], ["CTYPE1", ctype1, "[RA|GLON]---%%%, %%% represents the projection method such as AIT"], ["CRPIX1", crpix1, "Reference pixel"], ["CRVAL1", crval1, "RA or GLON at the reference pixel"], ["CDELT1", cdelt1, "X-axis incr per pixel of physical coord at position of ref pixel(deg)"], ["CTYPE2", ctype2, "[DEC|GLAT]---%%%, %%% represents the projection method such as AIT"], ["CRPIX2", crpix2, "Reference pixel"], ["CRVAL2", crval2, "DEC or GLAT at the reference pixel"], ["CDELT2", cdelt2, "Y-axis incr per pixel of physical coord at position of ref pixel(deg)"], ["CROTA2", 0, "Image rotation (deg)"], ] for i in values: if len(i)>2 and len(i[2])>47: i[2]=i[2][0:47] cards = [ pyfits.Card(*i) for i in values] header=pyfits.Header(cards=cards) hdu=pyfits.PrimaryHDU(data=self.image, header=header) fits = pyfits.HDUList([hdu]) return fits
def str2fitsheader(string): """ Convert a string into a pyfits.Header object All cards are extracted from the input string until the END keyword is reached. """ header = pyfits.Header() cards = header.ascard() iline = 0 while (iline * 80 < len(string)): line = string[iline * 80:(iline + 1) * 80] if line[0:3] == 'END': break cards.append(pyfits.Card().fromstring(line)) iline += 1 return header
def make_fits_header(header,first=True,LOFAR=False): '''Takes .fil header into fits header format ''' base_header = {} base_header['SIMPLE'] = True base_header['NAXIS'] = 2 base_header['NAXIS1'] = int(header['Number of channels']) base_header['DOPPLER'] = 0.0 base_header['SNR'] = 0.0 base_header['EXTEND'] = True base_header['DELTAT'] = float(header['Sample time (us)'])/1e6 base_header['MJD'] = float(header['Time stamp of first sample (MJD)']) base_header['XTENSION'] = 'IMAGE ' base_header['PCOUNT'] = 1 base_header['GCOUNT'] = 1 base_header['TOFFSET'] = float(header['Sample time (us)'])/1e6 if LOFAR: base_header['BITPIX'] = -32 base_header['DELTAF'] = 0.000001497456 # LOFAR specific (project LC2_040). base_header['DEC'] = float(header['Source DEC (J2000)']) base_header['RA'] = float(header['Source RA (J2000)']) base_header['SOURCE'] = header['Source Name'].replace('\xc2\xa0','_').replace(' ','_') else: if '32' in header['Number of bits per sample']: base_header['BITPIX'] = -32 else: raise ValueError('Check nbits per sample. Not equeal 32') base_header['DELTAF'] = np.abs(float(header['Channel bandwidth (MHz)'])) base_header['DEC'] = header['Source DEC (J2000)'] base_header['RA'] = header['Source RA (J2000)'] base_header['SOURCE'] = header['Source Name'].replace('\xc2\xa0','_').replace(' ','') base_header['FCNTR'] = float(header['Frequency of channel 1 (MHz)']) - base_header['DELTAF']*base_header['NAXIS1']/2 if first: base_header['NAXIS2'] = int(header['Number of samples']) key_list = ['SIMPLE','BITPIX','NAXIS','NAXIS1','NAXIS2','EXTEND','DELTAT','DELTAF','FCNTR','MJD','DEC','RA','DOPPLER','SNR','SOURCE'] else: base_header['NAXIS2'] = 1 key_list = ['XTENSION','BITPIX','NAXIS','NAXIS1','NAXIS2','PCOUNT','GCOUNT','DELTAT','DELTAF','FCNTR','TOFFSET','DEC','RA','DOPPLER','SNR','SOURCE'] fits_header=pyfits.Header(cards=[pyfits.Card(key=key,value=base_header[key]) for key in key_list]) return fits_header
def _idc2hdr(self): # save some of the idc coefficients coeffs = [ ('ocx10', 'original linear term from IDCTAB'), ('ocx11', 'original linear term from IDCTAB'), ('ocy10', 'original linear term from IDCTAB'), ('ocy11', 'original linear term from IDCTAB'), ('idcscale', 'pixel scale from the IDCTAB reference file'), ] cards = [] for k, c in coeffs: try: val = self.__getattribute__(k) except AttributeError: continue if val: cards.append(fits.Card(keyword=k, value=val, comment=c)) return cards
def create_monitoring(dlnum): """ Create an empty monitoring fits file for the given DL number Parameters ---------- dlnum: int delay line number """ dh = {"DL": (dlnum, "Delay line Number")} h = fits.Header([fits.Card(k, v, c) for k, (v, c) in dh.items()]) coldef = create_coldef() hdus = fits.HDUList( [fits.PrimaryHDU(header=h), fits.BinTableHDU.from_columns(coldef)]) return hdus