#include <KSFoundation.h>
Data Fields | |
int | role |
float | flip |
float | bw |
float | cf_offset |
float | amp |
int | start2iso |
int | iso2end |
int | iso2end_subpulse |
KS_DESCRIPTION | designinfo |
RF_PULSE | rfpulse |
KS_WAVE | rfwave |
KS_WAVE | omegawave |
KS_WAVE | thetawave |
int | omega_iwave_phase_at_iso |
The composite KS_RF sequence object holds all information necessary to create RF pulses, both real and freq/phase modulated ones. For RF pulses with slice selection, use a KS_SELRF object instead, which contains a KS_RF object and KS_TRAP objects. The KS_RF object (be it standalone or a part of KS_SELRF) needs to be set up along the lines described here
Independent of the design method chosen (see below), KS_RF has some field members worth mentioning:
.role
: This is a label for the role of the RF pulse. This information is primarily used by ks_eval_selrf() to determine what gradients to apply for slice selection. Valid values for .role
are.flip
: The desired flip angle of the RF pulse [degrees].bw
: The bandwidth of the RF pulse [Hz].iso2end
and .start2iso
: These fields are for convenience and easier timing calculations and are set in ks_eval_rf(). The value of .iso2end
is equal to .rfpulse.isodelay
and refers to the time from the effective center of the RF pulse to the end. Field .iso2end
must have a correct value before calling ks_eval_rf(). The .start2iso
field is the time from the beginning of the RF pulse to its effective center, calculated as .rfwave.duration - .iso2end
in ks_eval_rf().cf_offset
: is used to change the relative center frequency for non-slice selective RFs. A typical application is non-slice selective fat saturation..designinfo
: is an optional string to keep track of useful RF design details (mostly for debugging purposes), and it is up to the user to fill this in, except for some pre-generated RF pulses available in KSFoundation_GERF.h.amp
: This field is set to 1 by ks_eval_rf(), but will get a proper value after calling GEReq_eval_rfscaling(). The value of .amp
is used in the @pg
section by ks_pg_rf() to properly amplitude scale the actual RF waveform before internally calling ks_pg_wave() using the .rfwave
field.The simplest way to create a KS_RF object is to use one of the RF pulses in GE's product sequences, some of which are available in KSFoundation_GERF.h. To use these ready-made RF pulses, perform the following steps:
@ipgexport
sectionKS_RF myrf = KS_INIT_RF;
myrf = exc_fse90;
The field .flip
can be changed anytime between ks_eval_rf() and GEReq_eval_rfscaling(), e.g. by setting .flip = opflip
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, the function ks_eval_rf_sinc() 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), as follows:
@ipgexport
sectionKS_RF mysincrf = KS_INIT_RF;
mysincrf.rfwave.duration
) depends on the chosen BW and TBWmysincrf.role = KS_RF_ROLE_EXC; // or KS_RF_ROLE_REF, KS_RF_ROLE_INV, KS_RF_ROLE_CHEMSAT
Note that in most scenarios a KS_SELRF is used instead of a KS_RF, as Sinc RFs are typically used with slice selection. Hence, in practice, a KS_SELRF should be declared, and the above procedure should be applied to the .rf
field (of type KS_RF) in the KS_SELRF object.
Another method is to copy a waveform designed elsewhere into the .rfwave
(KS_WAVE) field of the KS_RF object. This can be done from either memory (ks_eval_wave()) or disk (ks_eval_wave_file()).
Assuming we have an RF envelope in some float array myexternalrfwave[]
, the following steps are performed:
@ipgexport
sectionKS_RF mycustomrf = KS_INIT_RF;
ks_eval_wave(&mycustomrf.rfwave, "", res, duration, myexternalrfwave);
.thetawave
and/or .omegawave
.role
.flip
[degrees] (will also be the nominal flip angle).bw
[Hz].iso2end
[us] (the time from effective center of the RF pulse to the end)mycustomrf.rfpulse
) that is needed for RF scaling and SAR calculations.rfpulse
struct needs to be set up manuallyFirst make sure there is a separate sequence making function in the @pg
section that holds all function calls to the various ks_pg_***()
functions building up the sequence. E.g. there is a ksfse_pg() function in ksfse.e.
seqctrl.min_duration
to a value corresponding to the number of us to the end of the sequence module (see example below).cveval()
(on HOST) and in pulsegen()
in the @pg
section (on TGT), UsePgenOnHost() must be set in the Imakefilecveval()
to perform RF scaling and SAR handling. **When KS_RF objects are added to an existing GE product sequence (or any other standard EPIC sequence), RF scaling and SAR calculations are already taken care of for the non-KSFoundation RF-pulses. To include also the KS_RF pulses (including the KS_RF objects in KS_SELRF) as a part of the main sequence's RF scaling, the following steps are needed:
rfpulse[]
struct array for each KS_RF (or KS_SELRF) object by editing grad_rf_<psdname>.h
. The file grad_rf_empty.h
in the KSFoundation folder can be used as a template. This only serves a place holder to fill up space in rfpulse[]
, and no need to edit the grad_rf_<psdname>.h
furtherRF_FREE1
(sometimes RF_FREE2
) in grad_rf_<psdname>.globals.h
and add defines
for the new slots.rfpulse
field of each KS_RF object has the fields:.activity = PSD_SCAN_ON
.num = <number of instances of this KS_RF object in the sequence>
.rfpulse
field of each KS_RF object in to each corresponding SLOT in the rfpulse[]
array. E.g.:rfpulse[MYOWNFATSAT_SLOT] = myfatsat.rfpulse;
where MYOWNFATSAT_SLOT
has been defined as an available number less than RF_FREE1 in grad_rf_<psdname>.globals.h
int role |
The purpose of the RF pulse. Valid values: KS_RF_ROLE_EXC, KS_RF_ROLE_REF, KS_RF_ROLE_CHEMSAT, KS_RF_ROLE_INV, KS_RF_ROLE_SPSAT
float flip |
The flip angle in [degrees]
float bw |
The bandwidth of the RF pulse [Hz]
float cf_offset |
Center frequency offset in [Hz] for non-slice selective RF. Use e.g. 0 for water, 220 (1.5T) or 440 (3T) for fat
float amp |
Relative amplitude, not in [G], set by GE's RF scaling routines in GEReq_eval_rfscaling() & ks_eval_rfimits()
int start2iso |
Time from start of RF pulse to its magnetic center in [us]
int iso2end |
Time from the magnetic center of the RF pulse to the end in [us]
int iso2end_subpulse |
Time for last subpulse to end of RF waveform. Used by SPSP
KS_DESCRIPTION designinfo |
Descriptive string regarding the RF pulse design with maximum KS_DESCRIPTION_LENGTH characters
RF_PULSE rfpulse |
Internal use (typedef struct RF_PULSE
)
int omega_iwave_phase_at_iso |
Internal use, when an RF object is pg'd this field is set according to start2iso.