Skip to content

Commit fd59a8b

Browse files
committed
feat: added 2 parameter fitting FunctionsT1TwoParam
1 parent 1f34654 commit fd59a8b

37 files changed

+808
-147
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,14 @@ Please see [contributing.md](contributing.md) and [codeofconduct.md](codeofcondu
6060

6161
## TODO
6262

63+
* add acceptance test for 2param
64+
* maybe rename calculatormolli to calculator3param?
6365
* Deployment: exe and lib in one zip
66+
* Deployment: cmake to download ITK and lmfit
6467
* output SNR maps
6568
* make sure SNR and nAmoebaCalls is the same as in Shmolli
6669
* fix downloadITK_linux_osx
67-
* seperate projects for building tomato dependencies (done for lmfit)
70+
* separate projects for building tomato dependencies (done for lmfit)
6871
* possibly I could make all FunctionsT1 object static
6972
* write user-friendly build scripts (and use them in CI)
7073

app/OxFactoryOfFunctions.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
#include "CmakeConfigForTomato.h"
1111

12-
#include "OxFunctionsT1Basic.h"
12+
#include "OxFunctionsT1ThreeParam.h"
13+
#include "OxFunctionsT1TwoParam.h"
1314
#ifdef USE_PRIVATE_NR2
1415
#include "OxFunctionsT1Shmolli.h"
1516
#endif
@@ -21,18 +22,21 @@ namespace Ox {
2122

2223

2324
static const char *functionsTypeNames[] = {
24-
"FunctionsBasic",
25+
"FunctionsThreeParams",
26+
"FunctionsTwoParams",
2527
"FunctionsShmolli",
2628
};
2729

2830
enum functionsType_t {
29-
FunctionsBasic = 0,
30-
FunctionsShmolli = 1,
31+
FunctionsThreeParams = 0,
32+
FunctionsTwoParams = 1,
33+
FunctionsShmolli = 2,
3134
lastFunctorType = FunctionsShmolli
3235
};
3336

3437
static int functionsAvailability[] = {
35-
1, //FunctionsBasic
38+
1, //FunctionsThreeParams
39+
1, //FunctionsTwoParams
3640
#ifdef USE_PRIVATE_NR2
3741
1 // FunctionsShmolli
3842
#else
@@ -47,8 +51,11 @@ namespace Ox {
4751

4852
static FunctionsT1<TYPE>* newByFactory(TomatoOptions<TYPE> *opts){
4953
switch (opts->functions_type){
50-
case FunctionsBasic: {
51-
return new FunctionsT1Basic<TYPE>();
54+
case FunctionsThreeParams: {
55+
return new FunctionsT1ThreeParam<TYPE>();
56+
}
57+
case FunctionsTwoParams: {
58+
return new FunctionsT1TwoParam<TYPE>();
5259
}
5360
#ifdef USE_PRIVATE_NR2
5461
case FunctionsShmolli: {

app/TomatoOptions.h

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ namespace Ox {
5050

5151
// image
5252
MeasureType mean_cut_off;
53+
MeasureType map_scale_factor;
54+
bool use_colorbar;
5355
int number_of_threads;
5456

5557
// visualisation
@@ -74,7 +76,7 @@ namespace Ox {
7476

7577
parameter_to_map = T1_MOLLI;
7678
fitting_method = LevMarVnl;
77-
functions_type = FunctionsBasic;
79+
functions_type = FunctionsThreeParams;
7880
sign_calc_method = NoSign;
7981
start_point_calc_method = Default;
8082

@@ -83,7 +85,9 @@ namespace Ox {
8385
use_gradient = false;
8486

8587
// image
86-
mean_cut_off = 10;
88+
mean_cut_off = 10.0;
89+
map_scale_factor = 1.0;
90+
use_colorbar = true;
8791
number_of_threads = 0;
8892

8993
// visualisation
@@ -131,6 +135,8 @@ namespace Ox {
131135
parser._scalars["use_gradient"];
132136

133137
parser._scalars["mean_cut_off"];
138+
parser._scalars["map_scale_factor"];
139+
parser._scalars["use_colorbar"];
134140
parser._scalars["number_of_threads"];
135141
parser._scalars["visualise"];
136142

@@ -175,6 +181,10 @@ namespace Ox {
175181

176182
if (!parser._scalars["mean_cut_off"].empty())
177183
mean_cut_off = KWUtil::StringToNumber<MeasureType>(parser._scalars["mean_cut_off"]);
184+
if (!parser._scalars["map_scale_factor"].empty())
185+
map_scale_factor = KWUtil::StringToNumber<MeasureType>(parser._scalars["map_scale_factor"]);
186+
if (!parser._scalars["use_colorbar"].empty())
187+
use_colorbar = KWUtil::StringToNumber<MeasureType>(parser._scalars["use_colorbar"]);
178188
if (!parser._scalars["number_of_threads"].empty())
179189
number_of_threads = KWUtil::StringToNumber<MeasureType>(parser._scalars["number_of_threads"]);
180190

@@ -217,22 +227,19 @@ namespace Ox {
217227
Ox::FactoryOfSignCalculators<double>::disp(sign_calc_method);
218228
Ox::FactoryOfStartPointCalculators<double>::disp(start_point_calc_method);
219229

220-
221-
// printf("]\n sign_calc_method: %s [ ", signCalculatorsTypeNames[sign_calc_method]);
222-
// KWUtil::printArray(lastSignCalculatorType+1, signCalculatorsTypeNames);
223-
// printf("]\n start_point_calc_method: %s [ ", startPointCalculatorsTypeNames[start_point_calc_method]);
224-
// KWUtil::printArray(lastStartPointCalculatorType+1, startPointCalculatorsTypeNames);
225-
// printf("]\n");
226230
printf("\n fTolerance: %.2e ", fTolerance);
227231
//printf("xTolerance: %.2e ", xTolerance);
228232
printf("\n max_function_evals: %d ", max_function_evals);
229-
printf("\n use_gradient: %s", use_gradient?"1":"0");
230-
printf("\n mean_cut_off: %.2f ", mean_cut_off);
233+
printf("\n use_gradient: %s", use_gradient ? "1" : "0");
234+
printf("\n mean_cut_off: %.2f ", mean_cut_off ? "1" : "0");
235+
printf("\n map_scale_factor: %.2f ", map_scale_factor);
236+
printf("\n use_colorbar: %.sf ", use_colorbar);
231237
//printf("fittingCutOff: %.2f ", fittingCutOff);
232238
printf("\n number_of_threads: %d", number_of_threads);
233-
printf("\n visualise: %s", visualise?"1":"0");
234-
235-
printf("\n calculation time: %.2fs", calculation_time);
239+
printf("\n visualise: %s", visualise ? "1" : "0");
240+
if (calculation_time > 0) {
241+
printf("\n calculation time: %.2fs", calculation_time);
242+
}
236243

237244
printf("\n\n");
238245
}
@@ -284,6 +291,8 @@ namespace Ox {
284291
KWUtilYaml::addMapping(&document, mapping_node_number, "use_gradient", use_gradient ? "1" : "0");
285292

286293
KWUtilYaml::addMapping(&document, mapping_node_number, "mean_cut_off", KWUtil::NumberToString(mean_cut_off));
294+
KWUtilYaml::addMapping(&document, mapping_node_number, "map_scale_factor", KWUtil::NumberToString(map_scale_factor));
295+
KWUtilYaml::addMapping(&document, mapping_node_number, "use_colorbar", use_colorbar ? "1" : "0");
287296
KWUtilYaml::addMapping(&document, mapping_node_number, "number_of_threads", KWUtil::NumberToString(number_of_threads));
288297
KWUtilYaml::addMapping(&document, mapping_node_number, "visualise", visualise ? "1" : "0");
289298

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*!
2-
* \file OxFunctionsT1Basic.h
2+
* \file OxFunctionsT1ThreeParams.h
33
* \author Konrad Werys
44
* \date 2018/07/29
55
*/
66

7-
#ifndef Tomato_OXFUNCTIONST1BASIC_H
8-
#define Tomato_OXFUNCTIONST1BASIC_H
7+
#ifndef Tomato_OXFUNCTIONST1ThreeParams_H
8+
#define Tomato_OXFUNCTIONST1ThreeParams_H
99

1010
#include "tomatolib_export.h"
1111
#include "OxFunctionsT1.h"
@@ -14,14 +14,14 @@
1414
namespace Ox {
1515

1616
/**
17-
* \class FunctionsT1Basic
18-
* \brief Container for a basic model function \f$ A-B\exp(t/T_1^*) \f$, cost function and Least-Squares
17+
* \class FunctionsT1ThreeParams
18+
* \brief Container for a ThreeParams model function \f$ A-B\exp(t/T_1^*) \f$, cost function and Least-Squares
1919
* function and derivatives.
2020
* \details
2121
* @tparam MeasureType
2222
*/
2323
template< typename MeasureType >
24-
class FunctionsT1Basic : public FunctionsT1<MeasureType>{
24+
class FunctionsT1ThreeParam : public FunctionsT1<MeasureType>{
2525

2626
public:
2727

@@ -31,26 +31,26 @@ namespace Ox {
3131
virtual MeasureType calcCostValue(const MeasureType* parameters );
3232
virtual void calcCostDerivative(const MeasureType* parameters, MeasureType* derivative);
3333

34-
FunctionsT1Basic() : FunctionsT1<MeasureType>(){
34+
FunctionsT1ThreeParam() : FunctionsT1<MeasureType>(){
3535
this->_nDims = 3;
3636
}
3737

3838
/**
3939
* cloning
4040
* @return
4141
*/
42-
virtual FunctionsT1<MeasureType> *newByCloning() { return new FunctionsT1Basic<MeasureType>(*this); }
42+
virtual FunctionsT1<MeasureType> *newByCloning() { return new FunctionsT1ThreeParam<MeasureType>(*this); }
4343

4444
/**
4545
* \brief do not forget about the virtual destructor, see
4646
* https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors
4747
*/
48-
virtual ~FunctionsT1Basic(){};
48+
virtual ~FunctionsT1ThreeParam(){};
4949
};
5050
} //namespace Ox
5151

5252
#ifndef TOMATOLIB_COMPILED
53-
#include "OxFunctionsT1Basic.hxx"
53+
#include "OxFunctionsT1ThreeParam.hxx"
5454
#endif //TOMATOLIB_COMPILED
5555

56-
#endif //Tomato_OXFUNCTIONST1BASIC_H
56+
#endif //Tomato_OXFUNCTIONST1ThreeParams_H
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
/*!
2-
* \file OxFunctionsT1Basic.hxx
2+
* \file OxFunctionsT1ThreeParams.hxx
33
* \author Konrad Werys
44
* \date 2018/07/29
55
*/
66

7-
#ifndef Tomato_OXFUNCTIONST1BASIC_HXX
8-
#define Tomato_OXFUNCTIONST1BASIC_HXX
7+
#ifndef Tomato_OXFUNCTIONST1ThreeParams_HXX
8+
#define Tomato_OXFUNCTIONST1ThreeParams_HXX
99

1010
namespace Ox {
1111

1212

1313
template< typename MeasureType >
1414
MeasureType
15-
FunctionsT1Basic<MeasureType>
15+
FunctionsT1ThreeParam<MeasureType>
1616
::calcModelValue(const MeasureType* parameters, MeasureType time){
1717
MeasureType A = parameters[0];
1818
MeasureType B = parameters[1];
@@ -26,16 +26,11 @@ namespace Ox {
2626

2727
template< typename MeasureType >
2828
void
29-
FunctionsT1Basic<MeasureType>
29+
FunctionsT1ThreeParam<MeasureType>
3030
::calcLSResiduals(const MeasureType* parameters, MeasureType* residuals){
3131

32-
//std::cout << "calcLSResiduals" << std::endl;
3332
unsigned int nSamples = this->_nSamples;
3433

35-
MeasureType A = parameters[0];
36-
MeasureType B = parameters[1];
37-
MeasureType T1star = parameters[2];
38-
3934
for (unsigned int i = 0; i < nSamples; i++) {
4035
MeasureType invTime = this->_InvTimes[i];
4136
MeasureType measured = this->_Signal[i];
@@ -49,7 +44,7 @@ namespace Ox {
4944

5045
template< typename MeasureType >
5146
void
52-
FunctionsT1Basic<MeasureType>
47+
FunctionsT1ThreeParam<MeasureType>
5348
::calcLSJacobian(const MeasureType* parameters, MeasureType* jacobian){
5449
int nSamples = this->_nSamples;
5550

@@ -62,7 +57,7 @@ namespace Ox {
6257
invTime = this->_InvTimes[i];
6358
myexp = exp(-invTime/T1star);
6459

65-
// calculated in matlab (syms A B T1 t), f=A-B*exp(-t./T1); diff(f,A), diff(f,B), diff(calcCostValue,T1)
60+
// calculated in matlab (syms A B T1 t), f=A-B*exp(-t./T1); diff(f,A), diff(f,B), diff(f,T1)
6661
jacobian[i*3+0] = 1.0;
6762
jacobian[i*3+1] = -myexp;
6863
jacobian[i*3+2] = -B * invTime * myexp / (T1star * T1star);
@@ -71,7 +66,7 @@ namespace Ox {
7166

7267
template< typename MeasureType >
7368
MeasureType
74-
FunctionsT1Basic<MeasureType>
69+
FunctionsT1ThreeParam<MeasureType>
7570
::calcCostValue(const MeasureType* parameters){
7671
//std::cout << "calcCostValue" << std::endl;
7772

@@ -89,7 +84,7 @@ namespace Ox {
8984

9085
template< typename MeasureType >
9186
void
92-
FunctionsT1Basic<MeasureType>
87+
FunctionsT1ThreeParam<MeasureType>
9388
::calcCostDerivative(const MeasureType* parameters, MeasureType* derivative){
9489
//std::cout << "calcCostDerivative" << std::endl;
9590

@@ -105,7 +100,7 @@ namespace Ox {
105100
MeasureType B = parameters[1];
106101
MeasureType T1star = parameters[2];
107102

108-
// calculated in matlab (syms A B T1 t y), f=(A-B*exp(-t./T1)-y).^2; diff(f,A), diff(f,B), diff(calcCostValue,T1)
103+
// calculated in matlab (syms A B T1 t y), f=(A-B*exp(-t./T1)-y).^2; diff(f,A), diff(f,B), diff(f,T1)
109104
for (int i = 0; i < nSamples; ++i){
110105
measured = this->getSignal()[i];
111106
invTime = this->getInvTimes()[i];
@@ -120,4 +115,4 @@ namespace Ox {
120115
} //namespace Ox
121116

122117

123-
#endif //Tomato_OXFUNCTIONST1BASIC_HXX
118+
#endif //Tomato_OXFUNCTIONST1ThreeParams_HXX

lib/OxFunctionsT1TwoParam.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*!
2+
* \file OxFunctionsT1TwoParams.h
3+
* \author Konrad Werys
4+
* \date 2018/07/29
5+
*/
6+
7+
#ifndef Tomato_OXFUNCTIONST1TwoParams_H
8+
#define Tomato_OXFUNCTIONST1TwoParams_H
9+
10+
#include "tomatolib_export.h"
11+
#include "OxFunctionsT1.h"
12+
#include <cmath>
13+
14+
namespace Ox {
15+
16+
/**
17+
* \class FunctionsT1TwoParams
18+
* \brief Container for a TwoParams model function \f$ A-B\exp(t/T_1^*) \f$, cost function and Least-Squares
19+
* function and derivatives.
20+
* \details
21+
* @tparam MeasureType
22+
*/
23+
template< typename MeasureType >
24+
class FunctionsT1TwoParam : public FunctionsT1<MeasureType>{
25+
26+
public:
27+
28+
virtual MeasureType calcModelValue(const MeasureType* parameters, MeasureType time);
29+
virtual void calcLSResiduals(const MeasureType* parameters, MeasureType* residuals);
30+
virtual void calcLSJacobian(const MeasureType* parameters, MeasureType* jacobian);
31+
virtual MeasureType calcCostValue(const MeasureType* parameters );
32+
virtual void calcCostDerivative(const MeasureType* parameters, MeasureType* derivative);
33+
34+
FunctionsT1TwoParam() : FunctionsT1<MeasureType>(){
35+
this->_nDims = 2;
36+
}
37+
38+
/**
39+
* cloning
40+
* @return
41+
*/
42+
virtual FunctionsT1<MeasureType> *newByCloning() { return new FunctionsT1TwoParam<MeasureType>(*this); }
43+
44+
/**
45+
* \brief do not forget about the virtual destructor, see
46+
* https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors
47+
*/
48+
virtual ~FunctionsT1TwoParam(){};
49+
};
50+
} //namespace Ox
51+
52+
#ifndef TOMATOLIB_COMPILED
53+
#include "OxFunctionsT1TwoParam.hxx"
54+
#endif //TOMATOLIB_COMPILED
55+
56+
#endif //Tomato_OXFUNCTIONST1TwoParams_H

0 commit comments

Comments
 (0)