20 #ifndef MIRTK_DataStatistics_H 21 #define MIRTK_DataStatistics_H 25 #include "mirtk/Math.h" 26 #include "mirtk/String.h" 27 #include "mirtk/Stream.h" 28 #include "mirtk/Array.h" 29 #include "mirtk/Algorithm.h" 32 namespace mirtk {
namespace data {
44 mirtkPublicAttributeMacro(
bool, Hidden);
47 mirtkPublicAttributeMacro(
string, Description);
50 mirtkPublicAttributeMacro(Array<string>, Names);
53 mirtkReadOnlyAttributeMacro(Array<double>, Values);
58 Statistic(
int nvalues,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
61 _Description(desc ? desc :
"Unknown statistic")
63 if (nvalues <= 0) nvalues = 1;
64 _Names .resize(nvalues);
65 _Values.resize(nvalues, NaN);
67 for (
int i = 0; i < nvalues; ++i) {
68 _Names[i] = names->at(i);
92 virtual const double &
Value()
const 98 virtual void Process(
int n,
double *data,
bool *mask =
nullptr)
100 this->
Evaluate(_Values, n, data, mask);
103 #if MIRTK_Image_WITH_VTK 106 virtual void Process(vtkDataArray *data,
bool *mask =
nullptr)
108 const int n =
static_cast<int>(data->GetNumberOfTuples() * data->GetNumberOfComponents());
109 if (data->GetDataType() == VTK_DOUBLE) {
110 this->
Process(n, reinterpret_cast<double *>(data->GetVoidPointer(0)), mask);
112 UniquePtr<double[]> _data(
new double[n]);
113 double *tuple = _data.get();
114 for (vtkIdType i = 0; i < data->GetNumberOfTuples(); ++i) {
115 data->GetTuple(i, tuple);
116 tuple += data->GetNumberOfComponents();
118 this->
Process(n, _data.get(), mask);
123 #endif // MIRTK_Image_WITH_VTK 126 virtual void Evaluate(Array<double> &,
int,
const double *,
const bool * =
nullptr)
const = 0;
129 virtual void PrintHeader(ostream &os = cout,
const char *delimiter =
",")
const 131 for (
size_t i = 0; i < _Values.size(); ++i) {
132 if (i > 0) os << delimiter;
133 if (i < _Names.size()) os << _Names[i];
138 virtual void PrintValues(ostream &os = cout,
int digits = 5,
const char *delimiter =
",")
const 140 streamsize prev_precision = os.precision(digits);
141 for (
size_t i = 0; i < _Values.size(); ++i) {
142 if (i > 0) os << delimiter;
145 os.precision(prev_precision);
149 virtual void Print(ostream &os = cout,
int digits = 5,
const char *prefix =
"")
const 151 streamsize prev_precision = os.precision(digits);
152 if (prefix && prefix[0] !=
'\0') {
154 os << char(tolower(_Description[0]));
155 os << _Description.substr(1);
160 if (_Values.size() != 1) os <<
"[";
161 for (
size_t i = 0; i < _Values.size(); ++i) {
162 if (i > 0) os <<
", ";
165 if (_Values.size() != 1) os <<
"]";
167 os.precision(prev_precision);
177 namespace statistic {
186 Count(
const char *desc =
"N",
const Array<string> *names =
nullptr)
190 if (!names) _Names[0] =
"N";
194 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
198 for (
int i = 0; i < n; ++i) {
199 if (mask[i]) ++count;
207 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 210 values[0] = Calculate(n, data, mask);
214 virtual void PrintValues(ostream &os = cout,
int = 5,
const char *delimiter =
",")
const 216 for (
size_t i = 0; i < _Values.size(); ++i) {
217 if (i > 0) os << delimiter;
218 os << int(_Values[i]);
223 virtual void Print(ostream &os = cout,
int = 5,
const char *prefix =
"")
const 225 if (prefix && prefix[0] !=
'\0') {
227 os << char(tolower(_Description[0]));
228 os << _Description.substr(1);
233 if (_Values.size() != 1) os <<
"[";
234 for (
size_t i = 0; i < _Values.size(); ++i) {
235 if (i > 0) os <<
", ";
236 os << int(_Values[i]);
238 if (_Values.size() != 1) os <<
"]";
249 Sum(
const char *desc =
"Sum",
const Array<string> *names =
nullptr)
253 if (!names) _Names[0] =
"Sum";
257 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
261 for (
int i = 0; i < n; ++i) {
263 sum +=
static_cast<double>(data[i]);
267 for (
int i = 0; i < n; ++i) {
268 sum +=
static_cast<double>(data[i]);
274 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 277 values[0] = Calculate(n, data, mask);
281 mirtkCalculateVtkDataArray1();
290 Min(
const char *desc =
"Minimum",
const Array<string> *names =
nullptr)
294 if (!names) _Names[0] =
"Min";
298 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
302 for (
int i = 0; i < n; ++i) {
304 d =
static_cast<double>(data[i]);
309 for (
int i = 0; i < n; ++i) {
310 d =
static_cast<double>(data[i]);
314 return (
IsInf(v) ? NaN : v);
317 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 320 values[0] = Calculate(n, data, mask);
324 mirtkCalculateVtkDataArray1();
333 MinAbs(
const char *desc =
"Minimum absolute value",
const Array<string> *names =
nullptr)
337 if (!names) _Names[0] =
"Min abs value";
341 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
345 for (
int i = 0; i < n; ++i) {
347 d = abs(static_cast<double>(data[i]));
352 for (
int i = 0; i < n; ++i) {
353 d = abs(static_cast<double>(data[i]));
357 return (
IsInf(v) ? NaN : v);
360 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 363 values[0] = Calculate(n, data, mask);
367 mirtkCalculateVtkDataArray1();
376 Max(
const char *desc =
"Maximum",
const Array<string> *names =
nullptr)
380 if (!names) _Names[0] =
"Max";
384 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
388 for (
int i = 0; i < n; ++i) {
390 d =
static_cast<double>(data[i]);
395 for (
int i = 0; i < n; ++i) {
396 d =
static_cast<double>(data[i]);
400 return (
IsInf(v) ? NaN : v);
403 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 406 values[0] = Calculate(n, data, mask);
410 mirtkCalculateVtkDataArray1();
419 MaxAbs(
const char *desc =
"Maximum absolute value",
const Array<string> *names =
nullptr)
423 if (!names) _Names[0] =
"Max abs value";
427 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
431 for (
int i = 0; i < n; ++i) {
433 d = abs(static_cast<double>(data[i]));
438 for (
int i = 0; i < n; ++i) {
439 d = abs(static_cast<double>(data[i]));
443 return (
IsInf(v) ? NaN : v);
446 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 449 values[0] = Calculate(n, data, mask);
453 mirtkCalculateVtkDataArray1();
462 Extrema(
const char *desc =
"Extrema",
const Array<string> *names =
nullptr)
473 static void Calculate(
double &v1,
double &v2,
int n,
const T *data,
const bool *mask =
nullptr)
479 for (
int i = 0; i < n; ++i) {
481 d =
static_cast<double>(data[i]);
487 for (
int i = 0; i < n; ++i) {
488 d =
static_cast<double>(data[i]);
498 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 501 Calculate(values[0], values[1], n, data, mask);
504 double Min()
const {
return _Values[0]; }
505 double Max()
const {
return _Values[1]; }
508 mirtkCalculateVtkDataArray2();
517 Range(
const char *desc =
"Range",
const Array<string> *names =
nullptr)
521 if (!names) _Names[0] =
"Range";
525 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
528 Extrema::Calculate(v1, v2, n, data, mask);
532 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 535 values[0] = Calculate(n, data, mask);
539 mirtkCalculateVtkDataArray1();
548 Median(
const char *desc =
"Median",
const Array<string> *names =
nullptr)
552 if (!names) _Names[0] =
"Median";
556 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
561 for (
int i = 0; i < n; ++i) {
562 if (mask[i]) values.push_back(data[i]);
566 for (
int i = 0; i < n; ++i) {
570 if (values.size() <= 0)
return NaN;
571 return NthElement(values, static_cast<int>(values.size())/2);
574 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 577 values[0] = Calculate(n, data, mask);
581 mirtkCalculateVtkDataArray1();
590 Mean(
const char *desc =
"Mean",
const Array<string> *names =
nullptr)
594 if (!names) _Names[0] =
"Mean";
598 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
604 for (
int i = 0; i < n; ++i) {
606 ++m, v += (
static_cast<double>(data[i]) - v) / m;
610 for (
int i = 0; i < n; ++i) {
611 v += (
static_cast<double>(data[i]) - v) / (i + 1);
616 return (m < 1 ? NaN : v);
619 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 622 values[0] = Calculate(n, data, mask);
626 mirtkCalculateVtkDataArray1();
636 MeanVar(
int nvalues,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
644 static void Calculate(
double &mean,
double &var,
int n,
const T *data,
const bool *mask =
nullptr)
650 for (
int i = 0; i < n; ++i) {
651 if (!mask || mask[i]) {
653 d =
static_cast<double>(data[i]);
656 var += delta * (d - mean);
676 Var(
const char *desc =
"Variance",
const Array<string> *names =
nullptr)
680 if (!names) _Names[0] =
"Var";
684 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
687 MeanVar::Calculate(mean, var, n, data, mask);
691 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 695 MeanVar::Calculate(mean, values[0], n, data, mask);
699 mirtkCalculateVtkDataArray1();
708 StDev(
const char *desc =
"Standard deviation",
const Array<string> *names =
nullptr)
712 if (!names) _Names[0] =
"Sigma";
716 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
719 MeanVar::Calculate(mean, var, n, data, mask);
723 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 726 MeanVar::Calculate(mean, var, n, data, mask);
728 values[0] = sqrt(var);
732 mirtkCalculateVtkDataArray1();
741 NormalDistribution(
const char *desc =
"Normal distribution",
const Array<string> *names =
nullptr)
752 static void Calculate(
double &mean,
double &sigma,
int n,
const T *data,
const bool *mask =
nullptr)
754 MeanVar::Calculate(mean, sigma, n, data, mask);
758 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 761 Calculate(values[0], values[1], n, data, mask);
764 double Mean()
const {
return _Values[0]; }
765 double Sigma()
const {
return _Values[1]; }
768 mirtkCalculateVtkDataArray2();
776 mirtkPublicAttributeMacro(
double,
Mean);
784 mirtkPublicAggregateMacro(
const double, MeanPointer);
789 const char *desc =
"Average absolute difference",
790 const Array<string> *names =
nullptr)
794 _MeanPointer(mean_ptr)
796 if (!names) _Names[0] =
"MAD";
810 static double Calculate(
double mean,
int n,
const T *data,
const bool *mask =
nullptr)
815 for (
int i = 0; i < n; ++i) {
817 mad += abs(data[i] - mean);
822 for (
int i = 0; i < n; ++i) {
823 mad += abs(data[i] - mean);
827 return (num > 0 ? mad / num : 0.);
830 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 833 values[0] = Calculate(_MeanPointer ? *_MeanPointer : _Mean, n, data, mask);
843 MeanAbsoluteDifference(
const char *desc =
"Mean absolute difference",
const Array<string> *names =
nullptr)
848 _Names[0] =
"MAD mean";
853 static void Calculate(
double &mean,
double &mad,
int n,
const T *data,
const bool *mask =
nullptr)
856 mean = Mean::Calculate(n, data, mask);
859 for (
int i = 0; i < n; ++i) {
861 mad += abs(data[i] - mean);
866 for (
int i = 0; i < n; ++i) {
867 mad += abs(data[i] - mean);
871 if (num > 0) mad /= num;
875 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
878 Calculate(mean, mad, n, data, mask);
882 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 885 values[0] = Calculate(n, data, mask);
889 mirtkCalculateVtkDataArray1();
903 _Names[0] =
"MAD median";
908 static void Calculate(
double &median,
double &mad,
int n,
const T *data,
const bool *mask =
nullptr)
911 median = Median::Calculate(n, data, mask);
914 for (
int i = 0; i < n; ++i) {
916 mad += abs(data[i] - median);
921 for (
int i = 0; i < n; ++i) {
922 mad += abs(data[i] - median);
926 if (num > 0) mad /= num;
930 static double Calculate(
int n,
const T *data,
const bool *mask =
nullptr)
933 Calculate(median, mad, n, data, mask);
937 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 940 values[0] = Calculate(n, data, mask);
944 mirtkCalculateVtkDataArray1();
952 mirtkReadOnlyAttributeMacro(
int, P);
956 Percentile(
int p,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
962 if (p == 1) _Description +=
"st";
963 else if (p == 2) _Description +=
"nd";
964 else if (p == 3) _Description +=
"rd";
965 else _Description +=
"th";
966 _Description +=
" percentile";
970 if (p == 1) _Names[0] +=
"st";
971 else if (p == 2) _Names[0] +=
"nd";
972 else if (p == 3) _Names[0] +=
"rd";
973 else _Names[0] +=
"th";
979 static double CalculateGivenSortedData(
int p,
double &rank,
int n,
const T *data)
987 rank = (double(p) / 100.) * double(n + 1);
996 return Min::Calculate(n, data);
998 return Max::Calculate(n, data);
1000 return data[k - 1] + d * (data[k] - data[k - 1]);
1005 static double CalculateGivenSortedData(
int p,
int n,
const T *data)
1008 return CalculateGivenSortedData(p, rank, n, data);
1012 static double Calculate(
int p,
double &rank,
int n,
const T *data,
const bool *mask =
nullptr)
1018 for (
int i = 0; i < n; ++i) {
1029 rank = (double(p) / 100.) * double(m + 1);
1033 double d = rank - k;
1038 return Min::Calculate(n, data, mask);
1039 }
else if (k >= m) {
1040 return Max::Calculate(n, data, mask);
1043 double *v =
new double[m];
1046 for (
int i = 0; i < n; ++i) {
1047 if (mask[i]) v[m++] =
static_cast<double>(data[i]);
1050 for (
int i = 0; i < n; ++i) {
1051 v[i] =
static_cast<double>(data[i]);
1055 partial_sort(v, v + k + 1, v + m);
1057 double percentile = v[k - 1] + d * (v[k] - v[k - 1]);
1065 static double Calculate(
int p,
int n,
const T *data,
const bool *mask =
nullptr)
1068 return Calculate(p, rank, n, data, mask);
1071 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 1074 values[0] = Calculate(_P, n, data, mask);
1078 #if MIRTK_Image_WITH_VTK 1080 static double Calculate(
int p,
double &rank, vtkDataArray *data,
const bool *mask =
nullptr)
1082 const int n =
static_cast<int>(data->GetNumberOfTuples());
1083 const void *ptr = data->GetVoidPointer(0);
1084 switch (data->GetDataType()) {
1085 case VTK_SHORT:
return Calculate(p, rank, n, static_cast<const short *>(ptr), mask);
1086 case VTK_INT:
return Calculate(p, rank, n, static_cast<const int *>(ptr), mask);
1087 case VTK_FLOAT:
return Calculate(p, rank, n, static_cast<const float *>(ptr), mask);
1088 case VTK_DOUBLE:
return Calculate(p, rank, n, static_cast<const double *>(ptr), mask);
1090 cerr <<
"Unsupported vtkDataArray type: " << data->GetDataType() << endl;
1097 static double Calculate(
int p, vtkDataArray *data,
const bool *mask =
nullptr)
1100 return Calculate(p, rank, data, mask);
1103 #endif // MIRTK_Image_WITH_VTK 1111 mirtkReadOnlyAttributeMacro(
int, P);
1115 AbsPercentile(
int p,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
1121 if (p == 1) _Description +=
"st";
1122 else if (p == 2) _Description +=
"nd";
1123 else if (p == 3) _Description +=
"rd";
1124 else _Description +=
"th";
1125 _Description +=
" absolute value percentile";
1129 if (p == 1) _Names[0] +=
"st";
1130 else if (p == 2) _Names[0] +=
"nd";
1131 else if (p == 3) _Names[0] +=
"rd";
1132 else _Names[0] +=
"th";
1133 _Names[0] +=
"% (abs)";
1138 static double Calculate(
int p,
double &rank,
int n,
const T *data,
const bool *mask =
nullptr)
1144 for (
int i = 0; i < n; ++i) {
1155 rank = (double(p) / 100.) * double(m + 1);
1159 double d = rank - k;
1164 return MinAbs::Calculate(n, data, mask);
1165 }
else if (k >= m) {
1166 return MaxAbs::Calculate(n, data, mask);
1169 double *v =
new double[m];
1172 for (
int i = 0; i < n; ++i) {
1173 if (mask[i]) v[m++] = abs(static_cast<double>(data[i]));
1176 for (
int i = 0; i < n; ++i) {
1177 v[i] = abs(static_cast<double>(data[i]));
1181 partial_sort(v, v + k + 1, v + m);
1183 double percentile = v[k - 1] + d * (v[k] - v[k - 1]);
1191 static double Calculate(
int p,
int n,
const T *data,
const bool *mask =
nullptr)
1194 return Calculate(p, rank, n, data, mask);
1197 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 1200 values[0] = Calculate(_P, n, data, mask);
1204 #if MIRTK_Image_WITH_VTK 1206 static double Calculate(
int p,
double &rank, vtkDataArray *data,
const bool *mask =
nullptr)
1208 const int n =
static_cast<int>(data->GetNumberOfTuples());
1209 const void *ptr = data->GetVoidPointer(0);
1210 switch (data->GetDataType()) {
1211 case VTK_SHORT:
return Calculate(p, rank, n, static_cast<const short *>(ptr), mask);
1212 case VTK_INT:
return Calculate(p, rank, n, static_cast<const int *>(ptr), mask);
1213 case VTK_FLOAT:
return Calculate(p, rank, n, static_cast<const float *>(ptr), mask);
1214 case VTK_DOUBLE:
return Calculate(p, rank, n, static_cast<const double *>(ptr), mask);
1216 cerr <<
"Unsupported vtkDataArray type: " << data->GetDataType() << endl;
1219 rank = numeric_limits<double>::quiet_NaN();
1220 return numeric_limits<double>::quiet_NaN();
1223 static double Calculate(
int p, vtkDataArray *data,
const bool *mask =
nullptr)
1226 return Calculate(p, rank, data, mask);
1238 LowerPercentileMean(
int p,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
1243 _Description =
"Mean below ";
1245 if (p == 1) _Description +=
"st";
1246 else if (p == 2) _Description +=
"nd";
1247 else if (p == 3) _Description +=
"rd";
1248 else _Description +=
"th";
1249 _Description +=
" percentile";
1252 _Names[0] =
"Mean <";
1254 if (p == 1) _Names[0] +=
"st";
1255 else if (p == 2) _Names[0] +=
"nd";
1256 else if (p == 3) _Names[0] +=
"rd";
1257 else _Names[0] +=
"th";
1263 static double Calculate(
int p,
int n,
const T *data,
const bool *mask =
nullptr)
1265 const double threshold = Percentile::Calculate(p, n, data, mask);
1271 for (
int i = 0; i < n; ++i) {
1273 d =
static_cast<double>(data[i]);
1274 if (d <= threshold) {
1281 for (
int i = 0; i < n; ++i) {
1282 d =
static_cast<double>(data[i]);
1283 if (d <= threshold) {
1290 return (m < 1 ? NaN : v);
1293 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 1296 values[0] = Calculate(_P, n, data, mask);
1300 #if MIRTK_Image_WITH_VTK 1302 static double Calculate(
int p, vtkDataArray *data,
const bool *mask =
nullptr)
1304 const int n =
static_cast<int>(data->GetNumberOfTuples());
1305 const void *ptr = data->GetVoidPointer(0);
1306 switch (data->GetDataType()) {
1307 case VTK_SHORT:
return Calculate(p, n, static_cast<const short *>(ptr), mask);
1308 case VTK_INT:
return Calculate(p, n, static_cast<const int *>(ptr), mask);
1309 case VTK_FLOAT:
return Calculate(p, n, static_cast<const float *>(ptr), mask);
1310 case VTK_DOUBLE:
return Calculate(p, n, static_cast<const double *>(ptr), mask);
1312 cerr <<
"Unsupported vtkDataArray type: " << data->GetDataType() << endl;
1318 #endif // MIRTK_Image_WITH_VTK 1327 UpperPercentileMean(
int p,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
1332 _Description =
"Mean above ";
1334 if (p == 1) _Description +=
"st";
1335 else if (p == 2) _Description +=
"nd";
1336 else if (p == 3) _Description +=
"rd";
1337 else _Description +=
"th";
1338 _Description +=
" percentile";
1341 _Names[0] =
"Mean >";
1343 if (p == 1) _Names[0] +=
"st";
1344 else if (p == 2) _Names[0] +=
"nd";
1345 else if (p == 3) _Names[0] +=
"rd";
1346 else _Names[0] +=
"th";
1352 static double Calculate(
int p,
int n,
const T *data,
const bool *mask =
nullptr)
1354 const double threshold = Percentile::Calculate(p, n, data, mask);
1360 for (
int i = 0; i < n; ++i) {
1362 d =
static_cast<double>(data[i]);
1363 if (d >= threshold) {
1370 for (
int i = 0; i < n; ++i) {
1371 d =
static_cast<double>(data[i]);
1372 if (d >= threshold) {
1379 return (m < 1 ? NaN : v);
1382 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 1385 values[0] = Calculate(_P, n, data, mask);
1389 #if MIRTK_Image_WITH_VTK 1391 static double Calculate(
int p, vtkDataArray *data,
const bool *mask =
nullptr)
1393 const int n =
static_cast<int>(data->GetNumberOfTuples());
1394 const void *ptr = data->GetVoidPointer(0);
1395 switch (data->GetDataType()) {
1396 case VTK_SHORT:
return Calculate(p, n, static_cast<const short *>(ptr), mask);
1397 case VTK_INT:
return Calculate(p, n, static_cast<const int *>(ptr), mask);
1398 case VTK_FLOAT:
return Calculate(p, n, static_cast<const float *>(ptr), mask);
1399 case VTK_DOUBLE:
return Calculate(p, n, static_cast<const double *>(ptr), mask);
1401 cerr <<
"Unsupported vtkDataArray type: " << data->GetDataType() << endl;
1407 #endif // MIRTK_Image_WITH_VTK 1416 RobustMean(
int p,
const char *desc =
nullptr,
const Array<string> *names =
nullptr)
1421 _Description =
"Mean excl. ";
1423 if (p == 1) _Description +=
"st";
1424 else if (p == 2) _Description +=
"nd";
1425 else if (p == 3) _Description +=
"rd";
1426 else _Description +=
"th";
1427 _Description +=
" percentile";
1430 _Names[0] =
"Mean <>";
1432 if (p == 1) _Names[0] +=
"st";
1433 else if (p == 2) _Names[0] +=
"nd";
1434 else if (p == 3) _Names[0] +=
"rd";
1435 else _Names[0] +=
"th";
1441 static double Calculate(
int p,
int n,
const T *data,
const bool *mask =
nullptr)
1443 const double min = Percentile::Calculate( p, n, data, mask);
1444 const double max = Percentile::Calculate(100 - p, n, data, mask);
1450 for (
int i = 0; i < n; ++i) {
1452 d =
static_cast<double>(data[i]);
1453 if (min <= d && d <= max) {
1460 for (
int i = 0; i < n; ++i) {
1461 d =
static_cast<double>(data[i]);
1462 if (min <= d && d <= max) {
1469 return (m < 1 ? NaN : v);
1472 void Evaluate(Array<double> &values,
int n,
const double *data,
const bool *mask =
nullptr)
const 1475 values[0] = Calculate(_P, n, data, mask);
1479 #if MIRTK_Image_WITH_VTK 1481 static double Calculate(
int p, vtkDataArray *data,
const bool *mask =
nullptr)
1483 const int n =
static_cast<int>(data->GetNumberOfTuples());
1484 const void *ptr = data->GetVoidPointer(0);
1485 switch (data->GetDataType()) {
1486 case VTK_SHORT:
return Calculate(p, n, static_cast<const short *>(ptr), mask);
1487 case VTK_INT:
return Calculate(p, n, static_cast<const int *>(ptr), mask);
1488 case VTK_FLOAT:
return Calculate(p, n, static_cast<const float *>(ptr), mask);
1489 case VTK_DOUBLE:
return Calculate(p, n, static_cast<const double *>(ptr), mask);
1491 cerr <<
"Unsupported vtkDataArray type: " << data->GetDataType() << endl;
1497 #endif // MIRTK_Image_WITH_VTK 1503 #endif // MIRTK_DataStatistics_H Get minimum and maximum values.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Statistic(int nvalues, const char *desc=nullptr, const Array< string > *names=nullptr)
Constructor.
Count number of masked values (mask != false)
virtual void PrintValues(ostream &os=cout, int digits=5, const char *delimiter=",") const
Print delimited statistic values to output stream.
Base class of all data operations.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Defines base class and I/O functions for arbitrary 1D data sequences.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
virtual void PrintHeader(ostream &os=cout, const char *delimiter=",") const
Print column names of statistic values to output stream.
Mean absolute difference/deviation around the mean.
void Value(double v)
Set value of statistic (first entry of _Values vector)
Mean absolute difference/deviation around the specified value.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Robust evaluation of standard deviation.
MeanVar(int nvalues, const char *desc=nullptr, const Array< string > *names=nullptr)
Constructor.
Absolute value percentile calculation.
Robust variance evaluation.
virtual void Print(ostream &os=cout, int digits=5, const char *prefix="") const
Print statistic to output stream as "<desc> = <value>".
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Base class of all data statistics.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
virtual const double & Value() const
Get maximum absolute value.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
virtual void Process(int n, double *data, bool *mask=nullptr)
Process given data.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
MIRTKCU_API bool IsInf(double x)
Check if floating point value represents infinity.
virtual void Print(ostream &os=cout, int=5, const char *prefix="") const
Print statistic to output stream as "<desc> = <value>".
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Lower percentile mean calculation.
Robust mean calculation, ignoring values below and above a certain percentile.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Get minimum absolute value.
Robust mean/average evaluation.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
Base class of statistics which compute mean, variance, and/or standard deviation. ...
string ToString(const EnergyMeasure &value, int w, char c, bool left)
Convert energy measure enumeration value to string.
mirtkOnOffMacro(Hidden)
Hide/Show statistic in output report.
virtual ~Statistic()
Destructor.
Upper percentile mean calculation.
virtual void Evaluate(Array< double > &, int, const double *, const bool *=nullptr) const =0
Evaluate statistic for given data.
Robust evaluation of Gaussian mean and standard deviation.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
T & NthElement(Array< T > &values, int n)
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
MIRTK_Common_EXPORT const double inf
Positive infinity.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.
virtual void PrintValues(ostream &os=cout, int=5, const char *delimiter=",") const
Print delimited statistic values to output stream.
void Evaluate(Array< double > &values, int n, const double *data, const bool *mask=nullptr) const
Evaluate statistic for given data.