lib/mdflib/docs/manual/html/ichannelconversion_8h_source.html
| MDF Lib 2.2
Interface against MDF 3/4 files |
Loading...
Searching...
No Matches
ichannelconversion.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 Ingemar Hedvall
3 * SPDX-License-Identifier: MIT
4 */
5
10#pragma once
11#include <optional>
12#include <sstream>
13#include <string>
14#include <vector>
15#include <variant>
16
17#include "mdf/iblock.h"
18#include "mdf/imetadata.h"
19#include "mdf/mdfhelper.h"
20
21namespace mdf {
22
29enum class ConversionType : uint8_t {
31NoConversion = 0,
32
36Linear = 1,
37
42Rational = 2,
43Algebraic = 3,
44
49ValueToValueInterpolation = 4,
50
55ValueToValue = 5,
56
62ValueRangeToValue = 6,
63
70ValueToText = 7,
71
78ValueRangeToText = 8,
79
84TextToValue = 9,
85
91TextToTranslation = 10,
92
96BitfieldToText = 11,
97// MDF 3 types
98Polynomial = 30,
99Exponential = 31,
100Logarithmic = 32,
101DateConversion = 33,
102TimeConversion = 34
103};
104
108struct TextConversion {
111};
112
116struct TextRangeConversion {
121};
122
126namespace CcFlag {
127constexpr uint16_t PrecisionValid = 0x0001;
128constexpr uint16_t RangeValid = 0x0002;
129constexpr uint16_t StatusString = 0x0004;
130} // namespace CcFlag
131
142class IChannelConversion : public IBlock {
143
144 public:
145~IChannelConversion() override = default;
146
147virtual void Name(const std::string& name);
148 [[nodiscard]] virtual std::string Name() const;
149
150virtual void Description(const std::string& desc);
151 [[nodiscard]] virtual std::string Description() const;
152
153virtual void Unit(const std::string& unit) = 0;
154 [[nodiscard]] virtual std::string Unit() const = 0;
155 [[nodiscard]] virtual bool IsUnitValid() const = 0;
156
157virtual void Type(ConversionType type) = 0;
158 [[nodiscard]] virtual ConversionType Type() const = 0;
159
160 [[nodiscard]] virtual bool IsDecimalUsed()
161const = 0;
162virtual void Decimals(uint8_t decimals);
163 [[nodiscard]] virtual uint8_t Decimals() const = 0;
164
166 [[nodiscard]] virtual IChannelConversion* CreateInverse();
167
169 [[nodiscard]] virtual IChannelConversion* Inverse() const;
170
171virtual void Range(double min, double max);
172 [[nodiscard]] virtual std::optional<std::pair<double, double>> Range()
173const;
174
175virtual void Flags(uint16_t flags);
176 [[nodiscard]] virtual uint16_t Flags() const;
177
179 [[nodiscard]] virtual IMetaData* CreateMetaData();
180
182 [[nodiscard]] virtual IMetaData* MetaData() const;
183
185virtual void Formula( const std::string& formula);
187 [[nodiscard]] virtual const std::string& Formula() const;
188
190 [[nodiscard]] uint16_t NofParameters() const;
191
197void Parameter(uint16_t index, double parameter);
198
204 [[nodiscard]] double Parameter(uint16_t index) const;
205
211 [[nodiscard]] uint64_t ParameterUint(uint16_t index) const;
217void ParameterUint(uint16_t index, uint64_t parameter);
218
220 [[nodiscard]] virtual uint16_t NofReferences() const;
221
227virtual void Reference(uint16_t index, const std::string& text);
228
230 [[nodiscard]] virtual std::string Reference(uint16_t index) const;
231
237void ChannelDataType(uint8_t channel_data_type);
238
248template <typename T, typename V>
249bool Convert(const T& channel_value, V& eng_value) const;
250
261template <typename T, typename V = std::string>
262bool Convert(const T& channel_value, std::string& eng_value) const;
263
265template <typename T = std::string, typename V = double>
266bool Convert(const std::string& channel_value, double& eng_value) const;
267
269template <typename T = std::string, typename V = std::string>
270bool Convert(const std::string& channel_value, std::string& eng_value) const {
271if (Type() == ConversionType::TextToTranslation) {
272ConvertTextToTranslation(channel_value, eng_value);
273 } else if (Type() == ConversionType::NoConversion) {
274 eng_value = channel_value;
275 } else {
276return false;
277 }
278return true;
279 }
280
281 protected:
282 uint16_t nof_values_ = 0;
283
285using ParameterList = std::vector<std::variant<uint64_t, double>>;
286
288 uint8_t channel_data_type_ =
289 0;
290
291// The formula and conversion list is used in MDF 3 while MDF4
292// uses the reference list.
293mutable std::string formula_;
294 std::vector<TextConversion> text_conversion_list_;
295 std::vector<TextRangeConversion> text_range_conversion_list_;
296
297 [[nodiscard]] bool IsChannelInteger()
298const;
299 [[nodiscard]] bool IsChannelFloat()
300const;
301
302virtual bool ConvertLinear(double channel_value, double& eng_value)
303const;
304virtual bool ConvertRational(double channel_value, double& eng_value)
305const;
306virtual bool ConvertAlgebraic(double channel_value, double& eng_value)
307const;
308virtual bool ConvertValueToValueInterpolate(double channel_value,
309double& eng_value) const;
310virtual bool ConvertValueToValue(double channel_value,
311double& eng_value) const;
312virtual bool ConvertValueRangeToValue(double channel_value,
313double& eng_value) const;
314
315virtual bool ConvertValueToText(double channel_value,
316 std::string& eng_value) const;
317virtual bool ConvertValueRangeToText(double channel_value,
318 std::string& eng_value) const;
319virtual bool ConvertTextToValue(const std::string& channel_value,
320double& eng_value) const;
321virtual bool ConvertTextToTranslation(const std::string& channel_value,
322 std::string& eng_value) const;
323virtual bool ConvertPolynomial(double channel_value, double& eng_value)
324const;
325virtual bool ConvertLogarithmic(double channel_value,
326double& eng_value) const;
327virtual bool ConvertExponential(double channel_value,
328double& eng_value) const;
329};
330
331template <typename T, typename V>
332inline bool IChannelConversion::Convert(const T& channel_value,
333 V& eng_value) const {
334bool valid = false;
335double value = 0.0;
336switch (Type()) {
337case ConversionType::Linear: {
338 valid = ConvertLinear(static_cast<double>(channel_value), value);
339 eng_value = static_cast<V>(value);
340break;
341 }
342
343case ConversionType::Rational: {
344 valid = ConvertRational(static_cast<double>(channel_value), value);
345 eng_value = static_cast<V>(value);
346break;
347 }
348
349case ConversionType::Algebraic: {
350 valid = ConvertAlgebraic(static_cast<double>(channel_value), value);
351 eng_value = static_cast<V>(value);
352break;
353 }
354
355case ConversionType::ValueToValueInterpolation: {
356 valid = ConvertValueToValueInterpolate(
357static_cast<double>(channel_value), value);
358 eng_value = static_cast<V>(value);
359break;
360 }
361
362case ConversionType::ValueToValue: {
363 valid = ConvertValueToValue(static_cast<double>(channel_value), value);
364 eng_value = static_cast<V>(value);
365break;
366 }
367
368case ConversionType::ValueRangeToValue: {
369 valid =
370ConvertValueRangeToValue(static_cast<double>(channel_value), value);
371 eng_value = static_cast<V>(value);
372break;
373 }
374
375case ConversionType::ValueToText: {
376 std::string text;
377 valid = ConvertValueToText(static_cast<double>(channel_value), text);
378 std::istringstream s(text);
379 s >> eng_value;
380break;
381 }
382
383case ConversionType::ValueRangeToText: {
384 std::string text;
385 valid =
386ConvertValueRangeToText(static_cast<double>(channel_value), text);
387 std::istringstream s(text);
388 s >> eng_value;
389break;
390 }
391
392case ConversionType::Polynomial: {
393 valid = ConvertPolynomial(static_cast<double>(channel_value), value);
394 eng_value = static_cast<V>(value);
395break;
396 }
397
398case ConversionType::Exponential: {
399 valid = ConvertExponential(static_cast<double>(channel_value), value);
400 eng_value = static_cast<V>(value);
401break;
402 }
403
404case ConversionType::Logarithmic: {
405 valid = ConvertLogarithmic(static_cast<double>(channel_value), value);
406 eng_value = static_cast<V>(value);
407break;
408 }
409case ConversionType::NoConversion:
410default: {
411 eng_value = static_cast<V>(channel_value);
412 valid = true;
413break;
414 }
415 }
416return valid;
417}
418
419template <typename T, typename V>
420inline bool IChannelConversion::Convert(const T& channel_value,
421 std::string& eng_value) const {
422bool valid = false;
423double value = 0.0;
424switch (Type()) {
425case ConversionType::Linear: {
426 valid = ConvertLinear(static_cast<double>(channel_value), value);
427 eng_value =
428MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
429break;
430 }
431
432case ConversionType::Rational: {
433 valid = ConvertRational(static_cast<double>(channel_value), value);
434 eng_value =
435MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
436break;
437 }
438
439case ConversionType::Algebraic: {
440 valid = ConvertAlgebraic(static_cast<double>(channel_value), value);
441 eng_value =
442MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
443break;
444 }
445
446case ConversionType::ValueToValueInterpolation: {
447 valid = ConvertValueToValueInterpolate(
448static_cast<double>(channel_value), value);
449 eng_value =
450MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
451break;
452 }
453
454case ConversionType::ValueToValue: {
455 valid = ConvertValueToValue(static_cast<double>(channel_value), value);
456 eng_value =
457MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
458break;
459 }
460
461case ConversionType::ValueRangeToValue: {
462 valid =
463ConvertValueRangeToValue(static_cast<double>(channel_value), value);
464 eng_value =
465MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
466break;
467 }
468
469case ConversionType::ValueToText: {
470 valid =
471ConvertValueToText(static_cast<double>(channel_value), eng_value);
472break;
473 }
474
475case ConversionType::ValueRangeToText: {
476 valid = ConvertValueRangeToText(static_cast<double>(channel_value),
477 eng_value);
478break;
479 }
480
481case ConversionType::Polynomial: {
482 valid = ConvertPolynomial(static_cast<double>(channel_value), value);
483 eng_value =
484MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
485break;
486 }
487
488case ConversionType::Exponential: {
489 valid = ConvertExponential(static_cast<double>(channel_value), value);
490 eng_value =
491MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
492break;
493 }
494
495case ConversionType::Logarithmic: {
496 valid = ConvertLogarithmic(static_cast<double>(channel_value), value);
497 eng_value =
498MdfHelper::FormatDouble(value, IsDecimalUsed() ? Decimals() : 6);
499break;
500 }
501
502case ConversionType::NoConversion:
503default: {
504 eng_value = MdfHelper::FormatDouble(static_cast<double>(channel_value),
505IsDecimalUsed() ? Decimals() : 6);
506 valid = true;
507break;
508 }
509 }
510return valid;
511}
512
513template <typename T, typename V>
514bool IChannelConversion::Convert(const std::string& channel_value,
515double& eng_value) const {
516if (Type() == ConversionType::TextToValue) {
517ConvertTextToValue(channel_value, eng_value);
518 } else if (Type() == ConversionType::NoConversion) {
519 eng_value = std::stod(channel_value);
520 } else {
521return false;
522 }
523return true;
524}
525
526} // namespace mdf
Base class for all MDF blocks.
Definition iblock.h:19
Defines a channel conversion (CC) block.
Definition ichannelconversion.h:142
mdf::IChannelConversion::Decimals
virtual uint8_t Decimals() const =0
Number of decimals.
mdf::IChannelConversion::Range
virtual std::optional< std::pair< double, double > > Range() const
Returns the range if exist.
mdf::IChannelConversion::ConvertValueToValueInterpolate
virtual bool ConvertValueToValueInterpolate(double channel_value, double &eng_value) const
Value to value interpolation conversion.
virtual std::string Name() const
Name.
mdf::IChannelConversion::IsChannelInteger
bool IsChannelInteger() const
Returns true if channel is an integer.
mdf::IChannelConversion::ConvertRational
virtual bool ConvertRational(double channel_value, double &eng_value) const
Rational conversion.
mdf::IChannelConversion::Range
virtual void Range(double min, double max)
Sets the range.
mdf::IChannelConversion::IsDecimalUsed
virtual bool IsDecimalUsed() const =0
True if decimal is used.
mdf::IChannelConversion::ConvertExponential
virtual bool ConvertExponential(double channel_value, double &eng_value) const
Exponential conversion (MDF3).
mdf::IChannelConversion::Flags
virtual void Flags(uint16_t flags)
Sets the CcFlag.
mdf::IChannelConversion::ConvertTextToValue
virtual bool ConvertTextToValue(const std::string &channel_value, double &eng_value) const
Text to value conversion.
mdf::IChannelConversion::ConvertValueToText
virtual bool ConvertValueToText(double channel_value, std::string &eng_value) const
Value to text conversion.
mdf::IChannelConversion::ConvertLogarithmic
virtual bool ConvertLogarithmic(double channel_value, double &eng_value) const
Logarithmic conversion (MDF3).
mdf::IChannelConversion::nof_values_
uint16_t nof_values_
Number of parameter values (MDF3).
Definition ichannelconversion.h:282
virtual std::string Unit() const =0
Unit of measure.
virtual void Unit(const std::string &unit)=0
Sets the unit.
mdf::IChannelConversion::Parameter
double Parameter(uint16_t index) const
Returns the parameter (double)
mdf::IChannelConversion::text_conversion_list_
std::vector< TextConversion > text_conversion_list_
MDF3.
Definition ichannelconversion.h:294
mdf::IChannelConversion::IsUnitValid
virtual bool IsUnitValid() const =0
True if unit exist.
mdf::IChannelConversion::formula_
std::string formula_
Formula string (MDF3).
Definition ichannelconversion.h:293
mdf::IChannelConversion::Reference
virtual void Reference(uint16_t index, const std::string &text)
Sets text reference (TX) block.
mdf::IChannelConversion::ConvertTextToTranslation
virtual bool ConvertTextToTranslation(const std::string &channel_value, std::string &eng_value) const
Text to text conversion.
mdf::IChannelConversion::Convert
bool Convert(const T &channel_value, V &eng_value) const
Converts a channel value to an engineering (scaled) value.
Definition ichannelconversion.h:332
virtual ConversionType Type() const =0
Conversion type.
mdf::IChannelConversion::ParameterUint
uint64_t ParameterUint(uint16_t index) const
Returns the parameter as a bit field (uint64_t)
mdf::IChannelConversion::Formula
virtual void Formula(const std::string &formula)
Sets the formula string.
mdf::IChannelConversion::ConvertAlgebraic
virtual bool ConvertAlgebraic(double channel_value, double &eng_value) const
Algebraic conversion.
mdf::IChannelConversion::ConvertValueRangeToText
virtual bool ConvertValueRangeToText(double channel_value, std::string &eng_value) const
Value range to text value.
mdf::IChannelConversion::ConvertValueToValue
virtual bool ConvertValueToValue(double channel_value, double &eng_value) const
Value to value conversion.
mdf::IChannelConversion::NofReferences
virtual uint16_t NofReferences() const
Number of references in the block.
mdf::IChannelConversion::Decimals
virtual void Decimals(uint8_t decimals)
Sets number of decimals.
mdf::IChannelConversion::value_list_
ParameterList value_list_
List of parameters.
Definition ichannelconversion.h:287
mdf::IChannelConversion::Formula
virtual const std::string & Formula() const
Returns formula string.
mdf::IChannelConversion::text_range_conversion_list_
std::vector< TextRangeConversion > text_range_conversion_list_
MDF3.
Definition ichannelconversion.h:295
mdf::IChannelConversion::Flags
virtual uint16_t Flags() const
Returns CcFlag.
mdf::IChannelConversion::ParameterList
std::vector< std::variant< uint64_t, double > > ParameterList
List of floating point constants.
Definition ichannelconversion.h:285
mdf::IChannelConversion::Parameter
void Parameter(uint16_t index, double parameter)
Sets a floating point parameter value.
mdf::IChannelConversion::Reference
virtual std::string Reference(uint16_t index) const
Returns the reference string by its index.
mdf::IChannelConversion::channel_data_type_
uint8_t channel_data_type_
The channels data type. Needed by some conversions.
Definition ichannelconversion.h:288
mdf::IChannelConversion::ConvertLinear
virtual bool ConvertLinear(double channel_value, double &eng_value) const
Linear conversion.
mdf::IChannelConversion::IsChannelFloat
bool IsChannelFloat() const
Returns true if the channel is a float.
mdf::IChannelConversion::MetaData
virtual IMetaData * MetaData() const
Returns the meta-data block.
mdf::IChannelConversion::ChannelDataType
void ChannelDataType(uint8_t channel_data_type)
Sets the CN block data type.
mdf::IChannelConversion::NofParameters
uint16_t NofParameters() const
Returns number of parameters in the block.
mdf::IChannelConversion::Convert
bool Convert(const std::string &channel_value, std::string &eng_value) const
Converts from string to string.
Definition ichannelconversion.h:270
mdf::IChannelConversion::Description
virtual void Description(const std::string &desc)
Sets the description.
mdf::IChannelConversion::ParameterUint
void ParameterUint(uint16_t index, uint64_t parameter)
Sets an unsigned integer parameter value.
mdf::IChannelConversion::Inverse
virtual IChannelConversion * Inverse() const
Returns the inverse conversion block. Seldom in use.
mdf::IChannelConversion::ConvertValueRangeToValue
virtual bool ConvertValueRangeToValue(double channel_value, double &eng_value) const
Value range to value conversion.
mdf::IChannelConversion::CreateInverse
virtual IChannelConversion * CreateInverse()
Creates an inverse conversion block.
mdf::IChannelConversion::CreateMetaData
virtual IMetaData * CreateMetaData()
Creates a meta-data (MD) block.
virtual void Type(ConversionType type)=0
Sets the conversion type.
virtual void Name(const std::string &name)
Sets the CC name.
mdf::IChannelConversion::ConvertPolynomial
virtual bool ConvertPolynomial(double channel_value, double &eng_value) const
Polynomial conversion (MDF3).
mdf::IChannelConversion::Description
virtual std::string Description() const
Description.
Interface against an meta data block (MD) in a MDF4 file.
Definition imetadata.h:27
static std::string FormatDouble(double value, uint8_t decimals, bool fixed=false, const std::string &unit={})
Converts a float to a string.
All MDF blocks inherits from the IBlock class. The interface class is used internally in lists....
Support class for the MDF library.
constexpr uint16_t StatusString
Status string flag.
Definition ichannelconversion.h:129
constexpr uint16_t PrecisionValid
Precision is used.
Definition ichannelconversion.h:127
constexpr uint16_t RangeValid
Range is used.
Definition ichannelconversion.h:128
Main namespace for the MDF library.
Definition canmessage.h:17
ConversionType
Type of conversion formula.
Definition ichannelconversion.h:29
mdf::ConversionType::TextToTranslation
@ TextToTranslation
Text to text conversion. Defines a list of text string to text conversion. Ref(2*n) key to Ref(2*(n+1...
mdf::ConversionType::BitfieldToText
@ BitfieldToText
Bitfield to text conversion Currently unsupported conversion.
@ Rational
Rational function conversion. 6 parameters. Eng = (Par(0)*Ch^2 + Par(1)*Ch + Par(2)) / (Par(3)*Ch^2 +...
mdf::ConversionType::ValueToValue
@ ValueToValue
Value to value conversion without interpolation. Defined by a list of Key value pairs....
mdf::ConversionType::Polynomial
@ Polynomial
MDF 3 polynomial conversion.
mdf::ConversionType::NoConversion
@ NoConversion
1:1 conversion. No parameters needed.
mdf::ConversionType::Logarithmic
@ Logarithmic
MDF 3 logarithmic conversion.
@ Linear
Linear conversion. 2 parameters. Eng = Ch * Par(1) + Par(0).
mdf::ConversionType::ValueToText
@ ValueToText
Value to text conversion. Defined by a list of key values to text string conversions....
mdf::ConversionType::TextToValue
@ TextToValue
Text to value conversion. Defines a list of text string to value conversion. Ref(n) key to Par(n) val...
mdf::ConversionType::ValueToValueInterpolation
@ ValueToValueInterpolation
Value to value conversion with interpolation. Defined by a list of Key value pairs....
mdf::ConversionType::TimeConversion
@ TimeConversion
MDF 3 Time conversion.
mdf::ConversionType::DateConversion
@ DateConversion
MDF 3 Date conversion.
mdf::ConversionType::Algebraic
@ Algebraic
Text formula.
mdf::ConversionType::Exponential
@ Exponential
MDF 3 exponential conversion.
mdf::ConversionType::ValueRangeToText
@ ValueRangeToText
Value range to text conversion. Defined by a list of key min/max values to text string conversions....
mdf::ConversionType::ValueRangeToValue
@ ValueRangeToValue
Value range to value conversion without interpolation. Defined by a list of Key min/max value triplet...
MDF 3 text conversion structure. Not used in MDF 4. Key to text conversion.
Definition ichannelconversion.h:108
std::string text
Text string.
Definition ichannelconversion.h:110
double value
Key.
Definition ichannelconversion.h:109
MDF 3 range conversion structure. Not used in MDF 4. Key min/max to text conversion.
Definition ichannelconversion.h:116
mdf::TextRangeConversion::upper
double upper
Key max value.
Definition ichannelconversion.h:118
mdf::TextRangeConversion::link_text
uint32_t link_text
File position of the text value.
Definition ichannelconversion.h:119
mdf::TextRangeConversion::text
std::string text
The text value.
Definition ichannelconversion.h:120
mdf::TextRangeConversion::lower
double lower
Key min value.
Definition ichannelconversion.h:117