Data Structures | |
struct | KSEPI_SEQUENCE |
struct | KSEPI_FLEET_SEQUENCE |
struct | KSEPI_METADATA |
Enumerations | |
enum | KSEPI_SEQINDICES { KSEPI_SEQINDEX_MAIN, KSEPI_SEQINDEX_FLEET, KSEPI_SEQINDEX_MAIN_SPLITODDEVEN, KSEPI_SEQINDEX_FLEET_SPLITODDEVEN } |
enum | KSEPI_SEQPARTS { KSEPI_SEQPART_EPITRAIN, KSEPI_SEQPART_DYNREFTRAIN, KSEPI_SEQPART_FIDNAV } |
enum | ksepi_diffusion_return { DIFFRETURN_ALL = 0, DIFFRETURN_ACQUIRED = 1, DIFFRETURN_B0 = 2, DIFFRETURN_MEANDWI = 4, DIFFRETURN_MEANADC = 8, DIFFRETURN_EXPATT = 16, DIFFRETURN_FA = 32, DIFFRETURN_CFA = 64 } |
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 ("EPI [KSFoundation]") | |
psdname ("ksepi") | |
STATUS | ksepi_eval_flowcomp_phase (KS_TRAP *fcphase, const KS_EPI *epi, const char *desc) |
STATUS | ksepi_pg (int start_time) |
KS_CORESLICETIME | ksepi_scan_irslice (const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic) |
KS_CORESLICETIME | ksepi_scan_coreslice (const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic) |
KS_CORESLICETIME | ksepi_scan_coreslicegroup (const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic) |
KS_CORESLICETIME | ksepi_scan_fleet_coreslice (const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic) |
void | ksepi_scan_attach_metadata (KSEPI_SEQUENCE *seq, const KS_DYNAMIC_STATE *dynamic, uint8_t sequence_group) |
void | ksepi_dump_metadata (KSEPI_METADATA *metadata, const KS_DYNAMIC_STATE *dynamic) |
STATUS | ksepi_set_loop_control_design (KSSCAN_LOOP_CONTROL_DESIGN *loop_design, const KS_EPI *epitrain) |
STATUS | ksepi_scan_seqstate (SCAN_INFO slice_pos, KS_PHASEENCODING_COORD starting_coord, ks_enum_epiblipsign blipsign) |
s64 | ksepi_scan_scanloop () |
const KSSCAN_LOOP_CONTROL * | ksepi_get_loop_ctrl () |
void | ksepi_init_imagingoptions (void) |
STATUS | ksepi_init_UI (void) |
STATUS | ksepi_eval_UI () |
STATUS | ksepi_eval_setuprf () |
STATUS | ksepi_eval_setupfleet () |
STATUS | ksepi_eval_setupobjects () |
STATUS | ksepi_eval_TErange () |
void | ksepi_set_kspace_design_forsat (KS_KSPACE_DESIGN *kdesign) |
void | ksepi_set_slicetiming_design (KS_SLICETIMING_DESIGN *slicetiming_design) |
STATUS | ksepi_set_inversion_loop_control_design (KSINV_LOOP_CONTROL_DESIGN *invloopctrl_design, const KS_EPI *epitrain) |
STATUS | ksepi_eval_inversion (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksepi_eval_sat (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksepi_gradheat_play (const INT max_encode_mode, int nargs, void **args) |
STATUS | ksepi_eval_loops (KS_SEQ_COLLECTION *seqcollection) |
int | ksepi_eval_ssitime () |
STATUS | ksepi_eval_scantime (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksepi_update_UI () |
STATUS | ksepi_predownload_plot (KS_SEQ_COLLECTION *seqcollection) |
STATUS | ksepi_predownload_setrecon () |
STATUS | ksepi_pg_fleet (int start_time) |
STATUS | ksepi_fleet_scan_seqstate (const SCAN_INFO *slice_pos, KS_PHASEENCODING_COORD starting_coord, ks_enum_epiblipsign blipsign) |
void | ksepi_scan_rf_off () |
void | ksepi_scan_attach_metadata (KS_EPI *epitrain, KS_EPI *dynreftrain, const KS_DYNAMIC_STATE *dynamic, uint8_t sequence_group) |
STATUS | ksepi_scan_init (void) |
STATUS | ksepi_scan_prescanloop (int nloops, int dda) |
STATUS | ksepi_diffusion_init_UI () |
void | SolveCubic (double a, double b, double c, double d, int *nsol, double *x) |
STATUS | ksepi_diffusion_calcTE (double *TE_s, int exciso2end, int crsh1_half180, int half180_crsh2, int readout2echo, int ramptime, float G, int bval_desired) |
STATUS | ksepi_diffusion_eval_gradients_TE (KSEPI_SEQUENCE *epi, const KSDIFF_CONTROL *diff_ctrl) |
STATUS | ksepi_eval_diffusion (KSDIFF_CONTROL *diff_ctrl) |
STATUS | ksepi_diffusion_pg (KSEPI_SEQUENCE *epi, int TE) |
Variables | |
KS_SEQ_COLLECTION | seqcollection |
float | ksepi_excthickness = 0 |
float | ksepi_gscalerfexc = 0.9 with {0.1, 3.0, 0.9, VIS, "Excitation slice thk scaling (< 1.0 thicker slice)",} |
int | ksepi_slicecheck = 0 with {0, 1, 0, VIS, "move readout to z axis for slice thickness test",} |
float | ksepi_spoilerarea = 3000.0 with {0.0, 10000.0, 3000.0, VIS, "ksepi ksepi.spoiler gradient area",} |
int | ksepi_rfspoiling = 1 with {0, 1, 1, VIS, "Enable RF spoiling 1:on 0:off",} |
int | ksepi_fse90 = 0 with {0, 1, 0, VIS, "Use FSE90 instead of SPSP for non-fatsat",} |
float | ksepi_kissoff_factor = 0.04 with {0, 1, 0.04, VIS, "Slice oversampling fraction on each side (3D)",} |
float | ksepi_rfstretch_exc = 1.0 with {0.1,10.0, 1.0, VIS, "RF excitation stretch factor"} |
int | ksepi_fastexc3D = TRUE with {FALSE, TRUE, TRUE, VIS, "Sel. RF exc (3D) 0:EXC_SPSP_3D 1:EXC_FAST_SPSP_3D",} |
float | ksepi_crusher_dephasing = 6.0 with { 0.0, 100.0, 6.0, VIS, "crusher dephasing over slice [cycles]",} |
float | ksepi_gscalerfref = 0.9 with {0.1, 3.0, 0.9, VIS, "Refocusing slice thk scaling (< 1.0 thicker slice)",} |
float | ksepi_rfstretch_ref = 1.0 with {0.1,10.0, 1.0, VIS, "RF refocusing stretch factor",} |
int | ksepi_bridgecrushers = FALSE with {FALSE, TRUE, FALSE, VIS, "Bridge RF ref crushers",} |
int | ksepi_t1value_to_null = T1_FAT_3T with {0, 5s, T1_FAT_3T, VIS, "T1 value to NULL [us]",} |
int | ksepi_rampsampling = 1 with {0, 1, 1, VIS, "Rampsampling [0:OFF 1:ON]",} |
int | ksepi_readlobegap = 0 with {0, 10ms, 0, VIS, "extra gap between readout lobes [us]",} |
int | ksepi_echogap = 0 with {0, 100ms, 0, VIS, "extra gap between EPI echoes [us]",} |
int | ksepi_readsign = 1 with { -1, 1, 1, VIS, "Readout polarity: +1/-1",} |
float | ksepi_readampmax = 3.0 with {0.0, 5.0, 3.0, VIS, "Max grad amp for EPI readout lobes",} |
float | ksepi_sr = 0.01 with {0.0, , 0.01, VIS, "EPI SR: amp/ramp [(G/cm) / us]",} |
int | ksepi_esp = 0 with {0, 1000000, 0, VIS, "View-only: Echo spacing in [us]",} |
int | ksepi_blipsign = KS_EPI_POSBLIPS with {KS_EPI_NEGBLIPS, KS_EPI_POSBLIPS, KS_EPI_POSBLIPS, VIS, "Blip polarity: +1/-1",} |
int | ksepi_echotime_shifting = 1 with {0, 1, 1, VIS, "Enable echo time shifting for multi shot",} |
int | ksepi_kynover = 24 with {KSEPI_MINHNOVER, 512, 24, VIS, "#extralines for MinTE",} |
int | ksepi_kznover = 0 with {0, 512, 0, VIS, "#extralines in kz",} |
int | ksepi_kz_nacslines = 8 with {0, 64, 8, VIS, "#acslines in kz",} |
int | ksepi_caipi = 0 with {0, 512, 0, VIS, "CAIPIRINHA shift (affects 3D epi only. Set 0 for no CAIPI)",} |
int | ksepi_readout_mode = KS_EPI_BIPOLAR with {KS_EPI_BIPOLAR, KS_EPI_FLYBACK, KS_EPI_BIPOLAR, VIS, "EPI readout mode 0: bipolar 1:splitoddeven 2:flyback",} |
int | ksepi_fcy = 1 with {0, 1, 0, VIS, "Flowcomp Y when opfcomp"} |
int | ksepi_fcz = 1 with {0, 1, 0, VIS, "Flowcomp Z when opfcomp"} |
int | ksepi_fleet = 0 with {0, 1, 0, VIS, "FLEET calibration volume [0:OFF 1:ON]",} |
int | ksepi_echotime_shifting_fleet = 1 with {0, 1, 1, VIS, "Enable echo time shifting for multi shot FLEET",} |
float | ksepi_fleet_flip = 5.0 with {1.0, 90.0, 5.0, VIS, "FLEET flip angle [deg]",} |
int | ksepi_fleet_dda = 3 with {1, 200, 3, VIS, "Dummies for FLEET module",} |
int | ksepi_fleet_num_ky = 48 with {32, 256, 48, VIS, "Number of ky encodes for FLEET module",} |
int | ksepi_fleet_readout_mode = KS_EPI_SPLITODDEVEN with {KS_EPI_BIPOLAR, KS_EPI_FLYBACK, KS_EPI_SPLITODDEVEN, VIS, "FLEET EPI readout mode 0: bipolar 1:splitoddeven 2:flyback",} |
int | ksepi_fleet_nshots = 3 with {1, 128, 3, VIS, "# shots for FLEET",} |
int | ksepi_reflines = 0 with {0, 96, 0, VIS, "Number of phase reference lines per shot",} |
int | ksepi_swi_returnmode = 0 with {0, 7, 0, VIS, "SWI recon 0:Off 1:Acq 2:SWI 4:SWIphase",} |
int | ksepi_pos_start = KS_RFSSP_PRETIME with {0, , KS_RFSSP_PRETIME, INVIS, "us from start until the first waveform begins",} |
int | ksepi_ssi_time = KSEPI_DEFAULT_SSI_TIME with {32, , KSEPI_DEFAULT_SSI_TIME, VIS, "time from eos to ssi in intern trig",} |
int | ksepi_dda = 1 with {1, 200, 1, VIS, "Number of dummy scans for steady state",} |
int | ksepi_debug = 1 with {0, 100, 1, VIS, "Write out e.g. plot files (unless scan on HW)"} |
int | ksepi_imsize = KS_IMSIZE_POW2 with {KS_IMSIZE_NATIVE, KS_IMSIZE_MIN256, KS_IMSIZE_POW2, VIS, "img. upsamp. [0:native 1:pow2 2:min256]"} |
int | ksepi_abort_on_kserror = FALSE with {0, 1, 0, VIS, "Hard program abort on ks_error [0:OFF 1:ON]",} |
int | ksepi_ref_nsegments = 1 with {1, 512, 1, VIS, "Number of kz segments in reference volume",} |
float | ksepi_epiqfact = 1.0 with {1.0, 10.0, 1.0, VIS, "Quietness factor for the EPI readout only",} |
int | ksepi_recvgain_mode = RG_CAL_MODE_HIGH_FIXED with {RG_CAL_MODE_MIN, RG_CAL_MODE_MAX, RG_CAL_MODE_HIGH_FIXED, VIS, "RecvGain - 0:Measured 1:8 2:5 3:Max",} |
int | ksepi_metadump = 0 |
KSEPI_SEQUENCE | ksepi = KSEPI_INIT_SEQUENCE |
KSSCAN_LOOP_CONTROL | ksepi_loopctrl = KSSCAN_INIT_LOOP_CONTROL |
KSDIFF_CONTROL | ksepi_diffctrl = KSDIFF_INIT_CONTROL |
KSEPI_FLEET_SEQUENCE | ksepi_fleetseq = KSEPI_FLEET_INIT_SEQUENCE |
KSSCAN_LOOP_CONTROL | ksepi_fleet_loopctrl = KSSCAN_INIT_LOOP_CONTROL |
KSINV_MODULE | ksepi_inv = KSINV_INIT_MODULE |
KSINV_LOOP_CONTROL | ksepi_inv_loopctrl = KSINV_INIT_LOOP_CONTROL |
KS_PHASEENCODING_COORD | ksepi_phaseencoding_memorypool [KSEPI_PHASEENCODING_MEMORYPOOL_SIZE] = {KS_INIT_PHASEENCODING_COORD} |
int | ksepi_interechotime = 0 |
float | ksepi_echotime_shifting_shotdelay = 0.0 |
float | ksepi_echotime_shifting_shotdelay_fleet = 0.0 |
int | ksepi_echotime_shifting_sumdelay = 0 |
int | ksepi_echotime_shifting_sumdelay_fleet = 0 |
KS_KSPACE_ACQ | kacq = KS_INIT_KSPACE_ACQ |
int | sequence_iopts [] |
int | rfspoiling_phase_counter = 0 |
float | ksepi_diffusion_amp_scale = 1.0 with {0.0, 1.0, 1.0, VIS, "Cap for scaling factor of diffusion gradient amplitude", } |
int | ksepi_diffusion_heat_avg = 1 with {0, 1, 1, VIS, "Root mean sqared averaging diffusion amplitudes heat calculations", } |
float | ksepi_diffusion_scaleX_heatcal = 1 with {0, 1, 1, VIS, "View-only: x diffusion gradient amplitude for heating calculations", } |
float | ksepi_diffusion_scaleY_heatcal = 1 with {0, 1, 1, VIS, "View-only: y diffusion gradient amplitude for heating calculations", } |
float | ksepi_diffusion_scaleZ_heatcal = 1 with {0, 1, 1, VIS, "View-only: z diffusion gradient amplitude for heating calculations", } |
int | ksepi_diffusion_echotime = 0 with {0, , 0, VIS, "View-only: Echo time necessary to meet the desired b-value", } |
int | ksepi_diffusion_returnmode = DIFFRETURN_ALL with {DIFFRETURN_ALL, 128, DIFFRETURN_ALL, VIS, "Diff maps All:0 Acq:1 b0:2 DWI:4 ADC:8 Exp:16 FA:32 cFA:64",} |
int | ksepi_diffusion_minramptime = 1ms with {0, 20ms, 1ms, VIS, "Minimum diffusion ramp time. If 0: syslimits used",} |
MR-contrasts supported
Features
#define KSEPI_MINHNOVER 8 /* N.B. overscans below about 16-24 should be avoided for long TE */ |
#define KSEPI_MAXRBW_NORAMPSAMPLING 125.0 |
#define KSEPI_DEFAULT_SSI_TIME_ICEHARDWARE 100 |
#define KSEPI_DEFAULT_SSI_TIME 1500 |
#define PLAY_FLEET ((int) (!KS_3D_SELECTED && oparc && opaccel_ph_stride > 1)) /* conditions when to play FLEET */ |
#define OPUSER_PSDVERSION opuser0 |
#define SHOW_RHRECON use0 |
#define OPUSER_KYNOVER opuser1 |
#define SHOW_KYNOVER use1 |
#define OPUSER_BLIPSIGN opuser2 |
#define SHOW_BLIPSIGN use2 |
#define OPUSER_EPIREADOUTMODE opuser4 |
#define SHOW_EPIREADOUTMODE use4 |
#define OPUSER_FLEET_EPIREADOUTMODE opuser5 |
#define SHOW_FLEET_EPIREADOUTMODE use5 |
#define OPUSER6_DIFF_RETURNMODE opuser6 /* opuser6 is checked in recon_ksepi2, so don't chance this */ |
#define SHOW_DIFF_RETURNMODE use6 |
#define OPUSER7_SWI_RETURNMODE opuser7 /* opuser7 is checked in recon_ksepi2, so don't chance this */ |
#define SHOW_SWI_READOUTMODE use7 |
#define OPUSER_REFLINES opuser9 |
#define SHOW_REFLINES use9 |
#define OPUSER_KZACSLINES opuser15 |
#define SHOW_KZACSLINES use15 |
#define KSEPI_INIT_SEQUENCE {KS_INIT_SEQ_CONTROL, KS_INIT_EPI, KS_INIT_EPI, KS_INIT_TRAP, KS_INIT_SELRF, KS_INIT_SELRF, {KS_INIT_TRAP}, KS_INIT_WAIT, KS_INIT_WAIT, KS_INIT_TRAP, KS_INIT_TRAP} |
#define KSEPI_FLEET_INIT_SEQUENCE {KS_INIT_SEQ_CONTROL, KS_INIT_EPI, KS_INIT_TRAP, KS_INIT_SELRF, KS_INIT_WAIT, KS_INIT_WAIT} |
#define KSEPI_INIT_METADATA {KSEPI_SEQINDEX_MAIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, KSEPI_SEQPART_EPITRAIN, KS_NOTSET, KS_NOTSET, 1} |
initialization values for KSEPI_METADATA
#define KSEPI_PHASEENCODING_MEMORYPOOL_SIZE 25000 |
num elements allocated for unique phase encodes. For EPI, only the blipphaser's ky value goes in there (first ky line in EPI train)
#define MAX_DIFFSCHEME_LENGTH 512 |
Maximum 512 diffusion directions (including b=0)
#define KSEPI_DIFFUSION_MAXBVALS 10 |
10 different b-values > 0
#define KSEPI_DIFFUSION_MAXBVALUE 20000 |
enum KSEPI_SEQINDICES |
Enumerator | |
---|---|
KSEPI_SEQINDEX_MAIN | |
KSEPI_SEQINDEX_FLEET | |
KSEPI_SEQINDEX_MAIN_SPLITODDEVEN | |
KSEPI_SEQINDEX_FLEET_SPLITODDEVEN |
enum KSEPI_SEQPARTS |
Enumerator | |
---|---|
DIFFRETURN_ALL | |
DIFFRETURN_ACQUIRED | |
DIFFRETURN_B0 | |
DIFFRETURN_MEANDWI | |
DIFFRETURN_MEANADC | |
DIFFRETURN_EXPATT | |
DIFFRETURN_FA | |
DIFFRETURN_CFA |
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 | ( | "EPI " | [KSFoundation] | ) |
psdname | ( | "ksepi" | ) |
This function computes the flow compensation gradient for the phase encoding (Y) board based on the EPI readout struct
[out] | fcphase | Pointer to the flow compensation KS_TRAP gradient on the Y board |
[in] | epi | Pointer to the KS_EPI structure containing the EPI parameters |
[in] | desc | Description of the flow compensation phase gradients |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_pg | ( | int | start_time | ) |
This is the main pulse sequence in ksepi.e using the sequence objects in KSEPI_SEQUENCE with the sequence module name "ksepimain" (= ksepi.seqctrl.description)
STATUS | SUCCESS or FAILURE |
KS_CORESLICETIME ksepi_scan_irslice | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
ksepi_inv
(global in this file) as argumentThe inversion sequence's play function
[in] | slice_pos | Position of the slice to be played out (one element in the global ks_scan_info[] array) |
[in] | dynamic | Pointer to KS_DYNAMIC_STATE struct, which has elements being automatically updated by the scan looping functions |
KS_CORESLICETIME ksepi_scan_coreslice | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
ksepi
sequence module in real time during scanningThe main EPI sequence's play function
This function updates the waveforms, and plays out, the ksepi 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 += ...).
ks_scan_epi_loadecho() is called for data acquisition for each EPI readout.
After this, ksepi_scan_attach_metadata() adds additional data for each acqusition window for use in the recon_ksepi2.m Matlab script for sorting and reconstruction. To distinguish between the main and FLEET sequences, the sequence_group is here set to KSEPI_DATAGROUP_MAIN.
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 ksepi.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(&ksepi.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 |
coreslicetime | KS_CORESLICETIME containing the time taken in [us] to play out one slice and the moment start of the slice |
KS_CORESLICETIME ksepi_scan_coreslicegroup | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
The main EPI sequence + potential other modules' play function
With the use of generic scan loops (ksscan.cc:ksscan_scanloop()) performing the actual scan in ksepi_scan_scanloop(), using
ksepi_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 ksepi_scan_coreslice(), which only plays the main sequence (ksepi
), 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 ksepi_scan_fleet_coreslice | ( | const SCAN_INFO * | slice_pos, |
KS_DYNAMIC_STATE * | dynamic | ||
) |
ksepi_fleetseq
sequence module in real time during scanningThe FLEET EPI sequence's play function
This function updates the waveforms, and plays out, the ksepi_fleetseq
sequence module. It is quite similar to ksepi_scan_coreslice(), but with the FLEET sequence module instead of the main EPI sequence. In this function, sequence_group = KSEPI_DATAGROUP_FLEET, while it is KSEPI_DATAGROUP_MAIN in ksepi_scan_coreslice(), to let recon detect which readout windows are FLEET vs MAIN.
[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 |
void ksepi_scan_attach_metadata | ( | KSEPI_SEQUENCE * | seq, |
const KS_DYNAMIC_STATE * | dynamic, | ||
uint8_t | sequence_group | ||
) |
void ksepi_dump_metadata | ( | KSEPI_METADATA * | metadata, |
const KS_DYNAMIC_STATE * | dynamic | ||
) |
This debugging function can be used to find errors in the datastore tags of this sequence, created in ksepi_scan_attach_metadata(). Alternatively, this can be done graphically in Matlab (recon_ksepi2.m -> recon_ksepi2_splitdata.m)
metadata | Pointer to KSEPI_METADATA |
dynamic | Pointer to KS_DYNAMIC_STATE |
STATUS ksepi_set_loop_control_design | ( | KSSCAN_LOOP_CONTROL_DESIGN * | loop_design, |
const KS_EPI * | epitrain | ||
) |
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 ksepi_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 |
[in] | epitrain | KS_EPI struct with .blipphaser and .zphaser fields steering the set of k-space coordinates to reach |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_scan_seqstate | ( | SCAN_INFO | slice_pos, |
KS_PHASEENCODING_COORD | starting_coord, | ||
ks_enum_epiblipsign | blipsign | ||
) |
This function sets the current state of all ksepi sequence objects being part of KSEPI_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 ksepi_scan_coreslice() during scan.
Note that starting_coord
is the first line in the EPI train.
[in] | slice_pos | Position of the slice to be played out (one element in the ks_scan_info[] array) |
[in] | starting_coord | KS_PHASEENCODING_COORD holding the .ky and .kz coordinates of the first line in the EPI train |
[in] | blipsign | Sign of the EPI blips: [-1]:Negative (k-space top-down) [1]:Positive (k-space bottom-up) [0]:No blips |
STATUS | SUCCESS or FAILURE |
s64 ksepi_scan_scanloop | ( | ) |
This function is called from ksepi.e:scan(), which corresponds to the actual SCAN button press in the UI.
This function first completes the FLEET scan, for 2D imaging with parallel imaging, where the FLEET scan is used in recon for motion robust GRAPPA calibration.
If inversion is used, the function calls ksinv_scan_scanloop(), where ksepi_inv_loopctrl
is used to control the the scan looping. For non-inversion scans, depending on if diffusion is used, either ksdiff_schemeloop() or ksscan_scanloop() is called, where ksepi_loopctrl
is used to control the scan looping in both cases. ksscan_scanloop() and ksdiff_schemeloop() differ only on the outer volumne loop, but share the same inner looping from ksscan_acqloop(). While ksscan_scanloop() goes through volume indices like fMRI, ksdiff_schemeloop() goes through diffusion directions and b-values as different volumes.
const KSSCAN_LOOP_CONTROL * ksepi_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 ksepi_init_imagingoptions | ( | void | ) |
STATUS ksepi_init_UI | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_eval_UI | ( | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_eval_setuprf | ( | ) |
This function initializes the local excdesign and refdesign structures with default values and modifies them based on various CVs. The function then calls ks_eval_design_selrfexc() and ks_eval_design_selrfref() functions to evaluate the designs and store the results in ksepi.selrfexc and ksepi.selrfref structures respectively for later use in ksepi_pg()
STATUS | SUCCESS or FAILURE |
STATUS ksepi_eval_setupfleet | ( | ) |
Based on CVs and by copying the .epitrain from the main sequence, this function sets up the sequence components of the FLEET sequence. The FLEET sequence is used for GRAPPA calibration in the recon (recon_ksepi2.m) for 2D scans. See C macro PLAY_FLEET
in this file
STATUS | SUCCESS or FAILURE |
STATUS ksepi_eval_setupobjects | ( | ) |
This function will set up all objects for the main sequence module (ksepi) 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 ksepi_pg().
Note that at the very end of this function, ksepi_eval_setupfleet() is called to also set up ksepi_fleetseq (KSEPI_FLEET_SEQUENCE) as well as ksepi (KSEPI_SEQUENCE) if ksepi_fleet is TRUE
STATUS | SUCCESS or FAILURE |
STATUS ksepi_eval_TErange | ( | ) |
This function handles the TE range for SE-EPI, GE-EPI and DW-EPI (opdiffuse).
Multiple EPI trains (opnecho > 1) are supported Time between the EPI readouts is controlled using ksepi_echogap
, yielding a ksepi_interechotime
variable used in ksepi_pg().
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 ksepi_pg(). If the pulse sequence changes are made in ksepi_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 |
void ksepi_set_kspace_design_forsat | ( | KS_KSPACE_DESIGN * | kdesign | ) |
ksepi_eval_sat()->kssat_setup_from_UI() (see ksmodules/kssat.e) needs a KS_KSPACE_DESIGN to get the FOV borders, why such struct is setup here. Ideally, this KS_KSPACE_DESIGN should also set up the proper fields of .epitrain field for the main sequence (ksepi), but this is for now still set up manually in ksepi_eval_setupobjects().
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 ksepi_set_slicetiming_design | ( | KS_SLICETIMING_DESIGN * | slicetiming_design | ) |
This function is called from ksepi_eval_loops()->ksepi_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 ksepi_set_inversion_loop_control_design | ( | KSINV_LOOP_CONTROL_DESIGN * | invloopctrl_design, |
const KS_EPI * | epitrain | ||
) |
This function creates a KSSCAN_LOOP_CONTROL_DESIGN struct, which contains the same KSSCAN_LOOP_CONTROL_DESIGN struct as ksepi_set_loop_control_design() in its .loopctrl_design
field. This by calling ksepi_set_loop_control_design(&invloopctrl_design->loopctrl_design, epitrain) 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 |
[in] | epitrain | KS_EPI struct with .blipphaser and .zphaser fields steering the set of k-space coordinates to reach |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_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 ksepi_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 ksepi_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 ksepi.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 ksepi_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 ksepi_gradheat_play | ( | const INT | max_encode_mode, |
int | nargs, | ||
void ** | args | ||
) |
This function plays a set of sequence modules that collectively makes a test sequence that attempts to be a good approximation of the average and maxmimum power dissipation of the gradient system. This function is not used for any data collection.
This function first plays the saturation sequence (if kssat.seqctrl.duration > 0), then the inversion sequence (if any), then, if diffusion, scaled versions of the diffusion gradients are played (either .RMS_amp_scale or .max_power_amp_scale), with the main sequence based on the max_encode_mode
.
It should be noted that the content of this function is manual work and needs to be updated if the content of ksepi_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.
This function is passed as an argument to ks_eval_getduration() to get the playout time and to ks_eval_hwlimits() to get the new minimum time due to hardware heating and SAR calculations.
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 ksepi_eval_loops() for more details.
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 ksepi_eval_loops | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
This function performs the following tasks:
newtime
ksepi.seqctrl.duration
) if the newtime > time using ks_eval_seqctrl_setduration()fleet_loopctrl_design
, which is used together with the FLEET coreslice function (ksepi_scan_fleet_coreslice())ksepi_fleet_loopctrl
in ksscan_loop_control_eval_design() to control the scan loop for the FLEET sequenceloopctrl_design
(for main sequence), which is used together with the coreslice function (ksepi_scan_coreslicegroup())ksepi_loopctrl
in ksscan_loop_control_eval_design() to control the scan loop for the main sequenceinv_loopctrl_design
is used to create ksepi_inv_loopctrl
, which controls the scan loop instead of ksepi_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 fleet_loopctrl_design
, loopctrl_design
, and inv_loopctrl_design
.
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
int ksepi_eval_ssitime | ( | ) |
STATUS ksepi_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 ksepi_update_UI | ( | ) |
This function is called from cvcheck() to update the UI variables based largely on ksepi
and ksepi_loopctrl
after checks for some out-of-bounds values.
STATUS | SUCCESS or FAILURE |
STATUS ksepi_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 and FLEET sequence diagrams as HTML files, 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. If diffusion is on, only the diffusion scheme index should be changed by the slider, otherwise the shot index should be changed. To do this, this function must play the relevant changes that should be presented in the HTML plot slider and skip 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(). Then, for diffsion, a call to ksdiff_plotloop() is made to play a single slice and shot index for many diffusion scheme indices. For non-diffusion, 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.
The FLEET sequence is recorded using ksscan_plotloop_shots(), to show shot-to-shot variations with the HTML plot slider.
For the slicetiming plot, the three functions ks_plot_slicetime_begin();ksepi_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 ksepi_predownload_setrecon | ( | ) |
For most cases, the GEReq_predownload_*** functions in predownload() in ksepi.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. This function is called last in predownload()
The rhuser variables here are needed for the Matlab recon recon_ksepi2.m to work, so they should not be changed. Setting rhileaves here to 1, also for multi-shot EPI, is critical to make Nyquist ghost correction work in recon for multi-shot EPI.
The rhrecon
is set to 961 to call /usr/g/bin/recon961 on the scanner, which is present when this PSD is bundled with a compiled version of the matlab recon has been installed from an RPM. rhrecon
may be changed to any other number to call another recon script, possibly one that just copies the scan archive off the scanner, or compiled variants of the recon_ksepi2.m script for VRE recons.
STATUS | SUCCESS or FAILURE |
STATUS ksepi_pg_fleet | ( | int | start_time | ) |
This is the FLEET pulse sequence in ksepi.e using the sequence objects in KSEPI_FLEET_SEQUENCE with the sequence module name "ksepifleet" (= ksepi_fleet.seqctrl.description). The FLEET sequence module is needed for GRAPPA calibration in the recon (recon_ksepi2.m) for 2D scans
STATUS | SUCCESS or FAILURE |
STATUS ksepi_fleet_scan_seqstate | ( | const SCAN_INFO * | slice_pos, |
KS_PHASEENCODING_COORD | starting_coord, | ||
ks_enum_epiblipsign | blipsign | ||
) |
Sets the current state of all FLEET sequence objects at every FLEET sequence playout in scan.
This function sets the current state of all FLEET sequence objects being part of KSEPI_FLEET_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 ksepi_scan_fleet_coreslice() during scan.
slice_pos | Pointer to the SCAN_INFO structure containing slice information. |
starting_coord | The starting coordinate for the scan. |
blipsign | The blip sign for the scan. |
STATUS | SUCCESS or FAILURE |
void ksepi_scan_rf_off | ( | ) |
void ksepi_scan_attach_metadata | ( | KS_EPI * | epitrain, |
KS_EPI * | dynreftrain, | ||
const KS_DYNAMIC_STATE * | dynamic, | ||
uint8_t | sequence_group | ||
) |
The elements in KS_DYNAMIC_STATE are set by the nested scan loop functions (for EPI that is in ksepi.cc). These elements are e.g. .average, .shot, .slloc. For more details see KS_DYNAMIC_STATE.
With a 22-byte size limit of additional data to each DAB packet (i.e. each readout lobe), the 22-byte KSEPI_METADATA struct will here be filled with selected information from the dynamic
struct (which is too large to be passed on as DAB packets) as well as with static data (sequence_group
). The selected content of information in KSEPI_METADATA is given in ksepi2.h, where for now some free fields are available for future use.
To reduce the byte usage, diff_ampX/Y/Z are converted from float
to int16
and scaled by 32767
.
Once the local KSEPI_METADATA metadata_out
has been filled, it is passed to ks_loaddab() in this function.
Note that the sequence-independent KS_DYNAMIC_STATE can grow in the future with new fields to support more needs for various PSDs. In contrast, care needs to be taken not only to limit the number of bytes used in KSEPI_METADATA, and also to not shuffle the fields of KSEPI_METADATA for backwards compatibility of the Matlab recon ksepi2_recon.m
, which uses dab_getinfo_ksepi2.m
to parse each raw frame's additional bytes where the KSEPI_METADATA is stored.
[in] | epitrain | Pointer to KS_EPI for the main EPI train |
[in] | dynreftrain | Pointer to KS_EPI for the dynamic ref lines (may be NULL) |
[in] | dynamic | Pointer to KS_DYNAMIC_STATE that stores nex, slice, shot, vol information |
[in] | sequence_group | One of enums in KSEPI_SEQINDICES |
STATUS ksepi_scan_init | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_scan_prescanloop | ( | int | nloops, |
int | dda | ||
) |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_diffusion_init_UI | ( | ) |
STATUS | SUCCESS or FAILURE |
void SolveCubic | ( | double | a, |
double | b, | ||
double | c, | ||
double | d, | ||
int * | nsol, | ||
double * | x | ||
) |
STATUS ksepi_diffusion_calcTE | ( | double * | TE_s, |
int | exciso2end, | ||
int | crsh1_half180, | ||
int | half180_crsh2, | ||
int | readout2echo, | ||
int | ramptime, | ||
float | G, | ||
int | bval_desired | ||
) |
Using a set of fixed times in the sequence as input arguments as well as the diffusion gradient amplitude and the desired b-value, this function calculates the echo time (TE) that will yield the desired b-value.
[out] | TE_s | TE [s] that will yield the correct b-value |
[in] | exciso2end | [us] RF excitation isocenter to end of exc rephaser |
[in] | crsh1_half180 | [us] left crusher start to RF isocenter of 1st/only 180 |
[in] | half180_crsh2 | [us] RF isocenter to end of right crusher of 1st/only 180 |
[in] | readout2echo | [us] time from readout to echo |
[in] | ramptime | [us] minimum ramp time |
[in] | G | [G/cm] diffusion gradient amplitude |
[in] | bval_desired | [s/mm^2] desired b-value |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_diffusion_eval_gradients_TE | ( | KSEPI_SEQUENCE * | epi, |
const KSDIFF_CONTROL * | diff_ctrl | ||
) |
This function evaluates the diffusion gradients and TE based on the KSDIFF_CONTROL struct diff_ctrl
and the KSEPI_SEQUENCE struct epi
.
[in,out] | epi | KSEPI_SEQUENCE struct |
[in] | diff_ctrl | KSDIFF_CONTROL struct, with used fields .max_magnitude_amp and .bvalue |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_eval_diffusion | ( | KSDIFF_CONTROL * | diff_ctrl | ) |
The KSDIFF_CONTROL_DESIGN struct is set up mostly by UI CVs on the Diffusion tab. This is then used by ksdiff_eval_design() to create the KSDIFF_CONTROL struct ksepi_diffctrl
, which is later used in ksepi_eval_setupobjects()->ksepi_diffusion_eval_gradients_TE() to control diffusion timing, gradients, and TE
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] | diff_ctrl | KSDIFF_CONTROL struct to be created |
STATUS | SUCCESS or FAILURE |
STATUS ksepi_diffusion_pg | ( | KSEPI_SEQUENCE * | epi, |
int | TE | ||
) |
STATUS | SUCCESS or FAILURE |
KS_SEQ_COLLECTION seqcollection |
float ksepi_excthickness = 0 |
float ksepi_gscalerfexc = 0.9 with {0.1, 3.0, 0.9, VIS, "Excitation slice thk scaling (< 1.0 thicker slice)",} |
int ksepi_slicecheck = 0 with {0, 1, 0, VIS, "move readout to z axis for slice thickness test",} |
float ksepi_spoilerarea = 3000.0 with {0.0, 10000.0, 3000.0, VIS, "ksepi ksepi.spoiler gradient area",} |
int ksepi_rfspoiling = 1 with {0, 1, 1, VIS, "Enable RF spoiling 1:on 0:off",} |
int ksepi_fse90 = 0 with {0, 1, 0, VIS, "Use FSE90 instead of SPSP for non-fatsat",} |
float ksepi_kissoff_factor = 0.04 with {0, 1, 0.04, VIS, "Slice oversampling fraction on each side (3D)",} |
float ksepi_rfstretch_exc = 1.0 with {0.1,10.0, 1.0, VIS, "RF excitation stretch factor"} |
int ksepi_fastexc3D = TRUE with {FALSE, TRUE, TRUE, VIS, "Sel. RF exc (3D) 0:EXC_SPSP_3D 1:EXC_FAST_SPSP_3D",} |
float ksepi_crusher_dephasing = 6.0 with { 0.0, 100.0, 6.0, VIS, "crusher dephasing over slice [cycles]",} |
float ksepi_gscalerfref = 0.9 with {0.1, 3.0, 0.9, VIS, "Refocusing slice thk scaling (< 1.0 thicker slice)",} |
float ksepi_rfstretch_ref = 1.0 with {0.1,10.0, 1.0, VIS, "RF refocusing stretch factor",} |
int ksepi_bridgecrushers = FALSE with {FALSE, TRUE, FALSE, VIS, "Bridge RF ref crushers",} |
int ksepi_t1value_to_null = T1_FAT_3T with {0, 5s, T1_FAT_3T, VIS, "T1 value to NULL [us]",} |
int ksepi_rampsampling = 1 with {0, 1, 1, VIS, "Rampsampling [0:OFF 1:ON]",} |
int ksepi_readlobegap = 0 with {0, 10ms, 0, VIS, "extra gap between readout lobes [us]",} |
int ksepi_echogap = 0 with {0, 100ms, 0, VIS, "extra gap between EPI echoes [us]",} |
int ksepi_readsign = 1 with { -1, 1, 1, VIS, "Readout polarity: +1/-1",} |
float ksepi_readampmax = 3.0 with {0.0, 5.0, 3.0, VIS, "Max grad amp for EPI readout lobes",} |
float ksepi_sr = 0.01 with {0.0, , 0.01, VIS, "EPI SR: amp/ramp [(G/cm) / us]",} |
int ksepi_esp = 0 with {0, 1000000, 0, VIS, "View-only: Echo spacing in [us]",} |
int ksepi_blipsign = KS_EPI_POSBLIPS with {KS_EPI_NEGBLIPS, KS_EPI_POSBLIPS, KS_EPI_POSBLIPS, VIS, "Blip polarity: +1/-1",} |
int ksepi_echotime_shifting = 1 with {0, 1, 1, VIS, "Enable echo time shifting for multi shot",} |
int ksepi_kynover = 24 with {KSEPI_MINHNOVER, 512, 24, VIS, "#extralines for MinTE",} |
int ksepi_kznover = 0 with {0, 512, 0, VIS, "#extralines in kz",} |
int ksepi_kz_nacslines = 8 with {0, 64, 8, VIS, "#acslines in kz",} |
int ksepi_caipi = 0 with {0, 512, 0, VIS, "CAIPIRINHA shift (affects 3D epi only. Set 0 for no CAIPI)",} |
int ksepi_readout_mode = KS_EPI_BIPOLAR with {KS_EPI_BIPOLAR, KS_EPI_FLYBACK, KS_EPI_BIPOLAR, VIS, "EPI readout mode 0: bipolar 1:splitoddeven 2:flyback",} |
int ksepi_fcy = 1 with {0, 1, 0, VIS, "Flowcomp Y when opfcomp"} |
int ksepi_fcz = 1 with {0, 1, 0, VIS, "Flowcomp Z when opfcomp"} |
int ksepi_fleet = 0 with {0, 1, 0, VIS, "FLEET calibration volume [0:OFF 1:ON]",} |
int ksepi_echotime_shifting_fleet = 1 with {0, 1, 1, VIS, "Enable echo time shifting for multi shot FLEET",} |
float ksepi_fleet_flip = 5.0 with {1.0, 90.0, 5.0, VIS, "FLEET flip angle [deg]",} |
int ksepi_fleet_dda = 3 with {1, 200, 3, VIS, "Dummies for FLEET module",} |
int ksepi_fleet_num_ky = 48 with {32, 256, 48, VIS, "Number of ky encodes for FLEET module",} |
int ksepi_fleet_readout_mode = KS_EPI_SPLITODDEVEN with {KS_EPI_BIPOLAR, KS_EPI_FLYBACK, KS_EPI_SPLITODDEVEN, VIS, "FLEET EPI readout mode 0: bipolar 1:splitoddeven 2:flyback",} |
int ksepi_fleet_nshots = 3 with {1, 128, 3, VIS, "# shots for FLEET",} |
int ksepi_reflines = 0 with {0, 96, 0, VIS, "Number of phase reference lines per shot",} |
int ksepi_swi_returnmode = 0 with {0, 7, 0, VIS, "SWI recon 0:Off 1:Acq 2:SWI 4:SWIphase",} |
int ksepi_pos_start = KS_RFSSP_PRETIME with {0, , KS_RFSSP_PRETIME, INVIS, "us from start until the first waveform begins",} |
int ksepi_ssi_time = KSEPI_DEFAULT_SSI_TIME with {32, , KSEPI_DEFAULT_SSI_TIME, VIS, "time from eos to ssi in intern trig",} |
int ksepi_dda = 1 with {1, 200, 1, VIS, "Number of dummy scans for steady state",} |
int ksepi_debug = 1 with {0, 100, 1, VIS, "Write out e.g. plot files (unless scan on HW)"} |
int ksepi_imsize = KS_IMSIZE_POW2 with {KS_IMSIZE_NATIVE, KS_IMSIZE_MIN256, KS_IMSIZE_POW2, VIS, "img. upsamp. [0:native 1:pow2 2:min256]"} |
int ksepi_abort_on_kserror = FALSE with {0, 1, 0, VIS, "Hard program abort on ks_error [0:OFF 1:ON]",} |
int ksepi_ref_nsegments = 1 with {1, 512, 1, VIS, "Number of kz segments in reference volume",} |
float ksepi_epiqfact = 1.0 with {1.0, 10.0, 1.0, VIS, "Quietness factor for the EPI readout only",} |
int ksepi_recvgain_mode = RG_CAL_MODE_HIGH_FIXED with {RG_CAL_MODE_MIN, RG_CAL_MODE_MAX, RG_CAL_MODE_HIGH_FIXED, VIS, "RecvGain - 0:Measured 1:8 2:5 3:Max",} |
int ksepi_metadump = 0 |
KSEPI_SEQUENCE ksepi = KSEPI_INIT_SEQUENCE |
Main EPI sequence (KSEPI_DATAGROUP_MAIN or KSEPI_DATAGROUP_MAIN_SPLITODDEVEN)
KSSCAN_LOOP_CONTROL ksepi_loopctrl = KSSCAN_INIT_LOOP_CONTROL |
Scan loop control for the ksepi
sequence (without inversion)
KSDIFF_CONTROL ksepi_diffctrl = KSDIFF_INIT_CONTROL |
KSEPI_FLEET_SEQUENCE ksepi_fleetseq = KSEPI_FLEET_INIT_SEQUENCE |
FLEET calibation sequence for parallel imaging (KSEPI_DATAGROUP_FLEET or KSEPI_DATAGROUP_FLEET_SPLITODDEVEN)
KSSCAN_LOOP_CONTROL ksepi_fleet_loopctrl = KSSCAN_INIT_LOOP_CONTROL |
Scan loop control for the FLEET sequence
KSINV_MODULE ksepi_inv = KSINV_INIT_MODULE |
Inversion module
KSINV_LOOP_CONTROL ksepi_inv_loopctrl = KSINV_INIT_LOOP_CONTROL |
Scan loop control when using main sequence + inversion module
KS_PHASEENCODING_COORD ksepi_phaseencoding_memorypool[KSEPI_PHASEENCODING_MEMORYPOOL_SIZE] = {KS_INIT_PHASEENCODING_COORD} |
int ksepi_interechotime = 0 |
float ksepi_echotime_shifting_shotdelay = 0.0 |
float ksepi_echotime_shifting_shotdelay_fleet = 0.0 |
int ksepi_echotime_shifting_sumdelay = 0 |
int ksepi_echotime_shifting_sumdelay_fleet = 0 |
KS_KSPACE_ACQ kacq = KS_INIT_KSPACE_ACQ |
int sequence_iopts[] |
int rfspoiling_phase_counter = 0 |
float ksepi_diffusion_amp_scale = 1.0 with {0.0, 1.0, 1.0, VIS, "Cap for scaling factor of diffusion gradient amplitude", } |
int ksepi_diffusion_heat_avg = 1 with {0, 1, 1, VIS, "Root mean sqared averaging diffusion amplitudes heat calculations", } |
float ksepi_diffusion_scaleX_heatcal = 1 with {0, 1, 1, VIS, "View-only: x diffusion gradient amplitude for heating calculations", } |
float ksepi_diffusion_scaleY_heatcal = 1 with {0, 1, 1, VIS, "View-only: y diffusion gradient amplitude for heating calculations", } |
float ksepi_diffusion_scaleZ_heatcal = 1 with {0, 1, 1, VIS, "View-only: z diffusion gradient amplitude for heating calculations", } |
int ksepi_diffusion_echotime = 0 with {0, , 0, VIS, "View-only: Echo time necessary to meet the desired b-value", } |
int ksepi_diffusion_returnmode = DIFFRETURN_ALL with {DIFFRETURN_ALL, 128, DIFFRETURN_ALL, VIS, "Diff maps All:0 Acq:1 b0:2 DWI:4 ADC:8 Exp:16 FA:32 cFA:64",} |
int ksepi_diffusion_minramptime = 1ms with {0, 20ms, 1ms, VIS, "Minimum diffusion ramp time. If 0: syslimits used",} |