def filter_targets(obs, i, target_list, date_time, roof=2.5): """ A function that filters a list of targets and returns a list with airmass less than < 2.5. TO IMPLEMENT: Move the testing to a different file or into a different function Args: obs: List of Observer objects that represent observatories target_list: List of FixedTarget objects that represent target coords date_time: The date and time range over which we check for observability roof: Float defining the maximum airmass we'll allow for our targets; will exclude targets with airmass larger than 2.5 Returns: None """ targets = format_targets(target_list) observers = format_observatories(obs) airmass_max = AirmassConstraint(roof) observability = is_observable(airmass_max, observers[i], targets, date_time) print(observability) print("Success!!")
def __init__(self, time_range, targets, site='cfht', constraints=None, supp_cols=None): # Get infos from the MasterFile if isinstance(targets, list): info = load_from_masterfile(*targets) supp_cols = supp_cols or [ 'pl_orbper', 'st_j', 'st_h', 'ra', 'dec', 'pl_eqt', 'st_teff' ] else: info = targets.copy() if supp_cols is None: supp_cols = list(info.keys()) supp_cols.remove('pl_name') # Default constraint if constraints is None: constraints = [ AtNightConstraint.twilight_nautical(), AirmassConstraint(max=2.5) ] # Define time constraint and append it t1, t2 = Time(time_range) constraints.append(TimeConstraint(t1, t2)) # Convert to List_of_constraints (useful to print and save) constraints_list = List_of_constraints(constraints) # Save infos self.info = info self.constraints = constraints_list self.meta = { 'Time_limits': [t1, t2], 'Target_list': info['pl_name'].tolist(), 'Site': site, **constraints_list.show() } self.supp_cols = supp_cols self.info_cols = ['pl_name'] + supp_cols self.obs = Observer.at_site(site) # self.n_eclipses = n_eclipses # Resolve targets self.targets = [self.resolve_target(i) for i in range(len(targets))]
def __init__(self, lat, lon, elevation, ra, dec, discDate, airmassConstraint=2): self.airmassConstraint = airmassConstraint self.altConstraint = math.degrees(math.asin(1 / self.airmassConstraint)) self.location = EarthLocation(lat=lat, lon=lon, height=elevation * u.m) self.discDate = discDate self.observer = Observer(location=self.location, name="LT") self.target = SkyCoord(ra=ra, dec=dec, unit=(u.hourangle, u.deg)) self.constraints = [ AirmassConstraint(self.airmassConstraint), AtNightConstraint.twilight_astronomical() ] print("Discovery Date :", discDate.value)
def get_observability_fraction(name="WASP 4", site='keck', ra=None, dec=None, start_time=Time('2019-09-13 20:00:00'), end_time=Time('2020-07-31 20:00:00')): if isinstance(name,str) and ra is None and dec is None: target = FixedTarget.from_name(name) elif isinstance(ra,float) and isinstance(dec,float): target_coord = SkyCoord(ra=ra*u.deg, dec=dec*u.deg) target = FixedTarget(coord=target_coord, name=name) else: raise NotImplementedError('failed to make target') observer = Observer.at_site(site) constraints = [AltitudeConstraint(min=20*u.deg, max=85*u.deg), AirmassConstraint(3), AtNightConstraint.twilight_civil()] # over every day between start and end time, check if the observing # constraints are meetable. days = Time( np.arange(start_time.decimalyear, end_time.decimalyear, 1/(365.25)), format='decimalyear' ) frac, ever_observable = [], [] for day in days: table = observability_table(constraints, observer, [target], time_range=day) frac.append(float(table['fraction of time observable'])) ever_observable.append(bool(table['ever observable'])) ever_observable = np.array(ever_observable) frac = np.array(frac) return frac, ever_observable, days
def main(args=None): p = parser() opts = p.parse_args(args) # Late imports from astroplan import (AirmassConstraint, AtNightConstraint, Observer, is_event_observable) from astropy.coordinates import EarthLocation, SkyCoord from astropy.time import Time from astropy import units as u from matplotlib import dates from matplotlib import pyplot as plt from tqdm import tqdm from ..io import fits from .. import moc from .. import plot # noqa names = ('name', 'longitude', 'latitude', 'height') length0, *lengths = (len(getattr(opts, 'site_{}'.format(name))) for name in names) if not all(length0 == length for length in lengths): p.error('these options require equal numbers of arguments: {}'.format( ', '.join('--site-{}'.format(name) for name in names))) observers = [Observer.at_site(site) for site in opts.site] for name, lon, lat, height in zip(opts.site_name, opts.site_longitude, opts.site_latitude, opts.site_height): location = EarthLocation(lon=lon * u.deg, lat=lat * u.deg, height=(height or 0) * u.m) observers.append(Observer(location, name=name)) observers = list(reversed(observers)) m = fits.read_sky_map(opts.input.name, moc=True) t0 = Time(opts.time) if opts.time is not None else Time.now() times = t0 + np.linspace(0, 1) * u.day theta, phi = moc.uniq2ang(m['UNIQ']) coords = SkyCoord(phi, 0.5 * np.pi - theta, unit='rad') prob = np.asarray(moc.uniq2pixarea(m['UNIQ']) * m['PROBDENSITY']) constraints = [ getattr(AtNightConstraint, 'twilight_{}'.format(opts.twilight))(), AirmassConstraint(opts.max_airmass) ] fig = plt.figure() width, height = fig.get_size_inches() fig.set_size_inches(width, (len(observers) + 1) / 16 * width) ax = plt.axes() locator = dates.AutoDateLocator() formatter = dates.DateFormatter('%H:%M') ax.set_xlim([times[0].plot_date, times[-1].plot_date]) ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_major_locator(locator) ax.set_xlabel("Time from {0} [UTC]".format(min(times).datetime.date())) plt.setp(ax.get_xticklabels(), rotation=30, ha='right') ax.set_yticks(np.arange(len(observers))) ax.set_yticklabels([observer.name for observer in observers]) ax.yaxis.set_tick_params(left=False) ax.grid(axis='x') ax.spines['bottom'].set_visible(False) ax.spines['top'].set_visible(False) for i, observer in enumerate(tqdm(observers)): observable = 100 * np.dot( prob, is_event_observable(constraints, observer, coords, times)) ax.contourf(times.plot_date, [i - 0.4, i + 0.4], np.tile(observable, (2, 1)), levels=np.arange(10, 110, 10), cmap=plt.get_cmap().reversed()) plt.tight_layout() # Show or save output. opts.output()
from astroplan.scheduling import Schedule, ObservingBlock from astroplan import FixedTarget, Observer, Transitioner, AirmassConstraint from astropy.time import Time from SimpleScheduler import SimpleScheduler import astropy.units as u import matplotlib.pyplot as plt from astroplan.plots import plot_schedule_airmass con = AirmassConstraint(2) apo = Observer.at_site('apo') deneb = FixedTarget.from_name('Deneb') m13 = FixedTarget.from_name('M13') blocks = [ObservingBlock(deneb, 20 * u.minute, 0, con)] blocks.append(ObservingBlock(m13, 20 * u.minute, 0)) # Speed of telescope transitioner = Transitioner(slew_rate=2 * u.deg / u.second) # Schedule the observing blocks schedule = Schedule(Time('2016-07-06 19:00'), Time('2016-07-07 19:00')) scheduler = SimpleScheduler(observer=apo, transitioner=transitioner, constraints=[con]) scheduler(blocks, schedule) plot_schedule_airmass(schedule) plt.legend() #plt.show() plt.savefig('Our_scheduler.png')
def vis(date, objects, obj_tab): #This tool is designed for the Magellan Telescope @ Las Camapanas Observatory, in Chile las = Observer.at_site('LCO') #both las and los are the locations of MagAO, but one is used for the plot and the other for the time lco = EarthLocation.of_site('Las Campanas Observatory') userEntered_list = list(objects.split(",")) target_list = userEntered_list targets = [] for i in range(1, len(obj_tab)): ra = (obj_tab.iloc[i, 2])[1:] + ' hours' dec = (obj_tab.iloc[i, 3])[1:] + ' degrees' print(ra + ',' + dec) targets.append( FixedTarget(coord=SkyCoord(ra=ra, dec=dec), name=target_list[i - 1])) constraints = [ AltitudeConstraint(10 * u.deg, 80 * u.deg), AirmassConstraint(5), AtNightConstraint.twilight_civil() ] start_time = las.sun_set_time(Time(date), which='nearest') end_time = las.sun_rise_time(Time(date), which='nearest') date = start_time.iso[:10] + ' to ' + end_time.iso[:10] time_range = Time([start_time, end_time]) # In[ ]: delta_t = end_time - start_time observe_time = start_time + delta_t * np.linspace(0, 1, 75) # In[ ]: # Are targets *ever* observable in the time range? ever_observable = is_observable(constraints, las, targets, time_range=time_range) # Are targets *always* observable in the time range? always_observable = is_always_observable(constraints, las, targets, time_range=time_range) # During what months are the targets ever observable? best_months = months_observable(constraints, las, targets) # In[ ]: table = observability_table(constraints, las, targets, time_range=time_range) print(table) table = table.to_pandas() np.savetxt( 'static/data/visibility.txt', table, fmt="%-30s", header= 'Target name ever observable always observable fraction of time observable' )
for i in range(0, l): targs.append( FixedTarget(coord=SkyCoord(ra=(t[i]['ra']), dec=(t[i]['dec']), unit=(u.hourangle, u.deg)), name=t[i]['alt_name'] + " [" + t[i]['iau_name'] + ", " + t[i]['ra'] + ", " + t[i]['dec'] + "]")) # Accounting for the fact that ra is in [hour min sec] and dec is in [deg arcmin arcsec] # the "name" attribute is all of the information just smashed together and I know it's unclean, please don't judge me # print((targs[len(targs)-1].name)) # This was just to check where errors occurred time_range = Time(["2018-04-15 00:01", "2018-04-30 23:59"]) # This just takes the whole swath of time, not refining it or anything cons = [AirmassConstraint(2), AtNightConstraint.twilight_astronomical()] # don't use civil twilight because astronomers aren't civil obs_tab = observability_table(cons, kitt, targs, time_range=time_range) # print(obs_tab) obs_targs = [] total_save = [] # total_save is to keep all the data, not just some of it for i in range(0, len(obs_tab)): if obs_tab[i]['ever observable']: obs_targs.append([ obs_tab[i]['target name'], obs_tab[i]['fraction of time observable'] ])
def main(event, context): filename = 'MS190311l-1-Preliminary' # Get targetlist target_list = 'triggers/%s_bayestar.csv'%filename # replace with your object key s3 = boto3.resource('s3') print(target_list) s3.Bucket(bucketname).download_file(target_list, '/tmp/%s_targetlist.csv'%filename) galaxies = Table.read('/tmp/%s_targetlist.csv'%filename) del galaxies['col0'] galaxies = np.array(galaxies.as_array().tolist()) """Get the full galaxy list, and find which are good to observe at NOT""" # Setup observer time = Time.now() NOT = Observer.at_site("lapalma") tel_constraints = [AtNightConstraint.twilight_civil(), AirmassConstraint(max = 5)] # Check if nighttime if not NOT.is_night(time): sunset_tonight = NOT.sun_set_time(time, which='nearest') dt_sunset = (sunset_tonight - time) print("Daytime at the NOT! Preparing a plan for observations starting next sunset in ~ %s hours."%(int(dt_sunset.sec/3600))) time = sunset_tonight + 5*u.minute else: print("It's nighttime at the NOT! Preparing a plan immeidately.") # Get target list galaxycoord=SkyCoord(ra=galaxies[:, 1]*u.deg,dec=galaxies[:, 2]*u.deg) targets = [FixedTarget(coord=SkyCoord(ra=ra*u.deg, dec=dec*u.deg), name=int(name)) for name, ra, dec in galaxies[:, :3]] # Construct astroplan OBs blocks = [] exposure = 300*u.second read_out = 20 * u.second for priority, targ in enumerate(targets): for bandpass in ['r']: b = ObservingBlock.from_exposures( targ, priority, exposure, 1, read_out, configuration={'filter': bandpass}) blocks.append(b) # Transitioner between targets slew_rate = 10.8*u.deg/u.second transitioner = Transitioner( slew_rate, { 'filter': { ('g', 'r'): 30 * u.second, ('i', 'z'): 30 * u.second, 'default': 30 * u.second } }) # Initialize the priority scheduler with the constraints and transitioner prior_scheduler = SequentialScheduler(constraints = tel_constraints, observer = NOT, transitioner = transitioner) # Initialize a Schedule object, to contain the new schedule around night night_length = NOT.sun_set_time(time, which='nearest') - NOT.sun_rise_time(time, which='nearest') noon_before = time - 4 * u.hour noon_after = time + 16 * u.hour priority_schedule = Schedule(noon_before, noon_after) # Call the schedule with the observing blocks and schedule to schedule the blocks prior_scheduler(blocks, priority_schedule) # Remove transition blocks to read observing order priority_schedule_table = priority_schedule.to_table() mask = priority_schedule_table["target"] != "TransitionBlock" pruned_schedule = priority_schedule_table[mask] idxs = np.arange(0, len(pruned_schedule["target"])) # pl.figure(figsize = (14,6)) # plot_schedule_airmass(priority_schedule, show_night=True) # pl.legend(loc = "upper right") # schedule_path = filename+"schedule.pdf" # pl.savefig(schedule_path) # pl.clf() # print("Finished preparing an observing plan.") # s3.Bucket(bucketname).upload_file(schedule_path, 'triggers/%s'%schedule_path) instrumements = ["ALFOSC"] nothing_to_observe = True for tel in range(0, len(instrumements)): print("Writing a plan for {}".format(instrumements[tel])) outlist = [0]*galaxies.shape[0] for i in range(tel, galaxies.shape[0], len(instrumements)): ra = Angle(galaxies[i, 1] * u.deg) dec = Angle(galaxies[i, 2] * u.deg) mask = pruned_schedule['target'].astype("int") == int(galaxies[i, 0]) targ_row = pruned_schedule[mask] idx = idxs[mask] # Get observing scheduling rank and airmass at observing time. try: airm = NOT.altaz(Time(targ_row["start time (UTC)"].data), targets[i]).secz t_s = targ_row["start time (UTC)"].data t_e = targ_row["end time (UTC)"].data except: print("GLADE target name %s not found in schedule. Probably not visible. Replacing entry with -99"%(galaxies[i, 0])) idx = -99 airm = -99 outlist[i] = int(galaxies[i, 0]), ra.to_string( unit=u.hourangle, sep=':', precision=2, pad=True), dec.to_string( sep=':', precision=2, alwayssign=True, pad=True), idx, airm, galaxies[i, 3], galaxies[i, 4], galaxies[ i, 5], t_s, t_e header = ["GladeID", "RA", "Dec", "Observing number", "Airmass at observing time", "Distance", "B-band luminosity", "Probability", "Schduled integration start", "Schduled integration end"] outframe = Table(np.array(outlist), names=header) csv_path = filename+"_schedule.csv" ascii.write(outframe, "/tmp/"+csv_path, format='csv', overwrite=True, fast_writer=False) s3.Bucket(bucketname).upload_file("/tmp/"+csv_path, 'triggers/%s'%csv_path) return
def get_schedulable_blocks(self) -> list: """Returns list of schedulable blocks. Returns: List of schedulable blocks """ # get requests r = requests.get(urljoin(self._url, '/api/requestgroups/schedulable_requests/'), headers=self._header, proxies=self._proxies) if r.status_code != 200: raise ValueError('Could not fetch list of schedulable requests.') schedulable = r.json() # get proposal priorities r = requests.get(urljoin(self._url, '/api/proposals/'), headers=self._header, proxies=self._proxies) if r.status_code != 200: raise ValueError('Could not fetch list of proposals.') tac_priorities = { p['id']: p['tac_priority'] for p in r.json()['results'] } # loop all request groups blocks = [] for group in schedulable: # get base priority, which is tac_priority * ipp_value proposal = group['proposal'] if proposal not in tac_priorities: log.error('Could not find proposal "%s".', proposal) continue base_priority = group['ipp_value'] * tac_priorities[proposal] # loop all requests in group for req in group['requests']: # still pending? if req['state'] != 'PENDING': continue # duration duration = req['duration'] * u.second # time constraints time_constraints = [ TimeConstraint(Time(wnd['start']), Time(wnd['end'])) for wnd in req['windows'] ] # loop configs for cfg in req['configurations']: # get instrument and check, whether we schedule it instrument = cfg['instrument_type'] if instrument.lower( ) != self._portal_instrument_type.lower(): continue # target t = cfg['target'] target = SkyCoord(t['ra'] * u.deg, t['dec'] * u.deg, frame=t['type'].lower()) # constraints c = cfg['constraints'] constraints = [ AirmassConstraint(max=c['max_airmass'], boolean_constraint=False), MoonSeparationConstraint(min=c['min_lunar_distance'] * u.deg) ] # priority is base_priority times duration in minutes priority = base_priority * duration.value / 60. # create block block = ObservingBlock( FixedTarget(target, name=req["id"]), duration, priority, constraints=[*constraints, *time_constraints], configuration={'request': req}) blocks.append(block) # return blocks return blocks
def construct_plan(data, site, start_time, end_time, constraints=None, max_priority=3): if constraints is None: constraints = [ AltitudeConstraint(10 * u.deg, 80 * u.deg), AirmassConstraint(5), AtNightConstraint.twilight_civil() ] data = data.sort_values(by=["Add. Data Priority", "RA"], ascending=[1, 1]) time_range = Time([start_time, end_time]) # targets.lis format: # NAME # <RA hh:mm:ss.ss> <DEC dd:mm:ss.s> # <HMJD/BMJD T0 err P err # # NAME... # ENTRY = "{}\n{} {}\n{} linear {} {} {} {}\n\n" targets_list = "" targets_prg = "" targets_notes = "" for name, row in data.iterrows(): row['RA'], row['Dec'] = row['RA'].replace(" ", ":"), row['Dec'].replace( " ", ":") target = FixedTarget(coord=SkyCoord(ra=Angle(row['RA'], unit='hourangle'), dec=Angle(row['Dec'], unit='degree')), name=name) # Does the target rise above the horizon? ever_observable = is_observable(constraints, site, target, time_range=time_range) # Parse the ephemeris data try: T0, T0_err = row['T(0) +/- (d)'].replace(" ", "").split("(") calendar, T0 = T0.split("=") T0_err = T0_err.replace(")", "") N = len(T0.split(".")[1]) - len(T0_err) T0_err = "0.{}{}".format(("0" * N), T0_err) P, P_err = row['P +/- (d)'].split("(") P_err = P_err.replace(")", "") M = len(P.split(".")[1]) - len(P_err) P_err = "0.{}{}".format(("0" * M), P_err) except ValueError: print("Failed to extract row! {}".format(name)) continue # Get the priority of this system try: priority = int(row['Add. Data Priority']) except ValueError: continue # Logic about if we want to use this target writeme = ever_observable[0] and (priority <= max_priority) # If true, add to the list if writeme: # Output data formats line = "{}\n{} {}\n{} linear {} {} {} {}\n\n".format( name, row['RA'], row['Dec'], calendar, T0, T0_err, P, P_err) prgline = "{}\n0.7 1.3 3 8\n\n".format(name) notesline = '{}: "{}"\n\n\n'.format(name, row['Target Notes']) targets_list += line targets_prg += prgline targets_notes += notesline # Write out files with open(os.path.join('OUTPUT', 'targets.lis'), 'w') as f: f.write(targets_list) with open(os.path.join('OUTPUT', 'targets.prg'), 'w') as f: f.write(targets_prg) with open(os.path.join('OUTPUT', 'targets.txt'), 'w') as f: f.write(targets_notes)
from astroplan import ObservingBlock, AirmassConstraint ### There will be more types of observing block ## each observing type will have some constainst and configuration that more blocks will share surveyConfig = None surveyConst = AirmassConstraint(2) folowUpConfig = None folowUpConst = None # def survey(target, duration, priority, configuration, constraints): conf = surveyConfig + configuration const = constraints + surveyConst return ObservingBlock(target=target, duration=duration, priority=priority, configuration=conf, constraints=constraints) def folow_up(target, duration, priority, configuration, constraints): conf = folowUpConfig + configuration const = constraints + folowUpConst return ObservingBlock(target=target, duration=duration, priority=priority, configuration=conf, constraints=constraints)
from unittest.mock import patch from django.test import TestCase from mop.toolbox.obs_details import all_night_moon_sep, calculate_visibility from mop.toolbox.LCO_obs_locs import choose_loc OGG = choose_loc('OGG') v_test_target = ['Sirius', 100.7362500 * u.deg, -16.6459444 * u.deg] v_date = Time("2019-12-25 00:00:00", scale='utc') v_coords = SkyCoord(v_test_target[1], v_test_target[2], frame='icrs') v_obs_begin = OGG.twilight_evening_astronomical(v_date, which='nearest') v_obs_end = OGG.twilight_morning_astronomical(v_date, which='next') v_observing_range = [v_obs_begin, v_obs_end] constraints = [ AirmassConstraint(2.0), AltitudeConstraint(20 * u.deg, 85 * u.deg), AtNightConstraint.twilight_astronomical() ] ever_observable = is_observable(constraints, OGG, v_coords, time_range=v_observing_range) v_fail_start = Time("2019-12-24 10:00:00", scale='utc') v_fail_end = Time("2019-12-25 10:00:00", scale='utc') class TestVisibilityCalc(TestCase): def test_timeobj(self): self.assertEqual(v_date.scale, 'utc')
def plan_when_transits_will_occur( filename='targets.txt', observatory='Southern African Large Telescope', start='2017-06-22', end='2017-06-28', airmass_limit=2.5, moon_distance=10, do_secondary=True, method='by_night'): ''' Plan when targets will be visibile and transiting from a site. Inputs ------ filename : str A plain text file with the following columns: target : The name of the target (e.g. J0555-57). RA : The right ascension of the target (e.g. 05h55m32.62s). DEC : The declination of the target (e.g. -57d17m26.1s). epoch* : The epoch of the transit. Youc can either use: epoch_HJD-2400000 : HJD - 24500000 epoch_BJD-2455000 : MJD Period : The period of the system (days). Secondary : can be True or False depending on whether you want to see when the secondary transits will be. observatory : str The observatory you are observing from. See later for list of available observatories (accepted by astropy). start : str The first night of observation (e.g. 2017-08-31). end : str The last night of observation (e.g. 2017-09-10). airmass_limit : float The maximum airmass you want to observe through. moon_distance : float The closest the target can be t the moon in arcmins. do_secondary = True: Look for secondary eclipses assuming circularised orbits. Available observator names are: 'ALMA', 'Anglo-Australian Observatory', 'Apache Point', 'Apache Point Observatory', 'Atacama Large Millimeter Array', 'BAO', 'Beijing XingLong Observatory', 'Black Moshannon Observatory', 'CHARA', 'Canada-France-Hawaii Telescope', 'Catalina Observatory', 'Cerro Pachon', 'Cerro Paranal', 'Cerro Tololo', 'Cerro Tololo Interamerican Observatory', 'DCT', 'Discovery Channel Telescope', 'Dominion Astrophysical Observatory', 'Gemini South', 'Hale Telescope', 'Haleakala Observatories', 'Happy Jack', 'Jansky Very Large Array', 'Keck Observatory', 'Kitt Peak', 'Kitt Peak National Observatory', 'La Silla Observatory', 'Large Binocular Telescope', 'Las Campanas Observatory', 'Lick Observatory', 'Lowell Observatory', 'Manastash Ridge Observatory', 'McDonald Observatory', 'Medicina', 'Medicina Dish', 'Michigan-Dartmouth-MIT Observatory', 'Mount Graham International Observatory', 'Mt Graham', 'Mt. Ekar 182 cm. Telescope', 'Mt. Stromlo Observatory', 'Multiple Mirror Telescope', 'NOV', 'National Observatory of Venezuela', 'Noto', 'Observatorio Astronomico Nacional, San Pedro Martir', 'Observatorio Astronomico Nacional, Tonantzintla', 'Palomar', 'Paranal Observatory', 'Roque de los Muchachos', 'SAAO', 'SALT', 'SRT', 'Siding Spring Observatory', 'Southern African Large Telescope', 'Subaru', 'Subaru Telescope', 'Sutherland', 'Vainu Bappu Observatory', 'Very Large Array', 'W. M. Keck Observatory', 'Whipple', 'Whipple Observatory', 'aao', 'alma', 'apo', 'bmo', 'cfht', 'ctio', 'dao', 'dct', 'ekar', 'example_site', 'flwo', 'gemini_north', 'gemini_south', 'gemn', 'gems', 'greenwich', 'haleakala', 'irtf', 'keck', 'kpno', 'lapalma', 'lasilla', 'lbt', 'lco', 'lick', 'lowell', 'mcdonald', 'mdm', 'medicina', 'mmt', 'mro', 'mso', 'mtbigelow', 'mwo', 'noto', 'ohp', 'paranal', 'salt', 'sirene', 'spm', 'srt', 'sso', 'tona', 'vbo', 'vla'. ''' ################### # Try reading table ################### try: target_table = Table.read(filename, format='ascii') except: raise ValueError( 'I cant open the target file (make sure its ascii with the following first line:\ntarget RA DEC epoch_HJD-2400000 Period Secondary' ) ############################## # try reading observation site ############################## try: observation_site = coord.EarthLocation.of_site(observatory) observation_handle = Observer(location=observation_site) observation_handle1 = Observer.at_site(observatory) except: print(coord.EarthLocation.get_site_names()) raise ValueError('The site is not understood') ################################### # Try reading start and end times ################################### try: start_time = Time(start + ' 12:01:00', location=observation_site) end_time = Time(end + ' 12:01:00', location=observation_site) number_of_nights = int(end_time.jd - start_time.jd) time_range = Time([start + ' 12:01:00', end + ' 12:01:00']) print('Number of nights: {}'.format(number_of_nights)) except: raise ValueError('Start and end times not understood') ##################### # Now do constraints ##################### #try: constraints = [ AltitudeConstraint(0 * u.deg, 90 * u.deg), AirmassConstraint(3), AtNightConstraint.twilight_civil() ] #except: # raise ValueError('Unable to get set constraints') if method == 'by_night': for i in range(number_of_nights): start_time_tmp = start_time + TimeDelta( i, format='jd') # get start time (doesent need to be accurate) end_time_tmp = start_time + TimeDelta( i + 1, format='jd') # get start time (doesent need to be accurate) print('#' * 80) start_time_tmpss = start_time_tmp.datetime.ctime().split( ) # ['Fri', 'Dec', '24', '12:00:00', '2010'] print('Night {} - {} {} {} {}'.format(i + 1, start_time_tmpss[0], start_time_tmpss[2], start_time_tmpss[1], start_time_tmpss[-1])) print('#' * 80) # Now print Almnac information (sunset and end of evening twilight print('Almnac:') sun_set = observation_handle.sun_set_time(start_time_tmp, which='next') print('Sunset:\t\t\t\t\t\t\t' + sun_set.utc.datetime.ctime()) twilight_evening_astronomical = observation_handle.twilight_evening_astronomical( start_time_tmp, which='next') # -18 twilight_evening_nautical = observation_handle.twilight_evening_nautical( start_time_tmp, which='next') # -12 twilight_evening_civil = observation_handle.twilight_evening_civil( start_time_tmp, which='next') # -6 deg print('Civil evening twilight (-6 deg) (U.T.C):\t\t' + twilight_evening_civil.utc.datetime.ctime()) print('Nautical evening twilight (-12 deg) (U.T.C):\t\t' + twilight_evening_nautical.utc.datetime.ctime()) print('Astronomical evening twilight (-18 deg) (U.T.C):\t' + twilight_evening_astronomical.utc.datetime.ctime()) print('\n') twilight_morning_astronomical = observation_handle.twilight_morning_astronomical( start_time_tmp, which='next') # -18 twilight_morning_nautical = observation_handle.twilight_morning_nautical( start_time_tmp, which='next') # -12 twilight_morning_civil = observation_handle.twilight_morning_civil( start_time_tmp, which='next') # -6 deg print('Astronomical morning twilight (-18 deg) (U.T.C):\t' + twilight_morning_astronomical.utc.datetime.ctime()) print('Nautical morning twilight (-12 deg) (U.T.C):\t\t' + twilight_morning_nautical.utc.datetime.ctime()) print('Civil morning twilight (-6 deg) (U.T.C):\t\t' + twilight_morning_civil.utc.datetime.ctime()) sun_rise = observation_handle.sun_rise_time(start_time_tmp, which='next') print('Sunrise:\t\t\t\t\t\t' + sun_rise.utc.datetime.ctime()) print('\n') # stuff for creating plot plot_mids = [] plot_names = [] plot_widths = [] for j in range(len(target_table)): # Extract information star_coordinates = coord.SkyCoord('{} {}'.format( target_table['RA'][j], target_table['DEC'][j]), unit=(u.hourangle, u.deg), frame='icrs') star_fixed_coord = FixedTarget(coord=star_coordinates, name=target_table['target'][j]) #################### # Get finder image #################### ''' plt.close() try: finder_image = plot_finder_image(star_fixed_coord,reticle=True,fov_radius=10*u.arcmin) except: pass plt.savefig(target_table['target'][j]+'_finder_chart.eps') ''' P = target_table['Period'][j] Secondary_transit = target_table['Secondary'][j] transit_half_width = TimeDelta( target_table['width'][j] * 60 * 60 / 2, format='sec') # in seconds for a TimeDelta # now convert T0 to HJD -> JD -> BJD so we can cout period if 'epoch_HJD-2400000' in target_table.colnames: #print('Using HJD-2400000') T0 = target_table['epoch_HJD-2400000'][j] T0 = Time(T0 + 2400000, format='jd') # HJD given by WASP ltt_helio = T0.light_travel_time(star_coordinates, 'heliocentric', location=observation_site) T0 = T0 - ltt_helio # HJD -> JD ltt_bary = T0.light_travel_time(star_coordinates, 'barycentric', location=observation_site) T0 = T0 + ltt_bary # JD -> BJD elif 'epoch_BJD-2455000' in target_table.colnames: #print('Using BJD-2455000') T0 = target_table['epoch_BJD-2455000'][j] + 2455000 T0 = Time(T0, format='jd') # BJD else: print('\n\n\n\n FAILE\n\n\n\n') continue ########################################################## # Now start from T0 and count in periods to find transits ########################################################## # convert star and end time to BJD ltt_bary_start_time = start_time_tmp.light_travel_time( star_coordinates, 'barycentric', location=observation_site) # + TimeDelta(i,format='jd') start_time_bary = start_time_tmp + ltt_bary_start_time # + TimeDelta(i,format='jd') # convert start time to BJD ltt_bary_end_time_tmp = end_time_tmp.light_travel_time( star_coordinates, 'barycentric', location=observation_site) # + TimeDelta(i,format='jd') end_time_bary = end_time_tmp + ltt_bary_start_time #+ TimeDelta(i+1,format='jd') # convert end time to BJD and add 1 day 12pm -> 12pm the next day elapsed = end_time_bary - start_time_bary # now this is 24 hours from the start day 12:00 pm # now count transits time = Time(T0.jd, format='jd') # make a temporary copy transits = [] primary_count, secondary_count = 0, 0 while time.jd < end_time_bary.jd: if (time.jd > start_time_bary.jd) and (time.jd < end_time_bary.jd): if is_observable(constraints, observation_handle, [star_fixed_coord], times=[time])[0] == True: transits.append(time) primary_count += 1 if Secondary_transit == 'yes': timesecondary = time + TimeDelta(P / 2, format='jd') if (timesecondary.jd > start_time_bary.jd) and ( timesecondary.jd < end_time_bary.jd): if is_observable(constraints, observation_handle, [star_fixed_coord], times=[timesecondary])[0] == True: transits.append(timesecondary) secondary_count += 1 time = time + TimeDelta(P, format='jd') # add another P to T0 # Now find visible transits transits = [ i for i in transits if is_observable(constraints, observation_handle, [star_fixed_coord], times=[i])[0] == True ] if len(transits) == 0: message = '{} has no transits.'.format( target_table['target'][j]) print('-' * len(message)) print(message) print('-' * len(message)) print('\n') plt.close() continue else: message = '{} has {} primary transits and {} secondary transits.'.format( target_table['target'][j], primary_count, secondary_count) print('-' * len(message)) print(message) print('RA: {}'.format(target_table['RA'][j])) print('DEC: {}'.format(target_table['DEC'][j])) print('Epoch: 2000') print('T0 (BJD): {}'.format(T0.jd)) print('Period: {}'.format(P)) print('Transit width (hr): {}'.format( target_table['width'][j])) print('-' * len(message)) print('\n') for i in transits: # currently transit times are in BJD (need to convert to HJD to check ltt_helio = i.light_travel_time(star_coordinates, 'barycentric', location=observation_site) ii = i - ltt_helio ltt_helio = ii.light_travel_time(star_coordinates, 'heliocentric', location=observation_site) ii = ii + ltt_helio transit_1 = i - transit_half_width - TimeDelta( 7200, format='sec') # ingress - 2 hr transit_2 = i - transit_half_width - TimeDelta( 3600, format='sec') # ingress - 2 hr transit_3 = i - transit_half_width # ingress transit_4 = i + transit_half_width # egress transit_5 = i + transit_half_width + TimeDelta( 3600, format='sec') # ingress - 2 hr transit_6 = i + transit_half_width + TimeDelta( 7200, format='sec') # ingress - 2 hr if (((i.jd - time.jd) / P) - np.floor( (i.jd - time.jd) / P) < 0.1) or (( (i.jd - time.jd) / P) - np.floor( (i.jd - time.jd) / P) > 0.9): print('Primary Transit:') print('-' * len('Primary Transit')) if 0.4 < ((i.jd - time.jd) / P) - np.floor( (i.jd - time.jd) / P) < 0.6: print('Secondary Transit') print('-' * len('Secondary Transit')) ################## # now get sirmass ################## altaz = star_coordinates.transform_to( AltAz(obstime=transit_1, location=observation_site)) hourangle = observation_handle1.target_hour_angle( transit_1, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Ingress - 2hr (U.T.C):\t\t\t\t\t' + transit_1.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) altaz = star_coordinates.transform_to( AltAz(obstime=transit_2, location=observation_site)) hourangle = observation_handle1.target_hour_angle( transit_2, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Ingress - 1hr (U.T.C):\t\t\t\t\t' + transit_2.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) altaz = star_coordinates.transform_to( AltAz(obstime=transit_3, location=observation_site)) hourangle = observation_handle1.target_hour_angle( transit_3, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Ingress (U.T.C):\t\t\t\t\t' + transit_3.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) altaz = star_coordinates.transform_to( AltAz(obstime=i, location=observation_site)) hourangle = observation_handle1.target_hour_angle( i, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Mid transit (U.T.C):\t\t\t\t\t' + i.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) altaz = star_coordinates.transform_to( AltAz(obstime=transit_4, location=observation_site)) hourangle = observation_handle1.target_hour_angle( transit_4, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Egress (U.T.C):\t\t\t\t\t\t' + transit_4.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) altaz = star_coordinates.transform_to( AltAz(obstime=transit_5, location=observation_site)) hourangle = observation_handle1.target_hour_angle( transit_5, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Egress + 1hr (U.T.C):\t\t\t\t\t' + transit_5.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) altaz = star_coordinates.transform_to( AltAz(obstime=transit_6, location=observation_site)) hourangle = observation_handle1.target_hour_angle( transit_6, star_coordinates) hourangle = 24 * hourangle.degree / 360 if hourangle > 12: hourangle -= 24 print('Egress + 2hr (U.T.C):\t\t\t\t\t' + transit_6.utc.datetime.ctime() + '\tAirmass: {:.2f}\tHA:{:.2f}'.format( altaz.secz, hourangle)) print('HJD {} (to check with http://var2.astro.cz/)\n'. format(ii.jd)) # append stuff for plots plot_mids.append(i) # astropy Time plot_names.append(target_table['target'][j]) plot_widths.append(target_table['width'][j]) # Now plot plt.close() if len(plot_mids) == 0: continue date_formatter = dates.DateFormatter('%H:%M') #ax.xaxis.set_major_formatter(date_formatter) # now load dummy transit lightcurves xp, yp = np.load('lc.npy') xs, ys = np.load('lcs.npy') # x = np.linspace(0, 2*np.pi, 400) # y = np.sin(x**2) subplots_adjust(hspace=0.000) number_of_subplots = len( plot_names) # number of targets transiting that night time = sun_set + np.linspace(-1, 14, 100) * u.hour # take us to sunset for i, v in enumerate(xrange(number_of_subplots)): # exctract params width = plot_widths[v] name = plot_names[v] mid = plot_mids[v] # now set up dummy lc plot x_tmp = mid + xp * (width / 2) * u.hour # get right width in hours # now set up axis v = v + 1 ax1 = subplot(number_of_subplots, 1, v) ax1.xaxis.set_major_formatter(date_formatter) if v == 1: ax1.set_title(start) # plot transit model ax1.plot_date(x_tmp.plot_date, ys, 'k-') # plot continuum #xx =time.plot_date #xx = [uu for uu in xx if (uu<min(x_tmp.plot_date)) or (uu>max(x_tmp.plot_date))] #ax1.plot_date(xx, np.ones(len(xx)),'k--', alpha=0.3) ax1.set_xlim(min(time.plot_date), max(time.plot_date)) #ax1.plot_date(mid.plot_date, 0.5, 'ro') plt.setp(ax1.get_xticklabels(), rotation=30, ha='right') ax1.set_ylabel(name, rotation=45, labelpad=20) twilights = [ (sun_set.datetime, 0.0), (twilight_evening_civil.datetime, 0.1), (twilight_evening_nautical.datetime, 0.2), (twilight_evening_astronomical.datetime, 0.3), (twilight_morning_astronomical.datetime, 0.4), (twilight_morning_nautical.datetime, 0.3), (twilight_morning_civil.datetime, 0.2), (sun_rise.datetime, 0.1), ] for ii, twii in enumerate(twilights[1:], 1): ax1.axvspan(twilights[ii - 1][0], twilights[ii][0], ymin=0, ymax=1, color='grey', alpha=twii[1]) ax1.grid(alpha=0.5) ax1.get_yaxis().set_ticks([]) if v != number_of_subplots: ax1.get_xaxis().set_ticks([]) plt.xlabel('Time [U.T.C]') #plt.tight_layout() #plt.savefig('test.eps',format='eps') plt.show()
async def get_schedulable_blocks(self) -> List[ObservingBlock]: """Returns list of schedulable blocks. Returns: List of schedulable blocks """ # check if self._portal_instrument_type is None: raise ValueError("No instrument type for portal set.") # get data schedulable = await self._portal_get( urljoin(self._url, "/api/requestgroups/schedulable_requests/")) # get proposal priorities data = await self._portal_get(urljoin(self._url, "/api/proposals/")) tac_priorities = {p["id"]: p["tac_priority"] for p in data["results"]} # loop all request groups blocks = [] for group in schedulable: # get base priority, which is tac_priority * ipp_value proposal = group["proposal"] if proposal not in tac_priorities: log.error('Could not find proposal "%s".', proposal) continue base_priority = group["ipp_value"] * tac_priorities[proposal] # loop all requests in group for req in group["requests"]: # still pending? if req["state"] != "PENDING": continue # duration duration = req["duration"] * u.second # time constraints time_constraints = [ TimeConstraint(Time(wnd["start"]), Time(wnd["end"])) for wnd in req["windows"] ] # loop configs for cfg in req["configurations"]: # get instrument and check, whether we schedule it instrument = cfg["instrument_type"] if instrument.lower( ) != self._portal_instrument_type.lower(): continue # target t = cfg["target"] target = SkyCoord(t["ra"] * u.deg, t["dec"] * u.deg, frame=t["type"].lower()) # constraints c = cfg["constraints"] constraints = [] if "max_airmass" in c and c["max_airmass"] is not None: constraints.append( AirmassConstraint(max=c["max_airmass"], boolean_constraint=False)) if "min_lunar_distance" in c and c[ "min_lunar_distance"] is not None: constraints.append( MoonSeparationConstraint( min=c["min_lunar_distance"] * u.deg)) if "max_lunar_phase" in c and c[ "max_lunar_phase"] is not None: constraints.append( MoonIlluminationConstraint( max=c["max_lunar_phase"])) # if max lunar phase <= 0.4 (which would be DARK), we also enforce the sun to be <-18 degrees if c["max_lunar_phase"] <= 0.4: constraints.append( AtNightConstraint.twilight_astronomical()) # priority is base_priority times duration in minutes # priority = base_priority * duration.value / 60. priority = base_priority # create block block = ObservingBlock( FixedTarget(target, name=req["id"]), duration, priority, constraints=[*constraints, *time_constraints], configuration={"request": req}, ) blocks.append(block) # return blocks return blocks
def get_transit_observability(site, ra, dec, name, t_mid_0, period, duration, n_transits=100, obs_start_time=Time( dt.datetime.today().isoformat()), min_altitude=None, oot_duration=30 * u.minute, minokmoonsep=30 * u.deg, max_airmass=None, twilight_limit='nautical'): """ note: barycentric corrections not yet implemented. (could do this myself!) -> 16 minutes of imprecision is baked into this observability calculator! args: site (astroplan.observer.Observer) ra, dec (units u.deg), e.g.: ra=101.28715533*u.deg, dec=16.71611586*u.deg, or can also accept ra="17 56 35.51", dec="-29 32 21.5" name (str), e.g., "Sirius" t_mid_0 (float): in BJD_TDB, preferably (but see note above). period (astropy quantity, units time) duration (astropy quantity, units time) n_transits (int): number of transits forward extrapolated to obs_start_time (astropy.Time object): when to start calculation from min_altitude (astropy quantity, units deg): 20 degrees is the more relevant constraint. max_airmass: e.g., 2.5. One of max_airmass or min_altitude is required. oot_duration (astropy quantity, units time): with which to brack transit observations, to get an OOT baseline. twilight_limit: 'astronomical', 'nautical', 'civil' for -18, -12, -6 deg. """ if (isinstance(ra, u.quantity.Quantity) and isinstance(dec, u.quantity.Quantity)): target_coord = SkyCoord(ra=ra, dec=dec) elif (isinstance(ra, str) and isinstance(dec, str)): target_coord = SkyCoord(ra=ra, dec=dec, unit=(u.hourangle, u.deg)) else: raise NotImplementedError if (not isinstance(max_airmass, float) or isinstance(min_altitude, u.quantity.Quantity)): raise NotImplementedError target = FixedTarget(coord=target_coord, name=name) primary_eclipse_time = Time(t_mid_0, format='jd') system = EclipsingSystem(primary_eclipse_time=primary_eclipse_time, orbital_period=period, duration=duration, name=name) midtransit_times = system.next_primary_eclipse_time(obs_start_time, n_eclipses=n_transits) # for the time being, omit any local time constraints. if twilight_limit == 'astronomical': twilight_constraint = AtNightConstraint.twilight_astronomical() elif twilight_limit == 'nautical': twilight_constraint = AtNightConstraint.twilight_nautical() else: raise NotImplementedError('civil twilight is janky.') constraints = [ twilight_constraint, AltitudeConstraint(min=min_altitude), AirmassConstraint(max=max_airmass), MoonSeparationConstraint(min=minokmoonsep) ] # observable just at midtime (bottom) b = is_event_observable(constraints, site, target, times=midtransit_times) # observable full transits (ingress, bottom, egress) ing_egr = system.next_primary_ingress_egress_time(obs_start_time, n_eclipses=n_transits) ibe = is_event_observable(constraints, site, target, times_ingress_egress=ing_egr) # get moon separation over each transit. take minimum moon sep at # ing/tmid/egr as the moon separation. moon_tmid = get_moon(midtransit_times, location=site.location) moon_separation_tmid = moon_tmid.separation(target_coord) moon_ing = get_moon(ing_egr[:, 0], location=site.location) moon_separation_ing = moon_ing.separation(target_coord) moon_egr = get_moon(ing_egr[:, 1], location=site.location) moon_separation_egr = moon_egr.separation(target_coord) moon_separation = np.round( np.array( [moon_separation_tmid, moon_separation_ing, moon_separation_egr]).min(axis=0), 0).astype(int) moon_illumination = np.round( 100 * moon.moon_illumination(midtransit_times), 0).astype(int) # completely observable transits (OOT, ingress, bottom, egress, OOT) oot_ing_egr = np.concatenate( (np.array(ing_egr[:, 0] - oot_duration)[:, None], np.array(ing_egr[:, 1] + oot_duration)[:, None]), axis=1) oibeo = is_event_observable(constraints, site, target, times_ingress_egress=oot_ing_egr) ing_tmid_egr = np.concatenate( (np.array(ing_egr[:, 0])[:, None], np.array(midtransit_times)[:, None], np.array(ing_egr[:, 1])[:, None]), axis=1) return ibe, oibeo, ing_tmid_egr, moon_separation, moon_illumination
# Create astroplan.FixedTarget objects for each one in the table. from astropy.coordinates import SkyCoord import astropy.units as u targets = [(FixedTarget(coord=ra=ra*u.deg, dec=dec*u.deg), name=name) for name, ra, dec in target_table] # Build a bulleted list of constrains: # 1. Only observe btwn altitudes of 10-80 deg, with AltitudeConstraint class. # 2. Put an upper limit on the airmass of each target with AirmassConstraint # class. # 3. Use the AtNightConstraint class too, to see things at night. We can define # night to be "between civil twilights" with the class method twilight_civil, # but there are also other ways to define the observing window. from astroplan import (AltitudeConstraint, AirmassConstraint, AtNightConstraint) constraints = [AltitudeConstraint(10*u.deg, 80*u.deg), AirmassConstraint(5), AtNightConstraint.twilight_civil()] from astroplan import is_observable, is_always_observable, months_observable # Are targets *ever* observable in the time range? ever_observable = is_observable(constraints, subaru, targets, time_range=time_range) # Are targets *always* observable in the time range? always_observable = is_always_observable(constraints, subaru, targets, time_range=time_range) # During what months are the targets ever observable? best_months = months_observable(constraints, subaru, targets)
def get_event_observability( eventclass, site, ra, dec, name, t_mid_0, period, duration, n_transits=100, obs_start_time=Time(dt.datetime.today().isoformat()), min_altitude = None, oot_duration = 30*u.minute, minokmoonsep = 30*u.deg, max_airmass = None, twilight_limit = 'nautical'): """ note: barycentric corrections not yet implemented. (could do this myself!) -> 16 minutes of imprecision is baked into this observability calculator! args: eventclass: e.g., "OIBE". Function does NOT return longer events. site (astroplan.observer.Observer) ra, dec (units u.deg), e.g.: ra=101.28715533*u.deg, dec=16.71611586*u.deg, or can also accept ra="17 56 35.51", dec="-29 32 21.5" name (str), e.g., "Sirius" t_mid_0 (float): in BJD_TDB, preferably (but see note above). period (astropy quantity, units time) duration (astropy quantity, units time) n_transits (int): number of transits forward extrapolated to obs_start_time (astropy.Time object): when to start calculation from min_altitude (astropy quantity, units deg): 20 degrees is the more relevant constraint. max_airmass: e.g., 2.5. One of max_airmass or min_altitude is required. oot_duration (astropy quantity, units time): with which to brack transit observations, to get an OOT baseline. twilight_limit: 'astronomical', 'nautical', 'civil' for -18, -12, -6 deg. """ if eventclass not in [ 'OIBEO', 'OIBE', 'IBEO', 'IBE', 'BEO', 'OIB', 'OI', 'EO' ]: raise AssertionError if (isinstance(ra, u.quantity.Quantity) and isinstance(dec, u.quantity.Quantity) ): target_coord = SkyCoord(ra=ra, dec=dec) elif (isinstance(ra, str) and isinstance(dec, str) ): target_coord = SkyCoord(ra=ra, dec=dec, unit=(u.hourangle, u.deg)) else: raise NotImplementedError if ( not isinstance(max_airmass, float) or isinstance(min_altitude, u.quantity.Quantity) ): raise NotImplementedError target = FixedTarget(coord=target_coord, name=name) primary_eclipse_time = Time(t_mid_0, format='jd') system = EclipsingSystem(primary_eclipse_time=primary_eclipse_time, orbital_period=period, duration=duration, name=name) midtransit_times = system.next_primary_eclipse_time( obs_start_time, n_eclipses=n_transits) # for the time being, omit any local time constraints. if twilight_limit == 'astronomical': twilight_constraint = AtNightConstraint.twilight_astronomical() elif twilight_limit == 'nautical': twilight_constraint = AtNightConstraint.twilight_nautical() else: raise NotImplementedError('civil twilight is janky.') constraints = [twilight_constraint, AltitudeConstraint(min=min_altitude), AirmassConstraint(max=max_airmass), MoonSeparationConstraint(min=minokmoonsep)] # tabulate ingress and egress times. ing_egr = system.next_primary_ingress_egress_time( obs_start_time, n_eclipses=n_transits ) oibeo_window = np.concatenate( (np.array(ing_egr[:,0] - oot_duration)[:,None], np.array(ing_egr[:,1] + oot_duration)[:,None]), axis=1) oibe_window = np.concatenate( (np.array(ing_egr[:,0] - oot_duration)[:,None], np.array(ing_egr[:,1])[:,None]), axis=1) ibeo_window = np.concatenate( (np.array(ing_egr[:,0])[:,None], np.array(ing_egr[:,1] + oot_duration)[:,None]), axis=1) oib_window = np.concatenate( (np.array(ing_egr[:,0] - oot_duration)[:,None], np.array(midtransit_times)[:,None]), axis=1) beo_window = np.concatenate( (np.array(midtransit_times)[:,None], np.array(ing_egr[:,1] + oot_duration)[:,None]), axis=1) ibe_window = ing_egr oi_window = np.concatenate( (np.array(ing_egr[:,0] - oot_duration)[:,None], np.array(ing_egr[:,0])[:,None]), axis=1) eo_window = np.concatenate( (np.array(ing_egr[:,1])[:,None], np.array(ing_egr[:,1] + oot_duration)[:,None]), axis=1) keys = ['oibeo','oibe','ibeo','oib','beo','ibe','oi','eo'] windows = [oibeo_window, oibe_window, ibeo_window, oib_window, beo_window, ibe_window, oi_window, eo_window] is_obs_dict = {} for key, window in zip(keys, windows): is_obs_dict[key] = np.array( is_event_observable(constraints, site, target, times_ingress_egress=window) ).flatten() is_obs_df = pd.DataFrame(is_obs_dict) is_obs_df['ing'] = ing_egr[:,0] is_obs_df['egr'] = ing_egr[:,1] is_obs_df['isoing'] = Time(ing_egr[:,0], format='iso') is_obs_df['isoegr'] = Time(ing_egr[:,1], format='iso') # this function returns the observable events that are LONGEST. e.g., # during an OIBEO transit you COULD observe just OIB, but why would you? if eventclass == 'OIBEO': event_ind = np.array(is_obs_df[eventclass.lower()])[None,:] elif eventclass in ['IBEO', 'OIBE']: event_ind = np.array( is_obs_df[eventclass.lower()] & ~is_obs_df['oibeo'] )[None,:] elif eventclass in ['IBE', 'OIB', 'BEO']: event_ind = np.array( is_obs_df[eventclass.lower()] & ~is_obs_df['oibeo'] & ~is_obs_df['oibe'] & ~is_obs_df['ibeo'] )[None,:] elif eventclass in ['OI', 'EO']: event_ind = np.array( is_obs_df[eventclass.lower()] & ~is_obs_df['oibeo'] & ~is_obs_df['oibe'] & ~is_obs_df['ibeo'] & ~is_obs_df['oib'] & ~is_obs_df['ibe'] & ~is_obs_df['beo'] )[None,:] # get moon separation over each transit. take minimum moon sep at # ing/tmid/egr as the moon separation. moon_tmid = get_moon(midtransit_times, location=site.location) moon_separation_tmid = moon_tmid.separation(target_coord) moon_ing = get_moon(ing_egr[:,0], location=site.location) moon_separation_ing = moon_ing.separation(target_coord) moon_egr = get_moon(ing_egr[:,1], location=site.location) moon_separation_egr = moon_egr.separation(target_coord) moon_separation = np.round(np.array( [moon_separation_tmid, moon_separation_ing, moon_separation_egr]).min(axis=0),0).astype(int) moon_illumination = np.round( 100*moon.moon_illumination(midtransit_times),0).astype(int) # completely observable transits (OOT, ingress, bottom, egress, OOT) oibeo = is_event_observable(constraints, site, target, times_ingress_egress=oibeo_window) ing_tmid_egr = np.concatenate( (np.array(ing_egr[:,0])[:,None], np.array(midtransit_times)[:,None], np.array(ing_egr[:,1])[:,None]), axis=1) target_window = np.array(windows)[ int(np.argwhere(np.array(keys)==eventclass.lower())), :, : ] return ( event_ind, oibeo, ing_tmid_egr, target_window, moon_separation, moon_illumination )
params.ecc = 0 params.a = float(((G * M_star * (params.per * u.day)**2) / (4 * np.pi**2))**(1 / 3) / R_star) from astroplan import time_grid_from_range, observability_table n_objects_per_night = int(sys.argv[-1]) print(n_objects_per_night) airmass_cutoff = 3.5 fraction_cloudy = 0.3 n_years = 1 n_trials = 15 constraints = [ AtNightConstraint.twilight_nautical(), AirmassConstraint(max=airmass_cutoff) ] start_time = Time('2020-01-01 08:00') # near local midnight end_time = Time('2021-01-01 08:00') # near local midnight n_transits = [] for trial in range(n_trials): target_inds_observed = set([]) obs_database = { name: dict(times=[], fluxes=[], model=[], transit=False) for name in table['spc'] }
targets = [ FixedTarget(coord=SkyCoord(ra=ra * u.deg, dec=dec * u.deg), name=name) for name, ra, dec in target_table ] from astroplan import (AltitudeConstraint, AirmassConstraint, AtNightConstraint) for target in targets: print("Target: ", target.name) #if False: #print("Posang: ", target.posang) constraints = [ AltitudeConstraint(10 * u.deg, 80 * u.deg), AirmassConstraint(5), AtNightConstraint.twilight_civil() ] #from astroplan import is_observable, is_always_observable, months_observable ## Are targets *ever* observable in the time range? #ever_observable = is_observable(constraints, subaru, targets, time_range=time_range) ## Are targets *always* observable in the time range? #always_observable = is_always_observable(constraints, subaru, targets, time_range=time_range) ## During what months are the targets ever observable? ## best_months = months_observable(constraints, subaru, targets) #import numpy as np #observability_table = Table()
def observability(cand=[], site='VLT', time=['2017-09-01T00:00:00.00', '2018-03-01T00:00:00.00'], airmass=1.3): """ cand is class object with parameters: name, ra, dec """ # set observation site if site == 'VLT': if 0: longitude = '-70d24m12.000s' latitude = '-24d37m34.000s' elevation = 2635 * u.m vlt = EarthLocation.from_geodetic(longitude, latitude, elevation) observer = astroplan.Observer( name='VLT', location=vlt, pressure=0.750 * u.bar, relative_humidity=0.11, temperature=0 * u.deg_C, timezone=timezone('America/Santiago'), description="Very Large Telescope, Cerro Paranal") eso = astroplan.Observer.at_site('eso') else: observer = Observer.at_site('Cerro Paranal') if site == 'MagE': observer = Observer.at_site('las campanas observatory') if site == 'keck': observer = Observer.at_site('keck') print(observer) # set time range constrains if isinstance(time, str): # all year if len(time) == 4: timerange = 'period' time_range = Time(time + "-01-01T00:00:00.00", time + "-12-31T23:59:00.00") else: timerange = 'onenight' time = Time(time) elif isinstance(time, list): if len(time) == 2: timerange = 'period' print(Time(['2017-01-03']), time) time_range = Time(time) else: timerange = 'onenight' time = Time(time[0]) if timerange == 'onenight': # calculate sunset and sunrise sunset = observer.sun_set_time(time, which='nearest') print('Sunset at ', sunset.iso) sunrise = observer.sun_rise_time(time, which='nearest') print('Sunrise at ', sunrise.iso) time_range = Time([sunset, sunrise]) # set time array during the night time = time_range[0] + (time_range[1] - time_range[0]) * np.linspace( 0, 1, 55) print(time) # set visibility constrains # constraints = [AirmassConstraint(1.5), AtNightConstraint.twilight_civil()] print(airmass) constraints = [ AirmassConstraint(airmass), AtNightConstraint.twilight_civil() ] # set parameters of calculations read_vis = 0 if read_vis == 0: f_vis = open('DR12_cand_vis_temp.dat', 'w') month_detalied = 1 show_moon = 0 airmass_plot = 0 sky_plot = 0 if airmass_plot == 1: f, ax_air = plt.subplots() if sky_plot == 1: f, ax_sky = plt.subplots() targets = [] if show_moon == 1: print(observer.moon_altaz(time).alt) print(observer.moon_altaz(time).az) # moon = SkyCoord(alt = observer.moon_altaz(time).alt, az = observer.moon_altaz(time).az, obstime = time, frame = 'altaz', location = observer.location) # print(moon.icrs) for i, can in enumerate(cand): print(can.name) # calculate target coordinates coordinates = SkyCoord(float(can.ra) * u.deg, float(can.dec) * u.deg, frame='icrs') #print(can.ra, can.dec) #print(coordinates.to_string('hmsdms')) target = FixedTarget(name=can.name, coord=coordinates) targets.append(target) # print(observer.target_is_up(time, targets[i])) # calculate airmass if timerange == 'onenight': if sky_plot == 1: plot_sky(target, observer, time) airmass = observer.altaz(time, target).secz if airmass_plot == 1: plot_airmass(target, observer, time, ax=ax) air_min = 1000 k_min = -1 for k, a in enumerate(airmass): if 0 < a < air_min: air_min = a k_min = k print(air_min, time[k_min].iso) if k_min > -1 and show_moon == 1: moon = SkyCoord(alt=observer.moon_altaz(time[k_min]).alt, az=observer.moon_altaz(time[k_min]).az, obstime=time[k_min], frame='altaz', location=observer.location) can.moon_sep = Angle(moon.separation( target.coord)).to_string(fields=1) print(can.moon_sep) can.airmass = air_min can.time = time[k_min].iso # ever_observable = astroplan.is_observable(constraints, observer, targets, time_range=time_range) # print(ever_observable) if month_detalied == 1: tim = [] months = [ '2017-10-01', '2017-11-01', '2017-12-01', '2018-01-01', '2018-02-01', '2018-03-01', '2018-04-01' ] #for l in range(int(str(time_range[0])[5:7]), int(str(time_range[1])[5:7]) + 1): for l in range(len(months) - 1): if 0: start = "2017-" + "{0:0>2}".format(l) + "-01T00:00" end = "2017-" + "{0:0>2}".format(l + 1) + "-01T00:00" if l == 12: end = "2018-01-01T00:00" else: start = months[l] end = months[l + 1] time_range_temp = Time([start, end]) table = astroplan.observability_table( constraints, observer, [target], time_range=time_range_temp) tim.append(table[0][3]) # print(tim, max(tim), tim.index(max(tim))) print(tim) can.time = max(tim) if max(tim) != 0: if 0: can.month = str(calendar.month_name[tim.index(max(tim)) + 1])[:3] else: can.month = tim.index(max(tim)) can.up = 'True' else: can.up = 'False' can.month = '---' print(can.up, can.month, can.time) if month_detalied == 0: table = astroplan.observability_table(constraints, observer, targets, time_range=time_range) print(table) for i, can in enumerate(cand): can.up = table[i][1] can.time = table[i][3] # print(table[k][0], table[k][1], table[k][2], table[k][3]) #table.write('DR12_candidates_obs.dat', format='ascii') # f_out.write(table) if sky_plot == 1: plt.legend(loc='center left', bbox_to_anchor=(1.25, 0.5)) plt.show()