def apply_min_pulse_constraints(miniLL, wfLib): ''' Helper function to deal with LL elements less than minimum LL entry count by trying to concatenate them into neighbouring entries ''' newMiniLL = [] entryct = 0 while entryct < len(miniLL): curEntry = miniLL[entryct] if not isinstance(curEntry, Compiler.Waveform) or curEntry.length >= MIN_ENTRY_LENGTH: newMiniLL.append(curEntry) entryct += 1 continue if entryct == len(miniLL) - 1: # we've run out of entries to append to. drop it? warn("Unable to handle too short LL element, dropping.") break nextEntry = miniLL[entryct+1] previousEntry = miniLL[entryct-1] if entryct > 0 else None # For short TA pairs we see if we can add them to the next waveform if curEntry.isZero and not nextEntry.isZero: # Concatenate the waveforms paddedWF = np.hstack((np.zeros(curEntry.length, dtype=np.complex), wfLib[wf_sig(nextEntry)])) # Generate a new key nextEntry.key = hash_pulse(paddedWF) nextEntry.length = paddedWF.size wfLib[wf_sig(nextEntry)] = paddedWF newMiniLL.append(nextEntry) entryct += 2 # For short pulses we see if we can steal some padding from the previous or next entry elif isinstance(previousEntry, Compiler.Waveform) and previousEntry.isZero and previousEntry.length > 2*MIN_ENTRY_LENGTH: padLength = MIN_ENTRY_LENGTH - curEntry.length newMiniLL[-1].length -= padLength # Concatenate the waveforms if curEntry.isZero: curEntry.length += padLength entryct += 1 curEntry.isTimeAmp = True continue elif curEntry.isTimeAmp: # non-zero paddedWF = np.hstack((np.zeros(padLength, dtype=np.complex), wfLib[wf_sig(curEntry)]*np.ones(curEntry.length))) curEntry.isTimeAmp = False else: paddedWF = np.hstack((np.zeros(padLength, dtype=np.complex), wfLib[wf_sig(curEntry)])) # Generate a new key curEntry.key = hash_pulse(paddedWF) curEntry.length = paddedWF.size wfLib[wf_sig(curEntry)] = paddedWF newMiniLL.append(curEntry) entryct += 1 elif isinstance(nextEntry, Compiler.Waveform) and nextEntry.isZero and nextEntry.length > 2*MIN_ENTRY_LENGTH: padLength = MIN_ENTRY_LENGTH - curEntry.length nextEntry.length -= padLength # Concatenate the waveforms if curEntry.isZero: curEntry.length += padLength entryct += 1 curEntry.isTimeAmp = True continue elif curEntry.isTimeAmp: #non-zero paddedWF = np.hstack((wfLib[curEntry.key]*np.ones(curEntry.length), np.zeros(padLength, dtype=np.complex))) curEntry.isTimeAmp = False else: paddedWF = np.hstack((wfLib[curEntry.key], np.zeros(padLength, dtype=np.complex))) # Generate a new key curEntry.key = hash_pulse(paddedWF) curEntry.length = paddedWF.size wfLib[wf_sig(curEntry)] = paddedWF newMiniLL.append(curEntry) entryct += 1 else: warn("Unable to handle too short LL element, dropping.") entryct += 1 # Update the miniLL return newMiniLL
def apply_min_pulse_constraints(miniLL, wfLib): ''' Helper function to deal with LL elements less than minimum LL entry count by trying to concatenate them into neighbouring entries ''' newMiniLL = [] entryct = 0 while entryct < len(miniLL): curEntry = miniLL[entryct] if not isinstance(curEntry, APSWaveform) or \ curEntry.length >= MIN_ENTRY_LENGTH: newMiniLL.append(curEntry) entryct += 1 continue if entryct == len(miniLL) - 1: # we've run out of entries to append to. drop it? warn("Unable to handle too short LL element, dropping.") break nextEntry = miniLL[entryct + 1] previousEntry = miniLL[entryct - 1] if entryct > 0 else None # For short TA pairs we see if we can add them to the next waveform if curEntry.isZero and not nextEntry.isZero: # Concatenate the waveforms paddedWF = np.hstack( (np.zeros(curEntry.length, dtype=np.complex), wfLib[wf_sig(nextEntry)])) # Generate a new key nextEntry.key = hash_pulse(paddedWF) nextEntry.length = paddedWF.size wfLib[wf_sig(nextEntry)] = paddedWF newMiniLL.append(nextEntry) entryct += 2 # For short pulses we see if we can steal some padding from the previous or next entry elif isinstance(previousEntry, APSWaveform) and \ previousEntry.isZero and \ previousEntry.length > 2 * MIN_ENTRY_LENGTH: padLength = MIN_ENTRY_LENGTH - curEntry.length newMiniLL[-1].length -= padLength # Concatenate the waveforms if curEntry.isZero: curEntry.length += padLength entryct += 1 curEntry.isTimeAmp = True continue elif curEntry.isTimeAmp: # non-zero paddedWF = np.hstack( (np.zeros(padLength, dtype=np.complex), wfLib[wf_sig(curEntry)] * np.ones(curEntry.length))) curEntry.isTimeAmp = False else: paddedWF = np.hstack( (np.zeros(padLength, dtype=np.complex), wfLib[wf_sig(curEntry)])) # Generate a new key curEntry.key = hash_pulse(paddedWF) curEntry.length = paddedWF.size wfLib[wf_sig(curEntry)] = paddedWF newMiniLL.append(curEntry) entryct += 1 elif isinstance(nextEntry, APSWaveform) and \ nextEntry.isZero and \ nextEntry.length > 2 * MIN_ENTRY_LENGTH: padLength = MIN_ENTRY_LENGTH - curEntry.length nextEntry.length -= padLength # Concatenate the waveforms if curEntry.isZero: curEntry.length += padLength entryct += 1 curEntry.isTimeAmp = True continue elif curEntry.isTimeAmp: #non-zero paddedWF = np.hstack( (wfLib[curEntry.key] * np.ones(curEntry.length), np.zeros(padLength, dtype=np.complex))) curEntry.isTimeAmp = False else: paddedWF = np.hstack( (wfLib[curEntry.key], np.zeros(padLength, dtype=np.complex))) # Generate a new key curEntry.key = hash_pulse(paddedWF) curEntry.length = paddedWF.size wfLib[wf_sig(curEntry)] = paddedWF newMiniLL.append(curEntry) entryct += 1 else: warn("Unable to handle too short LL element, dropping.") entryct += 1 # Update the miniLL return newMiniLL
wfLib[wf_sig(wf)] = shape return wfLib def wf_sig(wf): ''' Compute a signature of a Compiler.Waveform that identifies the relevant properties for two Waveforms to be considered "equal" in the waveform library. For example, we ignore length of TA waveforms. ''' if wf.isZero or (wf.isTimeAmp and wf.frequency == 0): # 2nd condition necessary until we support RT SSB return (wf.amp, wf.phase) else: return (wf.key, wf.amp, round(wf.phase * 2**13), wf.length, wf.frequency) TAZShape = np.zeros(1, dtype=np.complex) TAZKey = hash_pulse(TAZShape) def padding_entry(length): entry = Compiler.Waveform() entry.length = length entry.key = TAZKey entry.isTimeAmp = True return entry def apply_min_pulse_constraints(miniLL, wfLib): ''' Helper function to deal with LL elements less than minimum LL entry count by trying to concatenate them into neighbouring entries ''' newMiniLL = [] entryct = 0
def wf_sig(wf): ''' Compute a signature of a Compiler.Waveform that identifies the relevant properties for two Waveforms to be considered "equal" in the waveform library. For example, we ignore length of TA waveforms. ''' # 2nd condition necessary until we support RT SSB if wf.isZero or (wf.isTimeAmp and wf.frequency == 0): return (wf.amp, wf.phase) else: return (wf.key, wf.amp, round(wf.phase * 2**13), wf.length, wf.frequency) TAZShape = np.zeros(1, dtype=np.complex) TAZKey = hash_pulse(TAZShape) def padding_entry(length): entry = Compiler.Waveform() entry.length = length / SAMPLING_RATE entry.key = TAZKey entry.isTimeAmp = True return APSWaveform(entry) def apply_min_pulse_constraints(miniLL, wfLib): ''' Helper function to deal with LL elements less than minimum LL entry count by trying to concatenate them into neighbouring entries '''