MMDevice
Loading...
Searching...
No Matches
DeviceBase.h
Go to the documentation of this file.
1
2// FILE: DeviceBase.h
3// PROJECT: Micro-Manager
4// SUBSYSTEM: MMDevice - Device adapter kit
5//-----------------------------------------------------------------------------
6// DESCRIPTION: Generic functionality for implementing device adapters
7//
8// AUTHOR: Nenad Amodaj, nenad@amodaj.com, 08/18/2005
9//
10// COPYRIGHT: University of California, San Francisco, 2006
11//
12// LICENSE: This file is distributed under the BSD license.
13// License text is included with the source distribution.
14//
15// This file is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty
17// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18//
19// IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
22//
23
24#pragma once
25
26#include "MMDevice.h"
27
28#include "CameraImageMetadata.h"
29#include "DeviceThreads.h"
30#include "DeviceUtils.h"
31#include "MMDeviceConstants.h"
32#include "ModuleInterface.h"
33#include "Property.h"
34
35#include <math.h>
36#include <assert.h>
37
38#include <string>
39#include <vector>
40#include <iomanip>
41#include <map>
42#include <sstream>
43#include <utility>
44
45// common error messages
46const char* const g_Msg_ERR = "Unknown error in the device";
47const char* const g_Msg_INVALID_PROPERTY = "Invalid property name encountered";
48const char* const g_Msg_INVALID_PROPERTY_VALUE = "Invalid property value";
49const char* const g_Msg_DUPLICATE_PROPERTY = "Duplicate property names are not allowed";
50const char* const g_Msg_INVALID_PROPERTY_TYPE = "Invalid property type";
51const char* const g_Msg_NATIVE_MODULE_FAILED = "Native module failed to load";
52const char* const g_Msg_UNSUPPORTED_DATA_FORMAT = "Unsupported data format encountered";
53const char* const g_Msg_INTERNAL_INCONSISTENCY = "Device adapter inconsistent with the actual device";
54const char* const g_Msg_NOT_SUPPORTED = "Device not supported by the adapter";
55const char* const g_Msg_UNKNOWN_LABEL = "Label not defined";
56const char* const g_Msg_UNSUPPORTED_COMMAND = "Unsupported device command";
57const char* const g_Msg_UNKNOWN_POSITION = "Invalid state (position) requested";
58const char* const g_Msg_NO_CALLBACK_REGISTERED = "No callback registered";
59const char* const g_Msg_SERIAL_BUFFER_OVERRUN = "Serial buffer overrun.";
60const char* const g_Msg_SERIAL_INVALID_RESPONSE = "Unexpected response from serial port. Is the device connected to the correct serial port?";
61const char* const g_Msg_SERIAL_TIMEOUT = "Serial timeout occurred.";
62const char* const g_Msg_SELF_REFERENCE = "Self reference error.";
63const char* const g_Msg_NO_PROPERTY_DATA = "No property data error.";
64const char* const g_Msg_DEVICE_DUPLICATE_LABEL = "Position label already in use";
65const char* const g_Msg_INVALID_INPUT_PARAM = "Invalid input parameter.";
66const char* const g_Msg_BUFFER_OVERFLOW = "Buffer Overflow.";
67const char* const g_Msg_SERIAL_COMMAND_FAILED = "Serial command failed. Is the device connected to the serial port?";
68const char* const g_Msg_DEVICE_NONEXISTENT_CHANNEL = "Requested channel is not defined.";
69const char* const g_Msg_DEVICE_INVALID_PROPERTY_LIMTS = "Specified property limits are not valid."
70" Either the property already has a set of discrete values, or the range is invalid";
71const char* const g_Msg_EXCEPTION_IN_THREAD = "Exception in the thread function.";
72const char* const g_Msg_EXCEPTION_IN_ON_THREAD_EXITING = "Exception in the OnThreadExiting function.";
73const char* const g_Msg_SEQUENCE_ACQUISITION_THREAD_EXITING="Sequence thread exiting";
74const char* const g_Msg_DEVICE_CAMERA_BUSY_ACQUIRING="Camera is busy acquiring images. Stop camera activity before changing this property";
75const char* const g_Msg_DEVICE_CAN_NOT_SET_PROPERTY="The device can not set this property at this moment";
76const char* const g_Msg_DEVICE_NOT_CONNECTED="Unable to communicate with the device.";
77const char* const g_Msg_DEVICE_COMM_HUB_MISSING= "Parent module (Hub) is not available or defined for this device!";
78const char* const g_Msg_DEVICE_DUPLICATE_LIBRARY="Duplicate Device Library Name";
79const char* const g_Msg_DEVICE_PROPERTY_NOT_SEQUENCEABLE="This property is not sequenceable";
80const char* const g_Msg_DEVICE_SEQUENCE_TOO_LARGE="Sequence is too large for this device";
81const char* const g_Msg_DEVICE_NOT_YET_IMPLEMENTED="This command has not yet been implemented for this device.";
82
83inline long nint( double value )
84{
85 return (long)floor( 0.5 + value);
86};
87
95template <class T, class U>
96class CDeviceBase : public T
97{
98public:
99
102
106 virtual void SetModuleName(const char* name)
107 {
108 moduleName_ = name;
109 }
110
114 virtual void GetModuleName(char* name) const
115 {
116 CDeviceUtils::CopyLimitedString(name, moduleName_.c_str());
117 }
118
122 virtual void SetDescription(const char* descr)
123 {
124 description_ = descr;
125 }
126
130 virtual void GetDescription(char* name) const
131 {
132 CDeviceUtils::CopyLimitedString(name, description_.c_str());
133 }
134
141 virtual void SetLabel(const char* label)
142 {
143 label_ = label;
144 }
145
152 virtual void GetLabel(char* name) const
153 {
154 CDeviceUtils::CopyLimitedString(name, label_.c_str());
155 }
156
163 virtual double GetDelayMs() const {return delayMs_;}
164
171 virtual void SetDelayMs(double delay) {delayMs_ = delay;}
172
176 virtual void SetCallback(MM::Core* cbk) {callback_ = cbk;}
177
183 virtual bool UsesDelay() {return usesDelay_;}
184
188 virtual unsigned GetNumberOfProperties() const {return (unsigned)properties_.GetSize();}
189
196 virtual int GetProperty(const char* name, char* value) const
197 {
198 std::string strVal;
199 // additional information for reporting invalid properties.
201 int nRet = properties_.Get(name, strVal);
202 if (nRet == DEVICE_OK)
203 CDeviceUtils::CopyLimitedString(value, strVal.c_str());
204 return nRet;
205 }
206
213 int GetProperty(const char* name, double& val)
214 {
215 std::string strVal;
216 int nRet = properties_.Get(name, strVal);
217 if (nRet == DEVICE_OK)
218 val = atof(strVal.c_str());
219 return nRet;
220 }
221
228 int GetProperty(const char* name, long& val)
229 {
230 std::string strVal;
231 int nRet = properties_.Get(name, strVal);
232 if (nRet == DEVICE_OK)
233 val = atol(strVal.c_str());
234 return nRet;
235 }
236
245 bool IsPropertyEqualTo(const char* name, const char* val) const
246 {
247 std::string strVal;
248 int nRet = properties_.Get(name, strVal);
249 if (nRet == DEVICE_OK)
250 return strcmp(val, strVal.c_str()) == 0;
251 else
252 return false;
253 }
254
261 virtual int GetPropertyReadOnly(const char* name, bool& readOnly) const
262 {
263 MM::Property* pProp = properties_.Find(name);
264 if (!pProp)
265 {
266 // additional information for reporting invalid properties.
269 }
270 readOnly = pProp->GetReadOnly();
271
272 return DEVICE_OK;
273 }
274
281 virtual int GetPropertyInitStatus(const char* name, bool& preInit) const
282 {
283 MM::Property* pProp = properties_.Find(name);
284 if (!pProp)
285 {
286 // additional information for reporting invalid properties.
289 }
290 preInit = pProp->GetInitStatus();
291
292 return DEVICE_OK;
293 }
294
295 virtual int HasPropertyLimits(const char* name, bool& hasLimits) const
296 {
297 MM::Property* pProp = properties_.Find(name);
298 if (!pProp)
299 {
300 // additional information for reporting invalid properties.
303 }
304 hasLimits = pProp->HasLimits();
305 return DEVICE_OK;
306 }
307
314 virtual int GetPropertyLowerLimit(const char* name, double& lowLimit) const
315 {
316 MM::Property* pProp = properties_.Find(name);
317 if (!pProp)
318 {
319 // additional information for reporting invalid properties.
322 }
323 lowLimit = pProp->GetLowerLimit();
324 return DEVICE_OK;
325 }
326
333 virtual int GetPropertyUpperLimit(const char* name, double& hiLimit) const
334 {
335 MM::Property* pProp = properties_.Find(name);
336 if (!pProp)
337 {
338 // additional information for reporting invalid properties.
341 }
342 hiLimit = pProp->GetUpperLimit();
343 return DEVICE_OK;
344 }
345
352 virtual int IsPropertySequenceable(const char* name, bool& sequenceable) const
353 {
354 MM::Property* pProp = properties_.Find(name);
355 if (!pProp)
356 {
357 // additional information for reporting invalid properties.
360 }
361 sequenceable = pProp->IsSequenceable();
362
363 return DEVICE_OK;
364 }
365
372 virtual int GetPropertySequenceMaxLength(const char* name, long& nrEvents) const
373 {
374 MM::Property* pProp = properties_.Find(name);
375 if (!pProp)
376 {
377 // additional information for reporting invalid properties.
380 }
381 bool sequenceable;
382 int ret = IsPropertySequenceable(name, sequenceable);
383 if (ret != DEVICE_OK)
384 return ret;
385 if (!sequenceable) {
388 }
389
390 nrEvents = pProp->GetSequenceMaxSize();
391
392 return DEVICE_OK;
393 }
394
403 virtual int StartPropertySequence(const char* name)
404 {
405 MM::Property* pProp = properties_.Find(name);
406 if (!pProp)
407 {
408 // additional information for reporting invalid properties.
411 }
412 bool sequenceable;
413 int ret = IsPropertySequenceable(name, sequenceable);
414 if (ret != DEVICE_OK)
415 return ret;
416 if (!sequenceable) {
419 }
420
421 return pProp->StartSequence();
422 }
423
432 virtual int StopPropertySequence(const char* name)
433 {
434 MM::Property* pProp = properties_.Find(name);
435 if (!pProp)
436 {
439 }
440 bool sequenceable;
441 int ret = IsPropertySequenceable(name, sequenceable);
442 if (ret != DEVICE_OK)
443 return ret;
444 if (!sequenceable) {
447 }
448
449 return pProp->StopSequence();
450 }
451
460 virtual int ClearPropertySequence(const char* name)
461 {
462 MM::Property* pProp;
463 int ret = GetSequenceableProperty(&pProp, name);
464 if (ret != DEVICE_OK)
465 return ret;
466
467 return pProp->ClearSequence();
468 }
469
479 virtual int AddToPropertySequence(const char* name, const char* value)
480 {
481 MM::Property* pProp;
482 int ret = GetSequenceableProperty(&pProp, name);
483 if (ret != DEVICE_OK)
484 return ret;
485
486 return pProp->AddToSequence(value);
487 }
488
498 virtual int SendPropertySequence(const char* name)
499 {
500 MM::Property* pProp;
501 int ret = GetSequenceableProperty(&pProp, name);
502 if (ret != DEVICE_OK)
503 return ret;
504
505 return pProp->SendSequence();
506 }
507
516 virtual bool GetPropertyName(unsigned uIdx, char* name) const
517 {
518 std::string strName;
519 if (!properties_.GetName(uIdx, strName))
520 return false;
521
522 CDeviceUtils::CopyLimitedString(name, strName.c_str());
523 return true;
524 }
525
529 virtual int GetPropertyType(const char* name, MM::PropertyType& pt) const
530 {
531 MM::Property* pProp = properties_.Find(name);
532 if (!pProp)
534
535 pt = pProp->GetType();
536 return DEVICE_OK;
537 }
538
545 virtual int SetProperty(const char* name, const char* value)
546 {
547 int ret = properties_.Set(name, value);
548 if( DEVICE_OK != ret)
549 {
550 // additional information for reporting invalid properties.
552
553 }
554 return ret;
555 }
556
560 virtual bool HasProperty(const char* name) const
561 {
562 MM::Property* pProp = properties_.Find(name);
563 if (pProp)
564 return true;
565 else
566 return false;
567 }
568
575 virtual unsigned GetNumberOfPropertyValues(const char* propertyName) const
576 {
577 MM::Property* pProp = properties_.Find(propertyName);
578 if (!pProp)
579 return 0;
580
581 return (unsigned)pProp->GetAllowedValues().size();
582 }
583
593 virtual bool GetPropertyValueAt(const char* propertyName, unsigned index, char* value) const
594 {
595 MM::Property* pProp = properties_.Find(propertyName);
596 if (!pProp)
597 return false;
598
599 std::vector<std::string> values = pProp->GetAllowedValues();
600 if (values.size() < index)
601 return false;
602
603 CDeviceUtils::CopyLimitedString(value, values[index].c_str());
604 return true;
605 }
606
618 int CreateProperty(const char* name, const char* value, MM::PropertyType eType, bool readOnly, MM::ActionFunctor* pAct=0, bool isPreInitProperty=false)
619 {
620 return properties_.CreateProperty(name, value, eType, readOnly, pAct, isPreInitProperty);
621 }
622
635 int CreatePropertyWithHandler(const char* name, const char* value, MM::PropertyType eType, bool readOnly,
636 int(U::*memberFunction)(MM::PropertyBase* pProp, MM::ActionType eAct), bool isPreInitProperty=false) {
637 CPropertyAction* pAct = new CPropertyAction((U*) this, memberFunction);
638 return CreateProperty(name, value, eType, readOnly, pAct, isPreInitProperty);
639 }
640
644 int CreateIntegerProperty(const char* name, long value, bool readOnly, MM::ActionFunctor* pAct = 0, bool isPreInitProperty = false)
645 {
646 // Note: in theory, we can avoid converting to string and back. At this
647 // moment, it is not worth the trouble.
648 std::ostringstream oss;
649 oss << value;
650 return CreateProperty(name, oss.str().c_str(), MM::Integer, readOnly, pAct, isPreInitProperty);
651 }
652
656 int CreateFloatProperty(const char* name, double value, bool readOnly, MM::ActionFunctor* pAct = 0, bool isPreInitProperty = false)
657 {
658 // Note: in theory, we can avoid converting to string and back. At this
659 // moment, it is not worth the trouble.
660 //
661 // However, note the following assumption being made here: the default
662 // settings of std::ostream will return strings with a decimal precision
663 // of 6 digits. When this eventually gets passed to
664 // MM::FloatProperty::Set(double), it gets truncated to 4 digits before
665 // being stored. Thus, we do not loose any information.
666 std::ostringstream oss;
667 oss << value;
668 return CreateProperty(name, oss.str().c_str(), MM::Float, readOnly, pAct, isPreInitProperty);
669 }
670
674 int CreateStringProperty(const char* name, const char* value, bool readOnly, MM::ActionFunctor* pAct = 0, bool isPreInitProperty = false)
675 {
676 return CreateProperty(name, value, MM::String, readOnly, pAct, isPreInitProperty);
677 }
678
682 int SetPropertyLimits(const char* name, double low, double high)
683 {
684 MM::Property* pProp = properties_.Find(name);
685 if (!pProp)
686 {
689 }
690 if (pProp->SetLimits(low, high))
691 return DEVICE_OK;
692 else {
693 std::ostringstream os;
694 os << "Device adapter requests invalid values ( " << low << ", ";
695 os << high << ") for property: " << name;
696 LogMessage(os.str().c_str(), false);
698 }
699 }
700
704 int SetAllowedValues(const char* name, std::vector<std::string>& values)
705 {
706 return properties_.SetAllowedValues(name, values);
707 }
708
712 int ClearAllowedValues(const char* name)
713 {
714 return properties_.ClearAllowedValues(name);
715 }
716
720 int AddAllowedValue(const char* name, const char* value)
721 {
722 return properties_.AddAllowedValue(name, value);
723 }
724
728 int AddAllowedValue(const char* name, const char* value, long data)
729 {
730 return properties_.AddAllowedValue(name, value, data);
731 }
732
736 int GetPropertyData(const char* name, const char* value, long& data)
737 {
738 int ret = properties_.GetPropertyData(name, value, data);
739 if( DEVICE_OK != ret)
740 // additional information for reporting invalid properties.
742
743 return ret;
744 }
745
749 int GetCurrentPropertyData(const char* name, long& data)
750 {
751 int ret = properties_.GetCurrentPropertyData(name, data);
752 if( DEVICE_OK != ret)
753 // additional information for reporting invalid properties.
755
756 return ret;
757 }
758
764 {
765 return properties_.UpdateAll();
766 }
767
771 int UpdateProperty(const char* name)
772 {
773 return properties_.Update(name);
774 }
775
776
780 int ApplyProperty(const char* name)
781 {
782 return properties_.Apply(name);
783 }
784
788 virtual bool GetErrorText(int errorCode, char* text) const
789 {
790 std::map<int, std::string>::const_iterator it;
791 it = messages_.find(errorCode);
792 if (it == messages_.end())
793 {
794 // generic message
795 std::ostringstream osTxt;
796 osTxt << "Error code " << errorCode << " (" << std::setbase(16) << errorCode << " hex)";
797 CDeviceUtils::CopyLimitedString(text, osTxt.str().c_str());
798 return false; // message text not found
799 }
800 else
801 {
802 std::ostringstream stringStreamMessage;
803 stringStreamMessage << it->second.c_str();
804 // add the additional 'property' error info.
805 if( 2<=errorCode && errorCode<=5 )
806 {
807 stringStreamMessage << ": " << GetMorePropertyErrorInfo();
808 }
810 // native message
811 CDeviceUtils::CopyLimitedString(text, stringStreamMessage.str().c_str());
812 return true; // message found
813 }
814 }
815
816 // device discovery (auto-configuration)
817 virtual bool SupportsDeviceDetection(void) {
818 return false;
819 }
823
824 // hub - peripheral relationship
825 virtual void SetParentID(const char* parentId)
826 {
827 parentID_ = parentId;
828
829 // truncate if necessary
830 if (parentID_.size() >= (unsigned) MM::MaxStrLength)
831 parentID_ = parentID_.substr(MM::MaxStrLength-1);
832
834 {
835 this->SetProperty(MM::g_Keyword_HubID, parentID_.c_str());
836 }
837 }
838
839 virtual void GetParentID(char* parentID) const
840 {
841 CDeviceUtils::CopyLimitedString(parentID, parentID_.c_str());
842 }
843
845 // Protected methods, for internal use by the device adapters
847
848protected:
849
850 CDeviceBase() : delayMs_(0), usesDelay_(false), callback_(0)
851 {
853 }
854 virtual ~CDeviceBase() {}
855
859 void SetErrorText(int errorCode, const char* text)
860 {
861 messages_[errorCode] = text;
862 }
863
864 const char* GetMorePropertyErrorInfo(void) const
865 {
866 return morePropertyErrorInfo_.c_str();
867 }
868
869 void SetMorePropertyErrorInfo( const char* ptext) const
870 {
871 morePropertyErrorInfo_ = ptext;
872 }
873
881 int LogMessage(const char* msg, bool debugOnly = false) const
882 {
883 if (callback_)
884 return callback_->LogMessage(this, msg, debugOnly);
886 }
887
895 int LogMessage(const std::string& msg, bool debugOnly = false) const
896 {
897 if (callback_)
898 return callback_->LogMessage(this, msg.c_str(), debugOnly);
900 }
901
909 int LogMessageCode(const int errorCode, bool debugOnly = false) const
910 {
911 if (callback_)
912 {
913 char text[MM::MaxStrLength];
914 GetErrorText(errorCode, text);
915 return callback_->LogMessage(this, text, debugOnly);
916 }
918 }
919
920
932 int LogTimeDiff(MM::MMTime start, MM::MMTime end, const std::string& message, bool debugOnly = false) const
933 {
934 std::ostringstream os;
935 MM::MMTime t = end-start;
936 os << message << t.toString() << " seconds";
937 if (callback_)
938 return callback_->LogMessage(this, os.str().c_str(), debugOnly);
940 }
941
952 int LogTimeDiff(MM::MMTime start, MM::MMTime end, bool debugOnly = false) const
953 {
954 return LogTimeDiff(start, end, "Process took: " , debugOnly);
955 }
956
961 {
962 // initialize error codes
996 }
997
1004 MM::Device* GetDevice(const char* deviceLabel) const
1005 {
1006 if (callback_)
1007 return callback_->GetDevice(this, deviceLabel);
1008 return 0;
1009 }
1010
1020 // Microsoft compiler has trouble generating code to transport stl objects across DLL boundary
1021 // so we use char*. Other compilers could conceivably have similar trouble, if for example,
1022 // a dynamic library is linked with a different CRT than its client.
1023 void GetLoadedDeviceOfType(MM::DeviceType devType, char* deviceName, const unsigned int deviceIterator )
1024 {
1025 deviceName[0] = 0;
1026 if (callback_)
1027 {
1028 callback_->GetLoadedDeviceOfType( this, devType, deviceName, deviceIterator);
1029 }
1030 }
1031
1032
1036 int WriteToComPort(const char* portLabel, const unsigned char* buf, unsigned bufLength)
1037 {
1038 if (callback_)
1039 return callback_->WriteToSerial(this, portLabel, buf, bufLength);
1040
1042 }
1043
1052 int SendSerialCommand(const char* portName, const char* command, const char* term)
1053 {
1054 if (callback_)
1055 return callback_->SetSerialCommand(this, portName, command, term);
1056
1058 }
1059
1068 int GetSerialAnswer (const char* portName, const char* term, std::string& ans)
1069 {
1070 const unsigned long MAX_BUFLEN = 2000;
1071 char buf[MAX_BUFLEN];
1072 if (callback_)
1073 {
1074 int ret = callback_->GetSerialAnswer(this, portName, MAX_BUFLEN, buf, term);
1075 if (ret != DEVICE_OK)
1076 return ret;
1077 ans = buf;
1078 return DEVICE_OK;
1079 }
1080
1082 }
1083
1087 int ReadFromComPort(const char* portLabel, unsigned char* buf, unsigned bufLength, unsigned long& read)
1088 {
1089 if (callback_)
1090 return callback_->ReadFromSerial(this, portLabel, buf, bufLength, read);
1092 }
1093
1097 int PurgeComPort(const char* portLabel)
1098 {
1099 if (callback_)
1100 return callback_->PurgeSerial(this, portLabel);
1102 }
1103
1109 MM::PortType GetSerialPortType(const char* portLabel)
1110 {
1111 if (callback_)
1112 return callback_->GetSerialPortType(portLabel);
1113 return MM::InvalidPort;
1114 }
1115
1125 {
1126 if (callback_)
1127 return callback_->OnPropertiesChanged(this);
1129 }
1130
1134 int OnPropertyChanged(const char* propName, const char* propValue)
1135 {
1136 if (callback_)
1137 return callback_->OnPropertyChanged(this, propName, propValue);
1139 }
1140
1153 {
1154 if (callback_)
1155 return callback_->OnStagePositionChanged(this, pos);
1157 }
1158
1170 int OnXYStagePositionChanged(double xPos, double yPos)
1171 {
1172 if (callback_)
1173 return callback_->OnXYStagePositionChanged(this, xPos, yPos);
1175 }
1176
1180 int OnExposureChanged(double exposure)
1181 {
1182 if (callback_)
1183 return callback_->OnExposureChanged(this, exposure);
1185 }
1186
1190 int OnSLMExposureChanged(double exposure)
1191 {
1192 if (callback_)
1193 return callback_->OnSLMExposureChanged(this, exposure);
1195 }
1196
1201 {
1202 if (callback_)
1203 return callback_->OnMagnifierChanged(this);
1205 }
1206
1212 unsigned long GetClockTicksUs()
1213 {
1214 if (callback_)
1215 return callback_->GetClockTicksUs(this);
1216
1217 return 0;
1218 }
1219
1224 {
1225 if (callback_)
1226 return callback_->GetCurrentMMTime();
1227
1228 return MM::MMTime(0.0);
1229 }
1230
1235 {
1236 return callback_ == 0 ? false : true;
1237 }
1238
1243 {
1244 return callback_;
1245 }
1246
1253 void EnableDelay(bool state = true)
1254 {
1255 usesDelay_ = state;
1256 }
1257
1267 {
1268 char pid[MM::MaxStrLength];
1269 this->GetParentID(pid);
1271 }
1272
1281 {
1283 return GetCoreCallback()->GetParentHub(this);
1284
1285 return 0;
1286 }
1287
1293 template<class T_HUB>
1294 T_HUB* AssignToHub() {
1295 T_HUB* hub = static_cast<T_HUB*>(GetParentHub());
1296 if (hub == NULL) {
1297 LogMessage("Parent hub not defined.");
1298 } else {
1299 char hubLabel[MM::MaxStrLength];
1300 hub->GetLabel(hubLabel);
1301 SetParentID(hubLabel); // for backward comp.
1302 }
1303 return hub;
1304 }
1305
1306private:
1307 bool PropertyDefined(const char* propName) const
1308 {
1309 return properties_.Find(propName) != 0;
1310 }
1311
1322 int GetSequenceableProperty(MM::Property** pProp, const char* name) const
1323 {
1324 *pProp = properties_.Find(name);
1325 if (!*pProp)
1326 {
1329 }
1330
1331 bool sequenceable = (*pProp)->IsSequenceable();
1332 if (!sequenceable) {
1335 }
1336 return DEVICE_OK;
1337 }
1338
1339
1340 MM::PropertyCollection properties_;
1341 std::string label_;
1342 std::string moduleName_;
1343 std::string description_;
1344 std::map<int, std::string> messages_;
1345 double delayMs_;
1346 bool usesDelay_;
1347 MM::Core* callback_;
1348 // specific information about the errant property, etc.
1349 mutable std::string morePropertyErrorInfo_;
1350 std::string parentID_;
1351};
1352
1353// Forbid instantiation of CDeviceBase<MM::Device, U>
1354// (It was abused in the past.)
1355template <class U>
1356class CDeviceBase<MM::Device, U>
1357{
1358 CDeviceBase(); // private; construction disallowed
1359};
1360
1364template <class U>
1365class CGenericBase : public CDeviceBase<MM::Generic, U>
1366{
1367};
1368
1369
1376template <class U>
1377class CCameraBase : public CDeviceBase<MM::Camera, U>
1378{
1379public:
1380 // These 2 'using' declarations were originally introduced in order to allow
1381 // C[Legacy]CameraBase member functions to call these functions (which would
1382 // have also been possible with 'this->'). The 2 functions are protected in
1383 // CDeviceBase. However, they are made public here, and some concrete
1384 // cameras ended up depending on that. So they need to be kept for now,
1385 // until and unless such cameras are fixed.
1388
1390 {
1391 // create and initialize common transpose properties
1392 std::vector<std::string> allowedValues;
1393 allowedValues.push_back("0");
1394 allowedValues.push_back("1");
1403
1404 }
1405
1406 virtual const unsigned char* GetImageBuffer() = 0;
1407 virtual unsigned GetImageWidth() const = 0;
1408 virtual unsigned GetImageHeight() const = 0;
1409 virtual unsigned GetImageBytesPerPixel() const = 0;
1410 virtual int SnapImage() = 0;
1411 virtual bool Busy() = 0;
1412
1418 virtual int StartSequenceAcquisition(double unused) = 0;
1419
1423 virtual int StopSequenceAcquisition() = 0;
1424
1425 virtual unsigned GetNumberOfComponents() const
1426 {
1427 return 1; // Default to monochrome (ie not RGB)
1428 }
1429
1436 virtual unsigned GetNumberOfChannels() const
1437 {
1438 return 1;
1439 }
1440
1448 virtual int GetChannelName(unsigned /* channel */, char* name)
1449 {
1451 return DEVICE_OK;
1452 }
1453
1460 virtual const unsigned char* GetImageBuffer(unsigned /* channelNr */)
1461 {
1462 if (GetNumberOfChannels() == 1)
1463 return GetImageBuffer();
1464 return 0;
1465 }
1466
1467 virtual const unsigned int* GetImageBufferAsRGB32()
1468 {
1469 return 0;
1470 }
1471
1475 virtual void GetTags(char* serializedMetadata)
1476 {
1478 for (const auto& p : addedTags_)
1479 {
1480 md.AddTag(p.first.c_str(), p.second.c_str());
1481 }
1482 CDeviceUtils::CopyLimitedString(serializedMetadata, md.Serialize());
1483 }
1484
1490 virtual int StartSequenceAcquisition(long numImages, double unused,
1491 bool stopOnOverflow) = 0;
1492
1493 virtual int GetExposureSequenceMaxLength(long& /*nrEvents*/) const
1494 {
1496 }
1497
1499 {
1501 }
1502
1504 {
1506 }
1507
1509 {
1511 }
1512
1513 virtual int AddToExposureSequence(double /*exposureTime_ms*/)
1514 {
1516 }
1517
1518 virtual int SendExposureSequence() const
1519 {
1521 }
1522
1523 virtual bool IsCapturing() = 0;
1524
1525 virtual void AddTag(const char* key, const char* deviceLabel, const char* value)
1526 {
1527 std::string k;
1528 if (deviceLabel != std::string("_"))
1529 {
1530 k += deviceLabel;
1531 k += '-';
1532 }
1533 k += key;
1534 addedTags_[k] = value;
1535 }
1536
1537 virtual void RemoveTag(const char* key)
1538 {
1539 addedTags_.erase(key);
1540 }
1541
1542 virtual bool SupportsMultiROI()
1543 {
1544 return false;
1545 }
1546
1547 virtual bool IsMultiROISet()
1548 {
1549 return false;
1550 }
1551
1552 virtual int GetMultiROICount(unsigned& /* count */)
1553 {
1555 }
1556
1557 virtual int SetMultiROI(const unsigned* /* xs */, const unsigned* /* ys */,
1558 const unsigned* /* widths */, const unsigned* /* heights */,
1559 unsigned /* numROIs */)
1560 {
1562 }
1563
1564 virtual int GetMultiROI(unsigned* /* xs */, unsigned* /* ys */,
1565 unsigned* /* widths */, unsigned* /* heights */, unsigned* /* length */)
1566 {
1568 }
1569
1570private:
1571 std::map<std::string, std::string> addedTags_;
1572};
1573
1574
1575
1576
1584template <class U>
1586{
1587public:
1588 CLegacyCameraBase() : busy_(false), stopWhenCBOverflows_(false), thd_(0)
1589 {
1590 thd_ = new BaseSequenceThread(this);
1591 }
1592
1594 {
1595 if (!thd_->IsStopped()) {
1596 thd_->Stop();
1597 thd_->wait();
1598 }
1599 delete thd_;
1600 }
1601
1602
1603 virtual bool Busy() {return busy_;}
1604
1610 virtual int StartSequenceAcquisition(double /*unused*/)
1611 {
1612 return StartSequenceAcquisition(LONG_MAX, 0.0, false);
1613 }
1614
1619 {
1620 if (!thd_->IsStopped()) {
1621 thd_->Stop();
1622 thd_->wait();
1623 }
1624
1625 return DEVICE_OK;
1626 }
1627
1628 // Implementation of a sequence acquisition as a series of snaps
1629 // This was a temporary method used for debugging, which is why its now
1630 // implemented in this legacy class. It's preferable that camera devices
1631 // inherit directly from CCameraBase and not use these default implementations.
1632 virtual int StartSequenceAcquisition(long numImages, double /*unused*/, bool stopOnOverflow)
1633 {
1634 if (IsCapturing())
1636
1637 int ret = this->GetCoreCallback()->PrepareForAcq(this);
1638 if (ret != DEVICE_OK)
1639 return ret;
1640 thd_->Start(numImages);
1641 stopWhenCBOverflows_ = stopOnOverflow;
1642 return DEVICE_OK;
1643 }
1644
1645 virtual bool IsCapturing(){return !thd_->IsStopped();}
1646
1647
1648protected:
1649 // Member functions that can be overridden by derived classes (these
1650 // customize the legacy snap-based sequence acquisition).
1651
1652 // Do actual capturing
1653 // Called from inside the thread
1654 virtual int ThreadRun (void)
1655 {
1656 int ret=DEVICE_ERR;
1657 ret = this->SnapImage();
1658 if (ret != DEVICE_OK)
1659 {
1660 return ret;
1661 }
1662 ret = InsertImage();
1663 if (ret != DEVICE_OK)
1664 {
1665 return ret;
1666 }
1667 return ret;
1668 };
1669
1670 virtual int InsertImage()
1671 {
1672 char label[MM::MaxStrLength];
1673 this->GetLabel(label);
1676 return this->GetCoreCallback()->InsertImage(this, this->GetImageBuffer(), this->GetImageWidth(),
1677 this->GetImageHeight(), this->GetImageBytesPerPixel(),
1678 md.Serialize());
1679 }
1680
1681 virtual double GetIntervalMs() {return 0.0;}
1682 virtual long GetImageCounter() {return thd_->GetImageCounter();}
1683 virtual long GetNumberOfImages() {return thd_->GetNumberOfImages();}
1684
1685 // called from the thread function before exit
1686 virtual void OnThreadExiting()
1687 {
1688 try
1689 {
1691 if (this->GetCoreCallback() != nullptr) {
1692 this->GetCoreCallback()->AcqFinished(this, 0);
1693 }
1694 }
1695 catch(...)
1696 {
1698 }
1699 }
1700
1701 virtual bool isStopOnOverflow() {return stopWhenCBOverflows_;}
1702 virtual void setStopOnOverflow(bool stop) {stopWhenCBOverflows_ = stop;}
1703
1705 // Helper Class
1707 {
1708 bool restart_;
1709 CLegacyCameraBase* pCam_;
1710
1711 public:
1713 :pCam_(pCam)
1714 {
1715 restart_=pCam_->IsCapturing();
1716 }
1717 operator bool()
1718 {
1719 return restart_;
1720 }
1721 };
1723
1724 // Nested class for live streaming
1727 {
1728 friend class CLegacyCameraBase;
1729 enum { default_numImages=1 };
1730 public:
1732 :numImages_(default_numImages)
1733 ,imageCounter_(0)
1734 ,stop_(true)
1735 ,suspend_(false)
1736 ,camera_(pCam)
1737 ,startTime_(0)
1738 ,actualDuration_(0)
1739 ,lastFrameTime_(0)
1740 {};
1741
1743
1744 void Stop() {
1745 MMThreadGuard g(this->stopLock_);
1746 stop_=true;
1747 }
1748
1749 void Start(long numImages)
1750 {
1751 MMThreadGuard g1(this->stopLock_);
1752 MMThreadGuard g2(this->suspendLock_);
1753 numImages_=numImages;
1754 imageCounter_=0;
1755 stop_ = false;
1756 suspend_=false;
1757 activate();
1758 actualDuration_ = MM::MMTime{};
1759 startTime_= camera_->GetCurrentMMTime();
1760 lastFrameTime_ = MM::MMTime{};
1761 }
1763 MMThreadGuard g(this->stopLock_);
1764 return stop_;
1765 }
1766 void Suspend() {
1767 MMThreadGuard g(this->suspendLock_);
1768 suspend_ = true;
1769 }
1771 MMThreadGuard g(this->suspendLock_);
1772 return suspend_;
1773 }
1774 void Resume() {
1775 MMThreadGuard g(this->suspendLock_);
1776 suspend_ = false;
1777 }
1778 void SetLength(long images) {numImages_ = images;}
1779
1780 long GetImageCounter(){return imageCounter_;}
1781 MM::MMTime GetStartTime(){return startTime_;}
1782 MM::MMTime GetActualDuration(){return actualDuration_;}
1783
1784 CLegacyCameraBase* GetCamera() {return camera_;}
1785 long GetNumberOfImages() {return numImages_;}
1786
1787 void UpdateActualDuration() {actualDuration_ = camera_->GetCurrentMMTime() - startTime_;}
1788
1789 private:
1790 virtual int svc()
1791 {
1792 int ret=DEVICE_ERR;
1793 try
1794 {
1795 do
1796 {
1797 ret=camera_->ThreadRun();
1798 } while (DEVICE_OK == ret && !IsStopped() && imageCounter_++ < numImages_-1);
1799 if (IsStopped())
1800 camera_->LogMessage("SeqAcquisition interrupted by the user\n");
1801
1802 }catch(...){
1803 camera_->LogMessage(g_Msg_EXCEPTION_IN_THREAD, false);
1804 }
1805 stop_=true;
1807 camera_->OnThreadExiting();
1808 return ret;
1809 }
1810 private:
1811 long numImages_;
1812 long imageCounter_;
1813 bool stop_;
1814 bool suspend_;
1815 CLegacyCameraBase* camera_;
1816 MM::MMTime startTime_;
1817 MM::MMTime actualDuration_;
1818 MM::MMTime lastFrameTime_;
1819 MMThreadLock stopLock_;
1820 MMThreadLock suspendLock_;
1821 };
1823
1824
1825private:
1826
1827 bool busy_;
1828 bool stopWhenCBOverflows_;
1829
1830 BaseSequenceThread * thd_;
1832};
1833
1834
1838template <class U>
1839class CStageBase : public CDeviceBase<MM::Stage, U>
1840{
1841 virtual int GetPositionUm(double& pos) = 0;
1842 virtual int SetPositionUm(double pos) = 0;
1843
1849 virtual int SetRelativePositionUm(double d)
1850 {
1851 double pos;
1852 int ret = GetPositionUm(pos);
1853 if (ret != DEVICE_OK)
1854 return ret;
1855 return SetPositionUm(pos + d);
1856 }
1857
1858 virtual int SetAdapterOriginUm(double /*d*/)
1859 {
1861 }
1862
1863 virtual int Move(double /*velocity*/)
1864 {
1866 }
1867
1868 virtual int Stop()
1869 {
1870 // Historically, Move() has been in this interface longer than Stop(), so
1871 // there is a chance that a stage implements Move() but not Stop(). In
1872 // which case zero velocity is the best thing to do.
1873 return Move(0.0);
1874 }
1875
1876 virtual int Home()
1877 {
1879 }
1880
1881 virtual int GetFocusDirection(MM::FocusDirection& direction)
1882 {
1883 // FocusDirectionUnknown is a safe default for all stages. Override this
1884 // only if direction is known for sure (i.e. does not depend on how the
1885 // hardware is installed).
1886 direction = MM::FocusDirectionUnknown;
1887 return DEVICE_OK;
1888 }
1889
1893 virtual int UsesOnStagePositionChanged(bool& result) const
1894 {
1895 result = false;
1896 return DEVICE_OK;
1897 }
1898
1899 virtual int IsStageLinearSequenceable(bool& isSequenceable) const
1900 {
1901 isSequenceable = false;
1902 return DEVICE_OK;
1903 }
1904
1905 virtual int GetStageSequenceMaxLength(long& /*nrEvents*/) const
1906 {
1908 }
1909
1910 virtual int StartStageSequence()
1911 {
1913 }
1914
1915 virtual int StopStageSequence()
1916 {
1918 }
1919
1920 virtual int ClearStageSequence()
1921 {
1923 }
1924
1925 virtual int AddToStageSequence(double /*position*/)
1926 {
1928 }
1929
1930 virtual int SendStageSequence()
1931 {
1933 }
1934
1935 virtual int SetStageLinearSequence(double, long)
1936 {
1938 }
1939};
1940
1947template <class U>
1948class CXYStageBase : public CDeviceBase<MM::XYStage, U>
1949{
1950public:
1951 CXYStageBase() : originXSteps_(0), originYSteps_(0), xPos_(0), yPos_(0)
1952 {
1953 // set-up directionality properties
1957
1961 }
1962
1963 // This converts an absolute position (x_um, y_um), under the current
1964 // adapter origin and x/y mirroring, to an absolute step position. Do not
1965 // use for relative offsets.
1966 std::pair<long, long> ConvertPositionUmToSteps(double x_um, double y_um)
1967 {
1968 bool mirrorX, mirrorY;
1969 GetOrientation(mirrorX, mirrorY);
1970
1971 long xSteps{}, ySteps{};
1972 if (mirrorX)
1973 xSteps = originXSteps_ - nint (x_um / this->GetStepSizeXUm());
1974 else
1975 xSteps = originXSteps_ + nint (x_um / this->GetStepSizeXUm());
1976 if (mirrorY)
1977 ySteps = originYSteps_ - nint (y_um / this->GetStepSizeYUm());
1978 else
1979 ySteps = originYSteps_ + nint (y_um / this->GetStepSizeYUm());
1980
1981 return {xSteps, ySteps};
1982 }
1983
1984 // This converts an absolute position (xSteps, ySteps), under the current
1985 // adapter origin and x/y mirroring, to an absolute um position. Do not use
1986 // for relative offsets.
1987 std::pair<double, double> ConvertPositionStepsToUm(long xSteps, long ySteps)
1988 {
1989 bool mirrorX, mirrorY;
1990 GetOrientation(mirrorX, mirrorY);
1991
1992 double x_um{}, y_um{};
1993 if (mirrorX)
1994 x_um = (originXSteps_ - xSteps) * this->GetStepSizeXUm();
1995 else
1996 x_um = - ((originXSteps_ - xSteps) * this->GetStepSizeXUm());
1997
1998 if (mirrorY)
1999 y_um = (originYSteps_ - ySteps) * this->GetStepSizeYUm();
2000 else
2001 y_um = - ((originYSteps_ - ySteps) * this->GetStepSizeYUm());
2002
2003 return {x_um, y_um};
2004 }
2005
2006 virtual int SetPositionUm(double x_um, double y_um)
2007 {
2008 auto posSteps = ConvertPositionUmToSteps(x_um, y_um);
2009 long xSteps = posSteps.first;
2010 long ySteps = posSteps.second;
2011
2012 int ret = this->SetPositionSteps(xSteps, ySteps);
2013 if (ret == DEVICE_OK) {
2014 xPos_ = x_um;
2015 yPos_ = y_um;
2016 }
2017 return ret;
2018 }
2019
2025 virtual int SetRelativePositionUm(double dx, double dy)
2026 {
2027 bool mirrorX, mirrorY;
2028 GetOrientation(mirrorX, mirrorY);
2029 double xPos = xPos_ + dx;
2030 double yPos = yPos_ + dy;
2031
2032 if (mirrorX)
2033 dx = -dx;
2034 if (mirrorY)
2035 dy = -dy;
2036
2037 int ret = SetRelativePositionSteps(nint(dx / this->GetStepSizeXUm()), nint(dy / this->GetStepSizeYUm()));
2038 if (ret == DEVICE_OK) {
2039 xPos_ = xPos;
2040 yPos_ = yPos;
2041 }
2042 return ret;
2043 }
2044
2052 virtual int SetAdapterOriginUm(double newXUm, double newYUm)
2053 {
2054 bool mirrorX, mirrorY;
2055 GetOrientation(mirrorX, mirrorY);
2056
2057 long xStep, yStep;
2058 int ret = this->GetPositionSteps(xStep, yStep);
2059 if (ret != DEVICE_OK)
2060 return ret;
2061
2062 if (mirrorX)
2063 originXSteps_ = xStep + nint(newXUm / this->GetStepSizeXUm());
2064 else
2065 originXSteps_ = xStep - nint(newXUm / this->GetStepSizeXUm());
2066 if (mirrorY)
2067 originYSteps_ = yStep + nint(newYUm / this->GetStepSizeYUm());
2068 else
2069 originYSteps_ = yStep - nint(newYUm / this->GetStepSizeYUm());
2070
2071 return DEVICE_OK;
2072 }
2073
2074 virtual int GetPositionUm(double& x_um, double& y_um)
2075 {
2076 long xSteps, ySteps;
2077 int ret = this->GetPositionSteps(xSteps, ySteps);
2078 if (ret != DEVICE_OK)
2079 return ret;
2080
2081 auto pos_um = ConvertPositionStepsToUm(xSteps, ySteps);
2082 x_um = pos_um.first;
2083 y_um = pos_um.second;
2084
2085 xPos_ = x_um;
2086 yPos_ = y_um;
2087
2088 return DEVICE_OK;
2089 }
2090
2097 virtual int SetRelativePositionSteps(long x, long y)
2098 {
2099 long xSteps, ySteps;
2100 int ret = this->GetPositionSteps(xSteps, ySteps);
2101 if (ret != DEVICE_OK)
2102 return ret;
2103
2104 return this->SetPositionSteps(xSteps+x, ySteps+y);
2105 }
2106
2110 virtual int UsesOnXYStagePositionChanged(bool& result) const
2111 {
2112 result = false;
2113 return DEVICE_OK;
2114 }
2115
2116 virtual int Move(double /*vx*/, double /*vy*/)
2117 {
2119 }
2120
2121 virtual int SetXOrigin()
2122 {
2124 }
2125
2126 virtual int SetYOrigin()
2127 {
2129 }
2130
2131 virtual int GetXYStageSequenceMaxLength(long& /*nrEvents*/) const
2132 {
2134 }
2135
2137 {
2139 }
2140
2142 {
2144 }
2145
2147 {
2149 }
2150
2151 virtual int AddToXYStageSequence(double /*positionX*/, double /*positionY*/)
2152 {
2154 }
2155
2157 {
2159 }
2160
2161protected:
2162
2174 double GetCachedXUm() {return xPos_;}
2175 double GetCachedYUm() {return yPos_;}
2176
2177private:
2178
2179 void GetOrientation(bool& mirrorX, bool& mirrorY)
2180 {
2181 char val[MM::MaxStrLength];
2182 int ret = this->GetProperty(MM::g_Keyword_Transpose_MirrorX, val);
2183 assert(ret == DEVICE_OK);
2184 mirrorX = strcmp(val, "1") == 0 ? true : false;
2185
2187 assert(ret == DEVICE_OK);
2188 mirrorY = strcmp(val, "1") == 0 ? true : false;
2189 }
2190
2191
2192 // absolute coordinate translation data
2193 long originXSteps_;
2194 long originYSteps_;
2195 double xPos_;
2196 double yPos_;
2197};
2198
2202template <class U>
2203class CShutterBase : public CDeviceBase<MM::Shutter, U>
2204{
2205};
2206
2210template <class U>
2211class CSerialBase : public CDeviceBase<MM::Serial, U>
2212{
2213};
2214
2218template <class U>
2219class CAutoFocusBase : public CDeviceBase<MM::AutoFocus, U>
2220{
2221 virtual int AutoSetParameters() {return DEVICE_UNSUPPORTED_COMMAND;}
2222};
2223
2227template <class U>
2228class CImageProcessorBase : public CDeviceBase<MM::ImageProcessor, U>
2229{
2230};
2231
2235template <class U>
2236class CSignalIOBase : public CDeviceBase<MM::SignalIO, U>
2237{
2238 virtual int GetDASequenceMaxLength(long& /*nrEvents*/) const
2239 {
2241 }
2242
2243 virtual int StartDASequence()
2244 {
2246 }
2247
2248 virtual int StopDASequence() {
2250 }
2251
2252 virtual int ClearDASequence() {
2254 }
2255
2256 virtual int AddToDASequence(double /*voltage*/)
2257 {
2259 }
2260
2261 virtual int SendDASequence() {
2263 }
2264};
2265
2269template <class U>
2270class CMagnifierBase : public CDeviceBase<MM::Magnifier, U>
2271{
2272};
2273
2277template <class U>
2278class CSLMBase : public CDeviceBase<MM::SLM, U>
2279{
2280 virtual int GetSLMSequenceMaxLength(long& /*nrEvents*/) const
2281 {
2283 }
2284
2285 virtual int StartSLMSequence()
2286 {
2288 }
2289
2290 virtual int StopSLMSequence() {
2292 }
2293
2294 virtual int ClearSLMSequence() {
2296 }
2297
2298 virtual int AddToSLMSequence(const unsigned char * const /*image*/)
2299 {
2301 }
2302
2303 virtual int AddToSLMSequence(const unsigned int * const /*image*/)
2304 {
2306 }
2307
2308 virtual int SendSLMSequence() {
2310 }
2311};
2312
2316template <class U>
2317class CGalvoBase : public CDeviceBase<MM::Galvo, U>
2318{
2319 double GetXMinimum() { return 0.0;};
2320 double GetYMinimum() { return 0.0;};
2321};
2322
2327template <class U>
2328class HubBase : public CDeviceBase<MM::Hub, U>
2329{
2330public:
2332 virtual ~HubBase() {}
2333
2342 virtual int DetectInstalledDevices() {return DEVICE_OK;}
2343
2350 virtual unsigned GetNumberOfInstalledDevices() {return (unsigned)installedDevices.size();}
2351
2358 virtual MM::Device* GetInstalledDevice(int devIdx) {return installedDevices[devIdx];}
2359
2367 {
2368 for (unsigned i=0; i<installedDevices.size(); i++)
2369 delete installedDevices[i];
2370 installedDevices.clear();
2371 }
2372
2373protected:
2374 void AddInstalledDevice(MM::Device* pdev) {installedDevices.push_back(pdev);}
2375
2376private:
2377 std::vector<MM::Device*> installedDevices;
2378
2379};
2380
2385template <class U>
2386class CStateDeviceBase : public CDeviceBase<MM::State, U>
2387{
2388public:
2389
2391
2392 CStateDeviceBase(): gateOpen_(true)
2393 {
2394 // set-up Position to move to when the state device's gate is closed
2395 // Allowed values should be set in the state device adapter
2396 // this->CreateProperty(MM::g_Keyword_Closed_Position, "0", MM::String, false);
2397 }
2398
2404 virtual int SetPosition(long pos)
2405 {
2407 }
2408
2414 virtual int SetPosition(const char* label)
2415 {
2416 std::map<std::string, long>::const_iterator it;
2417 it = labels_.find(label);
2418 if (it == labels_.end())
2419 return DEVICE_UNKNOWN_LABEL;
2420
2421 return SetPosition(it->second);
2422 }
2423
2424
2432 virtual int SetGateOpen(bool open)
2433 {
2434 if (gateOpen_ != open) {
2435 gateOpen_ = open;
2436 long position;
2437 int ret = GetPosition(position);
2438 if (ret != DEVICE_OK)
2439 return ret;
2440 return SetPosition(position);
2441 }
2442 return DEVICE_OK;
2443 }
2444
2445 virtual int GetGateOpen(bool& open)
2446 {
2447 open = gateOpen_;
2448 return DEVICE_OK;
2449 }
2450
2456 virtual int GetPosition(long& pos) const
2457 {
2458 char buf[MM::MaxStrLength];
2459 assert(this->HasProperty(MM::g_Keyword_State));
2460 int ret = this->GetProperty(MM::g_Keyword_State, buf);
2461 if (ret == DEVICE_OK)
2462 {
2463 pos = atol(buf);
2464 return DEVICE_OK;
2465 }
2466 else
2467 return ret;
2468 }
2469
2475 virtual int GetPosition(char* label) const
2476 {
2477 long pos;
2478 int ret = GetPosition(pos);
2479 if (ret == DEVICE_OK)
2480 return GetPositionLabel(pos, label);
2481 else
2482 return ret;
2483 }
2484
2488 virtual int GetPositionLabel(long pos, char* label) const
2489 {
2490 std::map<std::string, long>::const_iterator it;
2491 for (it=labels_.begin(); it!=labels_.end(); it++)
2492 {
2493 //string devLabel = it->first;
2494 //long devPosition = it->second;
2495 if (it->second == pos)
2496 {
2497 CDeviceUtils::CopyLimitedString(label, it->first.c_str());
2498 return DEVICE_OK;
2499 }
2500 }
2501
2502 // label not found
2504 }
2505
2510 virtual int SetPositionLabel(long pos, const char* label)
2511 {
2512 // first test if the label already exists with different position defined
2513 std::map<std::string, long>::iterator it;
2514 it = labels_.find(label);
2515 if (it != labels_.end() && it->second != pos)
2516 {
2517 // remove the existing one
2518 labels_.erase(it);
2519 }
2520
2521 // then test if the given position already has a label
2522 for (it=labels_.begin(); it!=labels_.end(); it++)
2523 {
2524 if (it->second == pos)
2525 {
2526 labels_.erase(it);
2527 break;
2528 }
2529 }
2530
2531 // finally we can add the new label-position mapping
2532 labels_[label] = pos;
2533
2534 // attempt to define allowed values for label property (if it exists),
2535 // and don't make any fuss if the operation fails
2536 std::string strLabel(label);
2537 std::vector<std::string> values;
2538 for (it=labels_.begin(); it!=labels_.end(); it++)
2539 values.push_back(it->first);
2541
2542 return DEVICE_OK;
2543 }
2544
2548 virtual int GetLabelPosition(const char* label, long& pos) const
2549 {
2550 std::map<std::string, long>::const_iterator it;
2551 it = labels_.find(label);
2552 if (it == labels_.end())
2553 return DEVICE_UNKNOWN_LABEL;
2554
2555 pos = it->second;
2556 return DEVICE_OK;
2557 }
2558
2563 {
2564 if (eAct == MM::BeforeGet)
2565 {
2566 char buf[MM::MaxStrLength];
2567 int ret = GetPosition(buf);
2568 if (ret != DEVICE_OK)
2569 return ret;
2570 pProp->Set(buf);
2571 }
2572 else if (eAct == MM::AfterSet)
2573 {
2574 std::string label;
2575 pProp->Get(label);
2576 int ret = SetPosition(label.c_str());
2577 if (ret != DEVICE_OK)
2578 return ret;
2579 }
2580 else if (eAct == MM::IsSequenceable)
2581 {
2582 assert(this->HasProperty(MM::g_Keyword_State));
2583 bool sequenceable;
2584 int ret = this->IsPropertySequenceable(MM::g_Keyword_State, sequenceable);
2585 if (ret != DEVICE_OK)
2586 return ret;
2587
2588 long nrEvents = 0;
2589 if (sequenceable) {
2591 if (ret != DEVICE_OK)
2592 return ret;
2593 }
2594 pProp->SetSequenceable(nrEvents);
2595 }
2596 else if (eAct == MM::AfterLoadSequence) {
2597 assert(this->HasProperty(MM::g_Keyword_State));
2598 std::vector<std::string> sequence = pProp->GetSequence();
2599 for (std::vector<std::string>::iterator it = sequence.begin(); it != sequence.end(); ++it) {
2600 long pos;
2601 int ret = GetLabelPosition((*it).c_str(), pos);
2602 if (ret != DEVICE_OK)
2603 return ret;
2604 std::stringstream s;
2605 s << pos;
2606 s >> *it;
2607 }
2608
2610 if (ret != DEVICE_OK)
2611 return ret;
2612
2613 std::vector<std::string>::iterator it;
2614 for ( it=sequence.begin() ; it < sequence.end(); it++ )
2615 {
2616 ret = this->AddToPropertySequence(MM::g_Keyword_State, (*it).c_str());
2617 if (ret != DEVICE_OK)
2618 return ret;
2619 }
2620
2622 if (ret != DEVICE_OK)
2623 return ret;
2624
2625 //this->LoadPropertySequence(MM::g_Keyword_State, sequence);
2626 }
2627 else if (eAct == MM::StartSequence) {
2628 assert(this->HasProperty(MM::g_Keyword_State));
2630 }
2631 else if (eAct == MM::StopSequence) {
2632 assert(this->HasProperty(MM::g_Keyword_State));
2634 }
2635
2636 return DEVICE_OK;
2637 }
2638
2643 int OnStateChanged(long position) {
2644 int ret;
2646 if (ret != DEVICE_OK) {
2647 return ret;
2648 }
2649
2650 char label[MM::MaxStrLength];
2651 GetPositionLabel(position, label);
2652 ret = this->OnPropertyChanged(MM::g_Keyword_Label, label);
2653 return ret;
2654 }
2655
2656private:
2657 bool gateOpen_;
2658
2659private:
2660 std::map<std::string, long> labels_;
2661};
2662
2666template <class U>
2667class CVolumetricPumpBase : public CDeviceBase<MM::VolumetricPump, U>
2668{
2669 int Home()
2670 {
2672 }
2673
2674 int InvertDirection(bool /*state*/)
2675 {
2677 }
2678};
2679
2683template <class U>
2684class CPressurePumpBase : public CDeviceBase<MM::PressurePump, U>
2685{
2686 int Calibrate()
2687 {
2689 }
2690};
const char *const g_Msg_DUPLICATE_PROPERTY
Definition DeviceBase.h:49
const char *const g_Msg_INTERNAL_INCONSISTENCY
Definition DeviceBase.h:53
const char *const g_Msg_DEVICE_NOT_YET_IMPLEMENTED
Definition DeviceBase.h:81
const char *const g_Msg_DEVICE_CAN_NOT_SET_PROPERTY
Definition DeviceBase.h:75
const char *const g_Msg_DEVICE_CAMERA_BUSY_ACQUIRING
Definition DeviceBase.h:74
const char *const g_Msg_EXCEPTION_IN_THREAD
Definition DeviceBase.h:71
const char *const g_Msg_DEVICE_COMM_HUB_MISSING
Definition DeviceBase.h:77
const char *const g_Msg_NO_PROPERTY_DATA
Definition DeviceBase.h:63
const char *const g_Msg_SERIAL_TIMEOUT
Definition DeviceBase.h:61
const char *const g_Msg_EXCEPTION_IN_ON_THREAD_EXITING
Definition DeviceBase.h:72
const char *const g_Msg_UNKNOWN_LABEL
Definition DeviceBase.h:55
const char *const g_Msg_INVALID_PROPERTY
Definition DeviceBase.h:47
const char *const g_Msg_BUFFER_OVERFLOW
Definition DeviceBase.h:66
const char *const g_Msg_SERIAL_INVALID_RESPONSE
Definition DeviceBase.h:60
const char *const g_Msg_DEVICE_PROPERTY_NOT_SEQUENCEABLE
Definition DeviceBase.h:79
const char *const g_Msg_DEVICE_NONEXISTENT_CHANNEL
Definition DeviceBase.h:68
const char *const g_Msg_SERIAL_BUFFER_OVERRUN
Definition DeviceBase.h:59
long nint(double value)
Definition DeviceBase.h:83
const char *const g_Msg_DEVICE_NOT_CONNECTED
Definition DeviceBase.h:76
const char *const g_Msg_DEVICE_SEQUENCE_TOO_LARGE
Definition DeviceBase.h:80
const char *const g_Msg_INVALID_INPUT_PARAM
Definition DeviceBase.h:65
const char *const g_Msg_UNSUPPORTED_COMMAND
Definition DeviceBase.h:56
const char *const g_Msg_SELF_REFERENCE
Definition DeviceBase.h:62
const char *const g_Msg_SEQUENCE_ACQUISITION_THREAD_EXITING
Definition DeviceBase.h:73
const char *const g_Msg_DEVICE_DUPLICATE_LIBRARY
Definition DeviceBase.h:78
const char *const g_Msg_UNSUPPORTED_DATA_FORMAT
Definition DeviceBase.h:52
const char *const g_Msg_SERIAL_COMMAND_FAILED
Definition DeviceBase.h:67
const char *const g_Msg_NOT_SUPPORTED
Definition DeviceBase.h:54
const char *const g_Msg_UNKNOWN_POSITION
Definition DeviceBase.h:57
const char *const g_Msg_DEVICE_INVALID_PROPERTY_LIMTS
Definition DeviceBase.h:69
const char *const g_Msg_INVALID_PROPERTY_VALUE
Definition DeviceBase.h:48
const char *const g_Msg_INVALID_PROPERTY_TYPE
Definition DeviceBase.h:50
const char *const g_Msg_NO_CALLBACK_REGISTERED
Definition DeviceBase.h:58
const char *const g_Msg_DEVICE_DUPLICATE_LABEL
Definition DeviceBase.h:64
const char *const g_Msg_ERR
Definition DeviceBase.h:46
const char *const g_Msg_NATIVE_MODULE_FAILED
Definition DeviceBase.h:51
#define DEVICE_NO_CALLBACK_REGISTERED
Definition MMDeviceConstants.h:60
#define DEVICE_SEQUENCE_TOO_LARGE
Definition MMDeviceConstants.h:86
#define DEVICE_NOT_SUPPORTED
Definition MMDeviceConstants.h:56
#define DEVICE_DUPLICATE_PROPERTY
Definition MMDeviceConstants.h:51
#define DEVICE_SERIAL_INVALID_RESPONSE
Definition MMDeviceConstants.h:63
#define DEVICE_UNKNOWN_LABEL
Definition MMDeviceConstants.h:57
#define DEVICE_PROPERTY_NOT_SEQUENCEABLE
Definition MMDeviceConstants.h:85
#define DEVICE_NO_PROPERTY_DATA
Definition MMDeviceConstants.h:66
#define DEVICE_BUFFER_OVERFLOW
Definition MMDeviceConstants.h:69
#define DEVICE_UNSUPPORTED_DATA_FORMAT
Definition MMDeviceConstants.h:54
#define DEVICE_NONEXISTENT_CHANNEL
Definition MMDeviceConstants.h:70
#define DEVICE_CAMERA_BUSY_ACQUIRING
Definition MMDeviceConstants.h:77
#define DEVICE_UNSUPPORTED_COMMAND
Definition MMDeviceConstants.h:58
#define DEVICE_ERR
Definition MMDeviceConstants.h:48
#define DEVICE_SERIAL_TIMEOUT
Definition MMDeviceConstants.h:64
#define DEVICE_NATIVE_MODULE_FAILED
Definition MMDeviceConstants.h:53
#define DEVICE_OK
Definition MMDeviceConstants.h:47
#define DEVICE_INVALID_PROPERTY_TYPE
Definition MMDeviceConstants.h:52
#define DEVICE_SELF_REFERENCE
Definition MMDeviceConstants.h:65
#define DEVICE_DUPLICATE_LABEL
Definition MMDeviceConstants.h:67
#define DEVICE_SERIAL_BUFFER_OVERRUN
Definition MMDeviceConstants.h:62
#define DEVICE_INTERNAL_INCONSISTENCY
Definition MMDeviceConstants.h:55
#define DEVICE_UNKNOWN_POSITION
Definition MMDeviceConstants.h:59
#define DEVICE_SERIAL_COMMAND_FAILED
Definition MMDeviceConstants.h:61
#define DEVICE_DUPLICATE_LIBRARY
Definition MMDeviceConstants.h:84
#define DEVICE_CAN_NOT_SET_PROPERTY
Definition MMDeviceConstants.h:79
#define DEVICE_INVALID_PROPERTY_VALUE
Definition MMDeviceConstants.h:50
#define DEVICE_INVALID_PROPERTY
Definition MMDeviceConstants.h:49
#define DEVICE_COMM_HUB_MISSING
Definition MMDeviceConstants.h:83
#define DEVICE_INVALID_PROPERTY_LIMTS
Definition MMDeviceConstants.h:71
#define DEVICE_NOT_CONNECTED
Definition MMDeviceConstants.h:82
#define DEVICE_LOCALLY_DEFINED_ERROR
Definition MMDeviceConstants.h:81
#define DEVICE_NOT_YET_IMPLEMENTED
Definition MMDeviceConstants.h:88
#define DEVICE_INVALID_INPUT_PARAM
Definition MMDeviceConstants.h:68
Base class for creating auto-focusing modules.
Definition DeviceBase.h:2220
Base class for creating camera device adapters.
Definition DeviceBase.h:1378
virtual int StartSequenceAcquisition(double unused)=0
Start continuous sequence acquisition.
virtual int GetMultiROI(unsigned *, unsigned *, unsigned *, unsigned *, unsigned *)
Definition DeviceBase.h:1564
virtual int StopExposureSequence()
Definition DeviceBase.h:1503
virtual int StartSequenceAcquisition(long numImages, double unused, bool stopOnOverflow)=0
Start sequence acquisition.
virtual int SetMultiROI(const unsigned *, const unsigned *, const unsigned *, const unsigned *, unsigned)
Definition DeviceBase.h:1557
virtual bool SupportsMultiROI()
Definition DeviceBase.h:1542
virtual unsigned GetImageBytesPerPixel() const =0
Return image buffer pixel depth in bytes.
virtual int GetExposureSequenceMaxLength(long &) const
Definition DeviceBase.h:1493
virtual int StartExposureSequence()
Definition DeviceBase.h:1498
virtual int GetMultiROICount(unsigned &)
Definition DeviceBase.h:1552
CCameraBase()
Definition DeviceBase.h:1389
virtual unsigned GetImageHeight() const =0
Return image buffer Y-size in pixels.
virtual int StopSequenceAcquisition()=0
Stop and wait for the thread to finish.
virtual void RemoveTag(const char *key)
Remove an existing tag from the metadata associated with this device.
Definition DeviceBase.h:1537
virtual int AddToExposureSequence(double)
Definition DeviceBase.h:1513
virtual int ClearExposureSequence()
Definition DeviceBase.h:1508
virtual unsigned GetNumberOfChannels() const
Return the number of channels.
Definition DeviceBase.h:1436
virtual bool Busy()=0
virtual int SendExposureSequence() const
Definition DeviceBase.h:1518
virtual const unsigned char * GetImageBuffer()=0
Return pixel data.
virtual bool IsMultiROISet()
Definition DeviceBase.h:1547
virtual unsigned GetNumberOfComponents() const
Return the number of components in this image.
Definition DeviceBase.h:1425
virtual int SnapImage()=0
Perform exposure and grab a single image.
virtual unsigned GetImageWidth() const =0
Return image buffer X-size in pixels.
virtual void AddTag(const char *key, const char *deviceLabel, const char *value)
Add new tag or modify the value of an existing one.
Definition DeviceBase.h:1525
virtual const unsigned char * GetImageBuffer(unsigned)
Return the image buffer for a specific channel.
Definition DeviceBase.h:1460
virtual bool IsCapturing()=0
Indicate whether sequence acquisition is currently running.
virtual const unsigned int * GetImageBufferAsRGB32()
Return pixel data with interleaved RGB pixels in 32 bpp format.
Definition DeviceBase.h:1467
virtual void GetTags(char *serializedMetadata)
Fill serializedMetadata with the device's metadata tags.
Definition DeviceBase.h:1475
virtual int GetChannelName(unsigned, char *name)
Return the channel name.
Definition DeviceBase.h:1448
Implement functionality common to all devices.
Definition DeviceBase.h:97
MM::Action< U > CPropertyAction
Definition DeviceBase.h:100
virtual bool GetErrorText(int errorCode, char *text) const
Obtain the error text associated with the error code.
Definition DeviceBase.h:788
virtual bool GetPropertyName(unsigned uIdx, char *name) const
Obtain the property name given the index.
Definition DeviceBase.h:516
const char * GetMorePropertyErrorInfo(void) const
Definition DeviceBase.h:864
int CreateStringProperty(const char *name, const char *value, bool readOnly, MM::ActionFunctor *pAct=0, bool isPreInitProperty=false)
Create a string-valued property for the device.
Definition DeviceBase.h:674
void InitializeDefaultErrorMessages()
Set up the standard set of error codes and error messages.
Definition DeviceBase.h:960
int LogMessageCode(const int errorCode, bool debugOnly=false) const
Output the text message of specified code to the log stream.
Definition DeviceBase.h:909
bool IsPropertyEqualTo(const char *name, const char *val) const
Check if the property value is equal to a specific string.
Definition DeviceBase.h:245
int CreateFloatProperty(const char *name, double value, bool readOnly, MM::ActionFunctor *pAct=0, bool isPreInitProperty=false)
Create a float-valued property for the device.
Definition DeviceBase.h:656
void SetErrorText(int errorCode, const char *text)
Define the error text associated with the code.
Definition DeviceBase.h:859
virtual void SetDelayMs(double delay)
Set the device delay used for synchronization by the calling code.
Definition DeviceBase.h:171
unsigned long GetClockTicksUs()
Get the system ticks in microseconds.
Definition DeviceBase.h:1212
CDeviceBase()
Definition DeviceBase.h:850
int UpdateStatus()
Refresh the entire state of the device and synchronize property values with the actual state of the h...
Definition DeviceBase.h:763
int OnPropertiesChanged()
Signal that something changed in the property structure.
Definition DeviceBase.h:1124
int SetPropertyLimits(const char *name, double low, double high)
Define limits for properties with a continuous range of values.
Definition DeviceBase.h:682
int CreateIntegerProperty(const char *name, long value, bool readOnly, MM::ActionFunctor *pAct=0, bool isPreInitProperty=false)
Create an integer-valued property for the device.
Definition DeviceBase.h:644
MM::Hub * GetParentHub() const
Return the parent Hub device pointer, or null if there isn't any.
Definition DeviceBase.h:1280
virtual void GetParentID(char *parentID) const
Definition DeviceBase.h:839
bool IsCallbackRegistered() const
Check if we have callback mechanism set up.
Definition DeviceBase.h:1234
MM::ActionEx< U > CPropertyActionEx
Definition DeviceBase.h:101
int CreateProperty(const char *name, const char *value, MM::PropertyType eType, bool readOnly, MM::ActionFunctor *pAct=0, bool isPreInitProperty=false)
Create a new property for the device.
Definition DeviceBase.h:618
int OnXYStagePositionChanged(double xPos, double yPos)
Report position change (for XY stage).
Definition DeviceBase.h:1170
int GetProperty(const char *name, long &val)
Obtain the value of the property.
Definition DeviceBase.h:228
int OnSLMExposureChanged(double exposure)
Signal that the SLM exposure has changed.
Definition DeviceBase.h:1190
int PurgeComPort(const char *portLabel)
Clear the serial port buffers.
Definition DeviceBase.h:1097
void EnableDelay(bool state=true)
Enable response to delay settings.
Definition DeviceBase.h:1253
virtual int StartPropertySequence(const char *name)
Start a (TTL-triggered) sequence for the given property.
Definition DeviceBase.h:403
int LogTimeDiff(MM::MMTime start, MM::MMTime end, bool debugOnly=false) const
Output time difference between two time stamps.
Definition DeviceBase.h:952
void CreateHubIDProperty()
Create read-only property displaying parentID (hub label).
Definition DeviceBase.h:1266
void GetLoadedDeviceOfType(MM::DeviceType devType, char *deviceName, const unsigned int deviceIterator)
Provide access to the names of devices of a given type.
Definition DeviceBase.h:1023
int ClearAllowedValues(const char *name)
Clear allowed values, and make any value valid.
Definition DeviceBase.h:712
int LogMessage(const char *msg, bool debugOnly=false) const
Output the specified text message to the log stream.
Definition DeviceBase.h:881
int OnPropertyChanged(const char *propName, const char *propValue)
Signal to the core that a property value has changed.
Definition DeviceBase.h:1134
virtual double GetDelayMs() const
Return device delay used for synchronization by the calling code.
Definition DeviceBase.h:163
virtual bool SupportsDeviceDetection(void)
Definition DeviceBase.h:817
virtual int ClearPropertySequence(const char *name)
Clear a property sequence.
Definition DeviceBase.h:460
virtual bool HasProperty(const char *name) const
Check if device supports a given property.
Definition DeviceBase.h:560
int GetSerialAnswer(const char *portName, const char *term, std::string &ans)
Get the received string from the serial port, waiting for the terminating character sequence.
Definition DeviceBase.h:1068
MM::Core * GetCoreCallback() const
Get the callback object.
Definition DeviceBase.h:1242
virtual bool UsesDelay()
Signal if the device responds to different delay settings.
Definition DeviceBase.h:183
int UpdateProperty(const char *name)
Update property value from the hardware.
Definition DeviceBase.h:771
T_HUB * AssignToHub()
Return the parent Hub device pointer, or null if there isn't any.
Definition DeviceBase.h:1294
virtual int AddToPropertySequence(const char *name, const char *value)
Add to a property sequence.
Definition DeviceBase.h:479
MM::PortType GetSerialPortType(const char *portLabel)
TODO-BRIEF.
Definition DeviceBase.h:1109
virtual int GetPropertySequenceMaxLength(const char *name, long &nrEvents) const
Provide the maximum number of events that can be executed by this sequenceable property.
Definition DeviceBase.h:372
virtual int HasPropertyLimits(const char *name, bool &hasLimits) const
Definition DeviceBase.h:295
MM::MMTime GetCurrentMMTime()
Get current time.
Definition DeviceBase.h:1223
virtual int StopPropertySequence(const char *name)
Stop a (TTL-triggered) sequence for the given property.
Definition DeviceBase.h:432
virtual void SetModuleName(const char *name)
Assign a name for the module (for use only by the calling code).
Definition DeviceBase.h:106
virtual unsigned GetNumberOfPropertyValues(const char *propertyName) const
Return the number of allowed property values.
Definition DeviceBase.h:575
virtual int SetProperty(const char *name, const char *value)
Set the property value.
Definition DeviceBase.h:545
virtual int SendPropertySequence(const char *name)
Send the property sequence to the device.
Definition DeviceBase.h:498
virtual void GetLabel(char *name) const
Return the device label (for use only by the calling code).
Definition DeviceBase.h:152
int LogMessage(const std::string &msg, bool debugOnly=false) const
Output the specified text message to the log stream.
Definition DeviceBase.h:895
virtual void GetDescription(char *name) const
Return device description (for use only by the calling code).
Definition DeviceBase.h:130
int WriteToComPort(const char *portLabel, const unsigned char *buf, unsigned bufLength)
Send an array of bytes to the COM port.
Definition DeviceBase.h:1036
virtual void SetLabel(const char *label)
Set the device label (for use only by the calling code).
Definition DeviceBase.h:141
virtual bool GetPropertyValueAt(const char *propertyName, unsigned index, char *value) const
Return the allowed value of the property, given its index.
Definition DeviceBase.h:593
virtual void GetModuleName(char *name) const
Return the module name (for use only by the calling code).
Definition DeviceBase.h:114
int SendSerialCommand(const char *portName, const char *command, const char *term)
Send an ASCII string with the specified terminating characters to the serial port.
Definition DeviceBase.h:1052
virtual void SetParentID(const char *parentId)
Definition DeviceBase.h:825
int GetPropertyData(const char *name, const char *value, long &data)
Obtain data field associated with the allowed property value.
Definition DeviceBase.h:736
int GetCurrentPropertyData(const char *name, long &data)
Obtain data field associated with the currently applied property value.
Definition DeviceBase.h:749
int OnMagnifierChanged()
Signal that the magnifier has changed.
Definition DeviceBase.h:1200
int OnStagePositionChanged(double pos)
Report position change (for single-axis stage).
Definition DeviceBase.h:1152
virtual unsigned GetNumberOfProperties() const
Return the number of properties.
Definition DeviceBase.h:188
virtual int GetProperty(const char *name, char *value) const
Obtain the value of the property.
Definition DeviceBase.h:196
int ApplyProperty(const char *name)
Apply the current property value to the hardware.
Definition DeviceBase.h:780
virtual MM::DeviceDetectionStatus DetectDevice(void)
Definition DeviceBase.h:820
virtual int GetPropertyType(const char *name, MM::PropertyType &pt) const
Obtain property type (string, float, or integer).
Definition DeviceBase.h:529
int ReadFromComPort(const char *portLabel, unsigned char *buf, unsigned bufLength, unsigned long &read)
Read the current contents of Rx serial buffer.
Definition DeviceBase.h:1087
int OnExposureChanged(double exposure)
Signal that the exposure has changed.
Definition DeviceBase.h:1180
virtual int GetPropertyInitStatus(const char *name, bool &preInit) const
Check whether the property is pre-init.
Definition DeviceBase.h:281
int LogTimeDiff(MM::MMTime start, MM::MMTime end, const std::string &message, bool debugOnly=false) const
Output time difference between two time stamps.
Definition DeviceBase.h:932
void SetMorePropertyErrorInfo(const char *ptext) const
Definition DeviceBase.h:869
virtual void SetDescription(const char *descr)
Assign description string for a device (for use only by the calling code).
Definition DeviceBase.h:122
virtual int GetPropertyLowerLimit(const char *name, double &lowLimit) const
Provide lower limit for a property that has property limits.
Definition DeviceBase.h:314
virtual int GetPropertyUpperLimit(const char *name, double &hiLimit) const
Provide upper limit for a property that has property limits.
Definition DeviceBase.h:333
virtual int GetPropertyReadOnly(const char *name, bool &readOnly) const
Check whether the property is read-only.
Definition DeviceBase.h:261
int GetProperty(const char *name, double &val)
Obtain the value of the property.
Definition DeviceBase.h:213
MM::Device * GetDevice(const char *deviceLabel) const
Get the handle (pointer) to the specified device label.
Definition DeviceBase.h:1004
int AddAllowedValue(const char *name, const char *value)
Add a single allowed value.
Definition DeviceBase.h:720
int SetAllowedValues(const char *name, std::vector< std::string > &values)
Set an entire array of allowed values.
Definition DeviceBase.h:704
int AddAllowedValue(const char *name, const char *value, long data)
Add a single allowed value, plus additional data.
Definition DeviceBase.h:728
int CreatePropertyWithHandler(const char *name, const char *value, MM::PropertyType eType, bool readOnly, int(U::*memberFunction)(MM::PropertyBase *pProp, MM::ActionType eAct), bool isPreInitProperty=false)
Create a new property for the device.
Definition DeviceBase.h:635
virtual ~CDeviceBase()
Definition DeviceBase.h:854
virtual int IsPropertySequenceable(const char *name, bool &sequenceable) const
Check whether the property can be run in a sequence.
Definition DeviceBase.h:352
virtual void SetCallback(MM::Core *cbk)
Set the callback for accessing parent functionality (used only by the calling code).
Definition DeviceBase.h:176
static const char * ConvertToString(long lnVal)
Definition DeviceUtils.cpp:63
static bool CopyLimitedString(char *pszTarget, const char *pszSource)
Definition DeviceUtils.cpp:43
Base class for creating Galvo devices.
Definition DeviceBase.h:2318
Base class for creating generic devices.
Definition DeviceBase.h:1366
Base class for creating image processing modules.
Definition DeviceBase.h:2229
Definition DeviceBase.h:1727
MM::MMTime GetStartTime()
Definition DeviceBase.h:1781
void Suspend()
Definition DeviceBase.h:1766
void Resume()
Definition DeviceBase.h:1774
long GetNumberOfImages()
Definition DeviceBase.h:1785
void Stop()
Definition DeviceBase.h:1744
void SetLength(long images)
Definition DeviceBase.h:1778
bool IsSuspended()
Definition DeviceBase.h:1770
~BaseSequenceThread()
Definition DeviceBase.h:1742
void UpdateActualDuration()
Definition DeviceBase.h:1787
CLegacyCameraBase * GetCamera()
Definition DeviceBase.h:1784
BaseSequenceThread(CLegacyCameraBase *pCam)
Definition DeviceBase.h:1731
bool IsStopped()
Definition DeviceBase.h:1762
long GetImageCounter()
Definition DeviceBase.h:1780
void Start(long numImages)
Definition DeviceBase.h:1749
MM::MMTime GetActualDuration()
Definition DeviceBase.h:1782
Definition DeviceBase.h:1707
CaptureRestartHelper(CLegacyCameraBase *pCam)
Definition DeviceBase.h:1712
Legacy base class for creating camera device adapters.
Definition DeviceBase.h:1586
virtual void setStopOnOverflow(bool stop)
Definition DeviceBase.h:1702
virtual bool isStopOnOverflow()
Definition DeviceBase.h:1701
virtual ~CLegacyCameraBase()
Definition DeviceBase.h:1593
virtual int ThreadRun(void)
Definition DeviceBase.h:1654
virtual double GetIntervalMs()
Definition DeviceBase.h:1681
CLegacyCameraBase()
Definition DeviceBase.h:1588
virtual bool Busy()
Definition DeviceBase.h:1603
virtual void OnThreadExiting()
Definition DeviceBase.h:1686
virtual int InsertImage()
Definition DeviceBase.h:1670
virtual int StartSequenceAcquisition(double)
Start continuous sequence acquisition.
Definition DeviceBase.h:1610
friend class BaseSequenceThread
Definition DeviceBase.h:1831
virtual long GetNumberOfImages()
Definition DeviceBase.h:1683
virtual bool IsCapturing()
Indicate whether sequence acquisition is currently running.
Definition DeviceBase.h:1645
virtual long GetImageCounter()
Definition DeviceBase.h:1682
virtual int StartSequenceAcquisition(long numImages, double, bool stopOnOverflow)
Start sequence acquisition.
Definition DeviceBase.h:1632
virtual int StopSequenceAcquisition()
Stop and wait for the thread to finish.
Definition DeviceBase.h:1618
Base class for creating devices that can change magnification (NS).
Definition DeviceBase.h:2271
Base class for creating pressure pump device adapters.
Definition DeviceBase.h:2685
Base class for creating SLM devices that can project images.
Definition DeviceBase.h:2279
Base class for creating serial port device adapters.
Definition DeviceBase.h:2212
Base class for creating shutter device adapters.
Definition DeviceBase.h:2204
Base class for creating ADC/DAC modules.
Definition DeviceBase.h:2237
Base class for creating single axis stage adapters.
Definition DeviceBase.h:1840
Base class for creating state device adapters such as filter wheels, objectives, turrets,...
Definition DeviceBase.h:2387
virtual int GetPosition(char *label) const
Obtain the state (position) label of the device.
Definition DeviceBase.h:2475
virtual int GetPositionLabel(long pos, char *label) const
Obtain the label associated with the position (state).
Definition DeviceBase.h:2488
virtual int SetPositionLabel(long pos, const char *label)
Create new label for the given position, or override the existing one.
Definition DeviceBase.h:2510
virtual int GetGateOpen(bool &open)
Definition DeviceBase.h:2445
virtual int GetPosition(long &pos) const
Obtain the state (position) index of the device.
Definition DeviceBase.h:2456
int OnLabel(MM::PropertyBase *pProp, MM::ActionType eAct)
Implement the default Label property action.
Definition DeviceBase.h:2562
CStateDeviceBase< U > CStateBase
Definition DeviceBase.h:2390
virtual int SetPosition(const char *label)
Set the state (position) of the device based on the state label.
Definition DeviceBase.h:2414
int OnStateChanged(long position)
Signal to the core that the state has changed, so that both "State" and "Label" properties should be ...
Definition DeviceBase.h:2643
virtual int GetLabelPosition(const char *label, long &pos) const
Obtain the position associated with a label.
Definition DeviceBase.h:2548
virtual int SetPosition(long pos)
Set the state (position) of the device based on the state index.
Definition DeviceBase.h:2404
CStateDeviceBase()
Definition DeviceBase.h:2392
virtual int SetGateOpen(bool open)
Implement a gate, i.e., a position where the state device is closed.
Definition DeviceBase.h:2432
Base class for creating volumetric pump device adapters.
Definition DeviceBase.h:2668
Base class for creating dual axis stage adapters.
Definition DeviceBase.h:1949
virtual int SetAdapterOriginUm(double newXUm, double newYUm)
Alter the software coordinate translation between micrometers and steps, such that the current positi...
Definition DeviceBase.h:2052
virtual int StartXYStageSequence()
Definition DeviceBase.h:2136
virtual int AddToXYStageSequence(double, double)
Add one value to the sequence.
Definition DeviceBase.h:2151
virtual int GetXYStageSequenceMaxLength(long &) const
Definition DeviceBase.h:2131
CXYStageBase()
Definition DeviceBase.h:1951
virtual int SetYOrigin()
Define the current position as Y = 0 (in hardware if possible).
Definition DeviceBase.h:2126
virtual int Move(double, double)
Definition DeviceBase.h:2116
std::pair< double, double > ConvertPositionStepsToUm(long xSteps, long ySteps)
Definition DeviceBase.h:1987
double GetCachedXUm()
Return the cached X position.
Definition DeviceBase.h:2174
virtual int SetPositionUm(double x_um, double y_um)
Definition DeviceBase.h:2006
double GetCachedYUm()
Definition DeviceBase.h:2175
virtual int GetPositionUm(double &x_um, double &y_um)
Definition DeviceBase.h:2074
virtual int SendXYStageSequence()
Signal that we are done sending sequence values so that the adapter can send the whole sequence to th...
Definition DeviceBase.h:2156
virtual int StopXYStageSequence()
Definition DeviceBase.h:2141
virtual int SetRelativePositionSteps(long x, long y)
Set relative position in steps.
Definition DeviceBase.h:2097
std::pair< long, long > ConvertPositionUmToSteps(double x_um, double y_um)
Definition DeviceBase.h:1966
virtual int SetRelativePositionUm(double dx, double dy)
Set relative position.
Definition DeviceBase.h:2025
virtual int ClearXYStageSequence()
Remove all values in the sequence.
Definition DeviceBase.h:2146
virtual int SetXOrigin()
Define the current position as X = 0 (in hardware if possible).
Definition DeviceBase.h:2121
virtual int UsesOnXYStagePositionChanged(bool &result) const
Return true when your device adapter uses OnXYStagePositionChanged callbacks.
Definition DeviceBase.h:2110
Base class for creating special HUB devices for managing device libraries.
Definition DeviceBase.h:2329
void AddInstalledDevice(MM::Device *pdev)
Definition DeviceBase.h:2374
virtual unsigned GetNumberOfInstalledDevices()
Return the number of child devices after DetectInstalledDevices was called.
Definition DeviceBase.h:2350
virtual int DetectInstalledDevices()
Detect installed child devices.
Definition DeviceBase.h:2342
virtual ~HubBase()
Definition DeviceBase.h:2332
HubBase()
Definition DeviceBase.h:2331
virtual void ClearInstalledDevices()
Remove all installed devices that were created by DetectInstalledDevices().
Definition DeviceBase.h:2366
virtual MM::Device * GetInstalledDevice(int devIdx)
Return a pointer to the device with index devIdx.
Definition DeviceBase.h:2358
Extended device action implementation.
Definition Property.h:109
Abstract interface to invoke specific action in the device.
Definition Property.h:76
Device action implementation.
Definition Property.h:87
Camera API.
Definition MMDevice.h:300
Definition CameraImageMetadata.h:29
void AddTag(const char *key, V value)
Add a tag.
Definition CameraImageMetadata.h:57
const char * Serialize() const
Return this metadata map serialized to string form.
Definition CameraImageMetadata.h:102
Callback API to the core control module.
Definition MMDevice.h:1596
virtual int OnPropertiesChanged(const Device *caller)=0
virtual MM::MMTime GetCurrentMMTime()=0
virtual unsigned long GetClockTicksUs(const Device *caller)=0
virtual int GetSerialAnswer(const Device *caller, const char *portName, unsigned long ansLength, char *answer, const char *term)=0
virtual int OnMagnifierChanged(const Device *caller)=0
Signal changes in magnification.
virtual int AcqFinished(const Device *caller, int statusCode)=0
virtual MM::PortType GetSerialPortType(const char *portName) const =0
virtual int SetSerialCommand(const Device *caller, const char *portName, const char *command, const char *term)=0
virtual int PurgeSerial(const Device *caller, const char *portName)=0
virtual int OnStagePositionChanged(const Device *caller, double pos)=0
Inform the UI when a stage has changed its position.
virtual void GetLoadedDeviceOfType(const Device *caller, MM::DeviceType devType, char *pDeviceName, const unsigned int deviceIterator)=0
Get the names of currently loaded devices of a given type.
virtual int OnExposureChanged(const Device *caller, double newExposure)=0
Inform the UI when the exposure time has changed.
virtual int WriteToSerial(const Device *caller, const char *port, const unsigned char *buf, unsigned long length)=0
virtual MM::Hub * GetParentHub(const MM::Device *caller) const =0
virtual int LogMessage(const Device *caller, const char *msg, bool debugOnly) const =0
Log a message (msg) in the Corelog output, labeled with the device name (derived from caller).
virtual int OnXYStagePositionChanged(const Device *caller, double xPos, double yPos)=0
Inform the UI when an XY stage has changed its position.
virtual int ReadFromSerial(const Device *caller, const char *port, unsigned char *buf, unsigned long length, unsigned long &read)=0
virtual Device * GetDevice(const Device *caller, const char *label)=0
Get a pointer to another device.
virtual int OnPropertyChanged(const Device *caller, const char *propName, const char *propValue)=0
Inform the UI that a property changed.
virtual int OnSLMExposureChanged(const Device *caller, double newExposure)=0
Inform the UI when the SLM exposure time has changed.
virtual int InsertImage(const Device *caller, const unsigned char *buf, unsigned width, unsigned height, unsigned bytePerPixel, unsigned nComponents, const char *serializedMetadata=nullptr)=0
Send a frame to the Core during sequence acquisition.
virtual int PrepareForAcq(const Device *caller)=0
Generic device interface.
Definition MMDevice.h:192
HUB device.
Definition MMDevice.h:1327
Utility class used both MMCore and devices to maintain time intervals in the uniform,...
Definition MMDevice.h:58
std::string toString() const
Definition MMDevice.h:144
Base API for all device properties.
Definition Property.h:39
virtual void SetSequenceable(long sequenceSize)=0
virtual std::vector< std::string > GetSequence() const =0
virtual bool Get(double &dVal) const =0
virtual bool Set(double dVal)=0
virtual PropertyType GetType()=0
An array of properties supported by a device.
Definition Property.h:438
bool GetName(unsigned uIdx, std::string &strName) const
Definition Property.cpp:436
int ClearAllowedValues(const char *name)
Definition Property.cpp:379
int UpdateAll()
Definition Property.cpp:459
int GetCurrentPropertyData(const char *name, long &data)
Definition Property.cpp:422
int GetPropertyData(const char *name, const char *value, long &data)
Definition Property.cpp:410
int AddAllowedValue(const char *name, const char *value, long data)
Definition Property.cpp:389
int Set(const char *propName, const char *Value)
Definition Property.cpp:266
int Get(const char *propName, std::string &val) const
Definition Property.cpp:289
int CreateProperty(const char *name, const char *value, PropertyType eType, bool bReadOnly, ActionFunctor *pAct=0, bool isPreInitProperty=false)
Definition Property.cpp:329
int Update(const char *Name)
Definition Property.cpp:485
Property * Find(const char *name) const
Definition Property.cpp:305
int Apply(const char *Name)
Definition Property.cpp:494
int SetAllowedValues(const char *name, std::vector< std::string > &values)
Definition Property.cpp:366
unsigned GetSize() const
Definition Property.cpp:324
Property API with most of the Property mechanism implemented.
Definition Property.h:145
double GetUpperLimit() const
Definition Property.h:215
bool GetReadOnly() const
Definition Property.h:170
bool IsSequenceable()
Definition Property.h:236
long GetSequenceMaxSize() const
Definition Property.h:245
int ClearSequence()
Definition Property.h:250
int StopSequence()
Definition Property.h:305
bool SetLimits(double lowerLimit, double upperLimit)
Definition Property.h:220
double GetLowerLimit() const
Definition Property.h:210
bool HasLimits() const
Definition Property.h:205
int AddToSequence(const char *value)
Definition Property.h:265
bool GetInitStatus() const
Definition Property.h:173
std::vector< std::string > GetAllowedValues() const
Definition Property.cpp:32
int StartSequence()
Definition Property.h:298
int SendSequence()
Definition Property.h:280
virtual double GetStepSizeXUm()=0
virtual int GetPositionSteps(long &x, long &y)=0
virtual double GetStepSizeYUm()=0
virtual int SetPositionSteps(long x, long y)=0
Base class for threads in MM devices.
Definition DeviceThreads.h:34
void wait()
Definition DeviceThreads.h:52
virtual int activate()
Definition DeviceThreads.h:41
Definition DeviceThreads.h:151
Critical section lock.
Definition DeviceThreads.h:95
Definition CameraImageMetadata.h:27
FocusDirection
Definition MMDeviceConstants.h:291
@ FocusDirectionUnknown
Definition MMDeviceConstants.h:292
PortType
Definition MMDeviceConstants.h:284
@ InvalidPort
Definition MMDeviceConstants.h:285
const char *const g_Keyword_Metadata_CameraLabel
Definition MMDeviceConstants.h:184
PropertyType
Definition MMDeviceConstants.h:267
@ Float
Definition MMDeviceConstants.h:270
@ String
Definition MMDeviceConstants.h:269
@ Integer
Definition MMDeviceConstants.h:271
const char *const g_Keyword_Transpose_Correction
Definition MMDeviceConstants.h:154
const int MaxStrLength
Definition MMDeviceConstants.h:96
DeviceType
Definition MMDeviceConstants.h:245
const char *const g_Keyword_State
Definition MMDeviceConstants.h:119
const char *const g_Keyword_Label
Definition MMDeviceConstants.h:120
const char *const g_Keyword_HubID
Definition MMDeviceConstants.h:156
ActionType
Definition MMDeviceConstants.h:274
@ IsSequenceable
Definition MMDeviceConstants.h:278
@ AfterSet
Definition MMDeviceConstants.h:277
@ StopSequence
Definition MMDeviceConstants.h:281
@ AfterLoadSequence
Definition MMDeviceConstants.h:279
@ StartSequence
Definition MMDeviceConstants.h:280
@ BeforeGet
Definition MMDeviceConstants.h:276
const char *const g_Keyword_Transpose_MirrorY
Definition MMDeviceConstants.h:153
const char *const g_Keyword_Transpose_SwapXY
Definition MMDeviceConstants.h:151
const char *const g_Keyword_Transpose_MirrorX
Definition MMDeviceConstants.h:152
DeviceDetectionStatus
Definition MMDeviceConstants.h:305
@ Unimplemented
Definition MMDeviceConstants.h:306