def mapcube_simple_replace(mc, simple_replace_nans=True, simple_replace_negative_values=True, simple_replace_zero_values=True, nans_replacement_value=1.0, negatives_replacement_value=1.0, zeroes_replacement_value=1.0): """ Return a version of input mapcube that has been cleaned in a very simple way. :param mc: :param simple_replace_nans: :param simple_replace_negative_values: :param simple_replace_zero_values: :return: """ # Get all the data from the mapcube layer by layer new_mapcube = [] for i, m in enumerate(mc): data = m.data # Apply the simple replacements as necessary if simple_replace_nans: data = data_simple_replace_nans(data, replacement_value=nans_replacement_value) if simple_replace_negative_values: data = data_simple_replace_negative_values(data, replacement_value=negatives_replacement_value) if simple_replace_zero_values: data = data_simple_replace_zero_values(data, replacement_value=zeroes_replacement_value) new_mapcube.append(Map(data, m.meta)) return Map(new_mapcube, cube=True)
def process_kcor_map(m, rsun=2.7, gamma=0.7): import skimage.exposure from sunpy.map.maputils import all_coordinates_from_map hpc_coords = all_coordinates_from_map(m) r = np.sqrt(hpc_coords.Tx ** 2 + hpc_coords.Ty ** 2) / m.rsun_obs mask = r > rsun # remove negative values for gamma correction rescaled_data = m.data # don't scale if NRGF if "PRODUCT" in m.fits_header: display_min = m.fits_header["DISPMIN"] display_max = m.fits_header["DISPMAX"] processed_data = np.clip(rescaled_data, display_min, display_max) - display_min processed_data /= display_max - display_min processed_map = Map(processed_data, m.meta, mask=mask) processed_map.plot_settings["cmap"] = kcor_nrgf_cmap() processed_map.plot_settings["norm"] = matplotlib.colors.NoNorm() return(processed_map) rescaled_data[rescaled_data < 0.0] = 0.0 adjusted_data = skimage.exposure.adjust_gamma(rescaled_data, gamma=gamma) processed_map = Map(adjusted_data, m.meta, mask=mask) return(processed_map)
def prepare_test_data(file_format): pytest.importorskip('sunpy', minversion='2.1.0') from sunpy.map import Map from sunpy.coordinates.ephemeris import get_body_heliographic_stonyhurst if file_format == 'fits': map_aia = Map(os.path.join(DATA, 'aia_171_level1.fits')) data = map_aia.data wcs = map_aia.wcs date = map_aia.date target_wcs = wcs.deepcopy() elif file_format == 'asdf': pytest.importorskip('astropy', minversion='4.0') pytest.importorskip('gwcs', minversion='0.12') asdf = pytest.importorskip('asdf') aia = asdf.open(os.path.join(DATA, 'aia_171_level1.asdf')) data = aia['data'][...] wcs = aia['wcs'] date = wcs.output_frame.reference_frame.obstime target_wcs = Map(os.path.join(DATA, 'aia_171_level1.fits')).wcs.deepcopy() else: raise ValueError('file_format should be fits or asdf') # Reproject to an observer on Venus target_wcs.wcs.cdelt = ([24, 24]*u.arcsec).to(u.deg) target_wcs.wcs.crpix = [64, 64] venus = get_body_heliographic_stonyhurst('venus', date) target_wcs.wcs.aux.hgln_obs = venus.lon.to_value(u.deg) target_wcs.wcs.aux.hglt_obs = venus.lat.to_value(u.deg) target_wcs.wcs.aux.dsun_obs = venus.radius.to_value(u.m) return data, wcs, target_wcs
def make_slope_map(emcube, temperature_lower_bound=None, em_threshold=None): """ Fit emission measure distribution in every pixel The fit is computed between `temperature_lower_bound` and the temeperature at which the EM is maximum. Parameters ---------- emcube: `EMCube` Emission measure map as a function space and temperature em_threshold: `~astropy.units.Quantity`, optional If the total EM in a pixel is below this, no slope is calculated Returns ------- slope_map: `~sunpy.map.GenericMap` rsquared_map: `~sunpy.map.GenericMap` """ if em_threshold is None: em_threshold = u.Quantity(1e25, u.cm**(-5)) i_valid = np.where( u.Quantity(emcube.total_emission.data, emcube[0].meta['bunit']) > em_threshold) em_valid = np.log10(emcube.as_array()[i_valid]) em_valid[np.logical_or(np.isinf(em_valid), np.isnan(em_valid))] = 0.0 i_peak = em_valid.argmax(axis=1) log_temperature_bin_centers = np.log10( emcube.temperature_bin_centers.value) if temperature_lower_bound is None: i_lower = 0 else: i_lower = np.fabs(emcube.temperature_bin_centers - temperature_lower_bound).argmin() slopes, rsquared = [], [] for emv, ip in zip(em_valid, i_peak): t_fit = log_temperature_bin_centers[i_lower:ip] if t_fit.size < 3: warnings.warn('Fit should be over 3 or more bins in temperature.') if t_fit.size == 0: slopes.append(np.nan) rsquared.append(0.) continue em_fit = emv[i_lower:ip] w = np.where(em_fit > 0, 1, 0) coeff, rss, _, _, _ = np.polyfit(t_fit, em_fit, 1, full=True, w=w) rss = 1 if rss.size == 0 else rss[0] _, rss_flat, _, _, _ = np.polyfit(t_fit, em_fit, 0, full=True, w=w) rss_flat = 1 if rss_flat.size == 0 else rss_flat[0] slopes.append(coeff[0]) rsquared.append(1 - rss / rss_flat) slopes_data = np.zeros(emcube.total_emission.data.shape) slopes_data[i_valid] = slopes rsquared_data = np.zeros(emcube.total_emission.data.shape) rsquared_data[i_valid] = rsquared return Map( slopes_data, emcube[0].meta, ), Map(rsquared_data, emcube[0].meta)
def persistence(mc, func=np.max): """ Parameters ---------- mc : sunpy.map.MapCube A sunpy mapcube object Returns ------- sunpy.map.MapCube A mapcube containing the persistence transform of the input mapcube. The value normalization function used in plotting the data is changed, prettifying movies of resultant mapcube. """ # Get the persistence transform new_datacube = persistence_dc(mc.as_array(), func=func) # Create a list containing the data for the new map object new_mc = [] for i, m in enumerate(mc): new_map = Map(new_datacube[:, :, i], m.meta) new_map.plot_settings = deepcopy(m.plot_settings) new_mc.append(new_map) # Create the new mapcube and return return Map(new_mc, cube=True)
def modifyData(self, data_model: DataModel) -> DataModel: plot_settings = data_model.plot_preferences plot_settings["show_colorbar"] = self._ui.color_bar.isChecked() plot_settings["show_limb"] = self._ui.limb.isChecked() plot_settings["draw_grid"] = self._ui.grid.isChecked() plot_settings["mask"] = self._ui.mask.isChecked() plot_settings["wcs_grid"] = self._ui.wcs_grid.isChecked() plot_settings["annotate"] = self._ui.annotate.isChecked() if self._ui.mask.isChecked(): s_map = data_model.map data_model.map = Map(s_map.data, s_map.meta, mask=self._createMask(s_map)) else: s_map = data_model.map data_model.map = Map(s_map.data, s_map.meta) if self._ui.contours.isChecked(): strings = self._ui.contours_list.text().split(" ") levels = [int(s) for s in set(strings) if s != ""] plot_settings["contours"] = levels else: plot_settings["contours"] = False return data_model
def aia171_test_mc(aia171_test_map, aia171_test_map_layer, aia171_test_mc_pixel_displacements): # Create a map that has been shifted a known amount. d1 = sp_shift(aia171_test_map_layer, aia171_test_mc_pixel_displacements) m1 = Map((d1, aia171_test_map.meta)) # Create the mapsequence return Map([aia171_test_map, m1], sequence=True)
def accumulate(mc, accum, normalize=True): """ Parameters ---------- mc : sunpy.map.MapCube A sunpy mapcube object accum : normalize : Returns ------- sunpy.map.MapCube A summed mapcube in the map layer (time) direction. """ # counter for number of maps. j = 0 # storage for the returned maps maps = [] nmaps = len(mc) while j + accum <= nmaps: i = 0 these_map_times = [] while i < accum: this_map = mc[i + j] these_map_times.append(parse_time(this_map.date)) if normalize: normalization = this_map.exposure_time else: normalization = 1.0 if i == 0: # Emission rate m = this_map.data / normalization else: # Emission rate m += this_map.data / normalization i += 1 j += accum # Make a copy of the meta header and set the exposure time to accum, # indicating that 'n' normalized exposures were used. new_meta = deepcopy(this_map.meta) new_meta['exptime'] = np.float64(accum) # Set the observation time to the average of the times used to form # the map. new_meta['date_obs'] = _max_time(these_map_times) # Create the map list that will be used to make the mapcube new_map = Map(m, new_meta) new_map.plot_settings = deepcopy(this_map.plot_settings) maps.append(new_map) # Create the new mapcube and return return Map(maps, cube=True)
def create_tempmap(date, n_params=1, data_dir=home + 'SDO_data/', maps_dir=home + 'temperature_maps/'): wlens = ['94', '131', '171', '193', '211', '335'] t0 = 5.6 images = [] #imdates = {} print 'Finding data for {}.'.format(date.date()) # Loop through wavelengths for wl, wlen in enumerate(wlens): #print 'Finding {}A data...'.format(wlen), fits_dir = data_dir + '{}/{:%Y/%m/%d}/'.format(wlen, date) filename = fits_dir + 'aia*{0}*{1:%Y?%m?%d}?{1:%H?%M}*lev1?fits'.format( wlen, date) temp_im = Map(filename) # Download data if not enough found client = vso.VSOClient() if temp_im == []: print 'File not found. Downloading from VSO...' # Wavelength value for query needs to be an astropy Quantity wquant = u.Quantity(value=int(wlen), unit='Angstrom') qr = client.query( vso.attrs.Time( date, # - dt.timedelta(seconds=6), date + dt.timedelta(seconds=12)), #6)), vso.attrs.Wave(wquant, wquant), vso.attrs.Instrument('aia'), vso.attrs.Provider('JSOC')) res = client.get(qr, path=fits_dir + '{file}', site='NSO').wait() temp_im = Map(res) if temp_im == []: print 'Downloading failed.' print res, len(qr), qr return np.zeros((512, 512)), None, None if isinstance(temp_im, list): temp_im = temp_im[0] # TODO: save out level 1.5 data so it can be loaded quickly. temp_im = aiaprep(temp_im) temp_im.data = temp_im.data / temp_im.exposure_time # Can probably increase speed a bit by making this * (1.0/exp_time) images.append(temp_im) #imdates[wlen] = temp_im.date normim = images[2].data.copy() # Normalise images to 171A print 'Normalising images' for i in range(len(wlens)): images[i].data = images[i].data / normim # Produce temperature map if n_params == 1: tempmap = find_temp(images, t0) #, force_temp_scan=True) else: #tempmap = find_temp_3params(images, t0) pass return tempmap
def downloadData(self): results = Fido.search(self.attrsTime, self.instrument) closest = results["gong"][0] print(closest) self.file = Fido.fetch(closest, path=self.path) # Fetching only one gongmap = Map(self.file) self.map = Map(gongmap.data - np.mean(gongmap.data), gongmap.meta) return self.map
def test_reproject_roundtrip(file_format): # Test the reprojection with solar data, which ensures that the masking of # pixels based on round-tripping works correctly. Using asdf is not just # about testing a different format but making sure that GWCS works. # The observer handling changed in 2.1. pytest.importorskip('sunpy', minversion='2.1.0') from sunpy.map import Map from sunpy.coordinates.ephemeris import get_body_heliographic_stonyhurst if file_format == 'fits': map_aia = Map(get_pkg_data_filename('data/aia_171_level1.fits', package='reproject.tests')) data = map_aia.data wcs = map_aia.wcs date = map_aia.date target_wcs = wcs.deepcopy() elif file_format == 'asdf': pytest.importorskip('astropy', minversion='4.0') pytest.importorskip('gwcs', minversion='0.12') asdf = pytest.importorskip('asdf') aia = asdf.open( get_pkg_data_filename('data/aia_171_level1.asdf', package='reproject.tests')) data = aia['data'][...] wcs = aia['wcs'] date = wcs.output_frame.reference_frame.obstime target_wcs = Map( get_pkg_data_filename('data/aia_171_level1.fits', package='reproject.tests')).wcs.deepcopy() else: raise ValueError('file_format should be fits or asdf') # Reproject to an observer on Venus target_wcs.wcs.cdelt = ([24, 24]*u.arcsec).to(u.deg) target_wcs.wcs.crpix = [64, 64] venus = get_body_heliographic_stonyhurst('venus', date) target_wcs.wcs.aux.hgln_obs = venus.lon.to_value(u.deg) target_wcs.wcs.aux.hglt_obs = venus.lat.to_value(u.deg) target_wcs.wcs.aux.dsun_obs = venus.radius.to_value(u.m) output, footprint = reproject_interp((data, wcs), target_wcs, (128, 128)) header_out = target_wcs.to_header() # ASTROPY_LT_40: astropy v4.0 introduced new default header keywords, # once we support only astropy 4.0 and later we can update the reference # data files and remove this section. for key in ('CRLN_OBS', 'CRLT_OBS', 'DSUN_OBS', 'HGLN_OBS', 'HGLT_OBS', 'MJDREFF', 'MJDREFI', 'MJDREF', 'MJD-OBS', 'RSUN_REF'): header_out.pop(key, None) header_out['DATE-OBS'] = header_out['DATE-OBS'].replace('T', ' ') return array_footprint_to_hdulist(output, footprint, header_out)
def running_difference(mc, offset=1, use_offset_for_meta='ahead'): """ Calculate the running difference of a mapcube. Parameters ---------- mc : sunpy.map.MapCube A sunpy mapcube object offset : [ int ] Calculate the running difference between map 'i + offset' and image 'i'. use_offset_for_meta : {'ahead', 'behind', 'mean'} Which meta header to use in layer 'i' in the returned mapcube, either from map 'i + offset' (when set to 'ahead') and image 'i' (when set to 'behind'). When set to 'mean', the ahead meta object is copied, with the observation date replaced with the mean of the ahead and behind observation dates. Returns ------- sunpy.map.MapCube A mapcube containing the running difference of the input mapcube. The value normalization function used in plotting the data is changed, prettifying movies of resultant mapcube. """ # Create a list containing the data for the new map object new_mc = [] for i in range(0, len(mc.maps) - offset): new_data = mc[i + offset].data - mc[i].data if use_offset_for_meta == 'ahead': new_meta = mc[i + offset].meta plot_settings = mc[i + offset].plot_settings elif use_offset_for_meta == 'behind': new_meta = mc[i].meta plot_settings = mc[i].plot_settings elif use_offset_for_meta == 'mean': new_meta = deepcopy(mc[i + offset].meta) new_meta['date_obs'] = _mean_time([parse_time(mc[i + offset].date), parse_time(mc[i].date)]) plot_settings = mc[i + offset].plot_settings else: raise ValueError('The value of the keyword "use_offset_for_meta" has not been recognized.') # Update the plot scaling. The default here attempts to produce decent # looking images new_map = Map(new_data, new_meta) new_map.plot_settings = plot_settings new_mc.append(new_map) # Create the new mapcube and return return Map(new_mc, cube=True)
def base_difference(mc, base=0, fraction=False): """ Calculate the base difference of a mapcube. Parameters ---------- mc : sunpy.map.MapCube A sunpy mapcube object base : int, sunpy.map.Map If base is an integer, this is understood as an index to the input mapcube. Differences are calculated relative to the map at index 'base'. If base is a sunpy map, then differences are calculated relative to that map fraction : boolean If False, then absolute changes relative to the base map are returned. If True, then fractional changes relative to the base map are returned Returns ------- sunpy.map.MapCube A mapcube containing base difference of the input mapcube. The value normalization function used in plotting the data is changed, prettifying movies of resultant mapcube. """ if not(isinstance(base, GenericMap)): base_data = mc[base].data else: base_data = base.data if base_data.shape != mc[0].data.shape: raise ValueError('Base map does not have the same shape as the maps in the input mapcube.') # Fractional changes or absolute changes if fraction: relative = base_data else: relative = 1.0 # Create a list containing the data for the new map object new_mc = [] for m in mc: new_data = (m.data - base_data) / relative new_mc.append(Map(new_data, m.meta)) # Create the new mapcube and return return Map(new_mc, cube=True)
def convolve(sunpy_map, oversample_psf=1): """Convolve the FOXSI psf with an input map Parameters ---------- sunpy_map : `~sunpy.map.GenericMap` An input map. oversample_psf : int The number of subpixels to average over to produce a more accurate PSF Returns ------- sunpy_map : `~sunpy.map.GenericMap` The map convolved with the FOXSI psf. """ this_psf = psf(0 * u.arcmin, 0 * u.arcmin, scale=sunpy_map.scale.x, oversample=oversample_psf) smoothed_data = astropy_convolve(sunpy_map.data, this_psf) meta = sunpy_map.meta.copy() meta['telescop'] = 'FOXSI-SMEX' result = Map((smoothed_data, meta)) return result
def get_CHMap_stats(map_path): '''Return all the requested stats in a SPoCA CHMap''' # Open the FITS file hdus = fits.open(map_path) # Create a sunpy Map for converting the pixel coordinates image_hdu = hdus[image_hdu_name] map = Map(image_hdu.data, image_hdu.header) # Get regions by id regions_hdu = hdus[region_hdu_name] regions = {region['ID']: region for region in regions_hdu.data} # Get region stats by id region_stats = { region_stat['ID']: region_stat for region_stat in hdus[region_stats_hdu_name].data } # Create the stats list stats_list = list() for id, region in regions.items(): stats_list.append(get_stats(map, region, region_stats[id])) return stats_list
def plot_aia_channels(aia, time: u.s, root_dir, corners=None, figsize=None, norm=None, fontsize=14, **kwargs): """ Plot maps of the EUV channels of AIA for a given timestep Parameters ---------- aia : `synthesizAR.instruments.InstrumentSDOAIA` time : `astropy.Quantity` root_dir : `str` figsize : `tuple`, optional """ if figsize is None: figsize = (15, 10) if norm is None: norm = matplotlib.colors.SymLogNorm(1e-6, vmin=1, vmax=5e3) with h5py.File(aia.counts_file, 'r') as hf: reference_time = u.Quantity(hf['time'], hf['time'].attrs['unit']) i_time = np.where(reference_time == time)[0][0] fig_format = os.path.join(root_dir, f'{aia.name}', '{}', f'map_t{i_time:06d}.fits') fig = plt.figure(figsize=figsize) plt.subplots_adjust(wspace=0., hspace=0., top=0.95) ims = {} for i, channel in enumerate(aia.channels): tmp = Map(fig_format.format(channel['name'])) if corners is not None: blc = SkyCoord(*corners[0], frame=tmp.coordinate_frame) trc = SkyCoord(*corners[1], frame=tmp.coordinate_frame) tmp = tmp.submap(blc, trc) ax = fig.add_subplot(2, 3, i + 1, projection=tmp) ims[channel['name']] = tmp.plot(annotate=False, title=False, norm=norm) lon, lat = ax.coords lon.grid(alpha=0) lat.grid(alpha=0) if i % 3 == 0: lat.set_axislabel(r'solar-y [arcsec]', fontsize=fontsize) else: lat.set_ticks_visible(False) lat.set_ticklabel_visible(False) if i > 2: lon.set_axislabel(r'solar-x [arcsec]', fontsize=fontsize) else: lon.set_ticks_visible(False) lon.set_ticklabel_visible(False) ax.text(0.1 * tmp.dimensions.x.value, 0.9 * tmp.dimensions.y.value, r'${}$ $\mathrm{{\mathring{{A}}}}$'.format(channel['name']), color='w', fontsize=fontsize) fig.suptitle(r'$t={:.0f}$ {}'.format(time.value, time.unit.to_string()), fontsize=fontsize) if kwargs.get('use_with_animation', False): return fig, ims
def test_rsun_missing(): """Tests output if 'rsun' is missing""" euvi_no_rsun = Map(fitspath) euvi_no_rsun.meta['rsun'] = None r = euvi_no_rsun.observer_coordinate.radius with pytest.warns(SunpyUserWarning, match='Missing metadata for solar angular radius'): assert euvi_no_rsun.rsun_obs == sun._angular_radius(constants.radius, r)
def test_to_sunpy_map(self, m, n, pos, pixel): pos = pos * unit.arcsec pixel = pixel * unit.arcsec u = generate_uv(m, pixel[0]) v = generate_uv(n, pixel[1]) u, v = np.meshgrid(u, v) uv = np.array([u, v]).reshape(2, m * n) / unit.arcsec header = { 'crval1': pos[0].value, 'crval2': pos[1].value, 'cdelt1': pixel[0].value, 'cdelt2': pixel[1].value } data = Gaussian2DKernel(stddev=2, x_size=n, y_size=m).array mp = Map((data, header)) vis = Visibility.from_map(mp, uv) res = vis.to_map((m, n), pixel_size=pixel) # assert np.allclose(res.data, data) assert res.reference_coordinate.Tx == pos[0] assert res.reference_coordinate.Ty == pos[1] assert res.scale.axis1 == pixel[0] / unit.pix assert res.scale.axis2 == pixel[1] / unit.pix assert res.dimensions.x == m * unit.pix assert res.dimensions.y == n * unit.pix
def eitprep(fitsfile, return_map=False): hdul = fits.open(fitsfile) hdul[0].verify('silentfix') header = hdul[0].header data = hdul[0].data.astype(np.float64) new_coords = get_horizons_coord(header['TELESCOP'], parse_time(header['DATE_OBS'])) header['HGLN_OBS'] = new_coords.lon.to('deg').value header['HGLT_OBS'] = new_coords.lat.to('deg').value header['DSUN_OBS'] = new_coords.radius.to('m').value header.pop('hec_x') header.pop('hec_y') header.pop('hec_z') # Target scale is 2.63 arcsec/px target_scale = 2.63 scale_factor = header['CDELT1'] / target_scale # Center of rotation at reference pixel converted to a coordinate origin at 0 reference_pixel = [header['CRPIX1'] - 1, header['CRPIX2'] - 1] # Rotation angle with openCV uses coordinate origin at top-left corner. For solar images in numpy we need to invert the angle. angle = -header['SC_ROLL'] # Run scaled rotation. The output will be a rotated, rescaled, padded array. prepdata = scale_rotate(data, angle=angle, scale_factor=scale_factor, reference_pixel=reference_pixel) prepdata[prepdata < 0] = 0 prepdata[np.isnan(prepdata)] = 0 if return_map: prepdata = Map(prepdata, header) return prepdata
def clean_ne(log_ne_map): data = log_ne_map.data baddata = (data > 12) | (data < 7) data[baddata] = np.nan return Map((data, log_ne_map.meta))
def hsi_fits2map(url): f = read(url) header = f[0].header del header["CROTACN1"] del header["CROTACN2"] del header["CROTA"] d_min = 1e10 d_max = -1e10 for t in range(len(f[1].data[0]["TIME_AXIS"])): for e in range(len(f[1].data[0]["ENERGY_AXIS"])): d_min = min(d_min, f[0].data[t][e].min()) d_max = max(d_max, f[0].data[t][e].max()) maps = {} # result dictionary for e in f[1].data[0]["ENERGY_AXIS"].astype('int'): maps[f"{e[0]}-{e[1]} keV"] = [] # init all layers (each energy band corresponds to a layer) header["DATAMIN"] = d_min header["DATAMAX"] = d_max for t in range(len(f[1].data[0]["TIME_AXIS"])): header["DATE_OBS"] = parse_time(f[1].data[0]["TIME_AXIS"][t][0], format='utime').to_value('isot') header["DATE_END"] = parse_time(f[1].data[0]["TIME_AXIS"][t][1], format='utime').to_value('isot') for e in range(len(f[1].data[0]["ENERGY_AXIS"])): header["ENERGY_L"] = f[1].data[0]["ENERGY_AXIS"][e][0] header["ENERGY_H"] = f[1].data[0]["ENERGY_AXIS"][e][1] key = f"{int(header['ENERGY_L'])}-{int(header['ENERGY_H'])} keV" maps[key].append(Map(f[0].data[t][e], header)) # extract image into sunpy.Map return maps
def submap(mc, range_a, range_b, **kwargs): """ Parameters ---------- mc : sunpy.map.MapCube A sunpy mapcube object range_a : list range_b : list Returns ------- sunpy.map.MapCube A mapcube containing maps that have had the map submap method applied to each layer. """ nmc = len(mc) if (len(range_a) == nmc) and (len(range_b) == nmc): ra = range_a rb = range_b elif (len(range_a) == 1) and (len(range_b) == 1): ra = [range_a for i in range(0, nmc)] rb = [range_b for i in range(0, nmc)] else: raise ValueError('Both input ranges must be either of size 1 or size ' 'equal to the number of maps in the mapcube') # Storage for the returned maps maps = [] for im, m in enumerate(mc): maps.append(Map.submap(m, ra[im], rb[im], **kwargs)) # Create the new mapcube and return return Map(maps, cube=True)
def detect(self, channel, i_time, header, bins, bin_range): """ For a given timestep, map the intensity along the loop to the 3D field and return the Hi-C data product. Parameters ---------- channel : `dict` i_time : `int` header : `~sunpy.util.metadata.MetaDict` bins : `~synthesizAR.util.SpatialPair` bin_range : `~synthesizAR.util.SpatialPair` Returns ------- AIA data product : `~sunpy.map.Map` """ with h5py.File(self.counts_file, 'r') as hf: weights = np.array(hf[channel['name']][i_time, :]) units = u.Unit(get_keys(hf[channel['name']].attrs, ('unit','units'))) hpc_coordinates = self.total_coordinates dz = np.diff(bin_range.z)[0].cgs / bins.z * (1. * u.pixel) visible = is_visible(hpc_coordinates, self.observer_coordinate) hist, _, _ = np.histogram2d(hpc_coordinates.Tx.value, hpc_coordinates.Ty.value, bins=(bins.x.value, bins.y.value), range=(bin_range.x.value, bin_range.y.value), weights=visible * weights * dz.value) header['bunit'] = (units * dz.unit).to_string() counts = gaussian_filter(hist.T, (channel['gaussian_width']['y'].value, channel['gaussian_width']['x'].value)) return Map(counts.astype(np.float32), header)
def test_read_file(): """ Tests the reading of the complete JP2 file and its conversion into a SunPy map. """ map_ = Map(AIA_193_JP2) assert isinstance(map_, GenericMap)
def apply_movie_normalization(mc, image_normalization): """ A convenience function that applies an image normalization that means a movie of the input mapcube will not flicker. Assumes that all layers are similar and the stretch function for all layers is the same Parameters ---------- mc : `sunpy.map.MapCube` a sunpy mapcube image_normalization : `~astropy.visualization.ImageNormalize` image stretch function Returns ------- An image normalization setting that can be used with all the images in the mapcube ensuring no flickering in a movie of the images. """ new_mc = [] for m in mc: m_new = deepcopy(m) m_new.plot_settings["norm"] = image_normalization new_mc.append(m_new) return Map(new_mc, cube=True)
def composite_map(self): comp_map = Map(composite=True) for i, (c_id, (m, settings)) in enumerate(self.maps.items()): comp_map.add_map(m, settings["zorder"], settings["alpha"] / 100) if settings["levels"]: comp_map.set_levels(i, sorted(settings["levels"]), True) return comp_map
def aiaprep(fitsFile): map = Map(fitsFile) from aiapy.calibrate import register, update_pointing, normalize_exposure m_updated_pointing = update_pointing(map) m_registered = register(m_updated_pointing) m_normalized = normalize_exposure(m_registered) return m_normalized
def process_med_int(fle): """ Processes 1 image and extracts the median intensity on the disk normalized for exposure time. Args: fle (str): image file name Returns: median intensity of the solar disk normalized for exptime """ amap = Map(fle) amap = aiaprep(amap) data = amap.data date = amap.date hdr = getFitsHdr(fle) exp_time = hdr['exptime'] r_pix = hdr['rsun_obs'] / hdr['cdelt1'] # radius of the sun in pixels disk_mask = get_disk_mask(data.shape, r_pix) disk_data = np.ma.array(data, mask=disk_mask) med_int = np.ma.median(disk_data) # np.median doesn't support masking return med_int / exp_time
def test_from_sunpy_map(self, pos, pixel): m = n = 33 size = m * n pos = pos * unit.arcsec pixel = pixel * unit.arcsec # Calculate full u, v coverage so will be equivalent to a discrete Fourier transform (DFT) u = generate_uv(m, pos[0]) v = generate_uv(n, pos[1]) u, v = np.meshgrid(u, v) uv = np.array([u, v]).reshape(2, size) / unit.arcsec header = { 'crval1': pos[0].value, 'crval2': pos[1].value, 'cdelt1': pixel[0].value, 'cdelt2': pixel[1].value } # Astropy index order is opposite to that of numpy, is 1st dim is across second down data = Gaussian2DKernel(stddev=6, x_size=n, y_size=m).array mp = Map((data, header)) vis = Visibility.from_map(mp, uv) assert np.array_equal(vis.pixel_size, pixel) assert np.array_equal(vis.xyoffset, pos) res = vis.to_image((m, n), center=pos, pixel_size=pixel) assert np.allclose(res, data)
def irismap(): path = sunpy.data.test.rootdir fitspath = glob.glob( os.path.join(path, "iris_l2_20130801_074720_4040000014_SJI_1400_t000.fits")) with pytest.warns(SunpyUserWarning, match='This file contains more than 2 dimensions'): return Map(fitspath, silence_errors=True)