ChimeraTK-DeviceAccess  03.18.00
testMappedImage.cc
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 MappedImageTest
6 
7 #include "Device.h"
8 #include "MappedImage.h"
9 #include "OneDRegisterAccessor.h"
10 
11 #include <boost/test/unit_test.hpp>
12 
13 using namespace boost::unit_test_framework;
14 using namespace ChimeraTK;
15 
16 BOOST_AUTO_TEST_SUITE(MappedImageTestSuite)
17 
18 struct DummyFixture {
19  unsigned bufLen = 100; // includes header: 64 bytes
22  setDMapFilePath("testMappedImage.dmap");
23  Device device;
24  device.open("DUMMY");
25 
26  buf.replace(device.getOneDRegisterAccessor<unsigned char>("DAQ/IMAGE", bufLen));
27  }
28 };
29 
31  // this test shows an example how to map user-defined opaque structs onto a byte array
32  struct AStruct : public OpaqueStructHeader {
33  int a = 0;
34  float x = 0, y = 1;
35  AStruct() : OpaqueStructHeader(typeid(AStruct)) {}
36  };
37 
39  auto* h = ms.header();
40  h->x = 4.;
41  BOOST_CHECK(h->totalLength == sizeof(AStruct));
42 
44  BOOST_CHECK(ms1.header()->x == 4.);
45  BOOST_CHECK(ms1.header()->y == 1.); // a value set in constructor of AStruct
46 
47  buf.write();
48  // test that values can be restored by reading from device
49  ms.header()->x = 0;
50  buf.read();
51  BOOST_CHECK(ms.header()->x == 4.);
52 }
53 
55  // this test shows MappedImage usage
56 
57  MappedImage A0(buf);
58  unsigned w = 4, h = 2;
59  A0.setShape(w, h, ImgFormat::Gray16);
60  auto Av = A0.interpretedView<uint16_t>();
61  Av(0, 0) = 8;
62  Av(1, 0) = 7;
63  Av(2, 0) = 6;
64  Av(3, 0) = 5;
65  Av(0, 1) = 4;
66  Av(1, 1) = 3;
67  Av(2, 1) = 2;
68  Av(3, 1) = 1;
69  float val = Av(2, 0);
70  BOOST_CHECK(val == 6);
71 
72  // also test iterator-style access
73  for(unsigned y = 0; y < h; y++) {
74  unsigned x = 0;
75  for(auto* it = Av.beginRow(y); it != Av.endRow(y); ++it) {
76  BOOST_CHECK(*it == Av(x, y));
77  x++;
78  }
79  }
80  // iterate over whole image
81  unsigned counter = 0;
82  for(auto& pixVal : Av) {
83  pixVal = ++counter;
84  }
85  counter = 0;
86  for(auto& pixVal : Av) {
87  counter++;
88  BOOST_CHECK(pixVal == counter);
89  }
90 
91  // test actual header contents of our buffer
92  auto* bufData0 = buf.data();
93  auto* head = reinterpret_cast<ImgHeader*>(bufData0);
94  BOOST_CHECK(head->width == w);
95  BOOST_CHECK(head->height == h);
96  BOOST_CHECK(head->image_format == ImgFormat::Gray16);
97  BOOST_CHECK(head->channels == 1);
98  BOOST_CHECK(head->bytesPerPixel == 2);
99 
100  // test actual image body contents of buffer
101  auto* imgBody = reinterpret_cast<uint16_t*>(buf.data() + sizeof(ImgHeader));
102  unsigned i = 0;
103  for(auto& pixVal : Av) {
104  BOOST_CHECK(imgBody[i] == pixVal);
105  i++;
106  }
107 
108  ImgHeader head0 = *head;
109  buf.write(); // this allows to analyse data in dummy device, e.g. with shm dummy
110  // set up memory location buf1 with slightly modified image content
111  std::vector<unsigned char> buf1(buf.getNElements());
112  *reinterpret_cast<ImgHeader*>(buf1.data()) = head0; // copy back header
113  auto* imgBody1 = reinterpret_cast<uint16_t*>(buf1.data() + sizeof(ImgHeader));
114  imgBody1[w * h - 1] = 42;
115  buf.swap(buf1);
116  BOOST_CHECK(buf.data() != bufData0);
117  // check that ImgView can still be used, even though user buffer of accessor was swapped
118  // compare bottow right value with previously written content.
119  auto lastVal = Av(w - 1, h - 1);
120  BOOST_CHECK(lastVal == 42);
121 
122  // re-use as float and check pixel channel access
123  A0.setShape(2, 1, ImgFormat::FLOAT2);
124  auto AvFloat2 = A0.interpretedView<float>();
125  AvFloat2(0, 0, 1) = 0.1F;
126  AvFloat2(1, 0, 1) = 1.1F;
127  BOOST_TEST(AvFloat2(0, 0, 1) == 0.1F);
128  BOOST_TEST(AvFloat2(1, 0, 1) == 1.1F);
129 }
130 
131 BOOST_AUTO_TEST_SUITE_END()
device
ctk::Device device
Definition: testExceptionDummyDevice.cc:18
DummyFixture::buf
ChimeraTK::OneDRegisterAccessor< unsigned char > buf
Definition: testMappedImage.cc:20
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
OneDRegisterAccessor.h
DummyFixture::DummyFixture
DummyFixture()
Definition: testMappedImage.cc:21
BOOST_FIXTURE_TEST_CASE
BOOST_FIXTURE_TEST_CASE(testStructMapping, DummyFixture)
Definition: testMappedImage.cc:30
ChimeraTK::MappedImage::setShape
void setShape(unsigned width, unsigned height, ImgFormat fmt)
needs to be called after construction.
Definition: MappedImage.h:260
F
Definition: testRebotConnectionTimeouts.cpp:20
MappedImage.h
ChimeraTK::NDRegisterAccessorAbstractor::replace
void replace(const NDRegisterAccessorAbstractor< UserType > &newAccessor)
Assign a new accessor to this NDRegisterAccessorAbstractor.
Definition: NDRegisterAccessorAbstractor.h:67
ChimeraTK::OneDRegisterAccessor< unsigned char >
ChimeraTK::MappedStruct
Provides interface to a struct that is mapped onto a 1D array of ValType StructHeader must be derived...
Definition: MappedImage.h:38
ChimeraTK::MappedStruct::header
StructHeader * header()
returns header, e.g. for setting meta data
Definition: MappedImage.h:54
ChimeraTK::OpaqueStructHeader
generic header for opaque struct handling It has fields needed for communication in the same process,...
Definition: MappedImage.h:23
Device.h
ChimeraTK::ImgHeader
Image header.
Definition: MappedImage.h:86
DummyFixture
Definition: testMappedImage.cc:18
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::setDMapFilePath
void setDMapFilePath(std::string dmapFilePath)
Set the location of the dmap file.
Definition: Utilities.cpp:327
ChimeraTK::MappedImage::interpretedView
ImgView< UserType, OPTIONS > interpretedView()
returns an ImgView object which can be used like a matrix.
Definition: MappedImage.h:161
ChimeraTK::MappedImage
interface to an image that is mapped onto a 1D array of ValType
Definition: MappedImage.h:147
ChimeraTK
Definition: DummyBackend.h:16