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)
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
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', )
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
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)