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