def animate( obs ): ts = np.array( obs.sji[0].get_timestamps() ) start_date = obs.raster("Mg II k").time_specific_headers[0]['DATE_OBS'] stop_date = obs.raster("Mg II k").time_specific_headers[-1]['DATE_OBS'] i_start_sji = np.argmin( np.abs( ts - to_epoch( from_Tformat( start_date ) ) ) ) i_stop_sji = np.argmin( np.abs( ts - to_epoch( from_Tformat( stop_date ) ) ) ) return obs.sji[0].animate( index_start=i_start_sji, index_stop=i_stop_sji, cutoff_percentile=99.0 )
def find_sji_inds( obs ): ts = np.array( obs.sji[0].get_timestamps() ) start_date = obs.raster("Mg II k").time_specific_headers[0]['DATE_OBS'] stop_date = obs.raster("Mg II k").time_specific_headers[-1]['DATE_OBS'] i_start_sji = np.argmin( np.abs( ts - to_epoch( from_Tformat( start_date ) ) ) ) i_stop_sji = np.argmin( np.abs( ts - to_epoch( from_Tformat( stop_date ) ) ) ) return i_start_sji, i_stop_sji
def extract_flare( obs, lambda_min, lambda_max, n_bins, length_minutes=25, flare_margin_minutes=1, savedir="level_2A/", data_format="hdf5", verbosity_level=1 ): raster = obs.raster("Mg II k") # get event info of closest flare mx_flares = obs.goes.events.get_flares( classes="MX" ) closest_flare = mx_flares.iloc[0] # extract raster_pos=0 indices of flare start and stop start_time = from_Tformat( closest_flare['event_starttime'] ) stop_time = from_Tformat( closest_flare['event_endtime'] ) ts = np.array( raster.get_timestamps( raster_pos=0 ) ) start = np.argmin( np.abs(ts-to_epoch(start_time) ) ) stop = np.argmin( np.abs(ts-to_epoch(stop_time) ) ) eff_start_time = from_Tformat( raster.get_raster_pos_headers( raster_pos=0 )[start]['DATE_OBS'] ) eff_stop_time = from_Tformat( raster.get_raster_pos_headers( raster_pos=raster.n_raster_pos-1 )[stop]['DATE_OBS'] ) # plot GOES curve if verbosity_level >= 2: plot_goes_flux( obs, start, stop ) if verbosity_level >= 1: print( "Cutting raster from indices {}-{} --> {:.1f} minutes (of {:.1f} minutes total flare duration)".format( start, stop, (eff_stop_time-eff_start_time).seconds/60, (stop_time-start_time).seconds/60 ) ) # cut the raster raster.cut( raster.get_global_raster_step( raster_pos=0, raster_step=start ), raster.get_global_raster_step( raster_pos=0, raster_step=stop+1 ) ) # show animation if verbosity_level >= 2: display( animate( obs ) ) print("HEK URL:") display( obs.get_hek_url() ) # save the data # print( "Saving data.." ) data = get_interpolated_raster_data( raster, lambda_min, lambda_max, n_bins ) # save_data( data, raster.headers, savedir, "{}_{}".format( "FL", obs.full_obsid ) ) if verbosity_level >= 1: full_obs_timedelta = np.round( ( from_Tformat( raster.time_specific_headers[-1]['DATE_OBS'] ) - from_Tformat( raster.time_specific_headers[0]['DATE_OBS'] ) ).seconds/60, 1 ) print("Raster is {} minutes long after cut".format( full_obs_timedelta ) ) print( "data Shape: {}, raster shape: {}, n_raster_pos: {}".format( data.shape, raster.shape, raster.n_raster_pos ) ) try: sji = obs.sji("Mg II h/k 2796") except: sji = obs.sji("Si") return data, raster, sji
def get_timestamps( self, raster_pos=None ): """ Converts DATE_OBS to milliseconds since 1970 with the aim to make timestamp comparisons easier. Parameters ---------- raster_pos : int raster position (between 0 and n_raster_pos) Returns ------- float : List of millisecond timestamps. """ if raster_pos is None: headers = self.time_specific_headers else: headers = self.get_raster_pos_headers( raster_pos ) return [to_epoch( from_Tformat( h['DATE_OBS'] ) ) for h in headers]
def animate(self, clr_dic, labels, gamma=0.2, cutoff_percentile=99.9, figsize=(15, 15), transparency=.5, marker_size=5, x_range=None, y_range=None, save_path=None): ''' Setup the first step in the animation. Input - clr_dic: dictionary of colrs associated to each centroid - labels: labels from k-means indicating which centroid each spectra is best represented by. Lables could also be a vector of feature values. - gamma: exponent for gamma correction that adjusts the plot color scale - cutoff_percentile: "often the maximum pixels shine out everything else, even after gamma correction. In order to reduce this effect, the percentile at which to cut the intensity off can be specified with cutoff_percentile in a range between 0 and 100". - transparency: adjust the transparency of the centroid mask (0=transparent, 1=opaque) - marker_size: adjust the size of each marker denoting the spectra position on the SJI - save_path: specify a path to save the data Returns - centroid or feature masked SJI animation of the specified observation. ''' step = 0 fig = plt.figure(figsize=figsize) sji_raster_pos = self.sji_raster(self.steps) times = [ to_epoch(from_Tformat(self.hdrs[sji_raster_pos][i]['DATE_OBS'])) for i in range(self.n_rasters) ] sjiind = np.argmin( np.abs(np.array(self.sji.get_timestamps()) - times[step])) image = self.sji.get_image_step(sjiind).clip(min=0.01)**gamma vmax = np.percentile(image, cutoff_percentile) # constant im = plt.imshow(image, cmap="Greys", vmax=vmax, origin='lower') centroid_mask = self.get_raster_centroid_mask(step, clr_dic, labels) # plot slits slits = np.vstack( (np.asarray(centroid_mask['x']), np.asarray(centroid_mask['y']))) slit_mask = plt.scatter(centroid_mask['x'], centroid_mask['y'], c='white', s=.1) # plot centroid mask clean_centroid_mask = self.clean_mask(step, centroid_mask['x'], centroid_mask['y'], centroid_mask['c']) if self.mode == 'cluster': clrs = clean_centroid_mask['c'] if self.mode == 'features': cmap = plt.cm.get_cmap(self.hmap) clrs = cmap(clean_centroid_mask['c']) scat = plt.scatter(clean_centroid_mask['x'], clean_centroid_mask['y'], c=clrs, s=marker_size, alpha=transparency) date_obs = self.sji.headers[sjiind]['DATE_OBS'] im.axes.set_title("Frame {}: {}".format(step, date_obs), fontsize=18, alpha=.8) plt.xlim(x_range[0], x_range[1]) plt.ylim(y_range[0], y_range[1]) plt.close(fig) # do nothing in the initialization function def init(): return im, # animation function def update(i): ''' Update the data for each successive raster. ''' sjiind = np.argmin( np.abs(np.array(self.sji.get_timestamps()) - times[i])) date_obs = self.sji.headers[sjiind]['DATE_OBS'] im.axes.set_title("Frame {}: {}".format(i, date_obs), fontsize=18, alpha=.8) im.set_data(self.sji.get_image_step(sjiind).clip(min=0.01)**gamma) centroid_mask = self.get_raster_centroid_mask( 0, clr_dic, labels) # make 0->i but doesnt seem to work slits = np.vstack((np.asarray(centroid_mask['x']), np.asarray(centroid_mask['y']))) slit_mask.set_offsets(slits.T) clean_centroid_mask = self.clean_mask(i, centroid_mask['x'], centroid_mask['y'], centroid_mask['c']) dd = np.vstack((np.asarray(clean_centroid_mask['x']), np.asarray(clean_centroid_mask['y']))) scat.set_offsets(dd.T) if self.mode == 'cluster': scat.set_color(clean_centroid_mask['c']) if self.mode == 'features': cmap = plt.cm.get_cmap(self.hmap) scat.set_color(cmap(clean_centroid_mask['c'])) return im, # Call the animator. blit=True means only re-draw the parts that have changed. anim = animation.FuncAnimation(fig, lambda i: update(i), init_func=init, frames=self.n_rasters, interval=200, blit=True) # Save animation if requested if save_path is not None: anim.save(save_path) # Show animation in notebook return HTML(anim.to_html5_video())