<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Planning Observations
Planning of observations is currently a weakness in python. We have the following packages to perform this task
Step1:  In order to know the altitude and azimuth of a fixed target in the sky we will mainly need to know
Step2:  You can also search by its name if it is in CDS...
Step3:  Now we should specify where the observer will be on Earth
Step4:  But maybe we are picky and want the exact location (or specify a different location that is not present in the database...)
Step5:  Finally we need to set up the time, which by default is set in UTC.
Step6:  Let's ask python if we can see the Nebula tonight from la palma
Step7:  We assume that at 11.30 pm will be dark, but let's make sure...
Step8:  You might get an IERS warning (International Earth Rotation and Reference Systems Service) to update the Earth Location.
For more info
Step9:  Calculate rise/set/meridian transit times
It can also provide information about all the twilight times
Step10:  By default it set's the nearest sunset but you can specify also next or previous.
Step11:  Similarly, we can ask when the target will be raising or setting
Step12:  Calculate alt/az positions for targets and Airmass
With this information we can also ask what is the Altitute and Azimuth of our target at that specific time
Step13:  With the integrated sec function we can easily get the Airmass
Step14:  We can now aim to make an altitude plot scanning the altitude of our target every hour
Step15:  Fortunately, there is a function that does it (much faster) within the day around the date we provide
Step16:  We can also give a range of dates to focus on a specific region of time (dark time)
Step17:  Making sky charts
Step18:  Finder Chart Image
Astroplan also provides the option to display sky charts from a list of surveys (but it goes really slow..)
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
import numpy as np
import math
import matplotlib.pyplot as plt
import seaborn
from astropy.io import fits
from astropy import units as u
from astropy.coordinates import SkyCoord
plt.rcParams['figure.figsize'] = (12, 8)
plt.rcParams['font.size'] = 14
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['xtick.labelsize'] = 13
plt.rcParams['ytick.labelsize'] = 13
plt.rcParams['axes.titlesize'] = 14
plt.rcParams['legend.fontsize'] = 13
Explanation: Planning Observations
Planning of observations is currently a weakness in python. We have the following packages to perform this task:
pyephem - works well, but is not maitained anymore and a bit obsolete
astropy - has basic operations (i.e. compute altaz of sources) but has no high-level functionalities
astroplan - aims many interesting and useful features but it is at a very early stage and some features do not work (and it is slow!) 
Here we will mostly review astroplan as we believe it will be adopted by astropy and possibly become a reference.
End of explanation
from astropy.coordinates import SkyCoord
from astroplan import FixedTarget
coordinates = SkyCoord('18h18m48.0s', '−13d49m0.0s', frame='icrs')
eagle_nebula = FixedTarget(name='M16', coord=coordinates)
print (eagle_nebula)
Explanation: In order to know the altitude and azimuth of a fixed target in the sky we will mainly need to know:
The location of the target (on Sky)
The location of the observer (on Earth)
The time
Let's define first the target we want to observe:
End of explanation
eagle_nebula = FixedTarget.from_name('M16')
print (eagle_nebula)
Explanation: You can also search by its name if it is in CDS...
End of explanation
from astroplan import Observer
observer = Observer.at_site('lapalma')
print (observer)
Explanation: Now we should specify where the observer will be on Earth:
End of explanation
import astropy.units as u
from astropy.coordinates import EarthLocation
#from pytz import timezone
from astroplan import Observer
longitude = '-17d52m54s'
latitude = '28d45m38s'
elevation = 2344 * u.m
location = EarthLocation.from_geodetic(longitude, latitude, elevation)
observer = Observer(name='WHT',
                    location=location,
                    pressure=0.615 * u.bar,
                    relative_humidity=0.04,
                    temperature=18 * u.deg_C,
                    #timezone=timezone('US/Hawaii'),
                    description="Our beloved William Herschel Telescope")
print (observer)
Explanation: But maybe we are picky and want the exact location (or specify a different location that is not present in the database...)
End of explanation
from astropy.time import Time
time = Time('2017-09-15 23:30:00')
Explanation: Finally we need to set up the time, which by default is set in UTC.
End of explanation
observer.target_is_up(time, eagle_nebula)
Explanation: Let's ask python if we can see the Nebula tonight from la palma:
End of explanation
observer.is_night(time)
Explanation: We assume that at 11.30 pm will be dark, but let's make sure...
End of explanation
from astroplan import download_IERS_A
download_IERS_A()
Explanation: You might get an IERS warning (International Earth Rotation and Reference Systems Service) to update the Earth Location.
For more info: http://astroplan.readthedocs.io/en/latest/faq/iers.html 
Let's do it:
End of explanation
observer.sun_set_time(time, which='nearest').iso
Explanation: Calculate rise/set/meridian transit times
It can also provide information about all the twilight times:
End of explanation
observer.sun_set_time(time, which='next').iso
observer.twilight_evening_civil(time, which='nearest').iso
observer.twilight_evening_nautical(time, which='nearest').iso
observer.twilight_evening_astronomical(time, which='nearest').iso
Explanation: By default it set's the nearest sunset but you can specify also next or previous.
End of explanation
observer.target_rise_time(time, eagle_nebula).iso
observer.target_set_time(time, eagle_nebula).iso
Explanation: Similarly, we can ask when the target will be raising or setting:
End of explanation
altaz_eagle = observer.altaz(time, eagle_nebula)
altaz_eagle.alt, altaz_eagle.az
Explanation: Calculate alt/az positions for targets and Airmass
With this information we can also ask what is the Altitute and Azimuth of our target at that specific time
End of explanation
altaz_eagle.secz
Explanation: With the integrated sec function we can easily get the Airmass
End of explanation
from astropy.time import TimeDelta
time_list = []
airmass_list = []
current_time = observer.sun_set_time(time, which='nearest') 
while current_time < observer.sun_rise_time(time, which='nearest'):
    current_altaz = observer.altaz(current_time, eagle_nebula)
    if current_altaz.alt > 0:
        airmass_list.append(current_altaz.alt.value)
    else:
        airmass_list.append(0)
    time_list.append(current_time.datetime)
    current_time += TimeDelta(3600, format='sec')    
    
plt.plot(time_list, airmass_list)
Explanation: We can now aim to make an altitude plot scanning the altitude of our target every hour
End of explanation
from astroplan.plots import plot_airmass
middle_of_the_night = Time('2017-09-16 01:00:00')
plot_airmass(targets=eagle_nebula, 
             observer=observer, 
             time=middle_of_the_night, 
             #brightness_shading=True,
             #altitude_yaxis=True
            )   
plt.legend() 
Explanation: Fortunately, there is a function that does it (much faster) within the day around the date we provide:
End of explanation
from astroplan.plots import dark_style_sheet
start_time = observer.sun_set_time(time, which='nearest') 
end_time = observer.sun_rise_time(time, which='nearest') 
delta_t = end_time - start_time
observe_time = start_time + delta_t*np.linspace(0, 1, 75)
andromeda = FixedTarget.from_name('M31')
pleiades = FixedTarget.from_name('M45')
some_nice_stuff_to_look_tonight = [eagle_nebula, andromeda, pleiades]
plot_airmass(targets=some_nice_stuff_to_look_tonight, 
             observer=observer, 
             time=observe_time, 
             brightness_shading=True,
             altitude_yaxis=True,
             #style_sheet=dark_style_sheet
            )   
plt.legend() 
Explanation: We can also give a range of dates to focus on a specific region of time (dark time)
End of explanation
from astroplan.plots import plot_sky
plot_sky(eagle_nebula, observer, middle_of_the_night)
plot_sky(pleiades, observer, middle_of_the_night)
plot_sky(andromeda, observer, middle_of_the_night)
plt.legend()
observe_time = Time('2000-03-15 17:00:00')
observe_time = observe_time + np.linspace(-4, 5, 10)*u.hour
plot_sky(pleiades, observer, observe_time)
plt.legend(loc='center left', bbox_to_anchor=(1.25, 0.5))
plt.show()
Explanation: Making sky charts
End of explanation
from astroplan.plots import plot_finder_image
plot_finder_image(eagle_nebula, survey='DSS', log=True)
Explanation: Finder Chart Image
Astroplan also provides the option to display sky charts from a list of surveys (but it goes really slow..)
End of explanation
<END_TASK>