def test_carrington_rotation_roundtrip(): t = Time('2010-1-1') crot = sun.carrington_rotation_number(t) t_roundtrip = sun.carrington_rotation_time(crot) dt = t - t_roundtrip # Stated precision in the docstring is 0.11 seconds assert_quantity_allclose(dt.to(u.s), 0 * u.s, atol=0.11 * u.s)
def make_afrl_df(source_file, resolution='1D', series='Agg8.25D'): """ :param source_file: dir where pickle detection files are saved generated by main.py :param resolution: time regularization parameter to put everything on a consistent grid :param series: Which of the aggregation series to use :return: none """ pch_dic = pickle.load(open(source_file, 'rb')) north = pch_dic[series][0].N_mean_lat north_std = pch_dic[series][0].N_mean_lat.rolling(series[3:]).std() north_min = north - north_std north_min[north_min.lt(np.deg2rad(50))] = np.deg2rad(50) # Calculating Standard deviation and clipping out of bounds north_max = north + north_std north_max[north_max.gt(np.pi / 2)] = np.pi / 2 south = pch_dic[series][1].S_mean_lat south_std = pch_dic[series][1].S_mean_lat.rolling(series[3:]).std() south_min = south - south_std south_min[south_min.lt(-np.pi / 2)] = -np.pi / 2 south_max = south + south_std south_max[south_max.gt(-np.deg2rad(50))] = -np.deg2rad(50) # Binning down to the specified resolution idx = pd.date_range(np.min([north.index[0], south.index[0]]), np.max([north.index[-1], south.index[-1]]), freq=resolution) north = north.resample(resolution).median().reindex(idx, fill_value=np.nan) north_min = north_min.resample(resolution).median().reindex( idx, fill_value=np.nan) north_max = north_max.resample(resolution).median().reindex( idx, fill_value=np.nan) south = south.resample(resolution).median().reindex(idx, fill_value=np.nan) south_min = south_min.resample(resolution).median().reindex( idx, fill_value=np.nan) south_max = south_max.resample(resolution).median().reindex( idx, fill_value=np.nan) afrl_df = pd.DataFrame( data={ 'north': north, 'north_min': north_min, 'north_max': north_max, 'south': south, 'south_min': south_min, 'south_max': south_max }) afrl_df['CR'] = carrington_rotation_number(afrl_df.index) save_name = path.join(path.dirname(path.abspath(source_file)), 'PCH_' + series + '_' + resolution + '_Bin.pkl') afrl_df.to_pickle(save_name)
def get_sharps(outputpath, t_start, t_end, restart=True, method='cm', maxlon=90): """ Generate pickle file listing SHARPs within a timeframe. Set method='cm' to choose frames closest to Central Meridian, or method='maxflux' to choose frames with the maximum unsigned flux. Parameter maxlon sets the maximum E-W distance from Central Meridian to include (in degrees). """ # Start time: cr_start = int(carrington_rotation_number(t_start)) # Identify all SHARP regions present within simulation timeframe, # with at least one frame within +=maxlon of Central Meridian: # [cache in pickle file for later use] try: if (restart): picklefile = open(outputpath + 'sharps.p', 'rb') picklefile.close() print('Reading pre-computed SHARPs from sharps.p') except: restart = False if (restart == False): sharps, t_rec, t_em = getSHARPs(t_start, t_end, method=method, maxlon=maxlon, discardfile=outputpath + 'limb_discards.txt') picklefile1 = open(outputpath + 'sharps.p', 'wb') pickle.dump(sharps, picklefile1) pickle.dump(t_rec, picklefile1) pickle.dump(t_em, picklefile1) picklefile1.close()
def test_carrington_rotation_number(date, day_fraction, rotation_number): assert_allclose(sun.carrington_rotation_number( Time(date, scale='tt') + day_fraction * u.day), rotation_number, rtol=0, atol=2e-4)
def get_pair_overlaps(outputpath, sharpsfile, repeat_threshold=1, outfile='repeatpairs.txt', plots=True, bmin=1e-12, t_restart=''): """ Reads data file produced by get_bmrs, identifies pairs of repeat regions, and saves list of their numbers to text file. """ print('Identifying repeat regions...') # Read "good" data (i.e. ones with BMRs): dat = np.loadtxt(outputpath + sharpsfile, skiprows=5, delimiter='\t', dtype={ 'names': ('SHARP', 'NOAA', 'CM time', 'Latitude', 'Carr-Longitude', 'Unsgnd flux', 'Imbalance', 'Good', 'Dipole', 'Bip-Separation', 'Bip-Tilt', 'Bip-Dipole'), 'formats': ('i4', 'i4', 'S10', 'f8', 'f8', 'f8', 'f8', 'i4', 'f8', 'f8', 'f8', 'f8') }) dat = dat[:][np.where(dat['Good'] == 1)] times = [ datetime.datetime.strptime(d.decode("utf-8"), '%Y-%m-%d') for d in dat['CM time'] ] # Prepare new ASCII file: if (plots): plt.figure(figsize=(12, 4)) gs = gridspec.GridSpec(2, 3, width_ratios=[1, 1, 1]) bmax = 200 # - Choose plotting boundaries: pmin = 0 pmax = 360 smin = -1 smax = 1 # - get coordinates: f = netcdf.netcdf_file(outputpath + 'sharp%5.5i.nc' % dat['SHARP'][0], 'r', mmap=False) br = f.variables['br'][:] f.close() ns, nph = np.shape(br) del (br) ds = 2.0 / ns dp = 2 * np.pi / nph sc = np.linspace(-1 + 0.5 * ds, 1 - 0.5 * ds, ns) pc = np.linspace(0.5 * dp, 2 * np.pi - 0.5 * dp, nph) cnt = 0 # If not restarting, set initial time and initialise ASCII file: if (t_restart == ''): t_restart = np.min(times) repeatfile = open(outputpath + outfile, 'w') repeatfile.write( 'List of pairs of repeat SHARPs with repeat_threshold=%g\n' % repeat_threshold) repeatfile.write('-- Produced by anthony.yeates[at]durham.ac.uk --\n') else: repeatfile = open(outputpath + outfile, 'a') # Loop through each region: for k1, sharp1 in enumerate(dat['SHARP']): print(sharp1) loaded1 = False for k2 in range(k1 + 1, len(dat)): # Select regions later in list with CM passage from 20 to 34 days later: if ((times[k2] > t_restart) & (times[k2] - times[k1] >= datetime.timedelta(days=20)) & (times[k2] - times[k1] <= datetime.timedelta(days=34))): sharp2 = dat['SHARP'][k2] # - Load footprints of regions on computational grid: if (loaded1 == False): # Load footprint of region on computational grid: f = netcdf.netcdf_file(outputpath + 'sharp%5.5i.nc' % sharp1, 'r', mmap=False) br1 = f.variables['br'][:] br1b = f.variables['br_bipole'][:] f.close() reg1 = (np.abs(br1) > bmin).astype('float') reg1b = (np.abs(br1b) > bmin).astype('float') flux1 = np.sum(np.abs(br1)) loaded1 = True f = netcdf.netcdf_file(outputpath + 'sharp%5.5i.nc' % sharp2, 'r', mmap=False) br2 = f.variables['br'][:] br2b = f.variables['br_bipole'][:] f.close() reg2 = (np.abs(br2) > bmin).astype('float') flux2 = np.sum(np.abs(br2)) if (flux2 > flux1): continue # - Rotate back differentially: dt = (times[k2] - times[k1]).days br2d = derotate(br2, times[k2] - times[k1]) reg2d = (np.abs(br2d) > bmin).astype('float') # - Flux of BMR 1 in derotated BMR 2: ofluxb1 = np.sum(np.abs(br1) * reg2d) olap = ofluxb1 / flux2 # - Get number of pixels in BMR representations npix1b = np.sum(reg1) npix2bd = np.sum(reg2d) # - If this is greater than overlap_threshold, record and plot: if ((olap > repeat_threshold) & (npix1b * npix2bd > 0)): if (plots): # Load corresponding HMI synoptic maps for context: crot1 = carrington_rotation_number(times[k1]) brm1, scm1, pcm1 = readmap(crot1) crot2 = carrington_rotation_number(times[k2]) brm2, scm2, pcm2 = readmap(crot2) # Compare two regions on grid: ax = plt.subplot(gs[0]) pm = ax.pcolormesh(np.rad2deg(pcm1), scm1, brm1, cmap='bwr') plt.contour(np.rad2deg(pc), sc, reg1, [0.5], colors='g', linewidths=0.75) pm.set_clim(vmin=-bmax, vmax=bmax) ax.text(10, 0.8, '(a) CR%4.4i' % crot1) ax.set_ylabel('Sine Latitude') ax = plt.subplot(gs[1]) pm = ax.pcolormesh(np.rad2deg(pc), sc, br1, cmap='bwr') pm.set_clim(vmin=-bmax, vmax=bmax) ax.text(pmin + 1. / 36 * (pmax - pmin), smax - 0.1 * (smax - smin), '(b) SHARP %i' % sharp1) ax.set_xlim(pmin, pmax) ax.set_ylim(smin, smax) ax = plt.subplot(gs[2]) pm = ax.pcolormesh(np.rad2deg(pc), sc, br1b, cmap='bwr') pm.set_clim(vmin=-bmax, vmax=bmax) ax.text( pmin + 1. / 36 * (pmax - pmin), smax - 0.1 * (smax - smin), r'(c) $\Phi$ = %6.2e' % (flux1 * ds * dp * 6.96e10**2)) # plt.contour(np.rad2deg(pc), sc, reg2bd, [0.5], colors='k', linewidths=0.75, linestyles='--') ax.text(pmin + 1. / 36 * (pmax - pmin), smax - 0.95 * (smax - smin), r'$R_{12}$ = %4.2f' % olap) ax.set_xlim(pmin, pmax) ax.set_ylim(smin, smax) ax = plt.subplot(gs[3]) pm = ax.pcolormesh(np.rad2deg(pcm2), scm2, brm2, cmap='bwr') plt.contour(np.rad2deg(pc), sc, reg2, [0.5], colors='k', linewidths=0.75) pm.set_clim(vmin=-bmax, vmax=bmax) ax.text(10, 0.8, '(d) CR%4.4i' % crot2) ax.set_xlabel('Carrington Longitude') ax.set_ylabel('Sine Latitude') ax = plt.subplot(gs[4]) pm = ax.pcolormesh(np.rad2deg(pc), sc, br2d, cmap='bwr') pm.set_clim(vmin=-bmax, vmax=bmax) ax.text(pmin + 1. / 36 * (pmax - pmin), smax - 0.1 * (smax - smin), '(e) SHARP %i' % sharp2) ax.set_xlabel('Carrington Longitude') ax.set_xlim(pmin, pmax) ax.set_ylim(smin, smax) ax = plt.subplot(gs[5]) br2bd = derotate(br2b, times[k2] - times[k1]) pm = ax.pcolormesh(np.rad2deg(pc), sc, br2bd, cmap='bwr') pm.set_clim(vmin=-bmax, vmax=bmax) ax.text( pmin + 1. / 36 * (pmax - pmin), smax - 0.1 * (smax - smin), r'(f) $\Phi$ = %6.2e' % (flux2 * ds * dp * 6.96e10**2)) ax.set_xlabel('Carrington Longitude') ax.set_xlim(pmin, pmax) ax.set_ylim(smin, smax) plt.savefig(outputpath + 'repeat1_%5.5i.png' % cnt, bbox_inches='tight') plt.clf() cnt += 1 # Output to list of repeat regions: repeatfile.write('%i\t%i\n' % (sharp1, sharp2)) repeatfile.close()
for jj in range(0,3): os.chdir(data_directory[jj]) for fitsfile in glob.glob('*.fits'): # Open the fits file hdulist_hinode = fits.open(fitsfile) # Create astropy time objects of the start and end times of the Hinode scan in UTC. start_time = Time(hdulist_hinode[0].header['TSTART'], format='isot', scale='utc') end_time = Time(hdulist_hinode[0].header['TEND'], format='isot', scale='utc') # Determine time in the middle of the scan (still in UTC). middle_of_scan = start_time+(end_time-start_time)/2 # Determine the Carrington rotation of this scan, round to the first significant # figure (which corresponds to the stretching of 10 we made above) this_carr_number = np.round(sun.carrington_rotation_number(t=middle_of_scan), decimals=1) # Here I am sorting out bad coordinates with quantiles, the example below assumes that a # maximum of 2% of the coordinates are bad (1% at the lower end, 1% at the upper end). # That fixes most of the maps, but not all of them. For now, I am just adding/subtracting # an arcsec on either end to counteract the (probable) overcompensation, i.e. # throwing away good coordinate values as well. If the HMI cutout needs to be # *really* precise, this needs to be done more carefully. Right now, the HMI map # might be a bit too small or too large depending on how many coordinate outliers # there are. hinode_xcoords = [np.quantile(hdulist_hinode[38].data,0.01)-1., np.quantile(hdulist_hinode[38].data,0.99)+1.] hinode_ycoords = [np.quantile(hdulist_hinode[39].data,0.01)-1., np.quantile(hdulist_hinode[39].data,0.99)+1.] # Take care of some problematic files in the list manually if fitsfile in ['20170402_210600.fits', '20170403_003405.fits', '20170828_102201.fits', \ '20171009_181600.fits', '20171127_175734.fits', '20180401_215905.fits', \