Example #1
0
def compile_to_hardware(seqs, fileName, suffix=''):
    '''
    Compiles 'seqs' to a hardware description and saves it to 'fileName'. Other inputs:
        suffix : string to append to end of fileName (e.g. with fileNames = 'test' and suffix = 'foo' might save to test-APSfoo.h5)
    '''

    # Add the digitizer trigger to measurements
    PatternUtils.add_digitizer_trigger(seqs, channelLib['digitizerTrig'])

    # Add gating/blanking pulses
    PatternUtils.add_gate_pulses(seqs)

    # Add the slave trigger
    PatternUtils.add_slave_trigger(seqs, channelLib['slaveTrig'])

    # find channel set at top level to account for individual sequence channel variability
    channels = set([])
    for seq in seqs:
        channels |= find_unique_channels(seq)

    # Compile all the pulses/pulseblocks to sequences of pulses and control flow
    wireSeqs = compile_sequences(seqs, channels)

    if not validate_linklist_channels(wireSeqs.keys()):
        print "Compile to hardware failed"
        return

    # apply gating constraints
    for chan, seq in wireSeqs.items():
        if isinstance(chan, Channels.LogicalMarkerChannel):
            wireSeqs[chan] = PatternUtils.apply_gating_constraints(
                chan.physChan, seq)
    # map logical to physical channels
    physWires = map_logical_to_physical(wireSeqs)

    # construct channel delay map
    delays = channel_delay_map(physWires)

    # apply delays
    for chan, wire in physWires.items():
        PatternUtils.delay(wire, delays[chan])

    # generate wf library (base shapes)
    wfs = generate_waveforms(physWires)

    # replace Pulse objects with Waveforms
    physWires = pulses_to_waveforms(physWires)

    # bundle wires on instruments
    awgData = bundle_wires(physWires, wfs)

    # convert to hardware formats
    fileList = []
    for awgName, data in awgData.items():
        # create the target folder if it does not exist
        targetFolder = os.path.split(
            os.path.normpath(os.path.join(config.AWGDir, fileName)))[0]
        if not os.path.exists(targetFolder):
            os.mkdir(targetFolder)
        fullFileName = os.path.normpath(
            os.path.join(
                config.AWGDir, fileName + '-' + awgName + suffix +
                instrumentLib[awgName].seqFileExt))
        instrumentLib[awgName].write_sequence_file(data, fullFileName)

        fileList.append(fullFileName)

    # Return the filenames we wrote
    return fileList
Example #2
0
def compile_to_hardware(seqs, fileName, suffix=''):
    '''
    Compiles 'seqs' to a hardware description and saves it to 'fileName'. Other inputs:
        suffix : string to append to end of fileName (e.g. with fileNames = 'test' and suffix = 'foo' might save to test-APSfoo.h5)
    '''

    # Add the digitizer trigger to measurements
    PatternUtils.add_digitizer_trigger(seqs, channelLib['digitizerTrig'])

    # Add gating/blanking pulses
    PatternUtils.add_gate_pulses(seqs)

    # Add the slave trigger
    PatternUtils.add_slave_trigger(seqs, channelLib['slaveTrig'])

    # find channel set at top level to account for individual sequence channel variability
    channels = set([])
    for seq in seqs:
        channels |= find_unique_channels(seq)

    # Compile all the pulses/pulseblocks to sequences of pulses and control flow
    wireSeqs = compile_sequences(seqs, channels)

    if not validate_linklist_channels(wireSeqs.keys()):
        print "Compile to hardware failed"
        return

    # apply gating constraints
    for chan, seq in wireSeqs.items():
        if isinstance(chan, Channels.LogicalMarkerChannel):
            wireSeqs[chan] = PatternUtils.apply_gating_constraints(chan.physChan, seq)
    # map logical to physical channels
    physWires = map_logical_to_physical(wireSeqs)

    # construct channel delay map
    delays = channel_delay_map(physWires)

    # apply delays
    for chan, wire in physWires.items():
        PatternUtils.delay(wire, delays[chan])

    # generate wf library (base shapes)
    wfs = generate_waveforms(physWires)

    # replace Pulse objects with Waveforms
    physWires = pulses_to_waveforms(physWires)

    # bundle wires on instruments
    awgData = bundle_wires(physWires, wfs)

    # convert to hardware formats
    fileList = []
    for awgName, data in awgData.items():
        # create the target folder if it does not exist
        targetFolder = os.path.split(os.path.normpath(os.path.join(config.AWGDir, fileName)))[0]
        if not os.path.exists(targetFolder):
            os.mkdir(targetFolder)
        fullFileName = os.path.normpath(os.path.join(config.AWGDir, fileName + '-' + awgName + suffix + instrumentLib[awgName].seqFileExt))
        instrumentLib[awgName].write_sequence_file(data, fullFileName)

        fileList.append(fullFileName)

    # Return the filenames we wrote
    return fileList
Example #3
0
def compile_to_hardware(seqs, fileName, suffix='', alignMode="right"):
    '''
    Compiles 'seqs' to a hardware description and saves it to 'fileName'. Other inputs:
        suffix : string to append to end of fileName (e.g. with fileNames = 'test' and suffix = 'foo' might save to test-APSfoo.h5)
        alignMode : 'left' or 'right' (default 'left')
    '''

    #Add the digitizer trigger to measurements
    PatternUtils.add_digitizer_trigger(seqs, channelLib['digitizerTrig'])

    # Add gating/blanking pulses
    PatternUtils.add_gate_pulses(seqs)

    # Add the slave trigger
    PatternUtils.add_slave_trigger(seqs, channelLib['slaveTrig'])

    # find channel set at top level to account for individual sequence channel variability
    channels = set([])
    for seq in seqs:
        channels |= find_unique_channels(seq)

    #Compile all the pulses/pulseblocks to linklists and waveform libraries
    linkLists, wfLib = compile_sequences(seqs, channels)

    if not validate_linklist_channels(linkLists.keys()):
        print "Compile to hardware failed"
        return        

    # apply gating constraints
    for chan, LL in linkLists.items():
        if isinstance(chan, Channels.LogicalMarkerChannel):
            linkLists[chan] = PatternUtils.apply_gating_constraints(chan.physChan, LL)
    # map logical to physical channels
    awgData = map_logical_to_physical(linkLists, wfLib)
    # construct channel delay map
    chanDelays = channel_delay_map(awgData)

    # for each physical channel need to:
    # 1) delay
    # 2) apply SSB if necessary
    # 3) mixer correct
    for awgName, data in awgData.items():
        for chanName, chanData in data.items():
            if chanData:
                # construct IQkey using existing convention
                IQkey = awgName + '-' + chanName[2:]
                chanObj = channelLib[IQkey]

                # apply channel delay
                PatternUtils.delay(chanData['linkList'], chanDelays[IQkey], chanObj.samplingRate)

                # For quadrature channels, apply SSB and mixer correction
                if isinstance(chanObj, Channels.PhysicalQuadratureChannel):

                    #At this point we finally have the timing of all the pulses so we can apply SSB
                    if hasattr(chanObj, 'SSBFreq') and abs(chanObj.SSBFreq) > 0:
                        PatternUtils.apply_SSB(chanData['linkList'], chanData['wfLib'], chanObj.SSBFreq, chanObj.samplingRate)

                    PatternUtils.correctMixer(chanData['wfLib'], chanObj.correctionT)

                #Remove unused waveforms
                compress_wfLib(chanData['linkList'], chanData['wfLib'])

    #Loop back through to fill empty channels and write to file
    fileList = []
    for awgName, data in awgData.items():
        #If all the channels are empty then do not bother writing the file
        if all([chan is None for chan in data.values()]):
            continue

        # convert to hardware formats
        # create the target folder if it does not exist
        targetFolder = os.path.split(os.path.normpath(os.path.join(config.AWGDir, fileName)))[0]
        if not os.path.exists(targetFolder):
            os.mkdir(targetFolder)
        fullFileName = os.path.normpath(os.path.join(config.AWGDir, fileName + '-' + awgName + suffix + instrumentLib[awgName].seqFileExt))
        write_sequence_file(instrumentLib[awgName], data, fullFileName)

        fileList.append(fullFileName)

    #Return the filenames we wrote
    return fileList
Example #4
0
def compile_to_hardware(seqs, fileName, suffix='', alignMode="right"):
    '''
    Compiles 'seqs' to a hardware description and saves it to 'fileName'. Other inputs:
        suffix : string to append to end of fileName (e.g. with fileNames = 'test' and suffix = 'foo' might save to test-APSfoo.h5)
        alignMode : 'left' or 'right' (default 'left')
    '''

    #Add the digitizer trigger to measurements
    PatternUtils.add_digitizer_trigger(seqs, channelLib['digitizerTrig'])

    # Add gating/blanking pulses
    PatternUtils.add_gate_pulses(seqs)

    # Add the slave trigger
    PatternUtils.add_slave_trigger(seqs, channelLib['slaveTrig'])

    # find channel set at top level to account for individual sequence channel variability
    channels = set([])
    for seq in seqs:
        channels |= find_unique_channels(seq)

    #Compile all the pulses/pulseblocks to linklists and waveform libraries
    linkLists, wfLib = compile_sequences(seqs, channels)

    if not validate_linklist_channels(linkLists.keys()):
        print "Compile to hardware failed"
        return

    # apply gating constraints
    for chan, LL in linkLists.items():
        if isinstance(chan, Channels.LogicalMarkerChannel):
            linkLists[chan] = PatternUtils.apply_gating_constraints(
                chan.physChan, LL)
    # map logical to physical channels
    awgData = map_logical_to_physical(linkLists, wfLib)
    # construct channel delay map
    chanDelays = channel_delay_map(awgData)

    # for each physical channel need to:
    # 1) delay
    # 2) apply SSB if necessary
    # 3) mixer correct
    for awgName, data in awgData.items():
        for chanName, chanData in data.items():
            if chanData:
                # construct IQkey using existing convention
                IQkey = awgName + '-' + chanName[2:]
                chanObj = channelLib[IQkey]

                # apply channel delay
                PatternUtils.delay(chanData['linkList'], chanDelays[IQkey],
                                   chanObj.samplingRate)

                # For quadrature channels, apply SSB and mixer correction
                if isinstance(chanObj, Channels.PhysicalQuadratureChannel):

                    #At this point we finally have the timing of all the pulses so we can apply SSB
                    if hasattr(chanObj,
                               'SSBFreq') and abs(chanObj.SSBFreq) > 0:
                        PatternUtils.apply_SSB(chanData['linkList'],
                                               chanData['wfLib'],
                                               chanObj.SSBFreq,
                                               chanObj.samplingRate)

                    PatternUtils.correctMixer(chanData['wfLib'],
                                              chanObj.correctionT)

                #Remove unused waveforms
                compress_wfLib(chanData['linkList'], chanData['wfLib'])

    #Loop back through to fill empty channels and write to file
    fileList = []
    for awgName, data in awgData.items():
        #If all the channels are empty then do not bother writing the file
        if all([chan is None for chan in data.values()]):
            continue

        # convert to hardware formats
        # create the target folder if it does not exist
        targetFolder = os.path.split(
            os.path.normpath(os.path.join(config.AWGDir, fileName)))[0]
        if not os.path.exists(targetFolder):
            os.mkdir(targetFolder)
        fullFileName = os.path.normpath(
            os.path.join(
                config.AWGDir, fileName + '-' + awgName + suffix +
                instrumentLib[awgName].seqFileExt))
        write_sequence_file(instrumentLib[awgName], data, fullFileName)

        fileList.append(fullFileName)

    #Return the filenames we wrote
    return fileList