# make the observing time - Local time. start_time_mst = Time('2017-06-17 18:30') end_time_mst = Time('2017-06-21 06:00') night_time = end_time_mst - start_time_mst observable_time_mst = start_time_mst + night_time * np.linspace(0, 1, 75) # convert everything to UTC start_time_utc = mst2utc(start_time_mst) end_time_utc = mst2utc(end_time_mst) observable_time_utc = mst2utc(observable_time_mst) time_range = Time([start_time_utc, end_time_utc]) # now we figure out what is observable at all with some simple constraints constraint = [ AtNightConstraint.twilight_civil(), AirmassConstraint(max=2.5, boolean_constraint=True) ] observable = astroplan.is_observable(constraint, kpno, targets, time_range=time_range) data['Observable'] = observable data.to_csv('updated.csv') if 0: # now we make the exposure times exp_time_single = 12 * u.second
def observation_schedule( followup_requests, instrument, observation_start=Time.now(), observation_end=Time.now() + TimeDelta(12 * u.hour), output_format='csv', figsize=(10, 8), ): """Create a schedule to display observations for a particular instrument Parameters ---------- followup_requests : skyportal.models.followup_request.FollowupRequest The planned observations associated with the request instrument : skyportal.models.instrument.Instrument The instrument that the request is made based on observation_start: astropy.time.Time Start time for the observations observation_end: astropy.time.Time End time for the observations output_format : str, optional "csv", "pdf" or "png" -- determines the format of the returned observation plan figsize : tuple, optional Matplotlib figsize of the pdf/png created Returns ------- dict success : bool Whether the request was successful or not, returning a sensible error in 'reason' name : str suggested filename based on `instrument` and `output_format` data : str binary encoded data for the file (to be streamed) reason : str If not successful, a reason is returned. """ location = EarthLocation.from_geodetic( instrument.telescope.lon * u.deg, instrument.telescope.lat * u.deg, instrument.telescope.elevation * u.m, ) observer = Observer(location=location, name=instrument.name) global_constraints = [ AirmassConstraint(max=2.50, boolean_constraint=False), AtNightConstraint.twilight_civil(), MoonSeparationConstraint(min=10.0 * u.deg), ] blocks = [] read_out = 10.0 * u.s for ii, followup_request in enumerate(followup_requests): obj = followup_request.obj coord = SkyCoord(ra=obj.ra * u.deg, dec=obj.dec * u.deg) target = FixedTarget(coord=coord, name=obj.id) payload = followup_request.payload allocation = followup_request.allocation requester = followup_request.requester if "start_date" in payload: start_date = Time(payload["start_date"], format='isot') if start_date > observation_end: continue if "end_date" in payload: end_date = Time(payload["end_date"], format='isot') if end_date < observation_start: continue if "priority" in payload: priority = payload["priority"] else: priority = 1 # make sure to invert priority (priority = 5.0 is max, priority = 1.0 is min) priority = 5.0 / priority if "exposure_time" in payload: exposure_time = payload["exposure_time"] * u.s else: exposure_time = 3600 * u.s if "exposure_counts" in payload: exposure_counts = payload["exposure_counts"] else: exposure_counts = 1 # get extra constraints constraints = [] if "minimum_lunar_distance" in payload: constraints.append( MoonSeparationConstraint( min=payload['minimum_lunar_distance'] * u.deg)) if "maximum_airmass" in payload: constraints.append( AirmassConstraint(max=payload['maximum_airmass'], boolean_constraint=False)) if "observation_choices" in payload: configurations = [{ 'requester': requester.username, 'group_id': allocation.group_id, 'request_id': followup_request.id, 'filter': bandpass, } for bandpass in payload["observation_choices"]] else: configurations = [{ 'requester': requester.username, 'group_id': allocation.group_id, 'request_id': followup_request.id, 'filter': 'default', }] for configuration in configurations: b = ObservingBlock.from_exposures( target, priority, exposure_time, exposure_counts, read_out, configuration=configuration, ) blocks.append(b) # Initialize a transitioner object with the slew rate and/or the # duration of other transitions (e.g. filter changes) slew_rate = 2.0 * u.deg / u.second transitioner = Transitioner(slew_rate, {'filter': { 'default': 10 * u.second }}) # Initialize the sequential scheduler with the constraints and transitioner prior_scheduler = PriorityScheduler(constraints=global_constraints, observer=observer, transitioner=transitioner) # Initialize a Schedule object, to contain the new schedule priority_schedule = Schedule(observation_start, observation_end) # Call the schedule with the observing blocks and schedule to schedule the blocks prior_scheduler(blocks, priority_schedule) if output_format in ["png", "pdf"]: matplotlib.use("Agg") fig = plt.figure(figsize=figsize, constrained_layout=False) plot_schedule_airmass(priority_schedule, show_night=True) plt.legend(loc="upper right") buf = io.BytesIO() fig.savefig(buf, format=output_format) plt.close(fig) buf.seek(0) return { "success": True, "name": f"schedule_{instrument.name}.{output_format}", "data": buf.read(), "reason": "", } elif output_format == "csv": try: schedule_table = priority_schedule.to_table(show_transitions=False, show_unused=False) except Exception as e: raise ValueError( f'Scheduling failed: there are probably no observable targets: {str(e)}.' ) schedule = [] for block in schedule_table: target = block["target"] if target == "TransitionBlock": continue filt = block["configuration"]["filter"] request_id = block["configuration"]["request_id"] group_id = block["configuration"]["group_id"] requester = block["configuration"]["requester"] obs_start = Time(block["start time (UTC)"], format='iso') obs_end = Time(block["end time (UTC)"], format='iso') exposure_time = int(block["duration (minutes)"] * 60.0) c = SkyCoord(ra=block["ra"] * u.degree, dec=block["dec"] * u.degree, frame='icrs') ra = c.ra.to_string(unit=u.hour, sep=':') dec = c.dec.to_string(unit=u.degree, sep=':') observation = { 'request_id': request_id, 'group_id': group_id, 'object_id': target, 'ra': ra, 'dec': dec, 'epoch': 2000, 'observation_start': obs_start, 'observation_end': obs_end, 'exposure_time': exposure_time, 'filter': filt, 'requester': requester, } schedule.append(observation) df = pd.DataFrame(schedule) with tempfile.NamedTemporaryFile(mode='w', suffix='.' + output_format) as f: df.to_csv(f.name) f.flush() with open(f.name, mode='rb') as g: csv_content = g.read() return { "success": True, "name": f"schedule_{instrument.name}.{output_format}", "data": csv_content, "reason": "", }
def create_at_night_constraint(*values): return AtNightConstraint.twilight_civil()