histogram_ostream_test.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // Copyright 2019 Przemyslaw Bartosik
  2. // Copyright 2019 Hans Dembinski
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt
  6. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #include <boost/core/lightweight_test.hpp>
  8. #include <boost/histogram/accumulators/mean.hpp>
  9. #include <boost/histogram/accumulators/ostream.hpp>
  10. #include <boost/histogram/axis/category.hpp>
  11. #include <boost/histogram/axis/integer.hpp>
  12. #include <boost/histogram/axis/option.hpp>
  13. #include <boost/histogram/axis/regular.hpp>
  14. #include <boost/histogram/make_histogram.hpp>
  15. #include <boost/histogram/ostream.hpp>
  16. #include <limits>
  17. #include <sstream>
  18. #include <string>
  19. #include "throw_exception.hpp"
  20. #include "utility_histogram.hpp"
  21. using namespace boost::histogram;
  22. template <class Histogram>
  23. auto str(const Histogram& h, const unsigned width = 0) {
  24. std::ostringstream os;
  25. // BEGIN and END make nicer error messages
  26. os << "BEGIN\n" << std::setw(width) << h << "END";
  27. return os.str();
  28. }
  29. template <class Tag>
  30. void run_tests() {
  31. using R = axis::regular<>;
  32. using R2 =
  33. axis::regular<double, boost::use_default, axis::null_type, axis::option::none_t>;
  34. using R3 = axis::regular<double, axis::transform::log>;
  35. using C = axis::category<std::string>;
  36. using I = axis::integer<>;
  37. // regular
  38. {
  39. auto h = make(Tag(), R(3, -0.5, 1.0));
  40. h.at(0) = 1;
  41. h.at(1) = 10;
  42. h.at(2) = 5;
  43. const auto expected =
  44. "BEGIN\n"
  45. "histogram(regular(3, -0.5, 1, options=underflow | overflow))\n"
  46. " +------------------------------------------------------------+\n"
  47. "[-inf, -0.5) 0 | |\n"
  48. "[-0.5, 0) 1 |====== |\n"
  49. "[ 0, 0.5) 10 |=========================================================== |\n"
  50. "[ 0.5, 1) 5 |============================== |\n"
  51. "[ 1, inf) 0 | |\n"
  52. " +------------------------------------------------------------+\n"
  53. "END";
  54. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  55. }
  56. // regular, narrow
  57. {
  58. auto h = make(Tag(), R2(3, -0.5, 1.0));
  59. h.at(0) = 1;
  60. h.at(1) = 10;
  61. h.at(2) = 2;
  62. const auto expected = "BEGIN\n"
  63. "histogram(regular(3, -0.5, 1, options=none))\n"
  64. " +-----------------------+\n"
  65. "[-0.5, 0) 1 |== |\n"
  66. "[ 0, 0.5) 10 |====================== |\n"
  67. "[ 0.5, 1) 2 |==== |\n"
  68. " +-----------------------+\n"
  69. "END";
  70. BOOST_TEST_CSTR_EQ(expected, str(h, 40).c_str());
  71. // too narrow
  72. BOOST_TEST_CSTR_EQ("BEGIN\n"
  73. "histogram(regular(3, -0.5, 1, options=none))END",
  74. str(h, 10).c_str());
  75. }
  76. // regular2
  77. {
  78. auto h = make(Tag(), R2(3, -0.5, 1.0));
  79. h.at(0) = 1;
  80. h.at(1) = -5;
  81. h.at(2) = 2;
  82. const auto expected =
  83. "BEGIN\n"
  84. "histogram(regular(3, -0.5, 1, options=none))\n"
  85. " +-------------------------------------------------------------+\n"
  86. "[-0.5, 0) 1 | ========= |\n"
  87. "[ 0, 0.5) -5 |=========================================== |\n"
  88. "[ 0.5, 1) 2 | ================= |\n"
  89. " +-------------------------------------------------------------+\n"
  90. "END";
  91. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  92. }
  93. // regular with log
  94. {
  95. auto h = make(Tag(), R3(6, 1e-3, 1e3, "foo"));
  96. const auto expected =
  97. "BEGIN\n"
  98. "histogram(regular_log(6, 0.001, 1000, metadata=\"foo\", options=underflow | "
  99. "overflow))\n"
  100. " +-----------------------------------------------------------+\n"
  101. "[ 0, 0.001) 0 | |\n"
  102. "[0.001, 0.01) 0 | |\n"
  103. "[ 0.01, 0.1) 0 | |\n"
  104. "[ 0.1, 1) 0 | |\n"
  105. "[ 1, 10) 0 | |\n"
  106. "[ 10, 100) 0 | |\n"
  107. "[ 100, 1000) 0 | |\n"
  108. "[ 1000, inf) 0 | |\n"
  109. " +-----------------------------------------------------------+\n"
  110. "END";
  111. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  112. }
  113. // integer
  114. {
  115. auto h = make(Tag(), I(0, 1));
  116. h.at(0) = -10;
  117. h.at(1) = 5;
  118. const auto expected =
  119. "BEGIN\n"
  120. "histogram(integer(0, 1, options=underflow | overflow))\n"
  121. " +---------------------------------------------------------------------+\n"
  122. "-1 0 | |\n"
  123. " 0 -10 |============================================= |\n"
  124. " 1 5 | ======================= |\n"
  125. " +---------------------------------------------------------------------+\n"
  126. "END";
  127. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  128. }
  129. // catorgy<string>
  130. {
  131. auto h = make(Tag(), C({"a", "bb", "ccc", "dddd"}));
  132. h.at(0) = 1.23;
  133. h.at(1) = 1;
  134. h.at(2) = 1.2345789e-3;
  135. h.at(3) = 1.2345789e-12;
  136. h.at(4) = std::numeric_limits<double>::quiet_NaN();
  137. const auto expected =
  138. "BEGIN\n"
  139. "histogram(category(\"a\", \"bb\", \"ccc\", \"dddd\", options=overflow))\n"
  140. " +------------------------------------------------------------+\n"
  141. " a 1.23 |=========================================================== |\n"
  142. " bb 1 |================================================ |\n"
  143. " ccc 0.001235 | |\n"
  144. " dddd 1.235e-12 | |\n"
  145. "other nan | |\n"
  146. " +------------------------------------------------------------+\n"
  147. "END";
  148. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  149. }
  150. // histogram with axis that has no value method
  151. {
  152. struct minimal_axis {
  153. int index(int x) const { return x % 2; }
  154. int size() const { return 2; }
  155. };
  156. auto h = make(Tag(), minimal_axis{});
  157. h.at(0) = 3;
  158. h.at(1) = 4;
  159. const auto expected =
  160. "BEGIN\n"
  161. "histogram(<unstreamable>)\n"
  162. " +------------------------------------------------------------------------+\n"
  163. "0 3 |===================================================== |\n"
  164. "1 4 |======================================================================= |\n"
  165. " +------------------------------------------------------------------------+\n"
  166. "END";
  167. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  168. }
  169. // fallback for 2D
  170. {
  171. auto h = make(Tag(), R(1, -1, 1), R(2, -4, 7));
  172. h.at(-1, 0) = 1000;
  173. h.at(-1, -1) = 123;
  174. h.at(1, 0) = 1.23456789;
  175. h.at(-1, 2) = std::numeric_limits<double>::quiet_NaN();
  176. const auto expected =
  177. "BEGIN\n"
  178. "histogram(\n"
  179. " regular(1, -1, 1, options=underflow | overflow)\n"
  180. " regular(2, -4, 7, options=underflow | overflow)\n"
  181. " (-1 -1): 123 ( 0 -1): 0 ( 1 -1): 0 (-1 0): 1000 \n"
  182. " ( 0 0): 0 ( 1 0): 1.235 (-1 1): 0 ( 0 1): 0 \n"
  183. " ( 1 1): 0 (-1 2): nan ( 0 2): 0 ( 1 2): 0 \n"
  184. ")END";
  185. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  186. }
  187. // fallback for profile
  188. {
  189. auto h = make_s(Tag(), profile_storage(), R(1, -1, 1));
  190. h.at(0) = accumulators::mean<>(10, 100, 1000);
  191. const auto expected = "BEGIN\n"
  192. "histogram(\n"
  193. " regular(1, -1, 1, options=underflow | overflow)\n"
  194. " (-1): mean(0, 0, -0) ( 0): mean(10, 100, 1000)\n"
  195. " ( 1): mean(0, 0, -0) \n"
  196. ")END";
  197. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  198. }
  199. }
  200. int main() {
  201. run_tests<static_tag>();
  202. run_tests<dynamic_tag>();
  203. {
  204. // cannot make empty static histogram
  205. auto h = histogram<std::vector<axis::regular<>>>();
  206. const auto expected = "BEGIN\n"
  207. "histogram()END";
  208. BOOST_TEST_CSTR_EQ(expected, str(h).c_str());
  209. }
  210. return boost::report_errors();
  211. }