def iv(target, rows):
    if target == 'hot':
        p_index = hot_p_index
    else:
        p_index = sky_p_index
    load.move('b%d_%s' % (band, target))

    if target == 'hot':
        cart.tune(lo_ghz, 0.0, skip_servo_pa=True)
        cart._set_pa([pas[0], pas[1]])
        cart.update_all()
        if namakanui.util.iftask_setup(2, 1000, 6, dcms):  # level only
            return 1

    sys.stderr.write('%s: ' % (target))
    sys.stderr.flush()

    mult = 1.0
    if band == 6:
        mult = -1.0
    cart._ramp_sis_bias_voltages(
        [mult * mvs[0], mvs[0], mult * mvs[0], mvs[0]])
    for i, mv in enumerate(mvs):
        if (i + 1) % 20 == 0:
            sys.stderr.write('%.2f%% ' % (0.0 + 50 * i / len(mvs)))
            sys.stderr.flush()
            cart.update_all()  # for anyone monitoring
        for po in range(2):
            cart.femc.set_sis_voltage(cart.ca, po, 0, mult * mv)
            cart.femc.set_sis_voltage(cart.ca, po, 1, mv)
        rows[i][mv_index] = mv
        # start IFTASK action while we average the mixer current readings
        transid = drama.obey("IFTASK@if-micro",
                             "WRITE_TP2",
                             FILE="NONE",
                             ITIME=0.1)
        # TODO: separate hot/cold mixer currents, or only calc hot
        for j in range(ua_n):
            for po in range(2):
                for sb in range(2):
                    ua = cart.femc.get_sis_current(cart.ca, po, sb) * 1e3
                    rows[i][ua_avg_index + po * 2 + sb] += abs(
                        ua)  # for band 6
                    rows[i][ua_dev_index + po * 2 + sb] += ua * ua
        # get IFTASK reply
        msg = transid.wait(5)
        if msg.reason != drama.REA_COMPLETE or msg.status != 0:
            logging.error('bad reply from IFTASK.WRITE_TP2: %s', msg)
            return 1
        for j, dcm in enumerate(dcms):
            rows[i][p_index + j] = msg.arg['POWER%d' % (dcm)]

    sys.stderr.write('\n')
    sys.stderr.flush()
    return 0
def LOAD_MOVE(msg):
    '''Move the load.  Arguments:
            POSITION:  Named position or absolute encoder counts.
    '''
    log.debug('LOAD_MOVE(%s)', msg.arg)
    if not initialised:
        raise drama.BadStatus(drama.APP_ERROR, 'task needs INITIALISE')
    if msg.reason == drama.REA_OBEY:
        args, kwargs = drama.parse_argument(msg.arg)
        pos = load_move_args(*args, **kwargs)
        log.info('moving load to %s...', pos)
        load.move(pos)
        log.info('load at %d, %s.', load.state['pos_counts'],
                 load.state['pos_name'])
    else:
        log.error('LOAD_MOVE stopping load due to unexpected msg %s', msg)
        load.stop()
Beispiel #3
0
def ip(target, rows, pas):
    if target == 'hot':
        p_index = hot_p_index
    else:
        p_index = sky_p_index
    load.move('b%d_%s' % (band, target))

    sys.stderr.write('%s: ' % (target))
    sys.stderr.flush()

    for i, pa in enumerate(pas):
        if (i + 1) % 20 == 0:
            sys.stderr.write('%.2f%% ' % (100.0 * i / len(pas)))
            sys.stderr.flush()
            cart.update_all()

        cart._set_pa([pa, pa])
        rows[i][pa_index] = pa

        # start IFTASK action while we average the mixer current readings
        transid = drama.obey("IFTASK@if-micro",
                             "WRITE_TP2",
                             FILE="NONE",
                             ITIME=0.1)
        for j in range(ua_n):
            for po in range(2):
                for sb in range(2):
                    ua = cart.femc.get_sis_current(cart.ca, po, sb) * 1e3
                    rows[i][ua_avg_index + po * 2 + sb] += abs(
                        ua)  # for band 6
                    rows[i][ua_dev_index + po * 2 + sb] += ua * ua
        # get IFTASK reply
        msg = transid.wait(5)
        if msg.reason != drama.REA_COMPLETE or msg.status != 0:
            logging.error('bad reply from IFTASK.WRITE_TP2: %s', msg)
            return 1

        for j, dcm in enumerate(dcm_0 + dcm_1):
            rows[i][p_index + j] = msg.arg['POWER%d' % (dcm)]

    sys.stderr.write('\n')
    sys.stderr.flush()
    return 0
Beispiel #4
0
parser.add_argument('--level_only', action='store_true')
args = parser.parse_args()

band = args.band
lo_ghz = args.lo_ghz
lo_range = {6:[219,266], 7:[281,367]}[band]
if not lo_range[0] <= lo_ghz <= lo_range[1]:
    logging.error('lo_ghz %g outside %s range for band %d', lo_ghz, lo_range, band)
    sys.exit(1)

# perform basic setup and get handles
cart, agilent, photonics = util.setup_script(args.band, args.lock_side)

# init load controller and set to hot (ambient) load for this band
load = namakanui.load.Load(datapath+'load.ini', time.sleep, namakanui.nop)
load.move('b%d_hot'%(band))

# tune cartridge, adjusting power as needed
if not util.tune(cart, agilent, photonics, lo_ghz):
    logging.error('failed to tune to %.3f ghz', lo_ghz)
    sys.exit(1)

# determine dbm limits
dbm = agilent.state['dbm']
orig_dbm = dbm
while dbm < agilent.max_dbm and cart.state['pll_if_power'] > -2.5 and not cart.state['pll_unlock']:
    dbm += 0.1
    agilent.set_dbm(dbm)
    time.sleep(0.05)
    cart.update_all()
    logging.info('+ dbm %.2f, pll_if %.3f', dbm, cart.state['pll_if_power'])
Beispiel #5
0
                    action='store_true',
                    help='print additional debug output')
parser.add_argument('pos',
                    help='"home", counts, or a named position from load.ini')
args = parser.parse_args()

if args.verbose:
    logging.root.setLevel(logging.DEBUG)
    logging.debug('verbose: log level set to DEBUG')

binpath, datapath = namakanui.util.get_paths()


def mypub(n, s):
    pass


load = namakanui.load.Load(datapath + 'load.ini', time.sleep, mypub)

pos = args.pos.strip()
if pos.lower() == 'home':
    logging.info('homing load controller...')
    load.home()
else:
    logging.info('moving to %s...', pos)
    load.move(pos)

load.update()
logging.info('done, load at %d: %s', load.state['pos_counts'],
             load.state['pos_name'])
Beispiel #6
0
for mixer in ['01', '02', '11', '12']:
    sys.stdout.write(' ua%s' % (mixer))
for po in ['0', '1']:
    sys.stdout.write(' vd%s' % (po))
for po in ['0', '1']:
    sys.stdout.write(' id%s' % (po))
for po in ['0', '1']:
    sys.stdout.write(' vg%s' % (po))
sys.stdout.write('\n')
sys.stdout.flush()

# init load controller and set desired load (default hot)
load = namakanui.load.Load(datapath + 'load.ini', time.sleep, namakanui.nop)
if args.load == 'hot' or args.load == 'sky':
    args.load = 'b%d_' % (band) + args.load
load.move(args.load)

# perform basic setup and get handles
cart, agilent, photonics = namakanui.util.setup_script(args.band,
                                                       args.lock_side)

# main loop
for lo in los:
    if not namakanui.util.tune(cart, agilent, photonics, lo):
        continue
    sys.stdout.write('%.3f ' % (lo))
    pa_drain_s = cart.state['pa_drain_s']
    sys.stdout.write('%.3f %.3f ' % (pa_drain_s[0], pa_drain_s[1]))
    # average mixer currents
    n = 10
    uas = [0.0] * 4
Beispiel #7
0
parser.add_argument('--vg')  # range (for b6, use -.40:.14:.01)
parser.add_argument('--vd', type=float,
                    default=2.5)  # vd for both pols during vg sweep
args = parser.parse_args()
args.lock_side = 'above'

los = namakanui.util.parse_range(args.lo, maxlen=1e3)
vgs = namakanui.util.parse_range(args.vg, maxlen=1e2)  # TODO okay for b7?

# perform basic setup and get handles
cart, agilent, photonics = namakanui.util.setup_script(args.band,
                                                       args.lock_side)

# init load controller and set to hot (ambient) load for this band
load = namakanui.load.Load(datapath + 'load.ini', time.sleep, namakanui.nop)
load.move('b%d_hot' % (args.band))

# for _servo_pa output
cart.log.setLevel(logging.DEBUG)

# write out a header for our output file
print(time.strftime('# %Y%m%d %H:%M:%S HST', time.localtime()))
print('#', sys.argv)
print('# vdX: LO PA drain voltage for polX')
print('# vdX: LO PA gate voltage for polX')
print('#')
print('#lo_ghz vd0   vd1   vg0  vg1')


# 7-point averaging function to smooth vg-ua curves
def smooth(y):
Beispiel #8
0
def iv(target, rows, pa):
    if target == 'hot':
        p_index = hot_p_index
    else:
        p_index = sky_p_index
    load.move('b%d_%s' % (band, target))

    # TODO Maybe it's wrong to relevel for each PA; it makes it harder
    # to compare power between PAs if the leveling is slightly different.
    # Ambient temperature shouldn't be changing much compared to the
    # difference between hot load and sky, either.

    # at the start of a HOT row, re-tune and re-level the power meters
    # at the nominal values.  do not relevel on SKY or y-factor won't work.
    # actually re-leveling makes it difficult to compare power levels
    # across sweeps, so skip it.  retuning is fine though.
    # 20200221 but ACTUALLY we're having problems with saturating power levels,
    # so DO relevel the detectors here.  we won't be able to see
    # relative power levels, but we mostly only do 2 PAs these days and care
    # more about Y-factor values anyway.
    if target == 'hot':
        # dbm/att should already be set from namakanui.util.tune
        cart.tune(lo_ghz, 0.0, skip_servo_pa=True)
        cart._set_pa([pa, pa])
        cart.update_all()
        if namakanui.util.iftask_setup(2, 1000, 6, dcms):  # level only
            return 1

    sys.stderr.write('%s: ' % (target))
    sys.stderr.flush()

    # NOTE: The two SIS mixers in each polarization module are not really USB and LSB.
    # Rather the input to one is phase-shifted relative to the other, and their
    # signals are then combined to produce USB and LSB outputs.  So to check the
    # power output and Y-factor from each mixer individually, the other one needs
    # to have its output disabled by setting its bias voltage to zero.
    # Since we still need to smoothly ramp SIS bias voltage for large changes,
    # we therefore do two separate loops for sis1 and sis2.

    # TODO: Once we have the mixers optimized individually, we might still need
    # to optimize their combined outputs.  This will require a 2D scan of
    # mixer bias voltage for each PA setting.

    # sis1
    sb = 0
    mult = 1.0
    if band == 6:
        mult = -1.0
    if args.zero:
        cart._ramp_sis_bias_voltages([mult * mvs[0], 0.0, mult * mvs[0], 0.0])
    else:
        cart._ramp_sis_bias_voltages(
            [mult * mvs[0], nom_v[1], mult * mvs[0], nom_v[3]])
    for i, mv in enumerate(mvs):
        if (i + 1) % 20 == 0:
            sys.stderr.write('%.2f%% ' % (0.0 + 50 * i / len(mvs)))
            sys.stderr.flush()
            cart.update_all()  # for anyone monitoring
        for po in range(2):
            cart.femc.set_sis_voltage(cart.ca, po, sb, mult * mv)
        rows[i][mv_index] = mv
        # start IFTASK action while we average the mixer current readings
        transid = drama.obey("IFTASK@if-micro",
                             "WRITE_TP2",
                             FILE="NONE",
                             ITIME=0.1)
        for j in range(ua_n):
            for po in range(2):
                ua = cart.femc.get_sis_current(cart.ca, po, sb) * 1e3
                rows[i][ua_avg_index + po * 2 + sb] += abs(ua)  # for band 6
                rows[i][ua_dev_index + po * 2 + sb] += ua * ua
        # get IFTASK reply
        msg = transid.wait(5)
        if msg.reason != drama.REA_COMPLETE or msg.status != 0:
            logging.error('bad reply from IFTASK.WRITE_TP2: %s', msg)
            return 1

        for j, dcm in enumerate(dcm_0):
            rows[i][p_index + j + 0] = msg.arg['POWER%d' % (dcm)]
        for j, dcm in enumerate(dcm_1):
            rows[i][p_index + j + 16] = msg.arg['POWER%d' % (dcm)]

    # sis2
    sb = 1
    if args.zero:
        cart._ramp_sis_bias_voltages([0.0, mvs[0], 0.0, mvs[0]])
    else:
        cart._ramp_sis_bias_voltages([nom_v[0], mvs[0], nom_v[2], mvs[0]])
    for i, mv in enumerate(mvs):
        if (i + 1) % 20 == 0:
            sys.stderr.write('%.2f%% ' % (50.0 + 50 * i / len(mvs)))
            sys.stderr.flush()
            cart.update_all()  # for anyone monitoring
        for po in range(2):
            cart.femc.set_sis_voltage(cart.ca, po, sb, mv)
        rows[i][mv_index] = mv
        # start IFTASK action while we average the mixer current readings
        transid = drama.obey("IFTASK@if-micro",
                             "WRITE_TP2",
                             FILE="NONE",
                             ITIME=0.1)
        for j in range(ua_n):
            for po in range(2):
                ua = cart.femc.get_sis_current(cart.ca, po, sb) * 1e3
                rows[i][ua_avg_index + po * 2 + sb] += ua
                rows[i][ua_dev_index + po * 2 + sb] += ua * ua
        # get IFTASK reply
        msg = transid.wait(5)
        if msg.reason != drama.REA_COMPLETE or msg.status != 0:
            logging.error('bad reply from IFTASK.WRITE_TP2: %s', msg)
            return 1

        for j, dcm in enumerate(dcm_0):
            rows[i][p_index + j + 8] = msg.arg['POWER%d' % (dcm)]
        for j, dcm in enumerate(dcm_1):
            rows[i][p_index + j + 24] = msg.arg['POWER%d' % (dcm)]

    sys.stderr.write('\n')
    sys.stderr.flush()
    return 0