DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Loading...
Searching...
No Matches
WidefieldLocalization.cpp
Go to the documentation of this file.
1// This file is part of DynExp.
2
3#include "stdafx.h"
5
6namespace DynExpInstr
7{
9 {
10 if (lhs.X_id == rhs.X_id && lhs.Y_id == rhs.Y_id)
11 return std::strong_ordering::equal;
12 else if (lhs.Y_id > rhs.Y_id || (lhs.Y_id == rhs.Y_id && lhs.X_id > rhs.X_id))
13 return std::strong_ordering::greater;
14 else
15 return std::strong_ordering::less;
16 }
17
18 std::ostream& operator<<(std::ostream& stream, const WidefieldLocalizationCellIDType& CellID)
19 {
20 stream << "CellIDString = " << CellID.IDString << "\n";
21 stream << "CellIDX = " << CellID.X_id << "\n";
22 stream << "CellIDY = " << CellID.Y_id << "\n";
23 stream << "CellIDValid = " << (CellID.Valid ? "yes" : "no") << "\n";
24
25 return stream;
26 }
27
32
37
42
44 : ImageWidth(Util::NumToT<google::protobuf::uint32>(Image.width())), ImageHeight(Util::NumToT<google::protobuf::uint32>(Image.height())),
45 ImageFormat(Image.format())
46 {
47 ImageData.resize(Image.sizeInBytes());
48
49 // No deep copy in QImage::bits(), since Image is const (see https://doc.qt.io/qt-5/qimage.html#bits-1).
50 std::memcpy(ImageData.data(), Image.bits(), ImageData.size());
51 }
52
53 DynExpProto::WidefieldLocalization::ImageMessage WidefieldLocalizationTasks::ImageProcessingTaskBase::MakeImageMessage()
54 {
55 DynExpProto::WidefieldLocalization::ImageMessage ImageMsg;
56
57 ImageMsg.set_width(ImageWidth);
58 ImageMsg.set_height(ImageHeight);
59
60 switch (ImageFormat)
61 {
62 case QImage::Format::Format_Grayscale8: ImageMsg.set_imageformat(DynExpProto::WidefieldLocalization::ImageFormatType::Mono8); break;
63 case QImage::Format::Format_Grayscale16: ImageMsg.set_imageformat(DynExpProto::WidefieldLocalization::ImageFormatType::Mono16); break;
64 default: throw Util::NotImplementedException("The format of the given image is not supported.");
65 }
66
67 ImageMsg.set_image(std::move(ImageData));
68
69 return ImageMsg;
70 }
71
73 : TaskBase(CallbackFunc), ImageProcessingTaskBase(Image)
74 {
75 }
76
78 {
79 grpc::ClientContext Context;
80 DynExpProto::WidefieldLocalization::ImageMessage ImageMsg = MakeImageMessage();
81 DynExpProto::WidefieldLocalization::CellIDMessage CellIDMsg;
82
84 {
85 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
86 StubPtr = InstrData->GetStub<0>();
87 } // InstrData unlocked here.
88
89 auto Result = StubPtr->ReadCellID(&Context, ImageMsg, &CellIDMsg);
90 if (!Result.ok())
92 if (CellIDMsg.resultmsg().result() != DynExpProto::WidefieldLocalization::ResultType::OK &&
93 CellIDMsg.resultmsg().result() != DynExpProto::WidefieldLocalization::ResultType::LocalizationFailed)
94 throw Util::ServiceFailedException("Reading the cell id failed on the remote service site.");
95
96 {
97 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
98
99 if (CellIDMsg.resultmsg().result() == DynExpProto::WidefieldLocalization::ResultType::OK)
100 {
101 // Reading the cell id worked.
102 InstrData->CellID.IDString = CellIDMsg.idstring();
103 InstrData->CellID.X_id = CellIDMsg.id().x();
104 InstrData->CellID.Y_id = CellIDMsg.id().y();
105 InstrData->CellID.Valid = true;
106 InstrData->CellID.CellShift_px_x = CellIDMsg.has_cellshift_px() ? CellIDMsg.cellshift_px().x() : 0;
107 InstrData->CellID.CellShift_px_y = CellIDMsg.has_cellshift_px() ? CellIDMsg.cellshift_px().y() : 0;
108 }
109 else
110 {
111 // Extracting the cell id did not work since it was not readable from the image.
112 // However, the extraction routines themselves worked. Do not throw in case of that 'soft' error.
113 InstrData->CellID = {};
114 }
115 } // InstrData unlocked here.
116
117 return {};
118 }
119
121 : TaskBase(CallbackFunc), ImageProcessingTaskBase(Image)
122 {
123 }
124
126 {
127 grpc::ClientContext Context;
128 DynExpProto::WidefieldLocalization::ImageMessage ImageMsg = MakeImageMessage();
129 DynExpProto::WidefieldLocalization::PositionsMessage PositionsMsg;
130
132 {
133 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
134 StubPtr = InstrData->GetStub<0>();
135 } // InstrData unlocked here.
136
137 auto Result = StubPtr->AnalyzeWidefield(&Context, ImageMsg, &PositionsMsg);
138 if (!Result.ok())
139 throw DynExpHardware::gRPCException(Result);
140
141 {
142 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
143 InstrData->SetLocalizedPositions(PositionsMsg);
144 } // InstrData unlocked here.
145
146 return {};
147 }
148
150 : TaskBase(CallbackFunc), ImageProcessingTaskBase(Image)
151 {
152 }
153
155 {
156 grpc::ClientContext Context;
157 DynExpProto::WidefieldLocalization::ImageMessage ImageMsg = MakeImageMessage();
158 DynExpProto::WidefieldLocalization::VoidMessage VoidMsg;
159
161 {
162 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
163 StubPtr = InstrData->GetStub<0>();
164 } // InstrData unlocked here.
165
166 auto Result = StubPtr->AnalyzeTipTilt(&Context, ImageMsg, &VoidMsg);
167 if (!Result.ok())
168 throw DynExpHardware::gRPCException(Result);
169
170 return {};
171 }
172
174 std::string_view MeasureSavePath, CallbackType CallbackFunc) noexcept
175 : TaskBase(CallbackFunc), ImageProcessingTaskBase(Image), CellID(CellID), MeasureSavePath(MeasureSavePath)
176 {
177 }
178
180 {
181 grpc::ClientContext Context;
182 DynExpProto::WidefieldLocalization::RecallPositionsMessage RecallPositionsMsg;
183 DynExpProto::WidefieldLocalization::PositionsMessage PositionsMsg;
184
185 auto ImageMsg = std::make_unique<DynExpProto::WidefieldLocalization::ImageMessage>(MakeImageMessage());
186 RecallPositionsMsg.set_allocated_image(ImageMsg.release());
187
188 auto CellIDResultsMsg = std::make_unique<DynExpProto::WidefieldLocalization::ResultMessage>();
189 CellIDResultsMsg->set_result(CellID.Valid ? DynExpProto::WidefieldLocalization::ResultType::OK : DynExpProto::WidefieldLocalization::ResultType::GeneralError);
190 auto IDPointMsg = std::make_unique<DynExpProto::WidefieldLocalization::PointMessage>();
191 IDPointMsg->set_x(CellID.X_id);
192 IDPointMsg->set_y(CellID.Y_id);
193 auto CellIDMsg = std::make_unique<DynExpProto::WidefieldLocalization::CellIDMessage>();
194 CellIDMsg->set_allocated_resultmsg(CellIDResultsMsg.release());
195 CellIDMsg->set_idstring(CellID.IDString);
196 CellIDMsg->set_allocated_id(IDPointMsg.release());
197 RecallPositionsMsg.set_allocated_cellid(CellIDMsg.release());
198
199 RecallPositionsMsg.set_measuresavepath(MeasureSavePath);
200
202 {
203 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
204 StubPtr = InstrData->GetStub<0>();
205 } // InstrData unlocked here.
206
207 auto Result = StubPtr->RecallPositions(&Context, RecallPositionsMsg, &PositionsMsg);
208 if (!Result.ok())
209 throw DynExpHardware::gRPCException(Result);
210
211 {
212 auto InstrData = DynExp::dynamic_InstrumentData_cast<WidefieldLocalization>(Instance.InstrumentDataGetter());
213 InstrData->SetLocalizedPositions(PositionsMsg);
214 } // InstrData unlocked here.
215
216 return {};
217 }
218
219 void WidefieldLocalizationData::ResetImpl(dispatch_tag<gRPCInstrumentData>)
220 {
221 CellID = {};
222 LocalizedPositions.clear();
223
224 ResetImpl(dispatch_tag<WidefieldLocalizationData>());
225 }
226
227 void WidefieldLocalizationData::SetLocalizedPositions(const DynExpProto::WidefieldLocalization::PositionsMessage& PositionsMsg)
228 {
229 if (PositionsMsg.resultmsg().result() != DynExpProto::WidefieldLocalization::ResultType::OK)
230 throw Util::ServiceFailedException("Widefield localization failed on the remote service site.");
231
232 const auto NumPositions = PositionsMsg.entries_size();
233 LocalizedPositions.clear();
234 for (std::remove_const_t<decltype(NumPositions)> i = 0; i < NumPositions; ++i)
235 {
236 QPoint Position{ Util::NumToT<int>(PositionsMsg.entries(i).pos_px().x()), Util::NumToT<int>(PositionsMsg.entries(i).pos_px().y()) };
237 LocalizedPositions.emplace(PositionsMsg.entries(i).id(), Position);
238 }
239 }
240
241 WidefieldLocalization::WidefieldLocalization(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
242 : gRPCInstrument(OwnerThreadID, std::move(Params))
243 {
244 }
245
250}
Implementation of a gRPC client instrument to access a remote service for image processing (localizat...
Defines an exception caused by an operation involving the gRPC library and communication over a TCP s...
void SetLocalizedPositions(const DynExpProto::WidefieldLocalization::PositionsMessage &PositionsMsg)
void ResetImpl(dispatch_tag< gRPCInstrumentData >) override final
AnalyzeDistortionTask(const QImage &Image, CallbackType CallbackFunc) noexcept
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...
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...
AnalyzeWidefieldTask(const QImage &Image, CallbackType CallbackFunc) noexcept
void ExitFuncImpl(dispatch_tag< gRPCInstrumentTasks::ExitTask< DynExp::InstrumentBase, 0, DynExpProto::WidefieldLocalization::WidefieldLocalization > >, DynExp::InstrumentInstance &Instance) override final
DynExpProto::WidefieldLocalization::ImageMessage MakeImageMessage()
void InitFuncImpl(dispatch_tag< gRPCInstrumentTasks::InitTask< DynExp::InstrumentBase, 0, DynExpProto::WidefieldLocalization::WidefieldLocalization > >, DynExp::InstrumentInstance &Instance) override final
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...
ReadCellIDTask(const QImage &Image, CallbackType CallbackFunc) noexcept
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...
RecallPositionsTask(const QImage &Image, const WidefieldLocalizationCellIDType &CellID, std::string_view MeasureSavePath, CallbackType CallbackFunc) noexcept
void UpdateFuncImpl(dispatch_tag< gRPCInstrumentTasks::UpdateTask< DynExp::InstrumentBase, 0, DynExpProto::WidefieldLocalization::WidefieldLocalization > >, DynExp::InstrumentInstance &Instance) override final
void ResetImpl(dispatch_tag< gRPCInstrument >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
WidefieldLocalization(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
Defines a task for deinitializing an instrument within an instrument inheritance hierarchy....
Defines a task for initializing an instrument within an instrument inheritance hierarchy....
Defines a task for updating an instrument within an instrument inheritance hierarchy....
Meta instrument template for transforming meta instruments into network instruments,...
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
std::function< void(const TaskBase &, ExceptionContainer &)> CallbackType
Type of a callback function which is invoked when a task has finished, failed or has been aborted....
Definition Instrument.h:939
Defines the return type of task functions.
Definition Instrument.h:824
Thrown when a requested feature is either under development and thus not implemented yet or when a sp...
Definition Exception.h:299
Denotes that e.g. a remote gRPC service failed.
Definition Exception.h:357
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
std::strong_ordering operator<=>(const WidefieldLocalizationCellIDType &lhs, const WidefieldLocalizationCellIDType &rhs)
std::shared_ptr< typename gRPCStub::Stub > StubPtrType
Alias for a pointer to a gRPC stub.
std::ostream & operator<<(std::ostream &stream, const WidefieldLocalizationCellIDType &CellID)
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition Object.h:1807
Accumulates include statements to provide a precompiled header.