This file is indexed.

/usr/include/odinseq/seqsim.h is in libodin-dev 1.8.8-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
/***************************************************************************
                          seqsim.h  -  description
                             -------------------
    begin                : Tue Jun 11 2002
    copyright            : (C) 2000-2014 by Thies H. Jochimsen
    email                : thies@jochimsen.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef SEQSIM_H
#define SEQSIM_H

#include <tjutils/tjthread.h>
#include <tjutils/tjnumeric.h> // for RandomDist

#include <odinpara/sample.h>
#include <odinseq/seqclass.h>


/**
  * @ingroup odinseq
  * \brief Time interval for simulation
  *
  * Data structure to hold the values for a single interval with constant fields
  * - dt:    Duration of the interval
  * - B1:    Complex RF field
  * - freq:  Transmit/receive frequency
  * - phase: Transmit/receive phase in deg
  * - rec:   Receiver (>0 means on)
  * - Gx:    Gradient in read direction
  * - Gy:    Gradient in phase direction
  * - Gz:    Gradient in slice direction
  */
struct SeqSimInterval {
  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) {}
  float dt;
  STD_complex B1;
  float freq;
  float phase;
  float rec;
  float Gx;
  float Gy;
  float Gz;
};

/////////////////////////////////////////////////////////////////////

class ProgressMeter; // forward declaration


/**
  * @ingroup odinseq_internals
  * Interface for Simulators
  */
class SeqSimAbstract : public virtual SeqClass {

 public:

  virtual ~SeqSimAbstract() {}

/**
  * Prepare a simulation (i.e. before successive calls to simulate() ) with the parameters:
  * - sample:  The virtual sample
  * - transmit_coil: Transmitter coil, 0 for none
  * - receive_coil:  Receiver coil, 0 for none
  * - progmeter:     Status indicator to trace progress, 0 for none
  */
  virtual void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0) = 0;

/**
  * Simulation with
  * - simvals: The magnetic fields during a time interval
  * - gamma:   Gyromagnetic ration of the nucleus observed
  * Return value: Signal in each receiver channel
  */
  virtual cvector simulate(const SeqSimInterval& simvals, double gamma) = 0;

/**
  * Call this function after a simulation (i.e. after successive calls to simulate() )
  */
  virtual void finalize_simulation() = 0;

};


/////////////////////////////////////////////////////////////////////

/**
  * @addtogroup odinseq
  * @{
  */

/**
  * \brief MAGSI-based Magnetization Simulator
  *
  * This is a simulator to calculate the time evolution of a magnetization grid
  * in 4 dimension (frequency and three spatial dimensions). This simulation of the
  * Bloch-Torrey equations is performed by means of the MAGSI algorith
  * (c.f. Journal of Magnetic Resonance 180:29-38, 2006).
  * Simulation usually involves the following steps:
  * - Initialize the simulator by prepare_simulation() using a virtual sample.
  * - Iterative simulation by simulate() using a structure with piece-wise constant fields.
  * - Finish simulation by calling finalize_simulation().
  */
class SeqSimMagsi : public JcampDxBlock, public ThreadedLoop<SeqSimInterval,cvector,int>, public virtual SeqSimAbstract {


 public:
/**
  * Constructs a simulator labeled 'object_label'.
  */
  SeqSimMagsi(const STD_string& label="unnamedSeqSimMagsi");

/**
  * Copy constructor
  */
  SeqSimMagsi(const SeqSimMagsi& ssm);

/**
  * Destructor
  */
  ~SeqSimMagsi();

/**
  * Assignment operator
  */
  SeqSimMagsi& operator = (const SeqSimMagsi& ssm);

/**
  * Returns the overall size of the array
  */
  unsigned int  get_total_size() const {return Mx.total();}

/**
  * Set each magnetization to initial state 'initial_vector', which is (0,0,1) by default
  */
  SeqSimMagsi& reset_magnetization();

/**
  * Set the vector for the initial magnetization
  */
  SeqSimMagsi& set_initial_vector(float Mx, float My, float Mz);

/**
  * Returns the real part of the transverse magnetisation
  */
  const farray& get_Mx() const {return Mx;}

/**
  * Returns the imaginary part of the transverse magnetisation
  */
  const farray& get_My() const {return My;}

/**
  * Returns the longitudinal magnetisation
  */
  const farray& get_Mz() const {return Mz;}

/**
  * Returns the amplitude of the transverse magnetisation
  */
  const farray& get_Mamp() const {return Mamp;}

/**
  * Returns the phase of the transverse magnetisation
  */
  const farray& get_Mpha() const {return Mpha;}

/**
  * Updates all parameter relations
  */
  SeqSimMagsi& update();


/**
  * Specifies whether simulation should be performed everytime update() is called
  */
  SeqSimMagsi& set_online_simulation(bool onlineflag) { online=onlineflag; return *this;}


/**
  * Specifies whether intra-voxel magnetzation gradients are considered during simulation
  */
  SeqSimMagsi& set_intravoxel_simulation(bool ivflag) { magsi=ivflag; return *this;}

/**
  * Specifies the number of threads used during simulation
  */
  SeqSimMagsi& set_numof_threads(unsigned int n) { nthreads=n; return *this;}

/**
  * Specifies a rotation matrix for the spatial domain, i.e. the magnetization
  * array will be rotated in space using the specified rotation matrix.
  */
  SeqSimMagsi& set_spat_rotmatrix(const RotMatrix& rotmatrix);


/**
  * Returns whether simulation should be performed, i.e. whether the 'online' flag
  * is true or 'update' was activated.
  */
  bool do_simulation();


  // implementing virtual functions of SeqSimAbstract
  void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0);
  cvector simulate(const SeqSimInterval& simvals, double gamma);
  void finalize_simulation();

  // implementing virtual functions of ThreadedLoop
  bool kernel(const SeqSimInterval& simvals, cvector& signal, int&, unsigned int begin, unsigned int end);

 private:
  friend class SeqTimecourse;



/**
  * Resize the array in the four dimensions according to the given sizes
  */
  SeqSimMagsi& resize(unsigned int xsize, unsigned int ysize, unsigned int zsize, unsigned int freqsize=1);



  void common_init();

  int append_all_members();

  SeqSimMagsi& MampMpha2MxMy();
  SeqSimMagsi& MxMy2MampMpha();

  void update_axes();

  void set_axes_cache(const Sample& sample);

  JDXfloatArr Mx;
  JDXfloatArr My;
  JDXfloatArr Mz;
  JDXfloatArr Mamp;
  JDXfloatArr Mpha;

  JDXbool   online;
  JDXaction update_now;
  JDXtriple initial_vector;


  bool iactive;
  bool magsi;
  unsigned int nthreads;
  RotMatrix* spat_rotmatrix;


  double gamma_cache;

  double elapsed_time; // within current time frame
  unsigned int time_index_cache;
  unsigned int numof_time_intervals_cache;
  double* time_intervals_cache;


  // cache for update_axes()
  float x_low;
  float x_upp;
  float y_low;
  float y_upp;
  float z_low;
  float z_upp;
  float freq_low; // in rad/s
  float freq_upp; // in rad/s


  // intra-voxel magn gradients
  float *dMx[4];
  float *dMy[4];
  float *dMz[4];
  float *dppm[3];  // readonly



  // use raw pointers to avoid slower []-operator of STD_vector
  unsigned int oneframe_size_cache; // size of one frame
  float* xpos_cache;
  float* ypos_cache;
  float* zpos_cache;
  float* freqoffset_cache; // in rad*kHz
  unsigned int nframes_ppm_cache;
  float* ppm_cache;
  unsigned int nframes_spin_density_cache;
  float* spin_density_cache;
  STD_complex* B1map_transm_cache;
  unsigned int num_rec_channel_cache;
  STD_complex** B1map_receiv_cache;
  unsigned int nframes_Dcoeff_cache;
  float* Dcoeff_cache;
  bool sim_diffusion;
  unsigned int nframes_r1_cache;
  float* r1_cache;
  unsigned int nframes_r2_cache;
  float* r2_cache;
  bool* has_relax_cache;
  float L[4];
  float B0_ppm;
  bool simcache_up2date;
  void outdate_simcache();
};



/////////////////////////////////////////////////////////////////////


#ifdef STANDALONE_PLUGIN // exclude from Siemens DLLs

/**
  * \brief Monte-Carlo-based Magnetization Simulator
  *
  * Monte-Carlo Simulator for diffusional averaging
  */
class SeqSimMonteCarlo : public ThreadedLoop<SeqSimInterval,cvector,RandomDist>, public virtual SeqSimAbstract {

 public:

  /**
  * Constructs a simulator labeled 'object_label' to simulate 'nparticles' diffusion trajectories using 'nthreads' threads.
  */
  SeqSimMonteCarlo(const STD_string& label="unnamedSeqSimMonteCarlo", unsigned int nparticles=10000, unsigned int nthreads=1);

/**
  * Copy constructor
  */
  SeqSimMonteCarlo(const SeqSimMonteCarlo& ssmc) {common_init(); SeqSimMonteCarlo::operator = (ssmc);}

/**
  * Assignment operator
  */
  SeqSimMonteCarlo& operator = (const SeqSimMonteCarlo& ssmc);

  
/**
  * Get spatial distribution of particles after simulation
  */
  farray get_spatial_dist() const;


  // implementing virtual functions of SeqSimAbstract
  void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0);
  cvector simulate(const SeqSimInterval& simvals, double gamma);
  void finalize_simulation();

  // implementing virtual functions of ThreadedLoop
  bool kernel(const SeqSimInterval& simvals, cvector& signal, RandomDist& local_rng, unsigned int begin, unsigned int end);

 private:
  struct Particle {
    float pos[3];
    float Mx, My, Mz;
  };

  void common_init();
  void clear_cache();

  unsigned int linear_index(const float pos[3]) const;

  STD_vector<Particle> particle;
  unsigned int numof_threads;

  RandomDist rng; // seed only once per simulator

  double gamma_cache;

  unsigned int size_cache[3];

  // use raw pointers to avoid slower []-operator of STD_vector
  float* Dcoeff_cache;
  float* ppmMap_cache;
  float* R1map_cache;
  float* R2map_cache;
  float* spinDensity_cache;

  float pixelspacing_cache[3];
  float B0_ppm_cache;


};

#endif





/////////////////////////////////////////////////////////////////////


/** @}
  */

#endif