Example #1
0
 def sanity_compAirmasses(self):
   """
     Compare different airmass calculations
   """
   from PyAstronomy import pyasl
   for za in range(0,70,10):
     ampp = pyasl.airmassPP(za)
     amsp = pyasl.airmassSpherical(za, 0.0)
     self.assertAlmostEqual(ampp/amsp, 1.0, delta=0.01)
Example #2
0
  def sanity_airmassPPExample(self):
    """
      Example for plane-parallel airmass
    """
    from PyAstronomy import pyasl

    print "Airmass for plane-parallel atmosphere"
    for za in range(0,70,10):
      print "Zenith angle: %2d deg, airmass = %7.2f" % \
        (za, pyasl.airmassPP(za))
def StarObsPlot(year=None,
                targets=None,
                observatory=None,
                period=None,
                hover=False,
                sunless_hours=None,
                remove_watermark=False):
    """
    Plot the visibility of target.

    Parameters
    ----------
    year: int
        The year for which to calculate the visibility.
    targets: list
        List of targets.
        Each target should be a dictionary with keys 'name' and 'coord'.
        The key 'name' is a string, 'coord' is a SkyCoord object.
    observatory: string
        Name of the observatory that pyasl.observatory can resolve.
        Basically, any of pyasl.listObservatories().keys()
    period: string, optional
        ESO period for which to calculate the visibility. Overrides `year`.
    hover: boolean, optional
        If True, color visibility lines when mouse over.
    sunless_hours: float, optional
        If not None, plot sunless hours above this airmass
  """

    from mpl_toolkits.axes_grid1 import host_subplot
    from matplotlib.ticker import MultipleLocator
    from matplotlib.font_manager import FontProperties
    from matplotlib import rcParams
    rcParams['xtick.major.pad'] = 12
    font0 = FontProperties()
    font1 = font0.copy()
    font0.set_family('sans-serif')
    font0.set_weight('light')
    font1.set_family('sans-serif')
    font1.set_weight('medium')

    # set the observatory
    if isinstance(observatory, dict):
        obs = observatory
    else:
        obs = pyasl.observatory(observatory)

    fig = plt.figure(figsize=(15, 10))
    fig.subplots_adjust(left=0.07, right=0.8, bottom=0.15, top=0.88)

    # watermak
    if not remove_watermark:
        fig.text(0.99,
                 0.99,
                 'Created with\ngithub.com/iastro-pt/ObservationTools',
                 fontsize=10,
                 color='gray',
                 ha='right',
                 va='top',
                 alpha=0.5)

    # plotting sunless hours?
    shmode = False
    if sunless_hours is not None:
        shmode = True
        # limit in airmass (assumed plane-parallel atm)
        shairmass = sunless_hours
        # correspoing limit in altitude
        from scipy.optimize import bisect
        shalt = 90 - bisect(lambda alt: pyasl.airmassPP(alt) - shairmass, 0,
                            89)

    if shmode:
        fig.subplots_adjust(hspace=0.35)
        ax = host_subplot(211)
        axsh = host_subplot(212)
        plt.text(0.5,
                 0.47,
                 "- sunless hours above airmass {:.1f} - \n".format(shairmass),
                 transform=fig.transFigure,
                 ha='center',
                 va='bottom',
                 fontsize=12)
        plt.text(0.5, 0.465,
              "the thick line above the curves represents the total sunless hours "\
              "for each day of the year",
              transform=fig.transFigure, ha='center', va='bottom', fontsize=10)

    else:
        ax = host_subplot(111)

    for n, target in enumerate(targets):

        target_coord = target['coord']
        target_ra = target_coord.ra.deg
        target_dec = target_coord.dec.deg

        if period is not None:
            jd_start, jd_end = get_ESO_period(period)
        else:
            jd_start = pyasl.jdcnv(dt.datetime(year, 1, 1))
            jd_end = pyasl.jdcnv(dt.datetime(year, 12, 31))

        jdbinsize = 1  # every day
        each_day = np.arange(jd_start, jd_end, jdbinsize)
        jds = []

        ## calculate the mid-dark times
        sun = ephem.Sun()
        for day in each_day:
            date_formatted = '/'.join([str(i) for i in pyasl.daycnv(day)[:-1]])
            s = ephem.Observer()
            s.date = date_formatted
            s.lat = ':'.join([str(i) for i in decdeg2dms(obs['latitude'])])
            s.lon = ':'.join([str(i) for i in decdeg2dms(obs['longitude'])])
            jds.append(ephem.julian_date(s.next_antitransit(sun)))

        jds = np.array(jds)

        # Get JD floating point
        jdsub = jds - np.floor(jds[0])

        # Get alt/az of object
        altaz = pyasl.eq2hor(jds, np.ones_like(jds)*target_ra, np.ones_like(jds)*target_dec, \
                            lon=obs['longitude'], lat=obs['latitude'], alt=obs['altitude'])
        ax.plot(jdsub, altaz[0], '-', color='k')

        # label for each target
        plabel = "[{0:2d}]  {1!s}".format(n + 1, target['name'])

        # number of target at the top of the curve
        ind_label = np.argmax(altaz[0])
        # or at the bottom if the top is too close to the corners
        # if jdsub[ind_label] < 5 or jdsub[ind_label] > jdsub.max()-5:
        #   ind_label = np.argmin(altaz[0])
        ax.text( jdsub[ind_label], altaz[0][ind_label], str(n+1), color="b", fontsize=14, \
                 fontproperties=font1, va="bottom", ha="center")

        if n + 1 == 29:
            # too many?
            ax.text(1.1, 1.0-float(n+1)*0.04, "too many targets", ha="left", va="top", transform=ax.transAxes, \
                    fontsize=10, fontproperties=font0, color="r")
        else:
            ax.text(1.1, 1.0-float(n+1)*0.04, plabel, ha="left", va="top", transform=ax.transAxes, \
                    fontsize=12, fontproperties=font0, color="b")

    if shmode:
        sunless_hours = []
        for day in each_day:
            date_formatted = '/'.join([str(i) for i in pyasl.daycnv(day)[:-1]])
            s = ephem.Observer()
            s.date = date_formatted
            s.lat = ':'.join([str(i) for i in decdeg2dms(obs['latitude'])])
            s.lon = ':'.join([str(i) for i in decdeg2dms(obs['longitude'])])
            # hours from sunrise to sunset
            td = pyasl.daycnv(ephem.julian_date(s.next_setting(sun)), mode='dt') \
                  - pyasl.daycnv(ephem.julian_date(s.next_rising(sun)), mode='dt')
            sunless_hours.append(24 - td.total_seconds() / 3600)

        days = each_day - np.floor(each_day[0])
        axsh.plot(days, sunless_hours, '-', color='k', lw=2)
        axsh.set(
            ylim=(0, 15),
            yticks=range(1, 15),
            ylabel='Useful hours',
            yticklabels=[r'${}^{{\rm h}}$'.format(n) for n in range(1, 15)])


    ax.text(1.1, 1.03, "List of targets", ha="left", va="top", transform=ax.transAxes, \
            fontsize=12, fontproperties=font0, color="b")

    axrange = ax.get_xlim()

    if period is None:
        months = range(1, 13)
        ndays = [0] + [calendar.monthrange(date, m)[1] for m in months]
        ax.set_xlim([0, 366])
        ax.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays) / 2.)[1:])
        ax.set_xticklabels(map(calendar.month_abbr.__getitem__, months),
                           fontsize=10)
        if shmode:
            axsh.set_xlim([0, 366])
            axsh.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays) / 2.)[1:])
            axsh.set_xticklabels(map(calendar.month_abbr.__getitem__, months),
                                 fontsize=10)
    else:
        if int(period) % 2 == 0:
            # even ESO period, Oct -> Mar
            months = [10, 11, 12, 1, 2, 3]
            ndays = [0] + [calendar.monthrange(date, m)[1] for m in months]
            ax.set_xlim([0, 181])
            ax.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays) / 2.)[1:])
            ax.set_xticklabels(map(calendar.month_abbr.__getitem__, months),
                               fontsize=10)
            if shmode:
                axsh.set_xlim([0, 181])
                axsh.set_xticks(
                    np.cumsum(ndays)[:-1] + (np.array(ndays) / 2.)[1:])
                axsh.set_xticklabels(map(calendar.month_abbr.__getitem__,
                                         months),
                                     fontsize=10)
        else:
            # odd ESO period, Apr -> Sep
            months = range(4, 10)
            ndays = [0] + [calendar.monthrange(date, m)[1] for m in months]
            ax.set_xlim([0, 182])
            ax.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays) / 2.)[1:])
            ax.set_xticklabels(map(calendar.month_abbr.__getitem__, months),
                               fontsize=10)
            if shmode:
                axsh.set_xlim([0, 182])
                axsh.set_xticks(
                    np.cumsum(ndays)[:-1] + (np.array(ndays) / 2.)[1:])
                axsh.set_xticklabels(map(calendar.month_abbr.__getitem__,
                                         months),
                                     fontsize=10)

    if axrange[1] - axrange[0] <= 1.0:
        jdhours = np.arange(0, 3, 1.0 / 24.)
        utchours = (np.arange(0, 72, dtype=int) + 12) % 24
    else:
        jdhours = np.arange(0, 3, 1.0 / 12.)
        utchours = (np.arange(0, 72, 2, dtype=int) + 12) % 24

    # Make ax2 responsible for "top" axis and "right" axis
    ax2 = ax.twin()
    # Set upper x ticks
    ax2.set_xticks(np.cumsum(ndays))
    ax2.set_xlabel("Day")

    # plane-parallel airmass
    airmass_ang = np.arange(10, 81, 5)
    geo_airmass = pyasl.airmass.airmassPP(airmass_ang)[::-1]
    ax2.set_yticks(airmass_ang)
    airmassformat = []
    for t in range(geo_airmass.size):
        airmassformat.append("{0:2.2f}".format(geo_airmass[t]))
    ax2.set_yticklabels(airmassformat)  #, rotation=90)
    ax2.set_ylabel("Relative airmass", labelpad=32)
    ax2.tick_params(axis="y", pad=6, labelsize=8)
    plt.text(1.02,-0.04, "Plane-parallel", transform=ax.transAxes, ha='left', \
             va='top', fontsize=10, rotation=90)

    ax22 = ax.twin()
    ax22.set_xticklabels([])
    ax22.set_frame_on(True)
    ax22.patch.set_visible(False)
    ax22.yaxis.set_ticks_position('right')
    ax22.yaxis.set_label_position('right')
    ax22.spines['right'].set_position(('outward', 30))
    ax22.spines['right'].set_color('k')
    ax22.spines['right'].set_visible(True)
    airmass2 = list(
        map(
            lambda ang: pyasl.airmass.airmassSpherical(90. - ang, obs[
                'altitude']), airmass_ang))
    ax22.set_yticks(airmass_ang)
    airmassformat = []
    for t in range(len(airmass2)):
        airmassformat.append(" {0:2.2f}".format(airmass2[t]))
    ax22.set_yticklabels(airmassformat, rotation=90)
    ax22.tick_params(axis="y", pad=8, labelsize=8)
    plt.text(1.05,-0.04, "Spherical+Alt", transform=ax.transAxes, ha='left', va='top', \
             fontsize=10, rotation=90)

    ax.set_ylim([0, 91])
    ax.yaxis.set_major_locator(MultipleLocator(15))
    ax.yaxis.set_minor_locator(MultipleLocator(5))
    yticks = ax.get_yticks()
    ytickformat = []
    for t in range(yticks.size):
        ytickformat.append(str(int(yticks[t])) + r"$^\circ$")
    ax.set_yticklabels(ytickformat, fontsize=16)
    ax.set_ylabel("Altitude", fontsize=18)
    yticksminor = ax.get_yticks(minor=True)
    ymind = np.where(yticksminor % 15. != 0.)[0]
    yticksminor = yticksminor[ymind]
    ax.set_yticks(yticksminor, minor=True)
    m_ytickformat = []
    for t in range(yticksminor.size):
        m_ytickformat.append(str(int(yticksminor[t])) + r"$^\circ$")
    ax.set_yticklabels(m_ytickformat, minor=True)
    ax.set_ylim([0, 91])

    ax.yaxis.grid(color='gray', linestyle='dashed')
    ax.yaxis.grid(color='gray', which="minor", linestyle='dotted')
    ax2.xaxis.grid(color='gray', linestyle='dotted')

    if period is not None:
        plt.text(
            0.5,
            0.95,
            "Visibility over P{0!s}\n - altitudes at mid-dark time -".format(
                period),
            transform=fig.transFigure,
            ha='center',
            va='bottom',
            fontsize=12)
    else:
        plt.text(
            0.5,
            0.95,
            "Visibility over {0!s}\n - altitudes at mid-dark time -".format(
                date),
            transform=fig.transFigure,
            ha='center',
            va='bottom',
            fontsize=12)

    obsco = "Obs coord.: {0:8.4f}$^\circ$, {1:8.4f}$^\circ$, {2:4f} m".format(
        obs['longitude'], obs['latitude'], obs['altitude'])

    plt.text(0.01,
             0.97,
             obsco,
             transform=fig.transFigure,
             ha='left',
             va='center',
             fontsize=10)
    plt.text(0.01,
             0.95,
             obs['name'],
             transform=fig.transFigure,
             ha='left',
             va='center',
             fontsize=10)

    # interactive!
    if hover:
        main_axis = fig.axes[0]
        all_lines = set(main_axis.get_lines())

        def on_plot_hover(event):
            for line in main_axis.get_lines():
                if line.contains(event)[0]:
                    line.set_color('red')  # make this line red
                    # and all others black
                    all_other_lines = all_lines - set([line])
                    for other_line in all_other_lines:
                        other_line.set_color('black')
                    fig.canvas.draw_idle()

        fig.canvas.mpl_connect('motion_notify_event', on_plot_hover)

    return fig
Example #4
0
def JupiterPlotEW(DateUT, BandID, Grating, FluxType='Albedo'):
    #JupiterPlotEW("20150123UT","619CH4","100lpm-550CLR")
    import sys
    sys.path.append('f:\Astronomy\Projects\Jupiter\Spectral Data')
    sys.path.append('f:\\Astronomy\Python Play')
    sys.path.append('f:\\Astronomy\Python Play\Utils')
    sys.path.append('f:\\Astronomy\Python Play\Spectrophotometry\Spectroscopy')

    import astropy.units as u
    from astropy.time import Time
    from astropy.coordinates import SkyCoord, EarthLocation, AltAz
    import numpy as np
    import ephem
    import EquivWidthUtils as EWU
    from PyAstronomy import pyasl
    import matplotlib.pyplot as pl
    import PlotUtils as PU
    import ConfigFiles as CF
    from scipy import interpolate

    TimePlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    TimePlot.loadplotparams("f:", "Jupiter_" + BandID, "Time")
    AirmassPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    AirmassPlot.loadplotparams("f:", "Jupiter_" + BandID, "Airmass")
    CMIIPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    CMIIPlot.loadplotparams("f:", "Jupiter_" + BandID, "CMII")
    PWVPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    PWVPlot.loadplotparams("f:", "Earth_PWV", "Time")
    PressPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    PressPlot.loadplotparams("f:", "Earth_Press", "Time")
    TempFPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    TempFPlot.loadplotparams("f:", "Earth_TempF", "Time")
    Earth_Airmass = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    Earth_Airmass.loadplotparams("f:", "Earth_Airmass", "Time")

    CalibrationStars = {
        '20150123UT': "Pollux",
        '20150209UT': "Pollux",
        '20150210UT': "Pollux",
        '20150318UT': "Pollux",
        '20150322UT': "Pollux",
        '20150331UT': "Pollux"
    }
    CalibrationDates = {
        '20150123UT': '2015-01-23 05:54:00',
        '20150209UT': '2015-02-10 05:54:00',
        '20150210UT': '2015-02-10 05:54:00',
        '20150318UT': '2015-03-18 05:54:00',
        '20150322UT': '2015-03-22 05:54:00',
        '20150331UT': '2015-03-22 05:54:00'
    }
    ResponseFile = {
        '20150123UT': 'PolluxResponse20150123UT.txt',
        '20150209UT': 'PolluxResponse20150210UT.txt',
        '20150210UT': 'PolluxResponse20150210UT.txt',
        '20150318UT': 'PolluxResponse20150318UT.txt',
        '20150322UT': 'PolluxResponse20150322UT.txt',
        '20150331UT': 'PolluxResponse20150322UT.txt'
    }

    Pollux = SkyCoord.from_name('Pollux')
    observer = ephem.Observer()
    #Location from Google Maps at 483 S Oneida Way, Denver 80224
    observer.lon = ephem.degrees('-104.907985')
    observer.lat = ephem.degrees('39.708200')
    print float(observer.lat) * 180 / np.pi
    Oneida = EarthLocation(lat=float(observer.lat) * u.rad,
                           lon=float(observer.lon) * u.rad,
                           height=1500 * u.m)
    utcoffset = 0 * u.hour  # Universal Time
    time = Time(CalibrationDates[DateUT]) - utcoffset

    Polluxaltaz = Pollux.transform_to(AltAz(obstime=time, location=Oneida))
    print Polluxaltaz.alt.deg
    print("Pollux's Altitude = {0.alt:.2}".format(Polluxaltaz))
    print Polluxaltaz.secz

    AEWs = EWU.EWObservations("../EWs/" + DateUT + "-" + Grating +
                              "-Albedo-EW.txt")
    AEWs.load_records("Jupiter", BandID)
    REWs = EWU.EWObservations("../EWs/" + DateUT + "-" + Grating +
                              "-RawFlux-EW.txt")
    REWs.load_records("Jupiter", BandID)
    #print EWs.DateTimeUTObs
    #print EWs.EW
    ########################################################
    TimePlot.Setup_PlotDate(min(AEWs.DateTimeUTObs),
                            max(AEWs.DateTimeUTObs),
                            1,
                            canvas_size=[8.0, 6.0],
                            subplot=[4, 1, 1])
    lbl = BandID + " REW " + str(round(np.mean(REWs.EW), 3)) + "$\pm$" + str(
        round(np.std(REWs.EW), 3))
    pl.plot_date(REWs.DateTimeUTObs, REWs.EW, label=lbl)
    lbl = BandID + " AEW " + str(round(np.mean(AEWs.EW), 3)) + "$\pm$" + str(
        round(np.std(AEWs.EW), 3))
    pl.plot_date(AEWs.DateTimeUTObs, AEWs.EW, label=lbl)
    pl.ylabel("Equiv. Width (nm)", fontsize=7)
    pl.legend(loc=2, ncol=3, fontsize=6, scatterpoints=1)
    pl.title("Jupiter " + DateUT + " " + BandID)
    print "Average AEW, Std. Dev., 95% Conf.= ",np.mean(AEWs.EW),np.std(AEWs.EW),\
            1.96*np.std(AEWs.EW)/np.sqrt(len(AEWs.EW))
    print "Average REW, Std. Dev., 95% Conf.= ",np.mean(REWs.EW),np.std(REWs.EW),\
            1.96*np.std(REWs.EW)/np.sqrt(len(REWs.EW))
    ########################################################
    print PWVPlot.DataFile
    Earth_atmo = CF.Observing_Conditions(PWVPlot.DataFile)
    print DateUT[0:4] + '-' + DateUT[4:6] + '-' + DateUT[6:8]
    Earth_atmo.load_records(DateUT[0:4] + '-' + DateUT[4:6] + '-' +
                            DateUT[6:8])
    AX = PWVPlot.Setup_PlotDate(min(AEWs.DateTimeUTObs),
                                max(AEWs.DateTimeUTObs),
                                1,
                                new_canvas=False,
                                subplot=[4, 1, 2])

    DTarray = []
    DT1array = []
    for DT in Earth_atmo.ObsDateUT:
        TmpDT = Time(DT[0:19], format='isot', scale='utc')
        DTarray.append(float(TmpDT.jd))
    for DT1 in AEWs.DateTimeUTObs:
        TmpDT1 = Time(DT1, format='iso', scale='utc')
        DT1array.append(float(TmpDT1.jd))

    InterpPWV = interpolate.interp1d(DTarray,
                                     Earth_atmo.PWV,
                                     kind='linear',
                                     copy=True,
                                     bounds_error=False,
                                     fill_value=np.NaN,
                                     axis=0)
    PWVonGrid = InterpPWV(np.array(DT1array))
    AX.plot_date(AEWs.DateTimeUTObs, PWVonGrid, label="PWV [mm]")
    AX.set_ylabel("PWV (mm)", fontsize=7)
    ########################################################
    InterpPress = interpolate.interp1d(DTarray,
                                       Earth_atmo.Press,
                                       kind='linear',
                                       copy=True,
                                       bounds_error=False,
                                       fill_value=np.NaN,
                                       axis=0)
    PressonGrid = InterpPress(np.array(DT1array))

    ax1 = AX.twinx()
    #ax1.set_xlim(x0,x1)
    #ax1.set_xticks(np.linspace(x0,x1,xtks, endpoint=True))
    ax1.set_ylim(800., 850.)
    ax1.set_yticks(np.linspace(800., 850., 11, endpoint=True))
    ax1.tick_params(axis='y', which='major', labelsize=7)
    ax1.set_ylabel("Pressure (mb)", fontsize=7)

    #PressPlot.Setup_PlotDate(min(EWs.DateTimeUTObs),max(EWs.DateTimeUTObs),1)
    ax1.plot_date(AEWs.DateTimeUTObs,
                  PressonGrid,
                  'C1',
                  markerfacecolor='C1',
                  marker="o",
                  linewidth=0.0,
                  label="Pressure")
    AX.legend(loc=2, ncol=3, fontsize=6, scatterpoints=1)
    ax1.legend(loc=1, ncol=3, fontsize=6, scatterpoints=1)

    ########################################################
    InterpTempC = interpolate.interp1d(DTarray,
                                       Earth_atmo.TempC,
                                       kind='linear',
                                       copy=True,
                                       bounds_error=False,
                                       fill_value=np.NaN,
                                       axis=0)
    TempConGrid = InterpTempC(np.array(DT1array))

    InterpRelHum = interpolate.interp1d(DTarray,
                                        Earth_atmo.RelHum,
                                        kind='linear',
                                        copy=True,
                                        bounds_error=False,
                                        fill_value=np.NaN,
                                        axis=0)
    RelHumonGrid = InterpRelHum(np.array(DT1array))

    az = TempFPlot.Setup_PlotDate(min(AEWs.DateTimeUTObs),
                                  max(AEWs.DateTimeUTObs),
                                  1,
                                  new_canvas=False,
                                  subplot=[4, 1, 3])

    az.plot_date(AEWs.DateTimeUTObs,
                 TempConGrid * 9.0 / 5.0 + 32.0,
                 label="Temp.[F]")
    az.plot_date(AEWs.DateTimeUTObs, RelHumonGrid, label="Rel. Hum. [%]")
    pl.legend(loc=2, ncol=3, fontsize=6, scatterpoints=1)
    ########################################################
    airmass = []
    CMII = []
    for d in AEWs.DateTimeUTObs:
        observer.date = d
        Planet = ephem.Jupiter(d)
        Planet.compute(observer)
        airmass.extend([pyasl.airmassPP(90. - Planet.alt * 180. / np.pi)])
        CMII.append(Planet.cmlII * 180. / np.pi)
    ########################################################

    EAM = Earth_Airmass.Setup_PlotDate(min(AEWs.DateTimeUTObs),
                                       max(AEWs.DateTimeUTObs),
                                       1,
                                       new_canvas=False,
                                       subplot=[4, 1, 4])
    #lbl=BandID+" AEW "+str(round(np.mean(AEWs.EW),3))+"$\pm$"+str(round(np.std(AEWs.EW),3))
    EAM.plot_date(AEWs.DateTimeUTObs, np.array(airmass), label=lbl)
    ref_airmass = np.full(len(airmass), Polluxaltaz.secz)
    EAM.plot_date(AEWs.DateTimeUTObs,
                  ref_airmass,
                  linestyle='solid',
                  marker='None',
                  color='C0')
    #PLOT HORIZONTAL LINE WITH REFERENCE AIR MASS HERE
    EAM.set_ylabel("Air Mass", fontsize=7)
    EAM.text(
        sorted(AEWs.DateTimeUTObs)[0],
        2.9,
        CalibrationStars[DateUT],
        color='#000000',
        fontsize=8,
        verticalalignment='top',
        horizontalalignment='left',
    )
    EAM.text(
        sorted(AEWs.DateTimeUTObs)[0],
        2.7,
        CalibrationDates[DateUT],
        color='#000000',
        fontsize=8,
        verticalalignment='top',
        horizontalalignment='left',
    )
    EAM.text(
        sorted(AEWs.DateTimeUTObs)[0],
        2.5,
        "Air Mass=" + str(round(Polluxaltaz.secz, 3)),
        color='#000000',
        fontsize=8,
        verticalalignment='top',
        horizontalalignment='left',
    )
    print ' '
    print sorted(AEWs.DateTimeUTObs)[0]
    pl.subplots_adjust(left=0.08, right=0.92, top=0.95, bottom=0.05)
    pl.savefig("Jupiter EW Plot" + DateUT + " " + BandID + ".png", dpi=300)

    ########################################################
    ########################################################
    AirmassPlot.Setup_Plot()
    pl.scatter(np.array(airmass), AEWs.EW)
    Coefs = np.polyfit(np.array(airmass), AEWs.EW, 1)
    EWFit = Coefs[1] + Coefs[0] * np.array(airmass)
    pl.plot(np.array(airmass), EWFit)
    corr = np.corrcoef([np.array(airmass), AEWs.EW])
    print "Coefs= ", Coefs
    print "Correlation Coef.= ", corr[0, 1]
    #CoefsUT=np.polyfit(np.array(EWs.DateTimeUTObs), EWs.EW, 1)
    ########################################################
    CMIIPlot.Setup_Plot()
    pl.scatter(np.array(CMII), AEWs.EW)
    pl.text(
        10.,
        20.,
        'GOES-16/SUVI  Fe195  YYYY-MM-DD HH:MM:SS',
        color='#000000',
        fontsize=8,
        verticalalignment='bottom',
        horizontalalignment='left',
    )
Example #5
0
def StarObsPlot(year=None, targets=None, observatory=None, period=None, 
                hover=False, sunless_hours=None, remove_watermark=False):
  """
    Plot the visibility of target.

    Parameters
    ----------
    year: int
        The year for which to calculate the visibility.
    targets: list
        List of targets.
        Each target should be a dictionary with keys 'name' and 'coord'.
        The key 'name' is a string, 'coord' is a SkyCoord object.
    observatory: string
        Name of the observatory that pyasl.observatory can resolve.
        Basically, any of pyasl.listObservatories().keys()
    period: string, optional
        ESO period for which to calculate the visibility. Overrides `year`.
    hover: boolean, optional
        If True, color visibility lines when mouse over.
    sunless_hours: float, optional
        If not None, plot sunless hours above this airmass
  """

  from mpl_toolkits.axes_grid1 import host_subplot
  from matplotlib.ticker import MultipleLocator
  from matplotlib.font_manager import FontProperties
  from matplotlib import rcParams
  rcParams['xtick.major.pad'] = 12
  font0 = FontProperties()
  font1 = font0.copy()
  font0.set_family('sans-serif')
  font0.set_weight('light')
  font1.set_family('sans-serif')
  font1.set_weight('medium')

  # set the observatory
  if isinstance(observatory, dict):
    obs = observatory
  else:
    obs = pyasl.observatory(observatory)


  fig = plt.figure(figsize=(15,10))
  fig.subplots_adjust(left=0.07, right=0.8, bottom=0.15, top=0.88)
  
  # watermak
  if not remove_watermark:
    fig.text(0.99, 0.99, 'Created with\ngithub.com/iastro-pt/ObservationTools',
            fontsize=10, color='gray',
            ha='right', va='top', alpha=0.5)

  # plotting sunless hours?
  shmode = False
  if sunless_hours is not None:
    shmode = True
    # limit in airmass (assumed plane-parallel atm)
    shairmass = sunless_hours
    # correspoing limit in altitude
    from scipy.optimize import bisect
    shalt = 90 - bisect(lambda alt: pyasl.airmassPP(alt) - shairmass, 0, 89)

  if shmode:
    fig.subplots_adjust(hspace=0.35)
    ax = host_subplot(211)
    axsh = host_subplot(212)
    plt.text(0.5, 0.47,
          "- sunless hours above airmass {:.1f} - \n".format(shairmass),
          transform=fig.transFigure, ha='center', va='bottom', fontsize=12)
    plt.text(0.5, 0.465,
          "the thick line above the curves represents the total sunless hours "\
          "for each day of the year",
          transform=fig.transFigure, ha='center', va='bottom', fontsize=10)

  else:
    ax = host_subplot(111)

  for n, target in enumerate(targets):

    target_coord = target['coord']
    target_ra = target_coord.ra.deg
    target_dec = target_coord.dec.deg

    
    if period is not None:
      jd_start, jd_end = get_ESO_period(period)
    else:
      jd_start = pyasl.jdcnv(dt.datetime(year, 1, 1))
      jd_end = pyasl.jdcnv(dt.datetime(year, 12, 31))
    
    jdbinsize = 1 # every day
    each_day = np.arange(jd_start, jd_end, jdbinsize)
    jds = []

    ## calculate the mid-dark times
    sun = ephem.Sun()
    for day in each_day:
      date_formatted = '/'.join([str(i) for i in pyasl.daycnv(day)[:-1]])
      s = ephem.Observer();
      s.date = date_formatted;
      s.lat = ':'.join([str(i) for i in decdeg2dms(obs['latitude'])])
      s.lon = ':'.join([str(i) for i in decdeg2dms(obs['longitude'])])
      jds.append(ephem.julian_date(s.next_antitransit(sun)))


    jds = np.array(jds)

    # Get JD floating point
    jdsub = jds - np.floor(jds[0])

    # Get alt/az of object
    altaz = pyasl.eq2hor(jds, np.ones_like(jds)*target_ra, np.ones_like(jds)*target_dec, \
                        lon=obs['longitude'], lat=obs['latitude'], alt=obs['altitude'])
    ax.plot( jdsub, altaz[0], '-', color='k')

    # label for each target
    plabel = "[{0:2d}]  {1!s}".format(n+1, target['name'])

    # number of target at the top of the curve
    ind_label = np.argmax(altaz[0])
    # or at the bottom if the top is too close to the corners
    # if jdsub[ind_label] < 5 or jdsub[ind_label] > jdsub.max()-5:
    #   ind_label = np.argmin(altaz[0])
    ax.text( jdsub[ind_label], altaz[0][ind_label], str(n+1), color="b", fontsize=14, \
             fontproperties=font1, va="bottom", ha="center")


    if n+1 == 29:
      # too many?
      ax.text(1.1, 1.0-float(n+1)*0.04, "too many targets", ha="left", va="top", transform=ax.transAxes, \
              fontsize=10, fontproperties=font0, color="r")
    else:
      ax.text(1.1, 1.0-float(n+1)*0.04, plabel, ha="left", va="top", transform=ax.transAxes, \
              fontsize=12, fontproperties=font0, color="b")

  if shmode:
    sunless_hours = []
    for day in each_day:
      date_formatted = '/'.join([str(i) for i in pyasl.daycnv(day)[:-1]])
      s = ephem.Observer();
      s.date = date_formatted;
      s.lat = ':'.join([str(i) for i in decdeg2dms(obs['latitude'])])
      s.lon = ':'.join([str(i) for i in decdeg2dms(obs['longitude'])])
      # hours from sunrise to sunset
      td = pyasl.daycnv(ephem.julian_date(s.next_setting(sun)), mode='dt') \
            - pyasl.daycnv(ephem.julian_date(s.next_rising(sun)), mode='dt')
      sunless_hours.append(24 - td.total_seconds() / 3600)

    days = each_day - np.floor(each_day[0])
    axsh.plot(days, sunless_hours, '-', color='k', lw=2)
    axsh.set(ylim=(0, 15), yticks=range(1,15), ylabel='Useful hours',
             yticklabels=[r'${}^{{\rm h}}$'.format(n) for n in range(1,15)])


  ax.text(1.1, 1.03, "List of targets", ha="left", va="top", transform=ax.transAxes, \
          fontsize=12, fontproperties=font0, color="b")


  axrange = ax.get_xlim()
  
  
  if period is None:
    months = range(1, 13)
    ndays = [0] + [calendar.monthrange(date, m)[1] for m in months]
    ax.set_xlim([0, 366])
    ax.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays)/2.)[1:])
    ax.set_xticklabels(map(calendar.month_abbr.__getitem__, months), fontsize=10)
    if shmode:
      axsh.set_xlim([0, 366])
      axsh.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays)/2.)[1:])
      axsh.set_xticklabels(map(calendar.month_abbr.__getitem__, months), fontsize=10)
  else:
    if int(period) % 2 == 0:
      # even ESO period, Oct -> Mar
      months = [10, 11, 12, 1, 2, 3]
      ndays = [0] + [calendar.monthrange(date, m)[1] for m in months]
      ax.set_xlim([0, 181])
      ax.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays)/2.)[1:])
      ax.set_xticklabels(map(calendar.month_abbr.__getitem__, months), fontsize=10)
      if shmode:
        axsh.set_xlim([0, 181])
        axsh.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays)/2.)[1:])
        axsh.set_xticklabels(map(calendar.month_abbr.__getitem__, months), fontsize=10)
    else:
      # odd ESO period, Apr -> Sep
      months = range(4, 10)
      ndays = [0] + [calendar.monthrange(date, m)[1] for m in months]
      ax.set_xlim([0, 182])
      ax.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays)/2.)[1:])
      ax.set_xticklabels(map(calendar.month_abbr.__getitem__, months), fontsize=10)
      if shmode:
        axsh.set_xlim([0, 182])
        axsh.set_xticks(np.cumsum(ndays)[:-1] + (np.array(ndays)/2.)[1:])
        axsh.set_xticklabels(map(calendar.month_abbr.__getitem__, months), fontsize=10)

  if axrange[1]-axrange[0] <= 1.0:
    jdhours = np.arange(0,3,1.0/24.)
    utchours = (np.arange(0,72,dtype=int)+12)%24
  else:
    jdhours = np.arange(0,3,1.0/12.)
    utchours = (np.arange(0,72, 2, dtype=int)+12)%24


  # Make ax2 responsible for "top" axis and "right" axis
  ax2 = ax.twin()
  # Set upper x ticks
  ax2.set_xticks(np.cumsum(ndays))
  ax2.set_xlabel("Day")

  # plane-parallel airmass
  airmass_ang = np.arange(10, 81, 5)
  geo_airmass = pyasl.airmass.airmassPP(airmass_ang)[::-1]
  ax2.set_yticks(airmass_ang)
  airmassformat = []
  for t in range(geo_airmass.size):
    airmassformat.append("{0:2.2f}".format(geo_airmass[t]))
  ax2.set_yticklabels(airmassformat)#, rotation=90)
  ax2.set_ylabel("Relative airmass", labelpad=32)
  ax2.tick_params(axis="y", pad=6, labelsize=8)
  plt.text(1.02,-0.04, "Plane-parallel", transform=ax.transAxes, ha='left', \
           va='top', fontsize=10, rotation=90)

  ax22 = ax.twin()
  ax22.set_xticklabels([])
  ax22.set_frame_on(True)
  ax22.patch.set_visible(False)
  ax22.yaxis.set_ticks_position('right')
  ax22.yaxis.set_label_position('right')
  ax22.spines['right'].set_position(('outward', 30))
  ax22.spines['right'].set_color('k')
  ax22.spines['right'].set_visible(True)
  airmass2 = list(map(lambda ang: pyasl.airmass.airmassSpherical(90. - ang, obs['altitude']), airmass_ang))
  ax22.set_yticks(airmass_ang)
  airmassformat = []
  for t in range(len(airmass2)): 
    airmassformat.append(" {0:2.2f}".format(airmass2[t]))
  ax22.set_yticklabels(airmassformat, rotation=90)
  ax22.tick_params(axis="y", pad=8, labelsize=8)
  plt.text(1.05,-0.04, "Spherical+Alt", transform=ax.transAxes, ha='left', va='top', \
           fontsize=10, rotation=90)


  ax.set_ylim([0, 91])
  ax.yaxis.set_major_locator(MultipleLocator(15))
  ax.yaxis.set_minor_locator(MultipleLocator(5))
  yticks = ax.get_yticks()
  ytickformat = []
  for t in range(yticks.size):
    ytickformat.append(str(int(yticks[t]))+r"$^\circ$")
  ax.set_yticklabels(ytickformat, fontsize=16)
  ax.set_ylabel("Altitude", fontsize=18)
  yticksminor = ax.get_yticks(minor=True)
  ymind = np.where( yticksminor % 15. != 0. )[0]
  yticksminor = yticksminor[ymind]
  ax.set_yticks(yticksminor, minor=True)
  m_ytickformat = []
  for t in range(yticksminor.size):
    m_ytickformat.append(str(int(yticksminor[t]))+r"$^\circ$")
  ax.set_yticklabels(m_ytickformat, minor=True)
  ax.set_ylim([0, 91])

  ax.yaxis.grid(color='gray', linestyle='dashed')
  ax.yaxis.grid(color='gray', which="minor", linestyle='dotted')
  ax2.xaxis.grid(color='gray', linestyle='dotted')

  if period is not None:
    plt.text(0.5, 0.95,
             "Visibility over P{0!s}\n - altitudes at mid-dark time -".format(period),
             transform=fig.transFigure, ha='center', va='bottom', fontsize=12)
  else:
    plt.text(0.5, 0.95,
             "Visibility over {0!s}\n - altitudes at mid-dark time -".format(date),
             transform=fig.transFigure, ha='center', va='bottom', fontsize=12)


  obsco = "Obs coord.: {0:8.4f}$^\circ$, {1:8.4f}$^\circ$, {2:4f} m".format(obs['longitude'], obs['latitude'], obs['altitude'])

  plt.text(0.01,0.97, obsco, transform=fig.transFigure, ha='left', va='center', fontsize=10)
  plt.text(0.01,0.95, obs['name'], transform=fig.transFigure, ha='left', va='center', fontsize=10)

  # interactive!
  if hover:
    main_axis = fig.axes[0]
    all_lines = set(main_axis.get_lines())
    def on_plot_hover(event):
      for line in main_axis.get_lines():
          if line.contains(event)[0]:
            line.set_color('red') # make this line red
            # and all others black
            all_other_lines = all_lines - set([line])
            for other_line in all_other_lines:
              other_line.set_color('black')
            fig.canvas.draw_idle()
    fig.canvas.mpl_connect('motion_notify_event', on_plot_hover)

  return fig
Example #6
0
def JupiterAirmass(DateUT, BandID, Grating):
    import sys
    sys.path.append('f:\Astronomy\Projects\Jupiter\Spectral Data')
    sys.path.append('f:\\Astronomy\Python Play')
    sys.path.append('f:\\Astronomy\Python Play\Utils')
    sys.path.append('f:\\Astronomy\Python Play\Spectrophotometry\Spectroscopy')

    import astropy.units as u
    from astropy.time import Time
    from astropy.coordinates import SkyCoord, EarthLocation, AltAz
    import numpy as np
    import ephem
    import EquivWidthUtils as EWU
    from PyAstronomy import pyasl
    import matplotlib.pyplot as pl
    import PlotUtils as PU

    TimePlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    TimePlot.loadplotparams("f:", "Jupiter_" + BandID, "Time")
    AirmassPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    AirmassPlot.loadplotparams("f:", "Jupiter_" + BandID, "Airmass")
    CMIIPlot = PU.PlotSetup("JupiterEWSpecPlotConfig.txt")
    CMIIPlot.loadplotparams("f:", "Jupiter_" + BandID, "CMII")

    Pollux = SkyCoord.from_name('Pollux')
    datestring = '2015-01-23 08:20:00'
    observer = ephem.Observer()
    #Location from Google Maps at 483 S Oneida Way, Denver 80224
    observer.lon = ephem.degrees('-104.907985')
    observer.lat = ephem.degrees('39.708200')
    print float(observer.lat) * 180 / np.pi
    Oneida = EarthLocation(lat=float(observer.lat) * u.rad,
                           lon=float(observer.lon) * u.rad,
                           height=1500 * u.m)
    utcoffset = 0 * u.hour  # Universal Time
    time = Time('2015-01-23 05:54:00') - utcoffset

    Polluxaltaz = Pollux.transform_to(AltAz(obstime=time, location=Oneida))
    print Polluxaltaz.alt.deg
    print("Pollux's Altitude = {0.alt:.2}".format(Polluxaltaz))
    print Polluxaltaz.secz

    EWs = EWU.EWObservations("../EWs/" + DateUT + "-" + Grating +
                             "-Albedo-EW.txt")
    EWs.load_records("Jupiter", BandID)
    #print EWs.DateTimeUTObs
    #print EWs.EW
    TimePlot.Setup_PlotDate(min(EWs.DateTimeUTObs), max(EWs.DateTimeUTObs), 1)

    pl.plot_date(EWs.DateTimeUTObs, EWs.EW)
    print "Average EW, Std. Dev., 95% Conf.= ",np.mean(EWs.EW),np.std(EWs.EW),\
            1.96*np.std(EWs.EW)/np.sqrt(len(EWs.EW))

    ######################

    airmass = []
    CMII = []
    for d in EWs.DateTimeUTObs:

        observer.date = d

        Planet = ephem.Jupiter(d)
        Planet.compute(observer)
        #print float(Planet.alt)*180./np.pi

        airmass.extend([pyasl.airmassPP(90. - Planet.alt * 180. / np.pi)])
        #print Planet.cmlII
        CMII.append(Planet.cmlII * 180. / np.pi)
        #print airmass

    AirmassPlot.Setup_Plot()
    pl.scatter(np.array(airmass), EWs.EW)
    Coefs = np.polyfit(np.array(airmass), EWs.EW, 1)
    EWFit = Coefs[1] + Coefs[0] * np.array(airmass)
    pl.plot(np.array(airmass), EWFit)
    corr = np.corrcoef([np.array(airmass), EWs.EW])
    print "Coefs= ", Coefs
    print "Correlation Coef.= ", corr[0, 1]
    #CoefsUT=np.polyfit(np.array(EWs.DateTimeUTObs), EWs.EW, 1)
    CMIIPlot.Setup_Plot()
    pl.scatter(np.array(CMII), EWs.EW)