##// END OF EJS Templates
Creates method to compute resolutions of a dataset...
Alexandre Leroux -
r964:0db55d2147b1
parent child
Show More
@@ -1,80 +1,139
1 1 #ifndef SCIQLOP_DATASERIESUTILS_H
2 2 #define SCIQLOP_DATASERIESUTILS_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <QLoggingCategory>
7 7
8 8 Q_DECLARE_LOGGING_CATEGORY(LOG_DataSeriesUtils)
9 9
10 10 /**
11 11 * Utility class with methods for data series
12 12 */
13 13 struct SCIQLOP_CORE_EXPORT DataSeriesUtils {
14 14 /**
15 * Represents a resolution used to generate the data of a mesh on the x-axis or in Y.
16 *
17 * A resolution is represented by a value and flag indicating if it's in the logarithmic scale
18 * @sa Mesh
19 */
20 struct Resolution {
21 double m_Val{std::numeric_limits<double>::quiet_NaN()};
22 bool m_Logarithmic{false};
23 };
24
25 /**
15 26 * Processes data from a data series to complete the data holes with a fill value.
16 27 *
17 28 * A data hole is determined by the resolution passed in parameter: if, between two continuous
18 29 * data on the x-axis, the difference between these data is greater than the resolution, then
19 30 * there is one or more holes between them. The holes are filled by adding:
20 31 * - for the x-axis, new data corresponding to the 'step resolution' starting from the first
21 32 * data;
22 33 * - for values, a default value (fill value) for each new data added on the x-axis.
23 34 *
24 35 * For example, with :
25 36 * - xAxisData = [0, 1, 5, 7, 14 ]
26 37 * - valuesData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (two components per x-axis data)
27 38 * - fillValue = NaN
28 39 * - and resolution = 2;
29 40 *
30 41 * For the x axis, we calculate as data holes: [3, 9, 11, 13]. These holes are added to the
31 42 * x-axis data, and NaNs (two per x-axis data) are added to the values:
32 43 * => xAxisData = [0, 1, 3, 5, 7, 9, 11, 13, 14 ]
33 44 * => valuesData = [0, 1, 2, 3, NaN, NaN, 4, 5, 6, 7, NaN, NaN, NaN, NaN, NaN, NaN, 8, 9]
34 45 *
35 46 * It is also possible to set bounds for the data series. If these bounds are defined and exceed
36 47 * the limits of the data series, data holes are added to the series at the beginning and/or the
37 48 * end.
38 49 *
39 50 * The generation of data holes at the beginning/end of the data series is performed starting
40 51 * from the x-axis series limit and adding data holes at each 'resolution step' as long as the
41 52 * new bound is not reached.
42 53 *
43 54 * For example, with :
44 55 * - xAxisData = [3, 4, 5, 6, 7 ]
45 56 * - valuesData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
46 57 * - fillValue = NaN
47 58 * - minBound = 0
48 59 * - maxBound = 12
49 60 * - and resolution = 2;
50 61 *
51 62 * => Starting from 3 and decreasing 2 by 2 until reaching 0 : a data hole at value 1 will be
52 63 * added to the beginning of the series
53 64 * => Starting from 7 and increasing 2 by 2 until reaching 12 : data holes at values 9 and 11
54 65 * will be added to the end of the series
55 66 *
56 67 * So :
57 68 * => xAxisData = [1, 3, 4, 5, 6, 7, 9, 11 ]
58 69 * => valuesData = [NaN, NaN, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, NaN, NaN, NaN, NaN]
59 70 *
60 71 * @param xAxisData the x-axis data of the data series
61 72 * @param valuesData the values data of the data series
62 73 * @param resolution the resoultion (on x-axis) used to determinate data holes
63 74 * @param fillValue the fill value used for data holes in the values data
64 75 * @param minBound the limit at which to start filling data holes for the series. If set to NaN,
65 76 * the limit is not used
66 77 * @param maxBound the limit at which to end filling data holes for the series. If set to NaN,
67 78 * the limit is not used
68 79 *
69 80 * @remarks There is no control over the consistency between x-axis data and values data. The
70 81 * method considers that the data is well formed (the total number of values data is a multiple
71 82 * of the number of x-axis data)
72 83 */
73 84 static void fillDataHoles(std::vector<double> &xAxisData, std::vector<double> &valuesData,
74 85 double resolution,
75 86 double fillValue = std::numeric_limits<double>::quiet_NaN(),
76 87 double minBound = std::numeric_limits<double>::quiet_NaN(),
77 88 double maxBound = std::numeric_limits<double>::quiet_NaN());
89 /**
90 * Computes the resolution of a dataset passed as a parameter.
91 *
92 * The resolution of a dataset is the minimum difference between two values that follow in the
93 * set.
94 * For example:
95 * - for the set [0, 2, 4, 8, 10, 11, 13] => the resolution is 1 (difference between 10 and 11).
96 *
97 * A resolution can be calculated on the logarithmic scale (base of 10). In this case, the
98 * dataset is first converted to logarithmic values.
99 * For example:
100 * - for the set [10, 100, 10000, 1000000], the values are converted to [1, 2, 4, 6] => the
101 * logarithmic resolution is 1 (difference between 1 and 2).
102 *
103 * @param begin the iterator pointing to the beginning of the dataset
104 * @param end the iterator pointing to the end of the dataset
105 * @param logarithmic computes a logarithmic resolution or not
106 * @return the resolution computed
107 * @warning the method considers the dataset as sorted and doesn't control it.
108 */
109 template <typename Iterator>
110 static Resolution resolution(Iterator begin, Iterator end, bool logarithmic = false);
78 111 };
79 112
113 template <typename Iterator>
114 DataSeriesUtils::Resolution DataSeriesUtils::resolution(Iterator begin, Iterator end,
115 bool logarithmic)
116 {
117 // Retrieves data into a work dataset
118 using ValueType = typename Iterator::value_type;
119 std::vector<ValueType> values{};
120 std::copy(begin, end, std::back_inserter(values));
121
122 // Converts data if logarithmic flag is activated
123 if (logarithmic) {
124 std::for_each(values.begin(), values.end(),
125 [logarithmic](auto &val) { val = std::log10(val); });
126 }
127
128 // Computes the differences between the values in the dataset
129 std::adjacent_difference(values.begin(), values.end(), values.begin());
130
131 // Retrieves the smallest difference
132 auto resolutionIt = std::min_element(values.begin(), values.end());
133 auto resolution
134 = resolutionIt != values.end() ? *resolutionIt : std::numeric_limits<double>::quiet_NaN();
135
136 return Resolution{resolution, logarithmic};
137 }
138
80 139 #endif // SCIQLOP_DATASERIESUTILS_H
General Comments 0
You need to be logged in to leave comments. Login now