def test_conv_hcc_hpc(): coord = [28748691, 22998953] result = wcs.convert_hcc_hpc(coord[0], coord[1], dsun_meters=img.dsun, angle_units=img.units['x']) known_answer = [40.0, 32.0] assert_allclose(result, known_answer, rtol=1e-4, atol=0)
def test_conv_hcc_hpc(angle_unit, dsun): coord = [28748691, 22998953] result = wcs.convert_hcc_hpc(coord[0], coord[1], angle_units=angle_unit, dsun_meters=dsun) known_answer = [40.331028, 32.264823] assert_allclose(result, known_answer, rtol=1e-4, atol=0)
def test_conv_hcc_hpc(): coord = [34.0, 132.0] result = wcs.convert_hcc_hpc(img.rsun_meters, img.dsun, coord[0], coord[1]) known_answer = [1.3140782e-08, 5.1017152e-08] magnitude = np.floor(np.log10(np.abs(known_answer))) assert_array_almost_equal(result*10**(-magnitude), known_answer*10**(-magnitude), decimal=2)
def test_convert_back(): # Make sure transformation followed by inverse transformation returns # the original coordinates coord = [40.0, 32.0] assert_allclose(wcs.convert_hcc_hpc(*wcs.convert_hpc_hcc(*coord)), coord, rtol=1e-2, atol=0) coord = [13.0, 58.0] assert_allclose(wcs.convert_hg_hcc(*wcs.convert_hcc_hg(*coord)), coord, rtol=1e-2, atol=0) coord = [34.0, 45.0] assert_allclose(wcs.convert_hpc_hg(*wcs.convert_hg_hpc(*coord)), coord, rtol=1e-2, atol=0)
def test_convert_to_coord(dsun, angle_unit, b0, l0): x, y = (34.0, 96.0) b0_deg = b0 l0_deg = l0 def check_conversion(from_coord, to_coord, expected): # Make sure that wcs.convert_to_coord returns the expected value assert_allclose(wcs.convert_to_coord(x, y, from_coord, to_coord, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=angle_unit), expected, rtol=1e-2, atol=0) check_conversion('hcc', 'hg', wcs.convert_hcc_hg(x, y, b0_deg=b0_deg, l0_deg=l0_deg)) check_conversion( 'hpc', 'hg', wcs.convert_hpc_hg(x, y, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=angle_unit)) check_conversion('hg', 'hcc', wcs.convert_hg_hcc(x, y, b0_deg=b0_deg, l0_deg=l0_deg)) check_conversion( 'hcc', 'hpc', wcs.convert_hcc_hpc(x, y, dsun_meters=dsun, angle_units=angle_unit)) check_conversion( 'hg', 'hpc', wcs.convert_hg_hpc(x, y, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=angle_unit)) check_conversion( 'hpc', 'hcc', wcs.convert_hpc_hcc(x, y, dsun_meters=dsun, angle_units=angle_unit))
def test_convert_to_coord(): x, y = (34.0, 96.0) b0_deg = img.heliographic_latitude l0_deg = img.heliographic_longitude units = img.units['x'] dsun=img.dsun def check_conversion(from_coord, to_coord, expected): # Make sure that wcs.convert_to_coord returns the expected value assert_allclose(wcs.convert_to_coord(x, y, from_coord, to_coord, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=units), expected, rtol=1e-2, atol=0) check_conversion('hcc', 'hg', wcs.convert_hcc_hg(x, y, b0_deg=b0_deg, l0_deg=l0_deg)) check_conversion('hpc', 'hg', wcs.convert_hpc_hg(x, y, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=units)) check_conversion('hg', 'hcc', wcs.convert_hg_hcc(x, y, b0_deg=b0_deg, l0_deg=l0_deg)) check_conversion('hcc', 'hpc', wcs.convert_hcc_hpc(x, y, dsun_meters=dsun, angle_units=units)) check_conversion('hg', 'hpc', wcs.convert_hg_hpc(x, y, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=units)) check_conversion('hpc', 'hcc', wcs.convert_hpc_hcc(x, y, dsun_meters=dsun, angle_units=units))
def test_convert_to_coord(dsun, angle_unit, b0, l0): x, y = (34.0, 96.0) b0_deg = b0 l0_deg = l0 def check_conversion(from_coord, to_coord, expected): # Make sure that wcs.convert_to_coord returns the expected value assert_allclose(wcs.convert_to_coord(x, y, from_coord, to_coord, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=angle_unit), expected, rtol=1e-2, atol=0) check_conversion('hcc', 'hg', wcs.convert_hcc_hg(x, y, b0_deg=b0_deg, l0_deg=l0_deg)) check_conversion('hpc', 'hg', wcs.convert_hpc_hg(x, y, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=angle_unit)) check_conversion('hg', 'hcc', wcs.convert_hg_hcc(x, y, b0_deg=b0_deg, l0_deg=l0_deg)) check_conversion('hcc', 'hpc', wcs.convert_hcc_hpc(x, y, dsun_meters=dsun, angle_units=angle_unit)) check_conversion('hg', 'hpc', wcs.convert_hg_hpc(x, y, b0_deg=b0_deg, l0_deg=l0_deg, dsun_meters=dsun, angle_units=angle_unit)) check_conversion('hpc', 'hcc', wcs.convert_hpc_hcc(x, y, dsun_meters=dsun, angle_units=angle_unit))
def transform(params, wave_maps, verbose=False): """ Transform raw data in HG' coordinates to HPC coordinates HG' = HG, except center at wave epicenter """ solar_rotation_rate = params["rotation"] hglt_obs = params["hglt_obs"].to('degree').value # crln_obs = params["crln_obs"] epi_lat = params["epi_lat"].to('degree').value epi_lon = params["epi_lon"].to('degree').value # Parameters for the HPC co-ordinates hpcx_min = params["hpcx_min"].to('arcsec').value hpcx_max = params["hpcx_max"].to('arcsec').value hpcx_bin = params["hpcx_bin"].to('arcsec').value hpcy_min = params["hpcy_min"].to('arcsec').value hpcy_max = params["hpcy_max"].to('arcsec').value hpcy_bin = params["hpcy_bin"].to('arcsec').value hpcx_num = int(round((hpcx_max-hpcx_min)/hpcx_bin)) hpcy_num = int(round((hpcy_max-hpcy_min)/hpcy_bin)) # Storage for the HPC version of the input maps wave_maps_transformed = [] # The properties of this map are used in the transform smap = wave_maps[0] # Basic dictionary version of the HPC map header dict_header = { "CDELT1": hpcx_bin, "NAXIS1": hpcx_num, "CRVAL1": hpcx_min, "CRPIX1": crpix12_value_for_HPC, "CUNIT1": "arcsec", "CTYPE1": "HPLN-TAN", "CDELT2": hpcy_bin, "NAXIS2": hpcy_num, "CRVAL2": hpcy_min, "CRPIX2": crpix12_value_for_HPC, "CUNIT2": "arcsec", "CTYPE2": "HPLT-TAN", "HGLT_OBS": hglt_obs, "CRLN_OBS": smap.carrington_longitude.to('degree').value, "DSUN_OBS": sun.sunearth_distance(BASE_DATE.strftime(BASE_DATE_FORMAT)).to('meter').value, "DATE_OBS": BASE_DATE.strftime(BASE_DATE_FORMAT), "EXPTIME": 1.0 } start_date = smap.date # Origin grid, HG' lon_grid, lat_grid = wcs.convert_pixel_to_data([smap.data.shape[1], smap.data.shape[0]], [smap.scale.x.value, smap.scale.y.value], [smap.reference_pixel.x.value, smap.reference_pixel.y.value], [smap.reference_coordinate.x.value, smap.reference_coordinate.y.value]) # Origin grid, HG' to HCC' # HCC' = HCC, except centered at wave epicenter x, y, z = wcs.convert_hg_hcc(lon_grid, lat_grid, b0_deg=smap.heliographic_latitude.to('degree').value, l0_deg=smap.carrington_longitude.to('degree').value, z=True) # Origin grid, HCC' to HCC'' # Moves the wave epicenter to initial conditions # HCC'' = HCC, except assuming that HGLT_OBS = 0 zxy_p = euler_zyz((z, x, y), (epi_lon, 90.-epi_lat, 0.)) # Destination HPC grid hpcx_grid, hpcy_grid = wcs.convert_pixel_to_data([dict_header['NAXIS1'], dict_header['NAXIS2']], [dict_header['CDELT1'], dict_header['CDELT2']], [dict_header['CRPIX1'], dict_header['CRPIX2']], [dict_header['CRVAL1'], dict_header['CRVAL2']]) for icwm, current_wave_map in enumerate(wave_maps): print(icwm, len(wave_maps)) # Elapsed time td = parse_time(current_wave_map.date) - parse_time(start_date) # Update the header dict_header['DATE_OBS'] = current_wave_map.date dict_header['DSUN_OBS'] = current_wave_map.dsun.to('m').value # Origin grid, HCC'' to HCC # Moves the observer to HGLT_OBS and adds rigid solar rotation total_seconds = u.s * (td.microseconds + (td.seconds + td.days * 24.0 * 3600.0) * 10.0**6) / 10.0**6 solar_rotation = (total_seconds * solar_rotation_rate).to('degree').value zpp, xpp, ypp = euler_zyz(zxy_p, (0., hglt_obs, solar_rotation)) # Origin grid, HCC to HPC (arcsec) xx, yy = wcs.convert_hcc_hpc(xpp, ypp, dsun_meters=current_wave_map.dsun.to('m').value) # Coordinate positions (HPC) with corresponding map data points = np.vstack((xx.ravel(), yy.ravel())).T values = np.asarray(deepcopy(current_wave_map.data)).ravel() # Solar rotation can push the points off disk and into areas that have # nans. if this is the case, then griddata fails # Two solutions # 1 - replace all the nans with zeros, in order to get the code to run # 2 - the initial condition of zpp.ravel() >= 0 should be extended # to make sure that only finite points are used. # 2D interpolation from origin grid to destination grid valid_points = np.logical_and(zpp.ravel() >= 0, np.isfinite(points[:, 0]), np.isfinite(points[:, 1])) grid = griddata(points[valid_points], values[valid_points], (hpcx_grid, hpcy_grid), method="linear") transformed_wave_map = Map(grid, MapMeta(dict_header)) transformed_wave_map.plot_settings = deepcopy(current_wave_map.plot_settings) # transformed_wave_map.name = current_wave_map.name # transformed_wave_map.meta['date-obs'] = current_wave_map.date wave_maps_transformed.append(transformed_wave_map) return Map(wave_maps_transformed, cube=True)
def map_hg_to_hpc_rotate(m, epi_lon=90*u.degree, epi_lat=0*u.degree, xbin=2.4*u.arcsec, ybin=2.4*u.arcsec, xnum=None, ynum=None, solar_information=None, **kwargs): """ Transform raw data in HG' coordinates to HPC coordinates HG' = HG, except center at wave epicenter """ # Origin grid, HG' lon_grid, lat_grid = wcs.convert_pixel_to_data([m.data.shape[1], m.data.shape[0]], [m.scale.x.value, m.scale.y.value], [m.reference_pixel.x.value, m.reference_pixel.y.value], [m.reference_coordinate.x.value, m.reference_coordinate.y.value]) # Origin grid, HG' to HCC' # HCC' = HCC, except centered at wave epicenter x, y, z = wcs.convert_hg_hcc(lon_grid, lat_grid, b0_deg=m.heliographic_latitude.to('degree').value, l0_deg=m.carrington_longitude.to('degree').value, z=True) # Origin grid, HCC' to HCC'' # Moves the wave epicenter to initial conditions # HCC'' = HCC, except assuming that HGLT_OBS = 0 zpp, xpp, ypp = euler_zyz((z, x, y), (epi_lon.to('degree').value, 90.-epi_lat.to('degree').value, 0.)) # Add in a solar rotation. Useful when creating simulated HPC data from # HG data. This code was adapted from the wave simulation code of the # AWARE project. if solar_information is not None: hglt_obs = solar_information['hglt_obs'].to('degree').value solar_rotation_value = solar_information['angle_rotated'].to('degree').value #print(hglt_obs, solar_rotation_value) #print('before', zpp, xpp, ypp) zpp, xpp, ypp = euler_zyz((zpp, xpp, ypp), (0., hglt_obs, solar_rotation_value)) #print('after', zpp, xpp, ypp) # Origin grid, HCC to HPC (arcsec) # xx, yy = wcs.convert_hcc_hpc(current_wave_map.header, xpp, ypp) xx, yy = wcs.convert_hcc_hpc(xpp, ypp, dsun_meters=m.dsun.to('meter').value) # Destination HPC grid hpcx_range = (np.nanmin(xx), np.nanmax(xx)) hpcy_range = (np.nanmin(yy), np.nanmax(yy)) if xnum is None: cdelt1 = xbin.to('arcsec').value hpcx = np.arange(hpcx_range[0], hpcx_range[1], cdelt1) else: nx = xnum.to('pixel').value cdelt1 = (hpcx_range[1] - hpcx_range[0]) / (1.0*nx - 1.0) hpcx = np.linspace(hpcx_range[1], hpcx_range[0], num=nx) if ynum is None: cdelt2 = ybin.to('arcsec').value hpcy = np.arange(hpcy_range[0], hpcy_range[1], cdelt2) else: ny = ynum.to('pixel').value cdelt2 = (hpcy_range[1] - hpcy_range[0]) / (1.0*ny - 1.0) hpcy = np.linspace(hpcy_range[1], hpcy_range[0], num=ny) # Calculate the grid mesh newgrid_x, newgrid_y = np.meshgrid(hpcx, hpcy) # # CRVAL1,2 and CRPIX1,2 are calculated so that the co-ordinate system is # at the center of the image # Note that crpix[] counts pixels starting at 1 crpix1 = 1 + hpcx.size // 2 crval1 = hpcx[crpix1 - 1] crpix2 = 1 + hpcy.size // 2 crval2 = hpcy[crpix2 - 1] dict_header = { "CDELT1": cdelt1, "NAXIS1": len(hpcx), "CRVAL1": crval1, "CRPIX1": crpix1, "CUNIT1": "arcsec", "CTYPE1": "HPLN-TAN", "CDELT2": cdelt2, "NAXIS2": len(hpcy), "CRVAL2": crval2, "CRPIX2": crpix2, "CUNIT2": "arcsec", "CTYPE2": "HPLT-TAN", "HGLT_OBS": m.heliographic_latitude.to('degree').value, # 0.0 # "HGLN_OBS": 0.0, "CRLN_OBS": m.carrington_longitude.to('degree').value, # 0.0 'DATE_OBS': m.meta['date-obs'], 'DSUN_OBS': m.dsun.to('m').value, 'EXPTIME': m.exposure_time.to('s').value } # Coordinate positions (HPC) with corresponding map data points = np.vstack((xx.ravel(), yy.ravel())).T values = np.asarray(deepcopy(m.data)).ravel() # Solar rotation can push the points off disk and into areas that have # nans. if this is the case, then griddata fails # Two solutions # 1 - replace all the nans with zeros, in order to get the code to run # 2 - the initial condition of zpp.ravel() >= 0 should be extended # to make sure that only finite points are used. # 2D interpolation from origin grid to destination grid valid_points = np.logical_and(zpp.ravel() >= 0, np.isfinite(points[:, 0]), np.isfinite(points[:, 1])) # 2D interpolation from origin grid to destination grid grid = griddata(points[valid_points], values[valid_points], (newgrid_x, newgrid_y), **kwargs) # Find out where the non-finites are mask = np.logical_not(np.isfinite(grid)) # Return a masked array is appropriate if mask is None: hpc = Map(grid, MapMeta(dict_header)) else: hpc = Map(ma.array(grid, mask=mask), MapMeta(dict_header)) hpc.plot_settings = m.plot_settings return hpc
hglt_obs = solar_information['hglt_obs'].to('degree').value solar_rotation_value = solar_information['angle_rotated'].to( 'degree').value # print(hglt_obs, solar_rotation_value) # print('before', zpp, xpp, ypp) zpp, xpp, ypp = euler_zyz((zpp, xpp, ypp), (0., hglt_obs, solar_rotation_value)) # print('after', zpp, xpp, ypp) """ # Origin grid, HCC to HPC (arcsec) # xx, yy = wcs.convert_hcc_hpc(current_wave_map.header, xpp, ypp) xx, yy = wcs.convert_hcc_hpc(xpp, ypp, dsun_meters=hg.dsun.to('meter').value) # Destination HPC grid hpcx_range = (np.nanmin(xx), np.nanmax(xx)) hpcy_range = (np.nanmin(yy), np.nanmax(yy)) if xnum is None: cdelt1 = xbin.to('arcsec').value hpcx = np.arange(hpcx_range[0], hpcx_range[1], cdelt1) else: nx = xnum.to('pixel').value cdelt1 = (hpcx_range[1] - hpcx_range[0]) / (1.0 * nx - 1.0) hpcx = np.linspace(hpcx_range[1], hpcx_range[0], num=nx) if ynum is None: cdelt2 = ybin.to('arcsec').value