Ejemplo n.º 1
0
    def test_phasecenter(self):
        phasecenter_str = '15:30:0 -10.30.00 J2000'
        phasecenter_rec = imagewriter.parse_phasecenter(phasecenter_str)
        self.result = phasecenter_rec
        lonstr, latstr, ref = phasecenter_str.split()
        qa = casa.CreateCasaQuantity()
        me = casa.CreateCasaMeasure()

        lon = qa.convert(qa.quantity(lonstr), 'rad')
        # to make value in ranges [-pi, pi]
        pi = qa.constants('pi')['value']
        lon['value'] = (lon['value'] + pi) % (2 * pi) - pi
        lat = qa.quantity(latstr)

        print(lon)
        print(lat)
        print(phasecenter_str)

        self.assertEqual(me.gettype(phasecenter_rec), 'Direction')
        self.assertEqual(me.getref(phasecenter_rec), ref)
        phasecenter_value = me.getvalue(phasecenter_rec)
        actual_lon = qa.convert(phasecenter_rec['m0'], 'rad')['value']
        expected_lon = qa.convert(lon, 'rad')['value']
        diff = abs((actual_lon - expected_lon) / expected_lon)
        eps = 1.0e-15
        self.assertLess(diff, eps)
        self.assertTrue(qa.eq(lat, phasecenter_value['m1']))
Ejemplo n.º 2
0
    def _get_lsr_frequency(self, times, data_desc_ids, field_ids):
        # sanity check
        # - consistency of chunk data length
        assert len(times) == len(data_desc_ids)
        assert len(times) == len(field_ids)

        me = casa.CreateCasaMeasure()
        qa = casa.CreateCasaQuantity()
        # position measure -- observatory position of ALMA
        me.doframe(me.observatory('ALMA'))

        nchunk = len(times)

        lsr_frequency = {}
        lsr_width = {}
        for i in range(nchunk):
            ddid = data_desc_ids[i]
            field_id = field_ids[i]
            spwid = self.dd_spw_map[ddid]
            freq_ref = self.freq_ref[spwid]
            chan_freq = self.chan_freq[spwid]
            chan_width = self.chan_width[spwid]
            nchan = len(chan_freq)
            lsr_freq_edge = numpy.empty(nchan + 1, dtype=numpy.float64)
            lsr_freq_edge[:nchan] = chan_freq - chan_width / 2.0
            lsr_freq_edge[nchan] = chan_freq[-1] + chan_width[-1] / 2.0
            if freq_ref == 'LSRK':
                # frequency is in LSRK, no conversion is needed
                pass
            else:
                # require conversion to LSRK
                # time measure
                epoch = qa.quantity(times[i], 's')
                mepoch = me.epoch('utc', epoch)
                me.doframe(mepoch)
                # direction measure
                field_dir = self.field_dir[field_id][:, 0]
                lon = qa.quantity(field_dir[0], 'rad')
                lat = qa.quantity(field_dir[1], 'rad')
                mdirection = me.direction(self.field_ref, lon, lat)
                me.doframe(mdirection)
                # frequency measure
                frequency = qa.quantity(0.0, 'Hz')
                mfrequency = me.frequency(freq_ref, frequency)
                for ichan in range(nchan):
                    mfrequency['m0']['value'] = lsr_freq_edge[
                        ichan]  #chan_freq[ichan] - 0.5 * chan_width[ichan]
                    #print 'LOG mfrequency = {0}'.format(mfrequency)
                    # convert
                    converted = me.measure(mfrequency, 'LSRK')
                    lsr_freq_edge[ichan] = converted['m0']['value']
                mfrequency['m0']['value'] = lsr_freq_edge[
                    nchan]  #chan_freq[nchan-1] + 0.5 * chan_width[nchan-1]
                converted = me.measure(mfrequency, 'LSRK')
                lsr_freq_edge[nchan] = converted['m0']['value']
            lsr_frequency[i] = lsr_freq_edge
            #print 'LOG    native = {0}'.format(chan_freq)
            #print 'LOG converted = {0}'.format(lsr_frequency[i])
        #return lsr_frequency, lsr_width
        return lsr_frequency
Ejemplo n.º 3
0
def parse_phasecenter(phasecenter_str):
    qa = casa.CreateCasaQuantity()
    me = casa.CreateCasaMeasure()

    if len(phasecenter_str) == 0:
        # defualt value '0:0:0 0.0.0 J2000'
        lat = qa.quantity(0.0, 'rad')
        lon = qa.quantity(0.0, 'rad')
        ref = 'J2000'
    else:
        # expected format: "longitude latitude [ref]"
        s = phasecenter_str.split()
        ref = 'J2000'  # default reference is J2000
        if len(s) == 3:
            lat = qa.quantity(s[1])
            lon = qa.quantity(s[0])
            ref = s[2]
        elif len(s) == 2:
            lat = qa.quantity(s[1])
            lon = qa.quantity(s[0])
        else:
            raise ValueError(
                'Invalid phasecenter: "{0}"'.format(phasecenter_str))

    #print 'DEBUG rf={0} lon={1} lat={2}'.format(ref, lon, lat)
    direction = me.direction(rf=ref, v0=lon, v1=lat)
    return direction
Ejemplo n.º 4
0
 def width(self, value):
     qa = casa.CreateCasaQuantity()
     if isinstance(value, str):
         self._width = qa.quantity(value)
     elif isinstance(value, dict):
         self._width = value
     else:
         # should be numeric value that
         # are expected to be channel
         self._width = value
Ejemplo n.º 5
0
 def rest_frequency(self, value):
     qa = casa.CreateCasaQuantity()
     if isinstance(value, str):
         if len(value) > 0:
             self._rest_frequency = qa.quantity(value)
         else:
             self._rest_frequency = qa.quantity(1.0e9, 'Hz')
     elif isinstance(value, dict):
         self._rest_frequency = value
     else:
         # should be numeric
         self._rest_frequency = qa.quantity(value, 'Hz')
Ejemplo n.º 6
0
 def _uv_from_pixel(self, px, py, uvw, lsr_freq):
     qa = casa.CreateCasaQuantity()
     nx = self.imageparam.imsize[0]
     ny = self.imageparam.imsize[1]
     dx = qa.convert(self.imageparam.cell[0], 'rad')['value']
     dy = qa.convert(self.imageparam.cell[1], 'rad')['value']
     wx = nx * dx
     wy = ny * dy
     offx = int(nx) // 2
     offy = int(ny) // 2
     fcenter = (lsr_freq.min() + lsr_freq.max()) / 2.0
     c = qa.convert(qa.constants('c'), 'm/s')['value']
     lcenter = c / fcenter
     uvw[0] = lcenter * (px - offx) / wx
     uvw[1] = lcenter * (py - offy) / wy
Ejemplo n.º 7
0
 def phasecenter_string(self):
     value = ''
     me = casa.CreateCasaMeasure()
     if isinstance(self.phasecenter, str):
         value = self.phasecenter
     elif me.ismeasure(self.phasecenter):
         pdir = self.phasecenter
         qa = casa.CreateCasaQuantity()
         ra = qa.formxxx(pdir['m0'], 'hms', prec=8)
         dec = qa.formxxx(pdir['m1'], 'dms', prec=8)
         phase_direction = '{0} {1} {2}'.format(ra, dec, pdir['refer'])
         value = phase_direction
     else:
         value = str(self.phasecenter)
     return value
Ejemplo n.º 8
0
Archivo: util.py Proyecto: yTogg/priism
    def suggest_imaging_param(visparam):
        vis = visparam.vis
        msselect = visparam.as_msselection()

        with casa.OpenMS(vis) as ms:
            ms.msselect(msselect, onlyparse=False)
            data = ms.getdata(['uvw', 'data_desc_id', 'antenna1', 'antenna2'])
        uvw = data['uvw']
        ddid = data['data_desc_id']
        antenna1 = data['antenna1']
        antenna2 = data['antenna2']

        observing_frequency = ImageConfigurationHelper.get_observing_frequency(
            vis)
        antenna_diameter = ImageConfigurationHelper.get_antenna_diameter(vis)

        # maximum antenna primary beam size [arcsec]
        min_freq = min(observing_frequency.values()) * 1e-9  # Hz -> GHz
        min_diameter = min(antenna_diameter)
        primary_beam = ImageConfigurationHelper.calc_primary_beam(
            min_diameter, min_freq)

        qa = casa.CreateCasaQuantity()
        c = qa.convert(qa.constants('c'), 'm/s')['value']
        nrow = len(ddid)
        umax = 0.0
        vmax = 0.0
        for irow in range(nrow):
            f = observing_frequency[ddid[irow]]
            u = uvw[0, irow] / c * f
            v = uvw[1, irow] / c * f
            umax = max(umax, u)
            vmax = max(vmax, v)

        rad2arcsec = 180.0 / numpy.pi * 3600.0
        dl = 1.0 / (2 * umax) * rad2arcsec  # rad -> arcsec
        dm = 1.0 / (2 * vmax) * rad2arcsec  # rad -> arcsec

        M = int(numpy.ceil(primary_beam / dl)) + 12
        N = int(numpy.ceil(primary_beam / dm)) + 12

        suggested = {
            'cell': ['{}arcsec'.format(dl), '{}arcsec'.format(dm)],
            'imsize': [M, N]
        }

        return suggested
Ejemplo n.º 9
0
    def get_default_imageparam(self):
        qa = casa.CreateCasaQuantity()
        phasecenter = '9:00:00 -60.00.00 J2000'
        #phasecenter_rec = imagewriter.parse_phasecenter(phasecenter_str)
        start = qa.quantity('101GHz')
        width = qa.quantity('1MHz')
        nchan = 3
        imsize = [10, 9]
        cell = '1arcsec'
        imageparam = paramcontainer.ImageParamContainer(
            imagename=self.imagename,
            phasecenter=phasecenter,
            imsize=imsize,
            cell=cell,
            start=start,
            width=width,
            nchan=nchan,
            outframe='LSRK',
            stokes='I')

        return imageparam
Ejemplo n.º 10
0
 def _convert(self, timestamp, field_id, mfr, chan_freq):
     me = casa.CreateCasaMeasure()
     qa = casa.CreateCasaQuantity()
     vis = self.vis
     with casa.OpenTableForRead(os.path.join(vis, 'FIELD')) as tb:
         reference_dir = tb.getcell('PHASE_DIR', field_id)[:, 0]
         reference_frame = 'J2000'  # hard coded
     lon = qa.quantity(reference_dir[0], 'rad')
     lat = qa.quantity(reference_dir[1], 'rad')
     mdirection = me.direction(rf=reference_frame, v0=lon, v1=lat)
     mepoch = me.epoch(rf='UTC', v0=qa.quantity(timestamp, 's'))
     mposition = me.observatory('ALMA')
     me.doframe(mdirection)
     me.doframe(mepoch)
     me.doframe(mposition)
     lsr_freq = numpy.empty_like(chan_freq)
     for ichan in range(len(lsr_freq)):
         mfrequency = me.frequency(rf=mfr,
                                   v0=qa.quantity(chan_freq[ichan], 'Hz'))
         converted = me.measure(mfrequency, rf='LSRK')
         lsr_freq[ichan] = converted['m0']['value']
     return lsr_freq
Ejemplo n.º 11
0
 def uvgridconfig(self):
     if not hasattr(self, '_uvgridconfig'):
         qa = casa.CreateCasaQuantity()
         cellx = qa.quantity(self.cell[0])
         celly = qa.quantity(self.cell[1])
         nu = self.imsize[0]
         nv = self.imsize[1]
         wx = nu * qa.convert(cellx, 'rad')['value']
         wy = nv * qa.convert(celly, 'rad')['value']
         cellu = 1 / wx
         cellv = 1 / wy
         # offset must always be pixel center even if nu and/or nv
         # is even (which causes offset value to be non-integer)
         offsetu = int(nu) // 2  # make sure integer operation
         offsetv = int(nv) // 2  # make sure integer operation
         self._uvgridconfig = datacontainer.UVGridConfig(cellu=cellu,
                                                         cellv=cellv,
                                                         nu=nu,
                                                         nv=nv,
                                                         offsetu=offsetu,
                                                         offsetv=offsetv)
     return self._uvgridconfig
Ejemplo n.º 12
0
    def _run_test(self, imageparam, arr, imagemeta=None):
        qa = casa.CreateCasaQuantity()

        writer = imagewriter.ImageWriter(imageparam, arr, imagemeta)

        if imagemeta is None:
            # default image metadata
            imagemeta = paramcontainer.ImageMetaInfoContainer()

        status = writer.write(overwrite=True)

        self.assertTrue(status)
        self.assertTrue(os.path.exists(self.imagename))

        self.result = self.imagename

        ia = casa.CreateCasaImageAnalysis()
        ia.open(self.imagename)
        try:
            # image shape
            expected_shape = (imageparam.imsize[0], imageparam.imsize[1],
                              imageparam.nchan, 1)
            self.assertTrue(numpy.all(expected_shape == ia.shape()))
            csys = ia.coordsys()

            # direction coordinate
            dirref = csys.referencecode(type='direction')[0]
            self.assertEqual(dirref, 'J2000')
            refpix = self._get_reference(csys, 'referencepixel', 'direction')
            refval = self._get_reference(csys, 'referencevalue', 'direction')
            incr = self._get_reference(csys, 'increment', 'direction')

            self.assertEqual(len(refpix), 2)
            self.assertEqual(refpix[0], 0.5 * (imageparam.imsize[0] - 1))
            self.assertEqual(refpix[1], 0.5 * (imageparam.imsize[1] - 1))

            phasecenter_rec = imagewriter.parse_phasecenter(
                imageparam.phasecenter)
            center_x = qa.convert(phasecenter_rec['m0'], 'rad')['value']
            center_y = qa.convert(phasecenter_rec['m1'], 'rad')['value']
            #print center_x, center_y
            eps = 1.0e-11
            self.assertClose(refval[0], center_x, eps)
            self.assertClose(refval[1], center_y, eps)
            cellx = -qa.convert(qa.quantity(imageparam.cell[0]),
                                'rad')['value']
            celly = qa.convert(qa.quantity(imageparam.cell[1]), 'rad')['value']
            #print cellx, celly
            self.assertClose(incr[0], cellx, eps)
            self.assertClose(incr[1], celly, eps)

            # spectral coordinate
            specref = csys.referencecode(type='spectral')[0]
            self.assertEqual(specref, 'LSRK')
            refpix = self._get_reference(csys, 'referencepixel', 'spectral')
            refval = self._get_reference(csys, 'referencevalue', 'spectral')
            incr = self._get_reference(csys, 'increment', 'spectral')
            self.assertEqual(refpix, 0.0)
            #self.assertEqual(refval, qa.convert(start, 'Hz')['value'])
            #self.assertEqual(incr, qa.convert(width, 'Hz')['value'])
            self.assertEqual(refval,
                             qa.convert(imageparam.start, 'Hz')['value'])
            self.assertEqual(incr, qa.convert(imageparam.width, 'Hz')['value'])

            # stokes coordinate
            refpix = self._get_reference(csys, 'referencepixel', 'stokes')
            refval = self._get_reference(csys, 'referencevalue', 'stokes')
            incr = self._get_reference(csys, 'increment', 'stokes')
            self.assertEqual(refpix, 0.0)
            self.assertEqual(refval, 1.0)
            self.assertEqual(incr, 1.0)

            # verify image meta data
            self.assertEqual(csys.observer(), imagemeta.observer)
            self.assertEqual(csys.telescope(), imagemeta.telescope)
            self.assertTrue(
                qa.eq(csys.restfrequency(), imagemeta.rest_frequency))
            epoch = csys.epoch()
            obsdate = imagemeta.observing_date
            self.assertEqual(epoch['refer'], obsdate['refer'])
            self.assertClose(epoch['m0']['value'], obsdate['m0']['value'])

            # image data
            chunk = ia.getchunk()
            imageshape = chunk.shape
            self.assertEqual(imageshape, expected_shape)

            shaped_chunk = chunk[:, :, :, 0]
            print(shaped_chunk.shape, arr.shape)
            self.assertTrue(numpy.allclose(arr, shaped_chunk),
                            msg='expected {0} actual {1} (maxdiff {2})'.format(
                                arr, shaped_chunk,
                                abs(arr - shaped_chunk).max()))

        finally:
            ia.done()
Ejemplo n.º 13
0
    def fill_uvw(self, ws, chunk, lsr_edge_frequency):
        """
        Fill UV coordinate

        ws -- working set to be filled
        chunk -- input data chunk
        lsr_edge_frequency -- channel edge frequency (LSRK)
        """
        phasecenter = self.imageparam.phasecenter
        self._check_phasecenter(phasecenter)
        #self._warn_refocus()

        qa = casa.CreateCasaQuantity()
        speed_of_light = qa.constants('c')
        c = qa.convert(speed_of_light, 'm/s')['value']
        data_shape = chunk['data'].shape
        nrow = data_shape[2]
        nchan = data_shape[1]
        uvw = chunk['uvw']
        data_desc_ids = chunk['data_desc_id']
        uvgrid = self.imageparam.uvgridconfig
        delta_u = uvgrid.cellu
        delta_v = uvgrid.cellv
        offset_u = uvgrid.offsetu
        offset_v = uvgrid.offsetv

        # UVW conversion
        u = sakura.empty_aligned((nrow, nchan), dtype=uvw.dtype)
        v = sakura.empty_like_aligned(u)
        for irow in range(nrow):
            # TODO: phase rotation if image phasecenter is different from
            #       the reference direction of the observation
            pass

            # conversion from physical baseline length to the value
            # normalized by observing wavelength
            u0 = uvw[0, irow]
            v0 = uvw[1, irow]
            spw_id = data_desc_ids[irow]
            #chan_freq = lsr_frequency
            #chan_width = (lsr_edge_frequency[1:] - lsr_edge_frequency[:-1]).mean()
            #freq_start = chan_freq[0] - chan_width / 2
            #freq_end = chan_freq[-1] + chan_width / 2
            #freq_start = lsr_edge_frequency[0]
            #freq_end = lsr_edge_frequency[-1]
            #center_freq = (freq_start + freq_end) / 2
            center_freq = numpy.fromiter(
                (numpy.mean(lsr_edge_frequency[i:i + 2])
                 for i in range(nchan)),
                dtype=numpy.float64)
            u[irow] = u0 * center_freq / c  # divided by wavelength
            v[irow] = v0 * center_freq / c  # divided by wavelength

            # TODO?: refocus UVW if distance to the source is known
            pass

            # project uv-coordinate value onto gridding pixel plane
            # pixel size is determined by an inverse of image extent
            # along x (RA) and y (DEC) direction
            #
            #    v
            #     nv-1|(nmin,vmax)      (umax,vmax)
            #        .|
            #        .|
            #        .|
            #        .|
            #     nv/2|           (0,0)
            #        .|
            #        .|
            #        2|
            #        1|
            #        0|(umin,vmin)      (umax,vmin)
            #         |__________________________
            #          0 1 2 ......nu/2...nu-1 u
            u[irow] = u[irow] / delta_u + offset_u

            # Sign of v must be inverted so that MFISTA routine generates
            # proper image. Otherwise, image will be flipped in the vertical
            # axis.
            v[irow] = -v[irow] / delta_v + offset_v

        ws.u = u
        ws.v = v
Ejemplo n.º 14
0
    def fill_data(self, ws, chunk, lsr_edge_frequency):
        qa = casa.CreateCasaQuantity()

        lsr_frequency = (lsr_edge_frequency[1:] +
                         lsr_edge_frequency[:-1]) / 2.0

        # info from chunk
        field_id = chunk['field_id'][0]
        data_desc_id = chunk['data_desc_id'][0]

        # get spectral channel selection parameter
        start = self.imageparam.start
        width = self.imageparam.width
        nchan = self.imageparam.nchan
        npol = chunk['data'].shape[0]
        nrow = chunk['data'].shape[2]
        qstart = qa.quantity(start)
        qwidth = qa.quantity(width)
        qnchan = qa.quantity(nchan)
        start_unit = qa.getunit(qstart)
        width_unit = qa.getunit(qwidth)
        frequency_pattern = re.compile('^(G|k|M|T)?Hz$')
        wavelength_pattern = re.compile('^(k|c|m|n)?m$')
        velocity_pattern = re.compile(
            wavelength_pattern.pattern.replace('$', '/s$'))
        match_with = lambda pattern: pattern.match(start_unit) is not None and \
                                        pattern.match(width_unit) is not None

        image_freq = numpy.empty(nchan, dtype=numpy.float64)
        image_width = 0.0

        # get image LSRK frequency
        # start, width, and nchan are defined as follows:
        #
        #   start=<center frequency of first image channel>
        #     |
        # |-------|-------|-------| nchan=3
        # |<----->|
        #   width=<constant channel width of image channel>
        #
        if len(start_unit) == 0 and len(width_unit) == 0:
            # channel selection
            # use nominal LSRK frequency for image (channel boundary)
            nominal_lsr_frequency = self.nominal_lsr_frequency[field_id][
                data_desc_id]
            #nominal_lsr_width = self.nominal_lsr_width[field_id][data_desc_id]
            if nchan == 1 and width == -1:
                # this is special setting that maps all visibility channels into
                # single image channel
                image_freq[0] = (nominal_lsr_frequency[-1] +
                                 nominal_lsr_frequency[0]) / 2.0
                image_width = nominal_lsr_frequency[
                    -1] - nominal_lsr_frequency[0]
            else:
                for ichan in range(nchan):
                    # left boundary of start channel
                    channel_start = int(
                        qstart['value']) + ichan * int(qwidth['value'])
                    # right boundary of end channel
                    channel_end = channel_start + int(qwidth['value'])
                    # center frequency of the range
                    image_freq[ichan] = (
                        nominal_lsr_frequency[channel_start] +
                        nominal_lsr_frequency[channel_end]) / 2.0
                image_width = (nominal_lsr_frequency[1] - nominal_lsr_frequency[0]) \
                                * int(qwidth['value'])
        elif match_with(frequency_pattern):
            # frequency selection
            for ichan in range(nchan):
                image_freq[ichan] = qa.convert(
                    qa.add(qstart, qa.mul(qwidth, ichan)), 'Hz')['value']
            image_width = qa.convert(qwidth, 'Hz')['value']
        elif match_with(wavelength_pattern):
            # wavelength selection -- not supported yet
            raise NotImplementedError(
                'wavelength selection is not implemented yet')
        elif match_with(velocity_pattern):
            # velocity selection -- not supported yet
            raise NotImplementedError(
                'velocity selection is not implemented yet')
        else:
            # invalid or mixed selection
            raise ValueError(
                'image channel selection is invalid or not supported')

        # map/interpolate
        data_desc_ids = chunk['data_desc_id']
        nchunk = len(data_desc_ids)
        spwid = self.dd_spw_map[data_desc_id]
        chan_width = self.chan_width[spwid][0]

        # chunk holds WEIGHT column, which should store channelized weight,
        # 2 * df * dt (which equals 2 * EFFECTIVE_BW[0] * INTEVAL) so that
        # weight scaling factor is 1.0 by default
        weight_factor = 1.0
        #print 'LOG: SPW {0} chan_width * 2 = {1}, image_width = {2}'.format(
        #    spwid, chan_width * 2, image_width)
        if abs(image_width) < 1.99 * abs(chan_width):
            #print 'LOG: do interpolation'
            # interpolation
            # TODO: array shape (order) should be compatible with sakura gridding function
            ws_shape = (
                nrow,
                1,
                nchan,
            )
            ws_shape2 = (
                nrow,
                nchan,
            )
            real = sakura.empty_aligned(ws_shape, dtype=numpy.float32)
            imag = sakura.empty_aligned(ws_shape, dtype=numpy.float32)
            flag = sakura.empty_aligned(ws_shape, dtype=numpy.bool)
            weight = sakura.empty_aligned(ws_shape2, dtype=numpy.float32)
            row_flag = sakura.empty_aligned((nrow, ), dtype=numpy.bool)
            channel_map = sakura.empty_aligned((nchan, ), dtype=numpy.int32)
            channel_map[:] = numpy.arange(nchan, dtype=numpy.int32)

            # real, image: linear interpolation
            #print 'LOG: lsr_frequency length {0} real.shape {1}'.format(
            #    len(lsr_frequency), chunk['data'].shape)
            if chunk['data'].shape[1] > 1:
                data_interp = interpolate.interp1d(lsr_frequency,
                                                   chunk['data'],
                                                   kind='linear',
                                                   axis=1,
                                                   fill_value='extrapolate')
                _data = data_interp(image_freq)
                # flag: nearest interpolation
                flag_interp = interpolate.interp1d(lsr_frequency,
                                                   chunk['flag'],
                                                   kind='nearest',
                                                   axis=1,
                                                   fill_value='extrapolate')
                _flag = flag_interp(image_freq)
            else:
                _data = chunk['data']
                _flag = chunk['flag']

            _weight = chunk['weight']
            self._to_stokesI(_data, _flag, _weight, weight_factor, real, imag,
                             flag, weight)
        else:
            #print 'LOG: do channel mapping'
            # channel mapping
            # if chunk frequency for i goes into image frequency cell for k,
            # i maps into k
            image_freq_boundary = numpy.empty(nchan + 1, dtype=numpy.float64)
            image_freq_boundary[:-1] = image_freq - 0.5 * image_width
            image_freq_boundary[-1] = image_freq[-1] + 0.5 * image_width
            image_freq_min = image_freq_boundary.min()
            image_freq_max = image_freq_boundary.max()
            in_range = numpy.where(
                numpy.logical_and(image_freq_min <= lsr_frequency,
                                  lsr_frequency <= image_freq_max))[0]
            nvischan = len(in_range)
            # accumulate N channels improves weight factor by N
            weight_factor *= float(nvischan)
            # TODO: array shape (order) should be compatible with sakura gridding function
            ws_shape = (
                nrow,
                1,
                nvischan,
            )
            ws_shape2 = (
                nrow,
                nvischan,
            )
            real = sakura.empty_aligned(ws_shape, dtype=numpy.float32)
            imag = sakura.empty_aligned(ws_shape, dtype=numpy.float32)
            flag = sakura.empty_aligned(ws_shape, dtype=numpy.bool)
            weight = sakura.empty_aligned(ws_shape2, dtype=numpy.float32)
            row_flag = sakura.empty_aligned((nrow, ), dtype=numpy.bool)
            channel_map = sakura.empty_aligned((nvischan, ), dtype=numpy.int32)
            for ichan, chan_chunk in enumerate(in_range):
                # fill in channel_map
                f = lsr_frequency[chan_chunk]
                for chan_image in range(nchan):
                    b0 = image_freq_boundary[chan_image]
                    b1 = image_freq_boundary[chan_image + 1]
                    if b0 > b1:
                        tmp = b1
                        b1 = b0
                        b0 = tmp
                    if b0 <= f and f <= b1:
                        channel_map[ichan] = chan_image
                        break

                # fill in data
                _data = chunk['data'][:, chan_chunk:chan_chunk + 1, :]
                _flag = chunk['flag'][:, chan_chunk:chan_chunk + 1, :]
                _weight = chunk['weight']
                self._to_stokesI(_data, _flag, _weight, weight_factor,
                                 real[:, :, ichan:ichan + 1],
                                 imag[:, :,
                                      ichan:ichan + 1], flag[:, :,
                                                             ichan:ichan + 1],
                                 weight[:, ichan:ichan + 1])

        # row_flag
        row_flag[:] = numpy.all(flag == True, axis=(
            1,
            2,
        ))

        # invert flag
        # reader definition:
        #     True: INVALID
        #     False: *VALID*
        # working set definition:
        #     True: *VALID*
        #     False: INVALID
        numpy.logical_not(row_flag, row_flag)
        numpy.logical_not(flag, flag)

        ws.rdata = real
        ws.idata = imag
        ws.flag = flag
        ws.row_flag = row_flag
        ws.weight = weight
        ws.channel_map = channel_map
Ejemplo n.º 15
0
    def _setup_coordsys(self):
        csys = casa.CreateCasaCoordSys()
        me = casa.CreateCasaMeasure()
        qa = casa.CreateCasaQuantity()

        c = csys.newcoordsys(direction=True,
                             spectral=True,
                             stokes=self.imageparam.stokes)

        # direction coordinate
        phasecenter = self.imageparam.phasecenter
        print('DEBUG phasecenter={0}'.format(phasecenter))
        refframe = me.getref(phasecenter)
        refpix = [int(x) // 2 for x in self.imageparam.imsize]
        center = me.getvalue(phasecenter)
        refval = [center['m0']['value'], center['m1']['value']]
        q2s = lambda x: '{0} {1}'.format(x['value'], x['unit'])
        srefval = list(map(q2s, [center['m0'], center['m1']]))
        incr = list(map(qa.quantity, self.imageparam.cell))
        # increment of horizontal axis should be negative
        incr[0] = qa.mul(-1.0, incr[0])
        sincr = list(map(q2s, incr))
        projection = self.imageparam.projection
        print('DEBUG refpix={0}, refval={1}'.format(refpix, refval))
        c.setdirection(refcode=refframe,
                       proj=projection,
                       refpix=refpix,
                       refval=srefval,
                       incr=sincr)

        # spectral coordinate
        refframe = 'LSRK'
        print('start {0} width {1}'.format(self.imageparam.start,
                                           self.imageparam.width))
        start = qa.convert(self.imageparam.start, 'Hz')
        width = qa.convert(self.imageparam.width, 'Hz')
        nchan = self.imageparam.nchan
        f = numpy.fromiter(
            (start['value'] + i * width['value'] for i in range(nchan)),
            dtype=numpy.float64)
        print('f = {0}'.format(f))
        frequencies = qa.quantity(f, 'Hz')
        veldef = 'radio'
        if len(f) > 1:
            c.setspectral(refcode=refframe,
                          frequencies=frequencies,
                          doppler=veldef)
        else:
            print('set increment for spectral axis: {0}'.format(width))
            #c.setreferencepixel(value=0, type='spectral')
            #c.setreferencevalue(value=start, type='spectral')
            #c.setincrement(value=width, type='spectral')
            r = c.torecord()
            if 'spectral2' in r:
                key = 'spectral2'
            elif 'spectral1' in r:
                key = 'spectral1'
            r[key]['wcs']['crpix'] = 0.0
            r[key]['wcs']['crval'] = start['value']
            r[key]['wcs']['cdelt'] = width['value']
            c.fromrecord(r)

        # Stokes coordinate
        # currently only 'I' image is supported
        #c.setstokes('I')
        #c.setincrement(value=1, type='stokes')

        # Meta info
        c.setobserver(self.imagemeta.observer)
        c.settelescope(self.imagemeta.telescope)
        c.setepoch(self.imagemeta.observing_date)
        rest_frequency = self.imagemeta.rest_frequency
        if isinstance(rest_frequency, str) and len(rest_frequency) == 0:
            f = frequencies['value']
            nchan = len(f)
            if nchan % 2 == 0:
                c1 = (nchan - 1) // 2
                c2 = c1 + 1
                rest_frequency = qa.quantity(0.5 * (f[c1] + f[c2]),
                                             frequencies['unit'])
            else:
                c1 = (nchan - 1) // 2
                rest_frequency = qa.quantity(f[c1], frequencies['unit'])

        print('rest_frequency={0}'.format(rest_frequency))
        c.setrestfrequency(rest_frequency)

        print(c.summary(list=False)[0])

        return c