Data Structures | |
struct | KSGRE_SEQUENCE |
Macros | |
#define | KSGRE_MINHNOVER 16 |
#define | KSGRE_DEFAULT_SSI_TIME 200 /* which may allow us to use the same SSI for other sequence modules too */ |
#define | KSGRE_DEFAULT_SSI_TIME_SSFP 100 |
#define | KSGRE_INIT_SEQUENCE |
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 ("GRE [KSFoundation]") | |
psdname ("ksgre") | |
STATUS | ksgre_pg (int start_time) |
int | ksgre_scan_coreslice (const SCAN_INFO *slice_pos, int dabslice, int shot, int exc) |
int | ksgre_scan_coreslice_nargs (const SCAN_INFO *slice_pos, int dabslice, int nargs, void **args) |
int | ksgre_scan_sliceloop (int slperpass, int passindx, int shot, int exc) |
int | ksgre_eval_ssitime () |
void | ksgre_init_imagingoptions (void) |
STATUS | ksgre_init_UI (void) |
STATUS | ksgre_eval_UI () |
STATUS | ksgre_eval_setupobjects () |
STATUS | ksgre_eval_TErange () |
STATUS | ksgre_eval_inversion (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksgre_eval_tr (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksgre_eval_scantime () |
STATUS | ksgre_check () |
STATUS | ksgre_predownload_plot (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksgre_predownload_setrecon () |
float | ksgre_scan_phase (int counter) |
STATUS | ksgre_scan_init (void) |
STATUS | ksgre_scan_prescanloop (int nloops, int dda) |
Variables | |
KS_SEQ_COLLECTION | seqcollection |
float | ksgre_excthickness = 0 |
float | ksgre_gscalerfexc = 0.9 |
int | ksgre_slicecheck = 0 with {0, 1, 0, VIS, "move readout to z axis for slice thickness test",} |
float | ksgre_spoilerarea = 1500.0 with {0.0, 10000.0, 1500.0, VIS, "ksgre spoiler gradient area",} |
int | ksgre_sincrf = 0 with {0, 1, 0, VIS, "Use Sinc RF",} |
float | ksgre_sincrf_bw = 2500 with {0, 100000, 2500, VIS, "Sinc RF BW",} |
float | ksgre_sincrf_tbw = 2 with {2, 100, 2, VIS, "Sinc RF TBW",} |
int | ksgre_rfexc_choice = 0 with {0, 3, 0, VIS, "RF pulse 0(fast)-1-2(high FA) 3 (Hard non-sel)",} |
int | ksgre_kxnover = 32 with {KSGRE_MINHNOVER, 512, 32, VIS, "Num kx overscans for minTE",} |
int | ksgre_rampsampling = FALSE with {FALSE, TRUE, FALSE, VIS, "Rampsampling [0:OFF 1:ON]",} |
int | ksgre_extragap = 0 with {0, 100ms, 0, VIS, "extra gap between readouts [us]",} |
int | ksgre_minacslines = 8 with {0, 512, 8, VIS, "Minimum ACS lines for ARC",} |
int | ksgre_minzacslines = 8 with {0, 512, 8, VIS, "Minimum z ACS lines for ARC",} |
int | ksgre_pos_start = KS_RFSSP_PRETIME with {0, , KS_RFSSP_PRETIME, VIS, "us from start until the first waveform begins",} |
int | ksgre_ssi_time = KSGRE_DEFAULT_SSI_TIME with {32, , KSGRE_DEFAULT_SSI_TIME, VIS, "time from eos to ssi in intern trig",} |
int | ksgre_dda = 2 with {0, 200, 2, VIS, "Number of dummy scans for steady state",} |
int | ksgre_debug = 1 with {0, 100, 1, VIS, "Write out e.g. plot files (unless scan on HW)",} |
int | ksgre_imsize = KS_IMSIZE_MIN256 with {KS_IMSIZE_NATIVE, KS_IMSIZE_MIN256, KS_IMSIZE_MIN256, VIS, "img. upsamp. [0:native 1:pow2 2:min256]"} |
int | ksgre_abort_on_kserror = FALSE with {0, 1, 0, VIS, "Hard program abort on ks_error [0:OFF 1:ON]",} |
int | ksgre_ellipsekspace = TRUE with {FALSE, TRUE, TRUE, VIS, "ky-kz coverage 0:Rect 1:Elliptical",} |
float | ksgre_fattune = 0 |
KSGRE_SEQUENCE | ksgre = KSGRE_INIT_SEQUENCE |
int | ksgre_ssfp_endtime = 0 |
int | sequence_iopts [] |
int | volindx |
int | passindx |
int | fiesta_firstplayout = 1 |
int | spgr_phase_counter = 0 |
MR-contrasts supported
Features
#define KSGRE_MINHNOVER 16 |
#define KSGRE_DEFAULT_SSI_TIME 200 /* which may allow us to use the same SSI for other sequence modules too */ |
#define KSGRE_DEFAULT_SSI_TIME_SSFP 100 |
#define KSGRE_INIT_SEQUENCE |
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 | ( | "GRE " | [KSFoundation] | ) |
psdname | ( | "ksgre" | ) |
STATUS ksgre_pg | ( | int | start_time | ) |
This is the main pulse sequence in ksgre.e using the sequence objects in KSGRE_SEQUENCE with the sequence module name "ksgremain" (= ksgre.seqctrl.description)
STATUS | SUCCESS or FAILURE |
int ksgre_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 (ksgre_scan_seqstate()) and plays out the core ksgre 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 ksgre_eval_tr()) we call ksgre_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 ksgre_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 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 ksgre_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 ksgre_scan_sliceloop() in ksgre_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 ksgre_scan_coreslice_nargs() wrapper function provides the argument translation for ksgre_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 ksgre_scan_coreslice()) are stored in the generic void pointer array with nargs
elements, which is then unpacked before calling ksgre_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 ksgre_scan_coreslice() in range [0,3] |
[in] | args | Void pointer array pointing to the variables containing the actual values needed for ksgre_scan_coreslice() |
coreslicetime | Time taken in [us] to play out one slice with potentially other sequence modules |
int ksgre_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 ksgre_scan_coreslice() to play out one coreslice (i.e. the main ksgre main sequence + optional sequence modules, excluding inversion modules).
[in] | slperpass | Number of slices to play in the slice loop |
[in] | passindx | 0-based pass index in range [0, ks_slice_plan.npasses - 1] |
[in] | shot | shot index in range [0, ksgre.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 ksgre_eval_ssitime | ( | ) |
int | SSI time in [us] |
void ksgre_init_imagingoptions | ( | void | ) |
STATUS ksgre_init_UI | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksgre_eval_UI | ( | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksgre_eval_setupobjects | ( | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksgre_eval_TErange | ( | ) |
N.B.: The minTE (avminte) and maxTE (avmaxte) ensures TE (opte) to be in the valid range for this pulse sequence to be set up in ksgre_pg(). If the pulse sequence design changes in ksgre_pg(), by adding/modifying/removing sequence objects in a way that affects the intended TE, this function needs to be updated too.
STATUS | SUCCESS or FAILURE |
STATUS ksgre_eval_inversion | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
N.B.: For now, ksgre.e has the same inversion logic as ksfse.e and this function is similar to ksfse_eval_inversion(). This is not used in clinical practice for 3D GRE and should be viewed as a placeholder. Once 3D mode is supported with ksgre.e, this section should change to perform an MP-RAGE type or BRAVO type of preparation instead.
It is important that ksgre_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 ksgre_eval_tr(). ksinv_eval_multislice() sets seqcollection.evaltrdone = TRUE, which indicates that TR timing has been done. ksgre_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,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS ksgre_eval_tr | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
With the current sequence collection (see my_cveval()), and a function pointer to an argument-standardized wrapper function (ksgre_scan_sliceloop_nargs()) to the slice loop function (ksgre_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 ksgre_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 ksgre_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 ksgre_check | ( | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksgre_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
STATUS ksgre_predownload_setrecon | ( | ) |
For most cases, the GEReq_predownload_*** functions in predownload() in ksgre.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 |
float ksgre_scan_phase | ( | int | counter | ) |
This function is largely what makes the difference between the the types of gradient echo sequences by different phase increment policies. For SPGR, RF spoiling is wanted and one tries to not repeat the same RF phase in a series of consecutive excitation. For bSSFP, the flip angle should be 'negative' every other time, which is accomplished by setting the RF phase to 0 or 180 [deg]. In all other cases (values of oppseq), the RF phase is set to 0.
[in] | counter | Counter from the calling function that should increment by 1 outside this function |
phase | RF phase in [deg] to be passed to ks_scan_selrf_setfreqphase() and ks_scan_offsetfov() |
STATUS ksgre_scan_init | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksgre_scan_prescanloop | ( | int | nloops, |
int | dda | ||
) |
STATUS | SUCCESS or FAILURE |
KS_SEQ_COLLECTION seqcollection |
float ksgre_excthickness = 0 |
float ksgre_gscalerfexc = 0.9 |
int ksgre_slicecheck = 0 with {0, 1, 0, VIS, "move readout to z axis for slice thickness test",} |
float ksgre_spoilerarea = 1500.0 with {0.0, 10000.0, 1500.0, VIS, "ksgre spoiler gradient area",} |
int ksgre_sincrf = 0 with {0, 1, 0, VIS, "Use Sinc RF",} |
float ksgre_sincrf_bw = 2500 with {0, 100000, 2500, VIS, "Sinc RF BW",} |
float ksgre_sincrf_tbw = 2 with {2, 100, 2, VIS, "Sinc RF TBW",} |
int ksgre_rfexc_choice = 0 with {0, 3, 0, VIS, "RF pulse 0(fast)-1-2(high FA) 3 (Hard non-sel)",} |
int ksgre_kxnover = 32 with {KSGRE_MINHNOVER, 512, 32, VIS, "Num kx overscans for minTE",} |
int ksgre_rampsampling = FALSE with {FALSE, TRUE, FALSE, VIS, "Rampsampling [0:OFF 1:ON]",} |
int ksgre_extragap = 0 with {0, 100ms, 0, VIS, "extra gap between readouts [us]",} |
int ksgre_minacslines = 8 with {0, 512, 8, VIS, "Minimum ACS lines for ARC",} |
int ksgre_minzacslines = 8 with {0, 512, 8, VIS, "Minimum z ACS lines for ARC",} |
int ksgre_pos_start = KS_RFSSP_PRETIME with {0, , KS_RFSSP_PRETIME, VIS, "us from start until the first waveform begins",} |
int ksgre_ssi_time = KSGRE_DEFAULT_SSI_TIME with {32, , KSGRE_DEFAULT_SSI_TIME, VIS, "time from eos to ssi in intern trig",} |
int ksgre_dda = 2 with {0, 200, 2, VIS, "Number of dummy scans for steady state",} |
int ksgre_debug = 1 with {0, 100, 1, VIS, "Write out e.g. plot files (unless scan on HW)",} |
int ksgre_imsize = KS_IMSIZE_MIN256 with {KS_IMSIZE_NATIVE, KS_IMSIZE_MIN256, KS_IMSIZE_MIN256, VIS, "img. upsamp. [0:native 1:pow2 2:min256]"} |
int ksgre_abort_on_kserror = FALSE with {0, 1, 0, VIS, "Hard program abort on ks_error [0:OFF 1:ON]",} |
int ksgre_ellipsekspace = TRUE with {FALSE, TRUE, TRUE, VIS, "ky-kz coverage 0:Rect 1:Elliptical",} |
float ksgre_fattune = 0 |
KSGRE_SEQUENCE ksgre = KSGRE_INIT_SEQUENCE |
int ksgre_ssfp_endtime = 0 |
int sequence_iopts[] |
int volindx |
int passindx |
int fiesta_firstplayout = 1 |
int spgr_phase_counter = 0 |