def get_observing_frequency(vis): """ Read observing frequency (REF_FREQUENCY) Return frequency value in Hz as a dictionary of {data_desc_id: frequency} """ assert os.path.exists(vis) spectralwindow_table = os.path.join(vis, 'SPECTRAL_WINDOW') assert os.path.exists(spectralwindow_table) with casa.OpenTableForRead(spectralwindow_table) as tb: ref_frequency = tb.getcol('REF_FREQUENCY') datadescription_table = os.path.join(vis, 'DATA_DESCRIPTION') assert os.path.exists(datadescription_table) with casa.OpenTableForRead(datadescription_table) as tb: ddid_map = tb.getcol('SPECTRAL_WINDOW_ID') observing_frequency = {} for (ddid, spwid) in enumerate(ddid_map): if spwid >= 0 and spwid < len(ref_frequency): observing_frequency[ddid] = ref_frequency[spwid] return observing_frequency
def setUp(self): print('setUp: copying {0}...'.format(self.vis)) shutil.copytree(os.path.join(self.datapath, self.vis), self.vis) self.assertTrue(os.path.exists(self.vis)) with casa.OpenTableForRead(os.path.join(self.vis, 'DATA_DESCRIPTION')) as tb: spw_ids = tb.getcol('SPECTRAL_WINDOW_ID') pol_ids = tb.getcol('POLARIZATION_ID') with casa.OpenTableForRead(os.path.join(self.vis, 'SPECTRAL_WINDOW')) as tb: num_chans = tb.getcol('NUM_CHAN') with casa.OpenTableForRead(os.path.join(self.vis, 'POLARIZATION')) as tb: num_corrs = tb.getcol('NUM_CORR') self.nchanmap = dict((( i, num_chans[spw_ids[i]], ) for i in range(len(spw_ids)))) self.ncorrmap = dict((( i, num_corrs[pol_ids[i]], ) for i in range(len(pol_ids))))
def _test_lsr_freq(self, mfr='TOPO'): chunk = {} ndds = len(self.dd_spw_map) with casa.OpenTableForRead(os.path.join(self.vis, 'FIELD')) as tb: nfields = tb.nrows() with casa.OpenTableForReadWrite( os.path.join(self.vis, 'SPECTRAL_WINDOW')) as tb: mfrs = tb.getcol('MEAS_FREQ_REF') self.assertTrue( mfr in visconverter.VisibilityConverter.frequency_reference) mfr_id = visconverter.VisibilityConverter.frequency_reference.index( mfr) if not numpy.all(mfrs == mfr_id): mfrs[:] = mfr_id tb.putcol('MEAS_FREQ_REF', mfrs) visparam = paramcontainer.VisParamContainer(vis=self.vis) imageparam = paramcontainer.ImageParamContainer( imagename=self.imagename, phasecenter=str(self.field_id)) converter = visconverter.VisibilityConverter(visparam, imageparam) nchunk = 1 chunk['time'] = numpy.empty(nchunk, dtype=numpy.float64) chunk['data_desc_id'] = numpy.empty(nchunk, dtype=numpy.int32) chunk['field_id'] = numpy.empty_like(chunk['data_desc_id']) with casa.OpenTableForRead(self.vis) as tb: chunk['time'][:] = tb.getcell('TIME', 0) for field_id in range(nfields): chunk['field_id'][0] = field_id for dd_id in range(ndds): chunk['data_desc_id'][0] = dd_id lsr_freq = converter.get_lsr_frequency(chunk) #print lsr_freq spw_id = self.dd_spw_map[dd_id] nchan = self.nchans[spw_id] self.assertEqual(nchan + 1, len(lsr_freq)) self.assertEqual(mfrs[spw_id], mfr_id) # special case for LSRK with casa.OpenTableForRead( os.path.join(self.vis, 'SPECTRAL_WINDOW')) as tb: chan_freq = tb.getcell('CHAN_FREQ', spw_id) chan_width = tb.getcell('CHAN_WIDTH', spw_id) expected = numpy.empty(nchan + 1, dtype=numpy.float64) expected[:-1] = chan_freq - chan_width / 2.0 expected[-1] = chan_freq[-1] + chan_width[-1] / 2.0 if mfr == 'LSRK': self.assertTrue(numpy.all(lsr_freq == expected)) else: expected = self._convert(chunk['time'][0], field_id, mfr, expected) self.assertMaxDiffLess(expected, lsr_freq, 1e-15)
def get_antenna_diameter(vis): """ Read antenna diameter (DISH_DIAMETER) Return antenna diameter in m """ assert os.path.exists(vis) antenna_table = os.path.join(vis, 'ANTENNA') assert os.path.exists(antenna_table) with casa.OpenTableForRead(antenna_table) as tb: antenna_diameter = tb.getcol('DISH_DIAMETER') return antenna_diameter
def setUp(self): print('setUp: copying {0}...'.format(self.vis)) shutil.copytree(os.path.join(self.datapath, self.vis), self.vis) self.assertTrue(os.path.exists(self.vis)) with casa.OpenTableForRead(os.path.join(self.vis, 'DATA_DESCRIPTION')) as tb: self.dd_spw_map = tb.getcol('SPECTRAL_WINDOW_ID') self.dd_pol_map = tb.getcol('POLARIZATION_ID') with casa.OpenTableForRead(os.path.join(self.vis, 'SPECTRAL_WINDOW')) as tb: self.nchans = tb.getcol('NUM_CHAN') with casa.OpenTableForRead(os.path.join(self.vis, 'POLARIZATION')) as tb: self.npols = tb.getcol('NUM_CORR') # avaliable FIELD_ID in MAIN table is only 6 self.field_id = 6 # default visparam self.visparam = paramcontainer.VisParamContainer(vis=self.vis)
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
def test_freq_map(self): # create data chunk nrow = 1 dd_id = 0 spw_id = self.dd_spw_map[dd_id] pol_id = self.dd_pol_map[dd_id] nchan = self.nchans[spw_id] npol = self.npols[pol_id] chunk = self.get_chunk_template(nrow=nrow, dd_id=dd_id) # create converter timestamp = chunk['time'][0] field_id = self.field_id mfr = 'TOPO' spw_id = self.dd_spw_map[dd_id] with casa.OpenTableForRead(os.path.join(self.vis, 'SPECTRAL_WINDOW')) as tb: chan_freq = tb.getcell('CHAN_FREQ', spw_id) lsr_freq = self._convert(timestamp, field_id, mfr, chan_freq) # start channel and width are chosen so that first 10 visibility # channels are included image_nchan = 1 f = (lsr_freq[4] + lsr_freq[5]) / 2.0 image_start = '{0}Hz'.format(f) image_width = '{0}Hz'.format(lsr_freq[10] - lsr_freq[0]) converter = self.get_converter(start=image_start, width=image_width, nchan=image_nchan) # uvw from expected pixel value expected_u = 0 expected_v = 0 self._uv_from_pixel(expected_u, expected_v, chunk['uvw'][:, 0], lsr_freq) # conversion ws = converter.generate_working_set(chunk) rdata = ws.rdata data_shape = rdata.shape # consistency check self.verify_ws_consistency(ws, chunk['chunk_id']) expected_shape = (nrow, 1, 10) self.assertEqual(data_shape, expected_shape) start = 0 end = start + image_nchan * 10 expected_data = numpy.zeros(expected_shape, dtype=numpy.complex) expected_flag = numpy.ones(expected_shape, dtype=numpy.bool) for ipol in range(npol): expected_data += (chunk['data'][ipol:ipol + 1, start:end, :] \ * numpy.where(chunk['flag'][ipol:ipol + 1, start:end, :] == False, 0.5, 0.0)).transpose((2, 0, 1)) expected_flag = numpy.logical_and( expected_flag, chunk['flag'][ipol:ipol + 1, start:end, :]) eps = 1e-7 self.assertMaxDiffLess(expected_data.real, ws.rdata, eps) self.assertMaxDiffLess(expected_data.imag, ws.idata, eps) self.assertTrue(numpy.all(numpy.logical_not(expected_flag) == ws.flag)) for ichan in range(image_nchan): s = ichan * 10 e = s + 10 self.assertTrue(numpy.all(ws.channel_map[s:e] == ichan)) # uv test # u,v should ideally be zero but allow small value within # the one indicated by tolerance, eps eps = 1.0e-5 self.assertLess(abs(ws.u[0]), eps) self.assertLess(abs(ws.v[0]), eps)
def test_freq_interp(self): # create data chunk nrow = 1 dd_id = 0 spw_id = self.dd_spw_map[dd_id] pol_id = self.dd_pol_map[dd_id] nchan = self.nchans[spw_id] npol = self.npols[pol_id] chunk = self.get_chunk_template(nrow=nrow, dd_id=dd_id) # create converter timestamp = chunk['time'][0] field_id = self.field_id mfr = 'TOPO' spw_id = self.dd_spw_map[dd_id] with casa.OpenTableForRead(os.path.join(self.vis, 'SPECTRAL_WINDOW')) as tb: chan_freq = tb.getcell('CHAN_FREQ', spw_id) lsr_freq = self._convert(timestamp, field_id, mfr, chan_freq) # start channel is lsr frequency that corresponds to 1/3 of first channel # channel width is native one image_nchan = 1 f = lsr_freq[0] + (lsr_freq[1] - lsr_freq[0]) / 3.0 image_start = '{0}Hz'.format(f) image_width = '{0}Hz'.format(lsr_freq[1] - lsr_freq[0]) converter = self.get_converter(start=image_start, width=image_width, nchan=image_nchan) # uvw from expected pixel value expected_u = 70 expected_v = 25 self._uv_from_pixel(expected_u, expected_v, chunk['uvw'][:, 0], lsr_freq) # conversion ws = converter.generate_working_set(chunk) rdata = ws.rdata data_shape = rdata.shape # consistency check self.verify_ws_consistency(ws, chunk['chunk_id']) expected_shape = (1, image_nchan, nrow) self.assertEqual(data_shape, expected_shape) print('LOG: rdata={0}'.format(ws.rdata)) print('LOG: idata={0}'.format(ws.idata)) print('LOG: chunk data0 {0} 1 {1}'.format(chunk['data'][:, 0, 0], chunk['data'][:, 1, 0])) d0 = chunk['data'][:, 0, 0] d1 = chunk['data'][:, 1, 0] base_data = (2.0 * d0 + 1.0 * d1) / 3.0 f0 = chunk['flag'][:, 0, 0] f1 = chunk['flag'][:, 0, 0] base_flag = f0 expected_data = numpy.zeros(expected_shape, dtype=numpy.complex) expected_flag = numpy.ones(expected_shape, dtype=numpy.bool) eps = 1e-5 for ipol in range(npol): if base_flag[ipol] == False: expected_data += 0.5 * base_data[ipol] expected_flag = numpy.logical_and(expected_flag, base_flag[ipol]) self.assertMaxDiffLess(expected_data.real, ws.rdata[0, 0, 0], eps) self.assertMaxDiffLess(expected_data.imag, ws.idata[0, 0, 0], eps) ref = numpy.logical_not(expected_flag) val = ws.flag[0, 0, 0] self.assertEqual(ref, val) self.assertEqual(ws.channel_map[0], 0) # TODO: uv test print(expected_u, ws.u[0]) print(expected_v, ws.v[0]) eps = 1.0e-5 self.assertMaxDiffLess(expected_u, ws.u[0], eps) self.assertMaxDiffLess(expected_v, ws.v[0], eps)
def test_channel_interp(self): # create data chunk nrow = 1 dd_id = 0 spw_id = self.dd_spw_map[dd_id] pol_id = self.dd_pol_map[dd_id] nchan = self.nchans[spw_id] npol = self.npols[pol_id] chunk = self.get_chunk_template(nrow=nrow, dd_id=dd_id) # here UVW is set to 0 # this should not happen in interferometry observation # but just for testing purpose... chunk['uvw'][:] = 0.0 # timestamp should be start time of the observation # for LSRK conversion with casa.OpenTableForRead(os.path.join(self.vis, 'OBSERVATION')) as tb: time_range = tb.getcell('TIME_RANGE', 0) chunk['time'][:] = time_range[0] # create converter image_nchan = 1 image_start = 0 image_width = 1 converter = self.get_converter(start=image_start, width=image_width, nchan=image_nchan) ws = converter.generate_working_set(chunk) rdata = ws.rdata data_shape = rdata.shape # consistency check self.verify_ws_consistency(ws, chunk['chunk_id']) expected_shape = (1, image_nchan * image_width, nrow) self.assertEqual(data_shape, expected_shape) d0 = chunk['data'][:, 0, 0] f0 = chunk['flag'][:, 0, 0] base_data = d0 base_flag = f0 expected_data = numpy.complex(0) expected_flag = True eps = 1e-5 for ipol in range(npol): if base_flag[ipol] == False: expected_data += 0.5 * base_data[ipol] expected_flag = numpy.logical_and(expected_flag, base_flag[ipol]) self.assertMaxDiffLess(expected_data.real, ws.rdata[0, 0, 0], eps) self.assertMaxDiffLess(expected_data.imag, ws.idata[0, 0, 0], eps) ref = numpy.logical_not(expected_flag) val = ws.flag[0, 0, 0] self.assertEqual(ref, val) self.assertEqual(ws.channel_map[0], 0) # (u,v) = (0,0) maps onto (nearly) grid plane center self.assertTrue(ws.u[0] == int(self.imageparam.imsize[0]) // 2) self.assertTrue(ws.v[0] == int(self.imageparam.imsize[1]) // 2)
def inspect_data(self): """ Inspect data given as a field 'vis' in visparam. """ vis = self.visparam.vis # make mapping between DATA_DESC_ID and SPECTRAL_WINDOW_ID/POLARIZATION_ID with casa.OpenTableForRead(os.path.join(vis, 'DATA_DESCRIPTION')) as tb: self.dd_spw_map = tb.getcol('SPECTRAL_WINDOW_ID') self.dd_pol_map = tb.getcol('POLARIZATION_ID') # read spw information (channel freq, channel width, freq_ref) with casa.OpenTableForRead(os.path.join(vis, 'SPECTRAL_WINDOW')) as tb: meas_freq_ref = tb.getcol('MEAS_FREQ_REF') self.chan_freq = {} self.chan_width = {} self.freq_ref = {} for irow in range(tb.nrows()): self.freq_ref[irow] = self.freq_ref_string(meas_freq_ref[irow]) self.chan_freq[irow] = tb.getcell('CHAN_FREQ', irow) self.chan_width[irow] = tb.getcell('CHAN_WIDTH', irow) # read field information with casa.OpenTableForRead(os.path.join(vis, 'FIELD')) as tb: self.field_dir = {} measinfo = tb.getcolkeyword('PHASE_DIR', 'MEASINFO') if 'Ref' in measinfo: self.field_ref = measinfo['Ref'] else: # variable reference column, assume J2000 self.field_ref = 'J2000' for irow in range(tb.nrows()): self.field_dir[irow] = tb.getcell('PHASE_DIR', irow) all_fields = numpy.arange(tb.nrows(), dtype=numpy.int) # nominal image LSRK frequency (will be used for channel selection) # calculate based on # - ALMA observatory position # - nominal field direction (one of the TARGET) # - observation start time (from OBSERVATION table?) # observation start time with casa.OpenTableForRead(os.path.join(vis, 'OBSERVATION')) as tb: time_range = tb.getcell('TIME_RANGE', 0) obs_start_time = time_range[0] # field id with casa.OpenMSMetaData(vis) as msmd: try: #field_ids = msmd.fieldsforintent(intent='OBSERVE_TARGET#ON_SOURCE*') field_ids = msmd.fieldsforintent(intent=self.visparam.intent) if len(field_ids) == 0: field_ids = all_fields except Exception: field_ids = all_fields #nominal_field_id = field_ids[0] # data description id data_desc_ids = numpy.arange(len(self.dd_spw_map)) _times = numpy.empty(len(data_desc_ids), dtype=numpy.float64) _times[:] = obs_start_time _field_ids = numpy.empty_like(data_desc_ids) self.nominal_lsr_frequency = {} for field_id in field_ids: _field_ids[:] = field_id cf = self._get_lsr_frequency(_times, data_desc_ids, _field_ids) self.nominal_lsr_frequency[field_id] = cf
def frequency_setup_for_spw(vis, spw_id, chan): with casa.OpenTableForRead(os.path.join(vis, 'SPECTRAL_WINDOW')) as tb: chan_freq = tb.getcell('CHAN_FREQ', spw_id) chan_width = tb.getcell('CHAN_WIDTH', spw_id) return '{0:16.12f}Hz'.format(chan_freq[chan]), '{0:16.12f}Hz'.format( chan_width[chan])