#include "grad_rf_empty.globals.h"
#include "em_psd_ermes.in"
#include "stddef_ep.h"
#include "epicconf.h"
#include "pulsegen.h"
#include "epic_error.h"
#include "epic_loadcvs.h"
#include "InitAdvisories.h"
#include "psdiopt.h"
#include "filter.h"
#include "epicfuns.h"
#include <sokPortable.h>
#include "KSFoundation.h"
#include <psd_proto.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sar_pm.h"
#include "grad_rf_empty.h"
#include <sysDep.h>
#include <sysDepSupport.h>
#include <support_func.h>
#include <math.h>
#include "psdopt.h"
#include "predownload.in"
#include "cvinit.in"
#include <support_func.host.h>
Data Structures | |
struct | ks_kacq_coord_params_t |
Macros | |
#define | seq_name ]_set |
#define | GEREQUIRED_E |
#define | CLINICAL_MODE 0 |
#define | MAX_ENTRY_POINTS 15 |
#define | MAX_SEQMODULES_DURATION_DEVIATION_FRACTION 0.0001 |
#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_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_PSD_USE_APX 0 |
Typedefs | |
typedef int | bool |
Functions | |
KS_SEQLENGTH (seq_name, seq_struct) | |
STATUS | calcPulseParams (int p) |
STATUS | simscan (void) |
STATUS | GEReq_init_gradspecs (LOG_GRAD *loggrd, PHYS_GRAD *phygrd, float srfact) |
STATUS | GEReq_init_accelUI (int integeraccel, int maxaccel) |
STATUS | GEReq_eval_TRrange (int *slperpass, int *timetoadd_perTR, int requested_minacqs, int mintr, int maxtr, KS_SEQ_COLLECTION *seqcollection, int(*play_loop)(int, int, void **), int nargs, void **args) |
STATUS | GEReq_eval_TR (int *slperpass, int *timetoadd_perTR, int requested_minacqs, KS_SEQ_COLLECTION *seqcollection, int(*play_loop)(int, int, void **), int nargs, void **args) |
STATUS | GEReq_eval_rfscaling (KS_SEQ_COLLECTION *seqcollection) |
STATUS | GEReq_eval_checkTR_SAR_calcs (KS_SEQ_COLLECTION *seqcollection, s64 intended_time) |
STATUS | GEReq_eval_checkTR_SAR (KS_SEQ_COLLECTION *seqcollection, int nslices, int(*play_loop)(int, int, void **), int nargs, void **args) |
STATUS | GEReq_predownload_store_sliceplan (KS_SLICE_PLAN slice_plan) |
STATUS | GEReq_predownload_store_sliceplan_sms (const KS_SLICE_PLAN slice_plan, int sms_factor) |
STATUS | GEReq_predownload_store_sliceplan3D (int slices_in_slab, int slabs) |
STATUS | GEReq_predownload_setfilter_or_find_equivalent (FILTER_INFO *myfilter, FILTER_BLOCK_TYPE type) |
int | GEReq_get_num_used_slots () |
PSD_FILTER_GEN | GEReq_get_maxsize_finfo (int n_prescan_slots) |
STATUS | GEReq_predownload_setfilter (FILTER_INFO *filt) |
STATUS | GEReq_echotrain_setfilters (KS_ECHOTRAIN *const echotrain) |
STATUS | GEReq_predownload_minimize_ps_filter_slots () |
STATUS | GEReq_setfilters (KS_SEQ_COLLECTION *const seq_collection) |
STATUS | GEReq_predownload_genVRGF (const KS_READTRAP *const readtrap) |
STATUS | GEReq_predownload_genrowflip (KS_EPI *epi, int blipsign, int assetflag, int dorowflip) |
STATUS | GEReq_predownload_setrecon_writekacq (const KS_READTRAP *const readtrap, const KS_PHASER *const phaser, const KS_PHASER *const zphaser) |
int | ks_get_unique_y_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_unique_z_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_ynover_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_znover_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_ry_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_rz_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_cal_z_from_pecoords (const KS_KSPACE_ACQ *kacq) |
int | ks_get_cal_y_from_pecoords (const KS_KSPACE_ACQ *kacq) |
ks_kacq_coord_params_t | GEReq_kacq_get_params (const KS_KSPACE_ACQ *kacq) |
STATUS | GEReq_writekacq (const int nrecon_schedule_entries, KS_KACQ_RECONSHEDULE_ENTRY *recon_schedule, const int num_patterns, const KS_KSPACE_ACQ *ks_kacq) |
STATUS | GEReq_writekacq_from_coords (const KS_KSPACE_ACQ *kacq, const int nechoes) |
STATUS | GEReq_predownload_setrecon_accel_from_coords (const KS_KSPACE_ACQ *kacq, const int is_pf_y, const int nechoes) |
STATUS | GEReq_predownload_setrecon_accel (const KS_READTRAP *const readtrap, const KS_PHASER *const phaser, const KS_PHASER *const zphaser, int datadestination) |
void | GEReq_predownload_setrecon_phase (const KS_PHASER *const phaser, const float readfov, const int datadestination) |
void | GEReq_predownload_setrecon_readwave (const KS_READWAVE *const readwave, const int yres, const int xres, int imsize_policy, int datadestination) |
void | GEReq_predownload_setrecon_image (const int xres, const int yres, const float xfov, const float yfov, const ks_enum_imsize imsize_policy) |
void | GEReq_predownload_setrecon_readtrap (const KS_READTRAP *const readtrap, int datadestination) |
void | GEReq_predownload_setrecon_readphase (const KS_READTRAP *const readtrap, const KS_PHASER *const phaser, const KS_PHASER *const zphaser, int imsize_policy, int datadestination) |
void | GEReq_predownload_setrecon_annotations (int tsp, int readdur, int time2center, int echogap) |
void | GEReq_predownload_setrecon_annotations_readtrap (KS_READTRAP *readtrap, int echogap) |
void | GEReq_predownload_setrecon_annotations_readwave (KS_READWAVE *readwave, int echogap) |
void | GEReq_predownload_setrecon_annotations_epi (KS_EPI *epi, int echogap) |
void | GEReq_predownload_setrecon_voldata (int numvols, const KS_SLICE_PLAN slice_plan) |
STATUS | GEReq_predownload_setrecon_epi (KS_EPI *epi, int numvols2store, const KS_SLICE_PLAN slice_plan, int echogap, int blipsign, int datadestination, int multishotflag, int staticghostcal, int imsize_policy) |
STATUS | GEReq_predownload_prescan_options (RG_CAL_MODE_E rg_cal_mode) |
STATUS | GEReq_cvinit (void) |
STATUS | GEReq_cveval (void) |
void | getAPxParam (optval *min, optval *max, optdelta *delta, optfix *fix, float coverage, int algorithm) |
int | getAPxAlgorithm (optparam *optflag, int *algorithm) |
STATUS | GEReq_cvcheck (void) |
STATUS | GEReq_predownload (void) |
void | GEReq_pulsegenBegin (void) |
void | GEReq_pulsegenEnd (void) |
int | GEReq_endofpass () |
int | GEReq_endofscan () |
int | GEReq_endofpassandscan () |
void | dummylinks (void) |
void | GEReq_initRSP (void) |
Variables | |
RF_PULSE_INFO | rfpulseInfo [RF_FREE] = { {0, 0} } |
int | avail_image_time |
ifndef ACT_TR_EXISTS int | act_tr |
endif SCAN_INFO | ks_scan_info [SLTAB_MAX] = {DEFAULT_AXIAL_SCAN_INFO} |
KS_SLICE_PLAN | ks_slice_plan = KS_INIT_SLICEPLAN |
int | ks_sarcheckdone = FALSE |
char | ks_psdname [256] |
int | ks_perform_slicetimeplot = FALSE |
KS_SEQ_CONTROL | seqctrl_passpack = KS_INIT_SEQ_CONTROL |
int | obl_debug = 0 with {0, 1, 0, INVIS, "On(=1) to print messages for obloptimize",} |
int | obl_method = PSD_OBL_OPTIMAL with {PSD_OBL_RESTRICT, PSD_OBL_OPTIMAL, PSD_OBL_OPTIMAL, INVIS, "On(=1) to optimize the targets based on actual rotation matrices",} |
int | filter_echo1 = 0 with {, , , INVIS, "Scan filter slot number needed for prescan",} |
int | pw_passpacket = 50ms with {10ms, 1000ms, 50ms, VIS, "Duration of the passpacket sequence",} |
int | ks_rfconf = ENBL_RHO1 + ENBL_THETA + ENBL_OMEGA + ENBL_OMEGA_FREQ_XTR1 |
int | ks_simscan = 1 with {0, 1, 1, VIS, "Simulate slice locations if 1 (and in simulation)",} |
float | ks_srfact = 1.0 with {0.01, 3.0, 1.0, VIS, "Slewrate factor (low value = slower gradients)",} |
float | ks_qfact = 1.0 with {0.1, 40.0, 1.0, VIS, "Quietness factor",} |
int | ks_plot_filefmt = KS_PLOT_MAKEPNG with {KS_PLOT_OFF,KS_PLOT_MAKEPNG,KS_PLOT_MAKEPNG, VIS, "Plot format 0:off 1:PDF 2:SVG 3:PNG"} |
int | ks_plot_kstmp = FALSE with {FALSE,TRUE,FALSE, VIS, "0: off 1:Copy plots to mrraw/kstmp"} |
int | ks_compress_ps_filter_slots = FALSE with {FALSE,TRUE,FALSE, VIS, "Minimize the number of filterslots for prescan"} |
int | ks_clinicalmode = CLINICAL_MODE with {0, 1, CLINICAL_MODE, VIS, "Clinical mode: on=1 / off=0"} |
float | maxB1 [MAX_ENTRY_POINTS] |
float | maxB1Seq |
short | debugstate |
short | viewtable [513] |
PSD_EXIT_ARG | psdexitarg |
int | rspent |
int | rspdda |
int | rspbas |
int | rspvus |
int | rspgy1 |
int | rspasl |
int | rspesl |
int | rspchp |
int | rspnex |
int | rspslq |
int | rspsct |
int | rsprep |
short | chopamp |
int | seqCount |
int | view |
int | excitation |
int | debug |
const CHAR * | entry_name_list [ENTRY_POINT_MAX] |
written entirely in KSFoundation EPIC. See instructions for each section on where to @inline
#define seq_name ]_set |
#define GEREQUIRED_E |
#define CLINICAL_MODE 0 |
#define MAX_ENTRY_POINTS 15 |
#define MAX_SEQMODULES_DURATION_DEVIATION_FRACTION 0.0001 |
#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_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_PSD_USE_APX 0 |
typedef int bool |
KS_SEQLENGTH | ( | seq_name | , |
seq_struct | |||
) |
This EPIC macro is adapted from GE's EPIC macro SEQLENGTH
. The seqctrl
(KS_SEQ_CONTROL) struct for the current sequence module is passed in as the second argument to this function, where seqctrl.duration
holds the information on the duration of the sequence module and passed on to createseq()
. During scanning, ks_scan_playsequence(), which takes a KS_SEQ_CONTROL struct as input, internally calls boffset()
to make a real-time hardware switch to this sequence module by passing in seqctrl.handle.offset
set by KS_SEQLENGTH().
KS_SEQLENGTH() must be called in pulsegen()
after the sequence (module) has been layed out using various ks_pg_***
calls. It must also be after GEReq_pulsegenBegin() and before GEReq_pulsegenEnd() and buildinstr()
. The first argument to KS_SEQLENGTH() is GE's name of the pulse sequence module, which by convention usually begins with "seq***". The hardware sequence handle is then named off_seq***
and this handle is stored in seqctrl.handle.offset
.
STATUS calcPulseParams | ( | int | p | ) |
STATUS simscan | ( | void | ) |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_init_gradspecs | ( | LOG_GRAD * | loggrd, |
PHYS_GRAD * | phygrd, | ||
float | srfact | ||
) |
This function calls inittargets() to get the physical gradient characteristics from the MR-system, followed by a call to obloptimize() (slice angulation dependence) to get the logical gradient specifications for the current slice angulation.
The ramp times (loggrd.xrt/yrt/zrt) are quite conservative (and longer than the ramptimes for phygrd). Preliminary testing indicates that the difference between the loggrd and phygrad structs can be reduced by a factor of two (not very scientific!) as a standard measure.
For further control over the slewrate, the srfact
argument is passed to ks_init_slewratecontrol(), which can both slow down and increase the gradient slewrate.
[out] | loggrd | The global logical gradient specification struct (dependent on slice angulation via global SCAN_INFO scan_info[] struct). |
[out] | phygrd | The global physical gradient struct |
[in] | srfact |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_init_accelUI | ( | int | integeraccel, |
int | maxaccel | ||
) |
[in] | integeraccel | Flag to make acceleration menu contain only integer acceleration factors enums: KS_ARCMENU_FRACTACCEL (0), KS_ARCMENU_INTACCEL (1) |
[in] | maxaccel | Maximum allowed acceleration factor for the sequence |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_eval_TRrange | ( | int * | slperpass, |
int * | timetoadd_perTR, | ||
int | requested_minacqs, | ||
int | mintr, | ||
int | maxtr, | ||
KS_SEQ_COLLECTION * | seqcollection, | ||
int(*)(int, int, void **) | play_loop, | ||
int | nargs, | ||
void ** | args | ||
) |
2024 UPDATE: THIS FUNCTION IS ONLY USED BY KSGRE_TUTORIAL.E AND DEPCREATED PSDS.
This function calculates the number of slices that can fit in one TR (optr) based on the duration and occurences of the sequence modules in the sequence collection (KS_SEQ_COLLECTION) determined by calling the sequence sliceloop (wrapper) function.
As the number of arguments to the sequence's sliceloop is psd-dependent, the function pointer play_loop
must be a wrapper function to the sliceloop function taking standardized input arguments (int) nargs
and (void **) args
. This sliceloop wrapper function must be on the form: int sliceloop_nargs(int slperpass, int nargs, void **args);
returning the duration in [us] to play out slperpass
number of slices. If the sliceloop function does not need any additional input arguments, nargs = 0
, and args = NULL
.
The minimum allowed TR is determined by ks_eval_mintr(), which honors SAR/heating limitations. If opautotr = 1
, optr
will be updated here, otherwise if optr
is too short, an error will be returned to the operator.
The calling function can specify the minimum acqs that are allowed, as well as a minimum and maximum TR interval. Setting maxtr = 0
disables the upper TR limit. Setting requested_minacqs <= 1
, disables the min acqs requirement.
This function should be called at the end of cveval() after all sequence modules have been set up and dry-runned on host by calling each sequence module's ****_pg()
function. See also the documentation for KS_SEQ_CONTROL and KS_SEQ_COLLECTION.
[out] | slperpass | Number of slices that can fit within each TR |
[out] | timetoadd_perTR | The total time in [us] that must be distributed manually to one or more sequence modules after the call to GEReq_eval_TR() in order to meet the desired TR |
[in] | requested_minacqs | The desired minimum number of acquisitions (passes) |
[in] | mintr | Lowest allowed TR in [us] |
[in] | maxtr | Highest allowed TR in [us]. 0: Disabled |
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
[in] | play_loop | Function pointer to (the wrapper function to) the sliceloop function of the sequence |
[in] | nargs | Number of extra input arguments to the sliceloop wrapper function. |
[in] | args | Void pointer array pointing to the variables containing the actual values needed for the sequence's sliceloop function |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_eval_TR | ( | int * | slperpass, |
int * | timetoadd_perTR, | ||
int | requested_minacqs, | ||
KS_SEQ_COLLECTION * | seqcollection, | ||
int(*)(int, int, void **) | play_loop, | ||
int | nargs, | ||
void ** | args | ||
) |
2024 UPDATE: THIS FUNCTION IS ONLY USED BY KSGRE_TUTORIAL.E AND DEPCREATED PSDS.
STATUS GEReq_eval_rfscaling | ( | KS_SEQ_COLLECTION * | seqcollection | ) |
RF scaling is a complicated process across RF pulses in scan (multiple sequence modules) and prescan, where the desired flip angles should be met partly using the maxB1 info for each RF pulse and scale it relative to the prescan result. This is done via a combination of scan and prescan attenuation factors (xmtaddScan) in the entry_point_table[]
, an extra global scaling factor, and change of the (instruction) amplitude of each RF pulse.
This function performs all these tasks using a KS_SEQ_COLLECTION as input. The sequence collection struct contains one KS_SEQ_CONTROL struct for each sequence module, which via the field gradrf.rfptr[]
has access to all KS_RF objects in the sequence module. As the ***_pg()
function for each sequence module should have been called prior to this function, the number of occurrences of each RF pulse is known. Moreover, the rfstat specification for every RF pulse is located in: seqcollection->seqctrl[]->gradrf->rfptr[]->rf.rfpulse which is used by ks_eval_seqcollection2rfpulse() to rewrite the global rfpulse[]
struct array required by GE's RF scaling functions peakB1() and setScale().
At the end of this function, the seqcollection mode is locked, preventing accidental addition of new sequence modules to the seqcollection using ks_eval_addtoseqcollection(). Moreover, each sequence module will have its rfscalingdone
field set to TRUE to signal to ks_pg_rf() that the RF pulse belonging to that sequence module has indeed been RF scaled properly. This extra safety mechanism makes it difficult to use ks_pg_rf() without first passing through this function and have the seqcollection struct set up.
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_eval_checkTR_SAR_calcs | ( | KS_SEQ_COLLECTION * | seqcollection, |
s64 | intended_time | ||
) |
2024 UPDATE: THE NEW HEATING MODEL IN KSFOUNDATION (2024) USES ks_eval_hwlimit()
INSTEAD OF GEReq_eval_checkTR_SAR()
This function is called to check that the sequence modules played out in the slice loop sum up to the specified TR (optr) accounting for SAR/heating limits. Moreover, the SAR values are updated in the UI, and the CV ks_sarcheckdone is set to TRUE. This CV is set to FALSE in GEReq_cvinit() and check whether it is TRUE in GEReq_predownload() to make sure SAR calculation have been performed before scanning.
[in,out] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
[in] | intended_time | Usually repetition time (optr), should correspond to the intended time to play the corresponding number of sequence instances now set in seqcollection[]->seqctrl.ninst |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_eval_checkTR_SAR | ( | KS_SEQ_COLLECTION * | seqcollection, |
int | nslices, | ||
int(*)(int, int, void **) | play_loop, | ||
int | nargs, | ||
void ** | args | ||
) |
2024 UPDATE: THIS FUNCTION IS ONLY USED BY KSGRE_TUTORIAL.E AND DEPCREATED PSDS.
This function first makes sure that the .nseqinstances
field for each sequence module in the sequence collection corresponds to the number of times played out in the sequence's sliceloop function.
In simulation (WTools), ks_print_seqcollection() will print out a table of the sequence modules in the sequence collection in the WToolsMgd window.
Finally, GEReq_eval_checkTR_SAR_calcs() is called to check that the TR is correct and within SAR/hardware limits.
N.B.: For inversion sequences, ksinv_eval_checkTR_SAR() is used to do the same thing, with the difference that ksinv_scan_sliceloop() is used instead.
[in] | seqcollection | Pointer to the KS_SEQ_COLLECTION struct holding all sequence modules |
[in] | nslices | Number of slices in TR |
[in] | play_loop | Function pointer to (the wrapper function to) the sliceloop function |
[in] | nargs | Number of extra input arguments to the sliceloop wrapper function. |
[in] | args | Void pointer array pointing to the variables containing the actual values needed for the sliceloop function |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_store_sliceplan | ( | KS_SLICE_PLAN | slice_plan | ) |
The following global GE arrays are set based on slperpass (arg 1) and global op** variables:
data_acq_order[]
: Critical for scanningrsp_info[]
: Copied from scan_info[] (the graphically prescibed slices), for conformance. Is a temporally sorted version of scan_info[] with integer rotation matrices. Not needed for scanning.rsptrigger[]
: Set to TRIG_INTERN for now.data_acq_order[] is only available on HOST, why this function also copies data_acq_order[] to ks_data_acq_order[], which is an ipgexport
array accessible on both HOST and TGT. This can be used by ks_scan_getsliceloc() to be independent on rsp_info[] during scan.
The slice plan is stored as a text file ("ks_sliceplan.txt") in the current directory in simulation and in /usr/g/mrraw on the MR scanner by calling ks_print_sliceplan().
[in] | slice_plan | The current slice plan (KS_SLICE_PLAN) set up for the sequence (see ks_calc_sliceplan()) |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_store_sliceplan_sms | ( | const KS_SLICE_PLAN | slice_plan, |
int | sms_factor | ||
) |
STATUS GEReq_predownload_store_sliceplan3D | ( | int | slices_in_slab, |
int | slabs | ||
) |
The following global GE arrays are set based on slperpass (arg 1) and global op** variables:
data_acq_order[]
: Critical for scanningrsp_info[]
: Copied from scan_info[] (the graphically prescibed slices), for conformance. Is a temporally sorted version of scan_info[] with integer rotation matrices. Not needed for scanning.rsptrigger[]
: Set to TRIG_INTERN for now.data_acq_order[] is only available on HOST, why this function also copies data_acq_order[] to ks_data_acq_order[], which is an ipgexport
array accessible on both HOST and TGT. This can be used by ks_scan_getsliceloc() to be independent on rsp_info[] during scan.
GEReq_predownload_store_sliceplan3D() has different input args compared to the 2D version. Here, a temporary slice plan is created based on slices_in_slab and slabs in order to create the proper content of data_acq_order[]. Note that it wouldn't have worked to pass ks_slice_plan for 3D. This is because we need a ks_slice_plan that is consistent with RF excitations for 2D, 3D, 3DMS in each sequence's looping structure in scan. For 3D, this very ks_slice_plan can then not also create the proper data_acq_order array here. This is why we pass in slices_in_slab and slabs instead and create e temp slice plan solely for the purpose of data_acq_order.
[in] | slices_in_slab | Number of slices in a slab |
[in] | slabs | Number slabs |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_setfilter_or_find_equivalent | ( | FILTER_INFO * | myfilter, |
FILTER_BLOCK_TYPE | type | ||
) |
This function must be called in predownload() after GE's initfilter() function, which resets all filter slots for scan and prescan entry points. The initfilter() function is called in GEReq_cvinit().
Given the FILTER_INFO of the acquisition window for the main pulse sequence (arg 1), this function assigns a new slot number (that matches one of the hardware slots in the data receive chain.
The .epfilter
and .epprexres
of GE's global struct array entry_point_table[]
is also set.
[in] | myfilter | Pointer to FILTER_INFO struct (.filt field in KS_READ) |
[in] | type | Choose between SCAN & PRESCAN |
STATUS | SUCCESS or FAILURE |
int GEReq_get_num_used_slots | ( | ) |
PSD_FILTER_GEN GEReq_get_maxsize_finfo | ( | int | n_prescan_slots | ) |
STATUS GEReq_predownload_setfilter | ( | FILTER_INFO * | filt | ) |
STATUS GEReq_echotrain_setfilters | ( | KS_ECHOTRAIN *const | echotrain | ) |
STATUS GEReq_predownload_minimize_ps_filter_slots | ( | ) |
STATUS GEReq_setfilters | ( | KS_SEQ_COLLECTION *const | seq_collection | ) |
STATUS GEReq_predownload_genVRGF | ( | const KS_READTRAP *const | readtrap | ) |
When the .rampsampling
field of a KS_READTRAP is set to 1, 1D gridding in the frequency encoding direction is necessary before FFT to obtain an equidistant k-space. GE's product reconstruction uses a file (vrgf.param
) for this, which is generated by this function.
See also GEReq_predownload_setrecon_readphase(), which sets VRGF-specific global variables.
[in] | readtrap |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_genrowflip | ( | KS_EPI * | epi, |
int | blipsign, | ||
int | assetflag, | ||
int | dorowflip | ||
) |
GE's reconstruction (and data dumping) of EPI data (where every other readout is negative) needs to know which k-space lines that have been acquired with a negative gradient to perform a row flip on these lines before proceeding with Pfile writing and FFT processing.
[in] | epi | Pointer to KS_EPI |
[in] | blipsign | KS_EPI_POSBLIPS or KS_EPI_NEGBLIPS |
[in] | assetflag | Flag for ASSET mode or not (0: off, 2: ASSET_SCAN (on)) |
[in] | dorowflip | If 0, write just ones to let rowflipping process for Pfiles being executed without actual flipping |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_setrecon_writekacq | ( | const KS_READTRAP *const | readtrap, |
const KS_PHASER *const | phaser, | ||
const KS_PHASER *const | zphaser | ||
) |
If phaser.R > 1, a file is written to disk with phase encoding steps in an ARC accelerated scan ("kacq_yz.txt.*****"). This function has been adapted from GE's ARC.e, but supports only 2D (i.e. 1D-acceleration)
[in] | readtrap | Pointer to readout trapezoid. Used to determine k-space peak along kx |
[in] | phaser | Pointer to phase encoding object (KS_PHASER) with acceleration |
[in] | zphaser | Pointer to z phase encoding object (KS_PHASER) with acceleration. NULL for 2D |
STATUS | SUCCESS or FAILURE |
int ks_get_unique_y_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_unique_z_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_ynover_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_znover_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_ry_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_rz_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_cal_z_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
int ks_get_cal_y_from_pecoords | ( | const KS_KSPACE_ACQ * | kacq | ) |
ks_kacq_coord_params_t GEReq_kacq_get_params | ( | const KS_KSPACE_ACQ * | kacq | ) |
STATUS GEReq_writekacq | ( | const int | nrecon_schedule_entries, |
KS_KACQ_RECONSHEDULE_ENTRY * | recon_schedule, | ||
const int | num_patterns, | ||
const KS_KSPACE_ACQ * | ks_kacq | ||
) |
STATUS GEReq_writekacq_from_coords | ( | const KS_KSPACE_ACQ * | kacq, |
const int | nechoes | ||
) |
STATUS GEReq_predownload_setrecon_accel_from_coords | ( | const KS_KSPACE_ACQ * | kacq, |
const int | is_pf_y, | ||
const int | nechoes | ||
) |
[in] | kacq | k-Space coordinates. |
[in] | is_pf_y | Flag if partial Fourier along Y. |
[in] | nechoes | Number of echoes. Only relevant for kacq file, i.e. ARC + online recon |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_setrecon_accel | ( | const KS_READTRAP *const | readtrap, |
const KS_PHASER *const | phaser, | ||
const KS_PHASER *const | zphaser, | ||
int | datadestination | ||
) |
[in] | readtrap | Pointer to KS_READTRAP |
[in] | phaser | Pointer to KS_PHASER (phase) |
[in] | zphaser | Pointer to KS_PHASER (slice). NULL for 2D |
[in] | datadestination | Value to assign to rhexecctrl (c.f. epic.h) |
STATUS | SUCCESS or FAILURE |
void GEReq_predownload_setrecon_phase | ( | const KS_PHASER *const | phaser, |
const float | readfov, | ||
const int | datadestination | ||
) |
void GEReq_predownload_setrecon_readwave | ( | const KS_READWAVE *const | readwave, |
const int | yres, | ||
const int | xres, | ||
int | imsize_policy, | ||
int | datadestination | ||
) |
void GEReq_predownload_setrecon_image | ( | const int | xres, |
const int | yres, | ||
const float | xfov, | ||
const float | yfov, | ||
const ks_enum_imsize | imsize_policy | ||
) |
void GEReq_predownload_setrecon_readtrap | ( | const KS_READTRAP *const | readtrap, |
int | datadestination | ||
) |
void GEReq_predownload_setrecon_readphase | ( | const KS_READTRAP *const | readtrap, |
const KS_PHASER *const | phaser, | ||
const KS_PHASER *const | zphaser, | ||
int | imsize_policy, | ||
int | datadestination | ||
) |
For Cartesian pulse sequences, using one KS_READTRAP and one KS_PHASER (each of which may have multiple instances), the required rh*** variables are set based on the content of the sequence objects KS_READTRAP (arg 1) and KS_PHASER (arg 2). The fields in each sequence object, including e.g. partial Fourier and rampsampling, controls the setting of GE's rh*** variables. In addition, the third argument specifies the desired upsampling policy for small matrix sizes.
[in] | readtrap | Pointer to KS_READTRAP |
[in] | phaser | Pointer to KS_PHASER |
[in] | zphaser | Pointer to KS_PHASER (slice). NULL for 2D |
[in] | imsize_policy | Choose between KS_IMSIZE_NATIVE , KS_IMSIZE_POW2 , KS_IMSIZE_MIN256 |
[in] | datadestination | Value for the rhexecctrl variable. Bitmasks for: KS_SAVEPFILES (dump Pfiles) and KS_GERECON (product recon) |
void GEReq_predownload_setrecon_annotations | ( | int | tsp, |
int | readdur, | ||
int | time2center, | ||
int | echogap | ||
) |
Uses the global UI CVs opnecho
, opnex
, opte
and opte2
[in] | tsp | Dwell time in [us], i.e. the duration of one sample (which is also 1/rBW) |
[in] | readdur | Duration in [us] of the readout window |
[in] | time2center | Time in [us] to the center of the echo |
[in] | echogap | Gap between two echoes |
void GEReq_predownload_setrecon_annotations_readtrap | ( | KS_READTRAP * | readtrap, |
int | echogap | ||
) |
This is a wrapper function to GEReq_predownload_setrecon_annotations() using a KS_READTRAP
[in] | readtrap | Pointer to KS_READTRAP |
[in] | echogap | Gap between two echoes |
void GEReq_predownload_setrecon_annotations_readwave | ( | KS_READWAVE * | readwave, |
int | echogap | ||
) |
This is a wrapper function to GEReq_predownload_setrecon_annotations() using a KS_READWAVE
[in] | readwave | Pointer to KS_READWAVE |
[in] | echogap | Gap between two echoes |
void GEReq_predownload_setrecon_annotations_epi | ( | KS_EPI * | epi, |
int | echogap | ||
) |
This is a wrapper function to GEReq_predownload_setrecon_annotations() using a KS_EPI
[in] | epi | Pointer to KS_EPI |
[in] | echogap | Gap between two EPI trains |
void GEReq_predownload_setrecon_voldata | ( | int | numvols, |
const KS_SLICE_PLAN | slice_plan | ||
) |
The combination of rh*** variables allow for 50,000 image planes in GE's database.
However, Pfile data stops writing after 512 planes. To store more than 512 image planes as rawdata, RDS (Raw Data Server) or multivolume Pfiles can be used instead. It is possible that other mechanisms will be available through GE's upcoming Orchestra Live in the future.
[in] | numvols | Number of volumes (opfphases ) |
[in] | slice_plan | The slice plan (KS_SLICE_PLAN), set up using ks_calc_sliceplan() or similar |
STATUS GEReq_predownload_setrecon_epi | ( | KS_EPI * | epi, |
int | numvols2store, | ||
const KS_SLICE_PLAN | slice_plan, | ||
int | echogap, | ||
int | blipsign, | ||
int | datadestination, | ||
int | multishotflag, | ||
int | staticghostcal, | ||
int | imsize_policy | ||
) |
Calls GEReq_predownload_setrecon_readphase(), GEReq_predownload_setrecon_voldata() and GEReq_predownload_setrecon_annotations_epi(), and GEReq_predownload_genrowflip(). Additionally, some rh*** variables are overridden for EPI.
[in] | epi | Pointer to KS_EPI |
[in] | numvols2store | Number of volumes to store (including calibration vols such as ghostcorr) |
[in] | slice_plan | The slice plan (KS_SLICE_PLAN) set up using ks_slice_plan() or similar |
[in] | echogap | Gap between two EPI trains in [us] |
[in] | blipsign | KS_EPI_POSBLIPS or KS_EPI_NEGBLIPS |
[in] | datadestination | Value passed on to GEReq_predownload_setrecon_readphase() to set rhexecctrl |
[in] | multishotflag | 0: Parallel imaging mode 1: Multishot mode |
[in] | staticghostcal | Integrated refscan (Nyquist ghost correction). 0:Off, 1:On |
[in] | imsize_policy | Choice between KS_IMSIZE_NATIVE , KS_IMSIZE_POW2 , KS_IMSIZE_MIN256 |
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload_prescan_options | ( | RG_CAL_MODE_E | rg_cal_mode | ) |
STATUS GEReq_cvinit | ( | void | ) |
In the beginning of cvinit()
the following lines should be added:
This function sets up various global GE stuff, including e.g. the gradient specs. The gradient specs are controlled by ks_srfact
and ks_qfact
. ks_srfact
Should have a value that will allow scanning on all MR systems without PNS effects. Also, ks_srfact
does not affect the EPI train in ksepi.e, since it controls the slewrate and gradient max separately. ks_qfact
is supposed to be 1 by default, with the purpose to from an optimal setting reduce the slewrate to reduce the acoustic noise. A default value of 1.0 will make the system perform best but with high acoustic noise. A value of about 8-10 may be a good trade-off between acoustic noise reduction and reasonable image quality.
In this function, ks_sarcheckdone
is set to FALSE. This CV is checked in GEReq_predownload() and ks_pg_rf(), which both will complain if it is not has been set to TRUE. GEReq_eval_checkTR_SAR_calcs() sets this CV to TRUE.
It is important that an error returned from GEReq_cvinit() also results in an error in cvinit()
, otherwise it will not show up in the UI.
STATUS | SUCCESS or FAILURE |
STATUS GEReq_cveval | ( | void | ) |
In the beginning of cveval()
the following lines should be added:
This function up various global GE stuff, and copies also the struct array scan_info
, holding the prescribed slice locations to ks_scan_info
, the latter which can also be accessible on TGT.
Simulation (WTools): If we have ks_simscan = 1 (default), simscan() will have make up slice locations in ks_scan_info based on opslthick, opslspace and opslquant. Note, GE clears scan_info between cvcheck() and predownload() when in simulation. Hence, we now have the opposite case, i.e. we have some slice info data in ks_scan_info but nothing in scan_info.
It is important that an error returned from GEReq_cveval() also results in an error in cveval()
, otherwise it will not show up in the UI.
STATUS | SUCCESS or FAILURE |
void getAPxParam | ( | optval * | min, |
optval * | max, | ||
optdelta * | delta, | ||
optfix * | fix, | ||
float | coverage, | ||
int | algorithm | ||
) |
DV26 requires getAPxAlgorithm() and getAPxParam() functions to exist in each PSD. Empty getAPxAlgorithm() and getAPxParam() functions are declared below in GERequired.e to allow compilation on DV26. If a PSD wants to use this new functionality in DV26 it should add the following line: #define KS_PSD_USE_APX 1 in its @global section, so that KS_PSD_USE_APX is not set to 0 here, and hence getAPxAlgorithm() and getAPxParam() wont be redeclared here in GERequired.e.
int getAPxAlgorithm | ( | optparam * | optflag, |
int * | algorithm | ||
) |
STATUS GEReq_cvcheck | ( | void | ) |
In the beginning of cvcheck()
the following lines should be added:
It is important that an error returned from GEReq_cvcheck() also results in an error in cvcheck()
, otherwise it will not show up in the UI.
STATUS | SUCCESS or FAILURE |
STATUS GEReq_predownload | ( | void | ) |
In the beginning of predownload()
the following lines should be added:
This function up various global GE stuff related to recon and data filters. Also, ks_sarcheckdone
is checked to make sure that GEReq_eval_checkTR_SAR_calcs() has been called to monitor SAR/heating limits.
It is important that an error returned from GEReq_predownload() also results in an error in predownload()
, otherwise it will not show up in the UI.
STATUS | SUCCESS or FAILURE |
void GEReq_pulsegenBegin | ( | void | ) |
In the beginning of pulsegen()
the following lines should be added:
This function up various global GE stuff related to pulsegen()
void GEReq_pulsegenEnd | ( | void | ) |
In the end of pulsegen()
, but before buildinstr()
, the following lines should be added:
This function up prescan pulsegen and adds a PASSPACK sequence ("GEendpass"), which is used to dump rawdata and mark the end of scan. See GEReq_endofpass() and GEReq_endofscan() and how they are used in a psd.
int GEReq_endofpass | ( | ) |
After calling this function, the parent function must switch back to the previous/main sequence using ks_scan_playsequence() (or boffset()).
int GEReq_endofscan | ( | ) |
int GEReq_endofpassandscan | ( | ) |
void dummylinks | ( | void | ) |
void GEReq_initRSP | ( | void | ) |
RF_PULSE_INFO rfpulseInfo[RF_FREE] = { {0, 0} } |
int avail_image_time |
ifndef ACT_TR_EXISTS int act_tr |
endif SCAN_INFO ks_scan_info[SLTAB_MAX] = {DEFAULT_AXIAL_SCAN_INFO} |
N.B.: this file should contain includes and definitions common for host, target and sim that are private to KSFoundation. If in doubt always try to add here first instead of KSFoundation.h since that contains the public interface.
KS_SLICE_PLAN ks_slice_plan = KS_INIT_SLICEPLAN |
int ks_sarcheckdone = FALSE |
char ks_psdname[256] |
int ks_perform_slicetimeplot = FALSE |
KS_SEQ_CONTROL seqctrl_passpack = KS_INIT_SEQ_CONTROL |
int obl_debug = 0 with {0, 1, 0, INVIS, "On(=1) to print messages for obloptimize",} |
int obl_method = PSD_OBL_OPTIMAL with {PSD_OBL_RESTRICT, PSD_OBL_OPTIMAL, PSD_OBL_OPTIMAL, INVIS, "On(=1) to optimize the targets based on actual rotation matrices",} |
int filter_echo1 = 0 with {, , , INVIS, "Scan filter slot number needed for prescan",} |
int pw_passpacket = 50ms with {10ms, 1000ms, 50ms, VIS, "Duration of the passpacket sequence",} |
int ks_rfconf = ENBL_RHO1 + ENBL_THETA + ENBL_OMEGA + ENBL_OMEGA_FREQ_XTR1 |
int ks_simscan = 1 with {0, 1, 1, VIS, "Simulate slice locations if 1 (and in simulation)",} |
float ks_srfact = 1.0 with {0.01, 3.0, 1.0, VIS, "Slewrate factor (low value = slower gradients)",} |
float ks_qfact = 1.0 with {0.1, 40.0, 1.0, VIS, "Quietness factor",} |
int ks_plot_filefmt = KS_PLOT_MAKEPNG with {KS_PLOT_OFF,KS_PLOT_MAKEPNG,KS_PLOT_MAKEPNG, VIS, "Plot format 0:off 1:PDF 2:SVG 3:PNG"} |
int ks_plot_kstmp = FALSE with {FALSE,TRUE,FALSE, VIS, "0: off 1:Copy plots to mrraw/kstmp"} |
int ks_compress_ps_filter_slots = FALSE with {FALSE,TRUE,FALSE, VIS, "Minimize the number of filterslots for prescan"} |
int ks_clinicalmode = CLINICAL_MODE with {0, 1, CLINICAL_MODE, VIS, "Clinical mode: on=1 / off=0"} |
float maxB1[MAX_ENTRY_POINTS] |
float maxB1Seq |
short debugstate |
short viewtable[513] |
PSD_EXIT_ARG psdexitarg |
int rspent |
int rspdda |
int rspbas |
int rspvus |
int rspgy1 |
int rspasl |
int rspesl |
int rspchp |
int rspnex |
int rspslq |
int rspsct |
int rsprep |
short chopamp |
int seqCount |
int view |
int excitation |
int debug |
const CHAR* entry_name_list[ENTRY_POINT_MAX] |