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 interval) = 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
1488 virtual int StartSequenceAcquisition(long numImages, double interval_ms,
1489 bool stopOnOverflow) = 0;
1490
1491 virtual int GetExposureSequenceMaxLength(long& /*nrEvents*/) const
1492 {
1494 }
1495
1497 {
1499 }
1500
1502 {
1504 }
1505
1507 {
1509 }
1510
1511 virtual int AddToExposureSequence(double /*exposureTime_ms*/)
1512 {
1514 }
1515
1516 virtual int SendExposureSequence() const
1517 {
1519 }
1520
1521 virtual bool IsCapturing() = 0;
1522
1523 virtual void AddTag(const char* key, const char* deviceLabel, const char* value)
1524 {
1525 std::string k;
1526 if (deviceLabel != std::string("_"))
1527 {
1528 k += deviceLabel;
1529 k += '-';
1530 }
1531 k += key;
1532 addedTags_[k] = value;
1533 }
1534
1535 virtual void RemoveTag(const char* key)
1536 {
1537 addedTags_.erase(key);
1538 }
1539
1540 virtual bool SupportsMultiROI()
1541 {
1542 return false;
1543 }
1544
1545 virtual bool IsMultiROISet()
1546 {
1547 return false;
1548 }
1549
1550 virtual int GetMultiROICount(unsigned& /* count */)
1551 {
1553 }
1554
1555 virtual int SetMultiROI(const unsigned* /* xs */, const unsigned* /* ys */,
1556 const unsigned* /* widths */, const unsigned* /* heights */,
1557 unsigned /* numROIs */)
1558 {
1560 }
1561
1562 virtual int GetMultiROI(unsigned* /* xs */, unsigned* /* ys */,
1563 unsigned* /* widths */, unsigned* /* heights */, unsigned* /* length */)
1564 {
1566 }
1567
1568private:
1569 std::map<std::string, std::string> addedTags_;
1570};
1571
1572
1573
1574
1582template <class U>
1584{
1585public:
1586 CLegacyCameraBase() : busy_(false), stopWhenCBOverflows_(false), thd_(0)
1587 {
1588 thd_ = new BaseSequenceThread(this);
1589 }
1590
1592 {
1593 if (!thd_->IsStopped()) {
1594 thd_->Stop();
1595 thd_->wait();
1596 }
1597 delete thd_;
1598 }
1599
1600
1601 virtual bool Busy() {return busy_;}
1602
1608 virtual int StartSequenceAcquisition(double interval)
1609 {
1610 return StartSequenceAcquisition(LONG_MAX, interval, false);
1611 }
1612
1617 {
1618 if (!thd_->IsStopped()) {
1619 thd_->Stop();
1620 thd_->wait();
1621 }
1622
1623 return DEVICE_OK;
1624 }
1625
1626 // Implementation of a sequence acquisition as a series of snaps
1627 // This was a temporary method used for debugging, which is why its now
1628 // implemented in this legacy class. It's preferable that camera devices
1629 // inherit directly from CCameraBase and not use these default implementations.
1630 virtual int StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow)
1631 {
1632 if (IsCapturing())
1634
1635 int ret = this->GetCoreCallback()->PrepareForAcq(this);
1636 if (ret != DEVICE_OK)
1637 return ret;
1638 thd_->Start(numImages,interval_ms);
1639 stopWhenCBOverflows_ = stopOnOverflow;
1640 return DEVICE_OK;
1641 }
1642
1643 virtual bool IsCapturing(){return !thd_->IsStopped();}
1644
1645
1646protected:
1647 // Member functions that can be overridden by derived classes (these
1648 // customize the legacy snap-based sequence acquisition).
1649
1650 // Do actual capturing
1651 // Called from inside the thread
1652 virtual int ThreadRun (void)
1653 {
1654 int ret=DEVICE_ERR;
1655 ret = this->SnapImage();
1656 if (ret != DEVICE_OK)
1657 {
1658 return ret;
1659 }
1660 ret = InsertImage();
1661 if (ret != DEVICE_OK)
1662 {
1663 return ret;
1664 }
1665 return ret;
1666 };
1667
1668 virtual int InsertImage()
1669 {
1670 char label[MM::MaxStrLength];
1671 this->GetLabel(label);
1674 return this->GetCoreCallback()->InsertImage(this, this->GetImageBuffer(), this->GetImageWidth(),
1675 this->GetImageHeight(), this->GetImageBytesPerPixel(),
1676 md.Serialize());
1677 }
1678
1679 virtual double GetIntervalMs() {return thd_->GetIntervalMs();}
1680 virtual long GetImageCounter() {return thd_->GetImageCounter();}
1681 virtual long GetNumberOfImages() {return thd_->GetNumberOfImages();}
1682
1683 // called from the thread function before exit
1684 virtual void OnThreadExiting()
1685 {
1686 try
1687 {
1689 if (this->GetCoreCallback() != nullptr) {
1690 this->GetCoreCallback()->AcqFinished(this, 0);
1691 }
1692 }
1693 catch(...)
1694 {
1696 }
1697 }
1698
1699 virtual bool isStopOnOverflow() {return stopWhenCBOverflows_;}
1700 virtual void setStopOnOverflow(bool stop) {stopWhenCBOverflows_ = stop;}
1701
1703 // Helper Class
1705 {
1706 bool restart_;
1707 CLegacyCameraBase* pCam_;
1708
1709 public:
1711 :pCam_(pCam)
1712 {
1713 restart_=pCam_->IsCapturing();
1714 }
1715 operator bool()
1716 {
1717 return restart_;
1718 }
1719 };
1721
1722 // Nested class for live streaming
1725 {
1726 friend class CLegacyCameraBase;
1727 enum { default_numImages=1, default_intervalMS = 100 };
1728 public:
1730 :intervalMs_(default_intervalMS)
1731 ,numImages_(default_numImages)
1732 ,imageCounter_(0)
1733 ,stop_(true)
1734 ,suspend_(false)
1735 ,camera_(pCam)
1736 ,startTime_(0)
1737 ,actualDuration_(0)
1738 ,lastFrameTime_(0)
1739 {};
1740
1742
1743 void Stop() {
1744 MMThreadGuard g(this->stopLock_);
1745 stop_=true;
1746 }
1747
1748 void Start(long numImages, double intervalMs)
1749 {
1750 MMThreadGuard g1(this->stopLock_);
1751 MMThreadGuard g2(this->suspendLock_);
1752 numImages_=numImages;
1753 intervalMs_=intervalMs;
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 double GetIntervalMs(){return intervalMs_;}
1779 void SetLength(long images) {numImages_ = images;}
1780 //long GetLength() const {return numImages_;}
1781
1782 long GetImageCounter(){return imageCounter_;}
1783 MM::MMTime GetStartTime(){return startTime_;}
1784 MM::MMTime GetActualDuration(){return actualDuration_;}
1785
1786 CLegacyCameraBase* GetCamera() {return camera_;}
1787 long GetNumberOfImages() {return numImages_;}
1788
1789 void UpdateActualDuration() {actualDuration_ = camera_->GetCurrentMMTime() - startTime_;}
1790
1791 private:
1792 virtual int svc()
1793 {
1794 int ret=DEVICE_ERR;
1795 try
1796 {
1797 do
1798 {
1799 ret=camera_->ThreadRun();
1800 } while (DEVICE_OK == ret && !IsStopped() && imageCounter_++ < numImages_-1);
1801 if (IsStopped())
1802 camera_->LogMessage("SeqAcquisition interrupted by the user\n");
1803
1804 }catch(...){
1805 camera_->LogMessage(g_Msg_EXCEPTION_IN_THREAD, false);
1806 }
1807 stop_=true;
1809 camera_->OnThreadExiting();
1810 return ret;
1811 }
1812 private:
1813 double intervalMs_;
1814 long numImages_;
1815 long imageCounter_;
1816 bool stop_;
1817 bool suspend_;
1818 CLegacyCameraBase* camera_;
1819 MM::MMTime startTime_;
1820 MM::MMTime actualDuration_;
1821 MM::MMTime lastFrameTime_;
1822 MMThreadLock stopLock_;
1823 MMThreadLock suspendLock_;
1824 };
1826
1827
1828private:
1829
1830 bool busy_;
1831 bool stopWhenCBOverflows_;
1832
1833 BaseSequenceThread * thd_;
1835};
1836
1837
1841template <class U>
1842class CStageBase : public CDeviceBase<MM::Stage, U>
1843{
1844 virtual int GetPositionUm(double& pos) = 0;
1845 virtual int SetPositionUm(double pos) = 0;
1846
1852 virtual int SetRelativePositionUm(double d)
1853 {
1854 double pos;
1855 int ret = GetPositionUm(pos);
1856 if (ret != DEVICE_OK)
1857 return ret;
1858 return SetPositionUm(pos + d);
1859 }
1860
1861 virtual int SetAdapterOriginUm(double /*d*/)
1862 {
1864 }
1865
1866 virtual int Move(double /*velocity*/)
1867 {
1869 }
1870
1871 virtual int Stop()
1872 {
1873 // Historically, Move() has been in this interface longer than Stop(), so
1874 // there is a chance that a stage implements Move() but not Stop(). In
1875 // which case zero velocity is the best thing to do.
1876 return Move(0.0);
1877 }
1878
1879 virtual int Home()
1880 {
1882 }
1883
1884 virtual int GetFocusDirection(MM::FocusDirection& direction)
1885 {
1886 // FocusDirectionUnknown is a safe default for all stages. Override this
1887 // only if direction is known for sure (i.e. does not depend on how the
1888 // hardware is installed).
1889 direction = MM::FocusDirectionUnknown;
1890 return DEVICE_OK;
1891 }
1892
1896 virtual int UsesOnStagePositionChanged(bool& result) const
1897 {
1898 result = false;
1899 return DEVICE_OK;
1900 }
1901
1902 virtual int IsStageLinearSequenceable(bool& isSequenceable) const
1903 {
1904 isSequenceable = false;
1905 return DEVICE_OK;
1906 }
1907
1908 virtual int GetStageSequenceMaxLength(long& /*nrEvents*/) const
1909 {
1911 }
1912
1913 virtual int StartStageSequence()
1914 {
1916 }
1917
1918 virtual int StopStageSequence()
1919 {
1921 }
1922
1923 virtual int ClearStageSequence()
1924 {
1926 }
1927
1928 virtual int AddToStageSequence(double /*position*/)
1929 {
1931 }
1932
1933 virtual int SendStageSequence()
1934 {
1936 }
1937
1938 virtual int SetStageLinearSequence(double, long)
1939 {
1941 }
1942};
1943
1950template <class U>
1951class CXYStageBase : public CDeviceBase<MM::XYStage, U>
1952{
1953public:
1954 CXYStageBase() : originXSteps_(0), originYSteps_(0), xPos_(0), yPos_(0)
1955 {
1956 // set-up directionality properties
1960
1964 }
1965
1966 // This converts an absolute position (x_um, y_um), under the current
1967 // adapter origin and x/y mirroring, to an absolute step position. Do not
1968 // use for relative offsets.
1969 std::pair<long, long> ConvertPositionUmToSteps(double x_um, double y_um)
1970 {
1971 bool mirrorX, mirrorY;
1972 GetOrientation(mirrorX, mirrorY);
1973
1974 long xSteps{}, ySteps{};
1975 if (mirrorX)
1976 xSteps = originXSteps_ - nint (x_um / this->GetStepSizeXUm());
1977 else
1978 xSteps = originXSteps_ + nint (x_um / this->GetStepSizeXUm());
1979 if (mirrorY)
1980 ySteps = originYSteps_ - nint (y_um / this->GetStepSizeYUm());
1981 else
1982 ySteps = originYSteps_ + nint (y_um / this->GetStepSizeYUm());
1983
1984 return {xSteps, ySteps};
1985 }
1986
1987 // This converts an absolute position (xSteps, ySteps), under the current
1988 // adapter origin and x/y mirroring, to an absolute um position. Do not use
1989 // for relative offsets.
1990 std::pair<double, double> ConvertPositionStepsToUm(long xSteps, long ySteps)
1991 {
1992 bool mirrorX, mirrorY;
1993 GetOrientation(mirrorX, mirrorY);
1994
1995 double x_um{}, y_um{};
1996 if (mirrorX)
1997 x_um = (originXSteps_ - xSteps) * this->GetStepSizeXUm();
1998 else
1999 x_um = - ((originXSteps_ - xSteps) * this->GetStepSizeXUm());
2000
2001 if (mirrorY)
2002 y_um = (originYSteps_ - ySteps) * this->GetStepSizeYUm();
2003 else
2004 y_um = - ((originYSteps_ - ySteps) * this->GetStepSizeYUm());
2005
2006 return {x_um, y_um};
2007 }
2008
2009 virtual int SetPositionUm(double x_um, double y_um)
2010 {
2011 auto posSteps = ConvertPositionUmToSteps(x_um, y_um);
2012 long xSteps = posSteps.first;
2013 long ySteps = posSteps.second;
2014
2015 int ret = this->SetPositionSteps(xSteps, ySteps);
2016 if (ret == DEVICE_OK) {
2017 xPos_ = x_um;
2018 yPos_ = y_um;
2019 }
2020 return ret;
2021 }
2022
2028 virtual int SetRelativePositionUm(double dx, double dy)
2029 {
2030 bool mirrorX, mirrorY;
2031 GetOrientation(mirrorX, mirrorY);
2032 double xPos = xPos_ + dx;
2033 double yPos = yPos_ + dy;
2034
2035 if (mirrorX)
2036 dx = -dx;
2037 if (mirrorY)
2038 dy = -dy;
2039
2040 int ret = SetRelativePositionSteps(nint(dx / this->GetStepSizeXUm()), nint(dy / this->GetStepSizeYUm()));
2041 if (ret == DEVICE_OK) {
2042 xPos_ = xPos;
2043 yPos_ = yPos;
2044 }
2045 return ret;
2046 }
2047
2055 virtual int SetAdapterOriginUm(double newXUm, double newYUm)
2056 {
2057 bool mirrorX, mirrorY;
2058 GetOrientation(mirrorX, mirrorY);
2059
2060 long xStep, yStep;
2061 int ret = this->GetPositionSteps(xStep, yStep);
2062 if (ret != DEVICE_OK)
2063 return ret;
2064
2065 if (mirrorX)
2066 originXSteps_ = xStep + nint(newXUm / this->GetStepSizeXUm());
2067 else
2068 originXSteps_ = xStep - nint(newXUm / this->GetStepSizeXUm());
2069 if (mirrorY)
2070 originYSteps_ = yStep + nint(newYUm / this->GetStepSizeYUm());
2071 else
2072 originYSteps_ = yStep - nint(newYUm / this->GetStepSizeYUm());
2073
2074 return DEVICE_OK;
2075 }
2076
2077 virtual int GetPositionUm(double& x_um, double& y_um)
2078 {
2079 long xSteps, ySteps;
2080 int ret = this->GetPositionSteps(xSteps, ySteps);
2081 if (ret != DEVICE_OK)
2082 return ret;
2083
2084 auto pos_um = ConvertPositionStepsToUm(xSteps, ySteps);
2085 x_um = pos_um.first;
2086 y_um = pos_um.second;
2087
2088 xPos_ = x_um;
2089 yPos_ = y_um;
2090
2091 return DEVICE_OK;
2092 }
2093
2100 virtual int SetRelativePositionSteps(long x, long y)
2101 {
2102 long xSteps, ySteps;
2103 int ret = this->GetPositionSteps(xSteps, ySteps);
2104 if (ret != DEVICE_OK)
2105 return ret;
2106
2107 return this->SetPositionSteps(xSteps+x, ySteps+y);
2108 }
2109
2113 virtual int UsesOnXYStagePositionChanged(bool& result) const
2114 {
2115 result = false;
2116 return DEVICE_OK;
2117 }
2118
2119 virtual int Move(double /*vx*/, double /*vy*/)
2120 {
2122 }
2123
2124 virtual int SetXOrigin()
2125 {
2127 }
2128
2129 virtual int SetYOrigin()
2130 {
2132 }
2133
2134 virtual int GetXYStageSequenceMaxLength(long& /*nrEvents*/) const
2135 {
2137 }
2138
2140 {
2142 }
2143
2145 {
2147 }
2148
2150 {
2152 }
2153
2154 virtual int AddToXYStageSequence(double /*positionX*/, double /*positionY*/)
2155 {
2157 }
2158
2160 {
2162 }
2163
2164protected:
2165
2177 double GetCachedXUm() {return xPos_;}
2178 double GetCachedYUm() {return yPos_;}
2179
2180private:
2181
2182 void GetOrientation(bool& mirrorX, bool& mirrorY)
2183 {
2184 char val[MM::MaxStrLength];
2185 int ret = this->GetProperty(MM::g_Keyword_Transpose_MirrorX, val);
2186 assert(ret == DEVICE_OK);
2187 mirrorX = strcmp(val, "1") == 0 ? true : false;
2188
2190 assert(ret == DEVICE_OK);
2191 mirrorY = strcmp(val, "1") == 0 ? true : false;
2192 }
2193
2194
2195 // absolute coordinate translation data
2196 long originXSteps_;
2197 long originYSteps_;
2198 double xPos_;
2199 double yPos_;
2200};
2201
2205template <class U>
2206class CShutterBase : public CDeviceBase<MM::Shutter, U>
2207{
2208};
2209
2213template <class U>
2214class CSerialBase : public CDeviceBase<MM::Serial, U>
2215{
2216};
2217
2221template <class U>
2222class CAutoFocusBase : public CDeviceBase<MM::AutoFocus, U>
2223{
2224 virtual int AutoSetParameters() {return DEVICE_UNSUPPORTED_COMMAND;}
2225};
2226
2230template <class U>
2231class CImageProcessorBase : public CDeviceBase<MM::ImageProcessor, U>
2232{
2233};
2234
2238template <class U>
2239class CSignalIOBase : public CDeviceBase<MM::SignalIO, U>
2240{
2241 virtual int GetDASequenceMaxLength(long& /*nrEvents*/) const
2242 {
2244 }
2245
2246 virtual int StartDASequence()
2247 {
2249 }
2250
2251 virtual int StopDASequence() {
2253 }
2254
2255 virtual int ClearDASequence() {
2257 }
2258
2259 virtual int AddToDASequence(double /*voltage*/)
2260 {
2262 }
2263
2264 virtual int SendDASequence() {
2266 }
2267};
2268
2272template <class U>
2273class CMagnifierBase : public CDeviceBase<MM::Magnifier, U>
2274{
2275};
2276
2280template <class U>
2281class CSLMBase : public CDeviceBase<MM::SLM, U>
2282{
2283 virtual int GetSLMSequenceMaxLength(long& /*nrEvents*/) const
2284 {
2286 }
2287
2288 virtual int StartSLMSequence()
2289 {
2291 }
2292
2293 virtual int StopSLMSequence() {
2295 }
2296
2297 virtual int ClearSLMSequence() {
2299 }
2300
2301 virtual int AddToSLMSequence(const unsigned char * const /*image*/)
2302 {
2304 }
2305
2306 virtual int AddToSLMSequence(const unsigned int * const /*image*/)
2307 {
2309 }
2310
2311 virtual int SendSLMSequence() {
2313 }
2314};
2315
2319template <class U>
2320class CGalvoBase : public CDeviceBase<MM::Galvo, U>
2321{
2322 double GetXMinimum() { return 0.0;};
2323 double GetYMinimum() { return 0.0;};
2324};
2325
2330template <class U>
2331class HubBase : public CDeviceBase<MM::Hub, U>
2332{
2333public:
2335 virtual ~HubBase() {}
2336
2345 virtual int DetectInstalledDevices() {return DEVICE_OK;}
2346
2353 virtual unsigned GetNumberOfInstalledDevices() {return (unsigned)installedDevices.size();}
2354
2361 virtual MM::Device* GetInstalledDevice(int devIdx) {return installedDevices[devIdx];}
2362
2370 {
2371 for (unsigned i=0; i<installedDevices.size(); i++)
2372 delete installedDevices[i];
2373 installedDevices.clear();
2374 }
2375
2376protected:
2377 void AddInstalledDevice(MM::Device* pdev) {installedDevices.push_back(pdev);}
2378
2379private:
2380 std::vector<MM::Device*> installedDevices;
2381
2382};
2383
2388template <class U>
2389class CStateDeviceBase : public CDeviceBase<MM::State, U>
2390{
2391public:
2392
2394
2395 CStateDeviceBase(): gateOpen_(true)
2396 {
2397 // set-up Position to move to when the state device's gate is closed
2398 // Allowed values should be set in the state device adapter
2399 // this->CreateProperty(MM::g_Keyword_Closed_Position, "0", MM::String, false);
2400 }
2401
2407 virtual int SetPosition(long pos)
2408 {
2410 }
2411
2417 virtual int SetPosition(const char* label)
2418 {
2419 std::map<std::string, long>::const_iterator it;
2420 it = labels_.find(label);
2421 if (it == labels_.end())
2422 return DEVICE_UNKNOWN_LABEL;
2423
2424 return SetPosition(it->second);
2425 }
2426
2427
2435 virtual int SetGateOpen(bool open)
2436 {
2437 if (gateOpen_ != open) {
2438 gateOpen_ = open;
2439 long position;
2440 int ret = GetPosition(position);
2441 if (ret != DEVICE_OK)
2442 return ret;
2443 return SetPosition(position);
2444 }
2445 return DEVICE_OK;
2446 }
2447
2448 virtual int GetGateOpen(bool& open)
2449 {
2450 open = gateOpen_;
2451 return DEVICE_OK;
2452 }
2453
2459 virtual int GetPosition(long& pos) const
2460 {
2461 char buf[MM::MaxStrLength];
2462 assert(this->HasProperty(MM::g_Keyword_State));
2463 int ret = this->GetProperty(MM::g_Keyword_State, buf);
2464 if (ret == DEVICE_OK)
2465 {
2466 pos = atol(buf);
2467 return DEVICE_OK;
2468 }
2469 else
2470 return ret;
2471 }
2472
2478 virtual int GetPosition(char* label) const
2479 {
2480 long pos;
2481 int ret = GetPosition(pos);
2482 if (ret == DEVICE_OK)
2483 return GetPositionLabel(pos, label);
2484 else
2485 return ret;
2486 }
2487
2491 virtual int GetPositionLabel(long pos, char* label) const
2492 {
2493 std::map<std::string, long>::const_iterator it;
2494 for (it=labels_.begin(); it!=labels_.end(); it++)
2495 {
2496 //string devLabel = it->first;
2497 //long devPosition = it->second;
2498 if (it->second == pos)
2499 {
2500 CDeviceUtils::CopyLimitedString(label, it->first.c_str());
2501 return DEVICE_OK;
2502 }
2503 }
2504
2505 // label not found
2507 }
2508
2513 virtual int SetPositionLabel(long pos, const char* label)
2514 {
2515 // first test if the label already exists with different position defined
2516 std::map<std::string, long>::iterator it;
2517 it = labels_.find(label);
2518 if (it != labels_.end() && it->second != pos)
2519 {
2520 // remove the existing one
2521 labels_.erase(it);
2522 }
2523
2524 // then test if the given position already has a label
2525 for (it=labels_.begin(); it!=labels_.end(); it++)
2526 {
2527 if (it->second == pos)
2528 {
2529 labels_.erase(it);
2530 break;
2531 }
2532 }
2533
2534 // finally we can add the new label-position mapping
2535 labels_[label] = pos;
2536
2537 // attempt to define allowed values for label property (if it exists),
2538 // and don't make any fuss if the operation fails
2539 std::string strLabel(label);
2540 std::vector<std::string> values;
2541 for (it=labels_.begin(); it!=labels_.end(); it++)
2542 values.push_back(it->first);
2544
2545 return DEVICE_OK;
2546 }
2547
2551 virtual int GetLabelPosition(const char* label, long& pos) const
2552 {
2553 std::map<std::string, long>::const_iterator it;
2554 it = labels_.find(label);
2555 if (it == labels_.end())
2556 return DEVICE_UNKNOWN_LABEL;
2557
2558 pos = it->second;
2559 return DEVICE_OK;
2560 }
2561
2566 {
2567 if (eAct == MM::BeforeGet)
2568 {
2569 char buf[MM::MaxStrLength];
2570 int ret = GetPosition(buf);
2571 if (ret != DEVICE_OK)
2572 return ret;
2573 pProp->Set(buf);
2574 }
2575 else if (eAct == MM::AfterSet)
2576 {
2577 std::string label;
2578 pProp->Get(label);
2579 int ret = SetPosition(label.c_str());
2580 if (ret != DEVICE_OK)
2581 return ret;
2582 }
2583 else if (eAct == MM::IsSequenceable)
2584 {
2585 assert(this->HasProperty(MM::g_Keyword_State));
2586 bool sequenceable;
2587 int ret = this->IsPropertySequenceable(MM::g_Keyword_State, sequenceable);
2588 if (ret != DEVICE_OK)
2589 return ret;
2590
2591 long nrEvents = 0;
2592 if (sequenceable) {
2594 if (ret != DEVICE_OK)
2595 return ret;
2596 }
2597 pProp->SetSequenceable(nrEvents);
2598 }
2599 else if (eAct == MM::AfterLoadSequence) {
2600 assert(this->HasProperty(MM::g_Keyword_State));
2601 std::vector<std::string> sequence = pProp->GetSequence();
2602 for (std::vector<std::string>::iterator it = sequence.begin(); it != sequence.end(); ++it) {
2603 long pos;
2604 int ret = GetLabelPosition((*it).c_str(), pos);
2605 if (ret != DEVICE_OK)
2606 return ret;
2607 std::stringstream s;
2608 s << pos;
2609 s >> *it;
2610 }
2611
2613 if (ret != DEVICE_OK)
2614 return ret;
2615
2616 std::vector<std::string>::iterator it;
2617 for ( it=sequence.begin() ; it < sequence.end(); it++ )
2618 {
2619 ret = this->AddToPropertySequence(MM::g_Keyword_State, (*it).c_str());
2620 if (ret != DEVICE_OK)
2621 return ret;
2622 }
2623
2625 if (ret != DEVICE_OK)
2626 return ret;
2627
2628 //this->LoadPropertySequence(MM::g_Keyword_State, sequence);
2629 }
2630 else if (eAct == MM::StartSequence) {
2631 assert(this->HasProperty(MM::g_Keyword_State));
2633 }
2634 else if (eAct == MM::StopSequence) {
2635 assert(this->HasProperty(MM::g_Keyword_State));
2637 }
2638
2639 return DEVICE_OK;
2640 }
2641
2646 int OnStateChanged(long position) {
2647 int ret;
2649 if (ret != DEVICE_OK) {
2650 return ret;
2651 }
2652
2653 char label[MM::MaxStrLength];
2654 GetPositionLabel(position, label);
2655 ret = this->OnPropertyChanged(MM::g_Keyword_Label, label);
2656 return ret;
2657 }
2658
2659private:
2660 bool gateOpen_;
2661
2662private:
2663 std::map<std::string, long> labels_;
2664};
2665
2669template <class U>
2670class CVolumetricPumpBase : public CDeviceBase<MM::VolumetricPump, U>
2671{
2672 int Home()
2673 {
2675 }
2676
2677 int InvertDirection(bool /*state*/)
2678 {
2680 }
2681};
2682
2686template <class U>
2687class CPressurePumpBase : public CDeviceBase<MM::PressurePump, U>
2688{
2689 int Calibrate()
2690 {
2692 }
2693};
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:2223
Base class for creating camera device adapters.
Definition DeviceBase.h:1378
virtual int GetMultiROI(unsigned *, unsigned *, unsigned *, unsigned *, unsigned *)
Definition DeviceBase.h:1562
virtual int StopExposureSequence()
Definition DeviceBase.h:1501
virtual int SetMultiROI(const unsigned *, const unsigned *, const unsigned *, const unsigned *, unsigned)
Definition DeviceBase.h:1555
virtual bool SupportsMultiROI()
Definition DeviceBase.h:1540
virtual unsigned GetImageBytesPerPixel() const =0
Return image buffer pixel depth in bytes.
virtual int GetExposureSequenceMaxLength(long &) const
Definition DeviceBase.h:1491
virtual int StartExposureSequence()
Definition DeviceBase.h:1496
virtual int GetMultiROICount(unsigned &)
Definition DeviceBase.h:1550
CCameraBase()
Definition DeviceBase.h:1389
virtual int StartSequenceAcquisition(double interval)=0
Start continuous sequence acquisition.
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:1535
virtual int AddToExposureSequence(double)
Definition DeviceBase.h:1511
virtual int ClearExposureSequence()
Definition DeviceBase.h:1506
virtual unsigned GetNumberOfChannels() const
Return the number of channels.
Definition DeviceBase.h:1436
virtual bool Busy()=0
virtual int StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow)=0
Start sequence acquisition.
virtual int SendExposureSequence() const
Definition DeviceBase.h:1516
virtual const unsigned char * GetImageBuffer()=0
Return pixel data.
virtual bool IsMultiROISet()
Definition DeviceBase.h:1545
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:1523
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:2321
Base class for creating generic devices.
Definition DeviceBase.h:1366
Base class for creating image processing modules.
Definition DeviceBase.h:2232
Definition DeviceBase.h:1725
MM::MMTime GetStartTime()
Definition DeviceBase.h:1783
void Start(long numImages, double intervalMs)
Definition DeviceBase.h:1748
void Suspend()
Definition DeviceBase.h:1766
void Resume()
Definition DeviceBase.h:1774
long GetNumberOfImages()
Definition DeviceBase.h:1787
void Stop()
Definition DeviceBase.h:1743
void SetLength(long images)
Definition DeviceBase.h:1779
bool IsSuspended()
Definition DeviceBase.h:1770
~BaseSequenceThread()
Definition DeviceBase.h:1741
void UpdateActualDuration()
Definition DeviceBase.h:1789
CLegacyCameraBase * GetCamera()
Definition DeviceBase.h:1786
BaseSequenceThread(CLegacyCameraBase *pCam)
Definition DeviceBase.h:1729
bool IsStopped()
Definition DeviceBase.h:1762
long GetImageCounter()
Definition DeviceBase.h:1782
MM::MMTime GetActualDuration()
Definition DeviceBase.h:1784
double GetIntervalMs()
Definition DeviceBase.h:1778
Definition DeviceBase.h:1705
CaptureRestartHelper(CLegacyCameraBase *pCam)
Definition DeviceBase.h:1710
Legacy base class for creating camera device adapters.
Definition DeviceBase.h:1584
virtual void setStopOnOverflow(bool stop)
Definition DeviceBase.h:1700
virtual bool isStopOnOverflow()
Definition DeviceBase.h:1699
virtual ~CLegacyCameraBase()
Definition DeviceBase.h:1591
virtual int ThreadRun(void)
Definition DeviceBase.h:1652
virtual double GetIntervalMs()
Definition DeviceBase.h:1679
CLegacyCameraBase()
Definition DeviceBase.h:1586
virtual bool Busy()
Definition DeviceBase.h:1601
virtual int StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow)
Start sequence acquisition.
Definition DeviceBase.h:1630
virtual void OnThreadExiting()
Definition DeviceBase.h:1684
virtual int InsertImage()
Definition DeviceBase.h:1668
friend class BaseSequenceThread
Definition DeviceBase.h:1834
virtual long GetNumberOfImages()
Definition DeviceBase.h:1681
virtual bool IsCapturing()
Indicate whether sequence acquisition is currently running.
Definition DeviceBase.h:1643
virtual int StartSequenceAcquisition(double interval)
Start continuous sequence acquisition.
Definition DeviceBase.h:1608
virtual long GetImageCounter()
Definition DeviceBase.h:1680
virtual int StopSequenceAcquisition()
Stop and wait for the thread to finish.
Definition DeviceBase.h:1616
Base class for creating devices that can change magnification (NS).
Definition DeviceBase.h:2274
Base class for creating pressure pump device adapters.
Definition DeviceBase.h:2688
Base class for creating SLM devices that can project images.
Definition DeviceBase.h:2282
Base class for creating serial port device adapters.
Definition DeviceBase.h:2215
Base class for creating shutter device adapters.
Definition DeviceBase.h:2207
Base class for creating ADC/DAC modules.
Definition DeviceBase.h:2240
Base class for creating single axis stage adapters.
Definition DeviceBase.h:1843
Base class for creating state device adapters such as filter wheels, objectives, turrets,...
Definition DeviceBase.h:2390
virtual int GetPosition(char *label) const
Obtain the state (position) label of the device.
Definition DeviceBase.h:2478
virtual int GetPositionLabel(long pos, char *label) const
Obtain the label associated with the position (state).
Definition DeviceBase.h:2491
virtual int SetPositionLabel(long pos, const char *label)
Create new label for the given position, or override the existing one.
Definition DeviceBase.h:2513
virtual int GetGateOpen(bool &open)
Definition DeviceBase.h:2448
virtual int GetPosition(long &pos) const
Obtain the state (position) index of the device.
Definition DeviceBase.h:2459
int OnLabel(MM::PropertyBase *pProp, MM::ActionType eAct)
Implement the default Label property action.
Definition DeviceBase.h:2565
CStateDeviceBase< U > CStateBase
Definition DeviceBase.h:2393
virtual int SetPosition(const char *label)
Set the state (position) of the device based on the state label.
Definition DeviceBase.h:2417
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:2646
virtual int GetLabelPosition(const char *label, long &pos) const
Obtain the position associated with a label.
Definition DeviceBase.h:2551
virtual int SetPosition(long pos)
Set the state (position) of the device based on the state index.
Definition DeviceBase.h:2407
CStateDeviceBase()
Definition DeviceBase.h:2395
virtual int SetGateOpen(bool open)
Implement a gate, i.e., a position where the state device is closed.
Definition DeviceBase.h:2435
Base class for creating volumetric pump device adapters.
Definition DeviceBase.h:2671
Base class for creating dual axis stage adapters.
Definition DeviceBase.h:1952
virtual int SetAdapterOriginUm(double newXUm, double newYUm)
Alter the software coordinate translation between micrometers and steps, such that the current positi...
Definition DeviceBase.h:2055
virtual int StartXYStageSequence()
Definition DeviceBase.h:2139
virtual int AddToXYStageSequence(double, double)
Add one value to the sequence.
Definition DeviceBase.h:2154
virtual int GetXYStageSequenceMaxLength(long &) const
Definition DeviceBase.h:2134
CXYStageBase()
Definition DeviceBase.h:1954
virtual int SetYOrigin()
Define the current position as Y = 0 (in hardware if possible).
Definition DeviceBase.h:2129
virtual int Move(double, double)
Definition DeviceBase.h:2119
std::pair< double, double > ConvertPositionStepsToUm(long xSteps, long ySteps)
Definition DeviceBase.h:1990
double GetCachedXUm()
Return the cached X position.
Definition DeviceBase.h:2177
virtual int SetPositionUm(double x_um, double y_um)
Definition DeviceBase.h:2009
double GetCachedYUm()
Definition DeviceBase.h:2178
virtual int GetPositionUm(double &x_um, double &y_um)
Definition DeviceBase.h:2077
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:2159
virtual int StopXYStageSequence()
Definition DeviceBase.h:2144
virtual int SetRelativePositionSteps(long x, long y)
Set relative position in steps.
Definition DeviceBase.h:2100
std::pair< long, long > ConvertPositionUmToSteps(double x_um, double y_um)
Definition DeviceBase.h:1969
virtual int SetRelativePositionUm(double dx, double dy)
Set relative position.
Definition DeviceBase.h:2028
virtual int ClearXYStageSequence()
Remove all values in the sequence.
Definition DeviceBase.h:2149
virtual int SetXOrigin()
Define the current position as X = 0 (in hardware if possible).
Definition DeviceBase.h:2124
virtual int UsesOnXYStagePositionChanged(bool &result) const
Return true when your device adapter uses OnXYStagePositionChanged callbacks.
Definition DeviceBase.h:2113
Base class for creating special HUB devices for managing device libraries.
Definition DeviceBase.h:2332
void AddInstalledDevice(MM::Device *pdev)
Definition DeviceBase.h:2377
virtual unsigned GetNumberOfInstalledDevices()
Return the number of child devices after DetectInstalledDevices was called.
Definition DeviceBase.h:2353
virtual int DetectInstalledDevices()
Detect installed child devices.
Definition DeviceBase.h:2345
virtual ~HubBase()
Definition DeviceBase.h:2335
HubBase()
Definition DeviceBase.h:2334
virtual void ClearInstalledDevices()
Remove all installed devices that were created by DetectInstalledDevices().
Definition DeviceBase.h:2369
virtual MM::Device * GetInstalledDevice(int devIdx)
Return a pointer to the device with index devIdx.
Definition DeviceBase.h:2361
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:27
void AddTag(const char *key, V value)
Add a tag.
Definition CameraImageMetadata.h:56
const char * Serialize() const
Return this metadata map serialized to string form.
Definition CameraImageMetadata.h:95
Callback API to the core control module.
Definition MMDevice.h:1583
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:1314
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:25
FocusDirection
Definition MMDeviceConstants.h:282
@ FocusDirectionUnknown
Definition MMDeviceConstants.h:283
PortType
Definition MMDeviceConstants.h:275
@ InvalidPort
Definition MMDeviceConstants.h:276
const char *const g_Keyword_Metadata_CameraLabel
Definition MMDeviceConstants.h:175
PropertyType
Definition MMDeviceConstants.h:258
@ Float
Definition MMDeviceConstants.h:261
@ String
Definition MMDeviceConstants.h:260
@ Integer
Definition MMDeviceConstants.h:262
const char *const g_Keyword_Transpose_Correction
Definition MMDeviceConstants.h:154
const int MaxStrLength
Definition MMDeviceConstants.h:96
DeviceType
Definition MMDeviceConstants.h:236
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:265
@ IsSequenceable
Definition MMDeviceConstants.h:269
@ AfterSet
Definition MMDeviceConstants.h:268
@ StopSequence
Definition MMDeviceConstants.h:272
@ AfterLoadSequence
Definition MMDeviceConstants.h:270
@ StartSequence
Definition MMDeviceConstants.h:271
@ BeforeGet
Definition MMDeviceConstants.h:267
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:296
@ Unimplemented
Definition MMDeviceConstants.h:297