Example #1
0
def test_get_aca_offsets():
    """
    Test that ACA offsets are reasonable, and regression test particular values
    corresponding to cycle 17 zero-offset aimpoints used below for chip_x, chip_y inputs.

    The output reference values here have been validated as being "reasonable" for the
    given inputs.
    """
    offsets = drift.get_aca_offsets('ACIS-I', 3, 930.2, 1009.6, '2016:180', -15.0)
    assert np.allclose(offsets, (11.83637884563926, 2.6860740140775334), atol=0.1)

    offsets = drift.get_aca_offsets('ACIS-S', 7, 200.7, 476.9, '2016:180', -15.0)
    assert np.allclose(offsets, (13.360706170615167, 3.8670874955935481), atol=0.1)

    offsets = drift.get_aca_offsets('HRC-I', 0, 7591, 7936, '2016:180', -15.0)
    assert np.allclose(offsets, (14.728718419826098, 0.7925650626134555), atol=0.1)

    offsets = drift.get_aca_offsets('HRC-S', 2, 2041, 9062, '2016:180', -15.0)
    assert np.allclose(offsets, (17.269560057119545, 3.4474216529603225), atol=0.1)
Example #2
0
def test_get_aca_offsets():
    """
    Test that ACA offsets are reasonable, and regression test particular values
    corresponding to cycle 17 zero-offset aimpoints used below for chip_x, chip_y inputs.

    The output reference values here have been validated as being "reasonable" for the
    given inputs.
    """
    offsets = drift.get_aca_offsets('ACIS-I', 3, 930.2, 1009.6,
                                    '2016:180:12:00:00', -15.0)
    assert np.allclose(offsets, (11.45, 2.34), atol=0.1, rtol=0)

    offsets = drift.get_aca_offsets('ACIS-S', 7, 200.7, 476.9,
                                    '2016:180:12:00:00', -15.0)
    assert np.allclose(offsets, (12.98, 3.52), atol=0.1, rtol=0)

    offsets = drift.get_aca_offsets('HRC-I', 0, 7591, 7936,
                                    '2016:180:12:00:00', -15.0)
    assert np.allclose(offsets, (14.35, 0.45), atol=0.1, rtol=0)

    offsets = drift.get_aca_offsets('HRC-S', 2, 2041, 9062,
                                    '2016:180:12:00:00', -15.0)
    assert np.allclose(offsets, (16.89, 3.10), atol=0.1, rtol=0)
Example #3
0
def get_interval_data(intervals, times, ccd_temp, obsreqs=None):
    """
    Determine the max temperature and mean offsets over each interval.

    If the OR list is supplied (in the obsreqs dictionary) the ACA offsets will
    also be calculated for each interval and included in the returned data.

    :param intervals: list of dictionaries describing obsid/catalog intervals
    :param times: times of the temperature samples
    :param ccd_temp: ccd temperature values
    :param obsreqs: optional dictionary of OR list from parse_cm.or_list

    :returns: dictionary (keyed by obsid) of intervals with max ccd_temps
    """
    obstemps = {}
    for interval in intervals:
        # treat the model samples as temperature intervals
        # and find the max during each obsid npnt interval
        obs = {'ccd_temp': None}
        obs.update(interval)
        stop_idx = 1 + np.searchsorted(times, interval['tstop'])
        start_idx = -1 + np.searchsorted(times, interval['tstart'])
        ok_temps = ccd_temp[start_idx:stop_idx]
        ok_times = times[start_idx:stop_idx]
        # If there are no good samples, put the times in the output dict and go to the next interval
        if len(ok_temps) == 0:
            obstemps[str(interval['obsid'])] = obs
            continue
        obs['ccd_temp'] = np.max(ok_temps)
        obs['ccd_temp_acq'] = np.max(ok_temps[:2])
        obs['n100_warm_frac'] = dark_model.get_warm_fracs(
            100, interval['tstart'], np.max(ok_temps))
        # If we have an OR list, the obsid is in that list, and the OR list has zero-offset keys
        if (obsreqs is not None and interval['obsid'] in obsreqs
                and 'chip_id' in obsreqs[interval['obsid']]):
            obsreq = obsreqs[interval['obsid']]
            ddy, ddz = get_aca_offsets(obsreq['detector'],
                                       obsreq['chip_id'],
                                       obsreq['chipx'],
                                       obsreq['chipy'],
                                       time=ok_times,
                                       t_ccd=ok_temps)
            obs['aca_offset_y'] = np.mean(ddy)
            obs['aca_offset_z'] = np.mean(ddz)
        obstemps[str(interval['obsid'])] = obs
    return obstemps
Example #4
0
def run_one_yoshi(*, obsid,
                  detector, chipx, chipy, chip_id,
                  ra_targ, dec_targ, roll_targ,
                  offset_y, offset_z, sim_offset, focus_offset,
                  dither_y, dither_z,
                  obs_date, t_ccd, man_angle):
    """
    Run proseco and sparkles for an observation request in a roll/temperature/man_angle
    scenario.

    :param obsid: obsid
    :param detector: detector (ACIS-I|ACIS-S|HRC-I|HRC-S)
    :param chipx: chipx from zero-offset aimpoint table entry for obsid
    :param chipy: chipy from zero-offset aimpoint table entry for obsid
    :param chip_id: chip_id from zero-offset aimpoint table entry for obsid
    :param ra_targ: target RA (degrees)
    :param dec_targ: target Dec (degrees)
    :param roll_targ: target Roll (degrees)
    :param offset_y: target offset_y (arcmin)
    :param offset_z: target offset_z (arcmin)
    :param sim_offset: SIM Z offset (steps)
    :param focus_offset: SIM focus offset (steps)
    :param dither_y: Y amplitude dither (arcsec)
    :param dither_z: Z amplitude dither (arcsec)
    :param obs_date: observation date (for proper motion and ACA offset projection)
    :param t_ccd: ACA CCD temperature (degrees C)
    :param man_angle: maneuver angle (degrees)
    :returns: dictionary of (ra_aca, dec_aca, roll_aca,
                             n_critical, n_warning, n_caution, n_info,
                             P2, guide_count)

    """

    # Calculate dynamic offsets using the supplied temperature.
    aca_offset_y, aca_offset_z = get_aca_offsets(detector,
                                                 chip_id, chipx, chipy,
                                                 obs_date, t_ccd)

    # Get the ACA quaternion using target offsets and dynamic offsets.
    # Note that calc_aca_from_targ expects target offsets in degrees and obs is now in arcmin
    q_aca = calc_aca_from_targ((ra_targ, dec_targ, roll_targ),
                               (offset_y / 60.) + (aca_offset_y / 3600.),
                               (offset_z / 60.) + (aca_offset_z / 3600.))

    # Run proseco and sparkles
    aca = proseco.get_aca_catalog(obsid=obsid,
                                  att=q_aca,
                                  man_angle=man_angle,
                                  date=obs_date,
                                  t_ccd=t_ccd,
                                  dither=(dither_y, dither_z),
                                  detector=detector,
                                  sim_offset=sim_offset,
                                  focus_offset=focus_offset,
                                  n_acq=8, n_guide=5, n_fid=3)
    acar = aca.get_review_table()
    acar.run_aca_review()

    # Get values for report
    report = {'ra_aca': q_aca.ra,
              'dec_aca': q_aca.dec,
              'roll_aca': q_aca.roll,
              'n_critical': len(acar.messages == 'critical'),
              'n_warning': len(acar.messages == 'warning'),
              'n_caution': len(acar.messages == 'caution'),
              'n_info': len(acar.messages == 'info'),
              'P2': -np.log10(acar.acqs.calc_p_safe()),
              'guide_count': acar.guide_count}
    return report