def create_test_image( canonical=True, cellsize=None, frequency=None, channel_bandwidth=None, phasecentre=None, polarisation_frame=PolarisationFrame("stokesI")) -> Image: """Create a useful test image This is the test image M31 widely used in ALMA and other simulations. It is actually part of an Halpha region in M31. :param canonical: Make the image into a 4 dimensional image :param cellsize: :param frequency: Frequency (array) in Hz :param channel_bandwidth: Channel bandwidth (array) in Hz :param phasecentre: Phase centre of image (SkyCoord) :param polarisation_frame: Polarisation frame :return: Image """ check_data_directory() if frequency is None: frequency = [1e8] im = import_image_from_fits(rascil_path("data/models/M31.MOD")) if canonical: if polarisation_frame is None: im.polarisation_frame = PolarisationFrame("stokesI") elif isinstance(polarisation_frame, PolarisationFrame): im.polarisation_frame = polarisation_frame else: raise ValueError("polarisation_frame is not valid") im = replicate_image(im, frequency=frequency, polarisation_frame=im.polarisation_frame) if cellsize is not None: im.wcs.wcs.cdelt[0] = -180.0 * cellsize / numpy.pi im.wcs.wcs.cdelt[1] = +180.0 * cellsize / numpy.pi if frequency is not None: im.wcs.wcs.crval[3] = frequency[0] if channel_bandwidth is not None: im.wcs.wcs.cdelt[3] = channel_bandwidth[0] else: if len(frequency) > 1: im.wcs.wcs.cdelt[3] = frequency[1] - frequency[0] else: im.wcs.wcs.cdelt[3] = 0.001 * frequency[0] im.wcs.wcs.radesys = 'ICRS' im.wcs.wcs.equinox = 2000.00 if phasecentre is not None: im.wcs.wcs.crval[0] = phasecentre.ra.deg im.wcs.wcs.crval[1] = phasecentre.dec.deg # WCS is 1 relative im.wcs.wcs.crpix[0] = im.data.shape[3] // 2 + 1 im.wcs.wcs.crpix[1] = im.data.shape[2] // 2 + 1 return im
def test_create_gaintable_from_screen(self): screen = import_image_from_fits( rascil_path('data/models/test_mpc_screen.fits')) beam = create_test_image(cellsize=0.0015, phasecentre=self.vis.phasecentre, frequency=self.frequency) beam = create_low_test_beam(beam, use_local=False) gleam_components = create_low_test_skycomponents_from_gleam( flux_limit=1.0, phasecentre=self.phasecentre, frequency=self.frequency, polarisation_frame=PolarisationFrame('stokesI'), radius=0.2) pb_gleam_components = apply_beam_to_skycomponent( gleam_components, beam) actual_components = filter_skycomponents_by_flux(pb_gleam_components, flux_min=1.0) gaintables = create_gaintable_from_screen(self.vis, actual_components, screen) assert len(gaintables) == len(actual_components), len(gaintables) assert gaintables[0].gain.shape == (3, 94, 3, 1, 1), gaintables[0].gain.shape
def create_low_test_beam(model: Image, use_local=True) -> Image: """Create a test power beam for LOW using an image from OSKAR This is not fit for anything except the most basic testing. It does not include any form of elevation/pa dependence. :param model: Template image :return: Image """ beam = import_image_from_fits( rascil_path('data/models/SKA1_LOW_beam.fits')) # Scale the image cellsize to account for the different in frequencies. Eventually we will want to # use a frequency cube log.debug( "create_low_test_beam: LOW voltage pattern is defined at %.3f MHz" % (beam.wcs.wcs.crval[2] * 1e-6)) nchan, npol, ny, nx = model.shape # We need to interpolate each frequency channel separately. The beam is assumed to just scale with # frequency. reprojected_beam = create_empty_image_like(model) for chan in range(nchan): model2dwcs = model.wcs.sub(2).deepcopy() model2dshape = [model.shape[2], model.shape[3]] beam2dwcs = beam.wcs.sub(2).deepcopy() # The frequency axis is the second to last in the beam frequency = model.wcs.sub(['spectral']).wcs_pix2world([chan], 0)[0] fscale = beam.wcs.wcs.crval[2] / frequency beam2dwcs.wcs.cdelt = fscale * beam.wcs.sub(2).wcs.cdelt beam2dwcs.wcs.crpix = beam.wcs.sub(2).wcs.crpix beam2dwcs.wcs.crval = model.wcs.sub(2).wcs.crval beam2dwcs.wcs.ctype = model.wcs.sub(2).wcs.ctype model2dwcs.wcs.crpix = [ model.shape[2] // 2 + 1, model.shape[3] // 2 + 1 ] beam2d = create_image_from_array(beam.data[0, 0, :, :], beam2dwcs, model.polarisation_frame) reprojected_beam2d, footprint = reproject_image(beam2d, model2dwcs, shape=model2dshape) assert numpy.max( footprint.data) > 0.0, "No overlap between beam and model" reprojected_beam2d.data[footprint.data <= 0.0] = 0.0 for pol in range(npol): reprojected_beam.data[chan, pol, :, :] = reprojected_beam2d.data[:, :] set_pb_header(reprojected_beam, use_local=use_local) return reprojected_beam
def test_create_gradient(self): real_vp = import_image_from_fits( rascil_path('data/models/MID_GRASP_VP_real.fits')) gradx, grady = image_gradients(real_vp) gradxx, gradxy = image_gradients(gradx) gradyx, gradyy = image_gradients(grady) gradx.data *= real_vp.data grady.data *= real_vp.data gradxx.data *= real_vp.data gradxy.data *= real_vp.data gradyx.data *= real_vp.data gradyy.data *= real_vp.data if self.show: import matplotlib.pyplot as plt plt.clf() show_image(gradx, title='gradx') plt.show() plt.clf() show_image(grady, title='grady') plt.show() if self.persist: export_image_to_fits( gradx, "%s/test_image_gradients_gradx.fits" % (self.dir)) export_image_to_fits( grady, "%s/test_image_gradients_grady.fits" % (self.dir)) if self.show: import matplotlib.pyplot as plt plt.clf() show_image(gradxx, title='gradxx') plt.show() plt.clf() show_image(gradxy, title='gradxy') plt.show() plt.clf() show_image(gradyx, title='gradyx') plt.show() plt.clf() show_image(gradyy, title='gradyy') plt.show() if self.persist: export_image_to_fits( gradxx, "%s/test_image_gradients_gradxx.fits" % (self.dir)) export_image_to_fits( gradxy, "%s/test_image_gradients_gradxy.fits" % (self.dir)) export_image_to_fits( gradyx, "%s/test_image_gradients_gradyx.fits" % (self.dir)) export_image_to_fits( gradyy, "%s/test_image_gradients_gradyy.fits" % (self.dir))
def test_grid_gaintable_to_screen(self): self.actualSetup() screen = import_image_from_fits( rascil_data_path('models/test_mpc_screen.fits')) beam = create_test_image(cellsize=0.0015, phasecentre=self.vis.phasecentre, frequency=self.frequency) beam = create_low_test_beam(beam, use_local=False) gleam_components = create_low_test_skycomponents_from_gleam( flux_limit=1.0, phasecentre=self.phasecentre, frequency=self.frequency, polarisation_frame=PolarisationFrame('stokesI'), radius=0.2) pb_gleam_components = apply_beam_to_skycomponent( gleam_components, beam) actual_components = filter_skycomponents_by_flux(pb_gleam_components, flux_min=1.0) gaintables = create_gaintable_from_screen(self.vis, actual_components, screen) assert len(gaintables) == len(actual_components), len(gaintables) assert gaintables[0].gain.shape == (3, 94, 1, 1, 1), gaintables[0].gain.shape newscreen = create_empty_image_like(screen) newscreen, weights = grid_gaintable_to_screen(self.vis, gaintables, newscreen) assert numpy.max(numpy.abs(screen.data)) > 0.0 if self.persist: export_image_to_fits( newscreen, rascil_path('test_results/test_mpc_screen_gridded.fits')) if self.persist: export_image_to_fits( weights, rascil_path( 'test_results/test_mpc_screen_gridded_weights.fits'))
def test_create_gaintable_from_screen_troposphere(self): self.actualSetup("troposphere") screen = import_image_from_fits( rascil_data_path('models/test_mpc_screen.fits')) beam = create_test_image(cellsize=0.00015, phasecentre=self.vis.phasecentre, frequency=self.frequency) beam = create_low_test_beam(beam, use_local=False) s3_components = create_test_skycomponents_from_s3( flux_limit=0.3, phasecentre=self.phasecentre, frequency=self.frequency, polarisation_frame=PolarisationFrame('stokesI'), radius=1.5 * numpy.pi / 180.0) assert len(s3_components) > 0, "No S3 components selected" pb_s3_components = apply_beam_to_skycomponent(s3_components, beam) actual_components = filter_skycomponents_by_flux(pb_s3_components, flux_max=10.0) assert len( actual_components) > 0, "No components after applying primary beam" gaintables = create_gaintable_from_screen( self.vis, actual_components, screen, height=3e3, type_atmosphere="troposphere") assert len(gaintables) == len(actual_components), len(gaintables) assert gaintables[0].gain.shape == (3, 63, 1, 1, 1), gaintables[0].gain.shape
def create_vp(model, telescope='MID', pointingcentre=None, padding=4, use_local=True): """ Create an image containing the dish voltage pattern for a number of cases :param model: Template image :param telescope: :return: Primary beam image """ if telescope == 'MID_GAUSS': log.debug( "create_vp: Using numeric tapered Gaussian model for MID voltage pattern" ) edge = numpy.power(10, -0.6) return create_vp_generic_numeric(model, pointingcentre=pointingcentre, diameter=15.0, blockage=0.0, edge=edge, padding=padding, use_local=use_local) elif telescope == 'MID': log.debug( "create_vp: Using no taper analytic model for MID voltage pattern") return create_vp_generic(model, pointingcentre=pointingcentre, diameter=15.0, blockage=0.0, use_local=use_local) elif telescope == 'MID_GRASP': log.debug("create_vp: Using GRASP model for MID voltage pattern") real_vp = import_image_from_fits( rascil_path('data/models/MID_GRASP_VP_real.fits')) imag_vp = import_image_from_fits( rascil_path('data/models/MID_GRASP_VP_imag.fits')) real_vp.data = real_vp.data + 1j * imag_vp.data real_vp.data /= numpy.max(numpy.abs(real_vp.data)) return real_vp elif telescope == 'MID_FEKO_B1': log.debug("create_vp: Using FEKO model for MID voltage pattern") real_vp = import_image_from_fits( rascil_path('data/models/MID_FEKO_VP_B1_45_0765_real.fits')) imag_vp = import_image_from_fits( rascil_path('data/models/MID_FEKO_VP_B1_45_0765_imag.fits')) real_vp.data = real_vp.data + 1j * imag_vp.data real_vp.data /= numpy.max(numpy.abs(real_vp.data)) return real_vp elif telescope == 'MID_FEKO_B2': log.debug("create_vp: Using FEKO model for MID voltage pattern") real_vp = import_image_from_fits( rascil_path('data/models/MID_FEKO_VP_B2_45_1360_real.fits')) imag_vp = import_image_from_fits( rascil_path('data/models/MID_FEKO_VP_B2_45_1360_imag.fits')) real_vp.data = real_vp.data + 1j * imag_vp.data real_vp.data /= numpy.max(numpy.abs(real_vp.data)) return real_vp elif telescope == 'MID_FEKO_Ku': log.debug("create_vp: Using FEKO model for MID voltage pattern") real_vp = import_image_from_fits( rascil_path('data/models/MID_FEKO_VP_Ku_45_12179_real.fits')) imag_vp = import_image_from_fits( rascil_path('data/models/MID_FEKO_VP_Ku_45_12179_imag.fits')) real_vp.data = real_vp.data + 1j * imag_vp.data real_vp.data /= numpy.max(numpy.abs(real_vp.data)) return real_vp elif telescope == 'MEERKAT': return create_vp_generic(model, pointingcentre=pointingcentre, diameter=13.5, blockage=0.0, use_local=use_local) elif telescope[0:3] == 'LOW': return create_low_test_vp(model) elif telescope[0:3] == 'VLA': return create_vp_generic(model, pointingcentre=pointingcentre, diameter=25.0, blockage=1.8, use_local=use_local) elif telescope[0:5] == 'ASKAP': return create_vp_generic(model, pointingcentre=pointingcentre, diameter=12.0, blockage=1.0, use_local=use_local) else: raise NotImplementedError('Telescope %s has no voltage pattern model' % telescope)
default=None, help='Second image') parser.add_argument('--outimage', type=str, default=None, help='Second image') parser.add_argument('--mode', type=str, default='pipeline', help='Imaging mode') args = parser.parse_args() pp.pprint(vars(args)) im1 = import_image_from_fits(args.image1) im2 = import_image_from_fits(args.image2) print(qa_image(im1, context='Image 1')) print(qa_image(im2, context='Image 2')) outim = copy_image(im1) outim.data -= im2.data print(qa_image(outim, context='Difference image')) export_image_to_fits(outim, args.outimage) plt.clf() show_image(outim) plt.savefig(args.outimage.replace('.fits', '.jpg')) plt.show(block=False)
def test_read_screen(self): screen = import_image_from_fits( rascil_path('data/models/test_mpc_screen.fits')) assert screen.data.shape == (1, 3, 2000, 2000), screen.data.shape