diff --git a/cmd/labelstats.cpp b/cmd/labelstats.cpp index c552976799..a32630f9d7 100644 --- a/cmd/labelstats.cpp +++ b/cmd/labelstats.cpp @@ -23,6 +23,8 @@ #include "connectome/connectome.h" +#include + using namespace MR; using namespace App; diff --git a/core/file/dicom/element.cpp b/core/file/dicom/element.cpp index 54b700e797..0b2ab31fd5 100644 --- a/core/file/dicom/element.cpp +++ b/core/file/dicom/element.cpp @@ -18,6 +18,8 @@ #include "debug.h" #include "file/path.h" +#include + namespace MR { namespace File { namespace Dicom { diff --git a/core/mrtrix.cpp b/core/mrtrix.cpp index 340a6dcfcc..328d09b7bf 100644 --- a/core/mrtrix.cpp +++ b/core/mrtrix.cpp @@ -16,6 +16,8 @@ #include "mrtrix.h" +#include + namespace MR { /************************************************************************ @@ -128,4 +130,138 @@ bool match(const std::string &pattern, const std::string &text, bool ignore_case return __match(pattern.c_str(), text.c_str()); } +std::istream &getline(std::istream &stream, std::string &string) { + std::getline(stream, string); + if (!string.empty()) + if (string[string.size() - 1] == 015) + string.resize(string.size() - 1); + return stream; +} + +std::string &add_line(std::string &original, const std::string &new_line) { + return original.empty() ? (original = new_line) : (original += "\n" + new_line); +} + +std::string shorten(const std::string &text, size_t longest, size_t prefix) { + if (text.size() > longest) + return (text.substr(0, prefix) + "..." + text.substr(text.size() - longest + prefix + 3)); + else + return text; +} + +std::string lowercase(const std::string &string) { + std::string ret; + ret.resize(string.size()); + transform(string.begin(), string.end(), ret.begin(), tolower); + return ret; +} + +std::string uppercase(const std::string &string) { + std::string ret; + ret.resize(string.size()); + transform(string.begin(), string.end(), ret.begin(), toupper); + return ret; +} + +std::string printf(const char *format, ...) { + size_t len = 0; + va_list list1, list2; + va_start(list1, format); + va_copy(list2, list1); + len = vsnprintf(nullptr, 0, format, list1) + 1; + va_end(list1); + VLA(buf, char, len); + vsnprintf(buf, len, format, list2); + va_end(list2); + return buf; +} + +std::string strip(const std::string &string, const std::string &ws, bool left, bool right) { + const std::string::size_type start = (left ? string.find_first_not_of(ws) : 0); + if (start == std::string::npos) + return ""; + const std::string::size_type end = (right ? string.find_last_not_of(ws) + 1 : std::string::npos); + return string.substr(start, end - start); +} + +std::string unquote(const std::string &string) { + if (string.size() <= 2) + return string; + if (!(string.front() == '\"' && string.back() == '\"')) + return string; + std::string substring = string.substr(1, string.size() - 2); + if (std::none_of(substring.begin(), substring.end(), [](const char &c) { return c == '\"'; })) + return substring; + return string; +} + +void replace(std::string &string, char orig, char final) { + for (auto &c : string) + if (c == orig) + c = final; +} + +void replace(std::string &str, const std::string &from, const std::string &to) { + if (from.empty()) + return; + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } +} + +std::vector split_lines(const std::string &string, bool ignore_empty_fields, size_t num) { + return split(string, "\n", ignore_empty_fields, num); +} + +size_t char_is_dash(const char *arg) { + assert(arg != nullptr); + if (arg[0] == '-') + return 1; + if (arg[0] == '\0' || arg[1] == '\0' || arg[2] == '\0') + return 0; + const unsigned char *uarg = reinterpret_cast(arg); + if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95)) + return 3; + if (uarg[0] == 0xEF) { + if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3)) + return 3; + if (uarg[1] == 0xBC && uarg[2] == 0x8D) + return 3; + } + return 0; +} + +bool is_dash(const std::string &arg) { + const size_t nbytes = char_is_dash(arg.c_str()); + return nbytes != 0 && nbytes == arg.size(); +} + +bool consume_dash(const char *&arg) { + size_t nbytes = char_is_dash(arg); + arg += nbytes; + return nbytes != 0; +} + +std::string join(const std::vector &V, const std::string &delimiter) { + std::string ret; + if (V.empty()) + return ret; + ret = V[0]; + for (std::vector::const_iterator i = V.begin() + 1; i != V.end(); ++i) + ret += delimiter + *i; + return ret; +} + +std::string join(const char *const *null_terminated_array, const std::string &delimiter) { + std::string ret; + if (!null_terminated_array) + return ret; + ret = null_terminated_array[0]; + for (const char *const *p = null_terminated_array + 1; *p; ++p) + ret += delimiter + *p; + return ret; +} + } // namespace MR diff --git a/core/mrtrix.h b/core/mrtrix.h index 54c5fe7313..efe5e19ba4 100644 --- a/core/mrtrix.h +++ b/core/mrtrix.h @@ -17,17 +17,10 @@ #ifndef __mrtrix_h__ #define __mrtrix_h__ -#include #include -#include -#include -#include -#include -#include #include #include #include -#include #include #include #include @@ -41,13 +34,7 @@ namespace MR { //! read a line from the stream /*! a replacement for the standard getline() function that also discards * carriage returns if found at the end of the line. */ -inline std::istream &getline(std::istream &stream, std::string &string) { - std::getline(stream, string); - if (string.size() > 0) - if (string[string.size() - 1] == 015) - string.resize(string.size() - 1); - return stream; -} +std::istream &getline(std::istream &stream, std::string &string); template struct max_digits { static constexpr int value() { return 0; } @@ -71,94 +58,37 @@ struct max_digits longest) - return (text.substr(0, prefix) + "..." + text.substr(text.size() - longest + prefix + 3)); - else - return text; -} +std::string shorten(const std::string &text, size_t longest = 40, size_t prefix = 10); //! return lowercase version of string -inline std::string lowercase(const std::string &string) { - std::string ret; - ret.resize(string.size()); - transform(string.begin(), string.end(), ret.begin(), tolower); - return ret; -} +std::string lowercase(const std::string &string); //! return uppercase version of string -inline std::string uppercase(const std::string &string) { - std::string ret; - ret.resize(string.size()); - transform(string.begin(), string.end(), ret.begin(), toupper); - return ret; -} +std::string uppercase(const std::string &string); -inline std::string printf(const char *format, ...) { - size_t len = 0; - va_list list1, list2; - va_start(list1, format); - va_copy(list2, list1); - len = vsnprintf(nullptr, 0, format, list1) + 1; - va_end(list1); - VLA(buf, char, len); - vsnprintf(buf, len, format, list2); - va_end(list2); - return buf; -} +std::string printf(const char *format, ...); -inline std::string -strip(const std::string &string, const std::string &ws = {" \0\t\r\n", 5}, bool left = true, bool right = true) { - std::string::size_type start = (left ? string.find_first_not_of(ws) : 0); - if (start == std::string::npos) - return ""; - std::string::size_type end = (right ? string.find_last_not_of(ws) + 1 : std::string::npos); - return string.substr(start, end - start); -} +std::string +strip(const std::string &string, const std::string &ws = {" \0\t\r\n", 5}, bool left = true, bool right = true); //! Remove quotation marks only if surrounding entire string -inline std::string unquote(const std::string &string) { - if (string.size() <= 2) - return string; - if (!(string.front() == '\"' && string.back() == '\"')) - return string; - const std::string substring = string.substr(1, string.size() - 2); - if (std::none_of(substring.begin(), substring.end(), [](const char &c) { return c == '\"'; })) - return substring; - return string; -} +std::string unquote(const std::string &string); -inline void replace(std::string &string, char orig, char final) { - for (auto &c : string) - if (c == orig) - c = final; -} +void replace(std::string &string, char orig, char final); -inline void replace(std::string &str, const std::string &from, const std::string &to) { - if (from.empty()) - return; - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); - } -} +void replace(std::string &str, const std::string &from, const std::string &to); std::vector split(const std::string &string, const char *delimiters = " \t\n", bool ignore_empty_fields = false, size_t num = std::numeric_limits::max()); -inline std::vector split_lines(const std::string &string, - bool ignore_empty_fields = true, - size_t num = std::numeric_limits::max()) { - return split(string, "\n", ignore_empty_fields, num); -} +std::vector split_lines(const std::string &string, + bool ignore_empty_fields = true, + size_t num = std::numeric_limits::max()); /* inline int round (default_type x) @@ -172,39 +102,16 @@ bool match(const std::string &pattern, const std::string &text, bool ignore_case //! match a dash or any Unicode character that looks like one /*! \note This returns the number of bytes taken up by the matched UTF8 * character, zero if no match. */ -inline size_t char_is_dash(const char *arg) { - assert(arg != nullptr); - if (arg[0] == '-') - return 1; - if (arg[0] == '\0' || arg[1] == '\0' || arg[2] == '\0') - return 0; - const unsigned char *uarg = reinterpret_cast(arg); - if (uarg[0] == 0xE2 && uarg[1] == 0x80 && (uarg[2] >= 0x90 && uarg[2] <= 0x95)) - return 3; - if (uarg[0] == 0xEF) { - if (uarg[1] == 0xB9 && (uarg[2] == 0x98 || uarg[2] == 0xA3)) - return 3; - if (uarg[1] == 0xBC && uarg[2] == 0x8D) - return 3; - } - return 0; -} +size_t char_is_dash(const char *arg); //! match whole string to a dash or any Unicode character that looks like one -inline size_t is_dash(const std::string &arg) { - size_t nbytes = char_is_dash(arg.c_str()); - return nbytes != 0 && nbytes == arg.size(); -} +bool is_dash(const std::string &arg); //! match current character to a dash or any Unicode character that looks like one /*! \note If a match is found, this also advances the \a arg pointer to the next * character in the string, which could be one or several bytes along depending on * the width of the UTF8 character identified. */ -inline bool consume_dash(const char *&arg) { - size_t nbytes = char_is_dash(arg); - arg += nbytes; - return nbytes != 0; -} +bool consume_dash(const char *&arg); template inline std::string str(const T &value, int precision = 0) { std::ostringstream stream; @@ -451,15 +358,7 @@ Eigen::Matrix parse_matrix(const std: return M; } -inline std::string join(const std::vector &V, const std::string &delimiter) { - std::string ret; - if (V.empty()) - return ret; - ret = V[0]; - for (std::vector::const_iterator i = V.begin() + 1; i != V.end(); ++i) - ret += delimiter + *i; - return ret; -} +std::string join(const std::vector &V, const std::string &delimiter); template inline std::string join(const std::vector &V, const std::string &delimiter) { std::string ret; @@ -471,15 +370,7 @@ template inline std::string join(const std::vector &V, const std return ret; } -inline std::string join(const char *const *null_terminated_array, const std::string &delimiter) { - std::string ret; - if (!null_terminated_array) - return ret; - ret = null_terminated_array[0]; - for (const char *const *p = null_terminated_array + 1; *p; ++p) - ret += delimiter + *p; - return ret; -} +std::string join(const char *const *null_terminated_array, const std::string &delimiter); } // namespace MR diff --git a/core/stats.cpp b/core/stats.cpp index 73c48f61fa..9bcaa5e67d 100644 --- a/core/stats.cpp +++ b/core/stats.cpp @@ -43,6 +43,41 @@ const OptionGroup Options = + Option("ignorezero", "ignore zero values during statistics calculation"); +void Stats::operator()(complex_type val) { + if (std::isfinite(val.real()) && std::isfinite(val.imag()) && + (!ignore_zero || val.real() != 0.0 || val.imag() != 0.0)) { + if (min.real() > val.real()) + min = complex_type(val.real(), min.imag()); + if (min.imag() > val.imag()) + min = complex_type(min.real(), val.imag()); + if (max.real() < val.real()) + max = complex_type(val.real(), max.imag()); + if (max.imag() < val.imag()) + max = complex_type(max.real(), val.imag()); + count++; + // Welford's online algorithm for variance calculation: + delta = val - mean; + mean += cdouble(delta.real() / static_cast(count), delta.imag() / static_cast(count)); + delta2 = val - mean; + m2 += cdouble(delta.real() * delta2.real(), delta.imag() * delta2.imag()); + if (!is_complex) + values.push_back(static_cast(val.real())); + } +} + +void print_header(bool is_complex) { + const int width = is_complex ? 20 : 10; + std::cout << std::setw(12) << std::right << "volume" + << " " << std::setw(width) << std::right << "mean"; + if (!is_complex) + std::cout << " " << std::setw(width) << std::right << "median"; + std::cout << " " << std::setw(width) << std::right << "std" + << " " << std::setw(width) << std::right << "min" + << " " << std::setw(width) << std::right << "max" + << " " << std::setw(10) << std::right << "count" + << "\n"; +} + } // namespace Stats } // namespace MR diff --git a/core/stats.h b/core/stats.h index 1ff16afc3a..49e54bdfe2 100644 --- a/core/stats.h +++ b/core/stats.h @@ -17,10 +17,10 @@ #ifndef __stats_h_ #define __stats_h_ -#include "app.h" -#include "file/ofstream.h" #include "math/median.h" +#include + namespace MR { namespace Stats { @@ -46,27 +46,7 @@ class Stats { is_complex(is_complex), ignore_zero(ignorezero) {} - void operator()(complex_type val) { - if (std::isfinite(val.real()) && std::isfinite(val.imag()) && - !(ignore_zero && val.real() == 0.0 && val.imag() == 0.0)) { - if (min.real() > val.real()) - min = complex_type(val.real(), min.imag()); - if (min.imag() > val.imag()) - min = complex_type(min.real(), val.imag()); - if (max.real() < val.real()) - max = complex_type(val.real(), max.imag()); - if (max.imag() < val.imag()) - max = complex_type(max.real(), val.imag()); - count++; - // Welford's online algorithm for variance calculation: - delta = val - mean; - mean += cdouble(delta.real() / count, delta.imag() / count); - delta2 = val - mean; - m2 += cdouble(delta.real() * delta2.real(), delta.imag() * delta2.imag()); - if (!is_complex) - values.push_back(val.real()); - } - } + void operator()(complex_type val); template void print(ImageType &ima, const std::vector &fields) { @@ -139,18 +119,7 @@ class Stats { std::vector values; }; -inline void print_header(bool is_complex) { - int width = is_complex ? 20 : 10; - std::cout << std::setw(12) << std::right << "volume" - << " " << std::setw(width) << std::right << "mean"; - if (!is_complex) - std::cout << " " << std::setw(width) << std::right << "median"; - std::cout << " " << std::setw(width) << std::right << "std" - << " " << std::setw(width) << std::right << "min" - << " " << std::setw(width) << std::right << "max" - << " " << std::setw(10) << std::right << "count" - << "\n"; -} +void print_header(bool is_complex); } // namespace Stats