KSFoundation  [October2024]
A platform for structured EPIC programming on GE MR systems
ksinversion.cc File Reference
#include "ksdesign.h"
#include "ksinversion.h"

Functions

void ksinv_init_design (KSINV_DESIGN *design, const char *desc)
 
void ksinv_init_sequence (KSINV_MODULE *seq)
 
STATUS ksinv_validate_loopcontroldesign (const KSINV_LOOP_CONTROL_DESIGN *design)
 
STATUS ksinv_eval_setupobjects (KSINV_MODULE *seq, const KSINV_DESIGN *design)
 
float ksinv_eval_gscale (float slice_thickness, float slice_spacing, int numacqs, KSINV_GSCALE_POLICY gscale_policy)
 
STATUS ksinv_eval_design (KSINV_MODULE *invseq, KSINV_DESIGN *invseq_design, int npasses, KS_SEQ_COLLECTION *seqcollection)
 
void ksinv_init_loopcontrol (KSINV_LOOP_CONTROL *loop_control)
 
STATUS ksinv_loop_control_eval_design (KSINV_LOOP_CONTROL *inv_loopctrl, KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_SEQ_CONTROL *invseq_seqctrl_ptr, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_SEQ_CONTROL *mainseq_seqctrl_ptr, const KSINV_LOOP_CONTROL_DESIGN *design, KS_SEQ_COLLECTION *seqcollection)
 
STATUS ksinv_eval_duration_simple (KSINV_LOOP_CONTROL *inv_loopctrl, KS_CORESLICETIME irslicetime, KS_CORESLICETIME coreslicetime, KS_SEQ_CONTROL *invseq_seqctrl_ptr, const KSINV_LOOP_CONTROL_DESIGN *design)
 
int ksinv_eval_nullti (int TR, int T1value, int seqdur)
 
int ksinv_eval_nulltr (int TI, int T1value, int seqdur)
 
STATUS ksinv_eval_duration_interleaved (KSINV_LOOP_CONTROL *inv_loopctrl, KS_CORESLICETIME irslicetime, KS_CORESLICETIME coreslicetime, KS_SEQ_CONTROL *invseq_seqctrl_ptr, KS_SEQ_CONTROL *mainseq_seqctrl_ptr, const KSINV_LOOP_CONTROL_DESIGN *design)
 
STATUS ksinv_eval_duration_flairblock (KSINV_LOOP_CONTROL *inv_loopctrl, KS_CORESLICETIME irslicetime, KS_CORESLICETIME coreslicetime, KS_SEQ_CONTROL *invseq_seqctrl_ptr, KS_SEQ_CONTROL *mainseq_seqctrl_ptr, const KSINV_LOOP_CONTROL_DESIGN *design)
 
STATUS ksinv_eval_duration_setfilltr (KS_SEQ_CONTROL *filltr, int duration)
 
STATUS ksinv_check ()
 
STATUS ksinv_predownload_setrecon ()
 
STATUS ksinv_eval_chain_design (KSINV_CHAIN *inv_chain, KSINV_CHAIN_DESIGN *inv_chain_design, const KSINV_LOOP_CONTROL *inv_loopctrl)
 
STATUS ksinv_pg (KSINV_MODULE *seq)
 
STATUS ksinv_scan_seqstate (KSINV_MODULE *seq, const SCAN_INFO *slice_info)
 
KS_CORESLICETIME ksinv_scan_irslice (KSINV_MODULE *seq, const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic)
 
s64 ksinv_scan_sliceloop (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KSINV_LOOP_MODE ksinv_loop_mode, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
 
s64 ksinv_scan_sliceloop_sliceahead (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), const int nslicesahead_current, const int nslicesahead_next, const int play_core)
 
s64 ksinv_scan_acqloop_sliceahead (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), const int nslicesahead_current, const int nslicesahead_next, const int inv_rampup)
 
s64 ksinv_scan_sliceloop_flairblock (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
 
s64 ksinv_scan_acqloop_flairblock (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
 
s64 ksinv_scan_acqloop (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), const int inv_rampup, const int inv_rampdown)
 
s64 ksinv_scan_scanloop (KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
 
void ksinv_prescanloop (KSINV_LOOP_CONTROL *inv_loopctrl, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), int nloops, int dda)
 
s64 ksinv_scan_acqloop_chain (const KSINV_CHAIN *inv_chain, KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
 
s64 ksinv_scan_scanloop_chain (const KSINV_CHAIN *inv_chain, KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
 

Function Documentation

◆ ksinv_validate_loopcontroldesign()

STATUS ksinv_validate_loopcontroldesign ( const KSINV_LOOP_CONTROL_DESIGN design)
60  {
61 
62  if (design->irmode == KSINV_OFF) {
63  return SUCCESS;
64  }
65 
66  if ((design->T1value == KS_NOTSET && design->TI == KS_NOTSET) || (design->T1value != KS_NOTSET && design->TI != KS_NOTSET)) {
67  return KS_THROW("TI xor T1value must be != KS_NOTSET");
68  }
69  if (design->TI != KS_NOTSET && design->TI < 5000) {
70  /* prevents accidental input in ms instead of us */
71  return KS_THROW("TI must be >= 5 ms");
72  }
73  if (design->T1value != KS_NOTSET && design->T1value < 5000) {
74  /* prevents accidental input in ms instead of us */
75  return KS_THROW("T1value must be >= 5 ms");
76  }
77  if (design->dosliceahead != FALSE && design->dosliceahead != TRUE) {
78  return KS_THROW("dosliceahead must be TRUE or FALSE");
79  }
80  if (design->irmode == KSINV_ON_FLAIR_BLOCK && design->dosliceahead == TRUE) {
81  return KS_THROW("dosliceahead must be FALSE for KSINV_ON_FLAIR_BLOCK");
82  }
83  if (design->irmode == KSINV_ON_FLAIR_BLOCK) {
84  if (design->loopctrl_design.slicetiming_design.minTR <= 0) {
85  return KS_THROW("FLAIR BLOCK - .minTR (%d) must be > 0", design->loopctrl_design.slicetiming_design.minTR/1000);
86  }
87  if (design->loopctrl_design.slicetiming_design.maxTR > 0) {
88  return KS_THROW("FLAIR BLOCK .maxTR must be 0");
89  }
90  } /* FLAIR BLOCK */
91 
93  return KS_THROW("Interleaved snapshot is not compatible with inversion");
94  }
95 
96  return SUCCESS;
97 
98 } /* ksinv_validate_loopcontroldesign() */
#define KS_NOTSET
Definition: KSFoundation.h:115
int T1value
Definition: ksinversion.h:91
Definition: ksinversion.h:27
KS_SLICETIMING_DESIGN slicetiming_design
Definition: ksscan.h:209
int irmode
Definition: ksinversion.h:89
Definition: ksinversion.h:27
int TI
Definition: ksinversion.h:90
int maxTR
Definition: ksscan.h:29
int interleaved_snapshot
Definition: ksscan.h:206
#define KS_THROW(format,...)
Definition: KSFoundation.h:181
int minTR
Definition: ksscan.h:28
KSSCAN_LOOP_CONTROL_DESIGN loopctrl_design
Definition: ksinversion.h:94
int dosliceahead
Definition: ksinversion.h:92

◆ ksinv_scan_acqloop_sliceahead()

s64 ksinv_scan_acqloop_sliceahead ( KSINV_LOOP_CONTROL inv_loopctrl,
KS_DYNAMIC_STATE *  dynamic,
KS_CORESLICETIME   coresliceconst SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic,
KS_CORESLICETIME   irsliceconst SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic,
const int  nslicesahead_current,
const int  nslicesahead_next,
const int  inv_rampup 
)
1050  {
1051  s64 time = 0;
1052  char slicegroup_desc[256];
1053 
1054  if (inv_rampup) {
1055  /* sliceahead inversion prologue (KSINV_LOOP_SLICEAHEAD_FIRST) */
1056 
1057  KS_DYNAMIC_STATE dynamic_sliceahead = KS_INIT_DYNAMIC_STATE; /* Everything is KS_NOTSET */
1058  dynamic_sliceahead.pass = dynamic->pass;
1059 
1060  time += (s64) ksinv_scan_sliceloop_sliceahead(inv_loopctrl, &dynamic_sliceahead, coreslice, irslice,
1061  KS_NOTSET, nslicesahead_current, 0);
1062  }
1063 
1064  /* shot < 0 means dummy scans */
1065  for (dynamic->shot = -inv_loopctrl->loopctrl.dda; dynamic->shot < inv_loopctrl->loopctrl.phaseenc_plan.num_shots; dynamic->shot++) {
1066 
1067  const int naverages = dynamic->shot < 0 ? 1 : inv_loopctrl->loopctrl.naverages;
1068  dynamic->shot_coords = dynamic->shot >= 0 ? ks_phaseencoding_get_shot(&inv_loopctrl->loopctrl.phaseenc_plan, dynamic->shot)
1069  : ks_phaseencoding_get_shot(&inv_loopctrl->loopctrl.phaseenc_plan_dummies, -dynamic->shot - 1);
1070 
1071  for (dynamic->average = 0; dynamic->average < naverages; dynamic->average++) {
1072 
1073  const int last = dynamic->shot == (inv_loopctrl->loopctrl.phaseenc_plan.num_shots- 1) &&
1074  dynamic->average == (inv_loopctrl->loopctrl.naverages - 1);
1075 
1076  time += (s64) ksinv_scan_sliceloop_sliceahead(inv_loopctrl, dynamic, coreslice, irslice,
1077  nslicesahead_current,
1078  last ? nslicesahead_next : nslicesahead_current,
1079  1);
1080 
1081  sprintf(slicegroup_desc, "Sliceahead inversion loop - vol %d, pass %d, shot %d, average %d",
1082  dynamic->vol, dynamic->pass, dynamic->shot, dynamic->average);
1083  ks_plot_slicetime_endofslicegroup_tagged(slicegroup_desc, (dynamic->average < 0) ? KS_PLOT_SG_DUMMY : KS_PLOT_SG_ACQUISITION);
1084  } /* for average */
1085 
1086  } /* for shot */
1087 
1088  return time;
1089 
1090 } /* ksinv_scan_acqloop_sliceahead() */
int num_shots
Definition: KSFoundation.h:1789
#define KS_NOTSET
Definition: KSFoundation.h:115
int dda
Definition: ksscan.h:185
int naverages
Definition: ksscan.h:187
#define KS_INIT_DYNAMIC_STATE
Definition: KSFoundation.h:1829
void ks_plot_slicetime_endofslicegroup_tagged(const char *desc, const KS_PLOT_SLICEGROUP_MODE tag)
ADDTITLEHERE
Definition: KSFoundation_common.c:4296
KS_PHASEENCODING_PLAN phaseenc_plan
Definition: ksscan.h:190
Definition: KSFoundation.h:412
Definition: KSFoundation.h:414
KS_PHASEENCODING_SHOTCOORDS ks_phaseencoding_get_shot(const KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, int shot)
ADDTITLEHERE
Definition: KSFoundation_common.c:623
KSSCAN_LOOP_CONTROL loopctrl
Definition: ksinversion.h:110
s64 ksinv_scan_sliceloop_sliceahead(KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), const int nslicesahead_current, const int nslicesahead_next, const int play_core)
[Internal ksinversion.cc] Plays a single repetition of an interleaved inversion sequence
Definition: ksinversion.cc:975

◆ ksinv_scan_acqloop_flairblock()

s64 ksinv_scan_acqloop_flairblock ( KSINV_LOOP_CONTROL inv_loopctrl,
KS_DYNAMIC_STATE *  dynamic,
KS_CORESLICETIME   coresliceconst SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic,
KS_CORESLICETIME   irsliceconst SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic 
)
1168  {
1169  s64 time = 0;
1170  char slicegroup_desc[256];
1171 
1172  /* shot < 0 means dummy scans */
1173  for (dynamic->shot = -inv_loopctrl->loopctrl.dda; dynamic->shot < inv_loopctrl->loopctrl.phaseenc_plan.num_shots; dynamic->shot++) {
1174 
1175  const int naverages = dynamic->shot < 0 ? 1 : inv_loopctrl->loopctrl.naverages;
1176  dynamic->shot_coords = dynamic->shot >= 0 ? ks_phaseencoding_get_shot(&inv_loopctrl->loopctrl.phaseenc_plan, dynamic->shot)
1177  : ks_phaseencoding_get_shot(&inv_loopctrl->loopctrl.phaseenc_plan_dummies, -dynamic->shot - 1);
1178 
1179  for (dynamic->average = 0; dynamic->average < naverages; dynamic->average++) {
1180 
1181  time += (s64) ksinv_scan_sliceloop_flairblock(inv_loopctrl, dynamic, coreslice, irslice);
1182 
1183  sprintf(slicegroup_desc, "Flairblock inversion loop - vol %d, pass %d, shot %d, average %d",
1184  dynamic->vol, dynamic->pass, dynamic->shot, dynamic->average);
1185  ks_plot_slicetime_endofslicegroup_tagged(slicegroup_desc, (dynamic->average < 0) ? KS_PLOT_SG_DUMMY : KS_PLOT_SG_ACQUISITION);
1186  } /* for average */
1187 
1188  } /* for shot */
1189 
1190  return time;
1191 
1192 } /* ksinv_scan_acqloop_flairblock() */
int num_shots
Definition: KSFoundation.h:1789
s64 ksinv_scan_sliceloop_flairblock(KSINV_LOOP_CONTROL *inv_loopctrl, KS_DYNAMIC_STATE *dynamic, KS_CORESLICETIME coreslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic), KS_CORESLICETIME irslice(const SCAN_INFO *slice_pos, KS_DYNAMIC_STATE *dynamic))
[Internal ksinversion.cc] Plays out one repetition for an inversion scan
Definition: ksinversion.cc:1095
int dda
Definition: ksscan.h:185
int naverages
Definition: ksscan.h:187
void ks_plot_slicetime_endofslicegroup_tagged(const char *desc, const KS_PLOT_SLICEGROUP_MODE tag)
ADDTITLEHERE
Definition: KSFoundation_common.c:4296
KS_PHASEENCODING_PLAN phaseenc_plan
Definition: ksscan.h:190
Definition: KSFoundation.h:412
Definition: KSFoundation.h:414
KS_PHASEENCODING_SHOTCOORDS ks_phaseencoding_get_shot(const KS_PHASEENCODING_PLAN *phaseenc_plan_ptr, int shot)
ADDTITLEHERE
Definition: KSFoundation_common.c:623
KSSCAN_LOOP_CONTROL loopctrl
Definition: ksinversion.h:110