Example 4. Identify Measurement Dictionary

Meas. mode:
Scope
Eye
TDR
Package License:
L-RND
L-SNT

This example shows that the dependent measurement's name, "ΔT[+1Mid,-1Mid]", is used as the dictionary key for the measurement results dictionary:

Copy
measList = variables['MeasData']  # get list of meas dictionaries
for measDict in measList:  # Loop thru list of dictionaries
    if 'ΔT[+1Mid,-1Mid]' in measDict['Name']:
        do_something()

This example also shows that the xml file's <Dependent> element is not required, but is recommended. If this element is present and the measurement is not currently running, FlexDCA attempts to run the measurement before the user measurement script runs. If the measurement fails to start, an error occurs . Since the DeltaTime-setup.py script starts the measurement for us, the script will still run.

This script also shows that you can define additional functions in your user measurement scripts.

This script simply returns the results of the "ΔT[+1Mid,-1Mid]" measurement and does not perform its own custom user measurement.

After you've been successful with this example, run Example 5. A User Measurement which demonstrate a complete user measurement!

Required Files

DeltaTime-setup.py

This script configures FlexDCA to the state required for the example script. The script installs a simulated module, selects the proper FlexDCA mode, and turns on a delta time measurement.

Copy

DeltaTime-setup.py

import pyvisa as visa  # import VISA library

visa_address = 'TCPIP0::localhost::hislip0,4880::INSTR'
CHANNEL = '1A'
TIMEOUT = 10000


def open_flexdca_connection(address):
    """ Opens visa connection to FlexFlexDCA. """
    print('Connecting to Flexdca ...')
    try:
        rm = visa.ResourceManager()
        connection = rm.open_resource(address)
        connection.timeout = TIMEOUT  # Set connection timeout to 20s
        connection.read_termination = '\n'
        connection.write_termination = '\n'
        inst_id = connection.query('*IDN?')
        print('\nFlexDCA connection established to:\n' + inst_id, flush=True)
        connection.write(':SYSTem:DEFault')
        connection.query('*OPC?')
    except (visa.VisaIOError, visa.InvalidSession):
        print('\nVISA ERROR: Cannot open instrument address.\n', flush=True)
        return None
    except Exception as other:
        print('\nVISA ERROR: Cannot connect to instrument:', other, flush=True)
        print('\n')
        return None
    return connection


def all_channels_off(FlexDCA):
    """ Turns all available channels off. """
    for slot in '12345678':
        for letter in 'ABCD':
            channel = slot + letter
            FlexDCA.write(':CHANnel' + channel + ':DISPlay OFF')


def install_simulated_module(FlexDCA, channel, model, signal='NRZ'):
    """ Simplified installation of a simulated FlexDCA module.
    model
        Type of simulated module. "DEM" is a dual-electrical module.
        "QEM" is a quad-electrical module. "DOM" is a dual-optical
        module. "QEM" is a electrical-optical module.
    signal
        Format of signal. NRZ or PAM4.
    """
    slot = channel[0]
    FlexDCA.write(':EMODules:SLOT' + slot + ':SELection ' + model)
    if signal in 'NRZ':
        FlexDCA.write(':SOURce' + channel + ':FORMat NRZ')
    else:
        FlexDCA.write(':SOURce' + channel + ':FORMat PAM4')
    FlexDCA.write(':SOURce' + channel + ':DRATe 9.95328E+9')
    FlexDCA.write(':SOURce' + channel + ':WTYPe DATA')
    FlexDCA.write(':SOURce' + channel + ':PLENgth 127')
    FlexDCA.write(':SOURce' + channel + ':AMPLitude 90E-3')
    FlexDCA.write(':SOURce' + channel + ':NOISe:RN 3.0E-6')
    FlexDCA.write(':SOURce' + channel + ':JITTer:RJ 4.0E-12')
    FlexDCA.write(':CHANnel' + channel + ':DISPlay ON')


def return_scalar(FlexDCA, query):
    """ Returns a FlexDCA scalar measurement result. """
    import time

    class ScalarMeasQuestionableException(Exception):
        """ A scalar measurement result is questionable. """
        pass

    class ScalarMeasTimeOutException(Exception):
        """ A scalar measurement has timed out. """
        pass

    timeout = FlexDCA.timeout / 1000  # convert ms to s
    query = query.strip('?')
    start_time = time.time()  # time in seconds
    while(True):
        time.sleep(0.2)
        status = FlexDCA.query(query + ':STATus?')
        if 'CORR' in status:  # valid measurement result
            return FlexDCA.query(query + '?')  # get measurement
        elif 'QUES' in status:  # questionable results
            s = query + '\nReason: ' + FlexDCA.query(query + ':STATus:REASon?')
            raise ScalarMeasQuestionableException(s)
        elif (int(time.time() - start_time)) > timeout:  # IO timout
            s = query + '\nReason: ' + FlexDCA.query(query + ':STATus:REASon?')
            raise ScalarMeasTimeOutException(s)


flexdca = open_flexdca_connection(visa_address)
flexdca.query(':SYSTem:DEFault;*OPC?')
all_channels_off(flexdca)
install_simulated_module(flexdca, CHANNEL, 'DEM')
flexdca.write(':ACQuire:RUN')
flexdca.query(':SYSTem:MODE OSCilloscope;*OPC?')  # Switch to Eye/Mask mode
flexdca.query(':TRIGger:PLOCk ON;*OPC?')
flexdca.write(':TIMebase:SCALe 2.0000E-10')
flexdca.query(':SYSTEM:AUToscale;*OPC?')
flexdca.write(':ACQuire:SMOothing AVERage')
flexdca.write(':MEASure:OSCilloscope:DELTatime:ENUMber2 1')
flexdca.write(':MEASure:OSCilloscope:DELTatime:EDIRection1 RISing')
flexdca.write(':MEASure:OSCilloscope:DELTatime:EDIRection2 FALLing')
flexdca.write(':MEASure:OSCilloscope:DELTatime:ETHReshold1 MIDDle')
flexdca.write(':MEASure:OSCilloscope:DELTatime:ETHReshold2 MIDDle')
flexdca.write(':MEASure:OSCilloscope:DELTatime')
flexdca.write(':MEASure:OSCilloscope:DELTatime')
meas = return_scalar(flexdca, ':MEASure:OSCilloscope:DELTatime?')
flexdca.write(':SYSTem:GTLocal')
flexdca.close()

DeltaTime.xml

Installs user measurement.

Copy

DeltaTime.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- DeltaTimeTest.xml -->
<Measurement>
    <Name>Delta T Modified</Name>
    <Abbreviation>DT+</Abbreviation>
    <Comments>In Scope mode, modified delta time measurement.</Comments>
    <Script>DeltaTime.py</Script>
    <MeasurementType>1 Source</MeasurementType>
    <ValidMode>Scope</ValidMode>
</Measurement>

DeltaTime.py

User measurement script. Notice that this script includes a handy print_to_show_window() function that increases the reliability of writing to the Show Output window. This function replaces Unicode characters, which cause an error, with the equivalent XML character entity. For example, the Δ symbol in the name of the "Δ Time" measurement is replaced with the entity string.

Copy

DeltaTime.py

def algorithm(variables): 
    # Initialize the four variables that are returned to FlexDCA. 
    Result = 0.0
    Units = 's'
    ErrorMsg = ''
    Status = 'Invalid'

    # Initialize local function variables with variables from FlexDCA.
    measList = variables['MeasData']  # get list of meas dictionaries
    # Find measurement results in MeasData:
    for measDict in measList:  # Loop thru list of dictionaries
        if 'ΔT[+1Mid,-1Mid]' in measDict['Name'] and 'Correct' in measDict['Status']:
            print_to_show_window('\nDependent measurement found and is correct!')
            print_to_show_window('\tMeasurement name: ' + measDict['Name'])
            Status = 'Correct'
            Result = measDict['Result']
            break
    else:
        print_to_show_window('Measurement is missing or incorrect!')
        Status = 'Invalid'
        ErrorMsg += ' ΔT input measurement is not correct.'
    if ErrorMsg:
        s = 'ErrorMsg: ' + ErrorMsg
        print_to_show_window(s)
    if 'Invalid' in ErrorMsg:
        return { 'Result': Result,
                 'Status': Status,
                 'ErrorMsg': ErrorMsg
        }
    else:
        Result = perform_measurement(Result)
        s = 'Result: ' + str(Result)
        print_to_show_window(s)
        s = 'Status: ' + measDict['Status']
        print_to_show_window(s)
        return { 'Result': Result,
                 'Units': Units,
                 'Resolution': 0.01e-15,
                 'ValueFormat': 'Engineering',
                 'Status': measDict['Status']
        }

def perform_measurement(measurement):
    measurement  *= 1.5
    return measurement

def print_to_show_window(message):
    """ FlexDCA's Show Output window for user measurements and operators
    causes a error if a Unicode character is in the printed string.
    Removes all Unicode characters. It also removes any '\n' and '\t'
    characters.
    """
    message = message.replace('\n', '1banana')
    message = message.replace('\t', '2squirrels')
    asciiString = message.encode('ascii', 'xmlcharrefreplace')
    cleanMessage = asciiString.decode('utf-8')
    cleanMessage = cleanMessage.replace('1banana', '\n')
    cleanMessage = cleanMessage.replace('2squirrels', '\t')
    print(cleanMessage)