Beispiel #1
0
def calc_weight(errdata):
    sp = np.fft.fft(errdata)[1:len(errdata) // 2]
    if sp.sum() == 0:  # there is no variation in the signal
        log.warn('no variation in the signal.  fft cannot continue')
        return 1

    # get the phase in radians  # -np.pi < phase <= +np.pi
    phase = np.angle(sp)  # radians

    # find the amplitude integral of neighboring samples.
    # search <360 degrees to left of most recent sample's phase
    # p_k = phase - degrees_between_samples * k  # kth phase
    amplitude_integrals = np.abs(np.sin(phase))  # iteratively updated
    # samples per cycle
    kth = len(errdata) / np.arange(1, len(errdata) // 2)
    num_degrees_between_samples = 2 * np.pi / kth
    p_k = phase.copy()
    while (kth > 0).any():
        # find amplitude of a sign wave at specific phase
        p_k -= num_degrees_between_samples
        amplitude_integrals += np.abs(np.sin(p_k))
        kth -= 1
        idxs = kth > 0
        not_idxs = ~idxs
        kth = kth[idxs]
        p_k[not_idxs] = 0
        num_degrees_between_samples[not_idxs] = 0

    # get the amplitude of each frequency in the fft spectrum
    amplitude = np.abs(sp)
    return (
        # np.sin(phase)
        (np.sin(phase) / amplitude_integrals) *
        (amplitude / amplitude.sum())).sum()
Beispiel #2
0
def calc_weight(errdata):
    sp = np.fft.fft(errdata)[1 : len(errdata) // 2]
    if sp.sum() == 0:  # there is no variation in the signal
        log.warn("no variation in the signal.  fft cannot continue")
        return 1

    # get the phase in radians  # -np.pi < phase <= +np.pi
    phase = np.angle(sp)  # radians

    # find the amplitude integral of neighboring samples.
    # search <360 degrees to left of most recent sample's phase
    # p_k = phase - degrees_between_samples * k  # kth phase
    amplitude_integrals = np.abs(np.sin(phase))  # iteratively updated
    # samples per cycle
    kth = len(errdata) / np.arange(1, len(errdata) // 2)
    num_degrees_between_samples = 2 * np.pi / kth
    p_k = phase.copy()
    while (kth > 0).any():
        # find amplitude of a sign wave at specific phase
        p_k -= num_degrees_between_samples
        amplitude_integrals += np.abs(np.sin(p_k))
        kth -= 1
        idxs = kth > 0
        not_idxs = ~idxs
        kth = kth[idxs]
        p_k[not_idxs] = 0
        num_degrees_between_samples[not_idxs] = 0

    # get the amplitude of each frequency in the fft spectrum
    amplitude = np.abs(sp)
    return (
        # np.sin(phase)
        (np.sin(phase) / amplitude_integrals)
        * (amplitude / amplitude.sum())
    ).sum()
Beispiel #3
0
def main(ns):
    validate_ns_or_sysexit(ns)
    configure_logging(True)
    if ns.sendstats:
        if ns.sendstats == 'webui':
            add_zmq_log_handler('ipc:///tmp/relaylog')
            start_webui()
        else:
            add_zmq_log_handler(ns.sendstats)
    log.info("Starting relay!",
             extra={k: str(v)
                    for k, v in ns.__dict__.items()})

    metric = ns.metric()
    target = ns.target()
    errhist = window(ns.lookback)
    ramp_index = 0

    while True:
        SP = next(target)  # set point
        PV = next(metric)  # process variable
        err = (SP - PV)
        log.debug('got metric value', extra=dict(PV=PV, SP=SP))
        if ramp_index < ns.ramp:
            if ramp_index == 0:
                plan = create_ramp_plan(err, ns.ramp)
            ramp_index += 1
            MV = next(plan)
            errdata = errhist.send(0)
        else:
            errdata = errhist.send(err)
            weight = calc_weight(errdata)
            MV = int(round(err - weight * sum(errdata) / len(errdata)))
            log.info(
                'data',
                extra=dict(data=[err, weight,
                                 sum(errdata) / len(errdata)]))

        if MV > 0:
            if ns.warmer:
                log.debug('adding heat', extra=dict(MV=MV, err=err))
                threading.Thread(target=ns.warmer, args=(MV, )).start()
            else:
                log.warn('too cold')
        elif MV < 0:
            if ns.cooler:
                log.debug('removing heat', extra=dict(MV=MV, err=err))
                threading.Thread(target=ns.cooler, args=(MV, )).start()
            else:
                log.warn('too hot')
        else:
            log.debug('stabilized PV at setpoint',
                      extra=dict(MV=MV, PV=PV, SP=SP))
        time.sleep(ns.delay)
        evaluate_stop_condition(list(errdata), ns.stop_condition)
Beispiel #4
0
def main(ns):
    validate_ns_or_sysexit(ns)
    configure_logging(True)
    if ns.sendstats:
        if ns.sendstats == "webui":
            add_zmq_log_handler("ipc:///tmp/relaylog")
            start_webui()
        else:
            add_zmq_log_handler(ns.sendstats)
    log.info("Starting relay!", extra={k: str(v) for k, v in ns.__dict__.items()})

    metric = ns.metric()
    target = ns.target()
    errhist = window(ns.lookback)
    ramp_index = 0

    while True:
        SP = next(target)  # set point
        PV = next(metric)  # process variable
        err = SP - PV
        log.debug("got metric value", extra=dict(PV=PV, SP=SP))
        if ramp_index < ns.ramp:
            if ramp_index == 0:
                plan = create_ramp_plan(err, ns.ramp)
            ramp_index += 1
            MV = next(plan)
            errdata = errhist.send(0)
        else:
            errdata = errhist.send(err)
            weight = calc_weight(errdata)
            MV = int(round(err - weight * sum(errdata) / len(errdata)))
            log.info("data", extra=dict(data=[err, weight, sum(errdata) / len(errdata)]))

        if MV > 0:
            if ns.warmer:
                log.debug("adding heat", extra=dict(MV=MV, err=err))
                threading.Thread(target=ns.warmer, args=(MV,)).start()
            else:
                log.warn("too cold")
        elif MV < 0:
            if ns.cooler:
                log.debug("removing heat", extra=dict(MV=MV, err=err))
                threading.Thread(target=ns.cooler, args=(MV,)).start()
            else:
                log.warn("too hot")
        else:
            log.debug("stabilized PV at setpoint", extra=dict(MV=MV, PV=PV, SP=SP))
        time.sleep(ns.delay)
        evaluate_stop_condition(list(errdata), ns.stop_condition)