示例#1
0
    def fill_in_summary(self, summaryfile):
        print('Loading {}'.format(summaryfile))
        with fits.open(summaryfile, memmap=False) as hdul:
            header = hdul[0].header
            hdudict = dict(header.items())

        self.ra = np.degrees(hdudict['RightAscension'])
        self.dec = np.degrees(hdudict['Declination'])
        self.restfreq = None
        if 'RESTFREQ1' in hdudict:
            self.resfreq = hdudict['RESTFREQ1']

        try:
            self.date_obs = Time(hdudict['DATE-OBS'])
        except KeyError:
            self.date_obs = Time(hdudict['DATE'])
        try:
            self.obsid = int(hdudict['OBSID'])
        except (KeyError, ValueError):
            self.obsid = 9999

        with fits.open(os.path.join(self.dirname, self.GROUPING),
                       memmap=False) as grouphdul:
            groupheader = grouphdul[0].header
            groupdict = dict(groupheader.items())
            for key in hdudict.keys():
                if key in groupdict:
                    groupheader[key] = hdudict[key]
            groupheader['RA'] = self.ra
            groupheader['DEC'] = self.dec
            groupheader['DATE-OBS'] = self.date_obs.value
            groupheader['MJD-OBS'] = self.date_obs.mjd
            groupheader['SCANNUM'] = self.obsid
            grouphdul.writeto('tmp.fits', overwrite=True)

        force_move_file('tmp.fits', os.path.join(self.dirname, self.GROUPING))

        with fits.open(os.path.join(self.dirname, self.SCAN),
                       memmap=False) as scanhdul:
            scanheader = reset_all_keywords(scanhdul[1].header)
            scandict = dict(scanheader.items())
            for key in hdudict.keys():
                if key[:5] in ['NAXIS', 'PGCOU', 'GCOUN']:
                    continue
                if key in scandict:
                    scanheader[key] = hdudict[key]
            # Todo: update with correct keywords
            scanheader['DATE-OBS'] = self.date_obs.value
            scanheader['MJD'] = self.date_obs.mjd
            scanheader['SCANNUM'] = self.obsid
            scanhdul.writeto('tmp.fits', overwrite=True)

        force_move_file('tmp.fits', os.path.join(self.dirname, self.SCAN))
示例#2
0
    def update_scan_info(self):
        info = \
            get_observing_strategy_from_subscan_info(self.scan_info)

        with fits.open(os.path.join(self.dirname, self.SCAN),
                       memmap=False) as scanhdul:
            scanheader = scanhdul[1].header
            # Todo: update with correct keywords
            scanheader['CTYPE'] = info.ctype
            scanheader['CTYPE1'] = 'RA---GLS'
            scanheader['CTYPE2'] = 'DEC--GLS'
            scanheader['CRVAL1'] = self.ra
            scanheader['CRVAL2'] = self.dec
            scanheader['BLONGOBJ'] = self.ra
            scanheader['BLATOBJ'] = self.dec
            scanheader['LONGOBJ'] = self.ra if not info.ctype[0] == 'A' else 0
            scanheader['LATOBJ'] = self.dec if not info.ctype[0] == 'A' else 0
            scanheader['EQUINOX'] = 2000.
            scanheader['GRPLC1'] = 'GROUPING.fits'
            scanheader['LST'] = self.lst
            scanheader['LATPOLE'] = 90.
            scanheader['LONPOLE'] = 0.
            scanheader['PATLONG'] = 0
            scanheader['MOVEFRAM'] = False
            if info.ctype == 'ALON/ALAT':
                scanheader['WCSNAME'] = 'Absolute horizontal'
            scanheader['SCANTYPE'] = info.stype.upper()
            scanheader['SCANDIR'] = info.direction.upper()
            scanheader['SCANXVEL'] = info.scanvel
            scanheader['SCANTIME'] = info.scantime
            scanheader['SCANMODE'] = info.mode.upper()
            scanheader['SCANGEOM'] = info.geom.upper()
            scanheader['SCANLINE'] = 1
            scanheader['SCANLEN'] = np.degrees(info.length)

            scanheader['SCANYSPC'] = np.degrees(info.sep[1])
            scanheader['SCANXSPC'] = np.degrees(info.sep[0])
            scanheader['SCANPAR1'] = -999
            scanheader['SCANPAR2'] = -999
            scanheader['ZIGZAG'] = info.zigzag
            scanheader['PHASE1'] = 'sig'
            scanheader['PHASE2'] = 'sig'
            scanheader['NOBS'] = info.nobs
            scanheader['NSUBS'] = info.nobs
            scanheader['WOBCYCLE'] = 0.
            scanheader['WOBDIR'] = 'NONE'
            scanheader['WOBMODE'] = 'NONE'
            scanheader['WOBPATT'] = 'NONE'
            scanhdul.writeto('tmp.fits', overwrite=True)
        force_move_file('tmp.fits', os.path.join(self.dirname, self.SCAN))
示例#3
0
    def add_febe(self, febe, feed_info, feed, meta, bands=None):
        if bands is None:
            bands = [1]
        polar = 'N'
        polar_code = polar[0]

        febe_name = febe + '-FEBEPAR.fits'

        with fits.open(
                os.path.join(self.template_dir,
                             'FLASH460L-XFFTS-FEBEPAR.fits'),
                memmap=False) as febe_template:

            febe_template[1].header = \
                reset_all_keywords(febe_template[1].header)

            febedata = Table(febe_template[1].data)
            # FEBEFEED stores the total number of feeds for the receiver in
            # use.  A receiver outputting two polarisations counts as two
            # feeds.  For an array, count the total no.  of pixels, even if
            # not all in use.
            febedata['USEBAND'] = np.array([bands])
            febedata['NUSEFEED'] = np.array([[2]])
            febedata['USEFEED'] = \
                np.array([[feed * 2 + 1, feed * 2 + 2,
                           feed * 2 + 1, feed * 2 + 2]])
            febedata['BESECTS'] = np.array([[0]])
            febedata['FEEDTYPE'] = np.array([[1, 2, 3, 4]])
            febedata['POLTY'][:] = np.array([polar_code])
            febedata['POLA'][:] = np.array([[0., 0.]])
            new_hdu = fits.table_to_hdu(febedata)

            febe_template[1].data = new_hdu.data
            # TODO: fill in the information given in the subscan[ch]

            new_febe = os.path.join(self.dirname, febe_name)

            febe_template[1].header['DATE-OBS'] = self.date_obs.fits
            febe_template[1].header['FEBE'] = febe
            febe_template[1].header['FEBEFEED'] = self.nfeeds * 2
            febe_template[1].header['NUSEBAND'] = max(bands)
            febe_template[1].header['NPHASES'] = 1
            febe_template[1].header['SWTCHMOD'] = 'NONE'
            febe_template[1].header['SCANNUM'] = self.obsid

            if 'Q' in feed_info[feed][bands[0]].keys():
                febe_template[1].header['FDTYPCOD'] = '1:L, 2:R, 3:Q, 4:U'
            else:
                febe_template[1].header['FDTYPCOD'] = '1:L, 2:R'
            febe_template.writeto('tmp.fits', overwrite=True)
        force_move_file('tmp.fits', new_febe)

        with fits.open(os.path.join(self.dirname, self.SCAN),
                       memmap=False) as scan:
            newtable = Table(scan[1].data)

            if newtable['FEBE'][0].strip() == 'EMPTY':
                newtable['FEBE'][0] = febe
            else:
                newtable.add_row([febe])

            new_hdu = fits.table_to_hdu(newtable)
            scan[1].data = new_hdu.data
            scanheader = scan[1].header
            scanheader['SITELONG'] = np.degrees(meta['SiteLongitude'])
            scanheader['SITELAT'] = np.degrees(meta['SiteLatitude'])
            scanheader['SITEELEV'] = meta['SiteHeight']
            diameter = 64. if meta['site'].lower().strip() == 'srt' else 32.
            scanheader['DIAMETER'] = diameter
            scanheader['PROJID'] = meta['Project_Name']

            scan.writeto('tmp.fits', overwrite=True)
        force_move_file('tmp.fits', os.path.join(self.dirname, self.SCAN))

        return febe_name
示例#4
0
    def add_subscan(self, scanfile, detrend=False):
        print('Loading {}'.format(scanfile))

        subscan = read_data_fitszilla(scanfile)
        subscan_info = get_subscan_info(subscan)

        self.scan_info.add_row(subscan_info[0])

        time = Time(subscan['time'] * u.day, scale='utc', format='mjd')
        if self.date_obs.mjd > time[0].mjd:
            self.date_obs = time[0]
        if self.site is None:
            self.site = subscan.meta['site']

        chans = get_chan_columns(subscan)

        combinations = classify_chan_columns(chans)

        if self.nfeeds is None:
            self.nfeeds = len(combinations.keys())

        for feed in combinations:
            felabel = subscan.meta['receiver'] + '{}'.format(feed)
            febe = felabel + '-' + subscan.meta['backend']

            datapar = os.path.join(self.template_dir, '1',
                                   'FLASH460L-XFFTS-DATAPAR.fits')
            with fits.open(datapar, memmap=False) as subs_par_template:
                n = len(subscan)
                # ------------- Update DATAPAR --------------
                subs_par_template[1] = \
                    _copy_hdu_and_adapt_length(subs_par_template[1], n)

                newtable = Table(subs_par_template[1].data)
                newtable['MJD'] = subscan['time']
                newtable['LST'][:] = \
                    time.sidereal_time('apparent',
                                       locations[subscan.meta['site']].lon
                                       ).value
                if newtable['LST'][0] < self.lst:
                    self.lst = newtable['LST'][0]
                newtable['INTEGTIM'][:] = \
                    subscan['Feed0_LCP'].meta['sample_rate']
                newtable['RA'] = subscan['ra'].to(u.deg)
                newtable['DEC'] = subscan['dec'].to(u.deg)
                newtable['AZIMUTH'] = subscan['az'].to(u.deg)
                newtable['ELEVATIO'] = subscan['el'].to(u.deg)
                _, direction = scantype(subscan['ra'], subscan['dec'],
                                        el=subscan['el'], az=subscan['az'])

                direction_cut = \
                    direction.replace('<', '').replace('>', '').lower()
                if direction_cut in ['ra', 'dec']:
                    baslon = subscan['ra'].to(u.deg)
                    baslat = subscan['dec'].to(u.deg)

                    yoff = baslat.value - self.dec
                    # GLS projection
                    xoff = \
                        (baslon.value - self.ra)
                    newtable['LONGOFF'] = xoff * np.cos(np.radians(self.dec))
                    newtable['LATOFF'] = yoff
                elif direction_cut in ['el', 'az']:
                    warnings.warn('AltAz projection not implemented properly')
                    baslon, baslat = \
                        subscan['az'].to(u.deg), subscan['el'].to(u.deg)
                    newtable['LONGOFF'] = 0 * u.deg
                    newtable['LATOFF'] = 0 * u.deg
                else:
                    raise ValueError('Unknown coordinates')

                newtable['CBASLONG'] = baslon
                newtable['CBASLAT'] = baslat
                newtable['BASLONG'] = baslon
                newtable['BASLAT'] = baslat

                newhdu = fits.table_to_hdu(newtable)
                subs_par_template[1].data = newhdu.data
                subs_par_template[1].header['DATE-OBS'] = \
                    time[0].fits.replace('(UTC)', '')
                subs_par_template[1].header['LST'] = newtable['LST'][0]
                subs_par_template[1].header['FEBE'] = febe
                subs_par_template[1].header['SCANDIR'] = \
                    format_direction(direction_cut).upper()
                subs_par_template[1].header['SCANNUM'] = self.obsid

                outdir = str(subscan.meta['SubScanID'])
                mkdir_p(os.path.join(self.dirname, outdir))
                new_datapar = os.path.join(outdir,
                                           febe + '-DATAPAR.fits')
                subs_par_template.writeto('tmp.fits', overwrite=True)

            force_move_file('tmp.fits',
                            os.path.join(self.dirname, new_datapar))

            arraydata = os.path.join(self.template_dir, '1',
                                     'FLASH460L-XFFTS-ARRAYDATA-1.fits')

            new_arraydata_rows = []
            bands = list(combinations[feed].keys())
            for baseband in combinations[feed]:
                nbands = np.max(bands)
                ch = list(combinations[feed][baseband].values())[0]

                packed_data = pack_data(subscan, combinations[feed][baseband],
                                        detrend=detrend)
                # ------------- Update ARRAYDATA -------------
                with fits.open(arraydata, memmap=False) as subs_template:
                    subs_template[1] = \
                        _copy_hdu_and_adapt_length(subs_template[1], n)

                    new_header = \
                        reset_all_keywords(subs_template[1].header)

                    new_header['SCANNUM'] = self.obsid
                    new_header['SUBSNUM'] = subscan.meta['SubScanID']
                    new_header['DATE-OBS'] = self.date_obs.fits
                    new_header['FEBE'] = febe
                    new_header['BASEBAND'] = baseband
                    new_header['NUSEBAND'] = nbands
                    new_header['CHANNELS'] = subscan.meta['channels']
                    new_header['SKYFREQ'] = \
                        subscan[ch].meta['frequency'].to('Hz').value
                    if self.restfreq is not None:
                        new_header['RESTFREQ'] = self.restfreq
                    else:
                        new_header['RESTFREQ'] = new_header['SKYFREQ']
                    bandwidth = subscan[ch].meta['bandwidth'].to('Hz').value
                    new_header['BANDWID'] = bandwidth

                    new_header['FREQRES'] = bandwidth / new_header['CHANNELS']

                    # Todo: check sideband
                    new_header['SIDEBAND'] = 'USB'
                    # Todo: check all these strange keywords. These are
                    # probably NOT the rest frequencies!
                    new_header['1CRVL2F'] = new_header['RESTFREQ']
                    new_header['1CRVL2S'] = new_header['RESTFREQ']
                    for i in ['1CRPX2S', '1CRPX2R', '1CRPX2F', '1CRPX2J']:
                        new_header[i] = (new_header['CHANNELS'] + 1) // 2

                    subs_template[1].header = new_header
                    newtable = Table(subs_template[1].data)
                    newtable['MJD'] = subscan['time']
                    newtable['DATA'] = packed_data
                    newhdu = fits.table_to_hdu(newtable)
                    subs_template[1].data = newhdu.data

                    subname = febe + '-ARRAYDATA-{}.fits'.format(baseband)
                    new_sub = \
                        os.path.join(outdir, subname)
                    subs_template.writeto('tmp.fits', overwrite=True)

                    new_arraydata_rows.append([2, new_sub, 'URL',
                                               'ARRAYDATA-MBFITS',
                                               subscan.meta['SubScanID'], febe,
                                               baseband])

                force_move_file('tmp.fits',
                                os.path.join(self.dirname, new_sub))

            # Finally, update GROUPING file
            with fits.open(os.path.join(self.dirname,
                                        self.GROUPING),
                           memmap=False) as grouping:
                newtable = Table(grouping[1].data)
                if febe not in self.FEBE:

                    nfebe = len(list(self.FEBE.keys()))
                    new_febe = self.add_febe(febe, combinations, feed,
                                             subscan[ch].meta,
                                             bands=bands)

                    grouping[0].header['FEBE{}'.format(nfebe)] = febe
                    grouping[0].header['FREQ{}'.format(nfebe)] = \
                        subscan[ch].meta['frequency'].to('Hz').value
                    grouping[0].header['BWID{}'.format(nfebe)] = \
                        subscan[ch].meta['bandwidth'].to('Hz').value
                    grouping[0].header['LINE{}'.format(nfebe)] = ''

                    newtable.add_row([2, new_febe, 'URL', 'FEBEPAR-MBFITS',
                                      -999, febe, -999])
                    self.FEBE[febe] = new_febe

                newtable.add_row([2, new_datapar, 'URL', 'DATAPAR-MBFITS',
                                  -999, febe, -999])

                for row in new_arraydata_rows:
                    newtable.add_row(row)
                new_hdu = fits.table_to_hdu(newtable)
                grouping[1].data = new_hdu.data
                grouping[0].header['INSTRUME'] = subscan[ch].meta['backend']
                grouping[0].header['TELESCOP'] = self.site

                grouping.writeto('tmp.fits', overwrite=True)

            force_move_file('tmp.fits',
                            os.path.join(self.dirname, self.GROUPING))

            if self.test:
                break