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
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
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
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