This feature introduces an efficient method for changing waveform shapes during scan time. In GE terminology, this preallocates sequencer memory for multiple waveform shapes (states) under one instruction. Instead of rewriting the entire waveform in sequencer memory (like with ks_wave2hardware), you can adjust the shape by simply modifying the waveform pointer in the instruction.
In KS terms, this allows you to generate up to KS_WAVE_MAXNSTATES (currently 16) waveform shapes of equal duration for each KS_WAVE object. The primary motivation for this feature is that we often know the different waveform shapes in advance of the pulse sequence execution. This allows us to account for gradient heating and SAR (Specific Absorption Rate) calculations efficiently.
In the past, you would have relied on wave2hardware(), which is not optimal for pre-scan checks and may result in faulty waveforms if your code contains bugs. The introduction of wave states ensures more predictable behaviour and greater efficiency, as waveforms are transferred to sequencer memory only once before scanning begins.
When you generate (pulsegen, pg) any KS_WAVE, it automatically adds the waveform to state0. This waveform must have the highest amplitude among all states because all subsequent states for that instruction use the same amplitude scaling factor (ampscale). Thus, to ensure the correct amplitude (i.e., iamp * iwave), the scaling must occur within waveform memory (iwave), which must not exceed a value of 1. Although we plan to automate this process in the future, you will currently receive an error if you attempt to add a state with an amplitude greater than state0.
In this example, we generate a KS_WAVE that is a cosine function modulated by a sin function (a waveform starting and ending with zero amplitude). We will use the maximum number of states (KS_WAVE_MAXNSTATES) to represent different phase shifts of the cosine function. This wave will be placed on all three gradient boards at the same location, and we will add the wave states generated in eval(). Finally, we modify the wave state of the three KS_WAVE instances based on the shot number.
First, declare KS_WAVEFORMS that will represent the states. Here, we group them with the KS_WAVE object in TRIG_WAVE:
The KS_WAVEFORMS used for states need to be exported with the KS_WAVE object. The TRIG_WAVE struct we just defined neatly packages the waveform states with the wave.
Next, generate the waveforms. We advise caution when using mathematical functions on the target, but as we are on the host, using cosf and sinf is acceptable:
Now, we place the wave on all three gradient boards and add all states:
Now the fun part, switching waveforms during scan time:
As these modifications are known on the host, they can be recorded and viewed in the html plotting. Checkout the configurations slider.
In cases where you require hundreds or even thousands of unique waveforms, you might run out of sequencer memory or hit the KS_WAVE_MAXNSTATES limit (currently a conservative 16). In such situations, you will need to use ks_scan_wave2hardware.
Here’s the function signature:
Unlike ks_pg_addwaveformstate (used above), this function is a scan-time version and doesn’t account for gradient and SAR heating. Be cautious when using it and ensure your sequence is in a representative state for the grad_heat_play function. It is also not possible to use ks_scan_wave2hardware on a KS_WAVE with only one state. This is because the pulse sequence code and sequencer are asynchronous, you could therefore modify the waveform shape of the previous TR while it is actually playing. Fortunately, each KS_WAVE object has a .current_state member which is an array of length ninstances (how many times the wave was placed) that keeps track of which states are currently active on the sequencer. If you try call ks_scan_wave2hardware on an active state the scan will continue without doing anything, so you will need to check the logfile ks_error.txt to see if you have actually been successful (empty is good).
Let’s modify the trig wave to decay over many shots using wave2hardware:
As these changes are not recorded for html plots. To debug you will need to use the GE tool called 'plotter'.