def stdExposures_masterFlats(ccd=None,
                             feeControl=None,
                             nflats=21,
                             exptime=10,
                             flux=1000,
                             comment='master flats'):
    """ Canonical bright flats sequence. 

    At 1000ADU/s, take flats running up past saturation.
    """
    if flux is not None:
        opticslab.setup(ccd.arm, flux=flux)

    flatlist = nflats * [('flat', exptime)]
    head = tail = 5 * [('bias', 0)] + [('dark', 100)]
    explist = head + flatlist + tail

    files = ccdFuncs.expList(explist,
                             ccd=ccd,
                             feeControl=feeControl,
                             comment=comment,
                             title='master flats')

    storeExposures("std_exposures_master_flats", files, comments=comment)
    return files
def stdExposures_Fe55(ccd=None, feeControl=None, comment='Fe55 sequence'):
    """ Take standard set of Fe55 exposures.

    The Fe55 source illuminates a pretty narrow area, so we move the arm
    to three positions. At each position we take 10 30s and 10 60s exposures.

    In practice, the calling routine would run this many times.
    """
    files = []
    explist = []
    explist.append(('bias', 0), )
    for i in range(10):
        explist.append(('dark', 30), )
    for i in range(10):
        explist.append(('dark', 60), )

    opticslab.setPower('off')

    for pos in 45, 53, 61, 69:
        opticslab.setFe55(pos)

        files += ccdFuncs.expList(explist,
                                  ccd=ccd,
                                  feeControl=feeControl,
                                  comment='Fe55 dark %s' % str(pos),
                                  title='Fe55 darks')

    storeExposures("std_exposures_fe55", files, comments=comment)
    return files
def stdExposures_brightFlats(ccd=None,
                             feeControl=None,
                             comment='bright flats'):
    """ Canonical bright flats sequence. 

    At 1000ADU/s, take flats running up past saturation.
    """
    files = []
    opticslab.setup(ccd.arm, flux=1000)

    explist = (('bias', 0), ('bias', 0), ('bias', 0), ('bias', 0), ('bias', 0),
               ('dark', 100), ('flat', 30), ('flat', 30), ('flat', 1),
               ('flat', 1), ('flat', 2), ('flat', 2), ('flat', 3), ('flat', 3),
               ('flat', 4), ('flat', 4), ('flat', 5), ('flat', 5),
               ('flat', 30), ('flat', 30), ('flat', 6), ('flat', 6),
               ('flat', 7), ('flat', 7), ('flat', 8), ('flat', 8), ('flat', 9),
               ('flat', 9), ('flat', 10), ('flat', 10), ('flat', 30),
               ('flat', 30), ('flat', 12), ('flat', 12), ('flat', 14),
               ('flat', 14), ('flat', 20), ('flat', 20), ('flat', 28),
               ('flat', 28), ('flat', 32), ('flat', 32), ('flat', 30),
               ('flat', 30), ('flat', 36), ('flat', 36), ('flat', 40),
               ('flat', 40), ('flat', 44), ('flat', 44), ('flat', 48), ('flat',
                                                                        48),
               ('flat', 52), ('flat', 52), ('flat', 30), ('flat', 30), ('flat',
                                                                        55),
               ('flat', 55), ('flat', 57), ('flat', 57), ('flat', 62), ('flat',
                                                                        62),
               ('flat', 65), ('flat', 65), ('flat', 67), ('flat', 67), ('flat',
                                                                        30),
               ('flat', 30), ('flat', 50), ('flat', 50), ('flat', 60), ('flat',
                                                                        60),
               ('flat', 70), ('flat', 70), ('flat', 71), ('flat', 71), ('flat',
                                                                        73),
               ('flat', 73), ('flat', 30), ('flat', 30), ('flat', 75), ('flat',
                                                                        75),
               ('flat', 77), ('flat', 77), ('flat', 78), ('flat', 78), ('flat',
                                                                        79),
               ('flat', 79), ('flat', 80), ('flat', 80), ('flat', 30), ('flat',
                                                                        30),
               ('flat', 72), ('flat', 72), ('flat', 74), ('flat', 74), ('flat',
                                                                        76),
               ('flat', 76), ('flat', 85), ('flat', 85), ('flat', 90), ('flat',
                                                                        90),
               ('bias', 0), ('flat', 100), ('bias', 0), ('flat', 200), ('bias',
                                                                        0),
               ('flat', 400), ('bias', 0), ('flat', 30), ('flat', 30), ('bias',
                                                                        0),
               ('bias', 0), ('bias', 0), ('bias', 0), ('bias', 0), ('dark',
                                                                    100))

    files = ccdFuncs.expList(explist,
                             ccd=ccd,
                             feeControl=feeControl,
                             comment=comment,
                             title='bright flats')

    storeExposures("std_exposures_bright_flats", files, comments=comment)
    return files
def stdExposures_QE(ccd=None,
                    feeControl=None,
                    comment='QE ramp',
                    waves=None,
                    duplicate=1,
                    flatTime=10,
                    exptimes=None):
    """ Take standard QE test exposures.

    Currently taking 50m steps across the detector bandpass, with 
    10s exposures at ~1000 ADU/s
    """
    files = []
    opticslab.setup(ccd.arm, flux=1000)

    if waves is None:
        if ccd.arm == 'red':
            waves = np.arange(600, 1051, 50)
        elif ccd.arm == 'blue':
            waves = np.arange(350, 701, 50)
        else:
            raise RuntimeError(
                'QE test only knows about red and blue detectors.')

    exptimes = [flatTime for wave in waves] if exptimes is None else exptimes

    for wave, flatTime in zip(waves, exptimes):
        wave = int(round(wave))
        opticslab.setWavelength(wave)

        for i in range(duplicate):
            time.sleep(2.0)
            ccdFuncs.wipe(ccd)

            ret = opticslab.pulseShutter(flatTime)
            stime, flux, current, wave, slitWidth = ret

            cards = []
            cards.append(('HIERARCH QE.slitwidth', slitWidth,
                          'monochrometer slit width, mm'), )
            cards.append(
                ('HIERARCH QE.wave', wave, 'monochrometer wavelength, nm'), )
            cards.append(('HIERARCH QE.flux', flux, 'calibrated flux, W'), )
            cards.append(
                ('HIERARCH QE.current', current, 'Keithley current, A'), )

            expComment = "%s wave: %s" % (comment, wave)
            im, imfile = ccdFuncs.readout('flat',
                                          ccd=ccd,
                                          expTime=flatTime,
                                          feeControl=feeControl,
                                          extraCards=cards,
                                          comment=expComment)
            files.append(imfile)

    storeExposures("std_exposures_qe", files, comments=comment)
    return files
def stdExposures_biases(ccd=None, nbias=21, feeControl=None, comment='biases'):

    files = ccdFuncs.expSequence(ccd=ccd,
                                 nbias=nbias,
                                 feeControl=feeControl,
                                 comment=comment,
                                 title='%d biases' % (nbias))

    storeExposures("std_exposures_biases", files, comments=comment)
    return files
def stdExposures_base(ccd=None, feeControl=None, comment=None):

    files = stdExposures_biases(ccd=ccd,
                                feeControl=feeControl,
                                comment=comment)
    files += stdExposures_darks(ccd=ccd,
                                feeControl=feeControl,
                                comment=comment)

    storeExposures("std_exposures_base", files, comments=comment)
    return files
def stdExposures_hours(ccd=None, feeControl=None, hours=4, comment=None):
    darkTime = 900
    files = []
    for i in range(hours):
        files += ccdFuncs.expSequence(ccd=ccd,
                                      biases=5,
                                      darks=[900] * 4,
                                      feeControl=feeControl,
                                      comment=comment,
                                      title='1 hour %fs dark loop' %
                                      (darkTime))

    storeExposures("std_exposures_hours", files, comments=comment)
    return files
def stdExposures_darks(ccd=None,
                       nbias=2,
                       ndarks=21,
                       darkTime=150,
                       feeControl=None,
                       comment='darks'):

    files = ccdFuncs.expSequence(ccd=ccd,
                                 nbias=nbias,
                                 darks=[darkTime] * ndarks,
                                 feeControl=feeControl,
                                 comment=comment,
                                 title='%d %gs darks' % (ndarks, darkTime))

    storeExposures("std_exposures_darks", files, comments=comment)
    return files
def stdExposures_VOD_VOG(ccd=None,
                         feeControl=None,
                         VOD=None,
                         VOG=None,
                         nrows=None,
                         ncols=None,
                         comment='VOD/VOG tuning'):

    if VOD is None:
        VOD = np.arange(-18.0, -22.01, -0.5)
    if VOG is None:
        VOG = np.arange(-3.0, -5.01, -0.25)

    opticslab.setup(ccd.arm, flux=1000)

    files = ccdFuncs.expSequence(ccd=ccd,
                                 nrows=nrows,
                                 ncols=ncols,
                                 nbias=3,
                                 feeControl=feeControl,
                                 comment=comment,
                                 title='pre-VOD/VOG tuning biases')

    storeExposures("std_exposures_biases", files, 'pre-VOD/VOG tuning biases')

    files = []
    for vod in VOD:
        for vog in VOG:
            tweaks = ccdFuncs.FeeTweaks(feeControl)
            tweaks.tweakMode('read', OD=vod, OG=vog)

            files1 = ccdFuncs.expSequence(
                ccd=ccd,
                nrows=nrows,
                ncols=ncols,
                nbias=1,
                flats=[4],
                feeControl=tweaks,
                comment=comment,
                title='VOD/VOG tuning (%0.1f, %0.1f)' % (vod, vog))
            files.extend(files1)

    storeExposures("std_exposures_vod_vog", files)
    return files
def stdExposures_lowFlats(ccd=None, feeControl=None, comment='low flats'):
    """ Canonical low flats sequence. 

    At 10 ADU/s, take flats running up to ~4000 ADU.
    """

    opticslab.setup(ccd.arm, flux=10)

    explist = (('bias', 0), ('bias', 0), ('bias', 0), ('bias', 0), ('bias', 0),
               ('dark', 100), ('flat', 112), ('flat', 112), ('flat', 1),
               ('flat', 1), ('flat', 2), ('flat', 2), ('flat', 3), ('flat', 3),
               ('flat', 5), ('flat', 5), ('flat', 7), ('flat', 7),
               ('flat', 112), ('flat', 112), ('flat', 8), ('flat', 8),
               ('flat', 10), ('flat', 10), ('flat', 14), ('flat', 14),
               ('flat', 20), ('flat', 20), ('flat', 28), ('flat', 28),
               ('flat', 40), ('flat', 40), ('flat', 112), ('flat',
                                                           112), ('flat', 45),
               ('flat', 45), ('flat', 56), ('flat', 56), ('flat', 80), ('flat',
                                                                        80),
               ('flat', 112), ('flat', 112), ('flat', 160), ('flat', 160),
               ('flat', 224), ('flat', 224), ('flat', 320), ('flat', 320),
               ('flat', 450), ('flat', 450), ('flat', 112), ('flat', 112),
               ('flat', 600), ('flat', 600), ('flat', 112), ('flat', 112),
               ('flat', 800), ('flat', 800), ('flat', 112), ('flat', 112),
               ('flat', 1000), ('flat', 1000), ('flat', 112), ('flat', 112),
               ('flat', 1200), ('flat', 1200), ('flat', 112), ('flat', 112),
               ('bias', 0), ('bias', 0), ('bias', 0), ('bias',
                                                       0), ('bias',
                                                            0), ('dark', 100))

    files = ccdFuncs.expList(explist,
                             ccd=ccd,
                             feeControl=feeControl,
                             comment=comment,
                             title='low flats')

    storeExposures("std_exposures_low_flats", files, comments=comment)
    return files