Ejemplo n.º 1
0
def Fits_Info(plate,mjd,fiber,version):

    from astropy.io import fits
    from PyAstronomy.pyasl import helcorr

    # Now we stitch together the server path to each file. Careful though as there is a folder for the APO telescope and one for LCO that   
    # contain different field. So we will check against LCO as it contains fewer plates

    lco = [9753,9761,9762,9856,9906,9907,9908]
    apopath = '/Volumes/CoveyData/APOGEE_Spectra/preDR15/apogee/spectro/redux/visits/apo25m/'
    lcopath = '/Volumes/CoveyData/APOGEE_Spectra/preDR15/apogee/spectro/redux/visits/lco25m/'

    int_plate = int(plate)

    # Setting path to file
    if int_plate in lco:
        filepath = lcopath + str(plate) + '/' + str(mjd) + '/asVisit-apogee2-' + str(plate) + '-' + str(mjd) + '-' + str(fiber) + '.fits'
    else:
        filepath = apopath + str(plate) + '/' + str(mjd) + '/apVisit-' + str(version) + '-' + str(plate) + '-' + str(mjd) + '-' + str(fiber) + '.fits'
    
    # Now we can open the fits file on the server
    try:
        fitsfile = fits.open(filepath)
        header = fitsfile[0].header
    except:
        print('Bad file path!')

    ''' Get: wavegrid, flux, error, VHELIO, RA, DEC, TELESCOP '''

    # Grabbing the data for the wavelength and flux
    wavedata = fitsfile[4].data
    fluxdata = fitsfile[1].data
    ferrordata = fitsfile[2].data

    # Getting location information and the barycentric correction
    ra = header['RA']
    dec = header['DEC']
    jd = header['JD-MID']
    telescope = header['TELESCOP']

    # Sometimes there is no reported BC so we need to get one from the helcorr package
    try:
        vbc = header['BC']

    except:
        if telescope == 'apo25m':
            vbc,hjd = helcorr(-105.4913,36.4649,2788,ra,dec,jd)
        else:
            vbc,hjd = helcorr(-70.413336,-29.05256,2380,ra,dec,jd)

    fitsfile.close()
    
    return(wavedata,fluxdata,ferrordata,vbc,ra,dec)
Ejemplo n.º 2
0
def compute_vbarycenter( spectrum):
    """ 
    Compute the velocity correction to Barycentric for this date and direction
    """
    global firstRun 

    if baryCenterAvailable: 
        longitude = spectrum.tellon
        latitude = spectrum.tellat
        altitude = spectrum.telelev
        ra2000 = spectrum.ra
        dec2000 = spectrum.dec

        # need to convert date time to Julian date
        jd = jdutil.datetime_to_jd(spectrum.utc)

# Calculate barycentric correction (debug=True show
# various intermediate results)
        corr, hjd = pyasl.helcorr(longitude, latitude, altitude, \
                                      ra2000, dec2000, jd, debug=doDebug)
        if doDebug or firstRun:
            print("Barycentric correction [km/s]: %8.3f" % (corr))
            firstRun = False
    else:
        corr = 0.
    return corr
Ejemplo n.º 3
0
def setjd(header, ra, dec):

    try:
        dateobs = header["EMMNWB"]
        t = astropy.time.Time(dateobs, format='fits', scale='utc')
    except ValueError:
        dateobs = header["DATE-OBS"]
        t = astropy.time.Time(dateobs, format='fits', scale='utc')

    try:
        jd = float(header["JD"])
    except KeyError:
        jd = t.jd

    # Coordinates of European Southern Observatory
    # (Coordinates of UT1)
    latitude = -30.169661
    longitude = -70.806525
    altitude = 2207.

    # Coordinates of HD 12345 (J2000)
    ra2000 = convHMS(ra)
    dec2000 = convDMS(dec)

    # Calculate barycentric correction (debug=True show
    # various intermediate results)
    corr, hjd = pyasl.helcorr(longitude, latitude, altitude, \
                              ra2000, dec2000, jd, debug=False)

    # #if abs(float(header["JD"])-jd) > 0.003:
    #    print "ERROR, check JD of exposures! mismatch between DATE-OBS or EMMNWB and JD header"
    #    #sys.exit(1)
    #    corr = header["BCV"]

    #    strout = header["OBJECT"] + " " + header["DATE-OBS"]
    #    strout = open("badfits_JD").read() + strout+"\n"
    #    o = open("badfits_JD","w")
    #    o.write(strout)
    #    o.close()

    bjd = bjdcalc(hjd, ra2000, dec2000)
    print corr, jd, hjd, bjd

    return corr, jd, hjd, bjd
Ejemplo n.º 4
0
def shift(wl, spec, rv, bcarr, **kwargs):
    """for bccorr, use bcarr as well, which should be EITHER:
	1) the pure barycentric velocity calculated elsewhere OR
	2) a dictionary with the following entries (all as floats, except the observatory name code, if using): 
	{'ra': RA (deg), 'dec': dec (deg), 'obs': observatory name or location of observatory, 'date': JD of midpoint of observation}
	The observatory can either be an observatory code as recognized in the PyAstronomy.pyasl.Observatory list of observatories,
	or an array containing longitude, latitude (both in deg) and altitude (in meters), in that order.

	To see a list of observatory codes use "PyAstronomy.pyasl.listobservatories()".
	
	Args:
		wl (list): wavelength array
		spec (list): flux array
		rv (float): Rotational velocity value
		bcarr (list): if len = 1, contains a precomputed barycentric velocity. Otherwise, should 
			be a dictionary with the following properties: either an "obs" keyword and code from pyasl
			or a long, lat, alt set of floats identifying the observatory coordinates.  

	Returns:
		barycentric velocity corrected wavelength vector using bccorr().

	"""
    if len(bcarr) == 1:
        bcvel = bcarr[0]
    if len(bcarr) > 1:
        if isinstance(bcarr['obs'], str):
            try:
                ob = pyasl.observatory(bcarr['obs'])
            except:
                print(
                    'This observatory code didn\'t work. Try help(shift) for more information'
                )
            lon, lat, alt = ob['longitude'], ob['latitude'], ob['altitude']
        if np.isarray(bcarr['obs']):
            lon, lat, alt = bcarr['obs'][0], bcarr['obs'][1], bcarr['obs'][2]
        bcvel = pyasl.helcorr(lon, lat, alt, bcarr['ra'], bcarr['dec'],
                              bcarr['date'])[0]

    wl = bccorr()

    return ''
def combine_header(header_list):
    new_header = header_list[0]

    new_header["MJD-OBS"] = mean(return_header_numbers(header_list, "MJD-OBS"))
    new_header["AIRMASS"] = mean(return_header_numbers(header_list, "AIRMASS"))
    new_header["EXPTIME"] = sum(return_header_numbers(header_list, "EXPTIME"))

    jd = new_header["MJD-OBS"] + 2400000.5
    t = astropy.time.Time(jd, format='jd', scale='utc')
    new_header["DATE-OBS"] = str(t.fits)

    # Coordinates of European Southern Observatory
    # (Coordinates of UT1)
    longitude = new_header["LONG-OBS"]
    latitude = new_header["LAT-OBS"]
    altitude = new_header["ALT-OBS"]

    # Coordinates of HD 12345 (J2000)
    ra2000 = convHMS(new_header["RA"])
    dec2000 = convDMS(new_header["DEC"])

    # Calculate barycentric correction (debug=True show
    # various intermediate results)
    corr, hjd = pyasl.helcorr(longitude, latitude, altitude, \
                              ra2000, dec2000, jd, debug=False)

    print jd, corr, hjd

    new_header.set('HJD', hjd)
    new_header.set('JD', jd)
    new_header.set('BCORR', corr)
    new_header.set('AP0', "Spectrum FFdiv+BKsub")
    new_header.set('AP1', "Background FFdiv")
    new_header.set('AP2', "ThAr")
    new_header.set('AP3', "Spectrum BKsub")
    new_header.set('AP4', "Background")
    new_header.set('AP5', "Wavelength")

    return new_header, string.replace(string.replace(str(t.fits), "(UTC)", ""),
                                      ":", "-")
Ejemplo n.º 6
0
 def revise_wavelength(self):
     fig = plt.figure(1)
     ax = fig.add_subplot(111)
     ax.plot(self.sky_sci)
     ylim = ax.get_ylim()
     
     xpos = []
     def onclick(event):
         
         print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
              ('double' if event.dblclick else 'single', event.button,
              event.x, event.y, event.xdata, event.ydata))
         xpos.append(event.xdata)
         ax.plot([event.xdata,event.xdata],ylim)
         plt.draw()
         
     cid = fig.canvas.mpl_connect('button_press_event', onclick)        
     plt.show(1)
     cid = fig.canvas.mpl_disconnect(cid)
     pixelpos = np.array(xpos)
     
     fig = plt.figure(1)
     ax = fig.add_subplot(111)
     ax.plot(self.wave, self.sky_model)
     ylim = ax.get_ylim()
     
     for pixel in pixelpos:
         pass
             
     xpos = []
     cid = fig.canvas.mpl_connect('button_press_event', onclick)        
     plt.show(1)
     cid = fig.canvas.mpl_disconnect(cid)
     
     wavepos = np.array(xpos)
     
     coeffs = np.polyfit(pixelpos,wavepos,1)
     
     new_wave_func = np.poly1d(coeffs)
     
     self.new_wave = new_wave_func(np.arange(self.wave.size))
     
     # Remember to sample the sky model on the new wavelength grid
     self.sky_model = np.interp(self.new_wave,self.wave,self.sky_model)
     self.wave = self.new_wave
     
     plt.plot(self.wave,self.sky_std/np.nanmedian(self.sky_std))
     plt.plot(self.wave,self.sky_model/np.nanmedian(self.sky_model))
     plt.show()
     
     # Calculate the barycentric correction 
     lat = 19.8238
     lon = 155.4689
     alt = 4213.0
     jd = Time(self.header['DATE-OBS']).jd
     ra = Angle(self.header['TARGRA'], unit='hourangle').degree
     dec = Angle(self.header['TARGDEC'], unit=u.deg).degree
     
     corr, hjd = pyasl.helcorr(lon, lat, alt, \
                 ra, dec, jd)
             
     cc = 299792.458 #km/s       
     self.wave *= (1.0 + corr/cc)    
Ejemplo n.º 7
0
    def extract_spectra(self, files, extractor, star_dark=None, flat_files=None,   
                        flat_dark=None, location=('151.2094','-33.865',100.0),  
                        coord=None, do_bcor=True, ra_dec_hr=False):
        """Extract the spectrum from a file, given a dark file, a flat file and
        a dark for the flat. The process is:
        
        1) Dark correcting the data and the flat fields.
        2) Computing (but not applying) Barycentric corrections.
        3) Extracting the data and the flat fields using the extract module, to form 
           :math:`f_m(x)`, the flux for orders m and dispersion direction pixels x. 
        4) Normalising the flat fields, so that the median of each order is 1.0.
        5) Dividing by the extracted flat field. Uncertainties from the flat field are 
           added in quadrature.

        TODO: Not the neatest implementation, but should account for the fact that
        there are no flats or darks for the ThAr frames. Might be worth tidying
        up and making the implementation a little more elegant.

        
        Parameters
        ----------
        files: list of strings
            One string for each file. CAn be on separate nights - a full 
            pathname should be given.
        star_dark:
            
        flat_files: list of strings.
            One string for each star file. CAn be on separate nights - a full 
            pathname should be given.
        flat_dark:
            
        location: (lattitude:string, longitude:string, elevation:string)
            The location on Earth where the data were taken.
        coord: astropy.coordinates.sky_coordinate.SkyCoord
            The coordinates of the observation site
        do_bcor: boolean
            Flag for whether to do barycentric correction
        
        Returns
        -------
        fluxes: 3D np.array(float)
            Fluxes of form (Observation, Order, Flux/pixel)
        vars: 3D np.array(float)
            Variance of form (Observation, Order, Variance/pixel)
        bcors: 1D np.array(float)
            Barycentric correction for each observation.
        wave: 2D np.array(float)
            Wavelength coordinate map of form (Order, Wavelength/pixel)
        mjds: 1D np.array(float)
            Modified Julian Date (MJD) of each observation.
        
        """
        # Initialise list of return values 
        # Each index represents a single observation
        fluxes = []
        vars = []
        dates = []
        bcors = []
        
        #!!! This is dodgy, as files and flat_files should go together in a dict
        for ix,file in enumerate(files):
            # Dark correct the science and flat frames
            # Only if flat/darks have been supplied --> ThAr might not have them
            # If not supplied, just use science/reference data
            try:
                # Dark correct science frames
                if len(star_dark) > 0: 
                    data = pyfits.getdata(file) - star_dark
                else:
                    data = pyfits.getdata(file)  
                # Dark correct flats    
                if len(flat_files) > 0 and len(flat_dark) > 0:    
                    flat = pyfits.getdata(flat_files[ix]) - flat_dark
                elif len(flat_files) > 0:
                    flat = pyfits.getdata(flat_files[ix])

            except: 
                print('Unable to calibrate file ' + file + 
                      '. Check that format of data arrays are consistent.')
                print(pyfits.getdata(file).shape)
                print(star_dark.shape)
                continue            
            header = pyfits.getheader(file)
            
            date = Time(header['JD'], format='jd', location=location)
            dates.append(date)
            
            # Determine the barycentric correction
            if do_bcor:
                if not coord:
                    # Depending on whether the RA and DEC is saved in hours or
                    # degrees, load and create a SkyCoord object
                    if ra_dec_hr:
                        ra_deg = float(header['RA'])*15
                    else:
                        ra_deg = float(header['RA'])

                    dec_deg = float(header['DEC'])                    
                    coord = SkyCoord(ra=ra_deg, dec=dec_deg, unit='deg') 
                    
                if not location:
                    location=(float(header['LONG']), float(header['LAT']), 
                              float(header['HEIGHT']))
                #(obs_long, obs_lat, obs_alt, ra2000, dec2000, jd, debug=False)
                #pdb.set_trace()
                bcors.append(1e3*pyasl.helcorr(float(location[0]), 
                             float(location[1]),location[2],coord.ra.deg, 
                             coord.dec.deg,date.jd)[0] )
            else:
                bcors.append(0.0)
            
            # Extract the fluxes and variance for the science and flat frames
            print("Extracting spectra from file #", str(ix))
            flux, var = extractor.one_d_extract(data=data, rnoise=20.0)
            
            # Continue only when flats have been supplied
            # Perform flat field correction and adjust variances
            if len(flat_files) > 0:
                flat_flux, fvar = extractor.one_d_extract(data=flat, 
                                                          rnoise=20.0)
            
                for j in range(flat_flux.shape[0]):
                    medf = np.median(flat_flux[j])
                    flat_flux[j] /= medf
                    fvar[j] /= medf**2
                
                #Calculate the variance after dividing by the flat
                var = var/flat_flux**2 + fvar * flux**2/flat_flux**4
                
                #Now normalise the flux.
                flux /= flat_flux

            # Regardless of whether the data has been flat field corrected, 
            # append to the arrays and continue
            fluxes.append(flux[:,:,0])
            vars.append(var[:,:,0])

        fluxes = np.array(fluxes)
        vars = np.array(vars)
        bcors = np.array(bcors)
        mjds = np.array([d.mjd for d in dates])

        return fluxes, vars, bcors, mjds
Ejemplo n.º 8
0
while not all_rvs_calculated:
    num_rvs_extracted += high - low
    # Load in a segment of files
    fluxes, vars, wave, bcors, mjds = rv.load_fluxes(extracted_files[low:high])
    
    bcors = []
    
    # Calculate the barycentric correction for each observation, based on the
    # instantaneous position of the sun
    for t in mjds:
        time = Time(t, format="mjd")
        coord = SkyCoord(coordinates.get_sun(time))
        location = location=('151.2094','-33.865',100.0)
        
        bcors.append(1e3*pyasl.helcorr(float(location[0]), float(location[1]),
                     location[2], coord.ra.deg, coord.dec.deg, time.jd)[0] )
    
    nf = fluxes.shape[0]
    nm = fluxes.shape[1]
    ny = fluxes.shape[2]

    # Calculate the RVs
    rvs, rv_sigs = rv.calculate_rv_shift(wave_ref, ref_spect, fluxes, vars,
                                         bcors, wave)  
    
    rv_list.append(rvs)
    rv_sig_list.append(rv_sigs)
    bcors_list.append(bcors)
    mjds_list.append(mjds)
    
    # Move to next segment
Ejemplo n.º 9
0
    def revise_wavelength(self):
        fig = plt.figure(1)
        ax = fig.add_subplot(111)
        ax.plot(self.sky_sci)
        ylim = ax.get_ylim()

        xpos = []

        def onclick(event):

            print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
                  ('double' if event.dblclick else 'single', event.button,
                   event.x, event.y, event.xdata, event.ydata))
            xpos.append(event.xdata)
            ax.plot([event.xdata, event.xdata], ylim)
            plt.draw()

        cid = fig.canvas.mpl_connect('button_press_event', onclick)
        plt.show(1)
        cid = fig.canvas.mpl_disconnect(cid)
        pixelpos = np.array(xpos)

        fig = plt.figure(1)
        ax = fig.add_subplot(111)
        ax.plot(self.wave, self.sky_model)
        ylim = ax.get_ylim()

        for pixel in pixelpos:
            pass

        xpos = []
        cid = fig.canvas.mpl_connect('button_press_event', onclick)
        plt.show(1)
        cid = fig.canvas.mpl_disconnect(cid)

        wavepos = np.array(xpos)

        coeffs = np.polyfit(pixelpos, wavepos, 1)

        new_wave_func = np.poly1d(coeffs)

        self.new_wave = new_wave_func(np.arange(self.wave.size))

        # Remember to sample the sky model on the new wavelength grid
        self.sky_model = np.interp(self.new_wave, self.wave, self.sky_model)
        self.wave = self.new_wave

        plt.plot(self.wave, self.sky_std / np.nanmedian(self.sky_std))
        plt.plot(self.wave, self.sky_model / np.nanmedian(self.sky_model))
        plt.show()

        # Calculate the barycentric correction
        lat = 19.8238
        lon = 155.4689
        alt = 4213.0
        jd = Time(self.header['DATE-OBS']).jd
        ra = Angle(self.header['TARGRA'], unit='hourangle').degree
        dec = Angle(self.header['TARGDEC'], unit=u.deg).degree

        corr, hjd = pyasl.helcorr(lon, lat, alt, \
                    ra, dec, jd)

        cc = 299792.458  #km/s
        self.wave *= (1.0 + corr / cc)
Ejemplo n.º 10
0
            fitspath = serverpath + str(plate) + '/' + str(mjd) + '/apVisit-r8-' + str(plate) + '-' + str(mjd) + '-' + str(fiber) + '.fits'
            openfile = fits.open(fitspath)
            header = openfile[0].header

        try:
            vbc = header['VHELIO']
        except:
            ra = header['RA']
            dec = header['DEC'] 
            jd = header['JD-MID']
                            
            height = 2788
            longg = -105.4913
            lat = 36.4649
                            
            vbc,hjd = helcorr(longg,lat,height,ra,dec,jd)
    
    else: 
        serverpath = '/Volumes/CoveyData/APOGEE_Spectra/preDR15/apogee/spectro/redux/visits/lco25m/' 
        fitspath = serverpath + str(plate) + '/' + str(mjd) + '/asVisit-apogee2-' + str(plate) + '-' + str(mjd) + '-' + str(fiber) + '.fits'
        openfile = fits.open(fitspath)
        header = openfile[0].header
        
        try:

            vbc = header['VHELIO']

        except:

            ra = header['RA']
            dec = header['DEC'] 
Ejemplo n.º 11
0
def barycorr_crires(wavelength, flux, header, extra_offset=None):
    """Calculate Heliocentric correction values and apply to spectrum.

    # SHOULD test again with bary and see what the difference is.
    """
    if header is None:
        logging.warning(
            "No header information to calculate heliocentric correction.")
        header = {}
        if (extra_offset is None) or (extra_offset == 0):
            return wavelength, flux

    try:
        longitude = float(header["HIERARCH ESO TEL GEOLON"])
        latitude = float(header["HIERARCH ESO TEL GEOLAT"])
        altitude = float(header["HIERARCH ESO TEL GEOELEV"])

        ra = header["RA"]  # CRIRES RA already in degrees
        dec = header["DEC"]  # CRIRES hdr DEC already in degrees

        time = header["DATE-OBS"]  # Observing date  '2012-08-02T08:47:30.8425'

        # Convert easily to julian date with ephem
        jd = ephem.julian_date(time.replace("T", " ").split(".")[0])

        # Calculate Heliocentric velocity
        helcorr = pyasl.helcorr(longitude,
                                latitude,
                                altitude,
                                ra,
                                dec,
                                jd,
                                debug=False)
        helcorr = helcorr[0]

        if header.get("BARYDONE", False):
            warnings.warn(
                "Applying barycentric correction when 'BARYDONE' already flag set."
            )

    except KeyError as e:
        logging.warning("Not a valid header so can't do automatic correction.")

        helcorr = 0.0

    if extra_offset is not None:
        logging.warning(
            "Warning!!!! have included a manual offset for testing")
    else:
        extra_offset = 0.0

    helcorr_val = helcorr + extra_offset

    if helcorr_val == 0:
        logging.warning("Helcorr value was zero")
        return wavelength, flux
    else:
        # Apply Doppler shift to the target spectra with helcorr correction velocity
        nflux, wlprime = pyasl.dopplerShift(wavelength,
                                            flux,
                                            helcorr_val,
                                            edgeHandling=None,
                                            fillValue=None)

        logging.info(
            __("RV Size of Heliocenter correction for spectra {}",
               helcorr_val))
        return wlprime, nflux
Ejemplo n.º 12
0
def structurate(ext, dirname, names):
    ext = ext.lower()
    for filein in names:
        if filein.lower().endswith(ext):
            filein = os.path.join(dirname, filein).strip('./')
            f = fits.open(filein)
            head = f[0].header

            prog = head['HIERARCH ESO OBS PROG ID']
            ob = head['HIERARCH ESO OBS NAME']

            if ob not in rej_ob:

                pplfil = head['PIPEFILE']
                airm = np.mean([
                    head['HIERARCH ESO TEL AIRM START'],
                    head['HIERARCH ESO TEL AIRM END']
                ])
                sng = np.mean([
                    head['HIERARCH ESO TEL AMBI FWHM START'],
                    head['HIERARCH ESO TEL AMBI FWHM END']
                ])
                pla = head['HIERARCH ESO INS OBSPLATE']
                expt = head['EXPTIME']
                dat = head['DATE-OBS'].split('T')[0]
                tim = head['DATE-OBS'].split('T')[1]
                lat = head['HIERARCH ESO TEL GEOLAT']
                lon = head['HIERARCH ESO TEL GEOLON']
                elv = head['HIERARCH ESO TEL GEOELEV']
                ptra = head['RA']
                ptdec = head['DEC']
                jld = head['MJD-OBS']
                helicorr = pyasl.helcorr(lon, lat, elv, ptra, ptdec,
                                         jld + 2.4e6)[0]

                if prog not in filstruc.keys():
                    filstruc[prog] = {}
                    infos[prog] = {}

                if ob not in filstruc[prog].keys():
                    filstruc[prog][ob] = {}
                    infos[prog][ob] = {}

                if 'bin_table_info' in pplfil:
                    tab = f[1].data
                    assoc = {}
                    coords = {}
                    for l in tab:
                        if l[3] != '':
                            assoc[l[2] + 1] = l[3]
                            coords[l[3]] = deg2HMS(l[4], l[5])
                    filstruc[prog][ob]['fibassoc'] = assoc
                    infos[prog][ob]['coords'] = coords
                    infos[prog][ob]['airmass'] = airm
                    infos[prog][ob]['seeing'] = sng
                    infos[prog][ob]['plate'] = pla
                    infos[prog][ob]['exptime'] = expt
                    infos[prog][ob]['date'] = dat
                    infos[prog][ob]['time'] = tim
                    infos[prog][ob]['vhelio'] = helicorr
                    infos[prog][ob]['rv'] = {}

                elif ('mwfxb' in pplfil) and ('sigma' not in pplfil):
                    if head['EXTNAME'].strip() == 'CCD-44':
                        chip = 'lower'
                    else:
                        chip = 'upper'
                    fibre = int(pplfil.strip('.fits').split('_')[2])
                    if fibre not in filstruc[prog][ob].keys():
                        filstruc[prog][ob][fibre] = {}

                    flux = f[0].data
                    wavest = head['CRVAL1']
                    wbin = head['CDELT1']
                    wave = [wavest + wbin * i for i in range(len(flux))]
                    filstruc[prog][ob][fibre][chip] = [wave, flux]
Ejemplo n.º 13
0
def fill_headers(file_names, device):
    if device == 'mres':
        obsname = 'TNO'  # Thai National Observatory, Doi Inthanon
        obslat = 18.573828  # Latitude of the observatory
        obslon = 98.4817485  # Longitude of the observatory, E
        obsalt = 2549.  # Altitude of the observatory
        gain = 0.55  # Electronic gain in e-/ADU
        rdnoise = 2.0  # CCD readout noise
    elif device == 'eshel_ccs':
        obsname = 'CCS'  # NARIT provincial observatory, Chachoengsao
        obslat = 13.593682  # Latitude of the observatory
        obslon = 101.256209  # Longitude of the observatory, E
        obsalt = 11.  # Altitude of the observatory
        gain = 0.95  # Electronic gain in e-/ADU
        rdnoise = 7.0  # CCD readout noise
    elif device == 'eshel_krt':
        obsname = 'KRT'  # NARIT provincial observatory, Korat
        obslat = 14.873460  # Latitude of the observatory
        obslon = 102.02883  # Longitude of the observatory, E
        obsalt = 245.  # Altitude of the observatory
        gain = 0.95  # Electronic gain in e-/ADU
        rdnoise = 7.0  # CCD readout noise
    elif device == 'eshel_tno':
        obsname = 'TNO'  # Thai National Observatory, Doi Inthanon
        obslat = 18.573828  # Latitude of the observatory
        obslon = 98.4817485  # Longitude of the observatory, E
        obsalt = 2549.  # Altitude of the observatory
        gain = 0.95  # Electronic gain in e-/ADU
        rdnoise = 7.0  # CCD readout noise
    elif device == 'maestro':
        obsname = 'Terskol'  # Terskol Observatory, Mt. Elbrus, Russia
        obslat = 43.272777  # Latitude of the observatory
        obslon = 42.500000  # Longitude of the observatory, E
        obsalt = 3100.  # Altitude of the observatory
        gain = 1.0  # Electronic gain in e-/ADU
        rdnoise = 4.0  # CCD readout noise

    files, objnames = np.loadtxt(file_names,
                                 unpack=True,
                                 usecols=(0, 1),
                                 dtype=str,
                                 delimiter=';')
    simbad_session = Simbad()
    simbad_session.add_votable_fields('ra(H;ICRS;J2000)', 'dec(D;ICRS;J2000)')
    simbad_session.remove_votable_fields('coordinates')
    for ii in range(len(files)):
        files[ii] = files[ii].strip()
        objnames[ii] = objnames[ii].strip()
        print(f"File: {files[ii]}\tObjname: {objnames[ii]}")
        with fits.open(files[ii].strip(), mode='update') as hdu:
            hdr = hdu[0].header
            if hdr['NAXIS'] == 2:
                data = hdu[0].data.copy()
            elif hdr['NAXIS'] == 3:
                data = hdu[0].data[0].copy()
            if data.dtype.name != 'uint32':
                print(f"Scale data from {hdu[0].data.dtype.name} to 'float32'")
                hdu[0].data = np.float32(data)
            if 'DATE-OBS' in hdr:
                tm_start = Time.Time(hdr['DATE-OBS'])
            elif 'FRAME' in hdr:
                tm_start = Time.Time(hdr['FRAME'])
            if 'EXPOSURE' in hdr:
                texp = hdr['EXPOSURE'] * u.s
                hdr.set('EXPTIME', hdr['EXPOSURE'], 'Exposure (s)')
            else:
                texp = hdr['EXPTIME'] * u.s
            tm_mid = tm_start + texp / 2.
            tm_end = tm_start + texp
            ut = tm_mid.ymdhms[
                3] + tm_mid.ymdhms[4] / 60. + tm_mid.ymdhms[5] / 3600.
            ut_end = tm_end.ymdhms[
                3] + tm_end.ymdhms[4] / 60. + tm_end.ymdhms[5] / 3600.
            if 'DATE' not in hdr:
                hdr.set('DATE', hdr['DATE-OBS'].split(".")[0],
                        'Copy of DATE-OBS')
            hdr.set('DISPAXIS', 1, 'Keyword for IRAF')
            hdr.set('GAIN', gain, '')
            hdr.set('RDNOISE', rdnoise, '')
            hdr.set('OBSGEO-B', obslat, 'Latitude of the observatory')
            hdr.set('OBSGEO-L', obslon, 'Longitude of the observatory')
            hdr.set('OBSGEO-H', obsalt, 'Altitude of the observatory')
            hdr.set('OBSERVAT', obsname, 'Thai National Observatory')

            if (objnames[ii].lower() == "flat"):
                hdr.set('IMAGETYP', 'FLAT', '')
            elif (objnames[ii].lower() == "bias"):
                hdr.set('IMAGETYP', 'BIAS', '')
            elif (objnames[ii].lower() == "thar"):
                hdr.set('IMAGETYP', 'THAR', '')
            elif (objnames[ii].lower() == "sky"):
                hdr.set('IMAGETYP', 'OBJ', '')
            elif (objnames[ii].lower() == "dark"):
                hdr.set('IMAGETYP', 'DARK', '')

            if (objnames[ii].lower() != "flat") and (objnames[ii].lower() != "thar") \
               and (objnames[ii].lower() != "bias") and (objnames[ii].lower() != "sky") and \
               (objnames[ii].lower() != "dark"):
                query_result = simbad_session.query_object(objnames[ii])
                ra = query_result['RA_H_ICRS_J2000'][0]
                dec = query_result['DEC_D_ICRS_J2000'][0]
                if 'RA' in hdr:
                    hdr['RA'] = ra
                else:
                    hdr.set('RA', ra, 'RA in hours')
                if 'DEC' in hdr:
                    hdr['DEC'] = dec
                else:
                    hdr.set('DEC', dec, 'DEC in degrees')
                if 'EPOCH' in hdr:
                    hdr['EPOCH'] = 2000.
                else:
                    hdr.set('EPOCH', 2000., 'EPOCH of coordinates')
                star = coord.SkyCoord(ra,
                                      dec,
                                      unit=(u.hourangle, u.deg),
                                      frame='icrs')
                observat = coord.EarthLocation.from_geodetic(
                    obslon, obslat, obsalt * u.m)
                dateobs = np.char.replace(tm_mid.fits, 'T', ' ')
                dateobs = Time.Time(dateobs, scale='utc', location=observat)
                ltt_bary = dateobs.light_travel_time(star)
                bjd = dateobs.jd + ltt_bary.value
                bcr, hjd = helcorr(observat.lon.degree, observat.lat.degree,
                                   obsalt, star.ra.degree, star.dec.degree,
                                   dateobs.jd)
                hdr.set('HJD', hjd, 'Heliocentric JD')
                hdr.set('BJD', bjd, 'Barycentric JD')
                hdr.set('BARYCORR', bcr, 'Barycentric correction')
                hdr.set('IMAGETYP', 'OBJ', '')
            if 'OBJNAME' in hdr:
                hdr['OBJNAME'] = objnames[ii]
            else:
                hdr.set('OBJNAME', objnames[ii], '')
            if 'DATE-OBS' in hdr:
                hdr['DATE-OBS'] = tm_mid.fits
            else:
                hdr.set('DATE-OBS', tm_mid.fits, '')
            if 'UT' in hdr:
                hdr['UT'] = ut
            else:
                hdr.set('UT', ut, '')
            if 'UTEND' in hdr:
                hdr['UTEND'] = ut_end
            else:
                hdr.set('UTEND', ut_end, '')
            hdu[0].header = hdr
            hdu.flush()
            print("File %s has been updated" % (files[ii].strip()))
    print("...done")
    return None
Ejemplo n.º 14
0
def get_lines(line):
    '''
    get_halpha, but more general
    '''

    flux_all = []
    vel_all = []
    MJD_all = []
    flag_all = []
    ra = 84.9122543
    dec = -34.07410972

    if line == 'Ha':
        USE = [
            'ESPaDOnS', 'BeSS', 'BeSOS', 'UVES', 'FEROS', 'OPD - Musicos',
            'OPD - Ecass', 'NRES'
        ]
    elif line == 'Hb':
        USE = ['ESPaDOnS', 'BeSOS', 'FEROS', 'NRES']
    else:
        USE = ['ESPaDOnS', 'BeSOS', 'FEROS', 'NRES']

    lbd0 = linesDict.line_names[line][1]

    # plot ESPaDOnS
    flag = 'ESPaDOnS'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/ESPaDOnS/new/*i.fits.gz')
        MJD = np.zeros([len(lines)])
        JD = np.zeros([len(lines)])
        ####
        # FROM THE HEADER
        ###COMMENT Correcting wavelength scale from Earth motion...
        ###COMMENT Coordinates of object : 5:39:38.94 & -34: 4:26.9
        ###COMMENT Time of observations : 2011 11 9 @ UT 13:34:33
        ###COMMENT  (hour angle = 0.775 hr, airmass = 1.742 )
        ###COMMENT Total exposure time : 25.0 s
        ###COMMENT Cosine latitude of observatory : 0.941
        ###COMMENT Heliocentric velocity of observer towards star : 9.114 km/s

        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdr_list = fits.open(fname)
            fits_data = hdr_list[0].data
            fits_header = hdr_list[0].header
            #f = open('{0}_{1}.txt'.format(flag, n), 'wb')
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            #read MJD
            MJD[n] = fits_header['MJDATE']
            #
            #lat = fits_header['LATITUDE']
            #lon = fits_header['LONGITUD']
            lbd = fits_data[0, :]
            ordem = lbd.argsort()
            lbd = lbd[ordem]
            flux_norm = fits_data[1, ordem]
            vel, flux = spt.lineProf(lbd, flux_norm, lbc=lbd0)
            #cut = asas(vel, flux, line)
            #cut_all.append(cut)
            vel_all.append(vel)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    ## plot BeSS
    flag = 'BeSS'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/BeSS/new/*fits')
        MJD = np.zeros([len(lines)])
        JD = np.zeros([len(lines)])

        #FROM HEADER
        #           BSS_VHEL shows the applied correction in km/s. If BSS_VHEL=0,
        #COMMENT   no correction has been applied. The required correction given
        #COMMENT   in BSS_RQVH (in km/s) is an escape velocity (redshift). To apply
        #COMMENT   it within Iraf, the keyword redshift must be set to -BSS_RQVH
        #COMMENT   and isvelocity must be set to "yes" in the dopcor task.

        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdr_list = fits.open(fname)
            fits_data = hdr_list[0].data
            fits_header = hdr_list[0].header
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            #read MJD
            MJD[n] = fits_header['MID-HJD']  #HJD at mid-exposure
            t = Time(MJD[n], format='jd', scale='utc')
            MJD[n] = t.mjd
            #lat = fits_header['BSS_LAT']
            #lon = fits_header['BSS_LONG']
            #elev = fits_header['BSS_ELEV']
            corr = -fits_header['BSS_RQVH']
            lbd = fits_header['CRVAL1'] + fits_header['CDELT1'] * np.arange(
                len(fits_data))
            vel, flux = spt.lineProf(lbd, fits_data, lbc=lbd0 * 10)
            vel = vel + corr
            #cut = asas(vel, flux, line)
            #cut_all.append(cut)
            vel_all.append(vel)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    # plot MUSICOS
    flag = 'OPD - Musicos'
    if flag in USE:
        lines = glob(
            direc +
            'Dropbox/Amanda/Data/MUSICOS/andre/spec_*/acol/*halpha.fits')
        MJD = np.zeros([len(lines)])
        #######################################
        # Andre disse q estao corrigidos
        #######################################
        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdr_list = fits.open(fname)
            fits_data = hdr_list[0].data
            fits_header = hdr_list[0].header
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            #read MJD
            MJD[n] = fits_header['JD']  #JD
            t = Time(MJD[n], format='jd', scale='utc')
            MJD[n] = t.mjd
            #corr = fits_header['VHELIO']
            lbd = fits_header['CRVAL1'] + fits_header['CDELT1'] * np.arange(
                len(fits_data))
            vel, flux = spt.lineProf(lbd, fits_data, lbc=lbd0 * 10)
            vel_all.append(vel)
            #cut = asas(vel, flux, line)
            #cut_all.append(cut)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    ## plot Moser
    flag = 'OPD - Ecass'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/ecass_musicos/data/alpCol*')
        MJD = np.zeros([len(lines)])

        ## NO INFO ON HEADER!
        #Latitude: 22° 32' 04" S	Longitude: 45° 34' 57" W
        lat = -22.53444
        lon = -45.5825
        alt = 1864.
        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdr_list = fits.open(fname)
            fits_data = hdr_list[0].data
            fits_header = hdr_list[0].header
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            #read MJD
            MJD[n] = fits_header['MJD']  #JD
            #t = Time(MJD[n], format = 'jd', scale='utc')
            #MJD[n] = t.mjd
            t = Time(MJD[n], format='mjd', scale='utc')
            JD[n] = t.jd
            corr, hjd = pyasl.helcorr(lon, lat, alt, ra, dec, JD[n])
            #corr = 0.
            lbd = fits_header['CRVAL1'] + fits_header['CDELT1'] * np.arange(
                len(fits_data))
            vel, flux = spt.lineProf(lbd, fits_data, lbc=lbd0 * 10)
            vel = vel + corr
            vel_all.append(vel)
            #cut = asas(vel, flux, line)
            #cut_all.append(cut)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    # plot UVES
    flag = 'UVES'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/UVES/new/*.fits')
        MJD = np.zeros([len(lines)])
        JD = np.zeros([len(lines)])

        #lat = -29.257778
        #lon = -70.736667

        # FROM HEADER
        ###################################################################################
        #HIERARCH ESO QC VRAD BARYCOR = -8.401681 / Barycentric radial velocity correctio
        #HIERARCH ESO QC VRAD HELICOR = -8.398018 / Heliocentric radial velocity correcti
        ###################################################################################

        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdulist = fits.open(fname)
            # print column information
            #hdulist[1].columns
            # get to the data part (in extension 1)
            scidata = hdulist[1].data
            wave = scidata[0][0]
            arr1 = scidata[0][1]
            arr2 = scidata[0][2]
            fits_header = hdulist[0].header
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            MJD[n] = fits_header['MJD-OBS']
            vel, flux = spt.lineProf(wave, arr1, lbc=lbd0 * 10)
            #vel = vel + corr
            #cut = asas(vel, flux, line)
            #cut_all.append(cut)
            vel_all.append(vel)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    ##plot BeSOS
    flag = 'BeSOS'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/BeSOS/2018/*.fits')
        MJD = np.zeros([len(lines)])
        JD = np.zeros([len(lines)])

        # FROM WEBSITE
        #All the spectra available are reduced and corrected with the heliocentric velocity

        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdr_list = fits.open(fname)
            fits_data = hdr_list[0].data
            fits_header = hdr_list[0].header
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            #read MJD
            MJD[n] = fits_header['MJD']
            #corr = 0.
            #t = Time(MJD[n], format = 'mjd', scale='utc')
            #JD[n] = t.jd
            #corr, hjd = pyasl.helcorr(lon, lat, 2400., ra, dec, JD[n])
            lbd = fits_header['CRVAL1'] + fits_header['CDELT1'] * np.arange(
                len(fits_data))
            vel, flux = spt.lineProf(lbd, fits_data, lbc=lbd0 * 10)
            #corr = fits_header['BVEL']
            #vel = vel + corr
            #cut = asas(vel, flux, line)
            #cut_all.append(cut)
            vel_all.append(vel)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    #plot prof_nelson
    flag = 'FEROS'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/prof_nelson/*/*')
        MJD = np.zeros([len(lines)])
        JD = np.zeros([len(lines)])

        #lat = -29.257778
        #lon = -70.736667

        # FROM HEADER
        ###################################################################
        #HISTORY  'BARY_CORR'      ,'R*4 '   ,    1,    1,'5E14.7',' ',' '
        #HISTORY  -1.5192770E+01
        ###################################################################

        for n in range(len(lines)):
            fname = lines[n]
            # read fits
            hdr_list = fits.open(fname)
            fits_data = hdr_list[0].data
            fits_header = hdr_list[0].header
            #fits_header.totextfile('{0}_{1}.txt'.format(flag, n))
            #read MJD
            MJD[n] = fits_header['MJD-OBS']
            t = Time(MJD[n], format='mjd', scale='utc')
            JD[n] = t.jd
            #corr = 0.
            lbd = fits_header['CRVAL1'] + fits_header['CDELT1'] * np.arange(
                len(fits_data))
            vel, flux = spt.lineProf(lbd, fits_data, lbc=lbd0 * 10)
            #vel = vel + corr
            vel_all.append(vel)
            #corr_all.append(corr)
            flux_all.append(flux)
            MJD_all.append(MJD[n])
            flag_all.append(flag)

    flag = 'NRES'
    if flag in USE:
        lines = glob(direc + 'Dropbox/Amanda/Data/NRES/*fits*')
        MJD = np.zeros([len(lines)])
        JD = np.zeros([len(lines)])

        #lat = -29.257778
        #lon = -70.736667
        barycorr_list = []
        # FROM HEADER
        ###################################################################
        #HISTORY  'BARY_CORR'      ,'R*4 '   ,    1,    1,'5E14.7',' ',' '
        #HISTORY  -1.5192770E+01
        ###################################################################
        order = linesDict.line_names[line][0]
        wl_list = []
        flx_list = []
        BJD_list = []
        for n in range(len(lines)):
            fname = lines[n]

            hdulist = fits.open(fname)
            headers = hdulist[0].header
            BJD_mid_exp = headers['BJD']
            #t = Time(BJD_mid_exp, format = 'jd', scale='utc')
            #MJD[n] = t.mjd
            DAY_OBS = headers['DATE-OBS']
            SITE = headers['SITE']
            LONG1 = headers['LONG1']
            LAT1 = headers['LAT1']
            HT1 = headers['HT1']
            SpecRaw = hdulist[1]
            SpecFlat = hdulist[2]
            SpecBlaze = hdulist[3]
            ThArRaw = hdulist[4]
            ThArFlat = hdulist[5]
            WaveSpec = hdulist[6]
            WaveThAr = hdulist[7]
            SpecXcor = hdulist[8]
            RVBlockFit = hdulist[9]

            wl_list.append(WaveSpec)
            flx_list.append(SpecFlat)
            #flx_list.append(SpecBlaze)
            BJD_list.append(BJD_mid_exp)

            obs_loc = EarthLocation.from_geodetic(lat=LAT1 * u.deg,
                                                  lon=LONG1 * u.deg,
                                                  height=HT1 * u.m)
            sc = SkyCoord(ra=ra * u.deg, dec=dec * u.deg)
        wl_list = np.array(wl_list)[np.argsort(BJD_list)]
        flx_list = np.array(flx_list)[np.argsort(BJD_list)]
        BJD_list = np.array(BJD_list)[np.argsort(BJD_list)]
        for i, x in enumerate(wl_list):
            vel, flux = spt.lineProf(wl_list[i].data[order],
                                     flx_list[i].data[order],
                                     lbc=lbd0)
            #vel = vel + corr
            #vel_all.append(vel)
            #corr_all.append(corr)
            flux_all.append(flux)
            t = Time(BJD_list[i], format='jd', scale='utc')
            MJD[n] = t.mjd
            MJD_all.append(MJD[n])

            flag_all.append(flag)
            # barycentric correction is more precise, but might be more difficult to apply
            barycorr = sc.radial_velocity_correction(kind='barycentric',
                                                     obstime=Time(BJD_list[i],
                                                                  format='jd'),
                                                     location=obs_loc)
            barycorr = barycorr.value / 1000.
            barycorr_list.append(barycorr)

            # heliocentric correction is easier, but less precise at a level of like 10 m/s
            #heliocorr = sc.radial_velocity_correction(kind='heliocentric',obstime=Time(BJD_list[i], format='jd'), location=obs_loc)
            #helcorr_list.append(heliocorr.value* au.value / (60*60*24)/ 1000.0)
            vl = vel + barycorr + vel * barycorr / (c.value / 1000.0)
            vel_all.append(vl)

    return MJD_all, vel_all, flux_all, flag_all
Ejemplo n.º 15
0
def disp_add(fits_name, thar_name, view):
    bcr = -999

    if view:
        disp = matplotlib.pyplot.figure(1)
        ax = matplotlib.pyplot.gca()

    #read fits
    hdulist = pyfits.open(fits_name)
    spectrum = hdulist[0].data.copy()
    prihdr = hdulist[0].header
    hdulist.close()

    if 'IMAGETYP' in prihdr:
        if prihdr['IMAGETYP'] == 'OBJ':
            # Compute barycentric correction
            if 'BARYCORR' not in prihdr:
                if 'OBSGEO-B' in prihdr and 'OBSGEO-L' in prihdr and 'OBSGEO-H' in prihdr \
                              and 'RA' in prihdr and 'DEC' in prihdr and 'EPOCH' in prihdr:
                    print("Compute barycentric correction...")
                    logging.info("Compute barycentric correction...")
                    dateobs = prihdr['DATE-OBS']
                    ra = prihdr['RA']
                    dec = prihdr['DEC']
                    epoch = prihdr['EPOCH']
                    obslat = prihdr['OBSGEO-B']
                    obslon = prihdr['OBSGEO-L']
                    obsalt = prihdr['OBSGEO-H']
                    star = coord.SkyCoord(ra, dec, unit=(u.hourangle, u.deg), frame='icrs')
                    observat = coord.EarthLocation.from_geodetic(obslon, obslat, obsalt * u.m)
                    dateobs = np.char.replace(dateobs, 'T', ' ')
                    dateobs = time.Time(dateobs, scale='utc', location=observat)
                    ltt_bary = dateobs.light_travel_time(star)
                    bjd = dateobs.jd + ltt_bary.value
                    bcr, hjd = helcorr(observat.lon.degree, observat.lat.degree, obsalt, star.ra.degree, star.dec.degree, dateobs.jd)
                    prihdr.set('HJD', hjd, 'Heliocentric JD')
                    prihdr.set('BJD', bjd, 'Barycentric JD')
                    prihdr.set('BARYCORR', bcr, 'Barycentric correction')
                else:
                    print("No information about the observatory in the header. Wavelength remains uncorrected")
                    logging.warning("No information about the observatory in the header. Wavelength remains uncorrected")
            else:
                bcr = prihdr['BARYCORR']

    #read solution
    sol_name = os.path.splitext(thar_name)[0] + '_disp.txt'
    print('Disp solution:', sol_name)
    solution = np.genfromtxt(sol_name)
    order_shift = int(solution[0])
    x_order = int(solution[1])
    y_order = int(solution[2])
    solution = np.delete(solution, [0, 1, 2])

    WAT2 = ''
    add_string = ''

    X = np.arange(0, spectrum.shape[1], 1)
    for ii in range(0, spectrum.shape[0]):
        O = np.empty_like(X)
        O.fill(ii+order_shift)
        WL = cheb_sol(solution, y_order)(X,O)
        if bcr != -999:
            WL = WL * np.sqrt((1. + bcr/c)/(1. - bcr/c))  # Doppler correction
        w1=np.min(WL)
        w2=np.max(WL)
        nw=len(X)
        dw=(w2-w1)/(nw-1) #-1
##        print ('Blue end:', w1, 'Red end:', w2, 'A/pix:', dw)
        X_lin=np.linspace(w1,w2, nw)
        graph_data = spectrum[ii,:]
        f2 = interp1d(WL, graph_data, kind='slinear', bounds_error = False)
        Y_lin=f2(X_lin)
        spectrum[ii,:] = Y_lin
        APNUM = (prihdr['APNUM'+str(ii+1)])
        del prihdr['APNUM'+str(ii+1)]
        APNUM = APNUM.split()
        add_string = (" spec%i = \"%i %i %i %.10f %0.15f %i %i. %.2f %.2f\"" % (spectrum.shape[0]-ii, spectrum.shape[0]-ii, ii+order_shift, 0, w1, dw, nw, 0, float(APNUM[2]), float(APNUM[3])))
        WAT2 = add_string + WAT2

        if view:
            ax.plot(X_lin, Y_lin, 'r')

    del prihdr['CTYPE1']
    del prihdr['CTYPE2']
    del prihdr['CRPIX1']
    del prihdr['WAT0_001']
    del prihdr['WAT1_001']
    del prihdr['WAT2_001']

    prihdr['CTYPE1'] = 'MULTISPE'
    prihdr['CTYPE2'] = 'MULTISPE'
    prihdr['CRPIX1'] = 0
    prihdr['WAT0_001'] = 'system=multispec'
    prihdr['WAT1_001'] = 'wtype=multispec label=Wavelength units=angstroms'
    WAT2 = 'wtype=multispec' + WAT2
    for ii in range(1, int(2+len(WAT2)/68)):
        keyword = str("WAT2_%03i" % ii)
        prihdr[keyword] =  str(WAT2[0:68])
        WAT2 = WAT2[68:]
    prihdr['REFSPEC'] = (str(sol_name.split(os.sep)[-1]), 'WL reference spectrum')
    if bcr != -999:
        prihdr['HISTORY'] = 'Applied barycentric correction BARYCORR'

    hdulist[0].data = np.flip(spectrum, axis=0)
    new_name = os.path.splitext(fits_name)[0]  + "_WCS.fits"
    hdulist.writeto(new_name, clobber=True)

    if view:
        matplotlib.pyplot.show()
    return new_name
Ejemplo n.º 16
0
def extract_spectra(files, star_dark, flat_files, flat_dark, location=('151.2094','-33.865',100.0), coord=None, outfile=None, do_bcor=True):
    """Extract the spectrum from a file, given a dark file, a flat file and
    a dark for the flat. 
    
    Parameters
    ----------
    files: list of strings
        One string for each file. CAn be on separate nights - a full pathname should be given.
    star_dark:
        
    flat_files: list of strings.
        One string for each star file. CAn be on separate nights - a full pathname should be given.
    flat_dark:
        
    location: (lattitude:string, longitude:string, elevation:string)
        The location on Earth where the data were taken.
    coord:
    
    outfile:
    
    do_bcor: boolean
    
    
    Returns
    -------
    fluxes:
    
    vars:
    
    wave:
    
    bcors:
    
    mjds:
    
    """
    # Initialise list of return values 
    # Each index represents a single observation
    fluxes = []
    vars = []
    dates = []
    bcors = []

    #!!! This is dodgy, as files and flat_files should go together in a dict. !!!
    for ix,file in enumerate(files):
        # Dark correct the science and flat frames
        data = pyfits.getdata(file) - star_dark
        flat = pyfits.getdata(flat_files[ix]) - flat_dark
        
        header = pyfits.getheader(file)
        
        date = Time(header['DATE-OBS'], location=location)
        dates.append(date)
        
        # Determine the barycentric correction
        if do_bcor:
            if not coord:
                coord=SkyCoord( ra=float(header['RA']) , dec=float(header['DEC']) , unit='deg')
            if not location:
                location=( float(header['LONG']), float(header['LAT']), float(header['HEIGHT']))
            #(obs_long, obs_lat, obs_alt, ra2000, dec2000, jd, debug=False)
            bcors.append( 1e3*pyasl.helcorr(float(location[0]),float(location[1]),location[2],coord.ra.deg, coord.dec.deg,date.jd)[0] )
        else:
            bcors.append(0.0)
        
        # Extract the fluxes and variance for the science and flat frames
        flux, var = rhea2_extract.one_d_extract(data=data, rnoise=20.0)
        flat_flux, fvar = rhea2_extract.one_d_extract(data=flat, rnoise=20.0)
        
        for j in range(flat_flux.shape[0]):
            medf = np.median(flat_flux[j])
            flat_flux[j] /= medf
            fvar[j] /= medf**2
        
        #Calculate the variance after dividing by the flat
        var = var/flat_flux**2 + fvar * flux**2/flat_flux**4
        
        #Now normalise the flux.
        flux /= flat_flux

        #pdb.set_trace()
        fluxes.append(flux[:,:,0])
        vars.append(var[:,:,0])

    fluxes = np.array(fluxes)
    vars = np.array(vars)
    bcors = np.array(bcors)
    mjds = np.array([d.mjd for d in dates])
    
    # Output and save the results
    if not outfile is None:
        hl = pyfits.HDUList()
        hl.append(pyfits.ImageHDU(fluxes,header))
        hl.append(pyfits.ImageHDU(vars))
        hl.append(pyfits.ImageHDU(wave))
        col1 = pyfits.Column(name='bcor', format='D', array=bcors)
        col2 = pyfits.Column(name='mjd', format='D', array=mjds)
        cols = pyfits.ColDefs([col1, col2])
        hl.append(pyfits.new_table(cols))
        hl.writeto(outfile, clobber=True)

    return fluxes,vars,wave,bcors,mjds