DynExp
Highly flexible laboratory automation for dynamically changing experiments.
PVCam.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "PVCam.h"
5 
6 namespace DynExpInstr
7 {
9  {
10  {
11  auto InstrParams = DynExp::dynamic_Params_cast<PVCam>(Instance.ParamsGetter());
12  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
13 
14  Instance.LockObject(InstrParams->HardwareAdapter, InstrData->HardwareAdapter);
15 
16  auto ColorMode = InstrData->HardwareAdapter->GetColorMode();
17  if (ColorMode != DynExpHardware::PVCamSyms::PL_COLOR_MODES::COLOR_NONE)
18  throw Util::NotImplementedException("Only monochrome PVCam cameras are supported.");
20  "Only monochrome PVCam cameras with an image format of 2 bytes per pixel are supported.");
21 
22  InstrData->SetImageWidth(InstrData->HardwareAdapter->GetImageWidth());
23  InstrData->SetImageHeight(InstrData->HardwareAdapter->GetImageHeight());
24  InstrData->SetCameraModes(InstrData->HardwareAdapter->GetCameraModes());
25  } // InstrParams and InstrData unlocked here.
26 
28  }
29 
31  {
32  ExitFuncImpl(dispatch_tag<ExitTask>(), Instance);
33 
34  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
35 
36  try
37  {
38  // Stop image capturing if this is the only or last instrument using the camera.
39  if (!InstrData->HardwareAdapter->IsSharedUsageEnabled() || InstrData->HardwareAdapter->GetUseCount() == 1)
40  InstrData->HardwareAdapter->StopCapturing();
41  }
42  catch (...)
43  {
44  // Swallow any exception which might arise from HardwareAdapter->StopCapturing() since a failure
45  // of this function is not considered a severe error.
46  }
47 
48  Instance.UnlockObject(InstrData->HardwareAdapter);
49  }
50 
52  {
53  try
54  {
55  Util::BlobDataType ImageBlob;
56  CameraData::ImageDimensionType ImageWidth = 0, ImageHeight = 0;
57  CameraData::ImageTransformationType ImageTransformation;
58  unsigned int BitDepth = 16;
59 
60  {
61  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
62  bool UpdateError = false;
63 
64  try
65  {
66  InstrData->SetMinExposureTime(InstrData->HardwareAdapter->GetMinExposureTime());
67  InstrData->SetMaxExposureTime(InstrData->HardwareAdapter->GetMaxExposureTime());
68  InstrData->SetExposureTime(InstrData->HardwareAdapter->GetExposureTime());
69  InstrData->SetCurrentFPS(InstrData->HardwareAdapter->GetFPS());
70  InstrData->SetCapturingState(InstrData->HardwareAdapter->GetCameraState());
71 
72  BitDepth = InstrData->HardwareAdapter->GetBitDepth();
73  ImageWidth = InstrData->GetImageWidth();
74  ImageHeight = InstrData->GetImageHeight();
75  ImageTransformation = InstrData->GetImageTransformation();
76  ImageBlob = InstrData->HardwareAdapter->GetCurrentImage();
77  }
78  catch ([[maybe_unused]] const DynExpHardware::PVCamException& e)
79  {
80  UpdateError = true;
81 
82  // Swallow if just one or two subsequent updates failed.
83  if (InstrData->NumFailedStatusUpdateAttempts++ >= 3)
84  throw;
85  }
86 
87  if (!UpdateError)
88  InstrData->NumFailedStatusUpdateAttempts = 0;
89  } // InstrData unlocked here.
90 
91  // Compute histogram stretch by bit depth of camera
92  auto ImageBlobPtr = ImageBlob.GetPtr();
93  for (auto i = 0; i < ImageBlob.Size(); i += 2)
94  {
95  // Convert pixel value by stretching the histogram according to the camera's bit depth.
96  DynExpHardware::PVCamSyms::uns16 Pixel = (*(ImageBlobPtr) | (*(ImageBlobPtr + 1) << 8)) * std::exp2(16) / std::exp2(BitDepth);
97 
98  // Apply user transformations
99  if (ImageTransformation.IsEnabled)
100  Pixel = TransformPixel(Pixel, ImageTransformation);
101 
102  // Write back
103  *(ImageBlobPtr) = Pixel & 0xff;
104  *(ImageBlobPtr + 1) = (Pixel & 0xff00) >> 8;
105 
106  ImageBlobPtr += 2;
107  }
108 
109  // Image moved by copy elision.
110  return Util::QImageFromBlobData(std::move(ImageBlob), ImageWidth, ImageHeight,
111  ImageWidth * DynExpHardware::PVCamHardwareAdapter::BytesPerPixel(), QImage::Format_Grayscale16);
112  }
113  // Issued if a mutex is blocked by another operation.
114  catch (const Util::TimeoutException& e)
115  {
116  Instance.GetOwner().SetWarning(e);
117 
118  return {};
119  }
120  // Issued if reading data from PVCam failed.
121  catch (const DynExpHardware::PVCamException& e)
122  {
123  Instance.GetOwner().SetWarning(e);
124 
125  return {};
126  }
127  }
128 
130  {
131  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
132 
133  InstrData->HardwareAdapter->SetCameraMode(ID);
134 
135  return {};
136  }
137 
139  {
140  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
141 
142  InstrData->HardwareAdapter->SetExposureTime(ExposureTime);
143 
144  return {};
145  }
146 
148  {
149  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
150 
151  InstrData->HardwareAdapter->CaptureSingle();
152 
153  return {};
154  }
155 
157  {
158  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
159 
160  InstrData->HardwareAdapter->StartCapturing();
161 
162  return {};
163  }
164 
166  {
167  auto InstrData = DynExp::dynamic_InstrumentData_cast<PVCam>(Instance.InstrumentDataGetter());
168 
169  InstrData->HardwareAdapter->StopCapturing();
170 
171  return {};
172  }
173 
175  {
176  CapturingState = CapturingStateType::Stopped;
177  NumFailedStatusUpdateAttempts = 0;
178 
179  ResetImpl(dispatch_tag<PVCamData>());
180  }
181 
182  PVCam::PVCam(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
183  : Camera(OwnerThreadID, std::move(Params))
184  {
185  }
186 
188  {
190  }
191 }
Implementation of an instrument to control Teledyne Photometrics PVCam cameras.
constexpr static auto BytesPerPixel() noexcept
unsigned int ImageDimensionType
Type describing image dimensions such as width and height.
Definition: Camera.h:99
bool IsEnabled
Determines whether the image transformation is to be applied (enabled).
Definition: Camera.h:96
Type describing an image transformation.
Definition: Camera.h:82
Meta instrument for an image capturing (camera) device.
Definition: Camera.h:313
void ResetImpl(dispatch_tag< CameraData >) override final
Definition: PVCam.cpp:174
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PVCam.cpp:147
void ExitFuncImpl(dispatch_tag< CameraTasks::ExitTask >, DynExp::InstrumentInstance &Instance) override final
Deinitializes the respective instrument within the instrument inheritance hierarchy....
Definition: PVCam.cpp:30
void InitFuncImpl(dispatch_tag< CameraTasks::InitTask >, DynExp::InstrumentInstance &Instance) override final
Initializes the respective instrument within the instrument inheritance hierarchy....
Definition: PVCam.cpp:8
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PVCam.cpp:129
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PVCam.cpp:138
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PVCam.cpp:156
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: PVCam.cpp:165
virtual QImage ObtainImage(DynExp::InstrumentInstance &Instance) override
Retrieves the current image from the underlying hardware device, applies image transformations (e....
Definition: PVCam.cpp:51
void ResetImpl(dispatch_tag< Camera >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
Definition: PVCam.cpp:187
PVCam(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
Definition: PVCam.cpp:182
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1151
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1120
Refer to ParamsBase::dispatch_tag.
Definition: Instrument.h:146
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
Definition: Instrument.h:772
const InstrumentBase::InstrumentDataGetterType InstrumentDataGetter
Getter for instrument's data. Refer to InstrumentBase::InstrumentDataGetterType.
Definition: Instrument.h:791
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition: Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition: Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT >> &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition: Object.h:3554
const auto & GetOwner() const noexcept
Returns Owner.
Definition: Object.h:3524
Defines the return type of task functions.
Definition: Instrument.h:824
Data type which manages a binary large object. The reserved memory is freed upon destruction.
Definition: Util.h:517
auto Size() const noexcept
Returns the size of the stored data in bytes.
Definition: Util.h:537
auto GetPtr() noexcept
Returns a pointer to the stored buffer.
Definition: Util.h:536
Thrown when a requested feature is either under development and thus not implemented yet or when a sp...
Definition: Exception.h:299
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
Definition: Instrument.h:1254
T TransformPixel(T Pixel, const CameraData::ImageTransformationType &ImageTransformation)
Applies an image transformation to a single pixel.
Definition: Camera.h:431
constexpr auto Stopped
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition: Object.h:1807
QImage QImageFromBlobData(BlobDataType &&BlobData, int Width, int Height, int BytesPerLine, QImage::Format Format)
Converts raw pixel data stored in a Util::BlobDataType object to a QImage transfering the ownership o...
Definition: QtUtil.cpp:153
Accumulates include statements to provide a precompiled header.