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, KS_INIT_PHASEENCODING_PLAN}; |
Enumerations | |
enum | { KSFSE_RECOVERY_OFF, KSFSE_RECOVERY_T1WOPT, KSFSE_RECOVERY_FAST } |
Functions | |
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) |
STATUS | ksfse_calc_echo (double *bestecho, double *optecho, KS_PHASER *pe, int TE, int etl, int esp) |
STATUS | ksfse_pg (int start_time) |
int | ksfse_scan_coreslice (const SCAN_INFO *slice_pos, int dabslice, int shot, int exc) |
int | ksfse_scan_coreslice_nargs (const SCAN_INFO *slice_pos, int dabslice, int nargs, void **args) |
int | ksfse_scan_sliceloop (int slperpass, int passindx, int shot, int exc) |
int | ksfse_scan_sliceloop_nargs (int slperpass, int nargs, void **args) |
float | ksfse_scan_acqloop (int passindx) |
float | ksfse_scan_scanloop () |
STATUS | ksfse_scan_seqstate (SCAN_INFO slice_info, int shot) |
void | ksfse_init_imagingoptions (void) |
STATUS | ksfse_init_UI (void) |
STATUS | ksfse_eval_UI () |
int | ksfse_eval_esp (int *min90_180, int *min180_echo, int slicecheck, KSFSE_SEQUENCE *seq) |
int | ksfse_eval_optimalkxnover (KSFSE_SEQUENCE *seq) |
float | ksfse_eval_rfstretchfactor (float patientweight, float flipangle, int tailoredrf_flag) |
STATUS | ksfse_eval_setuprfpulses_2D (KSFSE_SEQUENCE *seq) |
STATUS | ksfse_eval_setuprfpulses_3D (KSFSE_SEQUENCE *seq) |
STATUS | ksfse_eval_setuprfpulses_recovery (KSFSE_SEQUENCE *seq) |
int | ksfse_eval_ssitime () |
STATUS | ksfse_eval_setupobjects () |
STATUS | ksfse_eval_TErange () |
STATUS | ksfse_eval_inversion (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksfse_eval_tr (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksfse_eval_scantime () |
STATUS | ksfse_check () |
STATUS | ksfse_predownload_plot (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksfse_predownload_setrecon () |
STATUS | ksfse_etlphaseamps (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, KS_PHASER *phaser, KS_PHASER *zphaser, int shot) |
void | ksfse_spoilamp (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, KS_TRAP *spoiler, int res, int shot) |
void | ksfse_scan_rf_off () |
void | ksfse_scan_rf_on () |
STATUS | ksfse_scan_init (void) |
STATUS | ksfse_scan_prescanloop (int nloops, int dda) |
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_crusherscale = 0.5 with {0.0, 20.0, 0.5, VIS, "scaling of crusher gradient area",} |
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 |
int | sequence_iopts [] |
int | volindx |
int | passindx |
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, KS_INIT_PHASEENCODING_PLAN}; |
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.
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 |
int ksfse_scan_coreslice | ( | const SCAN_INFO * | slice_pos, |
int | dabslice, | ||
int | shot, | ||
int | exc | ||
) |
On TGT on the MR system (PSD_HW), this function sets up (ksfse_scan_seqstate()) and plays out the core ksfse sequence with optional sequence modules also called in this function. 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 += ...).
On HOST (in ksfse_eval_tr()) we call ksfse_scan_sliceloop_nargs(), which in turn calls this function that returns the total time in [us] taken to play out this core slice. These times are increasing in each parent function until ultimately ksfse_scan_scantime(), which returns the total time of the entire scan.
After each call to ks_scan_playsequence(), ks_plot_slicetime() is called to add slice-timing information on file for later PNG/PDF-generation 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). See predownload() for the PNG/PDF generation.
[in] | slice_pos | Position of the slice to be played out (one element in the global ks_scan_info[] array) |
[in] | dabslice | 0-based slice index for data storage |
[in] | shot | shot index (over ky and kz) |
[in] | exc | Excitation index in range [0, NEX-1] , where NEX = number of excitations (opnex) |
coreslicetime | Time taken in [us] to play out one slice with potentially other sequence modules |
int ksfse_scan_coreslice_nargs | ( | const SCAN_INFO * | slice_pos, |
int | dabslice, | ||
int | nargs, | ||
void ** | args | ||
) |
KSInversion.e has functions (ksinv_eval_multislice(), ksinv_eval_checkTR_SAR() and ksinv_scan_sliceloop()) that expect a standardized function pointer to the coreslice function of a main sequence. When inversion mode is enabled for the sequence, ksinv_scan_sliceloop() is used instead of ksfse_scan_sliceloop() in ksfse_scan_acqloop(), and the generic ksinv_scan_sliceloop() function need a handle to the coreslice function of the main sequence.
In order for these ksinv_***
functions to work for any pulse sequence they need a standardized function pointer with a fixed set of input arguments. As different pulse sequences may need different number of input arguments (with different meaning) this ksfse_scan_coreslice_nargs() wrapper function provides the argument translation for ksfse_scan_coreslice().
The function pointer must have SCAN_INFO and slice storage index (dabslice) as the first two input args, while remaining input arguments (to ksfse_scan_coreslice()) are stored in the generic void pointer array with nargs
elements, which is then unpacked before calling ksfse_scan_coreslice().
[in] | slice_pos | Pointer to the SCAN_INFO struct corresponding to the current slice to be played out |
[in] | dabslice | 0-based slice index for data storage |
[in] | nargs | Number of extra input arguments to ksfse_scan_coreslice() in range [0,2] |
[in] | args | Void pointer array pointing to the variables containing the actual values needed for ksfse_scan_coreslice() |
coreslicetime | Time taken in [us] to play out one slice with potentially other sequence modules |
int ksfse_scan_sliceloop | ( | int | slperpass, |
int | passindx, | ||
int | shot, | ||
int | exc | ||
) |
slperpass
slices corresponding to one TRThis function gets a spatial slice location index based on the pass index and temporal position within current pass. It then calls ksfse_scan_coreslice() to play out one coreslice (i.e. the main ksfse main sequence + optional sequence modules, excluding inversion modules).
[in] | slperpass | Number of slices to play in the slice loop |
[in] | passindx | Pass index in range [0, ks_slice_plan.npasses - 1] |
[in] | shot | shot index in range [0, ksfse.phaseenc_plan.num_shots - 1] |
[in] | exc | Excitation index in range [0, NEX-1] , where NEX = number of excitations (opnex) |
slicelooptime | Time taken in [us] to play out slperpass slices |
int ksfse_scan_sliceloop_nargs | ( | int | slperpass, |
int | nargs, | ||
void ** | args | ||
) |
For TR timing heat/SAR calculations of regular 2D multislice sequences, GEReq_eval_TR(), ks_eval_mintr() and GEReq_eval_checkTR_SAR() use a standardized function pointer with a fixed set of input arguments to call the sliceloop of the main sequence with different number of slices to check current slice loop duration. As different pulse sequences may need different number of input arguments (with different meaning) this ksfse_scan_sliceloop_nargs() wrapper function provides the argument translation for ksfse_scan_sliceloop().
The function pointer must have an integer corresponding to the number of slices to use as its first argument while the remaining input arguments (to ksfse_scan_sliceloop()) are stored in the generic void pointer array with nargs
elements, which is then unpacked before calling ksfse_scan_sliceloop().
[in] | slperpass | Number of slices to play in the slice loop |
[in] | nargs | Number of extra input arguments to ksfse_scan_sliceloop() in range [0,4] |
[in] | args | Void pointer array pointing to the variables containing the actual values needed for ksfse_scan_sliceloop() |
slicelooptime | Time taken in [us] to play out slperpass slices |
float ksfse_scan_acqloop | ( | int | passindx | ) |
This function traverses through all shots (ksfse.phaseenc_plan.num_shots
) to be played out and runs the ksfse_scan_sliceloop() for each set of shots and excitation. If ksfse_dda > 0, dummy scans will be played out before the phase encoding begins.
In the case of inversion, ksinv_scan_sliceloop() is called instead of ksfse_scan_sliceloop(), where the former takes a function pointer to ksfse_scan_coreslice_nargs() in order to be able to play out the coreslice in a timing scheme set by ksinv_scan_sliceloop().
[in] | passindx | 0-based pass index in range [0, ks_slice_plan.npasses - 1] |
passlooptime | Time taken in [us] to play out all phase encodes and excitations for slperpass slices. Note that the value is a float instead of int to avoid int overrange at 38 mins of scanning |
float ksfse_scan_scanloop | ( | ) |
This function performs the entire scan and traverses through passes and volumes. For now, since opmph = 0
as multiphase is controlled outside the psd via PSD_IOPT_DYNPL, opfphases will always be 1. For each passindx
(in range [0, ks_slice_plan.npasses-1]
), ksfse_scan_acqloop() will be called to acquire all data for the current set of slices belong to the current pass (acquisition). At the end of each pass, GEReq_endofpass() is called to trigger GE's recon and to dump Pfiles (if autolock = 1
).
scantime | Total scan time in [us] (float to avoid int overrange after 38 mins) |
STATUS ksfse_scan_seqstate | ( | SCAN_INFO | slice_info, |
int | shot | ||
) |
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.
The idea of having a 'seqstate' function is to be able to come back to a certain sequence state at any time and possibly play it out once more. This could for example be useful when certain lines or slices need to be rescanned due to image artifacts detected during scanning.
[in] | slice_info | Position of the slice to be played out (one element in the ks_scan_info[] array) |
[in] | shot | shot index in range [0, ksfse.phaseenc_plan.num_shots - 1] |
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 | ||
) |
STATUS ksfse_eval_setuprfpulses_2D | ( | KSFSE_SEQUENCE * | seq | ) |
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 to keep ksfse_eval_setupobjects() from growing too much in size.
[in] | seq | Pointer to the KSFSE_SEQUENCE struct holding all sequence objects |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_setuprfpulses_3D | ( | KSFSE_SEQUENCE * | seq | ) |
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 to keep ksfse_eval_setupobjects() from growing too much in size.
[in] | seq | Pointer to the KSFSE_SEQUENCE struct holding all sequence objects |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_setuprfpulses_recovery | ( | KSFSE_SEQUENCE * | seq | ) |
int ksfse_eval_ssitime | ( | ) |
int | SSI time in [us] |
STATUS ksfse_eval_setupobjects | ( | ) |
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 a) reduced T2-blurring due to faster k-space traversal, and b) no FSE ghosting. The drawback is that TE needs to be controlled via changing ETL in the UI, but image quality wise, it may still be worth it. If ksfse_etlte = FALSE, ksfse_calc_echo() will find the 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 |
STATUS ksfse_eval_inversion | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
It is important that ksfse_eval_inversion() is called after other sequence modules have been set up and added to the KS_SEQ_COLLECTION struct in my_cveval(). Otherwise the TI and TR timing will be wrong.
Whether IR is on or off is determined by ksinv1_mode, which is set up in KSINV_EVAL()->ksinv_eval(). If it is off, this function will return quietly.
This function calls ksinv_eval_multislice() (KSInversion.e), which takes over the responsibility of TR timing that otherwise is determined in ksfse_eval_tr(). ksinv_eval_multislice() sets seqcollection.evaltrdone = TRUE, which indicates that TR timing has been done. ksfse_eval_tr() checks whether seqcollection.evaltrdone = TRUE to avoid that non-inversion TR timing overrides the TR timing set up in ksinv_eval_multislice().
At the end of this function, TR validation and heat/SAR checks are done.
[in] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_tr | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
With the current sequence collection (see my_cveval()), and a function pointer to an argument-standardized wrapper function (ksfse_scan_sliceloop_nargs()) to the slice loop function (ksfse_scan_sliceloop(), this function calls GEReq_eval_TR(), where number of slices that can fit within one TR is determined by adding more slices as input argument to the slice loop function. For more details see GEReq_eval_TR().
With the number of slices/TR now known, a standard 2D slice plan is set up using ks_calc_sliceplan() and the duration of the main sequence is increased based on timetoadd_perTR, which was returned by GEReq_eval_TR(). timetoadd_perTR > 0 when optr > avmintr and when heat or SAR restrictions requires avmintr
to be larger than the net sum of sequence modules in the slice loop.
This function first checks whether seqcollection.evaltrdone == TRUE. This is e.g. the case for inversion where the TR timing instead is controlled using ksfse_eval_inversion() (calling ksinv_eval_multislice()).
At the end of this function, TR validation and heat/SAR checks are done using GEReq_eval_checkTR_SAR().
[in] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_eval_scantime | ( | ) |
After setting the number of dummy scans based on the current TR, the ksfse_scan_scanloop() is called to get the scan time. pitscan
is the UI variable for the scan clock shown in the top right corner on the MR scanner.
STATUS | SUCCESS or FAILURE |
STATUS ksfse_check | ( | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksfse_predownload_plot | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
The ks_plot_*** functions used in here will save plots to disk depending on the value of the CV ks_plot_filefmt
(see KS_PLOT_FILEFORMATS). E.g. if ks_plot_filefmt = KS_PLOT_OFF, nothing will be written to disk. On the MR scanner, the output will be located in /usr/g/mrraw/plot/<ks_psdname>. In simulation, it will be placed in the current directory (./plot/).
Please see the documentation on how to install the required python version and links. Specifically, there must be a link /usr/local/bin/apython pointing to the Anaconda 2 python binary (v. 2.7).
In addition, the following text files are printed out
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 |
STATUS ksfse_etlphaseamps | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
KS_PHASER * | phaser, | ||
KS_PHASER * | zphaser, | ||
int | shot | ||
) |
This function will quietly return early when called on HOST. On IPG, it will set the instruction amplitudes of the phase encoding gradients in the FSE train given the phase encoding table, the pointer to the single phase encoding object for all phase encodes in the echo train, and the shot index.
The shot
index must be in range [0, ceil(pe.numlinestoacq/etl)] and is used to select the current row of etl
different amplitudes in phaseenc_plan[][shot]
.
The KS_PHASER object must have been placed out 2*etl
times in ksfse_pg()
before calling this function. The etl
dephasing gradients before each readout in the echo train correspond to even indices, i.e. 0,2,4,...,(2*etl-1), whereas the rephasing gradients after each readout correspond to odd indices. This is an effect of that all ks_pg_***()
functions sort the instances of an object in time.
If shot < 0
(e.g. shot = KS_NOTSET = -1
), all phase encoding amplitudes will be set to zero.
[in] | phaseenc_plan_ptr | Pointer to the phase encoding table (KS_PHASEENCODING_PLAN) (2D & 3D) |
[in] | phaser | Pointer to a KS_PHASER ("ky") |
[in] | zphaser | Pointer to a KS_PHASER ("kz"). Pass in NULL for 2D |
[in] | shot | Which shot index to play out for this echo train. shot = KS_NOTSET will set all phase encoding gradients to zero. |
STATUS | SUCCESS or FAILURE |
void ksfse_spoilamp | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
KS_TRAP * | spoiler, | ||
int | res, | ||
int | shot | ||
) |
etl
and shot
This function updates the spoiler amplitude during scanning, and will return quietly if called on HOST.
[in] | phaseenc_plan_ptr | Pointer to the phase encoding table (KS_PHASEENCODING_PLAN) (2D & 3D) |
[in] | spoiler | Pointer to the KS_TRAP spoiler object |
[in] | res | Phase encoding resolution |
[in] | shot | shot index in range [0, ceil(pe.numlinestoacq/etl)] . |
void ksfse_scan_rf_off | ( | ) |
void ksfse_scan_rf_on | ( | ) |
STATUS ksfse_scan_init | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS 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_crusherscale = 0.5 with {0.0, 20.0, 0.5, VIS, "scaling of crusher gradient area",} |
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 |
int sequence_iopts[] |
int volindx |
int passindx |