Data Structures | |
struct | KSFSE_SEQUENCE |
Macros | |
#define | KSFSE_MINHNOVER 6 |
#define | KSFSE_MIN_SSI_TIME 200 |
#define | KSFSE_MAXTHICKFACT 3.0 |
#define | KSFSE_INIT_SEQUENCE {KS_INIT_SEQ_CONTROL, KS_INIT_READTRAP, KS_INIT_TRAP, KS_INIT_PHASER, KS_INIT_PHASER, KS_INIT_TRAP, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF}; |
#define | KSFSE_PHASEENCODING_MEMORYPOOL_SIZE 25000 |
Enumerations | |
enum | { KSFSE_RECOVERY_OFF, KSFSE_RECOVERY_T1WOPT, KSFSE_RECOVERY_FAST } |
Variables | |
KS_SEQ_COLLECTION | seqcollection |
float | ksfse_excthickness = 0 |
float | ksfse_gscalerfexc = 0.9 |
float | ksfse_flipexc = 90.0 with {0.0, 180.0, 90.0, VIS, "Excitation flip angle [deg]",} |
float | ksfse_spoilerarea = 2000.0 with {0.0, 20000.0, 5000.0, VIS, "ksfse spoiler gradient area",} |
float | rf_stretch_rfexc = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch RF excitation pulse if > 1.0",} |
int | ksfse_inflowsuppression = 0 with {0, 1, 0, VIS, "In-flow Suppression [0:OFF, 1:ON]",} |
float | ksfse_inflowsuppression_mm = 0.0 with {0.0, 100.0, 0.0, VIS, "In-flow suppression [mm]",} |
int | ksfse_vfa = 1 with {0, 1, 1, VIS, "Variable flip angles [0:OFF, 1:ON]",} |
float | ksfse_crusher_dephasing = 6.0 with {0.0, 100.0, 6.0, VIS, "scaling of crusher gradient area [cycles]",} |
float | ksfse_gscalerfref = 0.9 |
int | ksfse_slicecheck = 0 with {0, 1, 0, VIS, "move readout to z axis for slice thickness test",} |
float | rf_stretch_rfref = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch RF refocusing pulses if > 1.0",} |
float | rf_stretch_all = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch all RF pulses if > 1.0",} |
int | ksfse_recovery = KSFSE_RECOVERY_OFF with {KSFSE_RECOVERY_OFF, KSFSE_RECOVERY_FAST, KSFSE_RECOVERY_OFF, VIS, "Recovery. 0:off 1:T1wopt 2:T2fast", } |
float | rf_stretch_rfrecovery = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch RF recovery pulses if > 1.0",} |
int | ksfse_kxnover_min = KSFSE_MINHNOVER with {KSFSE_MINHNOVER, 512, KSFSE_MINHNOVER, VIS, "Min mum kx overscans for minTE",} |
int | ksfse_kxnover = 32 with {KSFSE_MINHNOVER, 512, 32, VIS, "Num kx overscans for minTE",} |
int | ksfse_rampsampling = 0 with {0, 1, 0, VIS, "Rampsampling [0:OFF 1:ON]",} |
int | ksfse_extragap = 0 with {0, 100ms, 0, VIS, "extra gap between readout [us]",} |
int | ksfse_etlte = 1 with {0, 1, 1, VIS, "ETL controls TE",} |
float | ksfse_xcrusherarea = 100.0 with {0.0, 1000.0, 100.0, VIS, "x crusher area for readout",} |
int | ksfse_esp = 0 with {0, 1000000, 0, VIS, "View-only: Echo spacing in [us]",} |
int | ksfse_noph = 0 with {0, 1, 0, VIS, "Turn OFF phase encoding [0:Disabled 1:Enabled]",} |
int | ksfse_minacslines = 12 with {0, 512, 12, VIS, "Minimum ACS lines for ARC",} |
int | ksfse_minzacslines = 12 with {0, 512, 12, VIS, "Minimum z ACS lines for ARC",} |
int | ksfse_pos_start = KS_RFSSP_PRETIME with {0, , KS_RFSSP_PRETIME, VIS, "us from start until the first waveform begins",} |
int | ksfse_ssi_time = KSFSE_MIN_SSI_TIME with {50, , KSFSE_MIN_SSI_TIME, VIS, "time from eos to ssi in intern trig",} |
int | ksfse_dda = 2 with {0, 200, 2, VIS, "Number of dummy scans for steady state",} |
int | ksfse_debug = 1 with {0, 100, 1, VIS, "Write out e.g. plot files (unless scan on HW)",} |
int | ksfse_imsize = KS_IMSIZE_NATIVE with {KS_IMSIZE_NATIVE, KS_IMSIZE_MIN256, KS_IMSIZE_MIN256, VIS, "img. upsamp. [0:native 1:pow2 2:min256]"} |
int | ksfse_abort_on_kserror = FALSE with {0, 1, 0, VIS, "Hard program abort on ks_error [0:OFF 1:ON]",} |
int | ksfse_mintr = 0 with {0, 20s, 0, VIS, "Min TR (ms) [0: Disabled]",} |
int | ksfse_maxtr = 0 with {0, 40s, 0, VIS, "Max TR (ms) [0: Disabled]",} |
KSFSE_SEQUENCE | ksfse = KSFSE_INIT_SEQUENCE |
KSSCAN_LOOP_CONTROL | ksfse_loopctrl = KSSCAN_INIT_LOOP_CONTROL |
KSINV_MODULE | ksfse_inv = KSINV_INIT_MODULE |
KSINV_LOOP_CONTROL | ksfse_inv_loopctrl = KSINV_INIT_LOOP_CONTROL |
KS_PHASEENCODING_COORD | ksfse_phaseencoding_memorypool [KSFSE_PHASEENCODING_MEMORYPOOL_SIZE] = {KS_INIT_PHASEENCODING_COORD} |
KS_KSPACE_ACQ | kacq = KS_INIT_KSPACE_ACQ |
int | sequence_iopts [] |
MR-contrasts supported
Features
#define KSFSE_MINHNOVER 6 |
#define KSFSE_MIN_SSI_TIME 200 |
#define KSFSE_MAXTHICKFACT 3.0 |
#define KSFSE_INIT_SEQUENCE {KS_INIT_SEQ_CONTROL, KS_INIT_READTRAP, KS_INIT_TRAP, KS_INIT_PHASER, KS_INIT_PHASER, KS_INIT_TRAP, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF, KS_INIT_SELRF}; |
#define KSFSE_PHASEENCODING_MEMORYPOOL_SIZE 25000 |
num elements allocated for unique phase encodes
anonymous enum |
STATUS cvinit | ( | void | ) |
STATUS cveval | ( | void | ) |
STATUS my_cveval | ( | void | ) |
STATUS cvcheck | ( | void | ) |
STATUS predownload | ( | void | ) |
STATUS pulsegen | ( | void | ) |
STATUS mps2 | ( | void | ) |
STATUS aps2 | ( | void | ) |
STATUS scan | ( | void | ) |
abstract | ( | "FSE " | [KSFoundation] | ) |
psdname | ( | "ksfse" | ) |
void ksfse_eval_TEmenu | ( | int | esp, |
int | maxte, | ||
int | etl, | ||
double | optechono | ||
) |
optechono
is the echo index in range [0, ETL-1] that is in the center of the FSE train. If the TE corresponding to this index is chosen, optimal image quality is achieved with minimal FSE ghosting.
For ETLs > 6, this value is given first in the TE menu, meaning that if the user chooses the first field in the TE menu this will have the same effect as setting "ETL controls TE", and the remaining TE fields in the menu are the ones straddling the optimal TE.
For ETLs in range [2,6], MinFull is the first, followed by the optimal TE.
For ETL = 1, which corresponds to a conventional Spin-Echo, the user can choose only between MinTE (partial kx Fourier) and MinFullTE. Manual type-in is not allowed for ETL = 1.
[in] | esp | Echo Spacing in [us] |
[in] | maxte | Maximum TE in [us] |
[in] | etl | Echo Train Length |
[in] | optechono | Optimal echo index in range [0, ETL-1] |
STATUS ksfse_calc_echo | ( | double * | bestecho, |
double * | optecho, | ||
KS_PHASER * | pe, | ||
int | TE, | ||
int | etl, | ||
int | esp | ||
) |
STATUS ksfse_pg | ( | int | start_time | ) |
This is the main pulse sequence in ksfse.e using the sequence objects in KSFSE_SEQUENCE with the sequence module name "ksfsemain" (= ksfse.seqctrl.description)
STATUS | SUCCESS or FAILURE |
KS_CORESLICETIME ksfse_scan_coreslice | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
ksfse
sequence module in real time during scanningThis function updates the waveforms, and plays out, the ksfse sequence module. The low-level function call startseq()
, which actually starts the realtime sequence playout is called from within ks_scan_playsequence(), which in addition also returns the time to play out that sequence module (see time += ...).
After each call to ks_scan_playsequence(), ks_plot_slicetime() is called to add slice-timing information for later HTML plotting of the sequence. As scanning is performed in real-time and may fail if interrupted, ks_plot_slicetime() will return quietly if it detects both IPG (TGT) and PSD_HW (on the MR scanner).
Common for all coreslice functions for any psd is the return of a KS_CORESLICETIME struct, which contains the time take to play out one slice (.duration
) and the time from the start of the coreslice to the (.referencetimepoint
) used to define the excitation location of the coreslice. Here this is simply ksfse.seqctrl.momentstart as there are no other embedded sequence modules played out inside this function. If any sequence module is added inside this function before/after ks_scan_playsequence(&ksfse.seqctrl), the KS_CORESLICETIME struct needs be updated accordingly.
[in] | slice_pos | Position of the slice to be played out (one element in the global ks_scan_info[] array) |
dynamic | Pointer to KS_DYNAMIC_STATE struct, which has elements being automatically updated by the scan looping functions |
KS_CORESLICETIME ksfse_scan_coreslicegroup | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
With the use of generic scan loops (ksscan.cc:ksscan_scanloop()) performing the actual scan in ksfse_scan_scanloop(), using
ksfse_loopctrl
)dynamic
)coreslice
)one needs to create the psd-specific function in this file to play out one slice of one or more sequence modules This is that function, which must take (const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic) as the two input arguments, and return a KS_CORESLICETIME struct. This to match the various ksscan_****loop() functions in ksscan.cc, used to run the scan.
Unlike ksfse_scan_coreslice(), which only plays the main sequence (ksfse
), this function also plays other sequence modules. For now, this is only the kssat
sequence module, which is played out before the main sequence, if active.
[in] | slice_pos | Pointer to the SCAN_INFO struct corresponding to the current slice to be played out |
dynamic | Pointer to KS_DYNAMIC_STATE struct, which has elements being automatically updated by the scan looping functions |
KS_CORESLICETIME ksfse_scan_irslice | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
s64 ksfse_scan_scanloop | ( | ) |
This function is called from ksfse.e:scan(), which corresponds to the actual SCAN button press in the UI.
If inversion is used, the function calls ksinv_scan_scanloop(), where ksfse_inv_loopctrl
is used to control the the scan looping. For non-inversion scans, ksscan_scanloop() is called, where ksfse_loopctrl
is used to control the scan looping in both cases.
STATUS ksfse_scan_seqstate | ( | SCAN_INFO | slice_pos, |
KS_PHASEENCODING_SHOTCOORDS | shot_coords | ||
) |
This function sets the current state of all ksfse sequence objects being part of KSFSE_SEQUENCE, incl. gradient amplitude changes, RF freq/phases and receive freq/phase based on current slice position and phase encoding indices for a given sequence playout in ksfse_scan_coreslice() during scan.
[in] | slice_pos | Position of the slice to be played out (one element in the ks_scan_info[] array) |
[in] | shot_coords | KS_PHASEENCODING_SHOTCOORDS with list of phase encoding indices for current shot |
STATUS | SUCCESS or FAILURE |
const KSSCAN_LOOP_CONTROL * ksfse_get_loop_ctrl | ( | ) |
To save if statments in the code, this function returns the loop control in use depending on inversion is on or off.
STATUS | SUCCESS or FAILURE |
void ksfse_init_imagingoptions | ( | void | ) |
STATUS ksfse_init_UI | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_UI | ( | ) |
STATUS | SUCCESS or FAILURE |
int ksfse_eval_esp | ( | int * | min90_180, |
int * | min180_echo, | ||
int | slicecheck, | ||
KSFSE_SEQUENCE * | seq | ||
) |
[out] | min90_180 | Pointer to the time between moment start of the excitation pulse to the center of the refocusing pulse in [us] |
[out] | min180_echo | Pointer to the time between center of the refocusing pulse to the center of the first echo in [us] |
[in] | slicecheck | 0: Normal mode 1: Slice check mode, where the readout is moved to the slice axis |
[in] | seq | Pointer to KSFSE_SEQUENCE |
echospacing | Echo Spacing in [us] |
int ksfse_eval_optimalkxnover | ( | KSFSE_SEQUENCE * | seq | ) |
This function plays by the following rules:
kxnover
until an increase in TE results, while staying within above limits[in] | seq | Pointer to the KSFSE_SEQUENCE struct holding all sequence objects |
kxnover | Optimal number of k-space points beyond half k-space for partial kx Fourier scans. |
float ksfse_eval_rfstretchfactor | ( | float | patientweight, |
float | flipangle, | ||
int | tailoredrf_flag | ||
) |
This function returns a suitable scale factor for the duration of the RF refocusing pulse to keep the SAR within limits for different patient weights and flip angles.
The function is called from ksfse_eval_setuprfpulses_2D().
[in] | patientweight | Patien weight [kg] |
[in] | flipangle | Flip angle [degrees] |
[in] | tailoredrf_flag | Tailored RF flag |
float | RF stretch factor |
STATUS ksfse_eval_setuprfpulses_2D | ( | KSFSE_SEQUENCE * | seq, |
float | crusher_dephasing | ||
) |
This function attempts to mimick the RF scaling and flip angle varation performed in the product fsemaster.e psd, with and without the tailored RF (optlrdrf) option. It is called from ksfse_eval_setupobjects() to set up the RF pulses.
[out] | seq | Pointer to the KSFSE_SEQUENCE struct holding all sequence objects |
[in] | crusher_dephasing | The amount of crusher_dephasing in [cycles] for refocusing pulses |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_setuprfpulses_3D | ( | KSFSE_SEQUENCE * | seq | ) |
[in] | seq | Pointer to the KSFSE_SEQUENCE struct holding all sequence objects |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_setuprfpulses_recovery | ( | KSFSE_SEQUENCE * | seq | ) |
Using ksfse.selrfexc
and ksfse.selrfref
as templates, this function sets up the RF pulses for fast recovery after the FSE train, which is controlled by the CV ksfse_recovery
. The .selrfrecover
pulse is a mirrored version of .selrfexc
.
[in,out] | seq | Pointer to KSFSE_SEQUENCE |
STATUS | SUCCESS or FAILURE |
int ksfse_eval_ssitime | ( | ) |
int | SSI time in [us] |
STATUS ksfse_eval_setupobjects | ( | ) |
This function will set up all objects for the main sequence module (ksfse) via a mix of UI CVs and other CVs. This effectively sets the shape (amp, ramptimes & duration) of each trapezoid and waveform in the sequence for later placement in ksfse_pg().
For the RF pulse evaluation, this function calls either ksfse_eval_setuprfpulses_3D() or ksfse_eval_setuprfpulses_2D() depending on the 2D/3D mode.
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_TErange | ( | ) |
Based on the duration of the sequence objects involved, this function first calculates the minimum echo spacing in the FSE train (ksfse_esp
). Then, if the SSFSE flag is set (opssfse), the ETL (opetl) is forced to be equal to the number of phase encoding lines acquired (see ks_eval_phaseviewtable()), otherwise the chosen ETL is used to calculate how many TRs (or shots) is necessary to fill k-space (ksfse.phaseenc_plan.num_shots
). This value is used later in scan.
Next, if the user has selected that the "ETL should set TE" (ksfse_etlte = TRUE), the echo time is forced to be equal to the most optimal one in the center of the echo train (optecho). The benefits of setting ksfse_etlte are
bestecho
, which is the echo index in the FSE train closest to the desired TE. When bestecho
ends up being equal to optecho
(as enforced by ksfse_etlte), the image quality improves, however this it not possible, especially for long ETLs with a normal TE of 80-100 ms.Last, this function calls ksfse_eval_TEmenu() to change the TE menu so the optimal TE is always at the top, followed by other TEs one or more echo spacings from the optimal TE.
N.B.: ksfse_esp
is the shortest time allowed between the RF excitation and the first echo, which is also the same time needed between two consecutive echoes in the FSE train. ksfse_esp
is used in ksfse_pg(). If the pulse sequence design changes in ksfse_pg() such that more/less time is needed to the first echo, or between consecutive echoes, ksfse_esp must here be updated to avoid gradient overlaps.
STATUS | SUCCESS or FAILURE |
void ksfse_set_kspace_design | ( | KS_KSPACE_DESIGN * | kdesign | ) |
This function sets up the k-space design for the FSE sequence based on UI CVs, including properties like FOV size, matrix size, parallel imaging factors, receiver bandwidth, and partial Fourier factors.
For acoustic noise reduction scans (opsilent), ramp sampling is enabled to reduce the echo spacing.
It is used by ksfse_set_loop_control_design() and ksfse_eval_sat().
Note that all design structs are short-lived and are set up as a receipe for other structures to be used in pulsegen and scan
[out] | kdesign | KS_KSPACE_DESIGN |
void ksfse_set_slicetiming_design | ( | KS_SLICETIMING_DESIGN * | slicetiming_design | ) |
This function is called from ksfse_eval_loops()->ksfse_set_loop_control_design() to produce a KSSCAN_LOOP_CONTROL_DESIGN, which contains this KS_SLICETIMING_DESIGN struct steering how the final KS_SLICETIMING struct will be set up by ksscan_slicetiming_eval_design(), taking a KS_SLICETIMING_DESIGN as input
Note that all design structs are short-lived and are set up as a receipe for other structures to be used in pulsegen and scan
[out] | slicetiming_design | KS_SLICETIMING_DESIGN to be created |
STATUS ksfse_set_loop_control_design | ( | KSSCAN_LOOP_CONTROL_DESIGN * | loop_design | ) |
This function creates a KSSCAN_LOOP_CONTROL_DESIGN struct, with fields .dda: Number of dummy scans .naverages: Number of averages .nvols: Number of volumes .phaseenc_design: KS_PHASEENCODING_DESIGN (containing coordinates and other phase encoding info) .slicetiming_design: KS_SLICETIMING_DESIGN (containing slice timing info)
This function is called from ksfse_eval_loops() to produce a KSSCAN_LOOP_CONTROL_DESIGN, which is then used in part to create a KSSCAN_LOOP_CONTROL struct used in scan
Note that all design structs are short-lived and are set up as a receipe for other structures to be used in pulsegen and scan
[out] | loop_design | KSSCAN_LOOP_CONTROL_DESIGN to be created |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_set_inversion_loop_control_design | ( | KSINV_LOOP_CONTROL_DESIGN * | invloopctrl_design | ) |
This function creates a KSSCAN_LOOP_CONTROL_DESIGN struct, which contains the same KSSCAN_LOOP_CONTROL_DESIGN struct as ksfse_set_loop_control_design() in its .loopctrl_design
field. This by calling ksfse_set_loop_control_design(&invloopctrl_design->loopctrl_design) here.
In addition, inversion-recovery-related design info is set up in this function, including the type of inversion mode depending on the UI CVs opirprep, opt1flair, opt2flair.
The desired inversion timing is controlled by either the inversion time (TI) xor the T1 value of the tissue
Note that all design structs are short-lived and are set up as a receipe for other structures to be used in pulsegen and scan
[out] | invloopctrl_design | KSINV_LOOP_CONTROL_DESIGN to be created |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_inversion | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
Note that all design structs are short-lived and are set up as a receipe for other structures to be used in pulsegen and scan. Here, the KSINV_DESIGN has local scope and is setup and used only by this function. What remains is the KSINV_MODULE ksfse_inv module, declaread in .
The KS_SEQ_COLLECTION is passed as a pointer to the function, to let the KSINV_MODULE to be registered in the collection for RF scaling, and heating calculations.
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_sat | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
As there can only be one global graphical saturation module that interacts with the UI, this function uses the global kssat
struct (KSSAT_MODULE) in kssat.e, which is at the top of ksfse.e
seqcollection
is passed as a pointer to the function, to register the KSSAT_MODULE in the collection for later RF scaling, and heating calculations.
Both design structs have local scope, and via ksfse_set_slicetiming_design(), the slice location info is used to control the location of the sat bands in kssat_setup_from_UI()
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_gradheat_play | ( | const INT | max_encode_mode, |
int | nargs, | ||
void ** | args | ||
) |
This function
It should be noted that the content of this function is manual work and needs to be updated if the content of ksfse_pg() or used sequence modules are changed for the gradient heating to be accurate. So if, for example, major dynamic changes of gradient amplitudes or which sequence modules that are used, this function should be updated accordingly.
As ks_eval_getduration() and ks_eval_hwlimits() are common for all psds, this function has to have nargs and args as input arguments, but they are not used here. See ksfse_eval_loops() for more details.
[in] | max_encode_mode | The maximum encoding mode, which can be either AVERAGE_POWER or MAXIMUM_POWER. |
[in] | nargs | (not used) Number of extra input arguments (# elements of void pointer array **args) |
[in] | args | (not used) Void pointer array with nargs elements (may be NULL) |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_loops | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
This function performs the following tasks:
newtime
ksfse.seqctrl.duration
) if the newtime > time using ks_eval_seqctrl_setduration()loopctrl_design
(for main sequence), which is used together with the coreslice function (ksfse_scan_coreslicegroup())ksfse_loopctrl
in ksscan_loop_control_eval_design() to control the scan loop for the main sequenceinv_loopctrl_design
is used to create ksfse_inv_loopctrl
, which controls the scan loop instead of ksfse_loopctrl
when inversion is on.Note that all design structs are short-lived and are set up as a receipe for other structures to be used in pulsegen and scan. Here this applies to the local variables loopctrl_design
and inv_loopctrl_design
.
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_scantime | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
pitscan
is the UI variable for the scan clock shown in the top right corner on the MR scanner. The call to GEReq_eval_checkTR_SAR_calcs() also sets up the UI SAR annotation.
STATUS | SUCCESS or FAILURE |
STATUS ksfse_update_UI | ( | ) |
This function is called from cvcheck() to update the UI variables based largely on ksfse
and ksfse_loopctrl
after checks for some out-of-bounds values.
STATUS | SUCCESS or FAILURE |
STATUS ksfse_predownload_plot | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
If a file /usr/g/research/bin/ksdonotplot exists, this function will return SUCCESS without plotting. This is a system-wide way of quickly disabling plotting for all sequences.
Otherwise the function first prints out the textfile: <ks_psdname>_objects.txt, which contains the specs of most sequence components in the sequence.
The rest of the function is the plotting the main sequence diagram as HTML file, and lastly the sequence timing plot, showing slice location on the y-axis and time on the x-axis for all sequence modules at the same time.
The HTML plots will have a slider to show the dynamics of a psd. What is interesting to show dynamics for can vary between psds. In most cases only the shot index might be interesting, skipping non-relevant changes such as change in slice location. One can think of this as recording something in a video, where only the relevant parts are recorded.
"Recording" is first reset by ks_eval_seqcollection_resetninst(). The generic ksscan_plotloop_shots() is used to play a single slice for many shot indices.
Note that ksscan_plotloop_shots() internally copies the loop_control struct (arg 2) and overrides the number of slices in order to play a single slice.
Lastly, ks_plot_psd() is called to write out a JSON file, followed by a system call to the python script psdplot/psdplot.py to create the HTML plots. The HTML files can take 10-20 s to generate, so be patient.
For the slicetiming plot, the three functions ks_plot_slicetime_begin();ksfse_scan_scanloop();ks_plot_slicetime_end(); creates a corresponding JSON file, followed by a system call to the python script psdplot/psdplot_slicetime.py to create the HTML plot.
STATUS | SUCCESS or FAILURE |
STATUS ksfse_predownload_setrecon | ( | ) |
For most cases, the GEReq_predownload_*** functions in predownload() in ksfse.e set up the necessary rh*** variables for the reconstruction to work properly. However, if this sequence is customized, certain rh*** variables may need to be changed. Doing this here instead of in predownload() directly separates these changes from the standard behavior.
STATUS | SUCCESS or FAILURE |
void ksfse_scan_rf_off | ( | ) |
void ksfse_scan_rf_on | ( | ) |
STATUS ksfse_scan_init | ( | void | ) |
STATUS | SUCCESS or FAILURE |
void ksfse_scan_prescanloop | ( | int | nloops, |
int | dda | ||
) |
STATUS | SUCCESS or FAILURE |
KS_SEQ_COLLECTION seqcollection |
float ksfse_excthickness = 0 |
float ksfse_gscalerfexc = 0.9 |
float ksfse_flipexc = 90.0 with {0.0, 180.0, 90.0, VIS, "Excitation flip angle [deg]",} |
float ksfse_spoilerarea = 2000.0 with {0.0, 20000.0, 5000.0, VIS, "ksfse spoiler gradient area",} |
float rf_stretch_rfexc = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch RF excitation pulse if > 1.0",} |
int ksfse_inflowsuppression = 0 with {0, 1, 0, VIS, "In-flow Suppression [0:OFF, 1:ON]",} |
float ksfse_inflowsuppression_mm = 0.0 with {0.0, 100.0, 0.0, VIS, "In-flow suppression [mm]",} |
int ksfse_vfa = 1 with {0, 1, 1, VIS, "Variable flip angles [0:OFF, 1:ON]",} |
float ksfse_crusher_dephasing = 6.0 with {0.0, 100.0, 6.0, VIS, "scaling of crusher gradient area [cycles]",} |
float ksfse_gscalerfref = 0.9 |
int ksfse_slicecheck = 0 with {0, 1, 0, VIS, "move readout to z axis for slice thickness test",} |
float rf_stretch_rfref = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch RF refocusing pulses if > 1.0",} |
float rf_stretch_all = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch all RF pulses if > 1.0",} |
int ksfse_recovery = KSFSE_RECOVERY_OFF with {KSFSE_RECOVERY_OFF, KSFSE_RECOVERY_FAST, KSFSE_RECOVERY_OFF, VIS, "Recovery. 0:off 1:T1wopt 2:T2fast", } |
float rf_stretch_rfrecovery = 1.0 with {0.01, 100.0, 1.0, VIS, "Stretch RF recovery pulses if > 1.0",} |
int ksfse_kxnover_min = KSFSE_MINHNOVER with {KSFSE_MINHNOVER, 512, KSFSE_MINHNOVER, VIS, "Min mum kx overscans for minTE",} |
int ksfse_kxnover = 32 with {KSFSE_MINHNOVER, 512, 32, VIS, "Num kx overscans for minTE",} |
int ksfse_rampsampling = 0 with {0, 1, 0, VIS, "Rampsampling [0:OFF 1:ON]",} |
int ksfse_extragap = 0 with {0, 100ms, 0, VIS, "extra gap between readout [us]",} |
int ksfse_etlte = 1 with {0, 1, 1, VIS, "ETL controls TE",} |
float ksfse_xcrusherarea = 100.0 with {0.0, 1000.0, 100.0, VIS, "x crusher area for readout",} |
int ksfse_esp = 0 with {0, 1000000, 0, VIS, "View-only: Echo spacing in [us]",} |
int ksfse_noph = 0 with {0, 1, 0, VIS, "Turn OFF phase encoding [0:Disabled 1:Enabled]",} |
int ksfse_minacslines = 12 with {0, 512, 12, VIS, "Minimum ACS lines for ARC",} |
int ksfse_minzacslines = 12 with {0, 512, 12, VIS, "Minimum z ACS lines for ARC",} |
int ksfse_pos_start = KS_RFSSP_PRETIME with {0, , KS_RFSSP_PRETIME, VIS, "us from start until the first waveform begins",} |
int ksfse_ssi_time = KSFSE_MIN_SSI_TIME with {50, , KSFSE_MIN_SSI_TIME, VIS, "time from eos to ssi in intern trig",} |
int ksfse_dda = 2 with {0, 200, 2, VIS, "Number of dummy scans for steady state",} |
int ksfse_debug = 1 with {0, 100, 1, VIS, "Write out e.g. plot files (unless scan on HW)",} |
int ksfse_imsize = KS_IMSIZE_NATIVE with {KS_IMSIZE_NATIVE, KS_IMSIZE_MIN256, KS_IMSIZE_MIN256, VIS, "img. upsamp. [0:native 1:pow2 2:min256]"} |
int ksfse_abort_on_kserror = FALSE with {0, 1, 0, VIS, "Hard program abort on ks_error [0:OFF 1:ON]",} |
int ksfse_mintr = 0 with {0, 20s, 0, VIS, "Min TR (ms) [0: Disabled]",} |
int ksfse_maxtr = 0 with {0, 40s, 0, VIS, "Max TR (ms) [0: Disabled]",} |
KSFSE_SEQUENCE ksfse = KSFSE_INIT_SEQUENCE |
Main FSE sequence
KSSCAN_LOOP_CONTROL ksfse_loopctrl = KSSCAN_INIT_LOOP_CONTROL |
Scan loop control for the ksfse
sequence (without inversion)
KSINV_MODULE ksfse_inv = KSINV_INIT_MODULE |
Inversion module
KSINV_LOOP_CONTROL ksfse_inv_loopctrl = KSINV_INIT_LOOP_CONTROL |
KS_PHASEENCODING_COORD ksfse_phaseencoding_memorypool[KSFSE_PHASEENCODING_MEMORYPOOL_SIZE] = {KS_INIT_PHASEENCODING_COORD} |
KS_KSPACE_ACQ kacq = KS_INIT_KSPACE_ACQ |
int sequence_iopts[] |