-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathasl_models.h
453 lines (409 loc) · 14.9 KB
/
asl_models.h
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
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/* asl_model.h Kinetic curve models for ASL
Michael Chappell - IBME & FMRIB Image Analysis Group
Copyright (C) 2010-2011 University of Oxford */
/* CCOPYRIGHT */
#if !defined(asl_models_h)
#define asl_models_h
#include "fabber_core/fwdmodel.h"
#include "armawrap/newmat.h"
#include "miscmaths/miscmaths.h"
#include "miscmaths/miscprob.h"
using namespace std;
using namespace MISCMATHS;
using NEWMAT::ColumnVector;
#ifdef _WIN32
#ifdef fabber_asl_EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif
#define CALL __stdcall
#else
#define DLLAPI
#define CALL
#endif
extern "C" {
DLLAPI int CALL get_num_models();
DLLAPI const char *CALL get_model_name(int index);
DLLAPI NewInstanceFptr CALL get_new_instance_func(const char *name);
}
namespace OXASL
{
// generic AIF model class
class AIFModel
{
public:
// evaluate the model
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const = 0;
// report the number of dispersion parameters
virtual int NumDisp() const = 0;
// return default priors for the parameters
virtual ColumnVector Priors() const { return priors; }
virtual string Name() const = 0;
virtual void SetPriorMean(int paramn, double value) { priors(paramn) = value; }
protected:
ColumnVector priors; // list of prior means and precisions - all means first
// then precisions
};
// Specific AIF models
class AIFModel_nodisp : public AIFModel
{
public:
AIFModel_nodisp(double leadscale=0.01)
: m_leadscale(leadscale)
{
}
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const;
virtual int NumDisp() const { return 0; }
virtual string Name() const { return "None"; }
private:
double m_leadscale;
};
class AIFModel_gammadisp : public AIFModel
{
public:
AIFModel_gammadisp()
{
priors.ReSize(4);
priors << 2 << -0.3 << 1 << 1;
} // old prec.s were 10 and 10
// corresponds to mean s~0.7 and p~0.1
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const;
virtual int NumDisp() const { return 2; }
virtual string Name() const { return "Gamma dispersion kernel"; }
};
class AIFModel_gvf : public AIFModel
{
public:
AIFModel_gvf()
{
priors.ReSize(4);
priors << 2 << 1.6 << 1 << 1;
}
// corresponds to mean s~0.7 and p~0.7
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const;
virtual int NumDisp() const { return 2; }
virtual string Name() const { return "GVF"; }
};
class AIFModel_gaussdisp : public AIFModel
{
public:
AIFModel_gaussdisp()
{
priors.ReSize(2);
priors << -1.6 << 1;
}
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const;
virtual int NumDisp() const { return 1; }
virtual string Name() const { return "Gauss dispersion kernel"; }
};
class AIFModel_spatialgaussdisp : public AIFModel
{
public:
AIFModel_spatialgaussdisp()
{
priors.ReSize(2);
priors << -1.4 << 1;
}
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const;
virtual int NumDisp() const { return 1; }
virtual string Name() const { return "Spatial gauss dispersion kernel"; }
};
class AIFModel_spatialgaussdisp_alternate : public AIFModel
{
public:
AIFModel_spatialgaussdisp_alternate()
{
priors.ReSize(2);
priors << -1.4 << 1;
}
virtual double kcblood(const double ti, const double deltblood, const double taub,
const double T_1b, bool casl, const ColumnVector dispparam) const;
virtual int NumDisp() const { return 1; }
virtual string Name() const { return "Spatial gauss dispersion kernel (alternate)"; }
private:
double integral(double t, double k, double A, double B, double C) const;
};
// double kcblood_gallichan(const double ti, const double deltblood, const
// double taub, const double T_1b, const double xdivVm, bool casl);
// -------------
// generic residue function model class
class ResidModel
{
public:
virtual double resid(const double ti, const double fcalib, const double T_1, const double T_1b,
const double lambda, const ColumnVector residparam) const = 0;
// report the number of residue function parameters
virtual int NumResid() const = 0;
// return the default priors for the parameters
virtual ColumnVector Priors() const { return residpriors; }
virtual string Name() const = 0;
virtual void SetPriorMean(int paramn, double value) { residpriors(paramn) = value; }
protected:
ColumnVector residpriors;
};
// specific residue function models
class ResidModel_wellmix : public ResidModel
{
public:
virtual double resid(const double ti, const double fcalib, const double T_1, const double T_1b,
const double lambda, const ColumnVector residparam) const;
virtual int NumResid() const { return 0; }
virtual string Name() const { return "Well mixed"; }
};
class ResidModel_simple : public ResidModel
{
public:
virtual double resid(const double ti, const double fcalib, const double T_1, const double T_1b,
const double lambda, const ColumnVector residparam) const;
virtual int NumResid() const { return 0; }
virtual string Name() const { return "Simple"; }
};
class ResidModel_imperm : public ResidModel
{
public:
ResidModel_imperm()
{
residpriors.ReSize(2);
residpriors << 0.5 << 10;
}
virtual double resid(const double ti, const double fcalib, const double T_1, const double T_1b,
const double lambda, const ColumnVector residparam) const;
virtual int NumResid() const { return 1; }
virtual string Name() const { return "Impermeable"; }
};
class ResidModel_twocpt : public ResidModel
{
public:
ResidModel_twocpt()
{
residpriors.ReSize(2);
residpriors << 0.8 << 10;
}
virtual double resid(const double ti, const double fcalib, const double T_1, const double T_1b,
const double lambda, const ColumnVector residparam) const;
virtual int NumResid() const { return 1; }
virtual string Name() const { return "Two comparment (no backflow, no venous output)"; }
};
class ResidModel_spa : public ResidModel
{
public:
ResidModel_spa()
{
residpriors.ReSize(6);
residpriors << 0.02 << 0.03 << 2 << 1e-3 << 1e12 << 10;
}
virtual double resid(const double ti, const double fcalib, const double T_1, const double T_1b,
const double lambda, const ColumnVector residparam) const;
virtual int NumResid() const { return 3; }
virtual string Name() const { return "Single Pass Approximation (2 compartment, no backflow)"; }
};
// ------------
// generic tissue model class
class TissueModel
{
public:
// evalute the model
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, const bool casl,
const ColumnVector dispparam, const ColumnVector residparam)
= 0;
// report the number of dipersion parameters
virtual int NumDisp() const = 0;
// report the number of residue function parameters (beyond the normal ones)
virtual int NumResid() const = 0;
// return default priors for the parameters
virtual ColumnVector DispPriors() const { return disppriors; }
virtual ColumnVector ResidPriors() const { return residpriors; }
virtual string Name() const = 0;
virtual void SetDispPriorMean(int paramn, double value) { disppriors(paramn) = value; }
virtual void SetResidPriorMean(int paramn, double value) { residpriors(paramn) = value; }
protected:
ColumnVector disppriors; // list of prior means and precisions - all means
// first then precisions
ColumnVector residpriors;
};
// specific tissue models
class TissueModel_nodisp_simple : public TissueModel
{
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, const bool casl,
const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return 0; }
virtual int NumResid() const { return 0; }
virtual string Name() const { return "No dispersion | Simple"; }
};
class TissueModel_nodisp_wellmix : public TissueModel
{
public:
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, const bool casl,
const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return 0; }
virtual int NumResid() const { return 0; }
virtual string Name() const { return "No dispersion | Well mixed"; }
};
class TissueModel_nodisp_imperm : public TissueModel
{
public:
TissueModel_nodisp_imperm()
{
residpriors.ReSize(2);
residpriors << 0.5 << 10;
}
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, bool casl,
const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return 0; }
virtual int NumResid() const { return 1; }
virtual string Name() const { return "No dispersion | Impermeable"; }
};
class TissueModel_nodisp_2cpt : public TissueModel
{
public:
enum Solution
{
FAST,
SLOW,
DIST
};
TissueModel_nodisp_2cpt(std::string &solution, double mtt_prior)
: m_mtt_prior(mtt_prior)
{
if (solution == "fast")
{
m_solution = FAST;
}
else if (solution == "slow")
{
m_solution = SLOW;
}
else if (solution == "dist")
{
m_solution = DIST;
}
else
{
throw InvalidOptionValue(
"solution", solution, "2 compartment solution type must be fast, slow or dist");
}
if (m_solution == SLOW)
{
residpriors.ReSize(2);
residpriors << 0.8 << 10;
}
else
{
residpriors.ReSize(4);
residpriors << 0.8 << mtt_prior << 10 << 10;
}
}
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, const bool casl,
const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return 0; }
virtual int NumResid() const { return (m_solution == SLOW) ? 1 : 2; }
virtual string Name() const
{
switch (m_solution)
{
case FAST:
return "Fast solution (MTT=" + stringify(m_mtt_prior)
+ " << measurement time) | Two compartment(no backflow)";
case SLOW:
return "Slow solution (MTT >> measurement time) | Two compartment(no backflow)";
case DIST:
default:
return "Distributed solution (MTT=" + stringify(m_mtt_prior)
+ ") | Two compartment(no backflow)";
}
}
private:
Solution m_solution;
double m_mtt_prior;
};
class TissueModel_nodisp_spa : public TissueModel
{
public:
TissueModel_nodisp_spa()
{
residpriors.ReSize(6);
residpriors << 0.02 << 0.03 << 2 << 1e-3 << 1e12 << 10;
}
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, const bool casl,
const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return 0; }
virtual int NumResid() const { return 3; }
virtual string Name() const
{
return "No dispersion | Single Pass Approximation (2 compartment no "
"backflow)";
}
private:
double Q(const double t1, const double t2, const double t3, const double PS, const double vb,
const double tauc, const double fcalib, const double T_1, const double T_1b) const;
double R(const double t1, const double t2, const double t3, const double PS, const double vb,
const double tauc, const double fcalib, const double T_1, const double T_1b) const;
};
class TissueModel_gammadisp_wellmix : public TissueModel
{
public:
TissueModel_gammadisp_wellmix()
{
disppriors.ReSize(4);
disppriors << 2 << -0.3 << 10 << 10;
}
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1, const double lambda, const bool casl,
const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return 2; }
virtual int NumResid() const { return 0; }
virtual string Name() const { return "Gamma kernel dispersion | Well mixed"; }
};
// double kctissue_gvf(const double ti, const double delttiss,const double tau,
// const double T_1b, const double T_1app, const double s, const double p);
// double kctissue_gaussdisp(const double ti, const double delttiss, const
// double tau, const double T_1b, const double T_1app, const double sig1, const
// double sig2);
// a general tissue model that does numerical convolution
class TissueModel_aif_residue : public TissueModel
{
public:
TissueModel_aif_residue(AIFModel *paifmodel, ResidModel *presidmodel, double delta = 0.1)
: aifmodel(paifmodel)
, residmodel(presidmodel)
, m_delta(delta)
{
disppriors << aifmodel->Priors();
residpriors << residmodel->Priors();
}
virtual double kctissue(const double ti, const double fcalib, const double delttiss,
const double tau, const double T_1b, const double T_1app, const double lambda,
const bool casl, const ColumnVector dispparam, const ColumnVector residparam);
virtual int NumDisp() const { return aifmodel->NumDisp(); }
virtual int NumResid() const { return residmodel->NumResid(); }
virtual string Name() const
{
string name;
name = "NUMERICAL CONVOLUTION - " + aifmodel->Name() + residmodel->Name();
return name;
}
protected:
AIFModel *aifmodel;
ResidModel *residmodel;
double m_delta;
};
// useful functions
double icgf(const double a, const double x);
double gvf(const double t, const double s, const double p);
double numerical_integration(
ColumnVector integrand, double del, double finalval, double finaldel, string method);
}
#endif