00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef SEQSIM_H
00019 #define SEQSIM_H
00020
00021 #include <tjutils/tjthread.h>
00022 #include <tjutils/tjnumeric.h>
00023
00024 #include <odinpara/sample.h>
00025 #include <odinseq/seqclass.h>
00026
00027
00042 struct SeqSimInterval {
00043 SeqSimInterval() : dt(0.0), B1(0.0), freq(0.0), phase(0.0), rec(0.0), Gx(0.0), Gy(0.0), Gz(0.0) {}
00044 float dt;
00045 STD_complex B1;
00046 float freq;
00047 float phase;
00048 float rec;
00049 float Gx;
00050 float Gy;
00051 float Gz;
00052 };
00053
00055
00056 class ProgressMeter;
00057
00058
00063 class SeqSimAbstract : public virtual SeqClass {
00064
00065 public:
00066
00067 virtual ~SeqSimAbstract() {}
00068
00076 virtual void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0) = 0;
00077
00084 virtual cvector simulate(const SeqSimInterval& simvals, double gamma) = 0;
00085
00089 virtual void finalize_simulation() = 0;
00090
00091 };
00092
00093
00095
00113 class SeqSimMagsi : public JcampDxBlock, public ThreadedLoop<SeqSimInterval,cvector>, public virtual SeqSimAbstract {
00114
00115
00116 public:
00120 SeqSimMagsi(const STD_string& label="unnamedSeqSimMagsi");
00121
00125 SeqSimMagsi(const SeqSimMagsi& ssm);
00126
00130 ~SeqSimMagsi();
00131
00135 SeqSimMagsi& operator = (const SeqSimMagsi& ssm);
00136
00140 unsigned int get_total_size() const {return Mx.total();}
00141
00145 SeqSimMagsi& reset_magnetization();
00146
00150 SeqSimMagsi& set_initial_vector(float Mx, float My, float Mz);
00151
00155 const farray& get_Mx() const {return Mx;}
00156
00160 const farray& get_My() const {return My;}
00161
00165 const farray& get_Mz() const {return Mz;}
00166
00170 const farray& get_Mamp() const {return Mamp;}
00171
00175 const farray& get_Mpha() const {return Mpha;}
00176
00180 SeqSimMagsi& update();
00181
00182
00186 SeqSimMagsi& set_online_simulation(bool onlineflag) { online=onlineflag; return *this;}
00187
00188
00192 SeqSimMagsi& set_intravoxel_simulation(bool ivflag) { magsi=ivflag; return *this;}
00193
00197 SeqSimMagsi& set_numof_threads(unsigned int n) { nthreads=n; return *this;}
00198
00203 SeqSimMagsi& set_spat_rotmatrix(const RotMatrix& rotmatrix);
00204
00205
00210 bool do_simulation();
00211
00212
00213
00214 void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0);
00215 cvector simulate(const SeqSimInterval& simvals, double gamma);
00216 void finalize_simulation();
00217
00218
00219 bool kernel(const SeqSimInterval& simvals, cvector& signal, unsigned int begin, unsigned int end);
00220
00221 private:
00222 friend class SeqTimecourse;
00223
00224
00225
00229 SeqSimMagsi& resize(unsigned int xsize, unsigned int ysize, unsigned int zsize, unsigned int freqsize=1);
00230
00231
00232
00233 void common_init();
00234
00235 int append_all_members();
00236
00237 SeqSimMagsi& MampMpha2MxMy();
00238 SeqSimMagsi& MxMy2MampMpha();
00239
00240 void update_axes();
00241
00242 void set_axes_cache(const Sample& sample);
00243
00244 JDXfloatArr Mx;
00245 JDXfloatArr My;
00246 JDXfloatArr Mz;
00247 JDXfloatArr Mamp;
00248 JDXfloatArr Mpha;
00249
00250 JDXbool online;
00251 JDXaction update_now;
00252 JDXtriple initial_vector;
00253
00254
00255 bool iactive;
00256 bool magsi;
00257 unsigned int nthreads;
00258 RotMatrix* spat_rotmatrix;
00259
00260
00261 double gamma_cache;
00262
00263 double elapsed_time;
00264 unsigned int time_index_cache;
00265 unsigned int numof_time_intervals_cache;
00266 double* time_intervals_cache;
00267
00268
00269
00270 float x_low;
00271 float x_upp;
00272 float y_low;
00273 float y_upp;
00274 float z_low;
00275 float z_upp;
00276 float freq_low;
00277 float freq_upp;
00278
00279
00280
00281 float *dMx[4];
00282 float *dMy[4];
00283 float *dMz[4];
00284 float *dppm[3];
00285
00286
00287
00288
00289 unsigned int oneframe_size_cache;
00290 float* xpos_cache;
00291 float* ypos_cache;
00292 float* zpos_cache;
00293 float* freqoffset_cache;
00294 unsigned int nframes_ppm_cache;
00295 float* ppm_cache;
00296 unsigned int nframes_spin_density_cache;
00297 float* spin_density_cache;
00298 STD_complex* B1map_transm_cache;
00299 unsigned int num_rec_channel_cache;
00300 STD_complex** B1map_receiv_cache;
00301 unsigned int nframes_Dcoeff_cache;
00302 float* Dcoeff_cache;
00303 bool sim_diffusion;
00304 unsigned int nframes_r1_cache;
00305 float* r1_cache;
00306 unsigned int nframes_r2_cache;
00307 float* r2_cache;
00308 bool* has_relax_cache;
00309 float L[4];
00310 float B0_ppm;
00311 bool simcache_up2date;
00312 void outdate_simcache();
00313 };
00314
00315
00316
00318
00319
00320 #ifdef STANDALONE_PLUGIN // exclude from Siemens DLLs
00321
00327 class SeqSimMonteCarlo : public virtual SeqSimAbstract {
00328
00329 public:
00330
00334 SeqSimMonteCarlo(const STD_string& label="unnamedSeqSimMonteCarlo", unsigned int nparticles=10000);
00335
00339 SeqSimMonteCarlo(const SeqSimMonteCarlo& ssmc) {common_init(); SeqSimMonteCarlo::operator = (ssmc);}
00340
00344 SeqSimMonteCarlo& operator = (const SeqSimMonteCarlo& ssmc);
00345
00346
00347
00348 void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0);
00349 cvector simulate(const SeqSimInterval& simvals, double gamma);
00350 void finalize_simulation();
00351
00352
00353 private:
00354 struct Particle {
00355 float xpos, ypos, zpos;
00356 float Mx, My, Mz;
00357 };
00358
00359 void common_init();
00360 void clear_cache();
00361
00362 unsigned int linear_index(float xpos, float ypos, float zpos) const;
00363
00364 STD_vector<Particle> particle;
00365
00366 RandomDist rng;
00367
00368 unsigned int xsize;
00369 unsigned int ysize;
00370 unsigned int zsize;
00371
00372
00373 float* Dcoeff_cache;
00374 float* ppmMap_cache;
00375 float* R1map_cache;
00376 float* R2map_cache;
00377 float* spinDensity_cache;
00378
00379 float xpixelspacing_cache;
00380 float ypixelspacing_cache;
00381 float zpixelspacing_cache;
00382 float B0_ppm_cache;
00383
00384
00385 };
00386
00387 #endif
00388
00389
00390
00391
00392
00394
00395
00399 #endif