Macros | |
#define | ABORT_ON_KSERROR 0 |
Functions | |
STATUS | acqq_longdab (WF_PULSE_ADDR pulse, LONG pos_ref, LONG dab_ref, LONG xtr_ref, LONG fslot_value) |
int | isNaN (float a) |
STATUS | ks_error (const char *format,...) |
void | ks_dbg_reset () |
STATUS | ks_dbg (const char *format,...) |
STATUS | existfile (const char *fname) |
int | ks_syslimits_hasICEhardware () |
float | ks_syslimits_ampmax_phys () |
float | ks_syslimits_ampmax (LOG_GRAD loggrd) |
float | ks_syslimits_ampmax2 (LOG_GRAD loggrd) |
float | ks_syslimits_ampmax1 (LOG_GRAD loggrd) |
float | ks_syslimits_ampmax1p (LOG_GRAD loggrd) |
float | ks_syslimits_gradtarget (LOG_GRAD loggrd, int board) |
int | ks_syslimits_ramptimemax (LOG_GRAD loggrd) |
int | ks_syslimits_ramptimemax_phys () |
float | ks_syslimits_slewrate_phys () |
float | ks_syslimits_slewrate (LOG_GRAD loggrd) |
float | ks_syslimits_slewrate2 (LOG_GRAD loggrd) |
float | ks_syslimits_slewrate1 (LOG_GRAD loggrd) |
float | ks_syslimits_slewrate1p (LOG_GRAD loggrd) |
short | ks_phase_radians2hw (float phase) |
short | ks_phase_degrees2hw (float phase) |
void | ks_polyval (const double *coeffs, const int order, const float x[], const int numx, float values[]) |
float | ks_calc_selgradamp (float rfbw, float slthick) |
float | ks_calc_minfov (float ampmax, int tsp) |
float | ks_calc_minslthick (float bw) |
int | ks_calc_mintsp (float ampmax, float fov) |
float | ks_calc_fov2gradareapixel (float fov) |
void | ks_phaseencoding_init_tgt (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr) |
KS_PHASEENCODING_COORD | ks_phaseencoding_get (const KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, int echo, int shot) |
void | ks_phaseencoding_set (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, int echo, int shot, int ky, int kz) |
void | ks_phaseencoding_print (const KS_PHASEENCODING_PLAN *phaseenc_plan_ptr) |
STATUS | ks_phaseencoding_resize (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, int etl, int num_shots) |
STATUS | ks_phaseencoding_generate_simple (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, const char *const desc, KS_PHASER *phaser, KS_PHASER *zphaser) |
STATUS | ks_phaseencoding_generate_simple_ellipse (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, const char *const desc, KS_PHASER *phaser, KS_PHASER *zphaser) |
STATUS | ks_fse_calcecho (double *bestecho, double *optecho, int *nacqlines_to_kspacecenter, KS_PHASER *pe, ks_enum_pf_earlylate_te pf_direction, int TE, int etl, int esp) |
STATUS | ks_phaseencoding_generate_2Dfse (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, const char *const desc, KS_PHASER *phaser, KS_PHASER *zphaser, ks_enum_pf_earlylate_te pf_direction, int TE, int etl, int esp) |
STATUS | ks_phaseencoding_generate_epi (KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, const char *const desc, const KS_EPI *epitrain, const ks_enum_epiblipsign blipsign, const ks_enum_pf_earlylate_te pf_direction, const int numileavestoacq, ks_enum_sweep_order sweep_order, int numsegments, const int caipi_delta) |
STATUS | ks_phaseencoding_generate_allepiplans (KS_PHASEENCODING_ALLEPIPLANS phaseenc_plans, const char *const desc, const KS_EPI *epitrain, const int caipi_delta) |
STATUS | ks_phaseencoding_allepiplans_setechoes (KS_PHASEENCODING_PLAN_16PTRS peplan_echoes, KS_PHASEENCODING_ALLEPIPLANS allepiplans, int nechoes, int multishot_flag, int min1stTE, int mirrorTE, ks_enum_epiblipsign blipsign) |
int | ks_wave_res (const KS_WAVE *wave) |
float | ks_waveform_max (const KS_WAVEFORM waveform, int res) |
float | ks_wave_max (const KS_WAVE *wave) |
float | ks_waveform_min (const KS_WAVEFORM waveform, int res) |
float | ks_wave_min (const KS_WAVE *wave) |
short | ks_iwave_absmax (const KS_IWAVE waveform, int res) |
float | ks_waveform_absmax (const KS_WAVEFORM waveform, int res) |
float | ks_wave_absmax (const KS_WAVE *wave) |
float | ks_waveform_maxslew (const KS_WAVEFORM waveform, int res, int duration) |
float | ks_wave_maxslew (const KS_WAVE *wave) |
float | ks_waveform_area (const KS_WAVEFORM waveform, int start, int end, int dwelltime) |
float | ks_wave_area (const KS_WAVE *wave, int start, int end) |
float | ks_waveform_sum (const KS_WAVEFORM waveform, int res) |
float | ks_wave_sum (const KS_WAVE *wave) |
float | ks_waveform_norm (const KS_WAVEFORM waveform, int res) |
float | ks_wave_norm (const KS_WAVE *wave) |
void | ks_waveform_cumsum (KS_WAVEFORM cumsumwaveform, const KS_WAVEFORM waveform, int res) |
void | ks_wave_cumsum (KS_WAVE *cumsumwave, const KS_WAVE *wave) |
void | ks_waveform_multiply (KS_WAVEFORM waveform_mod, const KS_WAVEFORM waveform, int res) |
void | ks_wave_multiply (KS_WAVE *wave_mod, const KS_WAVE *wave) |
void | ks_waveform_add (KS_WAVEFORM waveform_mod, const KS_WAVEFORM waveform, int res) |
void | ks_wave_add (KS_WAVE *wave_mod, const KS_WAVE *wave) |
void | ks_waveform_multiplyval (KS_WAVEFORM waveform, float val, int res) |
void | ks_wave_multiplyval (KS_WAVE *wave, float val) |
void | ks_waveform_addval (KS_WAVEFORM waveform, float val, int res) |
void | ks_wave_addval (KS_WAVE *wave, float val) |
STATUS | ks_waveform2iwave (KS_IWAVE iwave, const KS_WAVEFORM waveform, int res, int board) |
STATUS | ks_wave2iwave (KS_IWAVE iwave, const KS_WAVE *wave, int board) |
WF_PULSE * | ks_pg_echossp (WF_PULSE *echo, const char *suffix) |
STATUS | ks_pg_trap (KS_TRAP *trap, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_phaser (KS_PHASER *phaser, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_read (KS_READ *read, int pos, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_readtrap (KS_READTRAP *readtrap, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_wave (KS_WAVE *wave, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_rf (KS_RF *rf, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_selrf (KS_SELRF *selrf, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_wait (KS_WAIT *wait, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_isirot (KS_ISIROT *isirot, SCAN_INFO scan_info, int pos, void(*rotfun)(), KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_epi_dephasers (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_epi_rephasers (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_epi_echo (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
STATUS | ks_pg_epi (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) |
void | ks_pg_mod_fse_rfpulse_structs (KS_SELRF *rf1, KS_SELRF *rf2, KS_SELRF *rf3, const double *flip_angles, const int etl) |
STATUS | ks_pg_fse_flip_angle_taperoff (double *flip_angles, int etl, double flip1, double flip2, double flip3, double target_flip, int start_middle) |
void | ks_instancereset_trap (KS_TRAP *trap) |
void | ks_instancereset_wave (KS_WAVE *wave) |
void | ks_instancereset_wait (KS_WAIT *wait) |
void | ks_instancereset_phaser (KS_PHASER *phaser) |
void | ks_instancereset_readtrap (KS_READTRAP *read) |
void | ks_instancereset_rf (KS_RF *rf) |
void | ks_instancereset_selrf (KS_SELRF *selrf) |
void | ks_instancereset_epi (KS_EPI *epi) |
void | ks_mat4_zero (KS_MAT4x4 m) |
void | ks_mat4_identity (KS_MAT4x4 m) |
void | ks_mat4_print (const KS_MAT4x4 m) |
void | ks_mat4_multiply (KS_MAT4x4 lhs, const KS_MAT4x4 rhs_left, const KS_MAT4x4 rhs_right) |
void | ks_mat4_invert (KS_MAT4x4 lhs, const KS_MAT4x4 rhs) |
void | ks_mat4_setgeometry (KS_MAT4x4 lhs, float x, float y, float z, float xr, float yr, float zr) |
void | ks_mat4_setrotation1axis (KS_MAT4x4 rhs, float rot, char axis) |
void | ks_mat4_extractrotation (KS_MAT3x3 R, const KS_MAT4x4 M) |
void | ks_mat4_extracttranslation (double *T, const KS_MAT4x4 M) |
void | ks_mat3_identity (KS_MAT3x3 m) |
void | ks_mat3_multiply (KS_MAT3x3 lhs, const KS_MAT3x3 rhs_left, const KS_MAT3x3 rhs_right) |
void | ks_mat3_print (const KS_MAT3x3 m) |
void | ks_mat3_apply (double *w, const KS_MAT3x3 R, const double *v) |
void | ks_mat3_invapply (double *w, const KS_MAT3x3 R, const double *v) |
void | ks_scan_update_slice_location (SCAN_INFO *new_loc, const SCAN_INFO orig_loc, const KS_MAT4x4 M_physical, const KS_MAT4x4 M_logical) |
int | ks_compare_wfi_by_timeboard (const KS_WFINSTANCE *a, const KS_WFINSTANCE *b) |
int | ks_compare_wfi_by_boardtime (const KS_WFINSTANCE *a, const KS_WFINSTANCE *b) |
int | ks_compare_wfp_by_time (const WF_PULSE *a, const WF_PULSE *b) |
void | ks_sort_wfi_by_timeboard (KS_WFINSTANCE *a, int nitems) |
void | ks_sort_wfi_by_boardtime (KS_WFINSTANCE *a, int nitems) |
void | ks_sort_wfp_by_time (WF_PULSE *a, int nitems) |
int | ks_compare_pshort (const void *v1, const void *v2) |
int | ks_compare_pint (const void *v1, const void *v2) |
int | ks_compare_pfloat (const void *v1, const void *v2) |
int | ks_compare_short (const void *v1, const void *v2) |
int | ks_compare_int (const void *v1, const void *v2) |
int | ks_compare_float (const void *v1, const void *v2) |
void | ks_sort_getsortedindx (int *sortedindx, int *array, int n) |
void | ks_sort_getsortedindx_s (int *sortedindx, short *array, int n) |
void | ks_sort_getsortedindx_f (int *sortedindx, float *array, int n) |
void | ks_plot_slicetime_begin () |
void | ks_plot_slicetime (KS_SEQ_CONTROL *ctrl, int nslices, float *slicepos_mm, float slthick_mm, KS_PLOT_EXCITATION_MODE excmode) |
void | ks_plot_slicetime_endofpass (KS_PLOT_PASS_MODE pass_mode) |
void | ks_plot_slicetime_endofslicegroup_tagged (const char *desc, const KS_PLOT_SLICEGROUP_MODE tag) |
void | ks_plot_slicetime_endofslicegroup (const char *desc) |
void | ks_plot_slicetime_end () |
void | ks_plot_tgt_reset (KS_SEQ_CONTROL *ctrl) |
void | ks_plot_tgt_addframe (KS_SEQ_CONTROL *ctrl) |
STATUS | ks_eval_addtraptogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_TRAP *trap) |
STATUS | ks_eval_addwavetogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_WAVE *wave) |
STATUS | ks_eval_addrftogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_RF *rf) |
STATUS | ks_eval_addreadtogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_READ *read) |
float | ks_scan_rf_phase_spoiling (int counter) |
Variables | |
int | maxGradRes |
int | cfswgut |
int | cfswrfut |
int | psd_rf_wait |
int | psd_grd_wait |
float | GAM |
int | cfssctype |
float | opfov |
int | opxres |
int | opyres |
float | opslthick |
int | rhkacq_uid |
int | ks_plot_filefmt |
char | ks_psdname [256] |
int | abort_on_kserror = ABORT_ON_KSERROR |
int | ks_rhoboard = TYPRHO1 |
This file contains functions accessible on both HOST and TGT.
#define ABORT_ON_KSERROR 0 |
STATUS acqq_longdab | ( | WF_PULSE_ADDR | pulse, |
LONG | pos_ref, | ||
LONG | dab_ref, | ||
LONG | xtr_ref, | ||
LONG | fslot_value | ||
) |
STATUS ks_error | ( | const char * | format, |
... | |||
) |
void ks_dbg_reset | ( | ) |
STATUS ks_dbg | ( | const char * | format, |
... | |||
) |
STATUS existfile | ( | const char * | fname | ) |
int ks_syslimits_hasICEhardware | ( | ) |
float ks_syslimits_ampmax_phys | ( | ) |
All phase values in KSFoundation are in [degrees], including flip angles, RF/receive phases and THETA waveforms. This function is therefore currently not used. See instead ks_phase_degrees2hw()
[in] | radphase | Phase in radians |
intphase | Integer phase to use on THETA board on hardware |
float ks_syslimits_ampmax | ( | LOG_GRAD | loggrd | ) |
Since the waveform design (using ks_eval_***()
functions) is separated from the placement of waveforms (using ks_pg_***()
functions), the maximum gradient limit to use for gradient design must account for the least capable gradient board given the current slice angulation. ks_syslimits_ampmax() assumes that all gradients may be on simultaneously
The return value from this function can be passed in as ampmax
to all ks_eval***_constrained()
functions
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
gradmax | Maximum gradient amplitude ([G/cm]) that can be used on all boards simultaneously |
float ks_syslimits_ampmax2 | ( | LOG_GRAD | loggrd | ) |
Since the waveform design (using ks_eval_***()
functions) is separated from the placement of waveforms (using ks_pg_***()
functions), the maximum gradient limit to use for gradient design must account for the least capable gradient board given the current slice angulation. ks_syslimits_ampmax2() assumes that gradients are played out on at most one more board at the same time as the current trapezoid
The return value from this function can be passed in as ampmax
to all ks_eval***_constrained()
functions
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
gradmax | Maximum gradient amplitude ([G/cm]) that can be used on 2 boards simultaneously |
float ks_syslimits_ampmax1 | ( | LOG_GRAD | loggrd | ) |
Since the waveform design (using ks_eval_***()
functions) is separated from the placement of waveforms (using ks_pg_***()
functions), the maximum gradient limit to use for gradient design must account for the least capable gradient board given the current slice angulation. ks_syslimits_ampmax1() assumes that no other gradient is played out on another board at the same time as the current trapezoid
The return value from this function can be passed in as ampmax
to all ks_eval***_constrained()
functions
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
gradmax | Maximum gradient amplitude ([G/cm]) that can be used on one board at a time |
float ks_syslimits_ampmax1p | ( | LOG_GRAD | loggrd | ) |
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
gradmax | Maximum gradient amplitude ([G/cm]) as defined by the physical gradients (lowest of physical X, Y, Z) |
float ks_syslimits_gradtarget | ( | LOG_GRAD | loggrd, |
int | board | ||
) |
For gradient boards, the field .tx
, .ty
or .tz
is returned. For non-gradient boards, 1.0 is returned. This function is used internally by ks_pg_***()
functions and there should be no need to call it directly.
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
[in] | board | The board on which the current trapezoid or waveform is to be played out on |
gradamp | Maximum target amplitude for a board |
int ks_syslimits_ramptimemax | ( | LOG_GRAD | loggrd | ) |
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
ramptime | Ramptime in [us] to get from zero to full gradient scale |
int ks_syslimits_ramptimemax_phys | ( | ) |
float ks_syslimits_slewrate_phys | ( | ) |
float ks_syslimits_slewrate | ( | LOG_GRAD | loggrd | ) |
The return value from this function is the ratio of ks_syslimits_ampmax() and ks_syslimits_ramptimemax() and can be passed in as slewrate
to all ks_eval***_constrained()
functions
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
slewrate | Maximum slewrate ([(G/cm) / us]) that can be used on all boards simultaneously |
float ks_syslimits_slewrate2 | ( | LOG_GRAD | loggrd | ) |
The return value from this function is the ratio of ks_syslimits_ampmax2() and ks_syslimits_ramptimemax() and can be passed in as slewrate
to all ks_eval***_constrained()
functions
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
slewrate | Maximum slewrate ([(G/cm) / us]) that can be used on all boards simultaneously |
float ks_syslimits_slewrate1 | ( | LOG_GRAD | loggrd | ) |
The return value from this function is the ratio of ks_syslimits_ampmax1() and ks_syslimits_ramptimemax() and can be passed in as slewrate
to all ks_eval***_constrained()
functions
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
slewrate | Maximum slewrate ([(G/cm) / us]) that can be used on one board at at time |
float ks_syslimits_slewrate1p | ( | LOG_GRAD | loggrd | ) |
[in] | loggrd | GE's LOG_GRAD struct, dependent on the gradient system and current slice angulation |
gradmax | Maximum slewrate ([(G/cm) / us]) that can be used on one board at at time as defined by the physical gradients (lowest of physical X, Y, Z) |
short ks_phase_radians2hw | ( | float | phase | ) |
short ks_phase_degrees2hw | ( | float | degphase | ) |
All phase values in KSFoundation are in [degrees], including flip angles, RF/receive phases and THETA waveforms. This function is used internally by another internal function ks_wave2iwave(), which is in turn called by ks_pg_wave()
[in] | degphase | Phase in degrees |
intphase | Integer phase to use on THETA board on hardware |
void ks_polyval | ( | const double * | coeffs, |
const int | order, | ||
const float | x[], | ||
const int | numx, | ||
float | values[] | ||
) |
float ks_calc_selgradamp | ( | float | rfbw, |
float | slthick | ||
) |
Given an RF bandwidth in [Hz] and a slice thickness in [mm], this function calculates the gradient strength in [G/cm] necessary to produce a slice with the given slice thickness
This function is used by ks_eval_seltrap(), ks_eval_selrf_constrained() and ks_scan_selrf_setfreqphase()
[in] | rfbw | The bandwidth of the RF pulse to use with the gradient |
[in] | slthick | The desired slice thickness in [mm] |
gradamp | Gradient amplitude to use [G/cm] |
float ks_calc_minfov | ( | float | ampmax, |
int | tsp | ||
) |
Given a maximum allowed gradient amplitude in [G/cm] and a dwell time in [us] (see ks_calc_bw2tsp()), the minimum possible readout FOV in [mm] is calculated. This function is called internally by ks_eval_readtrap_constrained() when rampsampling is not used (.rampsampling = 0
)
[in] | ampmax | The maximum allowed gradient amplitude ([G/cm]) |
[in] | tsp | Duration in [us] for each data sample in the acquisition window. Minimum: 2 [us] |
minFOV | Minimum FOV in the readout direction |
float ks_calc_minslthick | ( | float | bw | ) |
Given an RF bandwidth in [kHz], this function returns the minimum slice thickness possible given the gradient max amplitude.
[in] | bw | RF bandwidth in [kHz] |
minSliceThickness | Minimum slice thickness in [mm] |
int ks_calc_mintsp | ( | float | ampmax, |
float | fov | ||
) |
Given a maximum allowed gradient amplitude in [G/cm] and a readout FOV in [mm], the smallest dwell time (i.e. largest rBW) in [us] is calculated.
[in] | ampmax | The maximum allowed gradient amplitude ([G/cm]) |
[in] | fov | FOV in the readout direction |
tsp | Duration in [us] for each data sample in the acquisition window |
float ks_calc_fov2gradareapixel | ( | float | fov | ) |
Given a readout FOV in [mm], the gradient area needed to move one pixel in a fully sampled k-space is calculated
[in] | fov | FOV in the readout direction |
area | Gradient area in [(G/cm) * us] |
void ks_phaseencoding_init_tgt | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr | ) |
[in] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
KS_PHASEENCODING_COORD ks_phaseencoding_get | ( | const KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
int | echo, | ||
int | shot | ||
) |
If the .ky and .kz values returned by this function is = KS_NOTSET (-1), it indicates that this echo/shot combination should have zero phase encoding and should be ignored. For 2D, .kz will always be KS_NOTSET
[in] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
[in] | echo | Echo index in the sequence ETL in range [0,ETL-1] |
[in] | shot | Shot index (i.e. how many times the sequence is played out per slice). For 3D, this is the combined number of shots over ky and kz |
<tt>KS_PHASEENCODING_COORD</tt> |
void ks_phaseencoding_set | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
int | echo, | ||
int | shot, | ||
int | ky, | ||
int | kz | ||
) |
If the .ky and .kz values passed to this function is = KS_NOTSET (-1), it indicates that this echo/shot combination should have zero phase encoding and should be ignored. However, ignored echo/shot combinations are not necessary since the etl*num_shots entries in .entries
of KS_PHASEENCODING_PLAN are always initialized to KS_NOTSET by ks_phaseencoding_resize(). Hence, it is only necessary to explicitly set the echo/shot combination for ky/kz coordinates being acquired.
For 2D, kz (5th arg) should always be KS_NOTSET.
[in] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
[in] | echo | Echo index in the sequence ETL in range [0,ETL-1] |
[in] | shot | Shot index (in range [0,how many times the sequence is played out per slice - 1]). For 3D, this is the combined number of shots over ky and kz |
[in] | ky | K-space coordinate along the first (only for 2D) phase encoding direction (integer) in range [0, phaser.numlinestoacq-1] |
[in] | kz | K-space coordinate along the second (use KS_NOTSET for 2D) phase encoding direction (integer) in range [0, zphaser.numlinestoacq-1] |
void ks_phaseencoding_print | ( | const KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr | ) |
In SIM (WTools), a file ks_phaseencodingtable.txt will be generated in the current directory On HW (MR scanner), the same file will be located in /usr/g/mrraw
[in] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
STATUS ks_phaseencoding_resize | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
int | etl, | ||
int | num_shots | ||
) |
For every (and custom) ks_phaseencoding_generate_** functions, this function must be called before ks_phaseencoding_set() so that there is memory allocataed for the array of KS_PHASEENCODING_COORD
[in] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
[in] | etl | The number of acquisition window in the pulse sequence, or echo train length (ETL) |
[in] | num_shots | Number of shots (i.e. how many times the sequence is played out per slice). For 3D, shot is over both ky and kz |
STATUS ks_phaseencoding_generate_simple | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
const char *const | desc, | ||
KS_PHASER * | phaser, | ||
KS_PHASER * | zphaser | ||
) |
For sequences having only one echo (ETL=1) or having more echoes but where all echoes have the same ky/kz coordinate, there is no special logic necessary regarding which order to traverse the ky-kz plane over shots.
Parallel imaging in ky (and kz for 3D), with acs lines, is set up as usual using ks_eval_phaser() first before calling this function. For 2D, the phase encoding object (KS_PHASER) is then passed in as the 2nd arg to this function, with the 3rd arg being NULL
. For 3D, both KS_PHASERs are passed in as 2nd and 3rd args, each with their own acceleration and resolution. For both 2D and 3D, the KS_PHASEENCODING_PLAN will be set up based on the KS_PHASER(s), but for 2D all entries.kz in the KS_PHASEENCODING_PLAN will be KS_NOTSET (-1)
[out] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
[in] | desc | A description (text string) of the KS_PHASEENCODING_PLAN object. This description is used in the psd plot. |
[in] | phaser | Pointer to the KS_PHASER object for the first (3D) / only (2D) phase encoding direction |
[in] | zphaser | Pointer to the KS_PHASER object for the second phase encoding direction (NULL for 2D) |
STATUS ks_phaseencoding_generate_simple_ellipse | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
const char *const | desc, | ||
KS_PHASER * | phaser, | ||
KS_PHASER * | zphaser | ||
) |
For sequences having only one echo (ETL=1) or having more echoes but where all echoes have the same ky/kz coordinate, there is no special logic necessary regarding which order to traverse the ky-kz plane over shots.
Parallel imaging in ky (and kz for 3D), with acs lines, is set up as usual using ks_eval_phaser() first before calling this function. For 2D, the phase encoding object (KS_PHASER) is then passed in as the 2nd arg to this function, with the 3rd arg being NULL
. For 3D, both KS_PHASERs are passed in as 2nd and 3rd args, each with their own acceleration and resolution. For both 2D and 3D, the KS_PHASEENCODING_PLAN will be set up based on the KS_PHASER(s), but for 2D all entries.kz in the KS_PHASEENCODING_PLAN will be KS_NOTSET (-1). This function will create an elliptical k-space in ky/kz. For rectangular k-space, use ks_phaseencoding_generate_simple
.
[out] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
[in] | desc | A description (text string) of the KS_PHASEENCODING_PLAN object. This description is used in the psd plot. |
[in] | phaser | Pointer to the KS_PHASER object for the first (3D) / only (2D) phase encoding direction |
[in] | zphaser | Pointer to the KS_PHASER object for the second phase encoding direction (NULL for 2D) |
STATUS ks_fse_calcecho | ( | double * | bestecho, |
double * | optecho, | ||
int * | nacqlines_to_kspacecenter, | ||
KS_PHASER * | pe, | ||
ks_enum_pf_earlylate_te | pf_direction, | ||
int | TE, | ||
int | etl, | ||
int | esp | ||
) |
Given the KS_PHASER object used in the FSE train (containing res and partial ky Fourier info), the desired effective echo time (TE
[us]), the echo train length (etl
) and the echo spacing between consecutive echoes (esp
[us]), this function calculates two echo indices:
bestecho
: is the 0-based index corresponding to the echo in the FSE train that should be placed in the center of k-space, i.e. the echo that most closely matches the desired TE. If bestecho
is an integer value (although it is in double format), the data acquired for this echo should straddle the k-space center. bestecho
can also be an interger + 0.5, indicating that there are two echo indices that should be placed around the k-space center. For example, floor(bestecho) corresponds to the echo index that should be placed just below the k-space center and ceil(bestecho) corresponds to the echo index that should be placed just above the k-space center. I.e. when bestecho = *.5
, no single echo index will straddle the k-space center, and the k-space line located at ky position +0.5 will come from data acquired from echo #[floor(bestecho)] and ky position -0.5 correspondingly from echo #[ceil(bestecho)].optecho
: is the 0-based index corresponding to an ideal TE choice that would allow the data from the echoes in the FSE train to be placed out linearly each time. Doing so will reduce ghosting and T2 blurring. Hence, optecho
ignores the input TE value here, but the calling function can use this information to determine k-space acquisition order, but also to suggest a TE (optecho * esp) that would result in optimal image quality for the chosen ETL.[out] | bestecho | Pointer to the echo number in the train that should be placed at the center of k-space given the current ETL and ESP |
[out] | optecho | Pointer to the optimal echo number in the train that would allow k-space to be sampled linearly (to reduce T2-blurring and ghosting) |
[out] | nacqlines_to_kspacecenter | Pointer to a an integer with the number of k-space lines until center |
[in] | pe | Pointer to a KS_PHASER |
[in] | pf_direction | Should be either KS_PF_EARLY_TE or KS_PF_LATE_TE (applies to partial Fourier in ky to set if k-space center should be acquired early or late in the EPI train. Has no effect for full ky Fourier) |
[in] | TE | (Echo Time in [us]) |
[in] | etl | (EchoTrain Length) |
[in] | esp | (Echo Spacing in [us]) |
STATUS | SUCCESS or FAILURE |
STATUS ks_phaseencoding_generate_2Dfse | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
const char *const | desc, | ||
KS_PHASER * | phaser, | ||
KS_PHASER * | zphaser, | ||
ks_enum_pf_earlylate_te | pf_direction, | ||
int | TE, | ||
int | etl, | ||
int | esp | ||
) |
This function is only executed on TGT and will return early when called on HOST.
The phase encoding sorting is depending on many factors. First, the desired TE will dictate which one (or two) of the echoes in the FSE train (of length etl
) that should be placed in the center. This is determined based on the properties of the KS_PHASER object (phase encoding gradients in the FSE train), TE
and esp
by calling ksfse_calc_echo().
Second, the sorting of the echoes will first of all depend on whether bestecho
is equal to optecho
. If it is, then the etl
echoes can be placed out linearly in k-space (from the bottom->top of k-space, or vice versa). This will produce the best image quality with minimal T2-blurring and FSE ghosting.
As partial ky Fourier is allowed, this function first checks on which side (top or bottom half) of k-space that has more room for the echo indices that are either before or after the bestecho
index corresponding to the desired TE
. The goal with this is to try to sweep k-space as linearly as possible in as much of the center portion of k-space as possible when bestecho != optecho
.
When bestecho != optecho
, there will be data from either the first or last echo indices that won't fit in k-space if placed next to a neighboring index. If this data would be placed on the other size of k-space (that still needs lines to be filled in), where e.g. echo index #0 would be placed next to echo index #(etl-1), strong ghosting will occur due to the much strong signal from echo #0 compared to #(etl-1). With an echo train length of etl
, k-space is filled in numshots = ceil(numlinestoacq / etl
. Using half of the numshots lines for each echo index a linear sweep of the center half of k-space can is layed out. To avoid FSE ghosting, the numshots/2 remaining lines for each early or late echo index are placed such as neighboring ky lines will never have a change in echo index by more than one. For example if etl = 8
, esp = 10 ms
and TE = 25
, then bestecho = 1.5
and optecho = 4.5
. We avoid to sort the echoes in the following k-space order for ghosting reasons: 7-6-0-1*2-3-4-5 (* = k-space center) since there will be a strong discontinuity between 6 and 0. Instead we use groups of numshots/2 per echo index (and get two groups per echo index in k-space): 5-4-3-2-1-0-0-1*2-3-4-5-6-7-6-5
[out] | phaseenc_plan_ptr | Pointer to KS_PHASEENCODING_PLAN |
[in] | desc | A description (text string) of the KS_PHASEENCODING_PLAN object. This description is used in the psd plot. |
[in] | phaser | Pointer to a KS_PHASER |
[in] | zphaser | Pointer to a KS_PHASER (3D) or NULL (2D) |
[in] | pf_direction | Should be either KS_PF_EARLY_TE or KS_PF_LATE_TE (applies to partial Fourier in ky to set if k-space center should be acquired early or late in the EPI train. Has no effect for full ky Fourier) |
[in] | TE | (Echo Time in [us]) |
[in] | etl | (EchoTrain Length) |
[in] | esp | (Echo Spacing in [us]) |
STATUS | SUCCESS or FAILURE |
Grouping shots for each of the ETL echoes in k-space: We don't place all shots for each echo together in k-space since we need to make a z-shaped pattern to avoid ghosting. Instead we let half of the shots be one group (of size 'cgroupsize') that we place in the central ~50% of k-space, which allows us to get a linear sweep in this central half of k-space using all 'etl' echoes, regardless of the chosen effective TE. The actual center-ness depends on TE, and the remaining of k-space is filled using the echoes belonging to the latter 'numshots-cgroupsize' number of shots. At the edges of k-space, numshots*etl seldom match up to the chosen opyres, but numshots*etl is always >= opyres thanks to the CEIL_DIV at the beginning of this function. The surplus echoes we don't need are numshots*etl - opyres (for full Fourier and no ARC), and as they are already tagged as -1 = KS_NOTSET in the beginning of this function, they will be placed in baseline view (0) in the ksfse_scan_acqloop()
STATUS ks_phaseencoding_generate_epi | ( | KS_PHASEENCODING_PLAN * | phaseenc_plan_ptr, |
const char *const | desc, | ||
const KS_EPI * | epitrain, | ||
const ks_enum_epiblipsign | blipsign, | ||
const ks_enum_pf_earlylate_te | pf_direction, | ||
const int | numileavestoacq, | ||
ks_enum_sweep_order | sweep_order, | ||
int | numsegments, | ||
const int | caipi_delta | ||
) |
The etl is the number of readouts in the EPI train, derived from the phaser. The number of ky shots is also given by the phaser, while the number of kz shots is given by zphaser. Any partial fourier is handled by the phasers, and acceleration and acs lines in the z direction is handled by zphaser. For 3D EPI, the number of shots in the phase encoding plan will be the product of the number of shots in the ky direction and the number of kz lines to acquire.
Each shot will be played out in a single kz plane. The shot order will be linear in ky and kz. The ky shots will be in the inner loop, unless kzshotsfirst is TRUE.
[out] | phaseenc_plan_ptr | Pointer to the phase encoding plan |
[in] | desc | A description (text string) of the KS_PHASEENCODING_PLAN object. This description is used in the psd plot. |
[in] | epitrain | Pointer to a KS_EPI |
[in] | blipsign | Should be either KS_EPI_POSBLIPS or KS_EPI_NEGBLIPS . Determines distortion direction. |
[in] | pf_direction | Should be either KS_PF_EARLY_TE or KS_PF_LATE_TE (applies to partial Fourier in ky to set if k-space center should be acquired early or late in the EPI train. Has no effect for full ky Fourier) |
[in] | numileavestoacq | Number of ky interleaves to play. Must be within 1-numInterleaves and an integer factor of numInterleaves. Set =1 for single-shot EPI. Set to phaser.R for full multi-shot EPI. |
[in] | sweep_order | Sweep order for shots as defined in KSFoundation.h (ks_enum_sweep_order). Has no effect on distortions. |
[in] | numsegments | Number of kz encodes to play |
[in] | caipi_delta | Use CAIPIRINHA sampling pattern (affects 3D epi only) |
STATUS | SUCCESS or FAILURE |
STATUS ks_phaseencoding_generate_allepiplans | ( | KS_PHASEENCODING_ALLEPIPLANS | phaseenc_plans, |
const char *const | desc, | ||
const KS_EPI * | epitrain, | ||
const int | caipi_delta | ||
) |
[out] | phaseenc_plans | Pointer to the phase encoding plan array (KS_PHASEENCODING_ALLEPIPLANS containing KS_EPI_PEPLAN_NUMPLANS elements) |
[in] | desc | A description (text string) of the KS_PHASEENCODING_PLAN object. This description is used in the psd plot. |
[in] | epitrain | Pointer to a KS_EPI |
[in] | caipi_delta | Use CAIPIRINHA sampling pattern (affects 3D epi only) |
STATUS | SUCCESS or FAILURE |
STATUS ks_phaseencoding_allepiplans_setechoes | ( | KS_PHASEENCODING_PLAN_16PTRS | peplan_echoes, |
KS_PHASEENCODING_ALLEPIPLANS | allepiplans, | ||
int | nechoes, | ||
int | multishot_flag, | ||
int | min1stTE, | ||
int | mirrorTE, | ||
ks_enum_epiblipsign | blipsign | ||
) |
[out] | peplan_echoes | Pointers to the phase encoding plan array to use for each EPI train in the sequence (max 16 EPI trains per sequence playout) |
[in] | allepiplans | All possible EPI plans for current EPI train (with given read.res and blipphaser.res/.nover) |
[in] | nechoes | Number of EPI train (echoes) in sequence (max 16) |
[in] | multishot_flag | Multishot EPI or underampled EPI (both controlled by epitrain.blipphaser.R) |
[in] | min1stTE | For partial ky Fourier (.blipphaser.nover > 0), should 1st EPI train pass k-space center early or late. Has no effect for full ky Fourier |
[in] | mirrorTE | Should lateTE/earlyTE alternate between EPI trains (as when an RF refocusing pulse is placed in-between trains) |
[in] | blipsign | Positive (KS_EPI_POSBLIPS) or negative (KS_EPI_NEGBLIPS) to control k-space direction and hence the geometric distortion direction |
STATUS | SUCCESS or FAILURE |
int ks_wave_res | ( | const KS_WAVE * | wave | ) |
[in] | wave | KS_WAVE object |
res | Resolution (i.e. number of samples) in the KS_WAVE object |
float ks_waveform_max | ( | const KS_WAVEFORM | waveform, |
int | res | ||
) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
maxval | Maximum value |
float ks_wave_max | ( | const KS_WAVE * | wave | ) |
float ks_waveform_min | ( | const KS_WAVEFORM | waveform, |
int | res | ||
) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
minval | Minimum value |
float ks_wave_min | ( | const KS_WAVE * | wave | ) |
short ks_iwave_absmax | ( | const KS_IWAVE | waveform, |
int | res | ||
) |
[in] | waveform | KS_WAVE object |
[in] | res | Check up to this many samples |
maximum | amplitude of the waveform |
float ks_waveform_absmax | ( | const KS_WAVEFORM | waveform, |
int | res | ||
) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
absmaxval | Maximum absolute value |
float ks_wave_absmax | ( | const KS_WAVE * | wave | ) |
float ks_waveform_maxslew | ( | const KS_WAVEFORM | waveform, |
int | res, | ||
int | duration | ||
) |
[in] | waveform | KS_WAVEFORM |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
[in] | duration | Duration of the waveform in us |
absmaxval | Maximum absolute value |
float ks_wave_maxslew | ( | const KS_WAVE * | wave | ) |
float ks_waveform_area | ( | const KS_WAVEFORM | waveform, |
int | start, | ||
int | end, | ||
int | dwelltime | ||
) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | start | [us] Start position of area calculation in [us] (0 = start of waveform) |
[in] | end | [us] End position of area calculation in [us] (res * dwelltime = end of waveform) |
[in] | dwelltime | [us] of each waveform point (duration/res) |
area | The area of the KS_WAVEFORM over the specified interval in [(G/cm) * us] |
float ks_wave_area | ( | const KS_WAVE * | wave, |
int | start, | ||
int | end | ||
) |
[in] | wave | KS_WAVE object |
[in] | start | [us] Start position of area calculation in [us] (0 = start of waveform) |
[in] | end | [us] End position of area calculation in us |
area | The area of the KS_WAVE object over the specified interval in [(G/cm) * us] |
float ks_waveform_sum | ( | const KS_WAVEFORM | waveform, |
int | res | ||
) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
sum | The sum of the KS_WAVEFORM |
float ks_wave_sum | ( | const KS_WAVE * | wave | ) |
float ks_waveform_norm | ( | const KS_WAVEFORM | waveform, |
int | res | ||
) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
norm2 | The 2-norm of a KS_WAVEFORM |
float ks_wave_norm | ( | const KS_WAVE * | wave | ) |
void ks_waveform_cumsum | ( | KS_WAVEFORM | cumsumwaveform, |
const KS_WAVEFORM | waveform, | ||
int | res | ||
) |
[out] | cumsumwaveform | KS_WAVEFORM (float array) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
void ks_waveform_multiply | ( | KS_WAVEFORM | waveform_mod, |
const KS_WAVEFORM | waveform, | ||
int | res | ||
) |
Multiplication of waveform a
(arg 1) with waveform b
(arg 2) as: a *= b
[in,out] | waveform_mod | KS_WAVE object |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
Multiplication of waveform a
(arg 1) with waveform b
(arg 2) as: a *= b
If the duration of the two KS_WAVE objects have different resolution, the shorter KS_WAVE will be multiplied with the first part of the longer KS_WAVE
void ks_waveform_add | ( | KS_WAVEFORM | waveform_mod, |
const KS_WAVEFORM | waveform, | ||
int | res | ||
) |
Addition of waveform a
(arg 1) with waveform b
(arg 2) as: a += b
[in,out] | waveform_mod | KS_WAVEFORM (float array) |
[in] | waveform | KS_WAVEFORM (float array) |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
Addition of waveform a
(arg 1) with waveform b
(arg 2) as: a *= b
If the duration of the two KS_WAVE objects have different resolution, the shorter KS_WAVE will be added to the first part of the longer KS_WAVE
void ks_waveform_multiplyval | ( | KS_WAVEFORM | waveform, |
float | val, | ||
int | res | ||
) |
The values in a KS_WAVEFORM are multiplied with a scalar value val
[in,out] | waveform | KS_WAVEFORM (float array) |
[in] | val | Floating point value to multiply with |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
void ks_wave_multiplyval | ( | KS_WAVE * | wave, |
float | val | ||
) |
The waveform values in a KS_WAVE sequence object (.waveform[]
) are multiplied with a scalar value val
[in,out] | wave | KS_WAVE object |
[in] | val | Floating point value to multiply with |
void ks_waveform_addval | ( | KS_WAVEFORM | waveform, |
float | val, | ||
int | res | ||
) |
The values in a KS_WAVEFORM are added with a scalar value val
[in,out] | waveform | KS_WAVEFORM (float array) |
[in] | val | Floating point value to add |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
void ks_wave_addval | ( | KS_WAVE * | wave, |
float | val | ||
) |
The waveform values in a KS_WAVE sequence object (.waveform[]
) are added with a scalar value val
[in,out] | wave | KS_WAVE object |
[in] | val | Floating point value to add |
STATUS ks_waveform2iwave | ( | KS_IWAVE | iwave, |
const KS_WAVEFORM | waveform, | ||
int | res, | ||
int | board | ||
) |
This function is used internally by ks_pg_wave() and there should be no need to call this function directly.
For all boards except THETA, this function auto-scales the (float) values in KS_WAVEFORM so that the maximum absolute value becomes +/- 32766. The output short int (KS_IWAVE) array is to be copied to hardware. For a KS_WAVEFORM on the THETA board, the necessary phase wraps and scaling to short int format is performed using ks_phase_degrees2hw(). GE's requirement of only having even numbers in the waveform except for a final odd value (end-of-waveform) is also taken care of here
Note that the preservation of the physical units are done in ks_pg_wave() by setting the correct instruction amplitude to multiply this auto-scaled waveform with in the sequence's hardware memory
[out] | iwave | KS_IWAVE (short int array) |
[in] | waveform | KS_WAVEFORM |
[in] | res | Resolution (i.e. number of samples) in the KS_WAVEFORM |
[in] | board | One of XGRAD, YGRAD, ZGRAD, RHO, THETA, OMEGA |
STATUS | SUCCESS or FAILURE |
This function is used internally by ks_pg_wave() and there should be no need to call this function directly.
For all boards except THETA, this function auto-scales the (float) values in the .waveform[]
field so that the maximum absolute value becomes +/- 32766. The output short int (KS_IWAVE) array is to be copied to hardware. For a KS_WAVE on the THETA board, the necessary phase wraps and scaling to short int format is performed using ks_phase_degrees2hw(). GE's requirement of only having even numbers in the waveform except for a final odd value (end-of-waveform) is also taken care of here
Note that the preservation of the physical units are done in ks_pg_wave() by setting the correct instruction amplitude to multiply this auto-scaled waveform with in the sequence's hardware memory
[out] | iwave | KS_IWAVE (short int array) |
[in] | wave | KS_WAVE |
[in] | board | One of XGRAD, YGRAD, ZGRAD, RHO, THETA, OMEGA |
STATUS | SUCCESS or FAILURE |
WF_PULSE* ks_pg_echossp | ( | WF_PULSE * | echo, |
const char * | suffix | ||
) |
This function is used internally by ks_pg_read() to get pointers to the XTR and RBA SSP packets for an acquisition window
[in] | echo | Pointer to an echo (WF_PULSE) |
[in] | suffix | String being "xtr", "rba", or empty |
wfptr | Pointer to a WF_PULSE |
STATUS ks_pg_trap | ( | KS_TRAP * | trap, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_TRAP sequence object that creates a static trapezoid in the pulse sequence. The same KS_TRAP object can be freely placed on XGRAD, YGRAD and ZGRAD as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). The second argument is a KS_SEQLOC struct with three fields:
.board
: Choose between XGRAD, YGRAD, ZGRAD (or OMEGA).pos
: Absolute time in [us] of the start of the attack ramp of the trapezoid.ampscale
: A factor that must be in range [-1.0,1.0] that is multiplied with .amp
to yield a per-instance (i.e. per-placement) amplitude ([G/cm]). The simplest is to use 1.0, which makes the KS_TRAP object to be placed out on the board as initially designed using ks_eval_trap(). For the OMEGA board, this factor must be 1.0.Regardless of the order placed out in the @pg
section, and on which boards (XGRAD, YGRAD, ZGRAD) the KS_TRAP object is placed, the instance number of the KS_TRAP is automatically sorted in time. If two instances of one KS_TRAP occur at the same time (.pos
) on different boards, XGRAD comes before YGRAD, which comes before ZGRAD. These abstract, sorted, instance numbers are used by ks_scan_***()
functions in scan() to refer to a specific instance of a KS_TRAP object in the sequence
If the .duration
field in the KS_TRAP object is 0, ks_pg_trap() will return SUCCESS and quietly ignore placing it out. This is a part of the mechanism that setting the .duration
field to 0 in cveval()
should eliminate its existance in both timing calulations and in the pulse sequence generation in @pg
When a trapezoid is placed on OMEGA, neither the designed amplitude (the .amp
field in KS_TRAP) nor the .ampscale
(in KS_SEQLOC) has an effect on the final frequency modulation. Instead the run-time amplitude of a KS_TRAP object on the OMEGA board is controlled in scan() via a function called ks_scan_omegatrap_hz()
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | trap | Pointer to a KS_TRAP sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the KS_TRAP |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_TRAP |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_phaser | ( | KS_PHASER * | phaser, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_PHASER sequence object that creates a dynamic trapezoid for phase encoding. For 3D applications, two different KS_PHASER objects should have been designed by calling ks_eval_phaser() on each KS_PHASER as FOV and resolution typically differ for the two phase encoding directions. The same KS_PHASER object can be freely placed on XGRAD, YGRAD and ZGRAD as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). For Cartesian applications, phase encoding gradients such as KS_PHASER are typically placed out on YGRAD (phase encoding axis), for 3D also on ZGRAD. For 3D, the KS_PHASER object may embed a slice rephaser (static trapezoid) by setting .areaoffset
to a non-zero value (see ks_eval_phaser()). The second argument is a KS_SEQLOC struct with three fields:
.board
: Choose between XGRAD, YGRAD, ZGRAD.pos
: Absolute time in [us] of the start of the attack ramp of the phase encoding trapezoid.ampscale
: For KS_PHASER objects, this must be 1.0. If not, ks_pg_phaser() will throw an error. Amplitude control should solely be done in scan using ks_scan_phaser_toline() and ks_scan_phaser_fromline().Regardless of the order placed out in the @pg
section, and on which boards (XGRAD, YGRAD, ZGRAD) the KS_PHASER object is placed, the instance number of the KS_PHASER is automatically sorted in time. If two instances of one KS_PHASER occur at the same time (.pos
) on different boards, XGRAD comes before YGRAD, which comes before ZGRAD. These abstract, sorted, instance numbers are used by ks_scan_***()
functions in scan() to refer to a specific instance of a KS_PHASER object in the sequence
If the .duration
field in the KS_PHASER object is 0, ks_pg_phaser() will return SUCCESS and quietly ignore placing it out. This is a part of the mechanism that setting the .duration
field to 0 in cveval()
should eliminate its existance in both timing calulations and in the pulse sequence generation in @pg
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | phaser | Pointer to a KS_PHASER sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the KS_PHASER |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_PHASER |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_read | ( | KS_READ * | read, |
int | pos, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_READ sequence object that creates an acquisition window in the pulse sequence. The same KS_READ object can be freely placed as many times as desired, by only changing the second argument each time (to avoid overlaps). The second argument is an integer with the absolute time in [us] of the start of the acquisition. System gradient delays are accounted for in ks_pg_read() by internally adjusting the position by adding the system variable psd_grd_wait
to the position value. This assures the gradients boards and acquisition window are in sync on the MR system.
Regardless of the order the acquisition windows are placed out in the @pg
section, the instance number of the KS_READ is automatically sorted in time
If the .duration
field in the KS_READ object is 0, ks_pg_read() will return SUCCESS and quietly ignore placing it out. This is a part of the mechanism that setting the .duration
field to 0 in cveval()
should eliminate its existance in both timing calulations and in the pulse sequence generation in @pg
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | read | Pointer to a KS_READ sequence object |
[in] | pos | Absolute time in [us] when to start data acquisition |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_READ |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_readtrap | ( | KS_READTRAP * | readtrap, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_READTRAP sequence object consisting of a trapezoid (KS_TRAP) and an acquisition window (KS_READ). The same KS_READTRAP object can be freely placed on XGRAD, YGRAD and ZGRAD as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). For Cartesian applications, readouts such as KS_READTRAP are typically placed on XGRAD (frequency encoding axis). The second argument is a KS_SEQLOC struct with three fields:
.board
: Choose between XGRAD, YGRAD, ZGRAD.pos
: Absolute time in [us] of the start of the attack ramp of the readout trapezoid.ampscale
: For KS_READTRAP objects, this must be either +1.0 or -1.0 so that the FOV is not altered. Negative amplitudes will automatically be taken into account in ks_scan_offsetfov() to create the necessary frequency offsetRegardless of the order placed out in the @pg
section, and on which boards (XGRAD, YGRAD, ZGRAD) the KS_READTRAP object is placed, the instance number of the KS_READTRAP is automatically sorted in time. If two instances of one KS_READTRAP occur at the same time (.pos
) on different boards, XGRAD comes before YGRAD, which comes before ZGRAD. These abstract, sorted, instance numbers are used by ks_scan_***()
functions in scan() to refer to a specific instance of a KS_READTRAP object in the sequence.
If the .duration
field in the KS_READTRAP object is 0, ks_pg_readtrap() will return SUCCESS and quietly ignore placing it out. This is a part of the mechanism that setting the .duration
field to 0 in cveval()
should eliminate its existance in both timing calulations and in the pulse sequence generation in @pg
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | readtrap | Pointer to a KS_READTRAP sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the KS_READTRAP |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_READTRAP |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_wave | ( | KS_WAVE * | wave, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_WAVE sequence object that creates an arbitrary waveform in the pulse sequence. The same KS_WAVE object can be placed on any board as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). However, the RHO (RF) board should be avoided as this bypasses RF scaling and SAR calculations, providing no control over the flip angle. For RF waveforms, always use KS_RF (or KS_SELRF). The second argument is a KS_SEQLOC struct with three fields:
.board
: Choose between XGRAD, YGRAD, ZGRAD, OMEGA, THETA.pos
: Absolute time in [us] of the start of the waveform. For RF
, OMEGA and THETA, pos_rf_wait
will be added to this time to take system delays into account.ampscale
: For gradient boards, this factor must be in range [-1.0,1.0] that is multiplied with the waveform to yield a per-instance (i.e. per-placement) amplitude ([G/cm]). For THETA, only values of +1.0 and -1.0 is allowed, and for OMEGA only 1.0 is allowedThe KS_WAVE sequence object contains a KS_WAVEFORM (float[KS_MAXWAVELEN]) to hold the waveform. The physical unit of the waveform in the KS_WAVE object depends the board on which it is placed using ks_pg_wave(). For the
When a waveform is placed on OMEGA, neither the waveform amplitude nor the .ampscale
(in KS_SEQLOC) affects the final frequency modulation. Instead the run-time amplitude of a KS_WAVE object on the OMEGA board is controlled in scan() via a function called ks_scan_omegawave_hz(), where the largest value in the field .waveform[]
in the KS_WAVE will correspond to the value in [Hz] provided.
If the .duration
field in the KS_WAVE object is 0, ks_pg_wave() will return SUCCESS and quietly ignore placing it out. This is a part of the mechanism that setting the .duration
field to 0 in cveval()
should eliminate its existance in both timing calulations and in the pulse sequence generation in @pg
All KS_WAVE objects are double buffered in ks_pg_wave() so that waveforms can be replaced in run-time (scan()) using ks_scan_wave2hardware()
Regardless of the order placed out in the @pg
section, and on which boards (XGRAD, YGRAD, ZGRAD) the KS_WAVE object is placed, the instance number of the KS_WAVE is automatically sorted in time. If two instances of one KS_WAVE occur at the same time (.pos
) on different boards, XGRAD comes before YGRAD, which comes before ZGRAD. These abstract, sorted, instance numbers are used by ks_scan_***()
functions in scan() to refer to a specific instance of a KS_WAVE object in the sequence.
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | wave | Pointer to a KS_WAVE sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the KS_WAVE |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_WAVE |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_rf | ( | KS_RF * | rf, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_RF sequence object that creates an RF pulse in the pulse sequence. The same KS_RF object can be placed out as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). The second argument is a KS_SEQLOC struct with three fields:
.board
: Ignored. .rfwave
will always be placed on RHO. If the resolution of .omegawave
is non-zero it will be placed on OMEGA, and correspondingly for .thetawave
on THETA.pos
: Absolute time in [us] of the start of the waveform.ampscale
: A factor that must be in range [-1.0,1.0] that is multiplied with .amp
to yield a per-instance (i.e. per-placement) amplitude. For KS_RF objects this will cause the flip angle to be reduced on a per-instance basis. This can be used to generate a variable flip-angle train of RF pulses using a single KS_RF object. An .ampscale
of -1.0 is equivalent to adding a 180 degree RF phase shift to the RF pulseIf the rfwave.duration
field in the KS_RF object is 0, ks_pg_rf() will return SUCCESS and quietly ignore placing it out. This is a part of the mechanism that setting the .duration
field to 0 in cveval()
should eliminate its existance in both timing calulations and in the pulse sequence generation in @pg
As ks_pg_rf() internally calls ks_pg_wave() for its KS_WAVEs, double buffering will be used for all hardware waveforms, allowing waveforms to be replaced in run-time (scan()) using ks_scan_wave2hardware()
Regardless of the order placed out in the @pg
section the KS_RF object is placed, the instance number of the KS_RF is automatically sorted in time. These abstract, sorted, instance numbers are used by ks_scan_***()
functions in scan() to refer to a specific instance of a KS_RF object in the sequence.
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
When ks_pg_rf() is run in cveval()
(on HOST), the field .rfpulse.activity
that was first set to 0 by ks_eval_rf() is now set to PSD_APS2_ON + PSD_MPS2_ON + PSD_SCAN_ON
by ks_pg_rf(). This triggers the RF functions used in ks_eval_gradrflimits() to include this KS_RF object in RF scaling and SAR calculations. Each time ks_pg_rf() is called, the field .rfpulse.num
is incremented after being first set to 0 by ks_eval_rf(). Hence, it is crucial that the sequence generating function (c.f. KS_SEQ_CONTROL) containing all ks_pg_***()
calls is executed between the ks_eval_rf() setup call and the call to ks_eval_gradrflimits()
[in,out] | rf | Pointer to a KS_RF sequence object |
[in] | loc | KS_SEQLOC struct to specify when to place the KS_RF |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_RF |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_selrf | ( | KS_SELRF * | selrf, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_SELRF sequence object that creates an RF pulse with associated trapezoids in the pulse sequence. The same KS_SELRF object can be placed out as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). The second argument is a KS_SEQLOC struct with three fields:
.board
: Choose between XGRAD, YGRAD, ZGRAD for the board on which .pregrad
, .grad
(or .gradwave
) and .postgrad
should be placed.pos
: Absolute time in [us] of the start of the .pregrad
attack ramp. If .pregrad
has zero duration, .pos
will in effect refer to the start of the .grad
attack ramp.ampscale
: A factor that must be in range [-1.0,1.0] that is multiplied with rf.rfwave.amp
to yield a per-instance (i.e. per-placement) amplitude. For KS_SELRF objects the .ampscale
value will be passed on its internal call to ks_pg_rf(), but not to its internal ks_pg_trap() calls. Hence .ampscale
will have the same effect for ks_pg_selrf() as for ks_pg_rf(), with no per-instance control of the amplitude of the gradients involved. A reduced .ampscale
will cause the flip angle to be reduced on a per-instance basis. This can be used to generate a variable flip-angle train of selective RF pulses using a single KS_SELRF object. An .ampscale
of -1.0 is equivalent to adding a 180 degree RF phase shift to the RF pulseIf the .gradwave
field has a non-zero resolution, ks_pg_selrf() will place out the .gradwave
(KS_WAVE) instead of the .grad
(KS_TRAP) during the time the RF pulse is played out. An error is thrown if .gradwave.duration
(if .gradwave.res
> 0) is not equal to the .rf.rfwave.duration
. If .pregrad
or .postgrad
has zero duration, they will not be placed out. The existance of non-zero .pregrad
and .postgrad
is determined by ks_eval_selrf() based on .rf.role
As ks_pg_selrf() internally calls ks_pg_wave() for its KS_WAVEs, hardware double buffering will be used for all waveforms, allowing waveforms to be replaced in run-time (scan()) using ks_scan_wave2hardware()
Regardless of the order placed out in the @pg
section the KS_SELRF object is placed, the instance number of the KS_SELRF is automatically sorted in time. These abstract, sorted, instance numbers are used by ks_scan_***()
functions in scan() to refer to a specific instance of a KS_SELRF object in the sequence.
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | selrf | Pointer to a KS_SELRF sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the KS_SELRF |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_SELRF |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_wait | ( | KS_WAIT * | wait, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_WAIT sequence object that creates a wait pulse. The same KS_WAIT object can be placed out as many times as desired, by only changing the second argument each time (to avoid waveform overlaps). The second argument is a KS_SEQLOC struct with three fields:
.board
: Ignored.pos
: Absolute time in [us] of the start of the wait pulse.ampscale
: IgnoredThis function will insert a deadtime of duration equal to the .duration
field in the KS_WAIT object at position .pos
. This delay can be changed in run-time by calling ks_scan_wait().
GENERAL NOTE: It is a requirement that the function in the @pg
section containing all ks_pg_***()
calls is also called exactly once in cveval()
after the calls to the corresponding ks_eval_***()
functions that design the KS_*** sequence objects. Each ks_pg_***()
will throw an error if this has not been done.
[in,out] | wait | Pointer to a KS_WAIT sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the KS_WAIT |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_WAIT |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_isirot | ( | KS_ISIROT * | isirot, |
SCAN_INFO | scan_info, | ||
int | pos, | ||
void(*)() | rotfun, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function connects the execution of a psd-specific rotation function in realtime when time passes this point in the sequence. This is done by two KS_WAIT pulses (being part of KS_ISIROT) on the SSP board.
Example of use in a myseqmodule_pg()
function of the sequence module (in pulsegen()):
where the psd-specific rotation function is declared as:
Note that the only difference between the psd-specific myisirotatefun()
and the general ks_scan_isirotate() is that myisirotatefun()
has no input arguments. Input arguments cannot be used as it is called from an interrupt routine, not from some other parent function.
Care must be taken when mixing the use of ks_scan_rotate() (executing during the SSI time) and these ISI interrupts, so that they are executed in the correct order. One way is to consistently avoid the use of ks_scan_rotate() and instead return to the prescribed slice rotation by calling ks_pg_isirot() again, last in the same myseqmodule_pg()
function, this time using the prescribed scan_info struct:
[in,out] | isirot | Pointer to a KS_ISIROT sequence object |
[in] | scan_info | SCAN_INFO struct holding an .oprot matrix to be used for real-time rotation |
[in] | pos | Absolute position in [us] in the pulse sequence when this rotation should occur |
[in] | rotfun | Function pointer to the psd-specific rotation function |
[in,out] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_epi_dephasers | ( | KS_EPI * | epi, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function is called internally by ks_pg_epi() to place out the dephasing gradients of a KS_EPI object. See ks_pg_epi() for more details
For advanced usage of KS_EPI, it is possible to call ks_pg_epi_dephaser(), ks_pg_epi_echo() and ks_pg_epi_rephasers() separately instead of the single call to ks_pg_epi(). This allows the dephasing and rephasing gradients to be detached from the core EPI readout part
[in,out] | epi | Pointer to a KS_EPI sequence object |
[in] | loc | KS_SEQLOC struct to specify when and where to place the dephasers of the KS_EPI object |
[in] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_EPI |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_epi_rephasers | ( | KS_EPI * | epi, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function is called internally by ks_pg_epi() to place out the rephasing gradients of a KS_EPI object. See ks_pg_epi() for more details
For advanced usage of KS_EPI, it is possible to call ks_pg_epi_dephaser(), ks_pg_epi_echo() and ks_pg_epi_rephasers() separately instead of the single call to ks_pg_epi(). This allows the dephasing and rephasing gradients to be detached from the core EPI readout part
[in,out] | epi | Pointer to a KS_EPI sequence object |
[in] | loc | KS_SEQLOC struct to specify when to place the rephasers of the KS_EPI object |
[in] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_EPI |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_epi_echo | ( | KS_EPI * | epi, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function is called internally by ks_pg_epi() to place out the core part of a KS_EPI object. The core part is the EPI train without leading dephaser gradients or trailing rephaser gradients. See ks_pg_epi() for more details
For advanced usage of KS_EPI, it is possible to call ks_pg_epi_dephaser(), ks_pg_epi_echo() and ks_pg_epi_rephasers() separately instead of the single call to ks_pg_epi(). This allows the dephasing and rephasing gradients to be detached from the core EPI readout part
[in,out] | epi | Pointer to a KS_EPI sequence object |
[in] | loc | KS_SEQLOC struct to specify when to place the core part of the KS_EPI object |
[in] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_EPI |
STATUS | SUCCESS or FAILURE |
STATUS ks_pg_epi | ( | KS_EPI * | epi, |
KS_SEQLOC | loc, | ||
KS_SEQ_CONTROL * | ctrl | ||
) |
This function should be called in the @pg
section to place out a KS_EPI sequence object that creates an EPI readout including dephaser and rephaser gradients. The moments of all trapezoids in the KS_EPI object sum to zero on the two axes the KS_EPI object is placed on. The KS_EPI object is to be placed on two out of three gradients, why special values for the field loc.board
must be used. The value should state which logical board (X,Y or Z) that should be used for the readout lobes (FREQ) and which logical board (X, Y or Z) that should be used for the blips (PHASE). One example is KS_FREQX_PHASEY, which will put the EPI readout lobes on XGRAD and the phase encoding blips on YGRAD
The same KS_EPI object can be placed out 16 times per sequence. This limitation is due to the hard limitation on the number of echoes (i.e. different k-spaces per image plane and image volume) that can be acquired per scan. Each time an instance of the KS_EPI object is placed out using ks_pg_epi(), the second argument (the KS_SEQLOC struct) should be modified:
.board
: Choose between KS_FREQX_PHASEY
, KS_FREQY_PHASEX
, KS_FREQX_PHASEZ
, KS_FREQZ_PHASEX
, KS_FREQY_PHASEZ
, KS_FREQZ_PHASEY
.pos
: Absolute time in [us] of the start of the first dephaser gradient.ampscale
: For KS_EPI objects, valid values are only +1.0 and -1.0, and this will control the polarity of the first readout gradient. This is rarely needed, and 1.0 should be the standard choice as this does only affect gradient delays and Nyquist ghosting, not the geometric distortion direction.The sign of the EPI blips will control the direction of the geometric distortions, and this is not done via .ampscale
but in run-time using ks_scan_epi_shotcontrol()
For advanced usage of KS_EPI, it is possible to call ks_pg_epi_dephaser(), ks_pg_epi_echo() and ks_pg_epi_rephasers() separately instead of the single call to ks_pg_epi(). This allows the dephasing and rephasing gradients to be detached from the core EPI readout part
[in,out] | epi | Pointer to a KS_EPI sequence object |
[in] | loc | KS_SEQLOC struct to specify when to place the core part of the KS_EPI object |
[in] | ctrl | Pointer to the KS_SEQ_CONTROL struct corresponding to the sequence module for this KS_EPI |
STATUS | SUCCESS or FAILURE |
void ks_pg_mod_fse_rfpulse_structs | ( | KS_SELRF * | rf1, |
KS_SELRF * | rf2, | ||
KS_SELRF * | rf3, | ||
const double * | flip_angles, | ||
const int | etl | ||
) |
STATUS ks_pg_fse_flip_angle_taperoff | ( | double * | flip_angles, |
int | etl, | ||
double | flip1, | ||
double | flip2, | ||
double | flip3, | ||
double | target_flip, | ||
int | start_middle | ||
) |
void ks_instancereset_trap | ( | KS_TRAP * | trap | ) |
This function is for advanced use where a single sequence generating function is used in parallel in multiple sequences (i.e. in different SEQLENGTH()). This should be called after calling ks_copy_and_reset_obj()
The function sets .base.ngenerated
to 0 (counter for number of times placed out on TGT), and se