KSFoundation  [April-2021]
A platform for simpler EPIC programming on GE MR systems
KSFoundation.h File Reference

Data Structures

struct  KSEPI_DATATAG
 
struct  KS_DATASTORE_STRUCT_DYNAMIC
 
struct  KS_DATASTORE_STRUCT_INFO
 
struct  KS_DATASTORETAG
 
struct  KS_SEQLOC
 
struct  KS_WFINSTANCE
 
struct  KS_BASE
 
struct  KS_WAIT
 
struct  KS_ISIROT
 
struct  KS_TRAP
 
struct  KS_WAVE
 
struct  KS_READ
 
struct  KS_RF
 
struct  KS_GRADRFCTRL
 
struct  KS_SEQ_HANDLE
 
struct  KS_SEQ_CONTROL
 
struct  KS_SEQ_COLLECTION
 
struct  KS_SAR
 
struct  KS_SLICE_PLAN
 
struct  KS_SMS_INFO
 
struct  KS_SELRF
 
struct  KS_READTRAP
 
struct  KS_READWAVE
 
struct  KS_PHASER
 
struct  KS_PHASEENCODING_COORD
 
struct  KS_PHASEENCODING_PLAN
 
struct  KS_EPI
 
struct  KS_DIXON_ASYMREADWAVE
 
struct  KS_DIXON_DUALREADTRAP
 

Macros

#define WARN_UNUSED_RESULT
 
#define DEFAULT_SCAN_INFO_HEAD   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0
 
#define DEFAULT_SCAN_INFO_TAIL
 
#define DEFAULT_AXIAL_SCAN_INFO
 
#define DEFAULT_AX_SCAN_INFO_FREQ_LR   DEFAULT_AXIAL_SCAN_INFO
 
#define DEFAULT_AX_SCAN_INFO_FREQ_AP
 
#define DEFAULT_SAG_SCAN_INFO_FREQ_SI
 
#define DEFAULT_SAG_SCAN_INFO_FREQ_AP
 
#define DEFAULT_COR_SCAN_INFO_FREQ_SI
 
#define DEFAULT_COR_SCAN_INFO_FREQ_LR
 
#define KS_NOTSET   -1
 
#define KS_INFINITY   (1.0/0.0)
 
#define _cvdesc(cv, string)
 
#define areSame(a, b)   (fabs((a) - (b)) < 1e-5)
 
#define isNotSet(a)   areSame((a), KS_NOTSET)
 
#define isSet(a)   !isNotSet(a)
 
#define KS_ISI_predelay   256
 
#define KS_ISI_time   256
 
#define KS_ISI_rotupdatetime   12
 
#define KS_ISI_postdelay   256
 
#define KS_MINPLATEAUTIME   8
 
#define KS_DEFAULT_SSI_TIME   1500
 
#define KS_DEFAULT_SSI_TIME_MR750w   500
 
#define KS_DEFAULT_SSI_TIME_MR750   1000
 
#define KS_DEFAULT_SSI_TIME_MR450W   500
 
#define KS_DEFAULT_SSI_TIME_MR450   1000
 
#define KS_DEFAULT_SSI_TIME_PREMIER   500
 
#define KS_DEFAULT_SSI_TIME_ICE   200
 
#define KS_DEFAULT_SSI_TIME_OTHERWISE   1500
 
#define KS_RFSSP_PRETIME   64
 
#define KS_RFSSP_POSTTIME   56
 
#define KS_RF_STANDARD_CRUSHERAREA   2000.0
 
#define KS_EPI_MIN_INTERTRAIN_SSPGAP   80
 
#define L_REF   10
 
#define PSD_HRMW_COIL   13
 
#define HAVE_PREMIER_GRADIENTS   (cfgcoiltype == PSD_HRMW_COIL)
 
#define HALF_KHZ_USEC   500.0
 
#define KS_SAVEPFILES   RHXC_AUTO_LOCK
 
#define KS_GERECON   (RHXC_AUTO_DISPLAY+RHXC_XFER_IM)
 
#define KS_3D_SELECTED   (opimode == PSD_3D || opimode == PSD_3DM)
 
#define KS_3D_SINGLESLAB_SELECTED   (opimode == PSD_3D)
 
#define KS_3D_MULTISLAB_SELECTED   (opimode == PSD_3DM)
 
#define KS_DESCRIPTION_LENGTH   128
 
#define KS_MAXWAVELEN   10000
 
#define KS_MAXUNIQUE_RF   20
 
#define KS_MAXUNIQUE_TRAP   200
 
#define KS_MAXUNIQUE_WAVE   200
 
#define KS_MAXUNIQUE_SEQUENCES   200
 
#define KS_MAX_PHASEDYN   2049
 
#define KS_MAXUNIQUE_READ   500
 
#define KS_MAXINSTANCES   500
 
#define KS_EPI_MINBLIPAREA   100
 
#define KS_INITZEROS(n)   {[0 ... (n-1)] = 0}
 
#define KS_INITVALUE(n, a)   {[0 ... (n-1)] = a}
 
#define KS_INIT_DESC   KS_INITZEROS(KS_DESCRIPTION_LENGTH)
 
#define KS_INIT_SEQLOC   {KS_NOTSET, KS_NOTSET, 1.0, 1.0}
 
#define KS_INIT_WFINSTANCE   {NULL, 0, NULL, {KS_INIT_SEQLOC}}
 
#define KS_INIT_WAIT   {{0,0,NULL,sizeof(KS_WAIT)}, KS_INIT_DESC, 0, KS_INITVALUE(KS_MAXINSTANCES, KS_INIT_SEQLOC), NULL, NULL}
 
#define KS_INIT_ISIROT   {KS_INIT_WAIT, KS_INIT_WAIT, NULL, 0, 0, 0, 0}
 
#define KS_INIT_TRAP   {{0,0,NULL,sizeof(KS_TRAP)}, KS_INIT_DESC, 0.0, 0.0, 0, 0, 0, {0, 0, 0}, {0, 0, 0}, {1, 1, 1}, KS_INITVALUE(KS_MAXINSTANCES,KS_INIT_SEQLOC), NULL, NULL, NULL}
 
#define KS_INIT_READ   {{0,0,NULL,sizeof(KS_READ)}, KS_INIT_DESC, 0, KS_NOTSET, {0.0, 0, 0.0, 0.0, KS_NOTSET, 0, 0, 0}, KS_INITVALUE(KS_MAXINSTANCES,KS_NOTSET), 0, NULL}
 
#define KS_INIT_READ_EPI   {{0,0,NULL,sizeof(KS_READ)}, KS_INIT_DESC, 0, 250.0, {0.0, 0, 0.0, 0.0, KS_NOTSET, 0, 0, 0}, KS_INITVALUE(KS_MAXINSTANCES,KS_NOTSET), 0, NULL}
 
#define KS_INIT_READTRAP   {KS_INIT_READ, 240.0, 256, 0, 0, 0, 0.0, 0.0, 0.0, 0, KS_INIT_TRAP, KS_INIT_TRAP}
 
#define KS_INIT_READTRAP_EPI   {KS_INIT_READ_EPI, 240.0, 64, 0, 0, 0, 0.0, 0.0, 0.0, 0, KS_INIT_TRAP, KS_INIT_TRAP}
 
#define KS_INIT_PHASEENCTABLE   KS_INITZEROS(KS_MAX_PHASEDYN)
 
#define KS_INIT_PHASER   {KS_INIT_TRAP, 240.0, KS_NOTSET, 0, 1, 0, 0, 0.0, 0, KS_INIT_PHASEENCTABLE}
 
#define KS_INIT_PHASEENCODING_COORD   {KS_NOTSET, KS_NOTSET}
 
#define KS_INIT_PHASEENCODING_PLAN   {KS_NOTSET, KS_NOTSET, KS_INIT_DESC, NULL, NULL, NULL, FALSE}
 
#define KS_INIT_PHASEENCODING_ALLEPIPLANS   KS_INITVALUE(KS_EPI_PEPLAN_NUMPLANS, KS_INIT_PHASEENCODING_PLAN)
 
#define KS_INIT_PHASEENCODING_PLAN_16PTRS   KS_INITVALUE(16, NULL)
 
#define KS_INIT_EPI   {KS_INIT_READTRAP_EPI, KS_INIT_TRAP, KS_INIT_TRAP, KS_INIT_PHASER, KS_INIT_PHASER, 1, 0, 0, 0, 0, 1.0, KS_EPI_MINBLIPAREA}
 
#define KS_INIT_WAVEVALUE   0
 
#define KS_INIT_WAVEFORM   KS_INITVALUE(KS_MAXWAVELEN, KS_INIT_WAVEVALUE)
 
#define KS_INIT_WAVE   {{0,0,NULL,sizeof(KS_WAVE)}, KS_INIT_DESC, 0, 0, KS_INIT_WAVEFORM, {0,0,0}, KS_NOTSET, KS_INITVALUE(KS_MAXINSTANCES,KS_INIT_SEQLOC), NULL, NULL, NULL}
 
#define KS_INIT_READWAVE   {KS_INITVALUE(3,KS_INIT_WAVE), KS_INIT_WAVE, KS_INIT_WAVE, KS_INIT_READ, KS_INITVALUE(3, 0), KS_INITVALUE(3, 0.0), 0.0, 0.0, 0, 0, 0}
 
#define KS_INIT_DIXON_ASYMREADWAVE   {KS_INIT_READWAVE, KS_INIT_DESC, KS_INITVALUE(2,0), 0, 0.0, 0, 0.0, KS_INITVALUE(8,0.0)}
 
#define KS_INIT_DIXON_DUALREADTRAP   {KS_INIT_READWAVE, KS_INIT_DESC, 0,0,0,0,0.0,0, KS_INITVALUE(2,0),0,0.0,0,0,0,0.0,0.0, KS_INITVALUE(4,0)}
 
#define RX27_APPLY_HADAMARD
 
#define KS_INIT_RFPULSE   {NULL, NULL, 0.0,0.0,0.0,0.0,0.0,0,0.0,0.0,0.0,0.0,NULL,0.0,0.0,0,0,-1,0.0,NULL,0,NULL RX27_APPLY_HADAMARD}
 
#define KS_INIT_RF   {KS_RF_ROLE_NOTSET, KS_NOTSET, KS_NOTSET, 0.0, 0.0, KS_NOTSET, KS_NOTSET, KS_NOTSET, KS_INIT_DESC, KS_INIT_RFPULSE, KS_INIT_WAVE, KS_INIT_WAVE, KS_INIT_WAVE}
 
#define KS_INIT_SELRF   {KS_INIT_RF, KS_NOTSET, 1.0, KS_INIT_TRAP, KS_INIT_TRAP, KS_INIT_TRAP, KS_INIT_WAVE, KS_INIT_SMS_INFO}
 
#define KS_INIT_GRADRFCTRL   {KS_INITZEROS(KS_MAXUNIQUE_RF), 0, KS_INITZEROS(KS_MAXUNIQUE_TRAP), 0, KS_INITZEROS(KS_MAXUNIQUE_WAVE), 0, KS_INITZEROS(KS_MAXUNIQUE_READ), 0, FALSE /* is_cleared_on_tgt */ }
 
#define KS_INIT_SEQ_HANDLE   {NULL, 0, NULL}
 
#define KS_INIT_SEQ_CONTROL   {0, 0, KS_DEFAULT_SSI_TIME, 0, KS_NOTSET, FALSE, KS_INIT_DESC, KS_INIT_SEQ_HANDLE, KS_INIT_GRADRFCTRL}
 
#define KS_INIT_SEQ_COLLECTION   {0, KS_SEQ_COLLECTION_ALLOWNEW, FALSE, KS_INITVALUE(KS_MAXUNIQUE_SEQUENCES, NULL)}
 
#define KS_INIT_SAR   {0, 0, 0, 0}
 
#define KS_INIT_SLICEPLAN   {0,0,0,{{0,0,0}}}
 
#define KS_INIT_SMS_INFO   {1, 0, 0}
 
#define KS_INIT_LOGGRD   {0,0,0,0,0,0,{0,0,0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
 
#define KS_INIT_PHYSGRD   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
 
#define KS_MAT3x3_IDENTITY   {1,0,0,0,1,0,0,0,1}
 
#define KS_MAT4x4_IDENTITY   {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}
 
#define KS_CUSTOM_DATASTORE_LENGTH   22
 
#define KSEPI_INIT_DATATAG   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 
#define KS_INIT_DATASTORE_STRUCT_DYNAMIC   {-1, -1, -1, -1, -1, {0.0}}
 
#define KS_INIT_DATASTORE_STRUCT_INFO   {TRUE, 0}
 
#define KS_INIT_DATASTORETAG   {KS_INIT_DATASTORE_STRUCT_DYNAMIC, KS_INIT_DATASTORE_STRUCT_INFO, KS_INITZEROS(KS_CUSTOM_DATASTORE_LENGTH), NULL}
 
#define cvset(cv, min, max, def, desc)
 

Typedefs

typedef char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
 
typedef float KS_WAVEFORM[KS_MAXWAVELEN]
 
typedef short KS_IWAVE[KS_MAXWAVELEN]
 
typedef double KS_MAT3x3[9]
 
typedef double KS_MAT4x4[16]
 
typedef KS_PHASEENCODING_PLAN KS_PHASEENCODING_ALLEPIPLANS[KS_EPI_PEPLAN_NUMPLANS]
 
typedef KS_PHASEENCODING_PLANKS_PHASEENCODING_PLAN_16PTRS[16]
 

Enumerations

enum  KS_PLOT_FILEFORMATS { KS_PLOT_OFF, KS_PLOT_MAKEPDF, KS_PLOT_MAKESVG, KS_PLOT_MAKEPNG }
 
enum  KS_PLOT_EXCITATION_MODE { KS_PLOT_STANDARD, KS_PLOT_NO_EXCITATION }
 
enum  KS_PLOT_PASS_MODE { KS_PLOT_PASS_WAS_DUMMY, KS_PLOT_PASS_WAS_CALIBRATION, KS_PLOT_PASS_WAS_STANDARD }
 
enum  KS_PLOT_SLICEGROUP_MODE { KS_PLOT_SG_DUMMY, KS_PLOT_SG_CALIBRATION, KS_PLOT_SG_ACQUISITION, KS_PLOT_SG_NOTSET }
 
enum  ks_enum_pf_earlylate_te { KS_PF_EARLY_TE, KS_PF_LATE_TE }
 
enum  ks_enum_sweep_order { KS_SWEEP_ORDER_TOP_DOWN = 0, KS_SWEEP_ORDER_BOTTOM_UP = 1, KS_SWEEP_ORDER_CENTER_OUT = 2, KS_SWEEP_ORDER_OUTSIDE_IN = 3 }
 
enum  ks_snr_mode { KS_SNR_MEAS_OFF = 0, KS_SNR_MEAS_FREQUENCY = 1, KS_SNR_MEAS_PHASE = 2 }
 
enum  ks_enum_trapparts { G_ATTACK, G_PLATEAU, G_DECAY }
 
enum  ks_enum_boarddef {
  KS_X = TYPXGRAD, KS_Y = TYPYGRAD, KS_Z = TYPZGRAD, KS_RHO = TYPRHO1,
  KS_RHO2 = TYPRHO2, KS_THETA = TYPTHETA, KS_OMEGA = TYPOMEGA, KS_SSP = TYPSSP,
  KS_FREQX_PHASEY, KS_FREQY_PHASEX, KS_FREQX_PHASEZ, KS_FREQZ_PHASEX,
  KS_FREQY_PHASEZ, KS_FREQZ_PHASEY, KS_XYZ, KS_ALL
}
 
enum  ks_enum_epiblipsign { KS_EPI_POSBLIPS = 1, KS_EPI_NOBLIPS = 0, KS_EPI_NEGBLIPS = -1 }
 
enum  ks_enum_epiplans {
  KS_EPI_PEPLAN_EARLYTE_BOTTOMUP_UNDERSAMPLED, KS_EPI_PEPLAN_EARLYTE_BOTTOMUP_MULTISHOT, KS_EPI_PEPLAN_EARLYTE_TOPDOWN_UNDERSAMPLED, KS_EPI_PEPLAN_EARLYTE_TOPDOWN_MULTISHOT,
  KS_EPI_PEPLAN_LATETE_BOTTOMUP_UNDERSAMPLED, KS_EPI_PEPLAN_LATETE_BOTTOMUP_MULTISHOT, KS_EPI_PEPLAN_LATETE_TOPDOWN_UNDERSAMPLED, KS_EPI_PEPLAN_LATETE_TOPDOWN_MULTISHOT,
  KS_EPI_PEPLAN_NUMPLANS
}
 
enum  ks_enum_diffusion { KS_EPI_DIFFUSION_OFF, KS_EPI_DIFFUSION_ON }
 
enum  ks_enum_imsize { KS_IMSIZE_NATIVE, KS_IMSIZE_POW2, KS_IMSIZE_MIN256 }
 
enum  ks_enum_datadestination { KS_DONT_SEND = -1, KS_SENDTOBAM = 0, KS_SENDTORTP = 1 }
 
enum  ks_enum_accelmenu { KS_ACCELMENU_FRACT, KS_ACCELMENU_INT }
 
enum  ks_enum_rfrole {
  KS_RF_ROLE_NOTSET, KS_RF_ROLE_EXC, KS_RF_ROLE_REF, KS_RF_ROLE_CHEMSAT,
  KS_RF_ROLE_SPSAT, KS_RF_ROLE_INV
}
 
enum  ks_enum_sincwin {
  KS_RF_SINCWIN_OFF, KS_RF_SINCWIN_HAMMING, KS_RF_SINCWIN_HANNING, KS_RF_SINCWIN_BLACKMAN,
  KS_RF_SINCWIN_BARTLETT
}
 
enum  ks_enum_wavebuf { KS_WF_MAIN, KS_WF_BUF1, KS_WF_BUF2, KS_WF_SIZE }
 
enum  ks_enum_smstype {
  KS_SELRF_SMS_MB, KS_SELRF_SMS_PINS, KS_SELRF_SMS_PINS_DANTE, KS_SELRF_SMS_MULTI_PINS,
  KS_SELRF_SMSTYPE_SIZE
}
 
enum  ks_enum_sms_phase_mod {
  KS_SELRF_SMS_PHAS_MOD_OFF, KS_SELRF_SMS_PHAS_MOD_PHAS, KS_SELRF_SMS_PHAS_MOD_AMPL, KS_SELRF_SMS_PHAS_MOD_QUAD,
  KS_SELRF_SMS_PHAS_MOD_SIZE
}
 
enum  { KS_SEQ_COLLECTION_ALLOWNEW, KS_SEQ_COLLECTION_LOCKED }
 
enum  ks_enum_grad_scaling_policy { KS_GRADWAVE_ABSOLUTE, KS_GRADWAVE_RELATIVE }
 

Functions

int isNaN (float a)
 
void ks_init_read (KS_READ *read)
 
void ks_init_trap (KS_TRAP *trap)
 
void ks_init_wait (KS_WAIT *wait)
 
void ks_init_wave (KS_WAVE *wave)
 
void ks_init_rf (KS_RF *rf)
 
void ks_init_sms_info (KS_SMS_INFO *sms_info)
 
void ks_init_selrf (KS_SELRF *selrf)
 
void ks_init_readtrap (KS_READTRAP *readtrap)
 
void ks_init_phaser (KS_PHASER *phaser)
 
void ks_init_epi (KS_EPI *epi)
 
void ks_init_dixon_asymreadwave (KS_DIXON_ASYMREADWAVE *asymreadwave)
 
void ks_init_dixon_dualreadtrap (KS_DIXON_DUALREADTRAP *dual_readtrap)
 
void ks_init_gradrfctrl (KS_GRADRFCTRL *gradrfctrl)
 
void ks_init_seqcontrol (KS_SEQ_CONTROL *seqcontrol)
 
void ks_init_seqcollection (KS_SEQ_COLLECTION *seqcollection)
 
STATUS ks_init_slewratecontrol (LOG_GRAD *loggrd, PHYS_GRAD *phygrd, float srfact) WARN_UNUSED_RESULT
 
STATUS ks_eval_addtoseqcollection (KS_SEQ_COLLECTION *seqcollection, KS_SEQ_CONTROL *seqctrl) WARN_UNUSED_RESULT
 
STATUS ks_eval_seqcollection_isadded (KS_SEQ_COLLECTION *seqcollection, KS_SEQ_CONTROL *seqctrl)
 
STATUS ks_eval_addtraptogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_TRAP *trap) WARN_UNUSED_RESULT
 
STATUS ks_eval_addwavetogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_WAVE *wave) WARN_UNUSED_RESULT
 
STATUS ks_eval_addrftogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_RF *rf) WARN_UNUSED_RESULT
 
STATUS ks_eval_addreadtogradrfctrl (KS_GRADRFCTRL *gradrfctrl, KS_READ *read) WARN_UNUSED_RESULT
 
STATUS ks_eval_wait (KS_WAIT *wait, const char *const desc, int maxduration) WARN_UNUSED_RESULT
 
STATUS ks_eval_isirot (KS_ISIROT *isirot, const char *const desc, int isinumber) WARN_UNUSED_RESULT
 
STATUS ks_eval_read (KS_READ *read, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_trap_constrained (KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration) WARN_UNUSED_RESULT
 
STATUS ks_eval_trap (KS_TRAP *trap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_trap2 (KS_TRAP *trap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_trap1 (KS_TRAP *trap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_trap_constrained_time_maxarea (KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, float maxarea, int derate_slewrate) WARN_UNUSED_RESULT
 
STATUS ks_eval_set_asym_padding (KS_READTRAP *readtrap, float wanted_paddingarea_pre, float wanted_paddingarea_post) WARN_UNUSED_RESULT
 
STATUS ks_eval_trap1p (KS_TRAP *trap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_readtrap_constrained (KS_READTRAP *readtrap, const char *const desc, float ampmax, float slewrate) WARN_UNUSED_RESULT
 
STATUS ks_eval_readtrap (KS_READTRAP *readtrap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_readtrap2 (KS_READTRAP *readtrap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_readtrap1 (KS_READTRAP *readtrap, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_readtrap_constrained_sample_duration (KS_READTRAP *readtrap, const char *const desc, const float ampmax, const float slewrate, const int t_A, const int sample_duration, const float area_post, const float area_total) WARN_UNUSED_RESULT
 
STATUS ks_eval_dixon_wang (struct _dixon_dualreadtrap_s *dual_read, const char *const desc, const float PF, float M)
 
STATUS ks_eval_dixon_dualreadtrap (struct _dixon_dualreadtrap_s *dual_read, const char *const desc, int flip)
 
STATUS ks_verify_dualreadtrap_setup (struct _dixon_dualreadtrap_s *dual_read)
 
STATUS ks_eval_dixon_dualreadtrap_slim (struct _dixon_dualreadtrap_s *dual_read, const char *const desc, int flip)
 
STATUS ks_eval_dixon_asymtriangle_padded (struct _dixon_asymreadwave_s *asym_readwave, const char *const desc, const int tas, const int time2center, const float area_pre, const float area_acq, const float fov, const int duration) WARN_UNUSED_RESULT
 
STATUS ks_eval_dixon_asymspline_padded (struct _dixon_asymreadwave_s *asym_readwave, const char *const desc, const int tas, const int time2center, const int tae, const float Apre, const float Aacq, const float Apost, const float fov, const int duration) WARN_UNUSED_RESULT
 
STATUS ks_eval_dixon_asymspline (struct _dixon_asymreadwave_s *asym_readwave, const char *const desc, const int time2center, const float area, const float fov, const int duration, const float paddingarea) WARN_UNUSED_RESULT
 
STATUS ks_eval_dixon_asymtriangle (struct _dixon_asymreadwave_s *asym_readwave, const char *const desc, const int ttc, const float area, const float fov, const int duration, const float paddingarea) WARN_UNUSED_RESULT
 
STATUS ks_eval_readtrap1p (KS_READTRAP *readtrap, const char *const desc) WARN_UNUSED_RESULT
 
int ks_eval_kynover_fromnex (int yres, float nex, int minkynover)
 
void ks_eval_phaseviewtable (KS_PHASER *phaser)
 
STATUS ks_eval_phaser_adjustres (KS_PHASER *phaser, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_phaser_setaccel (KS_PHASER *phaser, int min_acslines, float R) WARN_UNUSED_RESULT
 
STATUS ks_eval_phaser_constrained (KS_PHASER *phaser, const char *const desc, float ampmax, float slewrate, int minplateautime) WARN_UNUSED_RESULT
 
STATUS ks_eval_phaser (KS_PHASER *phaser, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_phaser2 (KS_PHASER *phaser, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_phaser1 (KS_PHASER *phaser, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_phaser1p (KS_PHASER *phaser, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_wave (KS_WAVE *wave, const char *const desc, int res, int duration, KS_WAVEFORM waveform) WARN_UNUSED_RESULT
 
STATUS ks_eval_mirrorwave (KS_WAVE *wave)
 
STATUS ks_eval_wave_file (KS_WAVE *wave, const char *const desc, int res, int duration, const char *const filename, const char *const format) WARN_UNUSED_RESULT
 
STATUS ks_eval_rf_sinc (KS_RF *rf, const char *const desc, double bw, double tbw, float flip, int wintype) WARN_UNUSED_RESULT
 
STATUS ks_eval_rf_secant (KS_RF *rf, const char *const desc, float A0, float tbw, float bw)
 
STATUS ks_eval_rf_hard (KS_RF *rf, const char *const desc, int duration, float flip) WARN_UNUSED_RESULT
 
STATUS ks_eval_rf_hard_optimal_duration (KS_RF *rf, const char *const desc, int order, float flip, float offsetFreq) WARN_UNUSED_RESULT
 
STATUS ks_eval_rf_binomial (KS_RF *rf, const char *const desc, int offResExc, int nPulses, float flip, float offsetFreq) WARN_UNUSED_RESULT
 
STATUS ks_eval_rfstat (KS_RF *rf) WARN_UNUSED_RESULT
 
STATUS ks_eval_rf (KS_RF *rf, const char *const desc) WARN_UNUSED_RESULT
 
void ks_eval_rf_relink (KS_RF *rf)
 
STATUS ks_eval_stretch_rf (KS_RF *rf, float stretch_factor)
 
STATUS ks_eval_seltrap (KS_TRAP *trap, const char *const desc, float slewrate, float slthick, float bw, int rfduration) WARN_UNUSED_RESULT
 
STATUS ks_eval_selrf_constrained (KS_SELRF *selrf, const char *const desc, float ampmax, float slewrate) WARN_UNUSED_RESULT
 
STATUS ks_eval_selrf (KS_SELRF *selrf, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_selrf2 (KS_SELRF *selrf, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_selrf1 (KS_SELRF *selrf, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_selrf1p (KS_SELRF *selrf, const char *const desc) WARN_UNUSED_RESULT
 
STATUS ks_eval_sms_get_phase_modulation (float *sms_phase_modulation, const int sms_multiband_factor, const int sms_phase_modulation_mode) WARN_UNUSED_RESULT
 
float ks_eval_findb1 (KS_SELRF *selrf, float max_b1, double scaleFactor, int sms_multiband_factor, int sms_phase_modulation_mode, float sms_slice_gap)
 
void ks_eval_transient_SPGR_FA_train_recursive (float *FA_train, float *MZ_train, int N, float E1, float target_MT, int n)
 
void ks_eval_transient_SPGR_FA_train_binary_search (float *FA_train, float *MZ_train, int N, float E1, float MTlo, float MThi, float total_FA)
 
STATUS ks_eval_check_FA_train (int N, float *FA_train, float *MZ_train, float total_FA)
 
STATUS ks_eval_transient_SPGR_FA_train (float *FA_train, int N, float TR, float T1, float total_FA)
 
STATUS ks_eval_sms_make_multiband (KS_SELRF *selrfMB, const KS_SELRF *selrf, const int sms_multiband_factor, const int sms_phase_modulation_mode, const float sms_slice_gap, int debug) WARN_UNUSED_RESULT
 
float ks_eval_sms_calc_slice_gap (int sms_multiband_factor, const SCAN_INFO *org_slice_positions, int nslices, float slthick, float slspace)
 
float ks_eval_sms_calc_caipi_area (int caipi_fov_shift, float sms_slice_gap)
 
STATUS ks_eval_sms_make_pins (KS_SELRF *selrfPINS, const KS_SELRF *selrf, float sms_slice_gap)
 
STATUS ks_eval_sms_make_pins_dante (KS_SELRF *selrfPINS, const KS_SELRF *selrf, float sms_slice_gap)
 
int ks_eval_findNearestNeighbourIndex (float value, const float *x, int length)
 
void ks_eval_linear_interp1 (const float *x, int x_length, const float *y, const float *xx, int xx_length, float *yy)
 
STATUS ks_eval_trap2wave (KS_WAVE *wave, const KS_TRAP *trap) WARN_UNUSED_RESULT
 
STATUS ks_eval_append_two_waves (KS_WAVE *first_wave, KS_WAVE *second_wave) WARN_UNUSED_RESULT
 
STATUS ks_eval_concatenate_waves (int num_waves, KS_WAVE *target_wave, KS_WAVE **waves_to_append) WARN_UNUSED_RESULT
 
STATUS ks_eval_epi_constrained (KS_EPI *epi, const char *const desc, float ampmax, float slewrate) WARN_UNUSED_RESULT
 
STATUS ks_eval_epi_setinfo (KS_EPI *epi)
 
STATUS ks_eval_epi_maxamp_slewrate (float *ampmax, float *slewrate, int xres, float quietnessfactor)
 
STATUS ks_eval_epi (KS_EPI *epi, const char *const desc, float quietnessfactor) WARN_UNUSED_RESULT
 
int ks_eval_gradrflimits (KS_SAR *sar, KS_SEQ_COLLECTION *seqcollection, float gheatfact)
 
int ks_eval_mintr (int nslices, KS_SEQ_COLLECTION *seqcollection, float gheatfact, int(*play_loop)(int, int, void **), int nargs, void **args)
 
int ks_eval_maxslicespertr (int TR, KS_SEQ_COLLECTION *seqcollection, float gheatfact, int(*play_loop)(int, int, void **), int nargs, void **args)
 
STATUS ks_eval_seqctrl_setminduration (KS_SEQ_CONTROL *seqctrl, int mindur)
 
STATUS ks_eval_seqctrl_setduration (KS_SEQ_CONTROL *seqctrl, int dur)
 
STATUS ks_eval_seqcollection_durations_setminimum (KS_SEQ_COLLECTION *seqcollection) WARN_UNUSED_RESULT
 
STATUS ks_eval_seqcollection_durations_atleastminimum (KS_SEQ_COLLECTION *seqcollection) WARN_UNUSED_RESULT
 
void ks_eval_seqcollection_resetninst (KS_SEQ_COLLECTION *seqcollection)
 
void ks_print_seqcollection (KS_SEQ_COLLECTION *seqcollection, FILE *fp)
 
void ks_print_scaninfo (const SCAN_INFO *scan_info, int nslices, const char *desc, FILE *fp)
 
int ks_eval_seqcollection_gettotalduration (KS_SEQ_COLLECTION *seqcollection)
 
int ks_eval_seqcollection_gettotalminduration (KS_SEQ_COLLECTION *seqcollection)
 
STATUS ks_eval_seqcollection2rfpulse (RF_PULSE *rfpulse, KS_SEQ_COLLECTION *seqcollection)
 
GRAD_PULSE ks_eval_makegradpulse (KS_TRAP *trp, int gradchoice)
 
void ks_read_header_pool (int *exam_number, int *series_number, int *run_number)
 
unsigned int ks_calc_nextpow2 (unsigned int x)
 
int ks_calc_roundupms (int time)
 
STATUS ks_calc_filter (FILTER_INFO *echo_filter, int tsp, int duration) WARN_UNUSED_RESULT
 
int ks_calc_bw2tsp (float bw)
 
float ks_calc_tsp2bw (int tsp)
 
int ks_calc_trap_time2area (KS_TRAP *trap, float area)
 
float ks_calc_nearestbw (float bw)
 
float ks_calc_lower_rbw (float rbw)
 
float ks_calc_higher_rbw (float rbw)
 
float ks_calc_max_rbw (float ampmax, float fov)
 
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)
 
int ks_calc_dixon_times_within_one_period (float t1, float t2, float B0)
 
float ks_calc_dixon_fat_nsa_2p (float t1, float t2, float B0, float F)
 
float ks_calc_dixon_water_nsa_2p (float t1, float t2, float B0, float W)
 
double ks_calc_dixon_cond_2p (double t1, double t2, double B0)
 
float ks_calc_dixon_mean_nsa_2p_ss (float t1, float t2, float B0)
 
float ks_calc_dixon_mean_nsa_2p_ss_weighted (float t1, float t2, float B0, float w1, float w2)
 
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)
 
STATUS ks_calc_sliceplan (KS_SLICE_PLAN *slice_plan, int nslices, int slperpass)
 
STATUS ks_calc_sliceplan_interleaved (KS_SLICE_PLAN *slice_plan, int nslices, int slperpass, int inpass_interleaves)
 
STATUS ks_calc_sliceplan_sms (KS_SLICE_PLAN *slice_plan, int nslices, int slperpass, int multiband_factor)
 
int ks_calc_slice_acquisition_order_smssingleacq (DATA_ACQ_ORDER *dacq, int nslices)
 
int ks_calc_sms_min_gap (DATA_ACQ_ORDER *dacq, int nslices)
 
void ks_print_sliceplan (const KS_SLICE_PLAN slice_plan, FILE *fp)
 
void ks_print_waveform (const KS_WAVEFORM waveform, const char *filename, int res)
 
void ks_print_read (KS_READ read, FILE *fp)
 
void ks_print_trap (KS_TRAP trap, FILE *fp)
 
void ks_print_readtrap (KS_READTRAP readtrap, FILE *fp)
 
void ks_print_phaser (KS_PHASER phaser, FILE *fp)
 
void ks_print_epi (KS_EPI epi, FILE *fp)
 
void ks_print_rf (KS_RF rf, FILE *fp)
 
void ks_print_rfpulse (RF_PULSE rfpulse, FILE *fp)
 
void ks_print_selrf (KS_SELRF selrf, FILE *fp)
 
void ks_print_gradrfctrl (KS_GRADRFCTRL gradrfctrl, FILE *fp)
 
STATUS ks_error (const char *format,...) __attribute__((format(printf
 
STATUS STATUS ks_dbg (const char *format,...) __attribute__((format(printf
 
STATUS STATUS STATUS existfile (const char *fname)
 
int ks_syslimits_hasICEhardware ()
 
void ks_dbg_reset ()
 
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)
 
int ks_syslimits_ramptimemax (LOG_GRAD loggrd)
 
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)
 
float ks_syslimits_gradtarget (LOG_GRAD loggrd, int board)
 
float ks_syslimits_ampmax_phys ()
 
int ks_syslimits_ramptimemax_phys ()
 
float ks_syslimits_slewrate_phys ()
 
short ks_phase_radians2hw (float radphase)
 
short ks_phase_degrees2hw (float degphase)
 
float ks_calc_selgradamp (float rfbw, float slthick)
 
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)
 
float ks_waveform_absmax (const KS_WAVEFORM waveform, int res)
 
float ks_waveform_maxslew (const KS_WAVEFORM waveform, int res, int duration)
 
float ks_wave_maxslew (const KS_WAVE *wave)
 
short ks_iwave_absmax (const KS_IWAVE waveform, int res)
 
float ks_wave_absmax (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) WARN_UNUSED_RESULT
 
STATUS ks_wave2iwave (KS_IWAVE iwave, const KS_WAVE *wave, int board) WARN_UNUSED_RESULT
 
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) WARN_UNUSED_RESULT
 
STATUS ks_pg_read (KS_READ *read, int pos, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_phaser (KS_PHASER *phaser, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_readtrap (KS_READTRAP *readtrap, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_wave (KS_WAVE *wave, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_rf (KS_RF *rf, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_selrf (KS_SELRF *selrf, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_wait (KS_WAIT *wait, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_isirot (KS_ISIROT *isirot, SCAN_INFO scan_info, int pos, void(*rotfun)(), KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_epi_dephasers (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_epi_rephasers (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_epi_echo (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
STATUS ks_pg_epi (KS_EPI *epi, KS_SEQLOC loc, KS_SEQ_CONTROL *ctrl) WARN_UNUSED_RESULT
 
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)
 
void ks_scan_rotate (SCAN_INFO slice_info)
 
void ks_scan_isirotate (KS_ISIROT *isirot)
 
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_pg_mod_fse_rfpulse_structs (KS_SELRF *rf1, KS_SELRF *rf2, KS_SELRF *rf3, const double *flip_angles, const int etl)
 
void ks_instancereset_trap (KS_TRAP *trap)
 
void ks_instancereset_wait (KS_WAIT *wait)
 
void ks_instancereset_phaser (KS_PHASER *phaser)
 
void ks_instancereset_readtrap (KS_READTRAP *readtrap)
 
void ks_instancereset_rf (KS_RF *rf)
 
void ks_instancereset_selrf (KS_SELRF *selrf)
 
void ks_instancereset_epi (KS_EPI *epi)
 
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)
 
int ks_compare_pint (const void *v1, const void *v2)
 
int ks_compare_pshort (const void *v1, const void *v2)
 
int ks_compare_pfloat (const void *v1, const void *v2)
 
int ks_compare_int (const void *v1, const void *v2)
 
int ks_compare_short (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_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_file_exist (char *filename)
 
void ks_plot_host_slicetime_delete ()
 
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 exctype)
 
void ks_plot_slicetime_endofslicegroup (const char *desc)
 
void ks_plot_slicetime_endofslicegroup_tagged (const char *desc, const KS_PLOT_SLICEGROUP_MODE tag)
 
void ks_plot_slicetime_endofpass (KS_PLOT_PASS_MODE)
 
void ks_plot_slicetime_end ()
 
void ks_plot_host_slicetime_begin ()
 
void ks_plot_host_slicetime (KS_SEQ_CONTROL *ctrl, int nslices, float *slicepos_mm, float slthick_mm, KS_PLOT_EXCITATION_MODE exctype)
 
void ks_plot_host_slicetime_endofslicegroup (const char *desc, const KS_PLOT_SLICEGROUP_MODE tag)
 
void ks_plot_host_slicetime_endofpass (KS_PLOT_PASS_MODE)
 
void ks_plot_host_slicetime_end ()
 
void ks_plot_host (KS_SEQ_COLLECTION *seqcollection, KS_PHASEENCODING_PLAN *plan)
 
void ks_plot_host_seqctrl (KS_SEQ_CONTROL *ctrl, KS_PHASEENCODING_PLAN *plan)
 
void ks_plot_host_seqctrl_manyplans (KS_SEQ_CONTROL *ctrl, KS_PHASEENCODING_PLAN **plan, const int num_plans)
 
void ks_plot_tgt_reset (KS_SEQ_CONTROL *ctrl)
 
void ks_plot_tgt_addframe (KS_SEQ_CONTROL *ctrl)
 
void ks_scan_rf_ampscale (KS_RF *rf, int instanceno, float ampscale)
 
void ks_scan_rf_on (KS_RF *rf, int instanceno)
 
void ks_scan_rf_on_chop (KS_RF *rf, int instanceno)
 
void ks_scan_rf_off (KS_RF *rf, int instanceno)
 
void ks_scan_selrf_setfreqphase (KS_SELRF *selrf, int instanceno, SCAN_INFO sliceinfo, float rfphase)
 
void ks_scan_selrf_setfreqphase_pins (KS_SELRF *selrf, int instanceno, SCAN_INFO sliceinfo, int sms_multiband_factor, float sms_slice_gap, float rfphase)
 
void ks_scan_rf_setphase (KS_RF *rf, int instanceno, float rfphase)
 
void ks_scan_wave2hardware (KS_WAVE *wave, const KS_WAVEFORM newwave)
 
void ks_scan_offsetfov_iso (KS_READTRAP *readtrap, int instanceno, SCAN_INFO sliceinfo, double ky, double kz, double rcvphase)
 
void ks_scan_offsetfov (KS_READTRAP *readtrap, int instanceno, SCAN_INFO sliceinfo, float view, float phasefovratio, float rcvphase)
 
void ks_scan_offsetfov3D (KS_READTRAP *readtrap, int instanceno, SCAN_INFO sliceinfo, float kyview, float phasefovratio, float kzview, float zphasefovratio, float rcvphase)
 
void ks_scan_offsetfov_readwave (KS_READWAVE *readwave, int instanceno, SCAN_INFO sliceinfo, float kyview, float phasefovratio, float rcvphase)
 
void ks_scan_omegatrap_hz (KS_TRAP *trap, int instanceno, float Hz)
 
void ks_scan_omegawave_hz (KS_WAVE *wave, int instanceno, float Hz)
 
void ks_scan_wait (KS_WAIT *wait, int waitperiod)
 
void ks_scan_trap_ampscale (KS_TRAP *trap, int instanceno, float ampscale)
 
void ks_scan_trap_ampscale_slice (KS_TRAP *trap, int start, int skip, int count, float ampscale)
 
void ks_scan_phaser_kmove (KS_PHASER *phaser, int instanceno, double pixelunits)
 
void ks_scan_phaser_toline (KS_PHASER *phaser, int instanceno, int view)
 
void ks_scan_phaser_fromline (KS_PHASER *phaser, int instanceno, int view)
 
int ks_scan_getsliceloc (const KS_SLICE_PLAN *slice_plan, int passindx, int sltimeinpass)
 
int ks_scan_getslicetime (const KS_SLICE_PLAN *slice_plan, int passindx, int slloc)
 
ks_enum_epiblipsign ks_scan_epi_verify_phaseenc_plan (KS_EPI *epi, KS_PHASEENCODING_PLAN *phaseenc_plan, int shot)
 
void ks_scan_epi_shotcontrol (KS_EPI *epi, int echo, SCAN_INFO sliceinfo, KS_PHASEENCODING_PLAN *phaseenc_plan, int shot, int exc, float rcvphase)
 
void ks_scan_epi_loadecho_with_tag (KS_EPI *epi, int echo, int storeecho, int slice, KS_PHASEENCODING_PLAN *phaseenc_plan, int shot, KSEPI_DATATAG *datatag, KS_DATASTORETAG *datastoretag)
 
void ks_scan_epi_loadecho_with_datastoretag (KS_EPI *epi, int echo, int storeecho, int slice, KS_PHASEENCODING_PLAN *phaseenc_plan, int shot, KS_DATASTORETAG *datastoretag)
 
void ks_scan_epi_loadecho_with_epidatatag (KS_EPI *epi, int echo, int storeecho, int slice, KS_PHASEENCODING_PLAN *phaseenc_plan, int shot, KSEPI_DATATAG *datatag)
 
void ks_scan_epi_loadecho (KS_EPI *epi, int echo, int storeecho, int slice, KS_PHASEENCODING_PLAN *phaseenc_plan, int shot)
 
void ks_loaddab (WF_PULSE_ADDR echo, char *dab_array)
 
void ks_loaddab_datastoretag (WF_PULSE_ADDR echo, KS_DATASTORETAG *datastoretag)
 
void ks_scan_acq_to_rtp (KS_READ *read, TYPDAB_PACKETS dabacqctrl, float fatoffset)
 
void ks_scan_switch_to_sequence (KS_SEQ_CONTROL *ctrl)
 
int ks_scan_playsequence (KS_SEQ_CONTROL *ctrl)
 
STATUS ks_scan_loaddabwithindices (WF_PULSE_ADDR pulse, LONG slice, LONG echo, LONG view, uint8_t acq, uint8_t vol, TYPDAB_PACKETS acqon_flag)
 
STATUS ks_scan_loaddabwithindices_nex (WF_PULSE_ADDR pulse, LONG slice, LONG echo, LONG view, uint8_t acq, uint8_t vol, LONG operation, TYPDAB_PACKETS acqon_flag)
 
int ks_scan_wait_for_rtp (void *rtpmsg, int maxmsgsize, int maxwait, KS_SEQ_CONTROL *waitctrl)
 
void ks_copy_and_reset_obj (void *pobj)
 
void ks_show_clock (FLOAT scantime)
 
float ks_scan_rf_phase_spoiling (int counter)
 
void ks_tgt_reset_gradrfctrl (KS_GRADRFCTRL *gradrfctrl)
 
int ks_eval_clear_readwave (KS_READWAVE *readwave)
 
int ks_eval_clear_dualreadtrap (KS_DIXON_DUALREADTRAP *dual_read)
 
void ks_polyval (const double *coeffs, const int order, const float *x, const int numx, float *values)
 

Variables

int abort_on_kserror
 
int ks_rhoboard
 
LOG_GRAD loggrd
 
PHYS_GRAD phygrd
 
int pscR1
 
int rspent
 

Detailed Description

This file contains the most documentation, and contains all definitions, sequence objects (typedef structs) and function prototypes for KSFoundation. @inline this file in the main sequence.

Macro Definition Documentation

◆ WARN_UNUSED_RESULT

#define WARN_UNUSED_RESULT

Compiler flag for DV25 and higher, causing a compiler error if the returned function value is not used by the calling function

◆ DEFAULT_SCAN_INFO_HEAD

#define DEFAULT_SCAN_INFO_HEAD   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0

◆ DEFAULT_SCAN_INFO_TAIL

#define DEFAULT_SCAN_INFO_TAIL

◆ DEFAULT_AXIAL_SCAN_INFO

#define DEFAULT_AXIAL_SCAN_INFO
Value:
{ DEFAULT_SCAN_INFO_HEAD, {1.0, 0.0, 0.0, \
0.0, 1.0, 0.0, \
0.0, 0.0, 1.0}, DEFAULT_SCAN_INFO_TAIL}
#define DEFAULT_SCAN_INFO_TAIL
Definition: KSFoundation.h:65
#define DEFAULT_SCAN_INFO_HEAD
Definition: KSFoundation.h:61

◆ DEFAULT_AX_SCAN_INFO_FREQ_LR

#define DEFAULT_AX_SCAN_INFO_FREQ_LR   DEFAULT_AXIAL_SCAN_INFO

◆ DEFAULT_AX_SCAN_INFO_FREQ_AP

#define DEFAULT_AX_SCAN_INFO_FREQ_AP
Value:
{ DEFAULT_SCAN_INFO_HEAD, {0.0, 1.0, 0.0, \
-1.0, 0.0, 0.0, \
0.0, 0.0, 1.0}, DEFAULT_SCAN_INFO_TAIL}
#define DEFAULT_SCAN_INFO_TAIL
Definition: KSFoundation.h:65
#define DEFAULT_SCAN_INFO_HEAD
Definition: KSFoundation.h:61

◆ DEFAULT_SAG_SCAN_INFO_FREQ_SI

#define DEFAULT_SAG_SCAN_INFO_FREQ_SI
Value:
{ DEFAULT_SCAN_INFO_HEAD, {0.0, 0.0, 1.0, \
0.0, 1.0, 0.0, \
-1.0, 0.0, 0.0}, DEFAULT_SCAN_INFO_TAIL}
#define DEFAULT_SCAN_INFO_TAIL
Definition: KSFoundation.h:65
#define DEFAULT_SCAN_INFO_HEAD
Definition: KSFoundation.h:61

◆ DEFAULT_SAG_SCAN_INFO_FREQ_AP

#define DEFAULT_SAG_SCAN_INFO_FREQ_AP
Value:
{ DEFAULT_SCAN_INFO_HEAD, {0.0, 0.0, 1.0, \
1.0, 0.0, 0.0, \
0.0, 1.0, 0.0}, DEFAULT_SCAN_INFO_TAIL}
#define DEFAULT_SCAN_INFO_TAIL
Definition: KSFoundation.h:65
#define DEFAULT_SCAN_INFO_HEAD
Definition: KSFoundation.h:61

◆ DEFAULT_COR_SCAN_INFO_FREQ_SI

#define DEFAULT_COR_SCAN_INFO_FREQ_SI
Value:
{ DEFAULT_SCAN_INFO_HEAD, {0.0, 1.0, 0.0, \
0.0, 0.0, 1.0, \
1.0, 0.0, 0.0}, DEFAULT_SCAN_INFO_TAIL}
#define DEFAULT_SCAN_INFO_TAIL
Definition: KSFoundation.h:65
#define DEFAULT_SCAN_INFO_HEAD
Definition: KSFoundation.h:61

◆ DEFAULT_COR_SCAN_INFO_FREQ_LR

#define DEFAULT_COR_SCAN_INFO_FREQ_LR
Value:
{ DEFAULT_SCAN_INFO_HEAD, {-1.0, 0.0, 0.0, \
0.0, 0.0, 1.0, \
0.0, 1.0, 0.0}, DEFAULT_SCAN_INFO_TAIL}
#define DEFAULT_SCAN_INFO_TAIL
Definition: KSFoundation.h:65
#define DEFAULT_SCAN_INFO_HEAD
Definition: KSFoundation.h:61

◆ KS_NOTSET

#define KS_NOTSET   -1

Unrealistic value used on some variables to trigger errors

◆ KS_INFINITY

#define KS_INFINITY   (1.0/0.0)

Infinity

◆ _cvdesc

#define _cvdesc (   cv,
  string 
)
Value:
{\
if( NULL != string ) {\
if( FALSE == (cv)->staticdescrflag ) {\
free( (void *)((cv)->descr) );\
}\
(cv)->descr = strdup( string );\
(cv)->staticdescrflag = FALSE;\
}\
}

◆ areSame

#define areSame (   a,
 
)    (fabs((a) - (b)) < 1e-5)

◆ isNotSet

#define isNotSet (   a)    areSame((a), KS_NOTSET)

◆ isSet

#define isSet (   a)    !isNotSet(a)

◆ KS_ISI_predelay

#define KS_ISI_predelay   256

◆ KS_ISI_time

#define KS_ISI_time   256

◆ KS_ISI_rotupdatetime

#define KS_ISI_rotupdatetime   12

◆ KS_ISI_postdelay

#define KS_ISI_postdelay   256

◆ KS_MINPLATEAUTIME

#define KS_MINPLATEAUTIME   8

Shortest plateautime of a trapezoid (KS_TRAP)

◆ KS_DEFAULT_SSI_TIME

#define KS_DEFAULT_SSI_TIME   1500

◆ KS_DEFAULT_SSI_TIME_MR750w

#define KS_DEFAULT_SSI_TIME_MR750w   500

◆ KS_DEFAULT_SSI_TIME_MR750

#define KS_DEFAULT_SSI_TIME_MR750   1000

◆ KS_DEFAULT_SSI_TIME_MR450W

#define KS_DEFAULT_SSI_TIME_MR450W   500

◆ KS_DEFAULT_SSI_TIME_MR450

#define KS_DEFAULT_SSI_TIME_MR450   1000

◆ KS_DEFAULT_SSI_TIME_PREMIER

#define KS_DEFAULT_SSI_TIME_PREMIER   500

◆ KS_DEFAULT_SSI_TIME_ICE

#define KS_DEFAULT_SSI_TIME_ICE   200

◆ KS_DEFAULT_SSI_TIME_OTHERWISE

#define KS_DEFAULT_SSI_TIME_OTHERWISE   1500

◆ KS_RFSSP_PRETIME

#define KS_RFSSP_PRETIME   64

Time in [us] before an RF pulse that is needed for SSP packets. May sometimes be taken into account

◆ KS_RFSSP_POSTTIME

#define KS_RFSSP_POSTTIME   56

Time in [us] after an RF pulse that is needed for SSP packets. May sometimes be taken into account

◆ KS_RF_STANDARD_CRUSHERAREA

#define KS_RF_STANDARD_CRUSHERAREA   2000.0

◆ KS_EPI_MIN_INTERTRAIN_SSPGAP

#define KS_EPI_MIN_INTERTRAIN_SSPGAP   80

EXPERIMENTAL. Check how the SSP packets in the beginning/end of the EPI train can be packed to minimize this one for all possible acq. parameters

◆ L_REF

#define L_REF   10

◆ PSD_HRMW_COIL

#define PSD_HRMW_COIL   13

◆ HAVE_PREMIER_GRADIENTS

#define HAVE_PREMIER_GRADIENTS   (cfgcoiltype == PSD_HRMW_COIL)

◆ HALF_KHZ_USEC

#define HALF_KHZ_USEC   500.0

◆ KS_SAVEPFILES

#define KS_SAVEPFILES   RHXC_AUTO_LOCK

Bit for rhexecctrl to dump Pfiles

◆ KS_GERECON

#define KS_GERECON   (RHXC_AUTO_DISPLAY+RHXC_XFER_IM)

Bit for rhexecctrl for GE product image reconstruction

◆ KS_3D_SELECTED

#define KS_3D_SELECTED   (opimode == PSD_3D || opimode == PSD_3DM)

◆ KS_3D_SINGLESLAB_SELECTED

#define KS_3D_SINGLESLAB_SELECTED   (opimode == PSD_3D)

◆ KS_3D_MULTISLAB_SELECTED

#define KS_3D_MULTISLAB_SELECTED   (opimode == PSD_3DM)

◆ KS_DESCRIPTION_LENGTH

#define KS_DESCRIPTION_LENGTH   128

Max # of characters in the description of the various sequence objects

◆ KS_MAXWAVELEN

#define KS_MAXWAVELEN   10000

KS_MAXWAVELEN (10000) sample points

◆ KS_MAXUNIQUE_RF

#define KS_MAXUNIQUE_RF   20

Maximum number of different RF pulses in the sequence (c.f. also grad_rf_empty**.h)

◆ KS_MAXUNIQUE_TRAP

#define KS_MAXUNIQUE_TRAP   200

Maximum number of different KS_TRAPs in the sequence

◆ KS_MAXUNIQUE_WAVE

#define KS_MAXUNIQUE_WAVE   200

Maximum number of different KS_WAVEs in the sequence

◆ KS_MAXUNIQUE_SEQUENCES

#define KS_MAXUNIQUE_SEQUENCES   200

Maximum number of pulses sequence modules, including core, (i.e. with own SEQLENGTH/bofffset()) in this pulse sequence

◆ KS_MAX_PHASEDYN

#define KS_MAX_PHASEDYN   2049

Maximum number of phase encoding steps in a KS_PHASER sequence object

◆ KS_MAXUNIQUE_READ

#define KS_MAXUNIQUE_READ   500

Maximum number of readout instances

◆ KS_MAXINSTANCES

#define KS_MAXINSTANCES   500

◆ KS_EPI_MINBLIPAREA

#define KS_EPI_MINBLIPAREA   100

Default value of lowest EPI blip area until blip is made wider to avoid discretization errors

◆ KS_INITZEROS

#define KS_INITZEROS (   n)    {[0 ... (n-1)] = 0}

C macro to initialize arrays with zeros at declaration

◆ KS_INITVALUE

#define KS_INITVALUE (   n,
 
)    {[0 ... (n-1)] = a}

C macro to initialize each element in an array with a number at declaration

◆ KS_INIT_DESC

#define KS_INIT_DESC   KS_INITZEROS(KS_DESCRIPTION_LENGTH)

Default values for KS_DESCRIPTION strings

◆ KS_INIT_SEQLOC

#define KS_INIT_SEQLOC   {KS_NOTSET, KS_NOTSET, 1.0, 1.0}

Default values for KS_SEQLOC structs

◆ KS_INIT_WFINSTANCE

#define KS_INIT_WFINSTANCE   {NULL, 0, NULL, {KS_INIT_SEQLOC}}

Default values for KS_WFINSTANCE structs (internal use)

◆ KS_INIT_WAIT

#define KS_INIT_WAIT   {{0,0,NULL,sizeof(KS_WAIT)}, KS_INIT_DESC, 0, KS_INITVALUE(KS_MAXINSTANCES, KS_INIT_SEQLOC), NULL, NULL}

Default values for KS_WAIT sequence objects

◆ KS_INIT_ISIROT

#define KS_INIT_ISIROT   {KS_INIT_WAIT, KS_INIT_WAIT, NULL, 0, 0, 0, 0}

◆ KS_INIT_TRAP

#define KS_INIT_TRAP   {{0,0,NULL,sizeof(KS_TRAP)}, KS_INIT_DESC, 0.0, 0.0, 0, 0, 0, {0, 0, 0}, {0, 0, 0}, {1, 1, 1}, KS_INITVALUE(KS_MAXINSTANCES,KS_INIT_SEQLOC), NULL, NULL, NULL}

Default values for KS_TRAP sequence objects

◆ KS_INIT_READ

#define KS_INIT_READ   {{0,0,NULL,sizeof(KS_READ)}, KS_INIT_DESC, 0, KS_NOTSET, {0.0, 0, 0.0, 0.0, KS_NOTSET, 0, 0, 0}, KS_INITVALUE(KS_MAXINSTANCES,KS_NOTSET), 0, NULL}

Default values for KS_READ sequence objects

◆ KS_INIT_READ_EPI

#define KS_INIT_READ_EPI   {{0,0,NULL,sizeof(KS_READ)}, KS_INIT_DESC, 0, 250.0, {0.0, 0, 0.0, 0.0, KS_NOTSET, 0, 0, 0}, KS_INITVALUE(KS_MAXINSTANCES,KS_NOTSET), 0, NULL}

Default values for KS_READ sequence objects in KS_EPI

◆ KS_INIT_READTRAP

#define KS_INIT_READTRAP   {KS_INIT_READ, 240.0, 256, 0, 0, 0, 0.0, 0.0, 0.0, 0, KS_INIT_TRAP, KS_INIT_TRAP}

Default values for KS_READTRAP sequence objects

◆ KS_INIT_READTRAP_EPI

#define KS_INIT_READTRAP_EPI   {KS_INIT_READ_EPI, 240.0, 64, 0, 0, 0, 0.0, 0.0, 0.0, 0, KS_INIT_TRAP, KS_INIT_TRAP}

Default values for the KS_READTRAP sequence objects in KS_EPI

◆ KS_INIT_PHASEENCTABLE

#define KS_INIT_PHASEENCTABLE   KS_INITZEROS(KS_MAX_PHASEDYN)

Default values for the phase encoding table *.linetoacq* in the KS_PHASER sequence object

◆ KS_INIT_PHASER

#define KS_INIT_PHASER   {KS_INIT_TRAP, 240.0, KS_NOTSET, 0, 1, 0, 0, 0.0, 0, KS_INIT_PHASEENCTABLE}

Default values for KS_PHASER sequence objects

◆ KS_INIT_PHASEENCODING_COORD

#define KS_INIT_PHASEENCODING_COORD   {KS_NOTSET, KS_NOTSET}

◆ KS_INIT_PHASEENCODING_PLAN

#define KS_INIT_PHASEENCODING_PLAN   {KS_NOTSET, KS_NOTSET, KS_INIT_DESC, NULL, NULL, NULL, FALSE}

◆ KS_INIT_PHASEENCODING_ALLEPIPLANS

#define KS_INIT_PHASEENCODING_ALLEPIPLANS   KS_INITVALUE(KS_EPI_PEPLAN_NUMPLANS, KS_INIT_PHASEENCODING_PLAN)

◆ KS_INIT_PHASEENCODING_PLAN_16PTRS

#define KS_INIT_PHASEENCODING_PLAN_16PTRS   KS_INITVALUE(16, NULL)

◆ KS_INIT_EPI

Default values for KS_EPI sequence objects

◆ KS_INIT_WAVEVALUE

#define KS_INIT_WAVEVALUE   0

Default value for one element in a KS_WAVEFORM

◆ KS_INIT_WAVEFORM

#define KS_INIT_WAVEFORM   KS_INITVALUE(KS_MAXWAVELEN, KS_INIT_WAVEVALUE)

Default values for KS_WAVEFORM

◆ KS_INIT_WAVE

#define KS_INIT_WAVE   {{0,0,NULL,sizeof(KS_WAVE)}, KS_INIT_DESC, 0, 0, KS_INIT_WAVEFORM, {0,0,0}, KS_NOTSET, KS_INITVALUE(KS_MAXINSTANCES,KS_INIT_SEQLOC), NULL, NULL, NULL}

Default values for KS_WAVE sequence objects

◆ KS_INIT_READWAVE

#define KS_INIT_READWAVE   {KS_INITVALUE(3,KS_INIT_WAVE), KS_INIT_WAVE, KS_INIT_WAVE, KS_INIT_READ, KS_INITVALUE(3, 0), KS_INITVALUE(3, 0.0), 0.0, 0.0, 0, 0, 0}

◆ KS_INIT_DIXON_ASYMREADWAVE

#define KS_INIT_DIXON_ASYMREADWAVE   {KS_INIT_READWAVE, KS_INIT_DESC, KS_INITVALUE(2,0), 0, 0.0, 0, 0.0, KS_INITVALUE(8,0.0)}

◆ KS_INIT_DIXON_DUALREADTRAP

#define KS_INIT_DIXON_DUALREADTRAP   {KS_INIT_READWAVE, KS_INIT_DESC, 0,0,0,0,0.0,0, KS_INITVALUE(2,0),0,0.0,0,0,0,0.0,0.0, KS_INITVALUE(4,0)}

Default values for KS_DIXON_DUALREADTRAP sequence objects

◆ RX27_APPLY_HADAMARD

#define RX27_APPLY_HADAMARD

◆ KS_INIT_RFPULSE

#define KS_INIT_RFPULSE   {NULL, NULL, 0.0,0.0,0.0,0.0,0.0,0,0.0,0.0,0.0,0.0,NULL,0.0,0.0,0,0,-1,0.0,NULL,0,NULL RX27_APPLY_HADAMARD}

Default values for GE's RF_PULSE structure

◆ KS_INIT_RF

Default values for KS_RF sequence objects

◆ KS_INIT_SELRF

Default values for KS_SELRF sequence objects

◆ KS_INIT_GRADRFCTRL

#define KS_INIT_GRADRFCTRL   {KS_INITZEROS(KS_MAXUNIQUE_RF), 0, KS_INITZEROS(KS_MAXUNIQUE_TRAP), 0, KS_INITZEROS(KS_MAXUNIQUE_WAVE), 0, KS_INITZEROS(KS_MAXUNIQUE_READ), 0, FALSE /* is_cleared_on_tgt */ }

Default values for KS_GRADRFCTRL control handler

◆ KS_INIT_SEQ_HANDLE

#define KS_INIT_SEQ_HANDLE   {NULL, 0, NULL}

Default values for the KS_SEQ_HANDLE struct

◆ KS_INIT_SEQ_CONTROL

#define KS_INIT_SEQ_CONTROL   {0, 0, KS_DEFAULT_SSI_TIME, 0, KS_NOTSET, FALSE, KS_INIT_DESC, KS_INIT_SEQ_HANDLE, KS_INIT_GRADRFCTRL}

Default values for the KS_SEQ_CONTROL struct

◆ KS_INIT_SEQ_COLLECTION

#define KS_INIT_SEQ_COLLECTION   {0, KS_SEQ_COLLECTION_ALLOWNEW, FALSE, KS_INITVALUE(KS_MAXUNIQUE_SEQUENCES, NULL)}

Default values for the KS_SEQ_CONTROL struct

◆ KS_INIT_SAR

#define KS_INIT_SAR   {0, 0, 0, 0}

Default values for the KS_SAR struct

◆ KS_INIT_SLICEPLAN

#define KS_INIT_SLICEPLAN   {0,0,0,{{0,0,0}}}

Default values for the KS_SLICE_PLAN struct

◆ KS_INIT_SMS_INFO

#define KS_INIT_SMS_INFO   {1, 0, 0}

Default values for the KS_INIT_SMS_INFO struct

◆ KS_INIT_LOGGRD

#define KS_INIT_LOGGRD   {0,0,0,0,0,0,{0,0,0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }

Default values for GE's loggrd struct

◆ KS_INIT_PHYSGRD

#define KS_INIT_PHYSGRD   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }

Default values for GE's phygrd struct

◆ KS_MAT3x3_IDENTITY

#define KS_MAT3x3_IDENTITY   {1,0,0,0,1,0,0,0,1}

Identity matrix initialization for KS_MAT3x3

◆ KS_MAT4x4_IDENTITY

#define KS_MAT4x4_IDENTITY   {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}

Identity matrix initialization for KS_MAT4x4

◆ KS_CUSTOM_DATASTORE_LENGTH

#define KS_CUSTOM_DATASTORE_LENGTH   22

◆ KSEPI_INIT_DATATAG

#define KSEPI_INIT_DATATAG   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

◆ KS_INIT_DATASTORE_STRUCT_DYNAMIC

#define KS_INIT_DATASTORE_STRUCT_DYNAMIC   {-1, -1, -1, -1, -1, {0.0}}

◆ KS_INIT_DATASTORE_STRUCT_INFO

#define KS_INIT_DATASTORE_STRUCT_INFO   {TRUE, 0}

◆ KS_INIT_DATASTORETAG

◆ cvset

#define cvset (   cv,
  min,
  max,
  def,
  desc 
)
Value:
cvmin(cv,min);\
cvmax(cv,max);\
cvdef(cv,def);\
if (strcmp(desc,"")) {cvdesc(cv,desc)};\
errornum(cv,0);\
errorstring(cv,"");\
if (CONCAT2(_,cv).fixedflag == 0) { cv = CONCAT2(_,cv).defval; }

Macro to set CVs directly with min/max/def

Typedef Documentation

◆ KS_DESCRIPTION

typedef char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]

Char array used in all KS_**** sequence objects

◆ KS_WAVEFORM

typedef float KS_WAVEFORM[KS_MAXWAVELEN]

Waveform array for RF, Theta or custom gradients

◆ KS_IWAVE

typedef short KS_IWAVE[KS_MAXWAVELEN]

Interim short integer array to copy to hardware (internal use)

◆ KS_MAT3x3

typedef double KS_MAT3x3[9]

Array to store a row major 3x3 matrix

◆ KS_MAT4x4

typedef double KS_MAT4x4[16]

Array to store a row major 4x4 matrix

◆ KS_PHASEENCODING_ALLEPIPLANS

typedef KS_PHASEENCODING_PLAN KS_PHASEENCODING_ALLEPIPLANS[KS_EPI_PEPLAN_NUMPLANS]

Readable names KS

◆ KS_PHASEENCODING_PLAN_16PTRS

typedef KS_PHASEENCODING_PLAN* KS_PHASEENCODING_PLAN_16PTRS[16]

KS_PHASEENCODING_PLAN array containing all 8 possible phase encoding plans for EPI

Enumeration Type Documentation

◆ KS_PLOT_FILEFORMATS

Enumerator
KS_PLOT_OFF 
KS_PLOT_MAKEPDF 
KS_PLOT_MAKESVG 
KS_PLOT_MAKEPNG 
328  {
329  KS_PLOT_OFF,
Definition: KSFoundation.h:329
Definition: KSFoundation.h:332
KS_PLOT_FILEFORMATS
Definition: KSFoundation.h:328
Definition: KSFoundation.h:330
Definition: KSFoundation.h:331

◆ KS_PLOT_EXCITATION_MODE

Enumerator
KS_PLOT_STANDARD 
KS_PLOT_NO_EXCITATION 
334  {
KS_PLOT_EXCITATION_MODE
Definition: KSFoundation.h:334
Definition: KSFoundation.h:336
Definition: KSFoundation.h:335

◆ KS_PLOT_PASS_MODE

Enumerator
KS_PLOT_PASS_WAS_DUMMY 
KS_PLOT_PASS_WAS_CALIBRATION 
KS_PLOT_PASS_WAS_STANDARD 
338  {
Definition: KSFoundation.h:339
KS_PLOT_PASS_MODE
Definition: KSFoundation.h:338
Definition: KSFoundation.h:341
Definition: KSFoundation.h:340

◆ KS_PLOT_SLICEGROUP_MODE

Enumerator
KS_PLOT_SG_DUMMY 
KS_PLOT_SG_CALIBRATION 
KS_PLOT_SG_ACQUISITION 
KS_PLOT_SG_NOTSET 
343  {
KS_PLOT_SLICEGROUP_MODE
Definition: KSFoundation.h:343
Definition: KSFoundation.h:347
Definition: KSFoundation.h:345
Definition: KSFoundation.h:344
Definition: KSFoundation.h:346

◆ ks_enum_pf_earlylate_te

Enumerator
KS_PF_EARLY_TE 
KS_PF_LATE_TE 
ks_enum_pf_earlylate_te
Definition: KSFoundation.h:1899
Definition: KSFoundation.h:1899
Definition: KSFoundation.h:1899

◆ ks_enum_sweep_order

Enumerator
KS_SWEEP_ORDER_TOP_DOWN 
KS_SWEEP_ORDER_BOTTOM_UP 
KS_SWEEP_ORDER_CENTER_OUT 
KS_SWEEP_ORDER_OUTSIDE_IN 
Definition: KSFoundation.h:1904
ks_enum_sweep_order
Definition: KSFoundation.h:1902
Definition: KSFoundation.h:1905
Definition: KSFoundation.h:1902
Definition: KSFoundation.h:1903

◆ ks_snr_mode

Enumerator
KS_SNR_MEAS_OFF 
KS_SNR_MEAS_FREQUENCY 
KS_SNR_MEAS_PHASE 
Definition: KSFoundation.h:1907
Definition: KSFoundation.h:1907
Definition: KSFoundation.h:1907

◆ ks_enum_trapparts

Enumerator
G_ATTACK 
G_PLATEAU 
G_DECAY 
Definition: KSFoundation.h:1910
Definition: KSFoundation.h:1910
Definition: KSFoundation.h:1910

◆ ks_enum_boarddef

Enumerator
KS_X 
KS_Y 
KS_Z 
KS_RHO 
KS_RHO2 
KS_THETA 
KS_OMEGA 
KS_SSP 
KS_FREQX_PHASEY 
KS_FREQY_PHASEX 
KS_FREQX_PHASEZ 
KS_FREQZ_PHASEX 
KS_FREQY_PHASEZ 
KS_FREQZ_PHASEY 
KS_XYZ 
KS_ALL 
1911  {KS_X = TYPXGRAD,
1912  KS_Y = TYPYGRAD,
1913  KS_Z = TYPZGRAD,
1914  KS_RHO = TYPRHO1,
1915  KS_RHO2 = TYPRHO2,
1916  KS_THETA = TYPTHETA,
1917  KS_OMEGA = TYPOMEGA,
1918  KS_SSP = TYPSSP,
1925  KS_XYZ,
1926  KS_ALL};
Definition: KSFoundation.h:1919
Definition: KSFoundation.h:1912
Definition: KSFoundation.h:1921
Definition: KSFoundation.h:1915
Definition: KSFoundation.h:1917
Definition: KSFoundation.h:1914
Definition: KSFoundation.h:1911
Definition: KSFoundation.h:1916
Definition: KSFoundation.h:1925
Definition: KSFoundation.h:1924
Definition: KSFoundation.h:1913
Definition: KSFoundation.h:1926
Definition: KSFoundation.h:1922
Definition: KSFoundation.h:1920
Definition: KSFoundation.h:1918
Definition: KSFoundation.h:1923

◆ ks_enum_epiblipsign

Enumerator
KS_EPI_POSBLIPS 
KS_EPI_NOBLIPS 
KS_EPI_NEGBLIPS 
1929 {KS_EPI_POSBLIPS = 1, KS_EPI_NOBLIPS = 0, KS_EPI_NEGBLIPS = -1} ks_enum_epiblipsign; /* positive or negative blips. Don't change the enum values (+1, -1)! */
Definition: KSFoundation.h:1929
ks_enum_epiblipsign
Definition: KSFoundation.h:1929
Definition: KSFoundation.h:1929
Definition: KSFoundation.h:1929

◆ ks_enum_epiplans

Enumerator
KS_EPI_PEPLAN_EARLYTE_BOTTOMUP_UNDERSAMPLED 
KS_EPI_PEPLAN_EARLYTE_BOTTOMUP_MULTISHOT 
KS_EPI_PEPLAN_EARLYTE_TOPDOWN_UNDERSAMPLED 
KS_EPI_PEPLAN_EARLYTE_TOPDOWN_MULTISHOT 
KS_EPI_PEPLAN_LATETE_BOTTOMUP_UNDERSAMPLED 
KS_EPI_PEPLAN_LATETE_BOTTOMUP_MULTISHOT 
KS_EPI_PEPLAN_LATETE_TOPDOWN_UNDERSAMPLED 
KS_EPI_PEPLAN_LATETE_TOPDOWN_MULTISHOT 
KS_EPI_PEPLAN_NUMPLANS 
1930  {
1939  KS_EPI_PEPLAN_NUMPLANS /* 8 */
1940 } ks_enum_epiplans;
Definition: KSFoundation.h:1931
ks_enum_epiplans
Definition: KSFoundation.h:1930
Definition: KSFoundation.h:1938
Definition: KSFoundation.h:1932
Definition: KSFoundation.h:1933
Definition: KSFoundation.h:1935
Definition: KSFoundation.h:1937
Definition: KSFoundation.h:1934
Definition: KSFoundation.h:1939
Definition: KSFoundation.h:1936

◆ ks_enum_diffusion

KS_PHASEENCODING_PLAN Array of 16 pointers to KS_PHASEENCODING_PLANS for multi-echo use

Enumerator
KS_EPI_DIFFUSION_OFF 
KS_EPI_DIFFUSION_ON 
Definition: KSFoundation.h:1945
Definition: KSFoundation.h:1945

◆ ks_enum_imsize

Enumerator
KS_IMSIZE_NATIVE 
KS_IMSIZE_POW2 
KS_IMSIZE_MIN256 
Definition: KSFoundation.h:1948
Definition: KSFoundation.h:1948
Definition: KSFoundation.h:1948

◆ ks_enum_datadestination

Enumerator
KS_DONT_SEND 
KS_SENDTOBAM 
KS_SENDTORTP 
1949 {KS_DONT_SEND = -1, KS_SENDTOBAM = 0, KS_SENDTORTP = 1};
Definition: KSFoundation.h:1949
Definition: KSFoundation.h:1949
Definition: KSFoundation.h:1949

◆ ks_enum_accelmenu

Enumerator
KS_ACCELMENU_FRACT 
KS_ACCELMENU_INT 
Definition: KSFoundation.h:1950
Definition: KSFoundation.h:1950

◆ ks_enum_rfrole

Enumerator
KS_RF_ROLE_NOTSET 
KS_RF_ROLE_EXC 
KS_RF_ROLE_REF 
KS_RF_ROLE_CHEMSAT 
KS_RF_ROLE_SPSAT 
KS_RF_ROLE_INV 
Definition: KSFoundation.h:1953
Definition: KSFoundation.h:1953
Definition: KSFoundation.h:1953
Definition: KSFoundation.h:1953
Definition: KSFoundation.h:1953
Definition: KSFoundation.h:1953

◆ ks_enum_sincwin

Enumerator
KS_RF_SINCWIN_OFF 
KS_RF_SINCWIN_HAMMING 
KS_RF_SINCWIN_HANNING 
KS_RF_SINCWIN_BLACKMAN 
KS_RF_SINCWIN_BARTLETT 
Definition: KSFoundation.h:1954
Definition: KSFoundation.h:1954
Definition: KSFoundation.h:1954
Definition: KSFoundation.h:1954
Definition: KSFoundation.h:1954

◆ ks_enum_wavebuf

Enumerator
KS_WF_MAIN 
KS_WF_BUF1 
KS_WF_BUF2 
KS_WF_SIZE 
Definition: KSFoundation.h:1957
Definition: KSFoundation.h:1957
Definition: KSFoundation.h:1957
Definition: KSFoundation.h:1957

◆ ks_enum_smstype

Enumerator
KS_SELRF_SMS_MB 
KS_SELRF_SMS_PINS 
KS_SELRF_SMS_PINS_DANTE 
KS_SELRF_SMS_MULTI_PINS 
KS_SELRF_SMSTYPE_SIZE 
1960  {
Definition: KSFoundation.h:1963
Definition: KSFoundation.h:1965
Definition: KSFoundation.h:1964
Definition: KSFoundation.h:1961
Definition: KSFoundation.h:1962

◆ ks_enum_sms_phase_mod

Enumerator
KS_SELRF_SMS_PHAS_MOD_OFF 
KS_SELRF_SMS_PHAS_MOD_PHAS 
KS_SELRF_SMS_PHAS_MOD_AMPL 
KS_SELRF_SMS_PHAS_MOD_QUAD 
KS_SELRF_SMS_PHAS_MOD_SIZE 
1967  {
Definition: KSFoundation.h:1969
Definition: KSFoundation.h:1972
Definition: KSFoundation.h:1970
Definition: KSFoundation.h:1968
Definition: KSFoundation.h:1971

◆ anonymous enum

anonymous enum
Enumerator
KS_SEQ_COLLECTION_ALLOWNEW 
KS_SEQ_COLLECTION_LOCKED 
Definition: KSFoundation.h:1974
Definition: KSFoundation.h:1974

◆ ks_enum_grad_scaling_policy

Enumerator
KS_GRADWAVE_ABSOLUTE 
KS_GRADWAVE_RELATIVE 
Definition: KSFoundation.h:1975
Definition: KSFoundation.h:1975

Function Documentation

◆ isNaN()

int isNaN ( float  a)
58  {
59  return a != a;
60 }

◆ ks_init_read()

void ks_init_read ( KS_READ read)

Resets a KS_READ sequence object to its default value (KS_INIT_READ)

Parameters
[out]readPointer to KS_READ
Returns
void
54  {
55  KS_READ defacq = KS_INIT_READ;
56  *read = defacq;
57 }
Core sequence object that handles a data acquisition window
Definition: KSFoundation.h:730
#define KS_INIT_READ
Definition: KSFoundation.h:213

◆ ks_init_trap()

void ks_init_trap ( KS_TRAP trap)

Resets a KS_TRAP sequence object to its default value (KS_INIT_TRAP)

Parameters
[out]trapPointer to KS_TRAP
Returns
void
58  {
59  KS_TRAP deftrap = KS_INIT_TRAP;
60  *trap = deftrap;
61 }
Core sequence object for making trapezoids on X,Y,Z, and OMEGA boards
Definition: KSFoundation.h:578
#define KS_INIT_TRAP
Definition: KSFoundation.h:212

◆ ks_init_wait()

void ks_init_wait ( KS_WAIT wait)

Resets a KS_WAIT sequence object to its default value (KS_INIT_WAIT)

Parameters
[out]waitPointer to KS_WAIT
Returns
void
62  {
63  KS_WAIT defwait = KS_INIT_WAIT;
64  *wait = defwait;
65 }
Core sequence object that adds wait periods in the pulse sequence (see ks_eval_wait(), ks_pg_wait()). Can be placed on any sequence board
Definition: KSFoundation.h:456
#define KS_INIT_WAIT
Definition: KSFoundation.h:210

◆ ks_init_wave()

void ks_init_wave ( KS_WAVE wave)

Resets a KS_WAVE sequence object to its default value (KS_INIT_WAVE)

Parameters
[out]wavePointer to KS_WAVE
Returns
void
66  {
67  KS_WAVE defwave = KS_INIT_WAVE;
68  *wave = defwave;
69 }
Core sequence object making arbitrary waveforms on any board (using float data format)
Definition: KSFoundation.h:664
#define KS_INIT_WAVE
Definition: KSFoundation.h:227

◆ ks_init_rf()

void ks_init_rf ( KS_RF rf)

Resets a KS_RF sequence object to its default value (KS_INIT_RF)

Parameters
[out]rfPointer to KS_RF
Returns
void
70  {
71  KS_RF defrf = KS_INIT_RF;
72  *rf = defrf;
73 }
#define KS_INIT_RF
Definition: KSFoundation.h:239
Composite sequence object for RF (with optional OMEGA & THETA pulses)
Definition: KSFoundation.h:938

◆ ks_init_sms_info()

void ks_init_sms_info ( KS_SMS_INFO sms_info)

Resets a KS_SMS_INFO sequence object to its default value (KS_INIT_SMS_INFO)

Parameters
[out]sms_infoPointer to KS_SMS_INFO
Returns
void
74  {
75  KS_SMS_INFO defsms_info = KS_INIT_SMS_INFO;
76  *sms_info = defsms_info;
77 }
Internal typedef struct that is a part of the KS_SELRF typedef struct, used to store information abou...
Definition: KSFoundation.h:1367
#define KS_INIT_SMS_INFO
Definition: KSFoundation.h:250

◆ ks_init_selrf()

void ks_init_selrf ( KS_SELRF selrf)

Resets a KS_SELRF sequence object to its default value (KS_INIT_SELRF)

Parameters
[out]selrfPointer to KS_SELRF
Returns
void
78  {
79  KS_SELRF defselrf = KS_INIT_SELRF;
80  *selrf = defselrf;
81 }
Composite sequence object for slice-selective RF
Definition: KSFoundation.h:1484
#define KS_INIT_SELRF
Definition: KSFoundation.h:240

◆ ks_init_readtrap()

void ks_init_readtrap ( KS_READTRAP readtrap)

Resets a KS_READTRAP sequence object to its default value (KS_INIT_READTRAP)

Parameters
[out]readtrapPointer to KS_READTRAP
Returns
void
82  {
83  KS_READTRAP defread = KS_INIT_READTRAP;
84  *readtrap = defread;
85 }
#define KS_INIT_READTRAP
Definition: KSFoundation.h:215
Composite sequence object for data readout using a trapezoid gradient
Definition: KSFoundation.h:1573

◆ ks_init_phaser()

void ks_init_phaser ( KS_PHASER phaser)

Resets a KS_PHASER sequence object to its default value (KS_INIT_PHASER)

Parameters
[out]phaserPointer to KS_PHASER
Returns
void
86  {
87  KS_PHASER defphaser = KS_INIT_PHASER;
88  *phaser = defphaser;
89 }
#define KS_INIT_PHASER
Definition: KSFoundation.h:218
Composite sequence object for phase encoding using a trapezoid gradient
Definition: KSFoundation.h:1675

◆ ks_init_epi()

void ks_init_epi ( KS_EPI epi)

Resets a KS_EPI sequence object to its default value (KS_INIT_EPI)

Parameters
[out]epiPointer to KS_EPI
Returns
void
90  {
91  KS_EPI defepi = KS_INIT_EPI;
92  *epi = defepi;
93 }
#define KS_INIT_EPI
Definition: KSFoundation.h:223
Composite sequence object for EPI readout
Definition: KSFoundation.h:1836

◆ ks_init_dixon_asymreadwave()

void ks_init_dixon_asymreadwave ( KS_DIXON_ASYMREADWAVE asymreadwave)

Resets a KS_DIXON_ASYMREADWAVE sequence object to its default value (KS_INIT_DIXON_ASYMREADWAVE)

Parameters
[in,out]asymreadwavePointer to KS_DIXON_ASYMREADWAVE
Returns
void
95  {
97  *asymreadwave = def_asymreadwave;
98 }
#define KS_INIT_DIXON_ASYMREADWAVE
Definition: KSFoundation.h:230
Definition: KSFoundation.h:1851

◆ ks_init_dixon_dualreadtrap()

void ks_init_dixon_dualreadtrap ( KS_DIXON_DUALREADTRAP dual_readtrap)

Resets a KS_DIXON_DUALREADTRAP sequence object to its default value (KS_INIT_DIXON_DUALREADTRAP)

Parameters
[in,out]dual_readtrapPointer to KS_DIXON_DUALREADTRAP
Returns
void
100  {
102  *dual_readtrap = def_dual_readtrap;
103 }
#define KS_INIT_DIXON_DUALREADTRAP
Definition: KSFoundation.h:231
Definition: KSFoundation.h:1862

◆ ks_init_gradrfctrl()

void ks_init_gradrfctrl ( KS_GRADRFCTRL gradrfctrl)

Resets KS_GRADRFCTRL to its default value (KS_INIT_GRADRFCTRL)

Parameters
[out]gradrfctrlPointer to KS_GRADRFCTRL
Returns
void
108  {
109  KS_GRADRFCTRL defgradrf = KS_INIT_GRADRFCTRL;
110  *gradrfctrl = defgradrf;
111 }
typedef struct that is a part of the KS_SEQ_CONTROL typedef struct, used internally to collect gradie...
Definition: KSFoundation.h:965
#define KS_INIT_GRADRFCTRL
Definition: KSFoundation.h:243

◆ ks_init_seqcontrol()

void ks_init_seqcontrol ( KS_SEQ_CONTROL seqcontrol)

Resets KS_SEQ_CONTROL to its default value (KS_INIT_SEQ_CONTROL)

Parameters
[out]seqcontrolPointer to KS_INIT_SEQ_CONTROL
Returns
void
112  {
113  KS_SEQ_CONTROL defseqcontrol = KS_INIT_SEQ_CONTROL;
114  *seqcontrol = defseqcontrol;
115 }
#define KS_INIT_SEQ_CONTROL
Definition: KSFoundation.h:245
A multi-purpose controller struct for each sequence module to facilitate RF scaling, SAR calculations, sequence duration and sequence switching
Definition: KSFoundation.h:1131

◆ ks_init_seqcollection()

void ks_init_seqcollection ( KS_SEQ_COLLECTION seqcollection)

Resets KS_SEQ_COLLECTION to its default value (KS_INIT_SEQ_COLLECTION)

Parameters
[out]seqcollectionPointer to KS_INIT_SEQ_COLLECTION
Returns
void
117  {
118  KS_SEQ_COLLECTION defseqcollection = KS_INIT_SEQ_COLLECTION;
119  *seqcollection = defseqcollection;
120 }
#define KS_INIT_SEQ_COLLECTION
Definition: KSFoundation.h:247
KS_SEQ_COLLECTION seqcollection
Definition: ksepi.e:80
Collection handle of all sequence modules involved in the pulse sequence, used for RF scaling...
Definition: KSFoundation.h:1299

◆ ks_init_slewratecontrol()

STATUS ks_init_slewratecontrol ( LOG_GRAD *  loggrd,
PHYS_GRAD *  phygrd,
float  srfact 
)

Changes existing (globally used) loggrd and phygrd structs (set up by inittargets() in e.g. GEReq_init_gradspecs())

If srfact < 1.0, both phygrd and loggrd are updated, and the gradients will be switched propotionally slower. This can be used to make the acquistion quieter. If srfact > 1.0, only loggrd will be updated. This could be used as an attempt to switch the gradients faster, but should be used with care as the risk for peripheral nerve stimulation (PNS) increases and the gradients may trip.

Parameters
[in,out]loggrdPointer to LOG_GRAD
[in,out]phygrdPointer to PHYS_GRAD
[in]srfactSlewrate factor (< 1.0 means less acquistic noise and reduced risk for PNS)
Returns
void
123  {
124 
125  if (fabs(srfact) < FLT_EPSILON) {
126  return ks_error("%s: slewrate factor can not be zero", __FUNCTION__);
127  }
128 
129  if (srfact < 1.0 && phygrd != NULL) {
130  phygrd->xrt = (int) ((float) phygrd->xrt / srfact);
131  phygrd->yrt = (int) ((float) phygrd->yrt / srfact);
132  phygrd->zrt = (int) ((float) phygrd->zrt / srfact);
133  }
134 
135  if (loggrd != NULL) {
136  loggrd->xrt = (int) ((float) loggrd->xrt / srfact);
137  loggrd->yrt = (int) ((float) loggrd->yrt / srfact);
138  loggrd->zrt = (int) ((float) loggrd->zrt / srfact);
139  }
140 
141  return SUCCESS;
142 }
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
PHYS_GRAD phygrd
LOG_GRAD loggrd

◆ ks_eval_addtoseqcollection()

STATUS ks_eval_addtoseqcollection ( KS_SEQ_COLLECTION seqcollection,
KS_SEQ_CONTROL seqctrl 
)

Adds a sequence module (KS_SEQ_CONTROL) to the KS_SEQ_COLLECTION struct for later RF scaling and SAR calculations

The KS_SEQ_CONTROL object will be ignored if added previously or if its .duration field is zero. A zero duration of a KS_SEQ_CONTROL indicates that this sequence module should not be used with the current settings

Parameters
[in,out]seqcollectionPointer to the KS_SEQ_COLLECTION for the sequence
[in]seqctrlPointer to KS_SEQ_CONTROL
Return values
STATUSSUCCESS or FAILURE
149  {
150  int i;
151 
152  if (seqcollection == NULL) {
153  return ks_error("%s: seqcollection is NULL", __FUNCTION__);
154  }
155 
156  if (seqctrl->duration == 0) {
157  /* Return early if seqctrl.duration = 0 so we are not adding sequence modules with zero duration to the collection.
158  This is in concert with:
159  - not performing createseq() in KS_SEQLENGTH if seqctrl.duration = 0
160  - not playing sequence modules in scan() using ks_scan_playsequence() if seqctrl.duration = 0
161 
162  It is the task of the PG function (e.g. <seqmodule>_pg()) of the current sequence module to set seqctrl.duration > 0 based on the waveform content in that module
163  and <seqmodule>_pg() should therefore be called before this function.
164  Preferred method is to add the following to the end of <seqmodule>_pg():
165  #ifndef IPG
166  // HOST only:
167  ks_eval_seqctrl_setminduration(&seqctrl, tmploc.pos); // tmploc.pos now corresponds to the end of last gradient in the sequence
168  #endif
169  */
170  return SUCCESS;
171  }
172 
174  return ks_error("%s: Number of sequence modules has been exceeded (max: %d)", __FUNCTION__, KS_MAXUNIQUE_SEQUENCES);
175  }
176 
178  return ks_error("%s - (%s): seqcollection.mode = KS_SEQ_COLLECTION_LOCKED. Module must be added before GEReq_eval_TR(), GEReq_eval_rfscaling(), and GEReq_eval_checkTR_SAR()", __FUNCTION__, seqctrl->description);
179  }
180 
181  /* check for previous registrations of this sequence module. If found, return */
182  if (seqcollection->numseq > 0) {
183  for (i = 0; i < seqcollection->numseq; i++) {
184  if (seqcollection->seqctrlptr[i] == seqctrl)
185  return SUCCESS;
186  }
187  }
188 
189  /* register the sequence module */
191 
192  return SUCCESS;
193 }
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
int mode
Definition: KSFoundation.h:1301
int duration
Definition: KSFoundation.h:1135
KS_SEQ_CONTROL * seqctrlptr[KS_MAXUNIQUE_SEQUENCES]
Definition: KSFoundation.h:1306
#define KS_MAXUNIQUE_SEQUENCES
Definition: KSFoundation.h:190
KS_SEQ_COLLECTION seqcollection
Definition: ksepi.e:80
KS_DESCRIPTION description
Definition: KSFoundation.h:1141
Definition: KSFoundation.h:1974
int numseq
Definition: KSFoundation.h:1300

◆ ks_eval_seqcollection_isadded()

STATUS ks_eval_seqcollection_isadded ( KS_SEQ_COLLECTION seqcollection,
KS_SEQ_CONTROL seqctrl 
)

Checks whether a sequence module (KS_SEQ_CONTROL) is a part of the KS_SEQ_COLLECTION struct

Parameters
[in]seqcollectionPointer to the KS_SEQ_COLLECTION for the sequence
[in]seqctrlPointer to KS_SEQ_CONTROL
Return values
STATUSSUCCESS or FAILURE
197  {
198  int i;
199 
200  if (seqctrl->duration == 0) {
201  return SUCCESS; /* it is not added, but we should still not complain as .duration = 0
202  means that it won't be used anyway */
203  }
204 
205  /* check for previous registrations of this sequence module. If found, return */
206  if (seqcollection->numseq > 0) {
207  for (i = 0; i < seqcollection->numseq; i++) {
208  if (seqcollection->seqctrlptr[i] == seqctrl)
209  return SUCCESS;
210  }
211  }
212 
213  return FAILURE;
214 
215 }
int duration
Definition: KSFoundation.h:1135
KS_SEQ_CONTROL * seqctrlptr[KS_MAXUNIQUE_SEQUENCES]
Definition: KSFoundation.h:1306
KS_SEQ_COLLECTION seqcollection
Definition: ksepi.e:80
int numseq
Definition: KSFoundation.h:1300

◆ ks_eval_addtraptogradrfctrl()

STATUS ks_eval_addtraptogradrfctrl ( KS_GRADRFCTRL gradrfctrl,
KS_TRAP trap 
)

*Internal use*. Adds a trapezoid (KS_TRAP) to the KS_GRADRFCTRL struct for later gradient heating calculations in ks_eval_gradrflimits()

The KS_TRAP object will be ignored if added previously

Parameters
[in,out]gradrfctrlPointer to the KS_GRADRFCTRL for the sequence
[in]trapPointer to KS_TRAP
Return values
STATUSSUCCESS or FAILURE
3773  {
3774  int i;
3775  if (trap == NULL) return SUCCESS;
3776 
3777  if (gradrfctrl == NULL) {
3778  return ks_error("%s: gradrfctrl is NULL", __FUNCTION__);
3779  }
3780 
3781  if (gradrfctrl->numtrap >= KS_MAXUNIQUE_TRAP) {
3782  return ks_error("%s: ERROR - too many unique KS_TRAP in sequence", __FUNCTION__);
3783  }
3784 
3785  /* check for previous registrations of this trap's memory address. If found, return */
3786  if (gradrfctrl->numtrap > 0) {
3787  for (i = 0; i < gradrfctrl->numtrap; i++) {
3788  if (gradrfctrl->trapptr[i] == trap)
3789  return SUCCESS;
3790  }
3791  }
3792 
3793  gradrfctrl->trapptr[gradrfctrl->numtrap++] = trap;
3794 
3795  return SUCCESS;
3796 }
int numtrap
Definition: KSFoundation.h:969
STATUS ks_error(const char *format,...)
Definition: KSFoundation_common.c:70
#define KS_MAXUNIQUE_TRAP
Definition: KSFoundation.h:188
KS_TRAP * trapptr[KS_MAXUNIQUE_TRAP]
Definition: KSFoundation.h:968

◆ ks_eval_addwavetogradrfctrl()

STATUS ks_eval_addwavetogradrfctrl ( KS_GRADRFCTRL gradrfctrl,
KS_WAVE wave 
)

*Internal use*. Adds a wave (KS_WAVE) - if it is not a part of a KS_RF object - to the KS_GRADRFCTRL struct for later gradient heating calculations in ks_eval_gradrflimits()

The KS_WAVE object will be ignored if added previously

Parameters
[in,out]gradrfctrlPointer to the KS_GRADRFCTRL for the sequence
[in]wavePointer to KS_WAVE
Return values
STATUSSUCCESS or FAILURE
3798  {
3799  int i;
3800  if (wave == NULL) return SUCCESS;
3801 
3802  if (gradrfctrl == NULL) {
3803  return ks_error("%s: gradrfctrl is NULL", __FUNCTION__);
3804  }
3805 
3806  if (gradrfctrl->numwave >= KS_MAXUNIQUE_WAVE) {
3807  return ks_error("%s: ERROR - too many unique KS_WAVE in sequence", __FUNCTION__);
3808  }
3809 
3810  /* check for previous registrations of this trap's memory address. If found, return */
3811  if (gradrfctrl->numwave > 0) {
3812  for (i = 0; i < gradrfctrl->numwave; i++) {
3813  if (gradrfctrl->waveptr[i] == wave)
3814  return SUCCESS;
3815  }
3816  }
3817 
3818  /* check also for previous waves in KS_RF (rfwave, omegawave, thetawave). If found, return */
3819  if (gradrfctrl->numrf > 0) {
3820  for (i = 0; i < gradrfctrl->numrf; i++) {
3821  if (&(gradrfctrl->rfptr[i]->rfwave) == wave || &(gradrfctrl->rfptr[i]->omegawave) == wave || &(gradrfctrl->rfptr[i]->thetawave) == wave)
3822  return SUCCESS;
3823  }
3824  }
3825 
3826  gradrfctrl->waveptr[gradrfctrl->numwave++] = wave;
3827 
3828  return SUCCESS;
3829 }
KS_RF * rfptr[KS_MAXUNIQUE_RF]
Definition: KSFoundation.h:966
STATUS ks_error(const char *format,...)
Definition: KSFoundation_common.c:70
int numrf
Definition: KSFoundation.h:967
KS_WAVE thetawave
Definition: KSFoundation.h:951
KS_WAVE * waveptr[KS_MAXUNIQUE_WAVE]
Definition: KSFoundation.h:970
KS_WAVE rfwave
Definition: KSFoundation.h:949
#define KS_MAXUNIQUE_WAVE
Definition: KSFoundation.h:189
int numwave
Definition: KSFoundation.h:971
KS_WAVE omegawave
Definition: KSFoundation.h:950

◆ ks_eval_addrftogradrfctrl()

STATUS ks_eval_addrftogradrfctrl ( KS_GRADRFCTRL gradrfctrl,
KS_RF rf 
)

*Internal use*. Adds an RF pulse to the KS_GRADRFCTRL struct for later SAR & RF power calculations in ks_eval_gradrflimits()

The RF object will be ignored if added previously

Parameters
[in,out]gradrfctrlPointer to the KS_GRADRFCTRL for the sequence
[in]rfPointer to KS_RF
Return values
STATUSSUCCESS or FAILURE
3832  {
3833  int i;
3834  if (rf == NULL) return SUCCESS;
3835 
3836  if (gradrfctrl == NULL) {
3837  return ks_error("%s: gradrfctrl is NULL", __FUNCTION__);
3838  }
3839 
3840  if (gradrfctrl->numrf >= KS_MAXUNIQUE_RF) {
3841  return ks_error("%s: ERROR - too many unique KS_RF in sequence", __FUNCTION__);
3842  }
3843 
3844  /* check for previous registrations of this rf's memory address. If found, return */
3845  if (gradrfctrl->numrf > 0) {
3846  for (i = 0; i < gradrfctrl->numrf; i++) {
3847  if (gradrfctrl->rfptr[i] == rf)
3848  return SUCCESS;
3849  }
3850  }
3851 
3852  gradrfctrl->rfptr[gradrfctrl->numrf++] = rf;
3853 
3854  return SUCCESS;
3855 }
#define KS_MAXUNIQUE_RF
Definition: KSFoundation.h:187
KS_RF * rfptr[KS_MAXUNIQUE_RF]
Definition: KSFoundation.h:966
STATUS ks_error(const char *format,...)
Definition: KSFoundation_common.c:70
int numrf
Definition: KSFoundation.h:967

◆ ks_eval_addreadtogradrfctrl()

STATUS ks_eval_addreadtogradrfctrl ( KS_GRADRFCTRL gradrfctrl,
KS_READ read 
)

*Internal use*. Adds an acquisition to the KS_GRADRFCTRL struct. Used for plotting

Parameters
[in,out]gradrfctrlPointer to the KS_GRADRFCTRL for the sequence
[in]readPointer to acquisition object.
Return values
STATUSSUCCESS or FAILURE
3857  {
3858  int i;
3859  if (read == NULL) return SUCCESS;
3860 
3861  if (gradrfctrl == NULL) {
3862  return ks_error("%s: gradrfctrl is NULL", __FUNCTION__);
3863  }
3864 
3865  if (gradrfctrl->numacq >= KS_MAXUNIQUE_READ) {
3866  return ks_error("%s: ERROR - too many readouts in sequence", __FUNCTION__);
3867  }
3868 
3869  /* check for previous registrations of the pointer. If found, return */
3870  if (gradrfctrl->numacq > 0) {
3871  for (i = 0; i < gradrfctrl->numacq; i++) {
3872  if (gradrfctrl->readptr[i] == read)
3873  return SUCCESS;
3874  }
3875  }
3876 
3877  gradrfctrl->readptr[gradrfctrl->numacq++] = read;
3878 
3879  return SUCCESS;
3880 }
STATUS ks_error(const char *format,...)
Definition: KSFoundation_common.c:70
#define KS_MAXUNIQUE_READ
Definition: KSFoundation.h:192
KS_READ * readptr[KS_MAXUNIQUE_READ]
Definition: KSFoundation.h:972
int numacq
Definition: KSFoundation.h:973

◆ ks_eval_wait()

STATUS ks_eval_wait ( KS_WAIT wait,
const char *const  desc,
int  maxduration 
)

Sets up a wait pulse using a KS_WAIT sequence object

This function should be called in cveval() and defines a wait pulse whose duration can be changed at scan-time up to .duration [us].

If ks_eval_wait() returns FAILURE, one must also make sure cveval() returns FAILURE, otherwise an error message created in ks_eval_wait() will not be seen in the UI.

Parameters
[out]waitPointer to the KS_WAIT object to be set up
[in]descA description (text string) of the KS_WAIT object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]maxdurationThe desired maximum duration in [us] of the KS_WAIT object
Return values
STATUSSUCCESS or FAILURE
219  {
220 
221  ks_init_wait(wait);
222 
223  if (desc == NULL || desc[0] == ' ') {
224  return ks_error("ks_eval_wait desc (2nd arg) cannot be NULL or begin with a space");
225  } else {
226  strncpy(wait->description, desc, KS_DESCRIPTION_LENGTH - 1);
227  }
228 
229 
230  wait->duration = duration;
231 
232  /* initialize counters to 0 */
233  wait->base.ninst = 0;
234  wait->base.ngenerated = 0;
235  wait->base.next = NULL;
236 
237  return SUCCESS;
238 }
void ks_init_wait(KS_WAIT *wait)
Resets a KS_WAIT sequence object to its default value (KS_INIT_WAIT)
Definition: KSFoundation_host.c:62
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
int ninst
Definition: KSFoundation.h:409
KS_DESCRIPTION description
Definition: KSFoundation.h:458
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
void * next
Definition: KSFoundation.h:411
KS_BASE base
Definition: KSFoundation.h:457
int duration
Definition: KSFoundation.h:459
int ngenerated
Definition: KSFoundation.h:410

◆ ks_eval_isirot()

STATUS ks_eval_isirot ( KS_ISIROT isirot,
const char *const  desc,
int  isinumber 
)

Sets up a KS_ISIROT object to be used for real-time coordinate rotations

See also ks_pg_isirot() and ks_scan_isirotate().

Parameters
[out]isirotPointer to the KS_ISIROT object to be set up
[in]descA description (text string) of the KS_ISIROT object
[in]isinumberA free ISI interrupt number in range [4,7]
Return values
STATUSSUCCESS or FAILURE
242  {
243  STATUS status;
244  char tmpdesc[KS_DESCRIPTION_LENGTH];
245 
246  if ((isinumber < 4) || (isinumber > 7)) {
247  return ks_error("%s: ISI number out of range (should be 4-7)", __FUNCTION__);
248  }
249 
250  sprintf(tmpdesc, "%s_isirotfun", desc);
251  status = ks_eval_wait(&isirot->waitfun, tmpdesc, RUP_GRD(KS_ISI_time));
252  if (status != SUCCESS) return status;
253 
254  sprintf(tmpdesc, "%s_isirotupdate", desc);
255  status = ks_eval_wait(&isirot->waitrot, tmpdesc, RUP_GRD(KS_ISI_rotupdatetime));
256  if (status != SUCCESS) return status;
257 
258  isirot->isinumber = isinumber;
259  isirot->duration = isirot->waitfun.duration + isirot->waitrot.duration;
260  isirot->counter = 0;
261  isirot->numinstances = 0;
262 
263  return SUCCESS;
264 }
int isinumber
Definition: KSFoundation.h:473
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
#define KS_ISI_rotupdatetime
Definition: KSFoundation.h:133
KS_WAIT waitfun
Definition: KSFoundation.h:470
STATUS ks_eval_wait(KS_WAIT *wait, const char *const desc, int duration)
Sets up a wait pulse using a KS_WAIT sequence object
Definition: KSFoundation_host.c:219
int counter
Definition: KSFoundation.h:475
int duration
Definition: KSFoundation.h:459
int numinstances
Definition: KSFoundation.h:476
KS_WAIT waitrot
Definition: KSFoundation.h:471
#define KS_ISI_time
Definition: KSFoundation.h:132
int duration
Definition: KSFoundation.h:474

◆ ks_eval_read()

STATUS ks_eval_read ( KS_READ read,
const char *const  desc 
)

Sets up a data acquisition window using a KS_READ sequence object

This function should be called in cveval() and defines a data acquisition window of a certain duration with some receiver bandwidth. Before calling this function, the following fields in the KS_READ object must be set:

  • .rbw: The desired receiver bandwidth / FOV in [kHz] (max: 250)
  • .duration: The duration in [us]

ks_eval_read() will validate the desired rBW and round it to the nearest valid value. Also the duration will be rounded up to fit a whole number of samples in the acquisition window.

To use an acquisition window with a gradient, see KS_READTRAP and ks_eval_readtrap()

If ks_eval_read() returns FAILURE, one must also make sure cveval() returns FAILURE, otherwise an error message created in ks_eval_read() will not be seen in the UI.

Parameters
[in,out]readPointer to the KS_READ object to be set up
[in]descA description (text string) of the KS_READ object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
270  {
271  char tmpdesc[KS_DESCRIPTION_LENGTH];
272  int duration;
273  float rbw;
274  int tsp;
275  int override_R1;
276  int noutputs;
277 
278  /* store desired inputs before resetting */
279  duration = read->duration;
280  rbw = read->rbw;
281  override_R1 = read->override_R1;
282  strcpy(tmpdesc, desc); /* copy in case the read->description has been passed in before ks_init_read wipes it */
283 
284  /* Reset all fields (after saving the desired info) */
285  ks_init_read(read);
286 
287  /* put back the input fields */
288  read->duration = duration;
289  read->rbw = ks_calc_nearestbw(rbw); /* round to nearest valid rBW */
290  read->override_R1 = override_R1;
291  tsp = ks_calc_bw2tsp(read->rbw);
292  strncpy(read->description, tmpdesc, KS_DESCRIPTION_LENGTH - 1);
293  read->description[KS_DESCRIPTION_LENGTH - 1] = 0;
294 
295  /* don't allow empty description or a description with leading space */
296  if (read->description == NULL || read->description[0] == ' ') {
297  return ks_error("ks_eval_read: read name (2nd arg) cannot be NULL or leading space");
298  }
299 
300  if (read->rbw <= 0) {
301  return ks_error("ks_eval_read: field 'rbw' (1st arg) is not set");
302  }
303  if (read->duration <= 2) {
304  return ks_error("ks_eval_read: field 'duration' (1st arg) must be a positive number in [us]");
305  }
306 
307  noutputs = CEIL_DIV(read->duration, tsp);
308  read->duration = noutputs * tsp;
309 
310  /* calculate read->filter (FILTER_INFO) */
311  if (ks_calc_filter(&read->filt, tsp, read->duration) == FAILURE)
312  return FAILURE;
313 
314  return SUCCESS;
315 }
float ks_calc_nearestbw(float bw)
Round receiver bandwidth to nearest valid value
Definition: KSFoundation_host.c:4740
void ks_init_read(KS_READ *read)
Resets a KS_READ sequence object to its default value (KS_INIT_READ)
Definition: KSFoundation_host.c:54
STATUS ks_calc_filter(FILTER_INFO *echortf, int tsp, int duration)
Sets up GE&#39;s FILTER_INFO struct based on dwell (sample point) time and duration of an acquisition win...
Definition: KSFoundation_host.c:4701
LONG override_R1
Definition: KSFoundation.h:737
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
float rbw
Definition: KSFoundation.h:734
KS_DESCRIPTION description
Definition: KSFoundation.h:732
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
int ks_calc_bw2tsp(float bw)
Convert receiver bandwidth to dwell time
Definition: KSFoundation_host.c:4722
int duration
Definition: KSFoundation.h:733
FILTER_INFO filt
Definition: KSFoundation.h:735

◆ ks_eval_trap_constrained()

STATUS ks_eval_trap_constrained ( KS_TRAP trap,
const char *const  desc,
float  ampmax,
float  slewrate,
int  minduration 
)

Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input arguments

Before calling this function, the following field in the KS_TRAP object must be set:

  • .area: Desired gradient area in units of [(G/cm) * us]

ks_eval_trap_constrained() will make a trapezoid pulse with the desired area, constrained by the specified maximum gradient amplitude, slewrate, and minimum plateau time (args 3-5).

If ks_eval_trap_constrained() returns FAILURE, one must also make sure cveval() returns FAILURE, otherwise an error message created in ks_eval_trap_constrained() will not be seen in the UI.

There are three wrapper functions to this function (ks_eval_trap(), ks_eval_trap1(), ks_eval_trap2()) that have reduced number of input arguments, and calls ks_eval_trap_constrained() with different preset gradient constraints. ks_eval_trap() makes fewest assumptions, making it the most general choice.

Parameters
[in,out]trapPointer to the KS_TRAP object to be set up
[in]descA description (text string) of the KS_TRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]ampmaxThe maximum allowed gradient amplitude ([G/cm])
[in]slewrateThe maximum allowed slewrate ([(G/cm) / us]). Value of 0.01 corresponds to 100 mT/m/s
[in]mindurationOptional minimum duration ([us]). A zero value is used to disregard this constraint
Return values
STATUSSUCCESS or FAILURE
319  {
320  double triangletrapezoid_area;
321  double maxramp_area;
322  double requested_area;
323  int maxramp_duration;
324  int sign_reqarea;
325  int minplateautime = KS_MINPLATEAUTIME;
326  char tmpdesc[KS_DESCRIPTION_LENGTH];
327 
328  /* store desired inputs before resetting the trap object */
329  requested_area = (double) trap->area;
330  strcpy(tmpdesc, desc); /* copy in case the trap->description has been passed in before ks_init_trap wipes it */
331 
332  /* Reset all fields and waveforms (after saving the desired area) */
333  ks_init_trap(trap);
334 
335  /* put back the input fields */
336  trap->area = requested_area;
337 
338  strncpy(trap->description, tmpdesc, KS_DESCRIPTION_LENGTH - 1);
339  trap->description[KS_DESCRIPTION_LENGTH - 1] = 0;
340 
341  /* don't allow empty description or a description with leading space */
342  if (trap->description == NULL || trap->description[0] == ' ') {
343  return ks_error("ks_eval_trap: trap name (2nd arg) cannot be NULL or leading space");
344  }
345 
346  if (areSame(requested_area, 0)) {
347  return SUCCESS;
348  }
349 
350  /* sign control: Store the sign of the requested area. Ignore all other signs */
351  sign_reqarea = (requested_area < 0) ? -1 : 1;
352  requested_area = fabs(requested_area);
353  slewrate = fabs(slewrate);
354  ampmax = fabs(ampmax);
355 
356  /* make sure the minimum duration is divisible by 8us */
357  minduration = RUP_FACTOR(minduration, 2 * GRAD_UPDATE_TIME);
358 
359 
360  /* area for one ramp from zero to max amplitude ('ampmax') */
361  maxramp_duration = RUP_GRD(ceil((double) ampmax / (double) slewrate)); /* [usec] */
362  maxramp_area = (double) ampmax * ((double) maxramp_duration) / 2.0; /* [G/cm * usec] */
363 
364  /* area for a trapezoid with a plateau time of 'minplateautime' and maximum amplitude ('ampmax') */
365  triangletrapezoid_area = ((double) minplateautime * (double) ampmax) + (2.0 * maxramp_area);
366 
367  if (requested_area > triangletrapezoid_area) {
368  /* ________......ampmax
369  / \
370  / \
371  / \
372  __/ \__
373 
374  We need max target amplitude and use a plateau time > minplateautime to reach required area. [amp = ampmax] */
375 
376  trap->ramptime = maxramp_duration;
377  trap->plateautime = (int) ceil((requested_area - 2.0 * maxramp_area) / (double) ampmax);
378 
379  /* Round *up* to nearest 8us to make the plateau contain an even # of points (which is always nice) */
380  trap->plateautime = RUP_FACTOR(trap->plateautime, 2 * GRAD_UPDATE_TIME);
381 
382 
383  } else {
384  /*
385  ......... ampmax
386 
387  _ amp
388  / \
389  / \
390  __/ \__
391 
392  We don't need max amplitude and will use a minimum plateau time of minplateautime
393  [amp = ramptime * slewrate] */
394 
395  trap->plateautime = minplateautime; /* Our minimum plateau time */
396 
397  /* Quadratic solution in 'ramptime':
398  slewrate*(ramptime)^2 + slewrate*minplateautime*(ramptime) - requested_area = 0
399  ...where: ramptime = unknownamp / slewrate <=> unknownamp = ramptime * slewrate */
400  trap->ramptime = ((int) ceil(pow(requested_area / (double) slewrate + ((double) minplateautime * (double) minplateautime) / 4.0, 0.5))) - minplateautime / 2;
401 
402  /* Round *up* to nearest GRAD_UPDATE_TIME (unit: usec) */
403  trap->ramptime = RUP_GRD(trap->ramptime);
404  }
405 
406 
407  /* amp (G/cm). Make the sign of the amp equal to that of the requested_area */
408  trap->amp = (float) (sign_reqarea * requested_area / ((double) (trap->ramptime + trap->plateautime)));
409 
410  /* amp watchdog */
411  if (fabs(trap->amp) > ampmax)
412  return ks_error("ks_eval_trap: amp (%.3f) of trap '%s' exceeds ampmax (%.3f)", trap->amp, trap->description, ampmax);
413 
414  /* store the duration */
415  trap->duration = trap->ramptime * 2 + trap->plateautime;
416 
417  /* if the duration is smaller than the minimum duration, increase the ramp times and reduce the gradient amp accordingly */
418  if (trap->duration < minduration) {
419  trap->ramptime += (minduration - trap->duration)/2;
420  trap->duration = trap->ramptime * 2 + trap->plateautime;
421  trap->amp = (float) (sign_reqarea * requested_area / ((double) (trap->ramptime + trap->plateautime)));
422  }
423 
424 
425  return SUCCESS;
426 
427 }
int plateautime
Definition: KSFoundation.h:584
#define areSame(a, b)
Definition: KSFoundation.h:119
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
void ks_init_trap(KS_TRAP *trap)
Resets a KS_TRAP sequence object to its default value (KS_INIT_TRAP)
Definition: KSFoundation_host.c:58
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
float area
Definition: KSFoundation.h:582
float amp
Definition: KSFoundation.h:581
KS_DESCRIPTION description
Definition: KSFoundation.h:580
#define KS_MINPLATEAUTIME
Definition: KSFoundation.h:137
int duration
Definition: KSFoundation.h:585
int ramptime
Definition: KSFoundation.h:583

◆ ks_eval_trap()

STATUS ks_eval_trap ( KS_TRAP trap,
const char *const  desc 
)

Sets up a trapezoid using a KS_TRAP sequence object with preset gradient constraints

Before calling this function, the following field in the KS_TRAP object must be set:

  • .area: Desired gradient area in units of [(G/cm) * us]

This is a wrapper function to ks_eval_trap_constrained() with gradient constraints set to allow this KS_TRAP to be simultaneously played on XGRAD, YGRAD, ZGRAD for any slice angulation.

Parameters
[in,out]trapPointer to the KS_TRAP object to be set up
[in]descA description (text string) of the KS_TRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
434  {
435 
437 
438 }
float ks_syslimits_ampmax(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on all gradient boards simultaneously
Definition: KSFoundation_common.c:201
STATUS ks_eval_trap_constrained(KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration)
Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input argu...
Definition: KSFoundation_host.c:319
LOG_GRAD loggrd
float ks_syslimits_slewrate(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on all gradient boards simultaneously
Definition: KSFoundation_common.c:248

◆ ks_eval_trap2()

STATUS ks_eval_trap2 ( KS_TRAP trap,
const char *const  desc 
)

Sets up a trapezoid using a KS_TRAP sequence object with preset gradient constraints

Before calling this function, the following field in the KS_TRAP object must be set:

  • .area: Desired gradient area in units of [(G/cm) * us]

This is a wrapper function to ks_eval_trap_constrained() with gradient constraints set to allow this KS_TRAP to be simultaneously played on up to two (2) logical gradients for any slice angulation.

Parameters
[in,out]trapPointer to the KS_TRAP object to be set up
[in]descA description (text string) of the KS_TRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
440  {
441 
443 
444 }
STATUS ks_eval_trap_constrained(KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration)
Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input argu...
Definition: KSFoundation_host.c:319
LOG_GRAD loggrd
float ks_syslimits_ampmax2(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on two gradient boards simultaneously
Definition: KSFoundation_common.c:205
float ks_syslimits_slewrate2(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on two gradient boards simultaneously
Definition: KSFoundation_common.c:252

◆ ks_eval_trap1()

STATUS ks_eval_trap1 ( KS_TRAP trap,
const char *const  desc 
)

Sets up a trapezoid using a KS_TRAP sequence object with preset gradient constraints

Before calling this function, the following field in the KS_TRAP object must be set:

  • .area: Desired gradient area in units of [(G/cm) * us]

This is a wrapper function to ks_eval_trap_constrained() with gradient constraints set to allow this KS_TRAP to only be played out on one (1) logical gradient at a time. No gradient may be active on another board while this trapezoid is played out.

Parameters
[in,out]trapPointer to the KS_TRAP object to be set up
[in]descA description (text string) of the KS_TRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
446  {
447 
449 
450 }
STATUS ks_eval_trap_constrained(KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration)
Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input argu...
Definition: KSFoundation_host.c:319
float ks_syslimits_slewrate1(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on one gradient board at a time
Definition: KSFoundation_common.c:256
LOG_GRAD loggrd
float ks_syslimits_ampmax1(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on one gradient board at a time...
Definition: KSFoundation_common.c:209

◆ ks_eval_trap_constrained_time_maxarea()

STATUS ks_eval_trap_constrained_time_maxarea ( KS_TRAP trap,
const char *const  desc,
float  ampmax,
float  slewrate,
float  maxarea,
int  derate_slewrate 
)
452  {
453  int requested_time;
454  int maxramp_duration;
455  char tmpdesc[KS_DESCRIPTION_LENGTH];
456  int sign = (maxarea < 0) ? -1 : 1;
457  strcpy(tmpdesc, desc); /* copy in case the trap->description has been passed in before ks_init_trap wipes it */
458 
459  /* make sure the minimum duration is divisible by 8us */
460  requested_time = RDN_FACTOR(trap->duration, 2 * GRAD_UPDATE_TIME);
461  /* Reset all fields and waveforms (after saving the desired area) */
462  ks_init_trap(trap);
463  strncpy(trap->description, tmpdesc, KS_DESCRIPTION_LENGTH - 1);
464  trap->description[KS_DESCRIPTION_LENGTH - 1] = 0;
465 
466  /* don't allow empty description or a description with leading space */
467  if (trap->description == NULL || trap->description[0] == ' ') {
468  return ks_error("%s: trap name (2nd arg) cannot be NULL or leading space", __FUNCTION__);
469  }
470  if (requested_time <= 0) {
471  return SUCCESS;
472  }
473 
474  slewrate = fabs(slewrate); /* [(G/cm) / us] */
475  ampmax = fabs(ampmax); /* [G/cm] */
476  maxramp_duration = RUP_GRD(ceil((double) ampmax / (double) slewrate)); /* [usec] */
477  if ((2*maxramp_duration + KS_MINPLATEAUTIME) > requested_time) {
478  /* Not enough time to make it to the plateau */
480  trap->ramptime = (requested_time - KS_MINPLATEAUTIME) / 2;
481  trap->amp = slewrate * trap->ramptime;
482  } else {
483  /* Enough time to reach plateau */
484  trap->amp = ampmax;
485  trap->ramptime = maxramp_duration;
486  trap->plateautime = (requested_time - 2 * trap->ramptime);
487  }
488 
489  trap->area = (trap->plateautime + trap->ramptime) * trap->amp * sign;
490  if (fabs(trap->area) > fabs(maxarea)) {
491  if (derate_slewrate == 1) {
492  trap->amp = maxarea / (trap->plateautime + trap->ramptime);
493  } else {
494  trap->ramptime = RUP_GRD( (int) ((requested_time - sqrtf(requested_time*requested_time - 4*maxarea/slewrate)) / 2.0));
495  trap->amp = trap->ramptime * slewrate;
496  trap->plateautime = (requested_time - 2 * trap->ramptime);
497  }
498  /* Adjust the amplitude to never go above maxarea */
499  trap->amp *= fabs(maxarea / ((trap->plateautime + trap->ramptime) * trap->amp));
500  trap->area = (trap->plateautime + trap->ramptime) * trap->amp * sign;
501  }
502 
503  trap->duration = trap->ramptime * 2 + trap->plateautime;
504  if (trap->duration != requested_time) {
505  ks_error("%s: Duration mismatch. this should not happen", __FUNCTION__);
506  }
507  return SUCCESS;
508 }
int plateautime
Definition: KSFoundation.h:584
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
void ks_init_trap(KS_TRAP *trap)
Resets a KS_TRAP sequence object to its default value (KS_INIT_TRAP)
Definition: KSFoundation_host.c:58
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
float area
Definition: KSFoundation.h:582
float amp
Definition: KSFoundation.h:581
KS_DESCRIPTION description
Definition: KSFoundation.h:580
#define KS_MINPLATEAUTIME
Definition: KSFoundation.h:137
int duration
Definition: KSFoundation.h:585
int ramptime
Definition: KSFoundation.h:583

◆ ks_eval_set_asym_padding()

STATUS ks_eval_set_asym_padding ( KS_READTRAP readtrap,
float  wanted_paddingarea_pre,
float  wanted_paddingarea_post 
)

◆ ks_eval_trap1p()

STATUS ks_eval_trap1p ( KS_TRAP trap,
const char *const  desc 
)

Sets up a trapezoid using a KS_TRAP sequence object with physical gradient constraints (invariant to slice angulation)

Before calling this function, the following field in the KS_TRAP object must be set:

  • .area: Desired gradient area in units of [(G/cm) * us]

This is a wrapper function to ks_eval_trap_constrained() with physical gradient constraints set to allow this KS_TRAP to only be played out on one (1) logical gradient at a time. No gradient may be active on another board while this trapezoid is played out.

Parameters
[in,out]trapPointer to the KS_TRAP object to be set up
[in]descA description (text string) of the KS_TRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
536  {
537 
539 
540 }
float ks_syslimits_ampmax1p(LOG_GRAD loggrd)
Returns the maximum gradient amplitude on the physical gradient axes
Definition: KSFoundation_common.c:214
STATUS ks_eval_trap_constrained(KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration)
Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input argu...
Definition: KSFoundation_host.c:319
LOG_GRAD loggrd
float ks_syslimits_slewrate1p(LOG_GRAD loggrd)
Returns the maximum gradient amplitude on the physical gradient axes
Definition: KSFoundation_common.c:261

◆ ks_eval_readtrap_constrained()

STATUS ks_eval_readtrap_constrained ( KS_READTRAP readtrap,
const char *const  desc,
float  ampmax,
float  slewrate 
)

Sets up an acquisition window with a trapezoid, subject to gradient constraints specified as input arguments

Before calling this function, the following fields in the KS_READTRAP object must be set:

  1. .fov: Desired image Field-of-View (FOV) in [mm] along the sequence board one intends to place the KS_READTRAP on (typically XGRAD)
  2. .res: Number of pixels within the FOV
  3. .acq.rbw: Receiver bandwidth (rBW) in [kHz/FOV]. Maximum is 250
  4. .rampsampling: If non-zero, data acquisition will be performed on the ramps of the trapezoid as well. This reduces the readout time, especially for high rBWs.
  5. .acqdelay: Needs to be set only if .rampsampling = 1. The .acqdelay (in [us]) will dictate the time from the start of the ramp-up until data acquisition will begin
  6. .nover: Number of 'overscans'. If 0, a full echo will be generated (filling k-space). If > 0, fractional echo (i.e. shorter TE) will be set up with .nover number of extra sample points beyond .res/2. The total number of samples will be .res/2 + .nover. Values of .nover between 1 and about 16 should be avoided since half Fourier reconstruction methods will likely have difficulties.

If the KS_READTRAP object is initialized with KS_INIT_READTRAP, the fields .nover, .rampsampling and .acqdelay will all be zero (steps 4-6 can be skipped)

Based on the information in the KS_READTRAP object, ks_eval_readtrap_constrained() will set up its .grad trapezoid (KS_TRAP) and its acquisition window .acq (KS_READ), constrained by the specified maximum gradient amplitude, slewrate, and minimum plateau time (args 3-5).

If .rampsampling = 1, ks_eval_readtrap_constrained() will also copy the shape of .grad to .omega (also a KS_TRAP). This is needed for FOV-offsets in the readout direction when data acquisition is done on both the ramps and on the plateau, and ks_pg_readtrap() and ks_scan_offsetfov() will handle the .omega KS_TRAP so that the intended FOV shift in [mm] will be performed.

ks_eval_readtrap_constrained() will also fill in the convenience fields .area2center and .time2center properly. .area2center is useful to use as .area for a read dephaser, and .time2center makes sequence timing calculations easier. Both fields take partial/full Fourier (.nover) into account.

If ks_eval_readtrap_constrained() returns FAILURE, one must also make sure cveval() returns FAILURE, otherwise an error message created in ks_eval_readtrap_constrained() will not be seen in the UI.

There are three wrapper functions to this function (ks_eval_readtrap(), ks_eval_readtrap1(), ks_eval_readtrap2()) that have reduced number of input arguments, and calls ks_eval_readtrap_constrained() with different preset gradient constraints. ks_eval_readtrap() makes fewest assumptions, making it the most general choice.

Parameters
[in,out]readtrapPointer to the KS_READTRAP object to be set up
[in]descA description (text string) of the KS_READTRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]ampmaxThe maximum allowed gradient amplitude ([G/cm])
[in]slewrateThe maximum allowed slewrate ([(G/cm) / us]). Value of 0.01 corresponds to 100 mT/m/s
Return values
STATUSSUCCESS or FAILURE
545  {
546  float minfov;
547  int tsp = 0;
548  float readpixelarea;
549  int nreadpixels;
550  float nonacq_readarea;
551  float ampmax_kspace_speedlimit;
552 
553  /* This function is for setting up readout trapezoid with fixed amplitude based on FOV and rBW */
554 
555  if (desc == NULL || desc[0] == ' ') {
556  return ks_error("ks_eval_readtrap: desc (2nd arg) cannot be NULL");
557  }
558  if (areSame(readtrap->acq.rbw, 0) || isNotSet(readtrap->acq.rbw)) {
559  return ks_error("ks_eval_readtrap: field 'acq.rbw' (1st arg) is not set");
560  }
561 
562  /* reset KS_TRAP's */
563  ks_init_trap(&readtrap->grad);
564  ks_init_trap(&readtrap->omega);
565 
566 
567  /* round rBW to nearest valid value */
568  readtrap->acq.rbw = ks_calc_nearestbw(readtrap->acq.rbw);
569  tsp = ks_calc_bw2tsp(readtrap->acq.rbw); /* us per sample point */
570 
571  minfov = ks_calc_minfov(ampmax, tsp);
572 
573  /* Programmer's error */
574  if (readtrap->res % 2 || readtrap->res <= 0 || readtrap->res > 2048) {
575  return ks_error("ks_eval_readtrap(%s): field 'res' must be even and in the range 2-2048", desc);
576  }
577  if (readtrap->fov < 10 || readtrap->fov > 600) {
578  return ks_error("ks_eval_readtrap(%s): field 'fov' must be in the range 10-600 mm", desc);
579  }
580  if (abs(readtrap->nover) > readtrap->res / 2) {
581  return ks_error("ks_eval_readtrap(%s): field 'nover' may not exceed res/2", desc);
582  }
583  if (readtrap->acq.rbw > 250) {
584  return ks_error("ks_eval_readtrap(%s): rBW cannot exceed +/- 250 kHz/FOV", desc);
585  }
586  /* Operator's error */
587  if (readtrap->fov < minfov && readtrap->rampsampling == 0) {
588  return ks_error("%s: Please increase the FOV to %.1f [cm] or decrease the rBW", desc, minfov / 10.0);
589  }
590 
591  if (abs(readtrap->nover)) {
592  nreadpixels = readtrap->res / 2 + abs(readtrap->nover);
593  } else {
594  nreadpixels = readtrap->res;
595  }
596  if (nreadpixels % 2) {
597  return ks_error("ks_eval_readtrap(%s): number of sampling points must be even (%d)", desc, nreadpixels);
598  }
599 
600 
601  if (readtrap->rampsampling == 1) { /* rampsampling */
602 
603  /* Gradient area necessary to move one pixel in k-space in the read direction */
604  readpixelarea = ks_calc_fov2gradareapixel(readtrap->fov); /* [(G/cm)*usec] */
605 
606  /* Speed limit the readout (i.e. put a cap on the readout amplitude) based on the FOV and the chosen rBW */
607  ampmax_kspace_speedlimit = FMin(2, readpixelarea / tsp, ampmax);
608 
609  /* delay of ACQ start relative to the beginning of the attack ramp.
610  For rampsampled cases, this value should be at least one dwell time (tsp) */
611  if (readtrap->acqdelay < 2 * tsp) {
612  readtrap->acqdelay = 2 * tsp;
613  }
614 
615  readtrap->acqdelay = RUP_FACTOR(readtrap->acqdelay, 2);
616 
617  /* gradient area before and after the acq window */
618  nonacq_readarea = slewrate /* [G/cm/usec] */ * (readtrap->acqdelay) * (readtrap->acqdelay) /* [usec^2] */; /* from both sides of the readout */
619 
620  /* required gradient area: gradient area needed during the acq window + nonacq_readarea */
621  readtrap->grad.area = (readpixelarea * nreadpixels) + nonacq_readarea;
622 
623  if (ks_eval_trap_constrained(&readtrap->grad, desc, ampmax_kspace_speedlimit, slewrate, 0) == FAILURE)
624  return FAILURE;
625 
626 
627  if (readtrap->grad.ramptime > readtrap->acqdelay) {
628  /* rampsampling attempt ok, continue calculating area2center and time2center */
629 
630  if (readtrap->nover > 0) { /* partial Fourier on the first part of the readout */
631  readtrap->area2center = readpixelarea * readtrap->nover + nonacq_readarea / 2;
632  } else { /* Full Fourier, or partial Fourier on the last part of the readout */
633  readtrap->area2center = readpixelarea * readtrap->res / 2 + nonacq_readarea / 2;
634  }
635 
636  /* area = (s*t^2)/2 [G/cm/usec] * [usec^2] */
637  if (readtrap->area2center < slewrate * (readtrap->grad.ramptime * readtrap->grad.ramptime / 2.0)) {
638  /* k-space center is on the attack ramp */
639  readtrap->time2center = (int) sqrt(readtrap->area2center * 2.0 / slewrate);
640  } else {
641  float arealeftonplateau = readtrap->area2center - (readtrap->grad.ramptime * readtrap->grad.amp / 2.0);
642  readtrap->time2center = (int) readtrap->grad.ramptime + (arealeftonplateau / readtrap->grad.amp); /* whole ramp + some plateau time */
643  }
644 
645  /* round up the readout window time to the nearest multiple of '2*tsp' to always make filt.outputs even */
646  readtrap->acq.duration = RUP_FACTOR(readtrap->grad.duration - readtrap->acqdelay * 2, (int) (2 * tsp));
647 
648  /* update 'acqdelay' due to this potential roundoff */
649  readtrap->acqdelay = (readtrap->grad.duration - readtrap->acq.duration) / 2;
650 
651  } else {
652 
653  readtrap->rampsampling = 0; /* let's skip ramp sampling then (and be caught by the next non-rampsampled case) */
654 
655  }
656 
657  } /* rampsampling */
658 
659 
660 
661 
662  if (readtrap->rampsampling == 0) { /* No rampsampling */
663 
664  if (desc[0] == ' ') {
665  ks_init_trap(&readtrap->grad);
666  return ks_error("ks_eval_readtrap: desc (2nd arg) cannot begin with a space");
667  } else {
668  strncpy(readtrap->grad.description, desc, KS_DESCRIPTION_LENGTH - 1);
669  readtrap->grad.description[KS_DESCRIPTION_LENGTH - 1] = 0;
670  }
671 
672  /* Error if requested constraints cannot be fullfilled */
673  if (readtrap->fov < minfov) {
674  return ks_error("%s: %s - Please increase the FOV to %.1f [cm] or decrease the rBW", __FUNCTION__, desc, minfov / 10.0);
675  }
676 
677  readtrap->grad.amp = ((float) (1.0 / (GAM * tsp * 1e-6) * (10.0 / readtrap->fov))); /* [G/cm] */
678  readtrap->grad.ramptime = RUP_GRD(readtrap->grad.amp / slewrate); /* [usec] */
679  readtrap->acq.duration = RUP_GRD(nreadpixels * tsp);
680 
681  /* adjust plateau time to account for padding */
682  const float ramparea = readtrap->grad.ramptime * readtrap->grad.amp / 2.0;
683  const int extradelay = RUP_GRD(FMax(2, readtrap->paddingarea - ramparea, 0.0) / readtrap->grad.amp);
684  readtrap->grad.plateautime = readtrap->acq.duration + 2*extradelay; /* [usec] */ /* Nkx * dwell time */
685 
686  readtrap->grad.duration = readtrap->grad.plateautime + readtrap->grad.ramptime * 2; /* [usec] */
687  readtrap->grad.area = (readtrap->grad.plateautime + readtrap->grad.ramptime) * readtrap->grad.amp; /* rounding effects */
688 
689  /* ACQ starts after the attack ramp */
690  readtrap->acqdelay = readtrap->grad.ramptime + extradelay;
691 
692  const int pixelstocenter = readtrap->nover > 0 ?
693  readtrap->nover : /* partial Fourier on the first part of the readout */
694  readtrap->res/2; /* Full Fourier, or partial Fourier on the last part of the readout */
695 
696  readtrap->area2center = (readtrap->grad.ramptime/2 + tsp * pixelstocenter + extradelay) * readtrap->grad.amp;
697  readtrap->time2center = readtrap->grad.ramptime + tsp * pixelstocenter + extradelay;
698 
699  } /* no rampsampling */
700 
701 
702 
703 
704  /* round up to nearest multiple of GRAD_UPDATE_TIME (4us) */
705  readtrap->time2center = RUP_GRD(readtrap->time2center);
706 
707 
708  /* setup acq window */
709  /* readtrap->acq.rbw is set > 0 by the calling function */
710  KS_DESCRIPTION read_description;
711  sprintf(read_description, "%s.echo", readtrap->grad.description);
712  if (ks_eval_read(&readtrap->acq, read_description) == FAILURE) {
713  return FAILURE;
714  }
715 
716  /* for rampsampling, create an omega waveform (for FOV shifts in the freq (read) direction for rampsampling) */
717  if (readtrap->rampsampling) {
718  readtrap->omega = readtrap->grad; /* copy the shape of the readout */
719  readtrap->omega.amp = 1.0; /* just unity value for conformance. It does not matter during scanning, since ks_scan_omegatrap_hz() ignores this value */
720  readtrap->omega.area = 0.0; /* Omega area has no meaning */
721  sprintf(readtrap->omega.description, "%s.omega", readtrap->grad.description);
722  } else {
723  readtrap->omega.duration = 0;
724  }
725 
726 
727  return SUCCESS;
728 }
int plateautime
Definition: KSFoundation.h:584
float ks_calc_nearestbw(float bw)
Round receiver bandwidth to nearest valid value
Definition: KSFoundation_host.c:4740
#define areSame(a, b)
Definition: KSFoundation.h:119
float ks_calc_fov2gradareapixel(float fov)
Calculates the gradient area needed to move one pixel in k-space
Definition: KSFoundation_common.c:346
float ks_calc_minfov(float ampmax, int tsp)
Calculates the minimum readout FOV
Definition: KSFoundation_common.c:319
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
void ks_init_trap(KS_TRAP *trap)
Resets a KS_TRAP sequence object to its default value (KS_INIT_TRAP)
Definition: KSFoundation_host.c:58
float fov
Definition: KSFoundation.h:1576
STATUS ks_eval_trap_constrained(KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration)
Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input argu...
Definition: KSFoundation_host.c:319
float rbw
Definition: KSFoundation.h:734
KS_TRAP grad
Definition: KSFoundation.h:1586
float paddingarea
Definition: KSFoundation.h:1581
float GAM
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
KS_TRAP omega
Definition: KSFoundation.h:1587
int res
Definition: KSFoundation.h:1577
int ks_calc_bw2tsp(float bw)
Convert receiver bandwidth to dwell time
Definition: KSFoundation_host.c:4722
STATUS ks_eval_read(KS_READ *read, const char *const desc)
Sets up a data acquisition window using a KS_READ sequence object
Definition: KSFoundation_host.c:270
int duration
Definition: KSFoundation.h:733
float area
Definition: KSFoundation.h:582
float amp
Definition: KSFoundation.h:581
KS_DESCRIPTION description
Definition: KSFoundation.h:580
int nover
Definition: KSFoundation.h:1579
int rampsampling
Definition: KSFoundation.h:1578
KS_READ acq
Definition: KSFoundation.h:1574
int duration
Definition: KSFoundation.h:585
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int time2center
Definition: KSFoundation.h:1585
float area2center
Definition: KSFoundation.h:1584
#define isNotSet(a)
Definition: KSFoundation.h:124
int acqdelay
Definition: KSFoundation.h:1580
int ramptime
Definition: KSFoundation.h:583

◆ ks_eval_readtrap()

STATUS ks_eval_readtrap ( KS_READTRAP readtrap,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with preset gradient constraints

This is a wrapper function to ks_eval_readtrap_constrained() with gradient constraints set to allow this KS_READTRAP to simultaneously be played on XGRAD, YGRAD, ZGRAD for any slice angulation. This is the generic and safest configuration, but for readouts with small FOV and high rBW, the gradient limits may be reached, especially for double oblique slices. See ks_eval_readtrap_constrained() for details on fields that need to be set before calling this function.

Parameters
[in,out]readtrapPointer to the KS_READTRAP object to be set up
[in]descA description (text string) of the KS_READTRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
733  {
734 
735  return ks_eval_readtrap_constrained(readtrap, desc,
737 
738 }
float ks_syslimits_ampmax(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on all gradient boards simultaneously
Definition: KSFoundation_common.c:201
STATUS ks_eval_readtrap_constrained(KS_READTRAP *readtrap, const char *const desc, float ampmax, float slewrate)
Sets up an acquisition window with a trapezoid, subject to gradient constraints specified as input ar...
Definition: KSFoundation_host.c:545
LOG_GRAD loggrd
float ks_syslimits_slewrate(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on all gradient boards simultaneously
Definition: KSFoundation_common.c:248

◆ ks_eval_readtrap2()

STATUS ks_eval_readtrap2 ( KS_READTRAP readtrap,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with preset gradient constraints

This is a wrapper function to ks_eval_readtrap_constrained() with gradient constraints set to allow this KS_TRAP to simultaneously be played on up to two (2) logical gradients for any slice angulation. For double oblique slice angulations, this function will allow for smaller FOVs and higher rBWs than ks_eval_readtrap().

See ks_eval_readtrap_constrained() for details on fields that need to be set before calling this function.

Parameters
[in,out]readtrapPointer to the KS_READTRAP object to be set up
[in]descA description (text string) of the KS_READTRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
741  {
742 
743  return ks_eval_readtrap_constrained(readtrap, desc,
745 
746 }
STATUS ks_eval_readtrap_constrained(KS_READTRAP *readtrap, const char *const desc, float ampmax, float slewrate)
Sets up an acquisition window with a trapezoid, subject to gradient constraints specified as input ar...
Definition: KSFoundation_host.c:545
LOG_GRAD loggrd
float ks_syslimits_ampmax2(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on two gradient boards simultaneously
Definition: KSFoundation_common.c:205
float ks_syslimits_slewrate2(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on two gradient boards simultaneously
Definition: KSFoundation_common.c:252

◆ ks_eval_readtrap1()

STATUS ks_eval_readtrap1 ( KS_READTRAP readtrap,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with preset gradient constraints

This is a wrapper function to ks_eval_readtrap_constrained() with gradient constraints set to allow this KS_TRAP to only be played out on one (1) logical gradient at a time. No gradient may be active on another board while this trapezoid is played out. For double oblique slice angulations, this function will allow for smaller FOVs and higher rBWs than ks_eval_readtrap() and ks_eval_readtrap2(). See ks_eval_readtrap_constrained() for details on fields that need to be set before calling this function.

Parameters
[in,out]readtrapPointer to the KS_READTRAP object to be set up
[in]descA description (text string) of the KS_READTRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
748  {
749 
750  return ks_eval_readtrap_constrained(readtrap, desc,
752 
753 }
float ks_syslimits_slewrate1(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on one gradient board at a time
Definition: KSFoundation_common.c:256
STATUS ks_eval_readtrap_constrained(KS_READTRAP *readtrap, const char *const desc, float ampmax, float slewrate)
Sets up an acquisition window with a trapezoid, subject to gradient constraints specified as input ar...
Definition: KSFoundation_host.c:545
LOG_GRAD loggrd
float ks_syslimits_ampmax1(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on one gradient board at a time...
Definition: KSFoundation_common.c:209

◆ ks_eval_readtrap_constrained_sample_duration()

STATUS ks_eval_readtrap_constrained_sample_duration ( KS_READTRAP readtrap,
const char *const  desc,
const float  ampmax,
const float  slewrate,
const int  t_A,
const int  sample_duration,
const float  area_post,
const float  area_total 
)

◆ ks_eval_dixon_wang()

STATUS ks_eval_dixon_wang ( struct _dixon_dualreadtrap_s *  dual_read,
const char *const  desc,
const float  PF,
float  M 
)

◆ ks_eval_dixon_dualreadtrap()

STATUS ks_eval_dixon_dualreadtrap ( struct _dixon_dualreadtrap_s *  dual_read,
const char *const  desc,
int  flip 
)

◆ ks_verify_dualreadtrap_setup()

STATUS ks_verify_dualreadtrap_setup ( struct _dixon_dualreadtrap_s *  dual_read)

◆ ks_eval_dixon_dualreadtrap_slim()

STATUS ks_eval_dixon_dualreadtrap_slim ( struct _dixon_dualreadtrap_s *  dual_read,
const char *const  desc,
int  flip 
)

◆ ks_eval_dixon_asymtriangle_padded()

STATUS ks_eval_dixon_asymtriangle_padded ( struct _dixon_asymreadwave_s *  asym_readwave,
const char *const  desc,
const int  tas,
const int  time2center,
const float  area_pre,
const float  area_acq,
const float  fov,
const int  duration 
)

◆ ks_eval_dixon_asymspline_padded()

STATUS ks_eval_dixon_asymspline_padded ( struct _dixon_asymreadwave_s *  asym_readwave,
const char *const  desc,
const int  tas,
const int  time2center,
const int  tae,
const float  Apre,
const float  Aacq,
const float  Apost,
const float  fov,
const int  duration 
)

◆ ks_eval_dixon_asymspline()

STATUS ks_eval_dixon_asymspline ( struct _dixon_asymreadwave_s *  asym_readwave,
const char *const  desc,
const int  time2center,
const float  area,
const float  fov,
const int  duration,
const float  paddingarea 
)

◆ ks_eval_dixon_asymtriangle()

STATUS ks_eval_dixon_asymtriangle ( struct _dixon_asymreadwave_s *  asym_readwave,
const char *const  desc,
const int  ttc,
const float  area,
const float  fov,
const int  duration,
const float  paddingarea 
)

◆ ks_eval_readtrap1p()

STATUS ks_eval_readtrap1p ( KS_READTRAP readtrap,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with physical gradient constraints (invariant to slice angulation)

This is a wrapper function to ks_eval_readtrap_constrained() with physical gradient constraints

Parameters
[in,out]readtrapPointer to the KS_READTRAP object to be set up
[in]descA description (text string) of the KS_READTRAP object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE

◆ ks_eval_kynover_fromnex()

int ks_eval_kynover_fromnex ( int  yres,
float  nex,
int  minkynover 
)
1854  {
1855  int kynover;
1856 
1857  if (nex < 1) {
1858  kynover = yres * (nex - 0.5);
1859  kynover = ((kynover + 1) / 2) * 2; /* round to nearest even number */
1860  if (kynover < minkynover) {
1861  kynover = minkynover; /* protect against too few overscans */
1862  }
1863  kynover = IMin(2, kynover, yres / 2);
1864  } else {
1865  kynover = 0;
1866  }
1867 
1868  return kynover;
1869 
1870 }

◆ ks_eval_phaseviewtable()

void ks_eval_phaseviewtable ( KS_PHASER phaser)

Sets up which lines to acquire for a KS_PHASER object

This function sets the following fields in a KS_PHASER object

  1. .numlinestoacq: Number of phase encoding lines to acquire
  2. .linetoacq[]: Array, where the first .numlinestoacq elements denotes which lines to acquire with indices corresponding to a fully sampled k-space. The top-most line has index 0 and the bottom-most line has index (.res-1).

These two fields are set based on .res, .nover, .nacslines, and .R in the KS_PHASER object. If .nover < 0, partial Fourier will be set up, but with flipped k-space coverage

Parameters
[in,out]phaserPointer to the KS_PHASER object to be set up
Returns
void
1875  {
1876  int i, index, firstline, lastline, halfacslines;
1877  short viewonflag[KS_MAX_PHASEDYN];
1878 
1879  /* reset arrays */
1880  for (i = 0; i < KS_MAX_PHASEDYN; i++) {
1881  phaser->linetoacq[i] = 0;
1882  viewonflag[i] = 0;
1883  }
1884 
1885  if (phaser->nover == 0) {
1886  firstline = 0;
1887  lastline = phaser->res - 1;
1888  } else if (phaser->nover > 0) { /* fractional ky upper half */
1889  firstline = 0;
1890  lastline = phaser->res / 2 + phaser->nover - 1;
1891  } else {
1892  firstline = phaser->res / 2 + phaser->nover; /* NOTE: phase->nover here negative ! */
1893  lastline = phaser->res - 1;
1894  }
1895 
1896  if ((lastline - firstline + 1) % 2) {
1897  /* /vobs/vre/recon/rcapps/rc_filter.cpp requires that rhdayres is odd (according to ARC.e) */
1898  ks_error("%s: #k-space lines *spanned* must be even",__FUNCTION__);
1899  }
1900 
1901  int acscenter = (phaser->res / 2) + phaser->acsshift;
1902 
1903  /* lower half of k-space: mark the lines to acquire with '1' */
1904  halfacslines = phaser->nacslines / 2;
1905  for (i = acscenter; i <= lastline; i++) {
1906  if (((i + 1) % phaser->R) == 1 || phaser->R == 1) {
1907  viewonflag[i] = 1;
1908  } else if (halfacslines > 0) {
1909  viewonflag[i] = 1;
1910  halfacslines--;
1911  }
1912  }
1913 
1914  /* upper half of k-space: mark the lines to acquire with '1' */
1915  halfacslines = phaser->nacslines - (phaser->nacslines / 2) + halfacslines;
1916  for (i = acscenter - 1; i >= 0; i--) {
1917  if (((i + 1) % phaser->R) == 1 || phaser->R == 1) {
1918  viewonflag[i] = 1;
1919  } else if (halfacslines > 0) {
1920  viewonflag[i] = 1;
1921  halfacslines--;
1922  }
1923  }
1924 
1925  /* sweep kspace linearly and save the line numbers to acquire.
1926  firstline/lastline handles full/partial Fourier */
1927  index = 0;
1928  for (i = firstline; i <= lastline; i++) {
1929  if (viewonflag[i]) {
1930  phaser->linetoacq[index++] = i;
1931  }
1932  }
1933  phaser->numlinestoacq = index;
1934 
1935 }
int R
Definition: KSFoundation.h:1680
int res
Definition: KSFoundation.h:1678
int nacslines
Definition: KSFoundation.h:1681
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
int numlinestoacq
Definition: KSFoundation.h:1684
int linetoacq[KS_MAX_PHASEDYN]
Definition: KSFoundation.h:1685
int nover
Definition: KSFoundation.h:1679
int acsshift
Definition: KSFoundation.h:1682
#define KS_MAX_PHASEDYN
Definition: KSFoundation.h:191

◆ ks_eval_phaser_adjustres()

STATUS ks_eval_phaser_adjustres ( KS_PHASER phaser,
const char *const  desc 
)

Adjusts the phase encoding resolution to the nearest valid value

Phase resolution must be divisible by .R and be even, and there are additional requirements for partial ky Fourier scans. Moreover, for parallel imaging using ASSET, only the acquired lines are stored in the data (compressed BAM), resulting in an R times lower value for rhnframes.

Here are the rules:

  • Resolution (and overscan) choice must guarantee that (rhhnover + rhnframes) is an even number
  • Full Fourier, ASSET:
    • rhnframes = res / R
    • rhhnover = 0
    • => res / R must be even
  • Partial Fourier:
    • rhnframes = (res / 2) / R
    • rhhnover = overscans/R
    • => res / (2 * R) and (res / (2 * R) + overscans) must be even
      • overscans/R and (res/2)/R must be integers
      • => res must be divisible by (4 * R)
      • => overscans must be divisible by (2 * R)
Parameters
[in,out]phaserPointer to KS_PHASER
[in]descA description (text string) of the KS_PHASER object, only used for error msg
Return values
STATUSSUCCESS or FAILURE
1939  {
1940 
1941  int kspacelines_noacc;
1942 
1943  if (phaser->nover == 0)
1944  kspacelines_noacc = phaser->res;
1945  else
1946  kspacelines_noacc = phaser->res / 2 + abs(phaser->nover);
1947 
1948  if (kspacelines_noacc < phaser->R) {
1949  /* Number of k-space lines less than R */
1950  return ks_error("%s(%s): R cannot exceed %d", __FUNCTION__, desc, kspacelines_noacc);
1951  } else if (kspacelines_noacc == phaser->R) {
1952  /* Number of k-space lines equal to R. Used for EPI when R is used as shots to produce ETL = 1.
1953  Just make sure that res is even */
1954  if (phaser->res % 2) {
1955  return ks_error("%s(%s): res must be even", __FUNCTION__, desc);
1956  } else {
1957  return SUCCESS;
1958  }
1959  }
1960 
1961  if (phaser->nover != 0) {
1962  /* partial Fourier */
1963  const int sign_nover = (phaser->nover >= 0) ? 1 : -1;
1964  phaser->nover = abs(phaser->nover);
1965  int invalidnover = TRUE;
1966 
1967  /* round res and nover to nearest valid values */
1968  if (phaser->R % 2) { /* R is odd */
1969  phaser->res = RUP_FACTOR(phaser->res - 2 * phaser->R, 4 * phaser->R);
1970  phaser->nover = RUP_FACTOR(phaser->nover - phaser->R, 2 * phaser->R) * sign_nover;
1971  invalidnover = phaser->nover < (2 * phaser->R) || phaser->nover > (phaser->res / 2);
1972  } else { /* R is even */
1973  phaser->res = RUP_FACTOR(phaser->res - phaser->R, 2 * phaser->R);
1974  phaser->nover = RUP_FACTOR(phaser->nover - phaser->R/2, phaser->R) * sign_nover;
1975  invalidnover = phaser->nover < phaser->R || phaser->nover > (phaser->res / 2);
1976  }
1977 
1978  if (invalidnover) {
1979  return ks_error("%s(%s): Valid #overscans not found", __FUNCTION__, desc);
1980  }
1981 
1982  } else {
1983  /* full Fourier */
1984 
1985  phaser->res = RUP_FACTOR(phaser->res - phaser->R, 2 * phaser->R);
1986 
1987  }
1988 
1989  return SUCCESS;
1990 }
int R
Definition: KSFoundation.h:1680
int res
Definition: KSFoundation.h:1678
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
int nover
Definition: KSFoundation.h:1679

◆ ks_eval_phaser_setaccel()

STATUS ks_eval_phaser_setaccel ( KS_PHASER phaser,
int  min_acslines,
float  R 
)

[ks_eval_phaser_setaccel description]

Parameters
[in,out]phaserPointer to KS_PHASER
[in]min_acslinesMinimum # of ACS lines
[in]R(floating point) acceleration (taken e.g. from the UI opaccel_ph_stride)
Return values
STATUSSUCCESS or FAILURE
1995  {
1996 
1997  if (R <= 1.0) {
1998  phaser->R = 1.0;
1999  phaser->nacslines = 0;
2000  return SUCCESS;
2001  }
2002 
2003  /* Get integer acceleration and store the Rfraction for ARC mode */
2004  double Rfraction = ceil(R) - R;
2005  if (Rfraction > 0.9999) { /* handle roundoff issues for e.g. R=2.0000001 */
2006  Rfraction = 0.0;
2007  }
2008  phaser->R = floor(R + Rfraction + 0.5); /* round-up R to nearest integer */
2009 
2010  if (min_acslines == 0) {
2011  /* ASSET mode */
2012 
2013  /* phaser.nacslines = 0 triggers ASSET scan mode in GEReq_predownload_setrecon_accel() */
2014  phaser->nacslines = 0;
2015 
2016  } else {
2017  /* ARC mode */
2018 
2019  double totlines_spanned = (phaser->nover != 0) ? (phaser->res / 2 + abs(phaser->nover)) : phaser->res;
2020  double acqlines_R = totlines_spanned / phaser->R;
2021  double acqlines_floorR = totlines_spanned / FMax(2, 1.0, floor(R));
2022 
2023  /* adapt #acs lines based on the fraction of the acceleration factor, but never go below min_acslines */
2024  phaser->nacslines = IMax(2, (int) ((acqlines_floorR - acqlines_R) * Rfraction), min_acslines);
2025 
2026  }
2027 
2028  return SUCCESS;
2029 }
int R
Definition: KSFoundation.h:1680
int res
Definition: KSFoundation.h:1678
int nacslines
Definition: KSFoundation.h:1681
int nover
Definition: KSFoundation.h:1679

◆ ks_eval_phaser_constrained()

STATUS ks_eval_phaser_constrained ( KS_PHASER phaser,
const char *const  desc,
float  ampmax,
float  slewrate,
int  minplateautime 
)

Sets up a trapezoid for phase encoding, subject to gradient constraints specified as input arguments

Before calling this function, the following fields in KS_PHASER must be set up:

  1. .fov: The desired image Field-of-View (FOV) in [mm] along the sequence board one intends to place the KS_PHASER on (typically YGRAD, for 3D also ZGRAD)
  2. .res: The number of pixels within the FOV
  3. .nover: Number of 'overscans'. If 0, a full-Fourier k-space will be set up. If > 0, partial Fourier will be set up (shorter scan time) where .nover number of extra k-space lines beyond .res/2. If < 0, partial Fourier will be set up, but with flipped k-space coverage. The total number of samples will be .res/2 + abs(.nover). Absolute values of .nover between 1 and about 16 should be avoided since half Fourier reconstruction methods will likely have difficulties
  4. .R: The parallel imaging acceleration factor
  5. .nacslines: If .R > 1, the value of .nacslines is the number of calibration lines around k-space center for parallel imaging calibration
  6. .areaoffset: It is possible to embed a static gradient area in the phase encoding functionality of KS_PHASER. This is useful for 3D imaging, where the area needed for the rephaser for the slice select gradient can be put into .areaoffset. This makes the KS_PHASER to act as both slice rephaser and slice phase encoding gradient, which can shorten TE

If the KS_PHASER object is initialized with KS_INIT_PHASER, .nover, .nacslines and .areaoffset will be zero, and .R will be 1 (steps 3-6 can be skipped)

Based on the information in the KS_PHASER object, ks_eval_phaser_constrained() will set up the .grad trapezoid (KS_TRAP). By internally calling ks_eval_phaseviewtable(), .numlinestoacq, and the array .linetoacq[] are also set up. The field .numlinestoacq is an integer corresponding to the actual number of lines to acquire, and also the number of elements to read in .linetoacq[], containing the complete list of phase encoding lines to acquire (honoring partial Fourier, parallel imaging acceleration and ACS lines)

If ks_eval_phaser_constrained() returns FAILURE, one must also make sure cveval() returns FAILURE, otherwise an error message created in ks_eval_phaser_constrained() will not be seen in the UI

There are three wrapper functions to this function (ks_eval_phaser(), ks_eval_phaser1(), ks_eval_phaser2()) that have reduced number of input arguments, and calls ks_eval_phaser_constrained() with different preset gradient constraints. ks_eval_phaser() makes fewest assumptions, making it the most general choice

Parameters
[in,out]phaserPointer to the KS_PHASER object to be set up
[in]descA description (text string) of the KS_PHASER object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]ampmaxThe maximum allowed gradient amplitude ([G/cm])
[in]slewrateThe maximum allowed slewrate ([(G/cm) / us]). Value of 0.01 corresponds to 100 mT/m/s
[in]minplateautimeThe minimum plateau time of the trapezoid ([us])
Return values
STATUSSUCCESS or FAILURE
2036  {
2037  float phasepixelarea;
2038 
2039  ks_init_trap(&phaser->grad);
2040 
2041  if (phaser->fov < 5 || phaser->fov > 600) {
2042  return ks_error("%s(%s): field 'fov' must be in the range 5-600 mm", __FUNCTION__, phasername);
2043  }
2044 
2045  /* adjust res and possibly nover to allow both ARC and ASSET scans with full and partial ky Fourier */
2046  if (ks_eval_phaser_adjustres(phaser, phasername) == FAILURE) {
2047  return FAILURE;
2048  }
2049 
2050  phasepixelarea = ks_calc_fov2gradareapixel(phaser->fov); /* [(G/cm)*usec] */
2051 
2052  /* area required to reach the outermost phase encoding step (incl. areaoffset)
2053  N.B.: The *sign* of the area is controlled in scan using ks_scan_phaser_toline(), hence on HOST all phase encoding gradient will be positive, unlike TGT */
2054  phaser->grad.area = ((phaser->res - 1.0) / 2.0) * phasepixelarea + fabs(phaser->areaoffset); /* .areaoffset is used in 3D imaging to embed e.g. a slice sel. rephaser in the phase encoding gradient */
2055 
2056  /* setup phaser trap */
2057  if (!areSame(phaser->grad.area, 0.0)) {
2058  if (ks_eval_trap_constrained(&phaser->grad, phasername, ampmax, slewrate, minduration) == FAILURE)
2059  return FAILURE;
2060  }
2061 
2062  /* setup phaser->linetoacq[] */
2063  ks_eval_phaseviewtable(phaser);
2064 
2065 
2066  return SUCCESS;
2067 
2068 }
int res
Definition: KSFoundation.h:1678
#define areSame(a, b)
Definition: KSFoundation.h:119
KS_TRAP grad
Definition: KSFoundation.h:1676
float ks_calc_fov2gradareapixel(float fov)
Calculates the gradient area needed to move one pixel in k-space
Definition: KSFoundation_common.c:346
STATUS ks_eval_phaser_adjustres(KS_PHASER *phaser, const char *const desc)
Adjusts the phase encoding resolution to the nearest valid value
Definition: KSFoundation_host.c:1939
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
void ks_init_trap(KS_TRAP *trap)
Resets a KS_TRAP sequence object to its default value (KS_INIT_TRAP)
Definition: KSFoundation_host.c:58
STATUS ks_eval_trap_constrained(KS_TRAP *trap, const char *const desc, float ampmax, float slewrate, int minduration)
Sets up a trapezoid using a KS_TRAP sequence object with gradient constraints specified as input argu...
Definition: KSFoundation_host.c:319
float areaoffset
Definition: KSFoundation.h:1683
float area
Definition: KSFoundation.h:582
float fov
Definition: KSFoundation.h:1677
void ks_eval_phaseviewtable(KS_PHASER *phaser)
Sets up which lines to acquire for a KS_PHASER object
Definition: KSFoundation_host.c:1875

◆ ks_eval_phaser()

STATUS ks_eval_phaser ( KS_PHASER phaser,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with preset gradient constraints

This is a wrapper function to ks_eval_phaser_constrained() with gradient constraints set to allow this KS_PHASER to simultaneously be played on XGRAD, YGRAD, ZGRAD for any slice angulation. This is the generic and safest configuration, but the duration of the KS_PHASER object may increase for double oblique slices

See ks_eval_phaser_constrained() for details on fields that need to be set before calling this function

Parameters
[in,out]phaserPointer to the KS_PHASER object to be set up
[in]descA description (text string) of the KS_PHASER object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
2073  {
2074 
2076 
2077 }
float ks_syslimits_ampmax(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on all gradient boards simultaneously
Definition: KSFoundation_common.c:201
STATUS ks_eval_phaser_constrained(KS_PHASER *phaser, const char *const phasername, float ampmax, float slewrate, int minduration)
Sets up a trapezoid for phase encoding, subject to gradient constraints specified as input arguments...
Definition: KSFoundation_host.c:2035
LOG_GRAD loggrd
float ks_syslimits_slewrate(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on all gradient boards simultaneously
Definition: KSFoundation_common.c:248

◆ ks_eval_phaser2()

STATUS ks_eval_phaser2 ( KS_PHASER phaser,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with preset gradient constraints

This is a wrapper function to ks_eval_phaser_constrained() with gradient constraints set to allow this KS_PHASER to simultaneously be played on up to two (2) logical gradients for any slice angulation. For double oblique slice angulations, this function may allow for shorter duration than ks_eval_phaser()

See ks_eval_phaser_constrained() for details on fields that need to be set before calling this function

Parameters
[in,out]phaserPointer to the KS_PHASER object to be set up
[in]descA description (text string) of the KS_PHASER object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
2079  {
2080 
2082 
2083 }
STATUS ks_eval_phaser_constrained(KS_PHASER *phaser, const char *const phasername, float ampmax, float slewrate, int minduration)
Sets up a trapezoid for phase encoding, subject to gradient constraints specified as input arguments...
Definition: KSFoundation_host.c:2035
LOG_GRAD loggrd
float ks_syslimits_ampmax2(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on two gradient boards simultaneously
Definition: KSFoundation_common.c:205
float ks_syslimits_slewrate2(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on two gradient boards simultaneously
Definition: KSFoundation_common.c:252

◆ ks_eval_phaser1()

STATUS ks_eval_phaser1 ( KS_PHASER phaser,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with preset gradient constraints

This is a wrapper function to ks_eval_phaser_constrained() with gradient constraints set to allow this KS_PHASER to only be played out on one (1) logical gradient at a time. No gradient may be active on another board while this trapezoid is played out. For double oblique slice angulations, this function may allow for shorter duration than ks_eval_phaser() and ks_eval_phaser2()

See ks_eval_phaser_constrained() for details on fields that need to be set before calling this function

Parameters
[in,out]phaserPointer to the KS_PHASER object to be set up
[in]descA description (text string) of the KS_PHASER object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
2085  {
2086 
2088 
2089 }
STATUS ks_eval_phaser_constrained(KS_PHASER *phaser, const char *const phasername, float ampmax, float slewrate, int minduration)
Sets up a trapezoid for phase encoding, subject to gradient constraints specified as input arguments...
Definition: KSFoundation_host.c:2035
float ks_syslimits_slewrate1(LOG_GRAD loggrd)
Returns the maximum slewrate that can be used on one gradient board at a time
Definition: KSFoundation_common.c:256
LOG_GRAD loggrd
float ks_syslimits_ampmax1(LOG_GRAD loggrd)
Returns the maximum gradient amplitude that can be used on one gradient board at a time...
Definition: KSFoundation_common.c:209

◆ ks_eval_phaser1p()

STATUS ks_eval_phaser1p ( KS_PHASER phaser,
const char *const  desc 
)

Sets up an acquisition window with a trapezoid with physical gradient constraints (invariant to slice angulation)

This is a wrapper function to ks_eval_phaser_constrained() with physical gradient constraints

Parameters
[in,out]phaserPointer to the KS_PHASER object to be set up
[in]descA description (text string) of the KS_PHASER object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
2091  {
2092 
2094 
2095 }
STATUS ks_eval_phaser_constrained(KS_PHASER *phaser, const char *const phasername, float ampmax, float slewrate, int minduration)
Sets up a trapezoid for phase encoding, subject to gradient constraints specified as input arguments...
Definition: KSFoundation_host.c:2035
float ks_syslimits_ampmax1p(LOG_GRAD loggrd)
Returns the maximum gradient amplitude on the physical gradient axes
Definition: KSFoundation_common.c:214
LOG_GRAD loggrd
float ks_syslimits_slewrate1p(LOG_GRAD loggrd)
Returns the maximum gradient amplitude on the physical gradient axes
Definition: KSFoundation_common.c:261

◆ ks_eval_wave()

STATUS ks_eval_wave ( KS_WAVE wave,
const char *const  desc,
int  res,
int  duration,
KS_WAVEFORM  waveform 
)

Sets up a KS_WAVE object based on a waveform (KS_WAVEFORM) in memory

ks_eval_wave() copies the content of a KS_WAVEFORM into a KS_WAVE sequence object. KS_WAVEFORM (5th arg) is a typedef for a float array with a fixed length of KS_MAXWAVELEN elements. Hence, a KS_WAVEFORM, or float array, must first be created and filled with some wave contents before calling this function. res elements are copied from the input KS_WAVEFORM to the field .waveform in the KS_WAVE object (1st arg). duration (4th arg) must be divisible by res (3rd arg) and at least 2x res.

When using (i.e. calling ks_pg_wave()) the waveform for:

  1. RF or OMEGA, nothing needs to be done in terms of amplitude scaling. For RF, amplitude scaling is handled via the KS_RF object, and for OMEGA the number of [Hz] are set directly in run-time (scan())
  2. THETA, the waveform needs to be scaled to units of [degrees]
  3. XGRAD, YGRAD, or ZGRAD, the waveform needs to be scaled to units of [G/cm]
Parameters
[out]waveKS_WAVE object to be created
[in]descA description (text string) of the KS_WAVE object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]resResolution of the waveform, i.e. number of elements from KS_WAVEFORM (5th arg) to read
[in]durationDesired duration in [us] of the waveform (must be divisible with res)
[in]waveformKS_WAVEFORM (float array of max length KS_MAXWAVELEN) with existing waveform content
Return values
STATUSSUCCESS or FAILURE
2097  {
2098  KS_DESCRIPTION tmpdesc;
2099 
2100  strncpy(tmpdesc, desc, KS_DESCRIPTION_LENGTH / 2);
2101  /* don't allow NULL or a description with leading space */
2102  if (desc == NULL || desc[0] == ' ') {
2103  return ks_error("ks_eval_wave: wave name (2nd arg) cannot be NULL or leading space");
2104  }
2105 
2106  if (duration < 0 || res < 0) {
2107  return ks_error("ks_eval_wave(%s): 'res' and 'duration' must be positive", desc);
2108  }
2109  if (res > KS_MAXWAVELEN) {
2110  return ks_error("ks_eval_wave(%s): 'res' cannot exceed %d", wave->description, KS_MAXWAVELEN);
2111  }
2112  if (res % 2) {
2113  return ks_error("ks_eval_wave(%s): 'res' must be even", wave->description);
2114  }
2115  if (duration > 0 && (duration % res)) {
2116  return ks_error("ks_eval_wave(%s): 'duration' (%d) [us] must be divisible by 'res' (%d)", desc, duration, res);
2117  }
2118  if (duration > 0 && (duration / res) < 2) {
2119  return ks_error("ks_eval_wave(%s): 'duration' (%d) [us] must be at least 2x 'res' (%d)", desc, duration, res);
2120  }
2121 
2122  /* reset wave object */
2123  ks_init_wave(wave);
2124 
2125  /* fill in wave object */
2126  strcpy(wave->description, tmpdesc);
2127  wave->res = res;
2128  wave->duration = duration;
2129 
2130  /* copy the waveform */
2131  memcpy(wave->waveform, newwave, sizeof(float) * wave->res);
2132 
2133 
2134 
2135  return SUCCESS;
2136 
2137 }
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
KS_DESCRIPTION description
Definition: KSFoundation.h:666
void ks_init_wave(KS_WAVE *wave)
Resets a KS_WAVE sequence object to its default value (KS_INIT_WAVE)
Definition: KSFoundation_host.c:66
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int res
Definition: KSFoundation.h:667
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
#define KS_MAXWAVELEN
Definition: KSFoundation.h:186

◆ ks_eval_mirrorwave()

STATUS ks_eval_mirrorwave ( KS_WAVE wave)

Flips the contents of the KS_WAVEFORM in a KS_WAVE object

ks_eval_mirrorwave() replaces the KS_WAVEFORM with its (temporally) mirrored version. This can be used to e.g. mirror a minimum phase excitation pulse for fast recovery and T1-optimization in FSE sequences (ksfse.e).#pragma endregion See also ks_eval_stretch_rf().

Parameters
[in,out]waveKS_WAVE object, whose KS_WAVEFORM to be mirrored
Return values
STATUSSUCCESS or FAILURE
2206  {
2207  KS_WAVEFORM tmpwave;
2208  int i;
2209 
2210  memcpy(tmpwave, wave->waveform, sizeof(float) * wave->res);
2211 
2212  for (i = 0; i < wave->res; i++) {
2213  wave->waveform[i] = tmpwave[wave->res-1 - i];
2214  }
2215  return SUCCESS;
2216 }
float KS_WAVEFORM[KS_MAXWAVELEN]
Definition: KSFoundation.h:262
int res
Definition: KSFoundation.h:667
KS_WAVEFORM waveform
Definition: KSFoundation.h:669

◆ ks_eval_wave_file()

STATUS ks_eval_wave_file ( KS_WAVE wave,
const char *const  desc,
int  res,
int  duration,
const char *const  filename,
const char *const  format 
)

Sets up a KS_WAVE object based on a waveform that resides on disk

ks_eval_wave_file() reads waveforms on disk into a KS_WAVE. The data format (arg 6) may currently be one of:

  1. "GE": GE's file format for external pulses (.rho, .gz, etc.). The data will be divided by a factor of MAX_PG_WAMP (32766) before copied to KS_WAVE
  2. "short": Plain short integer format. The data will be divided by a factor of MAX_PG_WAMP (32766) before copied to KS_WAVE
  3. "float": Plain float format. Data will be read in as is and copied to KS_WAVE

When the first two formats are used the field .waveform in KS_WAVE will contain data in the range [-1.0,1.0]. res elements are read from disk in the specified format into the field .waveform in the KS_WAVE object (1st arg). duration (4th arg) must be divisible by res (3rd arg) and at least 2x res.

When using (i.e. calling ks_pg_wave()) the waveform for:

  1. RF or OMEGA, nothing needs to be done in terms of amplitude scaling. For RF, amplitude scaling is handled via the KS_RF object, and for OMEGA the number of [Hz] are set directly in run-time (scan())
  2. THETA, the waveform needs to be scaled to units of [degrees]
  3. XGRAD, YGRAD, or ZGRAD, the waveform needs to be scaled to units of [G/cm]
Parameters
[out]waveKS_WAVE object to be created
[in]descA description (text string) of the KS_WAVE object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]resKS_WAVE object to be created
[in]durationKS_WAVE object to be created
[in]filenameFilename on disk
[in]formatString denoting the data format on disk. Valid values are: "ge" (reads GE's *.rho files with 32byte header), "short", and "float", the latter two being header-less
Return values
STATUSSUCCESS or FAILURE
2140  {
2141  KS_DESCRIPTION tmpdesc;
2142  int i;
2143 
2144  strncpy(tmpdesc, desc, KS_DESCRIPTION_LENGTH / 2);
2145  /* don't allow empty description or a description with leading space */
2146  if (desc == NULL || desc[0] == ' ') {
2147  return ks_error("ks_eval_wave_file: wave name (2nd arg) cannot be NULL or leading space");
2148  }
2149  if (res % 2) {
2150  return ks_error("ks_eval_wave_file(%s): 'res' must be even", wave->description);
2151  }
2152  if (duration > 0 && (duration % res)) {
2153  return ks_error("ks_eval_wave_file(%s): 'duration' (%d) [us] must be divisible by 'res' (%d)", desc, duration, res);
2154  }
2155  if (duration > 0 && (duration / res) < 2) {
2156  return ks_error("ks_eval_wave_file(%s): 'duration' (%d) [us] must be at least 2x 'res' (%d)", desc, duration, res);
2157  }
2158  if (duration < 0 || duration > 4 * KS_MAXWAVELEN) {
2159  return ks_error("ks_eval_wave_file(%s): 'duration' [us] must be in the range [0, %d]", desc, 4 * KS_MAXWAVELEN);
2160  }
2161 
2162  /* reset wave object */
2163  ks_init_wave(wave);
2164 
2165  /* fill in wave object */
2166  strcpy(wave->description, tmpdesc);
2167  wave->res = res;
2168  wave->duration = duration;
2169 
2170  /* read from file */
2171  if (!strncasecmp(format, "ge", 2)) { /* short format with 32-byte header and big-endian short int */
2172  KS_IWAVE iwave;
2173  uextwave(iwave, res, (char *) filename);
2174  for (i = 0; i < res; i++)
2175  wave->waveform[i] = (float) iwave[i] / (float) MAX_PG_WAMP;
2176  } else if (!strncasecmp(format, "short", 5)) {
2177  KS_IWAVE iwave;
2178  FILE *fp;
2179  int n;
2180  if ((fp = fopen(filename, "r")) == NULL)
2181  return ks_error("ks_eval_wave_file (%s): Error opening file '%s'", wave->description, filename);
2182  if ((n = fread(iwave, sizeof(short), res, fp)) < res)
2183  return ks_error("ks_eval_wave_file (%s): Only %d out of %d elements read from file '%s'", wave->description, n, res, filename);
2184  fclose(fp);
2185  for (i = 0; i < res; i++)
2186  wave->waveform[i] = (float) iwave[i] / (float) MAX_PG_WAMP;
2187  } else if (!strncasecmp(format, "float", 5)) {
2188  FILE *fp;
2189  int n;
2190  if ((fp = fopen(filename, "r")) == NULL)
2191  return ks_error("ks_eval_wave_file (%s): Error opening file '%s'", wave->description, filename);
2192  if ((n = fread(wave->waveform, sizeof(float), res, fp)) < res)
2193  return ks_error("ks_eval_wave_file (%s): Only %d out of %d elements read from file '%s'", wave->description, n, res, filename);
2194  fclose(fp);
2195  } else {
2196  return ks_error("ks_eval_wave_file (%s): 'format' (5th arg) must be 'ge','short' or 'float'", wave->description);
2197  }
2198 
2199 
2200  return SUCCESS;
2201 
2202 } /* ks_eval_wave_file */
short KS_IWAVE[KS_MAXWAVELEN]
Definition: KSFoundation.h:263
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
KS_DESCRIPTION description
Definition: KSFoundation.h:666
void ks_init_wave(KS_WAVE *wave)
Resets a KS_WAVE sequence object to its default value (KS_INIT_WAVE)
Definition: KSFoundation_host.c:66
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int res
Definition: KSFoundation.h:667
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
#define KS_MAXWAVELEN
Definition: KSFoundation.h:186

◆ ks_eval_rf_sinc()

STATUS ks_eval_rf_sinc ( KS_RF rf,
const char *const  desc,
double  bw,
double  tbw,
float  flip,
int  wintype 
)

Sets up a KS_RF object with a Sinc pulse shape

For small flip angles, the Fourier transform of the RF envelope is a good approximation of the final slice profile and SLR designed pulses may not be necessary. For these cases, this function can be used to create a Sinc RF pulse (as a KS_RF object) with a desired bandwidth (BW), time-bandwidth-product (TBW) and window function (e.g. KS_RF_SINCWIN_HAMMING, see ks_enum_sincwin). An increased TBW results in more Sinc lobes and sharper slice profiles, and the minimum value is 2. The duration of the RF pulse (.rfwave.duration) increases when BW decreases or TBW increases

Parameters
[out]rfKS_RF object to be created
[in]descA description (text string) of the KS_RF object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]bwBandwidth of the RF pulse [Hz]
[in]tbwTime-bandwidth-product of the RF pulse. Higher value gives sharper slice profiles but increases the duration
[in]flipNominal flip angle of the RF pulse
[in]wintypeWindow function over the Sinc. See ks_enum_sincwin for enums names that steer the window choice
Return values
STATUSSUCCESS or FAILURE
2227  {
2228  KS_DESCRIPTION tmpdesc;
2229  int i;
2230  double x, window, rfenvelope;
2231  int duration = RUP_GRD(tbw / bw * 1e6); /* [us]. We round up to nearest multiple of 4 (GRAD_UPDATE_TIME) to better align to gradients */
2232  int res = duration / RF_UPDATE_TIME; /* # sample points. RF_UPDATE_TIME = 2 => res always even */
2233 
2234  /* don't allow empty description or a description with leading space */
2235  if (desc == NULL || desc[0] == ' ') {
2236  return ks_error("ks_eval_rf_sinc: RF name (2nd arg) cannot be NULL or leading space");
2237  }
2238  strncpy(tmpdesc, desc, KS_DESCRIPTION_LENGTH/2);
2239  tmpdesc[KS_DESCRIPTION_LENGTH/2] = 0;
2240 
2241  /* reset RF object */
2242  ks_init_rf(rf);
2243 
2244  /* fill in wave object */
2245  sprintf(rf->rfwave.description, "%s.wave", tmpdesc);
2246 
2247  if (bw < 2 || bw > 100000) {
2248  return ks_error("ks_eval_rf_sinc(%s): 'bw' (%g, 3rd arg) must be in range [2,100000] Hz", rf->rfwave.description, bw);
2249  }
2250  if (tbw < 2 || tbw > 100) {
2251  return ks_error("ks_eval_rf_sinc(%s): 'tbw' (%g, 4th arg) must be in range [2,100]", rf->rfwave.description, tbw);
2252  }
2253  if (res > KS_MAXWAVELEN || res < 4) {
2254  return ks_error("ks_eval_rf_sinc(%s): combination of 'bw' and 'tbw' resulted in a resolution outside the valid range [4, %d]", rf->rfwave.description, KS_MAXWAVELEN);
2255  }
2256  if (flip <= 0 || flip > 10000.0) {
2257  return ks_error("ks_eval_rf_sinc(%s): 'flip' must be in range (0, 10000]", rf->rfwave.description);
2258  }
2259 
2260  rf->rfwave.res = res;
2261  rf->rfwave.duration = duration;
2262  rf->iso2end = duration / 2;
2263  rf->start2iso = duration / 2;
2264  rf->bw = bw;
2265  rf->flip = flip;
2266 
2267  /* generate waveform with max 1.0 */
2268  for (i = 0 ; i < (res - 1) ; i++) {
2269  x = 2.0 * i / (res - 1) - 1.0;
2270 
2271  if (fabs(2.0 * PI * (tbw / 4.0)*x) > 1e-6) {
2272  rfenvelope = sin(2.0 * PI * (tbw / 4.0) * x) / (2.0 * PI * (tbw / 4.0) * x);
2273  } else {
2274  rfenvelope = 1.0;
2275  }
2276 
2277  window = 1.0; /* init to no filter */
2278 
2279  if (wintype == KS_RF_SINCWIN_HAMMING) {
2280  window = 0.54 + 0.46 * cos(PI * x);
2281  } else if (wintype == KS_RF_SINCWIN_HANNING) {
2282  window = (1.0 + cos(PI * x)) * 0.5;
2283  } else if (wintype == KS_RF_SINCWIN_BLACKMAN) {
2284  window = 0.42 + 0.5 * cos(PI * x) + 0.08 * cos(2 * PI * x);
2285  } else if (wintype == KS_RF_SINCWIN_BARTLETT) {
2286  if (x < 0.0)
2287  window = x + 1.0;
2288  else
2289  window = 1.0 - x;
2290  }
2291 
2292  rf->rfwave.waveform[i] = rfenvelope * window;
2293 
2294  } /* for */
2295 
2296  /* initialize amplitude to 1 */
2297  rf->amp = 1;
2298 
2299  /* set the usage of the RF PULSE to off until .base.ninst > 0 (see ks_pg_rf() on HOST) */
2300  rf->rfpulse.activity = PSD_PULSE_OFF;
2301 
2302  /* initialize number of occurrences of RF pulse to zero */
2303  rf->rfpulse.num = 0;
2304 
2305  /* setup rfpulse structure */
2306  return ks_eval_rfstat(rf);
2307 }
int start2iso
Definition: KSFoundation.h:944
Definition: KSFoundation.h:1954
RF_PULSE rfpulse
Definition: KSFoundation.h:948
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
float flip
Definition: KSFoundation.h:940
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
void ks_init_rf(KS_RF *rf)
Resets a KS_RF sequence object to its default value (KS_INIT_RF)
Definition: KSFoundation_host.c:70
KS_DESCRIPTION description
Definition: KSFoundation.h:666
STATUS ks_eval_rfstat(KS_RF *rf)
Sets up the RF_PULSE structure of a KS_RF object
Definition: KSFoundation_host.c:2615
KS_WAVE rfwave
Definition: KSFoundation.h:949
Definition: KSFoundation.h:1954
float amp
Definition: KSFoundation.h:943
Definition: KSFoundation.h:1954
int iso2end
Definition: KSFoundation.h:945
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int res
Definition: KSFoundation.h:667
Definition: KSFoundation.h:1954
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
#define KS_MAXWAVELEN
Definition: KSFoundation.h:186
float bw
Definition: KSFoundation.h:941

◆ ks_eval_rf_secant()

STATUS ks_eval_rf_secant ( KS_RF rf,
const char *const  desc,
float  A0,
float  tbw,
float  bw 
)

Sets up a KS_RF object with a Hyperbolic Secant shape

2311  {
2312  STATUS status;
2313  int debug = 1;
2314 
2315  /* reset RF object */
2316  ks_init_rf(rf);
2317 
2318  KS_DESCRIPTION tmpdesc;
2319  int i;
2320 
2321  /* don't allow empty description or a description with leading space */
2322  if (desc == NULL || desc[0] == ' ') {
2323  return ks_error("ks_eval_rf_secant: 'RF name' (2nd arg) cannot be NULL or leading space");
2324  }
2325  strncpy(tmpdesc, desc, KS_DESCRIPTION_LENGTH/2);
2326  tmpdesc[KS_DESCRIPTION_LENGTH/2] = 0;
2327 
2328  /* fill in wave object */
2329  sprintf(rf->rfwave.description, "%s.wave", tmpdesc);
2330 
2331  if (A0 < 0 || 0.25 < A0) {
2332  return ks_error("ks_eval_rf_secant(%s): 'A0' (%g, 3rd arg) must be in range [0,0.25] Gauss", rf->rfwave.description, A0);
2333  }
2334  if (tbw < 2 || 20 < tbw) {
2335  return ks_error("ks_eval_rf_secant(%s): 'tbw' (%g, 4th arg) must be in range [2,20]", rf->rfwave.description, tbw);
2336  }
2337  if (bw < 100 || 10000 < bw) {
2338  return ks_error("ks_eval_rf_secant(%s): 'bw' (%g, 5th arg) must be in range [0,10000] Hz", rf->rfwave.description, bw);
2339  }
2340 
2341  int duration = RUP_GRD((int)(1000000.0 * tbw / bw));
2342  int res = duration / GRAD_UPDATE_TIME; /* # sample points. RF_UPDATE_TIME = 2 => res always even */
2343 
2344  if (res < 4 || KS_MAXWAVELEN < res) {
2345  return ks_error("ks_eval_rf_secant(%s): tbw / bw resulted in a resolution(%d)/duration(%d) outside the valid range [4, %d]", rf->rfwave.description, res, duration, KS_MAXWAVELEN);
2346  }
2347 
2348  rf->rfwave.res = res;
2349  rf->rfwave.duration = duration;
2350  rf->iso2end = duration / 2;
2351  rf->start2iso = duration / 2;
2352 
2353  /* calculate pulse properties */
2354  float y = 5; /* 5 is a standard value from literature */
2355  float B = (bw * PI) / y;
2356  float Acheck = (PI * bw) / (2.0 * PI * 4258 * sqrt(y)); /* Gauss */
2357 
2358  if (Acheck > A0 * 0.5) {
2359  return ks_error("ks_eval_rf_secant(%s): The adiabatic condition might not be met since %g !>> %g (needs to be at least half)", rf->rfwave.description, A0, Acheck);
2360  }
2361 
2362  rf->bw = bw;
2363  rf->flip = 180.0;
2364 
2365  double rfenvelope, phaseenvelope, tau, sech;
2366  for (i = 0 ; i < res; i++) {
2367 
2368  /* range from -2pi to 2pi */
2369  tau = ((i / (((float)res - 1.0) * 0.5)) - 1.0) * 2.0 * PI;
2370 
2371  sech = 1.0 / cosh(tau * B * 0.001);
2372  rfenvelope = A0 * sech;
2373  phaseenvelope = y * log(sech) + y * log(A0);
2374 
2375  rf->rfwave.waveform[i] = rfenvelope;
2376  rf->thetawave.waveform[i] = phaseenvelope * (180.0/PI);
2377 
2378  }
2379 
2380  if (debug == 1) {
2381  ks_print_waveform(rf->rfwave.waveform, "secant_a.txt", rf->rfwave.res);
2382  ks_print_waveform(rf->thetawave.waveform, "secant_p.txt", rf->rfwave.res);
2383  ks_error("HS: A0=%f >> Ac=%f, bw=%f, tbw=%f", A0, Acheck, bw, tbw);
2384  ks_error("HS: y=%f, B=%f", y, B);
2385  }
2386 
2387  /* Normalize waveform to one & initialize amplitude to 1 */
2388  ks_wave_multiplyval(&rf->rfwave, 1.0 / ks_wave_absmax(&rf->rfwave));
2389  rf->amp = 1;
2390 
2391  /* set the usage of the RF PULSE to off until .base.ninst > 0 (see ks_pg_rf() on HOST) */
2392  rf->rfpulse.activity = PSD_PULSE_OFF;
2393 
2394  /* initialize number of occurrences of RF pulse to zero */
2395  rf->rfpulse.num = 0;
2396 
2397  /* setup rfpulse structure */
2398  status = ks_eval_rfstat(rf);
2399  if (status != SUCCESS) return status;
2400 
2401  rf->rfpulse.max_b1 = A0;
2402  rf->thetawave.res = res;
2403  rf->thetawave.duration = duration;
2404  rf->role = KS_RF_ROLE_INV;
2405  return status;
2406 }
int start2iso
Definition: KSFoundation.h:944
int role
Definition: KSFoundation.h:939
int debug
Definition: GERequired.e:2642
RF_PULSE rfpulse
Definition: KSFoundation.h:948
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
Definition: KSFoundation.h:1953
float flip
Definition: KSFoundation.h:940
float ks_wave_absmax(const KS_WAVE *wave)
Returns the maximum absolute value in a KS_WAVE sequence object
Definition: KSFoundation_common.c:1224
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
KS_WAVE thetawave
Definition: KSFoundation.h:951
void ks_init_rf(KS_RF *rf)
Resets a KS_RF sequence object to its default value (KS_INIT_RF)
Definition: KSFoundation_host.c:70
KS_DESCRIPTION description
Definition: KSFoundation.h:666
STATUS ks_eval_rfstat(KS_RF *rf)
Sets up the RF_PULSE structure of a KS_RF object
Definition: KSFoundation_host.c:2615
KS_WAVE rfwave
Definition: KSFoundation.h:949
float amp
Definition: KSFoundation.h:943
int iso2end
Definition: KSFoundation.h:945
void ks_print_waveform(const KS_WAVEFORM waveform, const char *filename, int res)
Writes a KS_WAVEFORM to disk with the specified filename
Definition: KSFoundation_host.c:5135
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int res
Definition: KSFoundation.h:667
void ks_wave_multiplyval(KS_WAVE *wave, float val)
In-place scalar multiplication of a KS_WAVE
Definition: KSFoundation_common.c:1398
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
#define KS_MAXWAVELEN
Definition: KSFoundation.h:186
float bw
Definition: KSFoundation.h:941

◆ ks_eval_rf_hard()

STATUS ks_eval_rf_hard ( KS_RF rf,
const char *const  desc,
int  duration,
float  flip 
)

Sets up a KS_RF object with a rectangular (hard) pulse of a given duration.

This function creates a hard RF pulse of the desired duration. Hard pulses are typically used as non-slice selective RF pulses, as their slice profile would be very poor (Sinc-like). The resolution of the RF pulse created is equal to the duration/2

Parameters
[out]rfKS_RF object to be created
[in]descA description (text string) of the KS_RF object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]durationDesired duration in [us] of the waveform (must be even)
[in]flipNominal flip angle of the RF pulse
Return values
STATUSSUCCESS or FAILURE
2409  {
2410  KS_DESCRIPTION tmpdesc;
2411  int i;
2412 
2413  /* don't allow empty description or a description with leading space */
2414  if (desc == NULL || desc[0] == ' ') {
2415  return ks_error("ks_eval_rf_hard: RF name (2nd arg) cannot be NULL or leading space");
2416  }
2417  strncpy(tmpdesc, desc, KS_DESCRIPTION_LENGTH/2);
2418  tmpdesc[KS_DESCRIPTION_LENGTH/2] = 0;
2419 
2420  /* reset RF object */
2421  ks_init_rf(rf);
2422 
2423  /* fill in wave object */
2424  sprintf(rf->rfwave.description, "%s.wave", tmpdesc);
2425 
2426  if (duration > KS_MAXWAVELEN * RF_UPDATE_TIME || duration < 4) {
2427  return ks_error("ks_eval_rf_hard(%s): 'duration' (3rd arg) must be in range [4, %d]", rf->rfwave.description, KS_MAXWAVELEN * RF_UPDATE_TIME);
2428  }
2429  if (duration % 2) {
2430  return ks_error("ks_eval_rf_hard(%s): 'duration' (3rd arg) must be divisible by 2", rf->rfwave.description);
2431  }
2432 
2433  rf->rfwave.res = duration / RF_UPDATE_TIME;
2434  rf->rfwave.duration = duration;
2435  rf->iso2end = duration / 2;
2436  rf->start2iso = duration / 2;
2437  rf->bw = 0;
2438  rf->flip = flip;
2439 
2440  /* generate waveform with max 1.0 */
2441  for (i = 0 ; i < rf->rfwave.res ; i++) {
2442  rf->rfwave.waveform[i] = 1.0;
2443  }
2444 
2445  /* initialize amplitude to 1 */
2446  rf->amp = 1;
2447 
2448  /* set the usage of the RF PULSE to off until .base.ninst > 0 (see ks_pg_rf() on HOST) */
2449  rf->rfpulse.activity = PSD_PULSE_OFF;
2450 
2451  /* initialize number of occurrences of RF pulse to zero */
2452  rf->rfpulse.num = 0;
2453 
2454  /* setup rfpulse structure */
2455  STATUS status = ks_eval_rfstat(rf);
2456  if (status != SUCCESS) return status;
2457 
2458  return SUCCESS;
2459 }
int start2iso
Definition: KSFoundation.h:944
RF_PULSE rfpulse
Definition: KSFoundation.h:948
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
float flip
Definition: KSFoundation.h:940
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
void ks_init_rf(KS_RF *rf)
Resets a KS_RF sequence object to its default value (KS_INIT_RF)
Definition: KSFoundation_host.c:70
KS_DESCRIPTION description
Definition: KSFoundation.h:666
STATUS ks_eval_rfstat(KS_RF *rf)
Sets up the RF_PULSE structure of a KS_RF object
Definition: KSFoundation_host.c:2615
KS_WAVE rfwave
Definition: KSFoundation.h:949
float amp
Definition: KSFoundation.h:943
int iso2end
Definition: KSFoundation.h:945
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int res
Definition: KSFoundation.h:667
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
#define KS_MAXWAVELEN
Definition: KSFoundation.h:186
float bw
Definition: KSFoundation.h:941

◆ ks_eval_rf_hard_optimal_duration()

STATUS ks_eval_rf_hard_optimal_duration ( KS_RF rf,
const char *const  desc,
int  order,
float  flip,
float  offsetFreq 
)

Sets up a KS_RF object with a rectangular (hard) pulse with optimal duration for fat selection/saturation

This function creates a hard RF pulse with optimal duration for fat selection/saturation. Hard pulses are typically used as non-slice selective RF pulses. Their slice profile is sinc-like and with this function you can create a hard pulse with a sinc-minima at the center of the spectral fat-peak. You can select wich minima using the input 'order'. A higher order generates a longer pulse duration with a more narrow frequency response. If the pulse is tuned to the fat peak, using input 'offsetFreq', the minimia will instead end up at the water-peak. The resolution of the RF pulse created is equal to the duration/2

Parameters
[out]rfKS_RF object to be created
[in]descA description (text string) of the KS_RF object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]orderSelect wich minima to use
[in]flipNominal flip angle of the RF pulse
[in]offsetFreqchoose center frequency offset
Return values
STATUSSUCCESS or FAILURE
2462  {
2463 
2464  if (order < 1) {
2465  return ks_error("ks_eval_rf_hard(%s): 'order' (%d, 3rd arg) must be positive", desc, order);
2466  }
2467 
2468  int duration = RUP_FACTOR((int)(1000000.0 * sqrt(pow(2.0 * PI * (float)order, 2) - pow((float)flip * (PI / 180.0), 2)) / fabs(2.0 * PI * offsetFreq)), GRAD_UPDATE_TIME);
2469 
2470  return ks_eval_rf_hard(rf, desc, duration, flip);
2471 
2472 }
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
STATUS ks_eval_rf_hard(KS_RF *rf, const char *const desc, int duration, float flip)
Sets up a KS_RF object with a rectangular (hard) pulse of a given duration.
Definition: KSFoundation_host.c:2409

◆ ks_eval_rf_binomial()

STATUS ks_eval_rf_binomial ( KS_RF rf,
const char *const  desc,
int  offResExc,
int  nPulses,
float  flip,
float  offsetFreq 
)

Sets up a KS_RF object as a Binomial RF pulse

This function creates a binomial RF pulse, which consists of a series of hard pulses. Binomial pulses are used for spectral selection. They utilize the difference in resonance frequency of different tissue types, such as water and fat. Increasing the number of sub-pulses will improve the spectral selectivity but also increse the pulse duration.

Parameters
[out]rfKS_RF object to be created
[in]descA description (text string) of the KS_RF object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
[in]offResExcIf 0 the pulse will excite the spinns at the center frequency, If 1 the pulse will excite the spinns at the offset frequency (given by input: offsetFreq)
[in]nPulsesNumber of sub-pulses
[in]flipNominal flip angle of the RF pulse
[in]offsetFreqchoose center frequency offset in Hz
Return values
STATUSSUCCESS or FAILURE
2475  {
2476  KS_DESCRIPTION tmpdesc;
2477  int i, j;
2478 
2479  /* Don't allow empty description or a description with leading space */
2480  if (desc == NULL || desc[0] == ' ') {
2481  return ks_error("ks_eval_rf_binomial: RF name (2nd arg) cannot be NULL or leading space");
2482  }
2483  strncpy(tmpdesc, desc, KS_DESCRIPTION_LENGTH/2);
2484  tmpdesc[KS_DESCRIPTION_LENGTH/2] = 0;
2485 
2486  /* Reset RF object */
2487  ks_init_rf(rf);
2488 
2489  /* Fill in wave object */
2490  sprintf(rf->rfwave.description, "%s.wave", tmpdesc);
2491 
2492  if (offResExc < 0 || offResExc > 1) {
2493  return ks_error("ks_eval_rf_hard(%s): 'offResExc' (3rd arg) must be either 0 or 1", rf->rfwave.description);
2494  }
2495  if (nPulses < 2 || nPulses > 10) {
2496  return ks_error("ks_eval_rf_hard(%s): 'nPulses' (4th arg) must be in range [2, 10]", rf->rfwave.description);
2497  }
2498 
2499  int pascalstriangle[9][10] = { {1,1},
2500  {1,2,1},
2501  {1,3,3,1},
2502  {1,4,6,4,1},
2503  {1,5,10,10,5,1},
2504  {1,6,15,20,15,6,1},
2505  {1,7,21,35,35,21,7,1},
2506  {1,8,28,56,70,56,28,8,1},
2507  {1,9,36,84,126,126,84,36,9,1} };
2508 
2509  int P[10];
2510  int pulseSum = 0;
2511  for (i = 0; i < nPulses; i++) {
2512  P[i] = pascalstriangle[nPulses - 2][i];
2513  pulseSum += P[i];
2514  }
2515 
2516  /* Calculate subpulse separation */
2517  float tau = fabs(1.0 / (2.0 * offsetFreq)); /* sec */
2518 
2519  /* Calculate number of samples so that each subpulse is as close as possible to maxB1, without exceeding it */
2520  float maxB1 = 0.20; /* Gauss */
2521  float pulseArea = (float) flip * (PI / 180.0); /* radians or Hz (depending on how you look at it) */
2522  float dt = RF_UPDATE_TIME / 1000000.0; /* sec */
2523  float subArea[10];
2524  int ntp[10];
2525  for (i = 0; i < nPulses; i++) {
2526  subArea[i] = (P[i] * pulseArea) / (pulseSum * 2.0 * PI * GAM); /* Gauss * sec */
2527  ntp[i] = ceil(subArea[i] / (maxB1 * dt)); /* number of time points in sub pulse */
2528  if (ntp[i] < 4 ) {
2529  ntp[i] = 4;
2530  }
2531  }
2532 
2533  int idx = 0;
2534  for (i = 0; i < nPulses; i++) {
2535 
2536  /* Calculate how much we have to attenuate this pulse
2537  to account for the fact that with this dwell time
2538  we couldn't hit the target flip exactly */
2539  float currentSubArea = ntp[i] * dt * maxB1; /* Gauss * sec */
2540  float amp = maxB1 * (subArea[i] / currentSubArea); /* Gauss */
2541 
2542  /* Flip every other sub pulse for off resonace excitaion */
2543  if (offResExc) {
2544  /* make sure the second center sub-pulse flips in the right direction */
2545  amp *= pow(-1.0, (float)(i + nPulses/2 % 2));
2546  }
2547 
2548  /* Stitch on the sub pulse */
2549  for (j = 0; j < ntp[i]; j++) {
2550  rf->rfwave.waveform[idx] = amp;
2551  idx++;
2552  }
2553 
2554  /* Stitch on the gap, skip for last sub pulse */
2555  if (i < nPulses - 1) {
2556  int ntp_gap = ceil(tau / dt - (float)ntp[i] / 2.0 - (float)ntp[i + 1] / 2.0);
2557  for (j = 0; j < ntp_gap; j++) {
2558  rf->rfwave.waveform[idx] = 0.0;
2559  idx++;
2560  }
2561  }
2562  }
2563 
2564  /* Make sure the resolution is divisible by 2 and the duration divisible by 4 */
2565  rf->rfwave.res = RUP_FACTOR(idx, 4);
2566  rf->rfwave.duration = rf->rfwave.res * RF_UPDATE_TIME;
2567  rf->iso2end = rf->rfwave.duration / 2;
2568  rf->start2iso = rf->rfwave.duration / 2;
2569  rf->bw = 0; /* ? */
2570  rf->flip = flip;
2571 
2572  /* If the resolution has been rounded up, place zeros at the end */
2573  for (j = idx; j < rf->rfwave.res; j++) {
2574  rf->rfwave.waveform[j] = 0.0;
2575  }
2576 
2577  /* Normalize waveform to one */
2578  ks_wave_multiplyval(&rf->rfwave, 1.0 / ks_wave_absmax(&rf->rfwave));
2579 
2580  /* Initialize amplitude to one */
2581  rf->amp = 1;
2582 
2583  /* Set the usage of the RF PULSE to off until .base.ninst > 0 (see ks_pg_rf() on HOST) */
2584  rf->rfpulse.activity = PSD_PULSE_OFF;
2585 
2586  /* Never allow binomial RF pulses to be stretched. We can avoid this by always setting extgradfile = 1 (even if this is not the case) */
2587  rf->rfpulse.extgradfile = 1;
2588 
2589  /* Initialize number of occurrences of RF pulse to zero */
2590  rf->rfpulse.num = 0;
2591 
2592  /* Save original waveform to fool rfstat, with abs(waveform) */
2593  float *saveWave = (float*)alloca(rf->rfwave.res * sizeof(float));
2594  if (offResExc) {
2595  memcpy(saveWave, rf->rfwave.waveform, rf->rfwave.res * sizeof(float));
2596  for (j = 0; j < rf->rfwave.res; j++) {
2597  rf->rfwave.waveform[j] = fabs(rf->rfwave.waveform[j]);
2598  }
2599  }
2600 
2601  /* Setup rfpulse structure */
2602  STATUS status = ks_eval_rfstat(rf);
2603  if (status != SUCCESS) return status;
2604 
2605  /* Put back the correct waveform */
2606  if (offResExc) {
2607  memcpy(rf->rfwave.waveform, saveWave, rf->rfwave.res * sizeof(float));
2608  }
2609 
2610  return SUCCESS;
2611 
2612 }
int start2iso
Definition: KSFoundation.h:944
RF_PULSE rfpulse
Definition: KSFoundation.h:948
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
float GAM
float flip
Definition: KSFoundation.h:940
float ks_wave_absmax(const KS_WAVE *wave)
Returns the maximum absolute value in a KS_WAVE sequence object
Definition: KSFoundation_common.c:1224
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
void ks_init_rf(KS_RF *rf)
Resets a KS_RF sequence object to its default value (KS_INIT_RF)
Definition: KSFoundation_host.c:70
KS_DESCRIPTION description
Definition: KSFoundation.h:666
STATUS ks_eval_rfstat(KS_RF *rf)
Sets up the RF_PULSE structure of a KS_RF object
Definition: KSFoundation_host.c:2615
KS_WAVE rfwave
Definition: KSFoundation.h:949
float amp
Definition: KSFoundation.h:943
int iso2end
Definition: KSFoundation.h:945
float maxB1[MAX_ENTRY_POINTS]
Definition: GERequired.e:269
char KS_DESCRIPTION[KS_DESCRIPTION_LENGTH]
Definition: KSFoundation.h:261
int res
Definition: KSFoundation.h:667
void ks_wave_multiplyval(KS_WAVE *wave, float val)
In-place scalar multiplication of a KS_WAVE
Definition: KSFoundation_common.c:1398
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
float bw
Definition: KSFoundation.h:941

◆ ks_eval_rfstat()

STATUS ks_eval_rfstat ( KS_RF rf)

Sets up the RF_PULSE structure of a KS_RF object

For RF scaling, SAR calculation, and RF heating calculations, GE uses a global array of RF_PULSE structs, where each RF pulse is associated with one RF_PULSE struct each. This struct array contains RF pulses from Prescan as well as the pulse sequence itself, and is normally declared in a grad_rf_<psd>.h file.

Here, each KS_RF object has its own RF_PULSE struct (the field .rfpulse), which this function sets up. The following fields in the KS_RF object must be set before calling this ks_eval_rfstat()

  1. .rfwave: Must contain the RF pulse waveform. An error is return if either .thetawave or .omegawave are non-empty (complex RF pulses not allowed)
  2. .bw: The bandwidth of the RF pulse [Hz]
  3. .iso2end: Time from the magnetic center of the RF pulse to the end, in [us]
  4. .flip: The flip angle of the RF pulse [degrees]. In this function, .flip will set .rfpulse.nom_fa and make sure .rfpulse.act_fa points to .flip

The RF waveform will be amplitude scaled so that its maximum absolute amplitude is 1.0 before making the calculations. Also the proper links between fields int the .rfpulse (RF_PULSE) struct and the parent fields in KS_RF are set up by calling ks_eval_rf_relink()

Credits: This function has been made largely after the code by Atsushi Takahashi, GE Healthcare.

Parameters
[in,out]rfKS_RF object to calculate the RF_PULSE parameters for (in field .rfpulse)
Return values
STATUSSUCCESS or FAILURE
2615  {
2616  double standard_pw = 1e-3;
2617 
2618  double nRFenvelope;
2619  int indx;
2620 
2621  double area = 0.0;
2622  double abswidth = 0.0;
2623  double effwidth = 0.0;
2624  double dtycyc = 0.0;
2625  double max_pw = 0.0;
2626  double max_b1 = 0.0;
2627  double max_int_b1_sq = 0.0;
2628  double max_rms_b1 = 0.0;
2629 
2630 
2631  if (rf->thetawave.res > 0 || rf->omegawave.res > 0) {
2632  return ks_error("ks_eval_rfstat(%s): function is not validated for phase/frequency modulated RF-pulses", rf->rfwave.description);
2633  }
2634  /* require fields 'duration', 'isodelay' and 'bw' to be set to realistic values */
2635  if (rf->rfwave.duration < 4 || rf->rfwave.duration > KS_MAXWAVELEN * RF_UPDATE_TIME || rf->rfwave.duration % 2) {
2636  return ks_error("ks_eval_rfstat: 'rf.rfwave.duration' (%d) must be an even number in the range [4,%d] us", rf->rfwave.duration, KS_MAXWAVELEN * RF_UPDATE_TIME);
2637  }
2638  if (rf->bw < 0 || rf->bw > 100000) {
2639  return ks_error("ks_eval_rfstat: 'rf.bw' (%f) must be in the range [0,100000] Hz", rf->bw);
2640  }
2641  if (rf->iso2end < 0 || rf->iso2end > KS_MAXWAVELEN * RF_UPDATE_TIME) {
2642  return ks_error("ks_eval_rfstat: 'rf.iso2end' (%d) must be in the range [0,%d] us", rf->iso2end, KS_MAXWAVELEN * RF_UPDATE_TIME);
2643  }
2644  if (rf->flip < 0.0 || rf->flip > 10000.0) {
2645  return ks_error("ks_eval_rfstat: 'rf.flip' (%.2f) must be in the range [0,3000] deg", rf->flip);
2646  }
2647  /* for reference, see: /ESE_xxxxx/psd/include/private/sar_pm.h */
2648 
2649  /* normalize RF just in case */
2650  ks_wave_multiplyval(&rf->rfwave, 1.0 / ks_wave_absmax(&rf->rfwave));
2651 
2652 
2653  for (indx = 0; indx < rf->rfwave.res; indx++) {
2654  nRFenvelope = rf->rfwave.waveform[indx];
2655  area += nRFenvelope;
2656  abswidth += fabs(nRFenvelope);
2657  effwidth += (nRFenvelope * nRFenvelope);
2658 
2659  /* dtycyc: % of Pulse Widths above 5% power */
2660  if (fabs(nRFenvelope) > 0.05)
2661  dtycyc++;
2662  }
2663 
2664  area /= rf->rfwave.res;
2665  abswidth /= rf->rfwave.res;
2666  effwidth /= rf->rfwave.res;
2667  dtycyc /= rf->rfwave.res;
2668 
2669  /* max_pw: % of the pulse width whose widest lobe is above 5% power
2670  GE uses max_pw = dtycyc for most pulses (sar_pm.h)
2671  Neither max_pw nor dtycyc seem to match well with the values used in GEs product sequences unlike
2672  the other fields, which seems to agree within a few percent */
2673  max_pw = dtycyc;
2674 
2675  max_b1 = rf->flip / 360.0 / (area * (rf->rfwave.duration) * 1e-6) / GAM;
2676  max_int_b1_sq = max_b1 * max_b1 * effwidth * (rf->rfwave.duration) * 1e-6 / standard_pw;
2677  max_rms_b1 = sqrt(max_int_b1_sq / ((rf->rfwave.duration) * 1e-6) * standard_pw);
2678 
2679 
2680  ks_eval_rf_relink(rf);
2681 
2682  rf->rfpulse.abswidth = abswidth;
2683  rf->rfpulse.effwidth = effwidth;
2684  rf->rfpulse.area = area;
2685  rf->rfpulse.dtycyc = dtycyc;
2686  rf->rfpulse.maxpw = max_pw;
2687  rf->rfpulse.num = 0;
2688  rf->rfpulse.max_b1 = max_b1;
2689  rf->rfpulse.max_int_b1_sq = max_int_b1_sq;
2690  rf->rfpulse.max_rms_b1 = max_rms_b1;
2691  rf->rfpulse.nom_fa = rf->flip; /* nom_fa and act_fa are equal */
2692  rf->rfpulse.nom_pw = rf->rfwave.duration;
2693  rf->rfpulse.nom_bw = rf->bw;
2694  rf->rfpulse.activity = PSD_PULSE_OFF; /* is set to PSD_SCAN_ON by ks_pg_rf() */
2695  rf->rfpulse.reference = 0;
2696  rf->rfpulse.isodelay = rf->iso2end;
2697  rf->rfpulse.scale = 1.0;
2698  if (rf->rfpulse.extgradfile != 1) {
2699  rf->rfpulse.extgradfile = 0; /* Only allow 0 or 1. Disallows RF pulse stretching if 1 */
2700  }
2701 
2702  return SUCCESS;
2703 }
RF_PULSE rfpulse
Definition: KSFoundation.h:948
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
float GAM
float flip
Definition: KSFoundation.h:940
float ks_wave_absmax(const KS_WAVE *wave)
Returns the maximum absolute value in a KS_WAVE sequence object
Definition: KSFoundation_common.c:1224
KS_WAVE thetawave
Definition: KSFoundation.h:951
KS_DESCRIPTION description
Definition: KSFoundation.h:666
KS_WAVE rfwave
Definition: KSFoundation.h:949
int iso2end
Definition: KSFoundation.h:945
void ks_eval_rf_relink(KS_RF *rf)
(Internal use) Relinks pointers between fields in a KS_RF object
Definition: KSFoundation_host.c:2771
KS_WAVE omegawave
Definition: KSFoundation.h:950
int res
Definition: KSFoundation.h:667
void ks_wave_multiplyval(KS_WAVE *wave, float val)
In-place scalar multiplication of a KS_WAVE
Definition: KSFoundation_common.c:1398
KS_WAVEFORM waveform
Definition: KSFoundation.h:669
int duration
Definition: KSFoundation.h:668
#define KS_MAXWAVELEN
Definition: KSFoundation.h:186
float bw
Definition: KSFoundation.h:941

◆ ks_eval_rf()

STATUS ks_eval_rf ( KS_RF rf,
const char *const  desc 
)

Sets up a KS_RF object

See documentation for the KS_RF object for details on how to prepare the KS_RF object before calling ks_eval_rf()

This function does not set up a KS_RF object by itself, merely it peforms final validation, naming, makes sure fields and links in KS_RF are properly set up. ks_eval_rf() should be called for non-slice selective RF pulses. For slice-selective RF pulses, use KS_SELRF and call ks_eval_selrf() instead

Parameters
[in,out]rfPointer to the KS_RF object to be set up
[in]descA description (text string) of the KS_RF object. This description is used for pulse sequence generation (seen in the file generated by TimeHist in MGD Sim/WTools)
Return values
STATUSSUCCESS or FAILURE
2707  {
2708 
2709  if (desc == NULL || desc[0] == ' ') {
2710  return ks_error("ks_eval_rf: description (2nd arg) cannot be NULL or begin with a space");
2711  } else {
2712  strncpy(rf->rfwave.description, desc, KS_DESCRIPTION_LENGTH / 2); /* truncate after half max # chars to allow for suffixes */
2713  }
2714 
2715  ks_eval_rf_relink(rf);
2716 
2717  if (rf->role <= KS_RF_ROLE_NOTSET || rf->role > KS_RF_ROLE_INV) {
2718  return ks_error("ks_eval_rf(%s): 'rf.role' is not set or is invalid", desc);
2719  }
2720  if (rf->flip <= 0.0 || rf->flip > 10000.0) {
2721  return ks_error("ks_eval_rf(%s): 'rf.flip' (%.2f) must be in the range (0,3000] deg", desc, rf->flip);
2722  }
2723  if (rf->bw < 0 || rf->bw > 100000) {
2724  return ks_error("ks_eval_rf(%s): 'rf.bw' (%.2f) must be in the range [0,100000]", desc, rf->bw);
2725  }
2726  /* check that RF duration is even */
2727  if (rf->rfwave.duration % 2)
2728  return ks_error("ks_eval_rf (%s): RF duration (%d) [us] must be even", rf->rfwave.description, rf->rfwave.duration);
2729 
2730  /* check that RF duration and optional THETA / OMEGA waveforms have same duration */
2731  if (rf->omegawave.res) {
2732  sprintf(rf->omegawave.description, "%s", rf->rfwave.description); /* suffix '.x' is added automatically in ks_pg_wave(), where 'x' is the 1st letter of the board */
2733  if (rf->rfwave.duration != rf->omegawave.duration)
2734  return ks_error("ks_eval_rf (%s): OMEGA duration (%d) [us] must equal RF duration (%d) [us]", rf->rfwave.description, rf->omegawave.duration, rf->rfwave.duration);
2735  }
2736  if (rf->thetawave.res) {
2737  sprintf(rf->thetawave.description, "%s", rf->rfwave.description);
2738  if (rf->rfwave.duration != rf->thetawave.duration)
2739  return ks_error("ks_eval_rf (%s): THETA duration (%d) [us] must equal RF duration (%d) [us]", rf->rfwave.description, rf->thetawave.duration, rf->rfwave.duration);
2740  }
2741 
2742  if (rf->iso2end < 0 || rf->iso2end > rf->rfwave.duration) {
2743  return ks_error("ks_eval_rf (%s): 'rf.iso2end (%d) must in range [0,%d] [us]", rf->rfwave.description, rf->iso2end, rf->rfwave.duration);
2744  }
2745 
2746  /* check that .iso2end is equal to .rfpulse.isodelay */
2747  if (rf->rfpulse.isodelay != rf->iso2end) {
2748  return ks_error("ks_eval_rf (%s): 'rf.rfpulse.isodelay (%d) must be equal to 'rf.iso2end' (%d) [us]", rf->rfwave.description, rf->rfpulse.isodelay, rf->iso2end);
2749  }
2750 
2751  rf->rfpulse.isodelay = RUP_GRD(rf->rfpulse.isodelay); /* Round up using RUP_GRD() to fall on gradient raster (GRAD_UPDATE_TIME = 4us) */
2752  rf->iso2end = rf->rfpulse.isodelay;
2753  rf->start2iso = rf->rfwave.duration - rf->iso2end; /* time from start of RF pulse to its magnetic center */
2754 
2755  /* initialize amplitude to 1 */
2756  rf->amp = 1;
2757 
2758  /* set the usage of the RF PULSE to off until .base.ninst > 0 (see ks_pg_rf() on HOST) */
2759  rf->rfpulse.activity = PSD_PULSE_OFF;
2760 
2761  /* initialize number of occurrences of RF pulse to zero */
2762  rf->rfpulse.num = 0;
2763 
2764 
2765  return SUCCESS;
2766 
2767 } /* ks_eval_rf */
int start2iso
Definition: KSFoundation.h:944
int role
Definition: KSFoundation.h:939
RF_PULSE rfpulse
Definition: KSFoundation.h:948
STATUS ks_error(const char *format,...) __attribute__((format(printf
Common error message function for HOST and TGT
Definition: KSFoundation.h:1953
float flip
Definition: KSFoundation.h:940
#define KS_DESCRIPTION_LENGTH
Definition: KSFoundation.h:185
KS_WAVE thetawave
Definition: KSFoundation.h:951
KS_DESCRIPTION description
Definition: KSFoundation.h:666
KS_WAVE rfwave
Definition: KSFoundation.h:949
Definition: KSFoundation.h:1953
float amp
Definition: KSFoundation.h:943
int iso2end
Definition: KSFoundation.h:945
void ks_eval_rf_relink(KS_RF *rf)
(Internal use) Relinks pointers between fields in a KS_RF object
Definition: KSFoundation_host.c:2771
KS_WAVE omegawave
Definition: KSFoundation.h:950
int res
Definition: KSFoundation.h:667
int duration
Definition: KSFoundation.h:668
float bw
Definition: KSFoundation.h:941

◆ ks_eval_rf_relink()

void ks_eval_rf_relink ( KS_RF rf)

(Internal use) Relinks pointers between fields in a KS_RF object

This function is used by other RF functions to make sure that the links from pointers in .rfpulse are relinked to other fields inside the KS_RF object. This function does not need to be called manually as long as either ks_eval_rf(), ks_eval_selrf() are called.

If a KS_RF object is copied to another KS_RF object by simple assignment ('=' sign), then these pointers must be updated before the assigned KS_RF object can be used. Best practice is to call ks_eval_rf() or ks_eval_selrf() instead of this function, as more validation is performed and because description of the new KS_RF is also updated

Parameters
[in,out]rfPointer to the KS_RF object to be set up
2771  {
2772 
2773  /* link as required by RF_PULSE */
2774  rf->rfpulse.pw = &(rf->rfwave.duration);
2775  rf->rfpulse.amp = &(rf->amp);
2776  rf->rfpulse.act_fa = &(rf->flip);
2777  rf->rfpulse.res = &(rf->rfwave.res);
2778  rf->rfpulse.exciter = &ks_rhoboard;
2779 }
int ks_rhoboard
Definition: KSFoundation_common.c:42
RF_PULSE rfpulse
Definition: KSFoundation.h:948
float flip
Definition: KSFoundation.h:940
KS_WAVE rfwave
Definition: KSFoundation.h:949
float amp
Definition: KSFoundation.h:943
int res
Definition: KSFoundation.h:667
int duration
Definition: KSFoundation.h:668

◆ ks_eval_stretch_rf()

STATUS ks_eval_stretch_rf ( KS_RF rf,
float  stretch_factor 
)

In-place stretching of a KS_RF object

This function takes a KS_RF object already set up, having some resolution (rfwave.res), bandwidth (.bw), duration (rfwave.duration) and waveform (.rfwave.waveform) and performs a linear interpolation of the waveform contained in .rfwave.waveform so its new duration becomes

newDuration = oldDuration * stretch_factor

  • Note that regardless of the input resolution of the waveform, the output resolution will always be newDuration/2.
  • The description of the stretched KS_RF object (.rfwave.description) is updated with a suffix stretched
  • The fields .start2iso, .iso2end and .bw are automatically updated to reflect the new duration
Parameters
[in,out]rfPointer to the KS_RF object to be stretched
[in]stretch_factorStretch factor (float) that widens/shortens the RF pulse if larger/smaller than 1.0. If negative, the RF waveform will be mirrored (in time)
Return values
STATUSSUCCESS or FAILURE
3500  {
3501 
3502  STATUS status;
3503  int idx;
3504  int debug = 0;
3505  int mirror_rfpulse = 0;
3506 
3507  if (areSame(stretch_factor, 1.0)) {
3508  return SUCCESS;
3509  }
3510 
3511  mirror_rfpulse = (stretch_factor < 0); /* we are going to mirror the RF pulse after stretching */
3512  stretch_factor = fabsf(stretch_factor);
3513 
3514  if (stretch_factor < FLT_EPSILON) {
3515  return ks_error("%s(%s): can not stretch by %f", __FUNCTION__, rf->rfwave.description, stretch_factor);
3516  }
3517 
3518  /* get original duration/resolution and calculate new duration/resolution */
3519  int orgDur = rf->rfwave.duration;
3520  int newDur = RUP_GRD((int)(orgDur * stretch_factor));
3521  int orgRes = rf->rfwave.res;
3522  int newRes = newDur/RF_UPDATE_TIME;
3523 
3524  if (newRes > KS_MAXWAVELEN) {
3525  return ks_error("%s(%s): stretch => too high res (%d)", __FUNCTION__, rf->rfwave.description, newRes);
3526  }
3527 
3528  /* create index for interpolation */
3529  float *orgGrid = (float*)alloca(orgRes * sizeof(float));
3530  float *newGrid = (float*)alloca(newRes * sizeof(float));
3531  for (idx = 0; idx < orgRes; idx++) {
3532  orgGrid[idx] = (float) idx / (orgRes-1);
3533  }
3534  for (idx = 0; idx < newRes; idx++) {
3535  newGrid[idx] = (float) idx / (newRes-1);
3536  }
3537 
3538  if (debug == 1) {ks_print_waveform(rf->rfwave.waveform, "stretch_orgrf.txt", orgRes); }
3539 
3540  /* perform linear interpolation */
3541  ks_eval_linear_interp1(orgGrid, orgRes, rf->rfwave.waveform, newGrid, newRes, rf->rfwave.waveform);
3542