def compare_bins(evt, model, output):
    fig, ax = plt.subplots(6, 1, figsize=(8,20), sharex=True)
    bin_list = np.arange(50, 350, 50)
    label=False
    for i in tqdm(range(len(bin_list))):
        lc = LightCurve(evt)
        lc.generate(n_phase=2, nbins=bin_list[i])

        if i == 0:
            label=True

        ax[i], popt_tup = lc.fit_two(ax=ax[i], model=model, annotate=False, label=label)

        if i != len(bin_list)-1:
            ax[i].tick_params(labelbottom=False)
            ax[i].set_xlabel("") 
        else:
            ax[i].set_xlabel("Phase", fontsize=30)
        ax[i].set_ylabel("")
        fig.text(.95, .95, str(bin_list[i]), va='top', ha='right', 
                 transform=ax[i].transAxes, fontsize=20)

    fig.text(.04, .5, r'Photon Counts', ha='center', va='center',
             rotation='vertical', fontsize=30)
    plt.subplots_adjust(hspace=0, top=.98, right=.98)
    fig.savefig(output)
def parse_lc_input(lc_input):
    if type(lc_input) == str:
        filename = lc_input
        if not os.path.isfile(filename):
            raise FileNotFoundError
        lc = LightCurve(filename)
        lc.generate()
    elif type(lc_input) == LightCurve:
        lc = lc_input
    else:
        raise TypeError

    return lc
Example #3
0
def find_phase_ranges(evt, lower, upper, nranges, sigma0=3, nbins=100):

    #Parameter Checking
    if type(evt) != str:
        raise ValueError("filename must be string")
    if not os.path.isfile(evt):
        raise FileNotFoundError

    #Create LC object and find peak cutoff regions
    lc = LightCurve(evt)
    lc.generate(nbins=nbins)
    tup = lc.peak_cutoff(lower, upper, sigma0)
    p1_ranges = [
        niutils.phase_correction((tup.min_phase_p1, tup.max_phase_p1))
    ]
    p2_ranges = [
        niutils.phase_correction((tup.min_phase_p2, tup.max_phase_p2))
    ]

    #Iteratively reduce primary ranges
    while (len(p1_ranges) < nranges):
        if p1_ranges[-1][1] - p1_ranges[-1][0] > 0.02:
            newtup = (p1_ranges[-1][0] + .01, p1_ranges[-1][1] - .01)
            p1_ranges.append(newtup)
        else:
            break

    #Iteratively reduce secondary ranges
    while (len(p2_ranges) < nranges):
        if p2_ranges[-1][1] - p2_ranges[-1][0] > 0.02:
            newtup = (p2_ranges[-1][0] + .01, p2_ranges[-1][1] - .01)
            p2_ranges.append(newtup)
        else:
            break

    #Create named tuple output
    rangetup = collections.namedtuple('rangetup', ['p1', 'p2', 'nfound'])
    tup = rangetup(p1_ranges, p2_ranges, min(len(p1_ranges), len(p2_ranges)))
    return tup
def main():
    lc1821 = LightCurve("PSR_B1821-24/PSR_B1821-24_combined.evt")
    lc0218 = LightCurve("PSR_J0218+4232/PSR_J0218+4232_combined.evt")

    fig, ax = plt.subplots(2, 1, figsize=(8, 8))

    ax[0], _ = lc1821.fit_two('lorentzian',
                              ax=ax[0],
                              label=False,
                              annotate=False)
    ax[1], _ = lc0218.fit_two('gaussian',
                              ax=ax[1],
                              label=False,
                              annotate=False)

    ax[1].set_xlabel("Pulse Phase", fontsize=25)
    ax[0].text(.08,
               .95,
               r'PSR B1821$-$24',
               ha='left',
               va='top',
               fontsize=20,
               transform=ax[0].transAxes,
               bbox=dict(facecolor='white', edgecolor='none', alpha=0.6))
    ax[1].text(.08,
               .95,
               r'PSR J0218$+$4232',
               ha='left',
               va='top',
               fontsize=20,
               transform=ax[1].transAxes,
               bbox=dict(facecolor='white', edgecolor='none', alpha=0.6))

    ax[0].tick_params(labelbottom=False)
    #plt.setp(ax[0].get_yticklabels()[0], visible=False)

    fig.text(.04,
             .5,
             r'Photon Counts',
             ha='center',
             va='center',
             rotation='vertical',
             fontsize=25)

    plt.subplots_adjust(hspace=0, bottom=.08, top=.94, right=.98, left=.15)

    fig.savefig("poster_plot.svg")
def zoom_profile(evt, phase_min, phase_max):

    if type(evt) != str:
        raise ValueError("filename must be string")
    if any( [type(v) not in [float, int] for v in [phase_min, phase_max] ]):
        raise ValueError("phase must be int or float")
    if not os.path.isfile(evt):
        raise FileNotFoundError

    fig, ax = plt.subplots(1, 1, figsize=(8,4))

    lc = LightCurve(evt)
    pi_min = energy_min * 100
    pi_max = energy_max * 100
    lc.mask(lower_pi=pi_min, upper_pi=pi_max)
    lc.generate()

    ax = lc.plot(ax=ax)
    ax.set_xlim(left=phase_min, right=phase_max)
    plt.subplots_adjust(bottom=.08, top=.98, right=.98, left=.15)
    plt.show()
def find_min_energy(evt, component):
    if type(evt) != str:
        raise ValueError("filename must be string")
    if type(component) != str:
        raise ValuerError ("component must be string")

    sourcename = process.extract(evt, ['PSR B1821-24', 'PSR B1937+21'], 
                                 limit=1)[0][0]

    attempted_energies = [ round(a, 2) for a in np.arange(0, 2, 0.1) ]
    successful_energies = []
    fig, ax = plt.subplots(len(attempted_energies), 1, figsize=(8, len(attempted_energies)*4))
    for i in range(len(attempted_energies)):
        eng = attempted_energies[i]
        lc = LightCurve(evt)
        a = ax.reshape(-1)[i]
        print(eng)
        lc.mask(lower_pi=0, upper_pi=eng*100)
        lc.generate()
        a, chisq, p, ratio = lc.fit_gauss(component, ax=a)
        if ratio > 1:
            successful_energies.append(eng)
    plt.show()
    return successful_energies
def multiple_profiles(evt, energy_ranges, 
                      fit_two=False, model='gaussian',
                      output=None, show=True, nbins=300):
    if type(evt) != str:
        raise ValueError("filename must be string")
    if type(energy_ranges) not in [list, tuple]:
        raise ValueError("ranges must be entered in lists or tuples")
    for range_pair in energy_ranges:
        if type(range_pair) not in [list, tuple]:
            raise ValueError("ranges must be entered in lists or tuples")
        if len(range_pair) != 2:
            raise ValueError("range must have length 2")
        if any( [type(v) not in [float, int] for v in range_pair] ):
            raise ValueError("value must be int or float")

    sourcename = process.extract(evt, [r'PSR B1821$-$24', r'PSR B1937$+$21',
                                       r'PSR J0218$+$4232'],
                                 limit=1)[0][0]


    fig, ax = plt.subplots(len(energy_ranges), 1, figsize=(8, len(energy_ranges)*3.5))
    ratios = []
    popts  = []
    label_components=True
    for i in range(len(energy_ranges)):
        a = ax.reshape(-1)[i]
        lc = LightCurve(evt)
        name = lc.name
        if fit_two:
            lc.mask(lower_pi=energy_ranges[i][0]*100, 
                    upper_pi=energy_ranges[i][1]*100)
            lc.generate(nbins=nbins)
            a, popt = lc.fit_two(ax=a, model=model, annotate=False, 
                                       label=label_components)

            a, bounds = niutils.add_CharErrBar(a, lc.counts, .95, .80)
            label_components=False

            popts.append(popt)
        else:
            a = energy_filtered_profile(evt, energy_ranges[i][0], 
                                        energy_ranges[i][1], ax=a,
                                        label=False)
        textbox = a.text(
               .95, .95, 
               f"{energy_ranges[i][0]}"+r'$-$'+ f"{energy_ranges[i][1]} keV",
               ha='right', va='top', fontsize=20, transform=a.transAxes, 
               bbox=dict(facecolor='white', edgecolor='none', alpha=.6))
        
        """
        textbox_bounds = [textbox.get_bbox_patch().get_x(),
                          textbox.get_bbox_patch().get_y(),
                          textbox.get_bbox_patch().get_x() + textbox.get_bbox_patch().get_width(),
                          textbox.get_bbox_patch().get_y() + textbox.get_bbox_patch().get_height()]
        print(textbox_bounds)
        """
        text_bottom = (a.get_ylim()[1]-a.get_ylim()[0])*textbox.get_position()[1]+a.get_ylim()[0]
        if text_bottom / bounds[-1] <= 1.035:
            print("here")
            print(a.get_ylim()[1])
            print(1.02*a.get_ylim()[1])
            a.set_ylim(bottom=a.get_ylim()[0], top=1.02*a.get_ylim()[1])



        a.set_xlabel("")
        if i != len(energy_ranges)-1:
            a.tick_params(labelbottom=False)
            #a.yaxis.set_major_locator(ticker.MaxNLocator(prune='lower'))
            #plt.setp(a.get_yticklabels()[0], visible=False)

    if sourcename == r'PSR J0218$+$4232':
        ax.reshape(-1)[0].text(.25, .95, sourcename, ha='left',
                               va='top', transform=ax.reshape(-1)[0].transAxes,
                               fontsize=20)
    else:
        ax.reshape(-1)[0].text(.05, .95, sourcename, ha='left',
                               va='top', transform=ax.reshape(-1)[0].transAxes,
                               fontsize=20)
    ax.reshape(-1)[len(energy_ranges)-1].set_xlabel("Phase", fontsize=25)
    fig.text(.04, .5, r'Photon Counts', ha='center', va='center', 
             rotation='vertical', fontsize=30)
    plt.subplots_adjust(hspace=0, bottom=.08, top=.94, right=.98, left=.15)
    if output is None:
        if show:
            plt.show()
            plt.close()
    else:
        fig.savefig(output, dpi=2000)

    if fit_two:
        return popts