ChimeraTK-DeviceAccess  03.18.00
testFloatRawData.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2 // SPDX-License-Identifier: LGPL-3.0-or-later
3 
4 #define BOOST_TEST_DYN_LINK
5 #define BOOST_TEST_MODULE FloatRawDataTest
6 #include <boost/test/unit_test.hpp>
7 using namespace boost::unit_test_framework;
8 
9 /* This test is checking that IEE754 encoded single precision floats (32 bits) are transferred
10  * corretly to and from int32_t raw registers.
11  */
12 
13 #include "Device.h"
14 using namespace ChimeraTK;
15 
16 BOOST_AUTO_TEST_CASE(testCatalogueEntries) {
17  Device d;
18  d.open("(dummy?map=floatRawTest.map)");
19 
20  auto registerCatalogue = d.getRegisterCatalogue();
21  auto scalarInfo = registerCatalogue.getRegister("FLOAT_TEST/SCALAR");
22 
23  BOOST_CHECK_EQUAL(scalarInfo.getRegisterName(), "FLOAT_TEST/SCALAR");
24  BOOST_CHECK_EQUAL(scalarInfo.getNumberOfElements(), 1);
25  BOOST_CHECK_EQUAL(scalarInfo.getNumberOfChannels(), 1);
26  BOOST_CHECK_EQUAL(scalarInfo.getNumberOfDimensions(), 0);
27  BOOST_CHECK(scalarInfo.isReadable());
28  BOOST_CHECK(scalarInfo.isWriteable());
29 
30  BOOST_CHECK(scalarInfo.getSupportedAccessModes() == AccessModeFlags({AccessMode::raw}));
31 
32  auto dataDescriptor = scalarInfo.getDataDescriptor();
33  BOOST_CHECK(dataDescriptor.fundamentalType() == DataDescriptor::FundamentalType::numeric);
34  BOOST_CHECK(dataDescriptor.isSigned());
35  BOOST_CHECK(dataDescriptor.isIntegral() == false);
36  BOOST_CHECK_EQUAL(dataDescriptor.nDigits(), 48);
37  BOOST_CHECK_EQUAL(dataDescriptor.nFractionalDigits(), 45);
38  BOOST_CHECK_EQUAL(dataDescriptor.rawDataType(), DataType::int32);
39  // FIXME: the following should be int32, but this layer is not accessible through the interface anyway.
40  BOOST_CHECK_EQUAL(dataDescriptor.transportLayerDataType(), DataType::none);
41 }
42 
43 BOOST_AUTO_TEST_CASE(testReading) {
44  Device d;
45  d.open("(dummy?map=floatRawTest.map)");
46 
47  // There are two ways to check what is going on in the dummy (we want to go back there and check that is ends up
48  // correctly)
49  // 1. We get the dummy backend and use DummyRegisterAccessors
50  // 2. We use "integer" accessors pointing to the same memory, which have already been tested and we know that they
51  // work Here we use the second approach.
52  auto rawIntAccessor = d.getScalarRegisterAccessor<int32_t>("FLOAT_TEST/SCALAR_AS_INT", 0, {AccessMode::raw});
53  rawIntAccessor = 0x40700000; // IEE754 bit representation of 3.75
54  rawIntAccessor.write();
55 
56  auto floatAccessor = d.getScalarRegisterAccessor<float>("FLOAT_TEST/SCALAR");
57  floatAccessor.read();
58  BOOST_CHECK_CLOSE(float(floatAccessor), 3.75, 0.0001);
59 
60  auto doubleAccessor = d.getScalarRegisterAccessor<double>("FLOAT_TEST/SCALAR");
61  doubleAccessor.read();
62  BOOST_CHECK_CLOSE(double(doubleAccessor), 3.75, 0.0001);
63 
64  auto intAccessor = d.getScalarRegisterAccessor<int32_t>("FLOAT_TEST/SCALAR");
65  intAccessor.read();
66  BOOST_CHECK_EQUAL(int32_t(intAccessor), 4);
67 
68  auto stringAccessor = d.getScalarRegisterAccessor<std::string>("FLOAT_TEST/SCALAR");
69  stringAccessor.read();
70  BOOST_CHECK_EQUAL(std::string(stringAccessor), std::to_string(3.75));
71 
72  auto rawAccessor = d.getScalarRegisterAccessor<int32_t>("FLOAT_TEST/SCALAR", 0, {AccessMode::raw});
73  rawAccessor.read();
74  BOOST_CHECK_EQUAL(int32_t(rawAccessor), 0x40700000);
75  BOOST_CHECK_CLOSE(rawAccessor.getAsCooked<float>(), 3.75, 0.0001);
76 }
77 
78 void checkAsRaw(int32_t rawValue, float expectedValue) {
79  void* warningAvoider = &rawValue;
80  float testValue = *(reinterpret_cast<float*>(warningAvoider));
81 
82  BOOST_CHECK_CLOSE(testValue, expectedValue, 0.0001);
83 }
84 
85 BOOST_AUTO_TEST_CASE(testWriting) {
86  Device d;
87  d.open("(dummy?map=floatRawTest.map)");
88 
89  auto floatAccessor = d.getOneDRegisterAccessor<float>("FLOAT_TEST/ARRAY");
90  floatAccessor[0] = 1.23;
91  floatAccessor[1] = 2.23;
92  floatAccessor[2] = 3.23;
93  floatAccessor[3] = 4.23;
94  floatAccessor.write();
95 
96  auto rawIntAccessor = d.getOneDRegisterAccessor<int32_t>("FLOAT_TEST/ARRAY_AS_INT", 0, 0, {AccessMode::raw});
97  rawIntAccessor.read();
98  checkAsRaw(rawIntAccessor[0], 1.23);
99  checkAsRaw(rawIntAccessor[1], 2.23);
100  checkAsRaw(rawIntAccessor[2], 3.23);
101  checkAsRaw(rawIntAccessor[3], 4.23);
102 
103  auto doubleAccessor = d.getOneDRegisterAccessor<double>("FLOAT_TEST/ARRAY");
104  doubleAccessor[0] = 11.23;
105  doubleAccessor[1] = 22.23;
106  doubleAccessor[2] = 33.23;
107  doubleAccessor[3] = 44.23;
108  doubleAccessor.write();
109 
110  rawIntAccessor.read();
111  checkAsRaw(rawIntAccessor[0], 11.23);
112  checkAsRaw(rawIntAccessor[1], 22.23);
113  checkAsRaw(rawIntAccessor[2], 33.23);
114  checkAsRaw(rawIntAccessor[3], 44.23);
115 
116  auto intAccessor = d.getOneDRegisterAccessor<int>("FLOAT_TEST/ARRAY");
117  intAccessor[0] = 1;
118  intAccessor[1] = 2;
119  intAccessor[2] = 3;
120  intAccessor[3] = 4;
121  intAccessor.write();
122 
123  rawIntAccessor.read();
124  checkAsRaw(rawIntAccessor[0], 1.);
125  checkAsRaw(rawIntAccessor[1], 2.);
126  checkAsRaw(rawIntAccessor[2], 3.);
127  checkAsRaw(rawIntAccessor[3], 4.);
128 
129  auto stringAccessor = d.getOneDRegisterAccessor<std::string>("FLOAT_TEST/ARRAY");
130  stringAccessor[0] = "17.4";
131  stringAccessor[1] = "17.5";
132  stringAccessor[2] = "17.6";
133  stringAccessor[3] = "17.7";
134  stringAccessor.write();
135 
136  rawIntAccessor.read();
137  checkAsRaw(rawIntAccessor[0], 17.4);
138  checkAsRaw(rawIntAccessor[1], 17.5);
139  checkAsRaw(rawIntAccessor[2], 17.6);
140  checkAsRaw(rawIntAccessor[3], 17.7);
141 }
ChimeraTK::Device::getOneDRegisterAccessor
OneDRegisterAccessor< UserType > getOneDRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfWords=0, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a OneDRegisterAccessor object for the given register.
Definition: Device.h:273
checkAsRaw
void checkAsRaw(int32_t rawValue, float expectedValue)
Definition: testFloatRawData.cpp:78
ChimeraTK::RegisterCatalogue::getRegister
RegisterInfo getRegister(const RegisterPath &registerPathName) const
Get register information for a given full path name.
Definition: RegisterCatalogue.cc:43
Device.h
ChimeraTK::Device::getRegisterCatalogue
RegisterCatalogue getRegisterCatalogue() const
Return the register catalogue with detailed information on all registers.
Definition: Device.cc:22
ChimeraTK::Device
Class allows to read/write registers from device.
Definition: Device.h:39
ChimeraTK::Device::open
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition: Device.cc:58
ChimeraTK::Device::getScalarRegisterAccessor
ScalarRegisterAccessor< UserType > getScalarRegisterAccessor(const RegisterPath &registerPathName, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a ScalarRegisterObject object for the given register.
Definition: Device.h:263
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(testCatalogueEntries)
Definition: testFloatRawData.cpp:16
ChimeraTK::AccessModeFlags
Set of AccessMode flags with additional functionality for an easier handling.
Definition: AccessMode.h:48
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::to_string
std::string to_string(Boolean &value)
Definition: SupportedUserTypes.h:59