oversampling, xlims, vlines) time.sleep(1) if phase == True: Lv2_phase.partial_tE(eventfiles[i], par_list, tbin_size, Ebin_size, pulse_pars, shift, no_phase_bins, t1, t2, E1, E2, mode) time.sleep(1) if color == True: Lv2_color.plotting_t(eventfiles[i], par_list, E_bound, tbin_size, t1, t2, mode) if do_average_ps == True: for k in range(0, len(PI1)): for j in range(len(segment_lengths)): for i in range(len(eventfiles)): N = Lv3_detection_level.N_trials(tbin, segment_lengths[j]) if preprocessing == True: if time_segments == True or time_energy_segments == True: Lv2_presto_subroutines.get_gti_file( eventfiles[i], segment_lengths[j]) if time_segments == True: Lv2_presto_subroutines.niextract_gti_time( eventfiles[i], segment_lengths[j]) if time_energy_segments == True: Lv2_presto_subroutines.niextract_gti_time_energy( eventfiles[i], segment_lengths[j], PI1[k], PI2[k]) if demod == True: Lv2_average_ps_methods.do_demodulate(
demod = True merged = True preprocessing = True time_segments = False time_energy_segments = False ##### For merged = False: if merged == False: #eventfile = Lv0_dirs.NICERSOFT_DATADIR + '1034070101_pipe/ni1034070101_nicersoft_bary.evt' eventfile = Lv0_dirs.NICER_DATADIR + '/rxj0209/rxj0209kgfilt_bary.evt' segment_length = 10000 #segment length PI1 = 30 #lower bound for PI PI2 = 200 #upper bound for PI par_file = Lv0_dirs.NICERSOFT_DATADIR + 'J1231-1411.par' #parameter file for demodulation tbin = 0.025 #bin size in s N = Lv3_detection_level.N_trials(tbin,segment_length) threshold = 10 #threshold for counts in each segment W = 1 #number of consecutive Fourier bins to average over starting_freq = 1 #for noise_hist mode = 't' ##### For merged = True: if merged == True: obsids = ['20600603'+str(i) for i in range(61,66)] merged_id = '000013' #need to be very careful that I know what the next one is! eventfile = Lv0_dirs.NICERSOFT_DATADIR + 'merged_events/merged' + merged_id + '/merged' + merged_id + '_nicersoft_bary.evt' segment_length = 500 #segment length mode = 't' par_file = Lv0_dirs.NICERSOFT_DATADIR + 'J1231-1411.par' #parameter file for demodulation PI1 = 30 #lower bound for PI
def plotting(eventfile, segment_length, demod, tbin, threshold, PI1, PI2, t1, t2, starting_freq, W, hist_min_sig, N, xlims, plot_mode): """ Plotting the averaged power spectrum and the noise histogram eventfile - path to the event file. Will extract ObsID from this for the NICER files. segment_length - length of the segments demod - whether we're dealing with demodulated data or not! tbin_size - size of the time bin threshold - if data is under threshold (in percentage), then don't use the segment! PI1 - lower bound of PI (not energy in keV!) desired for the energy range PI2 - upper bound of PI (not energy in keV!) desired for the energy range t1 - starting time for calculation of averaged power spectra t2 - ending time for calculation of averaged power spectra (note that t=0 corresponds to the MET of the FIRST event in the eventfile, so will need to inspect light curve with Lv2_lc.py to get times) starting_freq - frequency to start constructing the histogram of powers from W - number of consecutive frequency bins to AVERAGE over hist_min_sig - minimum significance for a candidate frequency to be added to a text file; will be used to calculate histograms of candidates N - number of trials xlims - limits to apply on the x axis if desired plot_mode - whether to "show" the plots or to "save" them """ if demod != True and demod != False: raise ValueError("demod should either be True or False!") if plot_mode != "show" and plot_mode != "save": raise ValueError("plot_mode should either be 'show' or 'save'!") parent_folder = str(pathlib.Path(eventfile).parent) f, ps, ps_bins, N_greaterthanP, M = average_ps(eventfile, segment_length, demod, tbin, threshold, PI1, PI2, t1, t2, starting_freq, W) power_required_3 = Lv3_detection_level.power_for_sigma( 3, N, M, W) #power required for significance power_required_4 = Lv3_detection_level.power_for_sigma( 4, N, M, W) #power required for significance ### to create the histogram of pulsation candidates ps_sig = Lv3_detection_level.signal_significance(N, M, W, ps) if PI1 == '': output_file = open( parent_folder + '/S' + str(segment_length) + '_W' + str(W) + '_T' + str(threshold) + '_t1t2_' + str(t1) + '-' + str(t2) + '.txt', 'w') else: output_file = open( parent_folder + '/S' + str(segment_length) + '_W' + str(W) + '_T' + str(threshold) + '_E' + str(PI1) + '-' + str(PI2) + '_t1t2_' + str(t1) + '-' + str(t2) + '.txt', 'w') cand_f = f[ ps_sig >= hist_min_sig] #decided not to use hist_min_f ; otherwise I get empty files... cand_ps = ps_sig[ps_sig >= hist_min_sig] for i in range(len(cand_f)): output_file.write(str(cand_f[i]) + ' ' + str(cand_ps[i]) + '\n') output_file.close() plt.figure(num=1, figsize=(10, 5.63)) plt.errorbar(x=f, y=ps, color='r', drawstyle='steps-mid') plt.axhline(y=power_required_3, lw=0.8, alpha=0.5, color='b') plt.axhline(y=power_required_4, lw=0.8, alpha=0.5, color='k') plt.axhline(y=2, lw=0.8, alpha=0.5, color='k', linestyle='--') plt.xlabel('Frequency (Hz)', fontsize=12) plt.ylabel('Leahy-normalized power', fontsize=12) plt.xscale('log') plt.yscale('log') plt.ylim([1, min(20.0, 3 * power_required_4)]) plt.xlim([0.001, 1 / (2 * tbin)]) if len(xlims) != 0: plt.xlim([xlims[0], xlims[1]]) #plt.axvline(x=271.453,lw=0.5,alpha=0.5) plt.title('PI: ' + str(PI1) + '-' + str(PI2) + '; W = ' + str(W) + ', Threshold = ' + str(threshold) + '%' + '\n' + 't1 = ' + str(t1) + ', t2 = ' + str(t2) + ' ; Segment Length: ' + str(segment_length) + 's, No. Segments = ' + str(M) + '\n' + 'Demodulated: ' + str(demod) + ' ; St.D = ' + str(np.std(ps)), fontsize=12) plt.legend(('Power Spectrum', '3 sigma', '4 sigma', 'Poisson noise'), loc='best') if plot_mode == "save": if PI1 != '': energy_suffix = '_E' + str(PI1).zfill(4) + '-' + str(PI2).zfill(4) else: energy_suffix = '' if demod == True: demod_suffix = '_demod' else: demod_suffix = '' plt.savefig(parent_folder + '/' + str(segment_length) + 's_average_ps_W' + str(W) + '_T' + str(threshold) + demod_suffix + energy_suffix + '_t1t2_' + str(t1) + '-' + str(t2) + '.pdf', dpi=900) plt.close() plt.figure(2) plt.semilogy(ps_bins, N_greaterthanP, 'rx') plt.xlabel('Leahy-normalized power', fontsize=12) plt.ylabel('log[N(>P)]', fontsize=12) plt.title('Energy range: ' + str(PI1) + ' - ' + str(PI2) + ', W = ' + str(W), fontsize=12) if plot_mode == "save": if PI1 != '': energy_suffix = '_E' + str(PI1).zfill(4) + '-' + str(PI2).zfill(4) else: energy_suffix = '' if demod == True: demod_suffix = '_demod' else: demod_suffix = '' plt.savefig(parent_folder + '/' + str(segment_length) + 's_noise_hist_W' + str(W) + '_T' + str(threshold) + demod_suffix + energy_suffix + '_t1t2_' + str(t1) + '-' + str(t2) + '.pdf', dpi=900) plt.close() if plot_mode == "show": plt.show()
def dynamic_ps(eventfile, search_window, T, dt, tbin_size, df, f_central, mode): """ Plotting the dynamic power spectrum with both a colormap and a contour map. eventfile - path to the event file. Will extract ObsID from this for the NICER files. search_window - array of two values: [start time for burst searches, end time for burst searches] T - array of window sizes (not time interval) dt - array of time steps between consecutive time windows tbin_size - size of time bins df - frequency window width for the search f_central - central frequency of the search mode - "save" or "show" """ if mode != 'show' and mode != 'save': raise ValueError("Mode should either be 'show' or 'save'!") if len(search_window) != 2: raise ValueError( "search_window should have two values only - start and end times for burst searches" ) parent_folder = str(pathlib.Path(eventfile).parent) ev_header = fits.open(eventfile)[0].header MJDREFI = ev_header['MJDREFI'] MJDREFF = ev_header['MJDREFF'] source_name = ev_header['OBJECT'] obsid = ev_header['OBS_ID'] ### get the time series and zero-ise it #define an array of start times? So do in steps of dt from search_start to search_end times = fits.open(eventfile)[1].data['TIME'] T_zeroized = times - times[0] counts = np.ones(len(T_zeroized)) T_zeroized_trunc = T_zeroized[(T_zeroized >= search_window[0]) & (T_zeroized <= search_window[1])] counts_trunc = np.ones(len(T_zeroized_trunc)) #print(len(T_zeroized),len(T_zeroized_trunc),len(counts_trunc)) T_bins = np.linspace( T_zeroized_trunc[0], np.ceil(T_zeroized_trunc[-1]), np.ceil((T_zeroized_trunc[-1] - T_zeroized_trunc[0]) * 1 / tbin_size + 1)) #print(len(T_bins),T_bins[:20],T_bins[-20:]) binned_counts, bin_edges, binnumber = stats.binned_statistic( T_zeroized_trunc, counts_trunc, statistic='sum', bins=T_bins) #binning the photons #print(len(binned_counts)) for i in tqdm(range(len(T))): #for every window size: output_file = open( parent_folder + '/' + obsid + '_TBO_search_' + str(T[i]) + 's.txt', 'w') output_file.write('Source name: ' + source_name + ' ; ObsID: ' + obsid + '\n') output_file.write('Window size: T = ' + str(T[i]) + 's, stepping size = ' + str(dt[i]) + ' ; dt = ' + str(tbin_size) + '\n') T_start = np.arange(search_window[0], search_window[1], dt[i]) #start time of each sliding window T_end = T_start + T[i] #end time of each sliding window N = T[i] / tbin_size #number of trials for each window sig3 = Lv3_detection_level.power_for_sigma(3, N, 1, 1) sig4 = Lv3_detection_level.power_for_sigma(4, N, 1, 1) sig5 = Lv3_detection_level.power_for_sigma(5, N, 1, 1) output_file.write('Power needed for: 3 sigma - ' + str(sig3) + ' ; 4 sigma - ' + str(sig4) + ' ; 5 sigma - ' + str(sig5) + '\n') output_file.write('Starting/Ending MJD of TBO search scheme: ' + str(MJDREFI + MJDREFF + (times[0] + search_window[0]) / 86400) + '/' + str(MJDREFI + MJDREFF + (times[0] + search_window[1]) / 86400) + '\n') fig, (ax1, ax2, ax3) = plt.subplots( 3, 1, sharex=True ) #dynamic power spectrum #define a 2x1 subplot or something fig.subplots_adjust(hspace=0) f_max = [] #corresponding frequencies to the maximum power ps_max = [ ] #to store the maximum power from each power spectrum of each sliding time series for j in tqdm(range(len(T_start))): #for every sliding window T_search = T_bins[:-1][(T_bins[:-1] >= T_start[j]) & ( T_bins[:-1] <= T_end[j])] #time series to search for burst oscillations binned_search = binned_counts[(T_bins[:-1] >= T_start[j]) & (T_bins[:-1] <= T_end[j])] f, ps = Lv2_ps_method.manual( T_search, binned_search, [False, 400, 500], [False, 400], False, [False, 5]) #calculating Leahy-normalized power spectra f_window = f[(f >= f_central - df) & (f <= f_central + df)] #get frequency values 'df' Hz about f_central ps_window = ps[(f >= f_central - df) & ( f <= f_central + df)] #get powers 'df' Hz about f_central scatt = ax1.scatter(x=np.ones(len(f_window)) * T_start[j], y=f_window, s=12, c=ps_window, marker='o', cmap=cm.gist_heat, vmin=1, vmax=50) f_max.append(f_window[ps_window == np.max(ps_window)][0]) ps_max.append(ps_window[ps_window == np.max(ps_window)][0]) output_file.write('Start time for this window: zeroized - ' + str(T_start[j]) + ' ; MJD - ' + str(MJDREFI + MJDREFF + (times[0] + T_start[j]) / 86400) + '\n') for k in range(len(f_window)): output_file.write( str(f_window[k]) + ' ' + str(ps_window[k]) + ' ' + str( Lv3_detection_level.signal_significance( N, 1, 1, ps_window[k])) + '\n') output_file.close() ps_max = np.array(ps_max) f_max = np.array(f_max) print('The maximum power in the whole plot is ' + str(round(np.max(ps_max), 2)) + ' with corresponding frequency ' + str(f_max[ps_max == np.max(ps_max)][0]) + ' Hz') if mode == "show": mplcursors.cursor(hover=True) ax1.set_title('Window size: ' + str(T[i]) + 's, dt=' + str(dt[i]) + 's \n' + 'Central freq. = ' + str(f_central) + 'Hz, df = ' + str(df) + 'Hz \n Power required for 3 sigma: ' + str(sig3), fontsize=12) ax1.set_ylabel('Frequency (Hz)', fontsize=12) ax1.set_ylim([f_central - df, f_central + df]) ax2.set_ylabel('Frequency (Hz)', fontsize=12) scat = ax2.scatter(x=T_start, y=f_max, s=12, c=ps_max, marker='o', cmap=cm.gist_heat, vmin=np.min(ps_max), vmax=np.max(ps_max), edgecolors='k') if mode == "show": mplcursors.cursor(hover=True) #fig.colorbar(scat,ax=ax1) #fig.colorbar(scat,ax=ax2) ax2.set_ylim([f_central - df, f_central + df]) ps_contour = ax3.tricontour(T_start, f_max, ps_max, levels=30, linewidths=0.5, colors='k') ax3.clabel(ps_contour, fontsize=8) ax3.set_xlabel('Time (s)') ax3.set_ylim([f_central - df, f_central + df]) if mode == "show": mplcursors.cursor(hover=True) plt.show() if mode == "save": filename = obsid + "_TBO_plots_" + str(T[i]) + 's.pdf' plt.savefig(parent_folder + '/' + filename, dpi=900) plt.close()
T_zeroized, counts, statistic='sum', bins=T_bins) #binning the photons for i in tqdm(range(len(T))): #for every window size: output_file = open( Lv0_dirs.NICERSOFT_DATADIR + '2584010501_pipe/TBO_search_' + str(T[i]) + 's.txt', 'w') output_file.write('Source name: ' + source_name + ' ; ObsID: ' + obsid + '\n') output_file.write('Window size: T = ' + str(T[i]) + 's, stepping size = ' + str(dt[i]) + ' ; dt = ' + str(tbin_size) + '\n') T_start = np.arange(search_start, search_end, dt[i]) #start time of each sliding window T_end = T_start + T[i] #end time of each sliding window N = T[i] / tbin_size #number of trials for each window sig3 = Lv3_detection_level.power_for_sigma(3, N, 1, 1) sig4 = Lv3_detection_level.power_for_sigma(4, N, 1, 1) sig5 = Lv3_detection_level.power_for_sigma(5, N, 1, 1) power_required = Lv3_detection_level.power_for_sigma(significance, N, 1, 1) output_file.write('Power needed for: 3 sigma - ' + str(sig3) + ' ; 4 sigma - ' + str(sig4) + ' ; 5 sigma - ' + str(sig5) + '\n') output_file.write('Starting/Ending MJD of TBO search scheme: ' + str(MJDREFI + MJDREFF + (times[0] + search_start) / 86400) + '/' + str(MJDREFI + MJDREFF + (times[0] + search_end) / 86400) + '\n') fig, (ax1, ax2, ax3) = plt.subplots( 3, 1, sharex=True