def pf_E(eventfile,par_list,tbin_size,Ebin_size,f_pulse,shift,no_phase_bins,E1,E2,mode): """ Obtain the pulsed fraction from the pulse profile for a desired energy range. eventfile - path to the event file. Will extract ObsID from this for the NICER files. par_list - A list of parameters we'd like to extract from the FITS file (e.g., from eventcl, PI_FAST, TIME, PI,) tbin_size - the size of the time bins (in seconds!) >> e.g., tbin_size = 2 means bin by 2s >> e.g., tbin_size = 0.05 means by in 0.05s Ebin_size - the size of the energy bins (in keV!) >> e.g., Ebin_size = 0.1 means bin by 0.1keV >> e.g., Ebin_size = 0.01 means bin by 0.01keV! f_pulse - the frequency of the pulse shift - how much to shift the pulse by in the phase axis. It only affects how it is presented. no_phase_bins - number of phase bins desired E1 - lower energy boundary E2 - upper energy boundary """ if 'TIME' not in par_list: raise ValueError("You should have 'TIME' in the parameter list!") if type(par_list) != list and type(par_list) != np.ndarray: raise TypeError("par_list should either be a list or an array!") if E2<E1: raise ValueError("E2 should be greater than E1!") if mode != 'show' and mode != 'save' and mode != 'overlap': raise ValueError("Mode should either be 'show' or 'save' or 'overlap'!") phase,counts = Lv2_phase.partial_E(eventfile,par_list,tbin_size,Ebin_size,f_pulse,shift,no_phase_bins,E1,E2,mode) phase_ave_mean = np.mean(counts) variance = np.var(counts) return np.sqrt(variance)/phase_ave_mean
def pf_all(eventfile,par_list,tbin_size,f_pulse,shift,no_phase_bins,mode): """ Obtaining the pulsed fraction from the entire raw pulse profile without any cuts to the data. eventfile - path to the event file. Will extract ObsID from this for the NICER files. par_list - A list of parameters we'd like to extract from the FITS file (e.g., from eventcl, PI_FAST, TIME, PI,) tbin_size - the size of the time bins (in seconds!) >> e.g., tbin_size = 2 means bin by 2s >> e.g., tbin_size = 0.05 means bin by 0.05s! f_pulse - the frequency of the pulse shift - how much to shift the pulse by in the phase axis. It only affects how the pulse profile is 'displaced'. no_phase_bins - number of phase bins desired mode - whether we want to show or save the plot. """ if 'TIME' not in par_list: raise ValueError("You should have 'TIME' in the parameter list!") if type(par_list) != list and type(par_list) != np.ndarray: raise TypeError("par_list should either be a list or an array!") if mode != 'show' and mode != 'save': raise ValueError("Mode should either be 'show' or 'save'!") phase,counts = Lv2_phase.whole(eventfile,par_list,tbin_size,f_pulse,shift,no_phase_bins,mode) phase_ave_mean = np.mean(counts) variance = np.var(counts) #gives the same result as me writing out the formula manually! np.var is ok. return np.sqrt(variance)/phase_ave_mean
def get_pulse_profile(obsid, par_list, tbin_size, f_pulse, shift, no_phase_bins): """ Get pulse profile given binned data and frequency to fold obsid - Observation ID of the object of interest (10-digit str) par_list - A list of parameters we'd like to extract from the FITS file (e.g., from eventcl, PI_FAST, TIME, PI,) tbin_size - the size of the time bins (in seconds!) >> e.g., tbin_size = 2 means bin by 2s >> e.g., tbin_size = 0.05 means bin by 0.05s! f_pulse - the frequency of the pulse shift - how much to shift the pulse by in the phase axis. It only affects how the pulse profile is 'displaced'. no_phase_bins - number of phase bins desired """ if type(obsid) != str: raise TypeError("ObsID should be a string!") if 'TIME' not in par_list: raise ValueError("You should have 'TIME' in the parameter list!") if type(par_list) != list and type(par_list) != np.ndarray: raise TypeError("par_list should either be a list or an array!") t_bins, summed_data = binned_data(obsid, par_list, tbin_size) print("Making plots now.") if type(f_pulse) == np.ndarray or type(f_pulse) == list: for i in range(len(f_pulse)): print(f_pulse[i]) phase, phase_bins, summed_profile = Lv2_phase.pulse_profile( f_pulse[i], t_bins, summed_data, shift, no_phase_bins) print(len(phase_bins), len(summed_profile)) plt.figure(i) plt.title('Frequency: ' + str(f_pulse[i]) + ' Hz', fontsize=12) plt.xlabel('Phase', fontsize=12) plt.ylabel('Counts/s (binned by 0.0005s)', fontsize=12) plt.step(phase_bins[:-1], summed_profile) plt.show() else: phase, phase_bins, summed_profile = Lv2_phase.pulse_profile( f_pulse, t_bins, summed_data, shift, no_phase_bins) plt.step(phase_bins[:-1], summed_profile) plt.title('Frequency: ' + str(f_pulse) + ' Hz', fontsize=12) plt.xlabel('Phase', fontsize=12) plt.ylabel('Counts/s (binned by 0.0005s)', fontsize=12) plt.show()
def pulse_profile(merging, data_id, E_trunc, PI1, PI2, pulse_pars, no_phase_bins): """ Extracts the time series from the demodulated merged event file, and creates the pulse profile from Lv2_phase.py! merging - True/False - whether to use merged data data_id - 10-digit ObsID or 6-digit ID for the merged event file E_trunc - True/False - whether to do energy truncation 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 pulse_pars - parameters corresponding to the pulse no_phase_bins - number of phase bins desired """ if type(data_id) != str: raise TypeError("data_id should be a string!") if len(data_id) != 6 and len(data_id) != 10: raise ValueError("data_id should have 6 or 10 digits in the string!") if E_trunc != True and E_trunc != False: raise ValueError( "E_trunc (energy truncation) should either be True or False!") if type(pulse_pars) != list and type(pulse_pars) != np.ndarray: raise TypeError("pulse_pars should either be a list or an array!") if merging == True: print("Making pulse profile, merging is True!") all_merged_dir = Lv0_dirs.NICERSOFT_DATADIR + 'merged_events/' #directory for the merged events merged_dir = all_merged_dir + 'merged' + data_id + '/' if E_trunc == True: demod_merged_file = merged_dir + 'merged' + data_id + '_nicersoft_bary_E' + str( PI1).zfill(4) + '-' + str(PI2).zfill(4) + '_demod.evt' else: demod_merged_file = merged_dir + 'merged' + data_id + '_nicersoft_bary_demod.evt' else: print("Making pulse profile, merging is False!") if E_trunc == True: demod_merged_file = Lv0_dirs.NICERSOFT_DATADIR + data_id + '_pipe/ni' + data_id + '_nicersoft_bary_E' + str( PI1).zfill(4) + '-' + str(PI2).zfill(4) + '_demod.evt' else: demod_merged_file = Lv0_dirs.NICERSOFT_DATADIR + data_id + '_pipe/ni' + data_id + '_nicersoft_bary_demod.evt' #demod_merged_file = demod_merged_file[:-10] + '.evt' print('Will be using ' + str(demod_merged_file)) event = fits.open(demod_merged_file) times = event[1].data['TIME'] gtis = event[2].data T = sum([(gtis[i][1] - gtis[i][0]) for i in range(len(gtis))]) print('Will be using ' + str(T / 1000) + 'ks worth of data!') phase_bins, summed_profile = Lv2_phase.pulse_folding( times, T, times[0], pulse_pars[0], pulse_pars[1], pulse_pars[2], no_phase_bins) return phase_bins, summed_profile
E_bound = Lv3_E_boundary.E_bound( out_baryfile, par_list, E1_data, E2_data, cut_type, bound) #use Lv3_E_boundary to get boundary energy ############################ FOR WHOLE OBSERVATION ############################ if truncations == 'all': if lc == True: Lv2_lc.whole(out_baryfile, par_list, tbin_size, mode) #light curve time.sleep(1) if ps == True: Lv2_ps.whole(out_baryfile, par_list, tbin_size, mode, ps_type, oversampling, xlims, vlines) #power spectra time.sleep(1) if phase == True: Lv2_phase.whole(out_baryfile, par_list, tbin_size, pulse_pars, shift, no_phase_bins, mode) time.sleep(1) if color == True: Lv2_color.plotting(out_baryfile, par_list, E_bound, tbin_size, mode) ########################## FOR DESIRED TIME INTERVAL ########################## if truncations == 't': if lc == True: Lv2_lc.partial_t(out_baryfile, par_list, tbin_size, t1, t2, mode) #light curve time.sleep(1) if ps == True: Lv2_ps.partial_t(out_baryfile, par_list, tbin_size, t1, t2, mode, ps_type, oversampling, xlims, vlines) #power spectra
for i in range(len(eventfiles)): E_bound = Lv3_E_boundary.E_bound( eventfiles[i], par_list, E1_data, E2_data, cut_type, bound) #use Lv3_E_boundary to get boundary energy ############################ FOR WHOLE OBSERVATION ############################ if truncations == 'all': if lc == True: Lv2_lc.whole(eventfiles[i], par_list, tbin_size, mode) #light curve time.sleep(1) if ps == True: Lv2_ps.whole(eventfiles[i], par_list, tbin_size, mode, ps_type, oversampling, xlims, vlines) #power spectra time.sleep(1) if phase == True: Lv2_phase.whole(eventfiles[i], par_list, tbin_size, pulse_pars, shift, no_phase_bins, mode) time.sleep(1) if color == True: Lv2_color.plotting(eventfiles[i], par_list, E_bound, tbin_size, mode) ########################## FOR DESIRED TIME INTERVAL ########################## if truncations == 't': if lc == True: Lv2_lc.partial_t(eventfiles[i], par_list, tbin_size, t1, t2, mode) #light curve time.sleep(1) if ps == True: Lv2_ps.partial_t(eventfiles[i], par_list, tbin_size, t1, t2, mode, ps_type, oversampling, xlims, vlines) #power spectra
cover.text(0.05,0.75,str(gtis_unshifted)) cover.text(0.05,0.70,'RMS Pulsed Fraction/Fractional RMS Amplitude - ' + str(pf)) pdf.savefig() plt.close() ### SECOND PAGE plt.figure(figsize=(10,8)) Lv2_lc.whole(obsids[i],bary,par_list,tbin_size,'save') pdf.savefig() plt.close() ### THIRD PAGE - PULSE PROFILE if obsids[i] in obsids_freq: plt.figure(figsize=(10,8)) Lv2_phase.partial_E(obsids[i],bary,par_list,tbin_size,Ebin_size,np.float(peakf[0]),shift,no_phase_bins,0.3,Ebound,'overlap') Lv2_phase.partial_E(obsids[i],bary,par_list,tbin_size,Ebin_size,np.float(peakf[0]),shift,no_phase_bins,Ebound,12,'overlap') Lv2_phase.partial_E(obsids[i],bary,par_list,tbin_size,Ebin_size,np.float(peakf[0]),shift,no_phase_bins,0.3,12,'overlap') plt.title('Pulse profile for ' + obj_name + ', ObsID ' + str(obsids[i])+ '\n Energy range: ' + str(E1) + 'keV - ' + str(E2) + 'keV',fontsize=12) plt.legend((str(E1) + '-'+str(Ebound) + ' keV',str(Ebound)+'-'+str(E2)+' keV', str(E1)+'-'+str(E2)+' keV'),loc='best') pdf.savefig() plt.close() for j in range(0,len(gtis_shifted),2): plt.figure(figsize=(8.27,11.69)) Lv2_lc.partial_t(obsids[i],bary,par_list,tbin_size,gtis_shifted[j],gtis_shifted[j+1],'save') pdf.savefig() plt.close() plt.figure(figsize=(8.27,11.69)) Lv2_color.plotting_t(obsids[i],bary,par_list,Ebound,tbin_size,gtis_shifted[j],gtis_shifted[j+1],'save')
fig,ax = plt.subplots() chi2 = np.array(chi2) #secax = ax.secondary_xaxis('top',functions=(fdot_to_pdot,pdot_to_fdot)) #secax.set_xlabel('Period Derivative (1E-7 s/s)',fontsize=12) #print(np.max(chi2),freqs[chi2==np.max(chi2)]) ax.plot(freqs,chi2,'rx-') ax.set_xlabel('Frequency (Hz)',fontsize=12) ax.set_ylabel('chi^2 [ sum( (profile-mean)^2/error^2) ]',fontsize=12) plt.show() """ ##### Using Lv2_phase plt.figure() phase, profile, profile_error = Lv2_phase.pulse_folding( times_xmm, T_xmm, T0_MJD_xmm, 1 / pb, freqdot, freqdotdot, nbins, "XMM") plt.errorbar(x=phase[:-1], y=profile, yerr=profile_error, color='r', drawstyle='steps-mid') expos = Lv2_phase.phase_exposure(times_xmm[0] - times_xmm[0], times_xmm[-1] - times_xmm[0], pb, nbin=nbins, gtis=np.array(gtis_conform) - times_xmm[0]) total_expos = np.array(list(expos) + list(expos)) plt.errorbar(x=phase[:-1], y=profile / total_expos, yerr=profile_error / total_expos,
0.20846118761251825, 0.2080718358508059, 0.20854506857953284, 0.20796037636355533, 0.20799884640430513, 0.20854272550784736 ]) for i in range(len(obsids)): data_dict = Lv0_call_eventcl.get_eventcl(obsids[i], bary, par_list) times = data_dict['TIME'] counts = np.ones(len(times)) print(len(times), len(counts)) shifted_t = times - times[0] t_bins = np.linspace(0, int(shifted_t[-1]), int(shifted_t[-1]) * 1 / tbin_size + 1) summed_data, bin_edges, binnumber = stats.binned_statistic( shifted_t, counts, statistic='sum', bins=t_bins) #binning the time values in the data phase_bins, pulse_profile = Lv2_phase.pulse_profile( f_ave, times, counts, 0.5, 40) print(sum(pulse_profile)) phase_bins_f, pulse_profile_f = Lv2_phase.pulse_profile( f[i], times, counts, 0.5, 40) plt.figure(i) plt.title(obsids[i], fontsize=12) plt.xlabel('Phase', fontsize=12) plt.ylabel('Count/' + str(tbin_size) + 's') plt.plot(phase_bins[:-1], pulse_profile, 'rx-', alpha=0.5) plt.plot(phase_bins_f[:-1], pulse_profile_f, 'bx-', alpha=0.5) plt.legend(( 'Average f', 'Pulse f', ), loc='best')
""" nphase = 20 ##### using foldAt phases = foldAt(x, pb, T0=0) ##### using phase mod 1 phase_mod = (1 / pb * x) % 1 #or shift by -0.7*pb ##### using stingray.pulse.pulsar phase_stingray = pulse_phase(x, [1 / pb]) #,ph0=1-0.7) expocorr = Lv2_phase.phase_exposure(times[0] - times[0], times[-1] - times[0], period=pb, nbin=nphase, gtis=gtis_conform) ################################################################################ ##### Testing the 3 different routines for calculating phase phase_bins = np.linspace(0, 1, nphase + 1) profile, bin_edges, binnumber = stats.binned_statistic(phases, y, statistic='mean', bins=nphase) profile_mod, bin_edges, binnumber = stats.binned_statistic(phase_mod, y, statistic='mean',
sin1 = np.sin(2 * np.pi * freq1 * times1) timeseries1 = sin1 + np.random.normal(0, 0.2, len(times1)) zeromean1 = timeseries1 - np.mean(timeseries1) timeseries_power1 = sum(zeromean1**2) ### Doing the FFT fft1 = np.abs(np.fft.fft(zeromean1))**2 freqs1 = np.fft.fftfreq(zeromean1.size, times1[1] - times1[0]) ### 1/N * sum of squares of FFT powers fft_power1 = sum(fft1) / len(fft1) print(fft_power1 / timeseries_power1) ### Doing the pulse profile phases1, phasebins1, summed_prof1 = Lv2_phase.pulse_profile( freq1, times1, sin1, 0, 101) ### Doing FFT of the pulse profile fft_phase1 = np.abs(np.fft.fft(summed_prof1))**2 freqs_phase1 = np.fft.fftfreq(summed_prof1.size, (phasebins1[1] - phasebins1[0]) * 1 / freq1) plt.figure(1) plt.plot(freqs1, fft1) #plt.plot(times1,sin1,'r') plt.figure(2) plt.step(phasebins1[:-1], summed_prof1, 'r') plt.figure(3) plt.hist(np.log10(fft1), bins=100, log=True) #plt.plot(times1,sin1,'b-')