Esempio n. 1
0
def test_compare_block_lists():
    # create lists of blocks
    blocks = []
    for i in range(10):
        blocks.append(
            ObservingBlock(
                FixedTarget(SkyCoord(0. * u.deg, 0. * u.deg, frame='icrs'),
                            name=str(i)), 10 * u.minute, 10))

    # create two lists from these with some overlap
    blocks1 = blocks[:7]
    blocks2 = blocks[5:]

    # compare
    unique1, unique2 = Scheduler._compare_block_lists(blocks1, blocks2)

    # get names
    names1 = [int(b.target.name) for b in unique1]
    names2 = [int(b.target.name) for b in unique2]

    # names1 should contain 0, 1, 2, 3, 4
    assert set(names1) == {0, 1, 2, 3, 4}

    # names2 should contain 7, 8, 9
    assert set(names2) == {7, 8, 9}

    # create two lists from these with no overlap
    blocks1 = blocks[:5]
    blocks2 = blocks[5:]

    # compare
    unique1, unique2 = Scheduler._compare_block_lists(blocks1, blocks2)

    # get names
    names1 = [int(b.target.name) for b in unique1]
    names2 = [int(b.target.name) for b in unique2]

    # names1 should contain 0, 1, 2, 3, 4
    assert set(names1) == {0, 1, 2, 3, 4}

    # names2 should contain 5, 6, 7, 8, 9
    assert set(names2) == {5, 6, 7, 8, 9}

    # create two identical lists
    blocks1 = blocks
    blocks2 = blocks

    # compare
    unique1, unique2 = Scheduler._compare_block_lists(blocks1, blocks2)

    # get names
    names1 = [int(b.target.name) for b in unique1]
    names2 = [int(b.target.name) for b in unique2]

    # both lists should be empty
    assert len(names1) == 0
    assert len(names2) == 0
Esempio n. 2
0
def prio_schedule():
    for priority, bandpass in enumerate(['B', 'G', 'R']):
        b = ObservingBlock.from_exposures(deneb,
                                          priority,
                                          deneb_exp,
                                          n,
                                          read_out,
                                          configuration={'filter': bandpass},
                                          constraints=[first_half_night])
        blocks.append(b)
        b = ObservingBlock.from_exposures(m13,
                                          priority,
                                          m13_exp,
                                          n,
                                          read_out,
                                          configuration={'filter': bandpass},
                                          constraints=[first_half_night])
        blocks.append(b)
    slew_rate = .8 * u.deg / u.second
    # define how telescope transition between block
    transitioner = Transitioner(
        slew_rate, {
            'filter': {
                ('B', 'G'): 10 * u.second,
                ('G', 'R'): 10 * u.second,
                'default': 30 * u.second
            }
        })
    # init new seq scheduler
    prior_scheduler = PriorityScheduler(constraints=global_constraints,
                                        observer=apo,
                                        transitioner=transitioner)
    #Initialize a Schedule object, to contain the new schedule
    priority_schedule = Schedule(noon_before, noon_after)
    prior_scheduler(blocks, priority_schedule)
    plt.figure(figsize=(14, 6))
    plot_schedule_airmass(priority_schedule)
    plt.legend(loc="upper right")
    #plt.show()
    plt.savefig('prior_scheduler.png')
Esempio n. 3
0
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": "",
        }
Esempio n. 4
0
def schedule(observations: List[Dict], session: Dict, program: Dict) -> List[ObservingBlock]:
    """ Return the next object to be imaged according to the 'general' scheduling
    algorithm, and the time that the executor must wait before imaging this observation.

    Parameters
    ----------
    observations: List[Dict]
        A list of dictionaries representing the observations to be scheduled
    program: Dict
        The Program object containing the configuration of this observational program

    Returns
    -------
    obs: Dict
        The next observation to be executed
    wait: int
         The time (in seconds) to wait before imaging this observation.

    Authors: rprechelt
    """
    # create observer
    observatory = astroplan.Observer(latitude=config.general.latitude*units.deg,
                                     longitude=config.general.longitude*units.deg,
                                     elevation=config.general.altitude*units.m,
                                     name="Atlas", timezone="UTC")

    # build default constraints
    global_constraints = [constraints.AltitudeConstraint(min=40*units.deg), # set minimum altitude
                          constraints.AtNightConstraint.twilight_nautical()] # sun below -18

    # list to store observing blocks
    blocks = []

    # create targets
    for observation in observations:
        # target coordinates
        center = SkyCoord(observation['RA']+' '+observation['Dec'], unit=(units.hourangle, units.deg))

        # create and apply offset
        ra_offset = Angle(observation['options'].get('ra_offset') or 0, unit=units.arcsec)
        dec_offset = Angle(observation['options'].get('dec_offset') or 0, unit=units.arcsec)

        # offset coordinates
        coord = SkyCoord(center.ra + ra_offset, center.dec + dec_offset)

        # create astroplan traget
        target = FixedTarget(coord=coord, name=observation['target'])

        # priority - if the observation has a priority, otherwise 1
        priority = observation['options'].get('priority') or 1

        # create local constraints
        ltc = constraints.LocalTimeConstraint(min=datetime.datetime.now().time(),
                                              max=session['end'].time())

        # if specified, restrict airmass, otherwise no airmass restriction
        max_airmass = observation['options'].get('airmass') or 38
        airmass = constraints.AirmassConstraint(max=max_airmass, boolean_constraint = False)]  # rank by airmass

        # if specified, use observations moon separation, otherwise use 2 degrees
        moon_sep = observation['options'].get('moon')*units.deg or 2*units.deg
        moon = constraints.MoonSeparationConstraint(min=moon_sep*units.deg),

        # time, airmass, moon, + altitude, and at night
        constraints = [ltc, airmass, moon]

        # create observing block for this target
        blocks.append(ObservingBlock.from_exposures(target, priority, observation['exposure_time']*units.second,
                                                    observation['exposure_count']*len(observation['filters']),
                                                    config.telescope.readout_time*units.second,
                                                    configuration = observation,
                                                    constraints = [ltc]))

    # we need to create a transitioner to go between blocks
    transitioner = astroplan.Transitioner(1*units.deg/units.second,
                                          {'filter': {'default': 3*units.second}})
Esempio n. 5
0
    blocks = []

    array = data['SNR'].values
    temp = array.argsort()[::-1]  # sort high to low
    ranks = np.empty(len(array), int)
    ranks[temp] = np.arange(len(array)) + 1

    for index, t in enumerate(targets):
        #    if no_optical_data.values[index]:
        #        priority = 1
        #    else:
        #        priority = 2

        b = ObservingBlock(
            t,
            4 * 1230 * u.second,
            priority=ranks[index],
            constraints=constraint,
            configuration={'SNR': '%.4f' % data['SNR'].values[index]})
        blocks.append(b)

# now we make a transitioner
    slew_rate = .5 * u.deg / u.second
    setup_time = {'default': 160 * u.second}
    transitioner = Transitioner(slew_rate)
    '''
# now we do the scheduling
    seq_scheduler = SequentialScheduler(constraints=constraint, observer=kpno,
                                        transitioner=transitioner)
    sequential_schedule = Schedule(start_time_utc, end_time_utc)

    try:
                                        boolean_constraint = False),
                      AtNightConstraint.twilight_civil()]

rise_time = kp.sun_rise_time(tstart, which=u'next', horizon=-12*u.deg).iso
set_time = kp.sun_set_time(tstart, which=u'next', horizon=-12*u.deg).iso

blocks = []
read_out = 10.0 * u.s
nexp = 1
for ii, target in enumerate(targets):
    bandpass = target["filter"]
    exposure_time = int(target["exposure_time"]) * u.s
    priority = target["sig"]

    b = ObservingBlock.from_exposures(target["target"],priority,
                                      exposure_time, nexp, read_out,
                                      configuration = {'filter': bandpass})
    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 = kp,
                                    transitioner = transitioner)
# Initialize a Schedule object, to contain the new schedule
priority_schedule = Schedule(tstart, tend)
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)
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)
Esempio n. 9
0
deneb_exp = 60 * u.second
m13_exp = 100 * u.second
n = 16
blocks = []

half_night_start = Time('2016-07-07 02:00')
half_night_end = Time('2016-07-07 08:00')
first_half_night = TimeConstraint(half_night_start, half_night_end)

for priority, bandpass in enumerate(['B', 'G', 'R']):

    b = ObservingBlock.from_exposures(deneb,
                                      priority,
                                      deneb_exp,
                                      n,
                                      read_out,
                                      configuration={'filter': bandpass},
                                      constraints=[first_half_night])
    blocks.append(b)

    b = ObservingBlock.from_exposures(m13,
                                      priority,
                                      m13_exp,
                                      n,
                                      read_out,
                                      configuration={'filter': bandpass},
                                      constraints=[first_half_night])
    blocks.append(b)

slew_rate = .8 * u.deg / u.second
Esempio n. 10
0
def schedule(observations: List[Dict], session: Dict,
             program: Dict) -> List[ObservingBlock]:
    """ Return the next object to be imaged according to the 'general' scheduling
    algorithm, and the time that the executor must wait before imaging this observation.

    Parameters
    ----------
    observations: List[Dict]
        A list of dictionaries representing the observations to be scheduled
    program: Dict
        The Program object containing the configuration of this observational program

    Returns
    -------
    obs: Dict
        The next observation to be executed
    wait: int
         The time (in seconds) to wait before imaging this observation.

    Authors: rprechelt
    """
    # create observer
    observatory = astroplan.Observer(
        latitude=config.general.latitude * units.deg,
        longitude=config.general.longitude * units.deg,
        elevation=config.general.altitude * units.m,
        name=config.general.name,
        timezone="UTC")

    # build default constraints
    global_constraints = [
        constraints.AltitudeConstraint(min=config.telescope.min_alt *
                                       units.deg),  # set minimum altitude
        constraints.AtNightConstraint.twilight_nautical(),
        constraints.TimeConstraint(min=Time(datetime.datetime.now()),
                                   max=Time(session['end']))
    ]

    # list to store observing blocks
    blocks = []

    # create targets
    for observation in observations:

        # check whether observation has RA and Dec values
        if observation.get('RA') is None:
            continue
        if observation.get('Dec') is None:
            continue

        # target coordinates
        center = SkyCoord(observation['RA'] + ' ' + observation['Dec'],
                          unit=(units.hourangle, units.deg))

        # create and apply offset
        ra_offset = Angle(observation['options'].get('ra_offset') or 0,
                          unit=units.arcsec)
        dec_offset = Angle(observation['options'].get('dec_offset') or 0,
                           unit=units.arcsec)

        # offset coordinates
        coord = SkyCoord(center.ra + ra_offset, center.dec + dec_offset)

        # create astroplan traget
        target = FixedTarget(coord=coord, name=observation['target'])

        # priority - if the observation has a priority, otherwise 1
        priority = observation['options'].get('priority') or 1

        # if specified, restrict airmass, otherwise no airmass restriction
        max_airmass = observation['options'].get('airmass') or 38
        airmass = constraints.AirmassConstraint(
            max=max_airmass, boolean_constraint=False)  # rank by airmass

        # if specified, use observations moon separation, otherwise use 2 degrees
        moon_sep = (observation['options'].get('moon')
                    or config.queue.moon_separation) * units.deg
        moon = constraints.MoonSeparationConstraint(min=moon_sep)

        # time, airmass, moon, + altitude, and at night
        local_constraints = [moon]

        # create observing block for this target
        blocks.append(
            ObservingBlock.from_exposures(
                target,
                priority,
                observation['exposure_time'] * units.second,
                observation['exposure_count'] *
                (len(observation['filters']) + 1),
                config.telescope.readout_time * units.second,
                configuration=observation,
                constraints=local_constraints))

    # we need to create a transitioner to go between blocks
    transitioner = astroplan.Transitioner(
        1 * units.deg / units.second,
        {'filter': {
            'default': 4 * units.second
        }})

    # create priority scheduler
    priority_scheduler = scheduling.PriorityScheduler(
        constraints=global_constraints,
        observer=observatory,
        transitioner=transitioner)

    # initialize the schedule
    schedule = scheduling.Schedule(Time.now(), Time(session['end']))

    # schedule!
    schedule = priority_scheduler(blocks, schedule)

    # print(schedule.to_table())
    # print(f'observing_blocks: {schedule.observing_blocks}')
    # print(f'open_slots: {schedule.open_slots}')
    # print(f'scheduled_blocks: {schedule.scheduled_blocks}')

    # return the scheduled blocks
    return schedule
Esempio n. 11
0
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
Esempio n. 12
0
def generate_schedule(
    telescope_config,
    global_constraint_configuration,
    start_datetime,
    end_datetime,
    no_weather_constraints=False,
    requests=None
):

    # Sometimes a warning arises called OldEarthOrientationDataWarning which means the following line must run to refresh
    # should find a way to catch this warning and only download when necessary

    download_IERS_A()
    cfht = Observer.at_site('cfht')
    transitioner = create_transitioner(telescope_config['slew_rate'], telescope_config['filters'])

    # Retrieve global constraints from Constraint Aggregator

    global_constraints = ca.initialize_constraints(
        global_constraint_configuration,
        start_datetime,
        end_datetime,
        no_weather_constraints
    )

    # Currently defined in config but may belong on the block-level instead
    read_out = telescope_config['read_out'] * u.second

    # TODO: gather this data from each ObservationRequest instead
    n_exp = 5

    blocks = []

    # In order to supply block-level constraints, they should be initialized from attributes of the source data
    # and passed into the ObservingBlock initialization below

    for request in requests:
        # For each filter available on the telescope
        # TODO: define the available set within config
        for bandpass in ['B', 'G', 'R']:
            block = ObservingBlock.from_exposures(
                request.target,
                request.priority,
                request.duration,
                n_exp,
                read_out,
                configuration={'filter': bandpass},
                constraints=[]
            )
            blocks.append(block)
            print('Appending block {} with Target {} and filter {}'.format(block, request.target, bandpass))

    prior_scheduler = PriorityScheduler(
        constraints=global_constraints,
        observer=cfht,
        transitioner=transitioner
    )

    priority_schedule = Schedule(Time(start_datetime), Time(end_datetime))

    prior_scheduler(blocks, priority_schedule)

    return priority_schedule
Esempio n. 13
0
    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
Esempio n. 14
0
    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