diff --git a/sci-biology/micro-manager/Manifest b/sci-biology/micro-manager/Manifest new file mode 100644 index 0000000..f1ea2d0 --- /dev/null +++ b/sci-biology/micro-manager/Manifest @@ -0,0 +1,18 @@ +AUX Andor.cpp 138039 SHA256 17f089ac3a5e1d10f753d1c0319b6649170ceac0ac6c05cec6a88f928c7a83d5 SHA512 e32c9cc6c9d237b691bf95653a511d322a26179675921a1a4e5631f24971edb7eb14d74ebbab7148a0261cb33a05596d37af8bf863da2f1208c0a3e1fcbb457b WHIRLPOOL 21db067ec74dee9a271b87be6ee62b8fd4b411609c8b4bbd176c0bd727817e5c26f020dfc4d0cd9bff9e8be1266938a5f8d2ad7043a6a689848154b518f8ff61 +AUX Andor.h 13661 SHA256 87852c9dc2a31b80958f98fea24226fcbc31398735b32a99e7a9e45bbcbdf75a SHA512 cd37dde7dcb13c4e97416605581f768bdd483c7c5f43a916bfe9fed643b20307c6a0458ea8f4c58ec7e8f787cfb7dd9102bc6b517fca6aa6cadf19da2baa7bdb WHIRLPOOL c6517249b59c75d5fe08bd74278f5f5514264eed2bc35368efb7898261c787704a51dc9e91703cf00d7db26301f9fd445852c5902c63fbc78ad491ef4625afbb +AUX andor_camera_detection.patch 763 SHA256 eaf94996c94086cececeb359e0e056a09fcf6b6b3bdcfbc7657835d1c4039aa3 SHA512 17bdd0fdfbf8b1c9e004b2217fd6f81f25223b87a167de1d07b0e1266454bbe571b677850c316e0338bf7049adde8455f04365396f5daa912c1a0a5bad54de68 WHIRLPOOL e7518789d1a6b8878fe1082ed624b28e583ddd3dc2e3965d258ac089bc3dd3fc49e4b94cb6cd579ea530d0401311703136364909022021a51123a042c28f7794 +AUX arduino_detection.patch 634 SHA256 81f13ac088ddafa1c22a1e4bb3c616c2fcb437a38d32ca573f75dff5f1ca6a4d SHA512 3ccd769afba93f85d2962d0f31210e452f31b0647869b1bc504e958b71f96dfe67d4c312814a161a5b965abc434f3b6d413f157f7a5b0cfd99e52b2fd90ef768 WHIRLPOOL d01abf314a2ee9ab66fe7be01922be9de848d0b57fe983db3ae561c5cf6732ca2adc480096d4c50859d6914635561fbab41a5d0a8b5c6f9c7b6f4bb631b0d0e6 +AUX boost_ipc_detail.patch 858 SHA256 d56dfa262120dac6c54614d5f157bb412390ccadc22a151e736ce7372dfe154d SHA512 f1e5c6094e0b3961b3843d592f703246f119109e176e0d58a5ce92739331dd594d40f7d19b1c649f531b4c56f10c38c4bb5283e5fcd8276266c1f9e49b285ac2 WHIRLPOOL 1a8cc0be27965dedf55136dd60da65b5b5d7f39b799250fd504e5c9ea0c00c5425352e50c8b25f485aedc1e55a97207426423ef396378ca6d660f68458c184f0 +AUX disable_prefs_during_clojure_builds.patch 551 SHA256 1b5850d93bb52e971583986f3b7c936dcb6e53a085ee06cd10860543fc0c2528 SHA512 dc239137eecae4a39a38bedc5634e0ef3c4feb0bd9eb4738f5c06cbb106c07d8db5e1b2acb30b5963ab54dca0f6723e0c5772569fe95d61ae2152026990405f7 WHIRLPOOL 91984cba677ae48ce95160cfa8959de1f13c0fa4e77740cc991a3c86a8e88e2f3dcefe74cda72349b5edd2f91e37ad376fca376229e7c6c8ae23787821b6332c +AUX drop_direct_junit_paths.patch 853 SHA256 046002a1d521838c9b6914954189808f75ce30864b47ff6e003384a9f292e8e6 SHA512 9a5e41ef55b4712a56adba5a701e64199b8af36dee0a2b1e88e9b7cb1f79688676af83083b62a4a8c76dc38973d9b3d15d55836a0a7dace94f3dddcd27c6e320 WHIRLPOOL 7323e5f8cceba313617331399fe0540a418bab6799de16528c5040d0d9e8a01ecb1fb20567dc73459ae704a6ede2f6bffbd2bfed025f9c60f5b6aecbbbdf7ce1 +AUX makefile.am-typo.patch 244 SHA256 cb02714dae92dbe577c1863d73e78d405c6fe9318056319a47aee44d47b92e84 SHA512 9a5f1d7f024b4acd2a200af0705416d5ece7529e0f1300426aa526dca6e8a1715a5206838f06d8fe89c01c509e4538a95776fcced8969925b50bd712735f1de5 WHIRLPOOL 71e1eb813cd72118cf9bb0202739e546e0964169c5f08712872ed0ec9be9f694853da3f0a690c187f11c0b3910a3b916f8f527b903c3d456978346c49a4dc3cc +AUX mmcorepy_setup_add_zlib.patch 486 SHA256 ea9d7fa40410d5a6e26284d13781e23aa2d7855966661ecc6f1168dfa34d58c7 SHA512 6b0fb98f6a76bd4c13bfea169055b41165a723f1d6b55684300befb1b61b794f24ce8e6d14b0ad25eb84cc510b36b178c8d8b21c3309ab8305f79d764bef950b WHIRLPOOL 4c65bf04f7a7075311f6de1955757024c3e68d50e3bcebf5f731e700fe7a992e17dddf5f88740fdf74c292b7c40292466e7bc736f83b2aedd10e1f616f6682e3 +AUX secretdevice.patch 1074 SHA256 754561bc0f8491a765074bec7049da0184a5721614b5ade5d1fd91d73ccd6768 SHA512 63d06b8256e65a3b4d00e027e8b8e8932ce9e5d1d49603d7068757e84af6a6f706a999b24a845d3363bc466ebf6d55d8542a0be5dcc2fedba7e9e93ff8b8a25c WHIRLPOOL 2a6863edede587399c453d738c62c6ef8d3986a5da18d01cdcb852159063d4b61298bbcc2e960e47b1a2ca121c25dca28ce78ead546133c3f4349b4a8a44ae90 +DIST micro-manager-1.4.13.tar.gz 47277659 SHA256 08ce81263745e9cef928600257af6423728cc7d1840d1ccfc9f6be98e413e1bb SHA512 8473af6efbf871334512c7837baf9d6776d22bf1d061f932f97b20eb19d2e9aa01f0ab17cced422a10a5c9f4633e92141e8b8f94e8162336f812115874676ae0 WHIRLPOOL 03719f68fba876315831b25bfc60620d2b1ee70e3a47bff656ae0bdf864401d43961b0d9925b5bed7fcfa14acb70b415a85e149255bba69bcc58749d5be500c5 +DIST micro-manager-1.4.21.tar.gz 30896616 SHA256 bbb2c07455b6892f71b6e5911f9505f94c0116f0df4bb1da008a822b0dd20203 SHA512 7b82423a40c3aba24103fd5bc3dc48a6c4609e45556261c814393d68c67797ae3578a1787c1b9c2a1911b1d40ca859ea9065f56c3876f319d4483213cb675565 WHIRLPOOL 6bb75139af49ecd77a93874183e11f5d7e468eae666e65ad0ec42860d2f84dfb17cdb7054f142e1d4f966b1aa38eb9a8c9424a2a91200d78509c74f106b85d38 +DIST micro-manager-1.4.22.tar.gz 31106517 SHA256 69194632bea1f364c5f9afcd873cdc69ecf31a5c017bd2d7b2c80a78977a112d SHA512 79da65a4cf38b76eaadea72f9f2494b17726a6fbe4e790fa33802a862e1d381b0c1df0d0479a0a0fac746e90d5c32447ce34c3dcd433fc3f7dcb88e9300a1cd2 WHIRLPOOL 468c0e6d6be204da42814501e39fd1fd2c8c08c555cbfffcf100ed8fb8ea507a603d5f76f52bcb5a162818c965dcc529b27d67265585423ae0f827768adc57f6 +EBUILD micro-manager-1.4.10.ebuild 4908 SHA256 a28116c852fb2ad52d0da8989689472d530207eb8cf4ec224288097f9bad22f0 SHA512 4e327d139b1dc182356a37c553e57a9d1ad7af9ffbbd5ffdb51a08dda6b0bb8f349a8f928ffe709f35b6bf03359100962a42c65d9f5c07858fba87bf29c1271f WHIRLPOOL 136405ac0d690ce4c5d8924dad11caea8fbb516439cba3e3adebe527d2d3de1bf69dae400dd0ed9e86c795a217d5f17026798ff4c089f83f30ccf70e5d7dc040 +EBUILD micro-manager-1.4.13.ebuild 5905 SHA256 1d49668c156c9aba09c232b5fced56695904c46e7f4c913b20cd67ffeb1450e3 SHA512 2eee78a1017fe24b039ca8de4b5320ab9683294fb4ca3275416f47b034afc6162111682323163f41c61615a599528cb24e699cffd193322b7202bd27a3e50c69 WHIRLPOOL 2b793da0b8c2b3387b44cb49a23f7f94a4bd04214db218523f15703644b806cb04747c34cfb737d273e76ff9f5eeb0917ed8a63acb43a6104258e42e5d73d507 +EBUILD micro-manager-1.4.21-r1.ebuild 6151 SHA256 ef2307cc71434315c52b8f2961badc2e299546e0da90898f06b2914a7f8e1392 SHA512 547a61d0f63636ae098f3d9050993727c0318fa06ce6541ebf30153e00fd466299fdba22da909b6575d7ea79a91e28ae396504a5734565f7eaab728568d7617e WHIRLPOOL 6ea78ef3a928aa9b423f6f67a515a9773ef6f4beb148884aca8209dcbfdb18540a9b9cd093a8a8c35ab04d34853ee3d378640a61591188634f050978976998f2 +EBUILD micro-manager-1.4.22.ebuild 6192 SHA256 bb75f2e6f2aea81ca03335deb6cd4ee88012ea658c20118067caae851bd7f222 SHA512 7299b848c3f288b4fb3c6a3b9b5f70ba39c84aece37278e11362a51cad848b432b2381184efeaf46c6a23d317e69e8494134597ae0d309b603d48f081ecd48cc WHIRLPOOL 0e2a0de610cb005a1d83e99cfeca8aaad775860308cddea8c3d15b978a329ef6461135b9a6aa9a3f3738de46e41925eea17f941612dad939d476be1f7267d4ca +EBUILD micro-manager-9999.ebuild 6192 SHA256 f88bc6bf2a6ee4910c07f9adfe6d93146739655db42743e81fd0cdf69f4ae529 SHA512 09ec7df0e5dfab650856d45822f6c825c23ef9e910843627cdb971ab7abd23bb91a3bcfed9f0265ef68b9c5b2fa86e6317ee1f66fe7f3d1e37e135afa1465510 WHIRLPOOL e4004186b49d5ab89e7f70f0ada84db66a8a67f32bf7a8ce2495ed36c594e57f43a623039d9358096120e68cd489409a46187c986c9efcc856c65dca05945d54 diff --git a/sci-biology/micro-manager/files/Andor.cpp b/sci-biology/micro-manager/files/Andor.cpp new file mode 100644 index 0000000..8af93e3 --- /dev/null +++ b/sci-biology/micro-manager/files/Andor.cpp @@ -0,0 +1,4541 @@ +/////////////////////////////////////////////////////////////////////////////// +// FILE: Andor.cpp +// PROJECT: Micro-Manager +// SUBSYSTEM: DeviceAdapters +//----------------------------------------------------------------------------- +// DESCRIPTION: Andor camera module +// +// AUTHOR: Nenad Amodaj, nenad@amodaj.com, 06/30/2006 +// COPYRIGHT: University of California, San Francisco, 2006 +// LICENSE: This file is distributed under the BSD license. +// License text is included with the source distribution. +// +// This file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES. +// +// REVISIONS: May 21, 2007, Jizhen Zhao, Andor Technologies +// Temerature control and other additional related properties added, +// gain bug fixed, refernce counting fixed for shutter adapter. +// +// May 23 & 24, 2007, Daigang Wen, Andor Technology plc added/modified: +// Cooler is turned on at startup and turned off at shutdown +// Cooler control is changed to cooler mode control +// Pre-Amp-Gain property is added +// Temperature Setpoint property is added +// Temperature is resumed as readonly +// EMGainRangeMax and EMGainRangeMin are added +// +// April 3 & 4, 2008, Nico Stuurman, UCSF +// Changed Sleep statement in AcqSequenceThread to be 20% of the actualInterval instead of 5 ms +// Added property limits to the Gain (EMGain) property +// Added property limits to the Temperature Setpoint property and delete TempMin and TempMax properties +// +// FUTURE DEVELOPMENT: From September 1 2007, the development of this adaptor is taken over by Andor Technology plc. Daigang Wen (d.wen@andor.com) is the main contact. Changes made by him will not be labeled. +// LINUX DEVELOPMENT: From February 1, 2009, Linux compatibility was done by Karl Bellve at the Biomedical Imaging Group at the University of Massachusetts (Karl.Bellve@umassmed.edu) +// CVS: $Id: Andor.cpp 10061 2012-10-09 15:38:57Z normanglasgow $ + +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include "atmcd32d.h" +#else +#include "atmcdLXd.h" +#include +#include +#ifndef MAX_PATH +#define MAX_PATH PATH_MAX +#endif +#define stricmp strcasecmp +#define strnicmp strncasecmp +#endif + +#include "../../MMDevice/ModuleInterface.h" +#include "Andor.h" +#include +#include +#include +#include + + +#include +using namespace std; + +#pragma warning(disable : 4996) // disable warning for deperecated CRT functions on Windows + +using namespace std; + +// global constants +const char* g_AndorName = "Andor"; +const char* g_IxonName = "Ixon"; + +const char* g_PixelType_8bit = "8bit"; +const char* g_PixelType_16bit = "16bit"; + +const char* g_ShutterMode = "ShutterMode"; +const char* g_ShutterMode_Auto = "Auto"; +const char* g_ShutterMode_Open = "Open"; +const char* g_ShutterMode_Closed = "Closed"; + +const char* g_FanMode_Full = "Full"; +const char* g_FanMode_Low = "Low"; +const char* g_FanMode_Off = "Off"; + +const char* g_CoolerMode_FanOffAtShutdown = "Fan off at shutdown"; +const char* g_CoolerMode_FanOnAtShutdown = "Fan on at shutdown"; + +//const char* g_FrameTransferProp = "FrameTransfer"; +const char* g_FrameTransferOn = "On"; +const char* g_FrameTransferOff = "Off"; +const char* g_OutputAmplifier = "Output_Amplifier"; +const char* g_OutputAmplifier_EM = "Standard EMCCD gain register"; +const char* g_OutputAmplifier_Conventional = "Conventional CCD register"; + +const char* g_ADChannel = "AD_Converter"; + +const char* g_EMGain = "EMSwitch"; +const char* g_EMGainValue = "Gain"; +const char* g_TimeOut = "TimeOut"; +const char* g_CameraInformation = "1. Camera Information : | Type | Model | Serial No. |"; + +const char* g_cropMode = "Isolated Crop Mode"; +const char* g_cropModeWidth = "Isolated Crop Width"; +const char* g_cropModeHeight = "Isolated Crop Height"; + +// singleton instance +AndorCamera* AndorCamera::instance_ = 0; +unsigned int AndorCamera::refCount_ = 0; +bool AndorCamera::softwareTriggerUsed_ = false; + +// global Andor driver thread lock +MMThreadLock g_AndorDriverLock; + +// kdb 2/27/2009 +#ifdef WIN32 +// Windows dll entry routine +bool APIENTRY DllMain( HANDLE /*hModule*/, + DWORD ul_reason_for_call, + LPVOID /*lpReserved*/ ) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#else +#include +#define WORD ushort +long GetTickCount() +{ + tms tm; + return times(&tm); +} +#endif +// end of kdb + +// macro for finding the source of unsuccessful return error code +#define CATCH(err) if (err != DRV_SUCCESS) { \ + LogMessage("Return code %u instead of DRV_SUCCESS at %s/%s:%d\n", \ + err, __FILE__, __FUNCTION__, __LINE__); \ + return (int)ret; \ +} +/////////////////////////////////////////////////////////////////////////////// +// Exported MMDevice API +/////////////////////////////////////////////////////////////////////////////// + +MODULE_API void InitializeModuleData() +{ + AddAvailableDeviceName(g_AndorName, "Generic Andor Camera Adapter"); + +} + +char deviceName[64]; // jizhen 05.16.2007 + +MODULE_API void DeleteDevice(MM::Device* pDevice) +{ + + delete pDevice; + +} + +MODULE_API MM::Device* CreateDevice(const char* deviceName) +{ + if (deviceName == 0) { + return 0; + } + + string strName(deviceName); + + if (strcmp(deviceName, g_AndorName) == 0) { + return AndorCamera::GetInstance(); + } + else if (strcmp(deviceName, g_IxonName) == 0) { + return AndorCamera::GetInstance(); + } + + + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////// +// AndorCamera constructor/destructor + +AndorCamera::AndorCamera() : +initialized_(false), +busy_(false), +snapInProgress_(false), +binSize_(1), +expMs_(0.0), +driverDir_(""), +fullFrameBuffer_(0), +fullFrameX_(0), +fullFrameY_(0), +tempFrameX_(0), +tempFrameY_(0), +EmCCDGainLow_(0), +EmCCDGainHigh_(0), +EMSwitch_(true), +minTemp_(0), +ThermoSteady_(0), +lSnapImageCnt_(0), +currentGain_(-1), +ReadoutTime_(50), +ADChannelIndex_(0), +sequenceRunning_(false), +startTime_(0), +imageCounter_(0), +imageTimeOut_ms_(10000), +sequenceLength_(0), +OutputAmplifierIndex_(0), +HSSpeedIdx_(0), +bSoftwareTriggerSupported_(0), +maxTemp_(0), +myCameraID_(-1), +pImgBuffer_(0), +currentExpMS_(0.0), +cropModeSwitch_(false), +currentCropWidth_(64), +currentCropHeight_(64), +bFrameTransfer_(0), +stopOnOverflow_(true), +iCurrentTriggerMode_(INTERNAL), +strCurrentTriggerMode_(""), +ui_swVersion(0), +sequencePaused_(0), +countConvertMode_(""), +countConvertWavelength_(0.0), +optAcquireModeStr_(""), +optAcquireDescriptionStr_(""), +spuriousNoiseFilter_(""), +spuriousNoiseFilterDescriptionStr_("") +{ + InitializeDefaultErrorMessages(); + + // add custom messages + SetErrorText(ERR_BUSY_ACQUIRING, "Camera Busy. Stop camera activity first."); + SetErrorText(ERR_NO_AVAIL_AMPS, "No available amplifiers."); + SetErrorText(ERR_TRIGGER_NOT_SUPPORTED, "Trigger Not supported."); + SetErrorText(ERR_INVALID_VSPEED, "Invalid Vertical Shift Speed."); + SetErrorText(ERR_INVALID_PREAMPGAIN, "Invalid Pre-Amp Gain."); + SetErrorText(ERR_CAMERA_DOES_NOT_EXIST, "No Camera Found. Make sure it is connected and switched on, and try again."); + SetErrorText(DRV_NO_NEW_DATA, "No new data arrived within a reasonable time."); + SetErrorText(ERR_SOFTWARE_TRIGGER_IN_USE, "Only one camera can use software trigger."); + + seqThread_ = new AcqSequenceThread(this); + + // Pre-initialization properties + // ----------------------------- + + // Driver location property removed. atmcd32d.dll should be in the working directory + hAndorDll = 0; + fpGetKeepCleanTime = 0; + fpGetReadOutTime = 0; + +#ifdef WIN32 + if(hAndorDll == 0) + hAndorDll = ::GetModuleHandle("atmcd32d.dll"); + if(hAndorDll!=NULL) + { + fpGetKeepCleanTime = (FPGetKeepCleanTime)GetProcAddress(hAndorDll, "GetKeepCleanTime"); + fpGetReadOutTime = (FPGetReadOutTime)GetProcAddress(hAndorDll, "GetReadOutTime"); + } +#else + // load andor.so that interfaces with the andordrvlx kernel module on linux systems + hAndorDll = dlopen("libandor.so.2", RTLD_LAZY|RTLD_GLOBAL); + if (!hAndorDll) + { + fprintf(stderr,"Failed to find libandor.so.2\n"); + exit(1); + } + else + { + fpGetKeepCleanTime = (FPGetKeepCleanTime)dlsym(hAndorDll, "GetKeepCleanTime"); + fpGetReadOutTime = (FPGetReadOutTime)dlsym(hAndorDll, "GetReadOutTime"); + } + // this needs to be initialized for Linux, or ::Initialize() will not return + driverDir_ = "/usr/local/etc/andor/"; +#endif + + if (GetListOfAvailableCameras() != DRV_SUCCESS) + //exit(1); + LogMessage("No Andor camera found!"); +} + +AndorCamera::~AndorCamera() +{ + DriverGuard dg(this); + delete seqThread_; + + + refCount_--; + if (refCount_ == 0) { + // release resources + if (initialized_) { + SetToIdle(); + int ShutterMode = 2; //0: auto, 1: open, 2: close + SetShutter(1, ShutterMode, 20,20);//0, 0); + } + + + if (initialized_ && mb_canSetTemp) { + CoolerOFF(); //turn off the cooler at shutdown + } + + if (initialized_) { + Shutdown(); + } + // clear the instance pointer + instance_ = 0; + } + +#ifndef WIN32 + if (hAndorDll) dlclose(hAndorDll); +#endif +} + +AndorCamera* AndorCamera::GetInstance() +{ + //if (!instance_) { + instance_ = new AndorCamera(); + //} + + refCount_++; + return instance_; +} + + +/////////////////////////////////////////////////////////////////////////////// +// API methods +// ~~~~~~~~~~~ + +/** +* Get list of all available cameras +*/ +int AndorCamera::GetListOfAvailableCameras() +{ + unsigned int ret; + vCameraType.clear(); + NumberOfAvailableCameras_ = 0; + ret = GetAvailableCameras(&NumberOfAvailableCameras_); + CATCH(ret) + if(NumberOfAvailableCameras_ == 0) { + return ERR_CAMERA_DOES_NOT_EXIST; + } + + at_32 CameraID; + int UnknownCameraIndex = 0; + NumberOfWorkableCameras_ = 0; + cameraName_.clear(); + cameraID_.clear(); + for(int i=0;i(driverDir_.c_str())); + if( ret != DRV_SUCCESS && ret != DRV_ERROR_FILELOAD ) { + ret = ShutDown(); + } + } + if( ret == DRV_SUCCESS) { + NumberOfWorkableCameras_++; + + std::string anStr; + char chars[255]; + ret = GetHeadModel(chars); + if( ret!=DRV_SUCCESS ) { + anStr = "UnknownModel"; + } + else { + anStr = chars; + } + // mm can't deal with commas!! + size_t ifind = anStr.find(","); + while(std::string::npos != ifind) + { + anStr.replace(ifind,1,"~"); + ifind = anStr.find(","); + } + + int id; + ret = GetCameraSerialNumber(&id); + if( ret!=DRV_SUCCESS ) { + UnknownCameraIndex ++; + id = UnknownCameraIndex; + } + sprintf(chars, "%d", id); + + std::string camType = getCameraType(); + vCameraType.push_back(camType); + anStr = "| " + camType + " | " + anStr + " | " + chars + " |"; + cameraName_.push_back(anStr); + + cameraID_.push_back((int)CameraID); + } + + myCameraID_ = CameraID; + } + } + + if(NumberOfWorkableCameras_>=1) + { + //camera property for multiple camera support + //removed because list boxes in Property Browser of MM are unable to update their values after switching camera + CPropertyAction *pAct = new CPropertyAction (this, &AndorCamera::OnCamera); + int nRet = CreateProperty("Camera", cameraName_[NumberOfWorkableCameras_-1].c_str(), MM::String, false, pAct, true); + assert(nRet == DEVICE_OK); + nRet = SetAllowedValues("Camera", cameraName_); + + return DRV_SUCCESS; + } else { + return ERR_CAMERA_DOES_NOT_EXIST; + } + +} + + /** + * Set camera + */ + int AndorCamera::OnCamera(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + //added to use RTA + SetToIdle(); + + string CameraName; + pProp->Get(CameraName); + for (unsigned i=0; iSet(CameraName_.c_str()); + } + return DEVICE_OK; + } + + /** + * iCam Features + */ + int AndorCamera::OniCamFeatures(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(iCamFeatures_.c_str()); + } + return DEVICE_OK; + } + + /** + * Temperature Range Min + */ + int AndorCamera::OnTemperatureRangeMin(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(TemperatureRangeMin_.c_str()); + } + return DEVICE_OK; + } + + /** + * Temperature Range Min + */ + int AndorCamera::OnTemperatureRangeMax(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(TemperatureRangeMax_.c_str()); + } + return DEVICE_OK; + } + + + + /** + * Initialize the camera. + */ + int AndorCamera::Initialize() + { + if (initialized_) + return DEVICE_OK; + + unsigned ret; + int nRet; + CPropertyAction *pAct; + + if(myCameraID_ == -1) + { + ret = 0; + for(int i = 0; i < NumberOfWorkableCameras_; ++i) { + myCameraID_ = cameraID_[i]; + ret = SetCurrentCamera(myCameraID_); + if (ret == DRV_SUCCESS) + ret = ::Initialize(const_cast(driverDir_.c_str())); + } + + CATCH(ret) + } + else + { + ret = SetCurrentCamera(myCameraID_); + CATCH(ret) + ret = ::Initialize(const_cast(driverDir_.c_str())); + CATCH(ret) + } + + // Name + int currentCameraIdx = 0; + if(cameraID_.size()>1) + { + for(unsigned int i=0;i 1) + { + if(!HasProperty(g_OutputAmplifier)) + { + CPropertyAction *pAct = new CPropertyAction (this, &AndorCamera::OnOutputAmplifier); + nRet = CreateProperty(g_OutputAmplifier, vAvailAmps[0].c_str(), MM::String, false, pAct); + } + nRet = SetAllowedValues(g_OutputAmplifier, vAvailAmps); + assert(nRet == DEVICE_OK); + nRet = SetProperty(g_OutputAmplifier, vAvailAmps[0].c_str()); + assert(nRet == DEVICE_OK); + if (nRet != DEVICE_OK) + return nRet; + } + + //AD channel (pixel bitdepth) + int numADChannels; + ret = GetNumberADChannels(&numADChannels); + CATCH(ret) + + vChannels.clear(); + for(int i = 0; i < numADChannels; ++i) { + int depth; + ::GetBitDepth(i, &depth); + char * buffer = new char[64]; + sprintf(buffer, "%d. %dbit",(i+1), depth); + std::string temp(buffer); + vChannels.push_back(temp); + delete [] buffer; + } + if(numADChannels > 1) + { + + if(!HasProperty(g_ADChannel)) + { + CPropertyAction *pAct = new CPropertyAction (this, &AndorCamera::OnADChannel); + nRet = CreateProperty(g_ADChannel,vChannels[0].c_str() , MM::String, false, pAct); + assert(nRet == DEVICE_OK); + } + nRet = SetAllowedValues(g_ADChannel, vChannels); + assert(nRet == DEVICE_OK); + if (nRet != DEVICE_OK) + return nRet; + nRet = SetProperty(g_ADChannel, vChannels[0].c_str()); + if (nRet != DEVICE_OK) + return nRet; + } + + ret = SetADChannel(0); //0:14bit, 1:16bit(if supported) + CATCH(ret) + ret = SetOutputAmplifier(0); //0:EM port, 1:Conventional port + CATCH(ret) + + // head model + char model[32]; + ret = GetHeadModel(model); + CATCH(ret) + + // Get detector information + ret = GetDetector(&fullFrameX_, &fullFrameY_); + CATCH(ret) + + roi_.x = 0; + roi_.y = 0; + roi_.xSize = fullFrameX_; + roi_.ySize = fullFrameY_; + tempFrameX_ = fullFrameX_; + tempFrameY_ = fullFrameY_; + binSize_ = 1; + fullFrameBuffer_ = new short[fullFrameX_ * fullFrameY_]; + + // setup image parameters + // ---------------------- + if(iCurrentTriggerMode_ == SOFTWARE) + ret = SetAcquisitionMode(5);// 1: single scan mode, 5: RTA + else + ret = SetAcquisitionMode(1);// 1: single scan mode, 5: RTA + + CATCH(ret) + + ret = SetReadMode(4); // image mode + CATCH(ret) + + // binning + if(!HasProperty(MM::g_Keyword_Binning)) + { + CPropertyAction *pAct = new CPropertyAction (this, &AndorCamera::OnBinning); + nRet = CreateProperty(MM::g_Keyword_Binning, "1", MM::Integer, false, pAct); + assert(nRet == DEVICE_OK); + } + else + { + nRet = SetProperty(MM::g_Keyword_Binning, "1"); + if (nRet != DEVICE_OK) + return nRet; + } + + vector binValues; + binValues.push_back("1"); + binValues.push_back("2"); + binValues.push_back("4"); + binValues.push_back("8"); + nRet = SetAllowedValues(MM::g_Keyword_Binning, binValues); + if (nRet != DEVICE_OK) + return nRet; + + // pixel type + if(!HasProperty(MM::g_Keyword_PixelType)) + { + pAct = new CPropertyAction (this, &AndorCamera::OnPixelType); + nRet = CreateProperty(MM::g_Keyword_PixelType, g_PixelType_16bit, MM::String, false, pAct); + assert(nRet == DEVICE_OK); + } + + vector pixelTypeValues; + pixelTypeValues.push_back(g_PixelType_16bit); + nRet = SetAllowedValues(MM::g_Keyword_PixelType, pixelTypeValues); + if (nRet != DEVICE_OK) + return nRet; + nRet = SetProperty(MM::g_Keyword_PixelType, pixelTypeValues[0].c_str()); + if (nRet != DEVICE_OK) + return nRet; + + // exposure + if(!HasProperty(MM::g_Keyword_Exposure)) + { + pAct = new CPropertyAction (this, &AndorCamera::OnExposure); + nRet = CreateProperty(MM::g_Keyword_Exposure, "10.0", MM::Float, false, pAct); + assert(nRet == DEVICE_OK); + } + else + { + nRet = SetProperty(MM::g_Keyword_Exposure,"10.0"); + assert(nRet == DEVICE_OK); + } + + int InternalShutter; + ret = IsInternalMechanicalShutter(&InternalShutter); + if(InternalShutter == 0) + bShutterIntegrated_ = false; + else + { + bShutterIntegrated_ = true; + if(!HasProperty("InternalShutter")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnInternalShutter); + nRet = CreateProperty("InternalShutter", g_ShutterMode_Open, MM::String, false, pAct); + assert(nRet == DEVICE_OK); + } + + vector shutterValues; + shutterValues.push_back(g_ShutterMode_Open); + shutterValues.push_back(g_ShutterMode_Closed); + nRet = SetAllowedValues("InternalShutter", shutterValues); + if (nRet != DEVICE_OK) + return nRet; + nRet = SetProperty("InternalShutter", shutterValues[0].c_str()); + if (nRet != DEVICE_OK) + return nRet; + } + int ShutterMode = 1; //0: auto, 1: open, 2: close + ret = SetShutter(1, ShutterMode, 20,20);//Opened any way because some old AndorCamera has no flag for IsInternalMechanicalShutter + + + // readout mode + int numSpeeds; + ret = GetNumberHSSpeeds(0, 0, &numSpeeds); + CATCH(ret) + + char speedBuf[100]; + readoutModes_.clear(); + for (int i=0; i 0 ) { + + char PreAmpGainBuf[10]; + PreAmpGains_.clear(); + for (int i=0; i= 292) { + ret = GetPreAmpGainText(i, PreAmpGainBuf, sizeof(PreAmpGainBuf)); + } + else { + float pag; + ret = GetPreAmpGain(i, &pag); + sprintf(PreAmpGainBuf, "%.2f", pag); + } + CATCH(ret) + PreAmpGains_.push_back(PreAmpGainBuf); + } + if (PreAmpGains_.empty()) + return ERR_INVALID_PREAMPGAIN; + + if(!HasProperty("Pre-Amp-Gain")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnPreAmpGain); + if(numPreAmpGain>1) + nRet = CreateProperty("Pre-Amp-Gain", PreAmpGains_[numPreAmpGain-1].c_str(), MM::String, false, pAct); + else + nRet = CreateProperty("Pre-Amp-Gain", PreAmpGains_[numPreAmpGain-1].c_str(), MM::String, true, pAct); + assert(nRet == DEVICE_OK); + } + nRet = SetAllowedValues("Pre-Amp-Gain", PreAmpGains_); + nRet = SetProperty("Pre-Amp-Gain", PreAmpGains_[PreAmpGains_.size()-1].c_str()); + PreAmpGain_ = PreAmpGains_[numPreAmpGain-1]; + if(numPreAmpGain > 1) + { + ret = SetPreAmpGain(numPreAmpGain-1); + CATCH(ret) + } + } + + // Vertical Shift Speed + int numVSpeed; + ret = GetNumberVSSpeeds(&numVSpeed); + CATCH(ret) + + char VSpeedBuf[10]; + VSpeeds_.clear(); + for (int i=0; i1) + nRet = CreateProperty("VerticalSpeed", VSpeeds_[numVSpeed-1].c_str(), MM::String, false, pAct); + else + nRet = CreateProperty("VerticalSpeed", VSpeeds_[numVSpeed-1].c_str(), MM::String, true, pAct); + assert(nRet == DEVICE_OK); + } + nRet = SetAllowedValues("VerticalSpeed", VSpeeds_); + assert(nRet == DEVICE_OK); + nRet = SetProperty("VerticalSpeed", VSpeeds_[VSpeeds_.size()-1].c_str()); + VSpeed_ = VSpeeds_[numVSpeed-1]; + assert(nRet == DEVICE_OK); + + + // Vertical Clock Voltage + int numVCVoltages; + ret = GetNumberVSAmplitudes(&numVCVoltages); + if (ret != DRV_SUCCESS) { + numVCVoltages = 0; + ostringstream eMsg; + eMsg << "Andor driver returned error code: " << ret << " to GetNumberVSAmplitudes"; + LogMessage(eMsg.str().c_str(), true); + } + VCVoltages_.clear(); + if(ui_swVersion >= 292) { + for (int i = 0; i < numVCVoltages; i++) + { + char VCAmp[10]; + ret = GetVSAmplitudeString(i, VCAmp); + + if (ret != DRV_SUCCESS) { + numVCVoltages = 0; + ostringstream eMsg; + eMsg << "Andor driver returned error code: " << ret << " to GetVSAmplitudeString"; + LogMessage(eMsg.str().c_str(), true); + } + else + { + VCVoltages_.push_back(VCAmp); + } + } + } + else { + if(numVCVoltages>5) + numVCVoltages = 5; + switch(numVCVoltages) + { + case 1: + VCVoltages_.push_back("Normal"); + break; + case 2: + VCVoltages_.push_back("Normal"); + VCVoltages_.push_back("+1"); + break; + case 3: + VCVoltages_.push_back("Normal"); + VCVoltages_.push_back("+1"); + VCVoltages_.push_back("+2"); + break; + case 4: + VCVoltages_.push_back("Normal"); + VCVoltages_.push_back("+1"); + VCVoltages_.push_back("+2"); + VCVoltages_.push_back("+3"); + break; + case 5: + VCVoltages_.push_back("Normal"); + VCVoltages_.push_back("+1"); + VCVoltages_.push_back("+2"); + VCVoltages_.push_back("+3"); + VCVoltages_.push_back("+4"); + break; + default: + VCVoltages_.push_back("Normal"); + } + } + if (numVCVoltages>=1) + { + if(!HasProperty("VerticalClockVoltage")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnVCVoltage); + if(numVCVoltages>1) + nRet = CreateProperty("VerticalClockVoltage", VCVoltages_[0].c_str(), MM::String, false, pAct); + else + nRet = CreateProperty("VerticalClockVoltage", VCVoltages_[0].c_str(), MM::String, true, pAct); + assert(nRet == DEVICE_OK); + } + nRet = SetAllowedValues("VerticalClockVoltage", VCVoltages_); + assert(nRet == DEVICE_OK); + nRet = SetProperty("VerticalClockVoltage", VCVoltages_[0].c_str()); + VCVoltage_ = VCVoltages_[0]; + assert(nRet == DEVICE_OK); + } + + + // camera temperature + // temperature range + std::string strTips(""); + int minTemp, maxTemp; + + if(mb_canSetTemp) { + + ret = GetTemperatureRange(&minTemp, &maxTemp); + CATCH(ret) + minTemp_ = minTemp; + maxTemp_ = maxTemp; + ostringstream tMin; + ostringstream tMax; + tMin << minTemp; + tMax << maxTemp; + + + //added to show some tips + strTips = "Wait for temperature to stabilize before acquisition."; + if(!HasProperty("CCDTemperature Help")) + { + nRet = CreateProperty("CCDTemperature Help", strTips.c_str(), MM::String, true); + } + else + { + nRet = SetProperty("CCDTemperature Help", strTips.c_str()); + } + } + assert(nRet == DEVICE_OK); + + if(iCurrentTriggerMode_ == SOFTWARE) + { + strTips = "To maximize frame rate, do not change camera parameters except Exposure in Configuration Presets."; + if(!HasProperty(" Tip2")) + { + nRet = CreateProperty(" Tip2", strTips.c_str(), MM::String, true); + } + else + { + nRet = SetProperty(" Tip2", strTips.c_str()); + } + assert(nRet == DEVICE_OK); + } + + int temp; + ret = GetTemperature(&temp); + ostringstream strTemp; + strTemp< CCValues; + CCValues.push_back("Counts"); + CCValues.push_back("Electrons"); + CCValues.push_back("Photons"); + nRet = SetAllowedValues("CountConvert", CCValues); + + if (nRet != DEVICE_OK) + return nRet; + + + // CountCOnvertWavelength + if(!HasProperty("CountConvertWavelength")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnCountConvertWavelength); + nRet = CreateProperty("CountConvertWavelength", "0.0", MM::Float, false, pAct); + } + else + { + nRet = SetProperty("CountConvertWavelength", "0.0"); + } + assert(nRet == DEVICE_OK); + } + + // SpuriousNoiseFilter + if(caps.ulFeatures&AC_FEATURES_REALTIMESPURIOUSNOISEFILTER) //some cameras might not support this + { + if(!HasProperty("SpuriousNoiseFilter")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnSpuriousNoiseFilter); + nRet = CreateProperty("SpuriousNoiseFilter", "None", MM::String, false, pAct); + assert(nRet == DEVICE_OK); + } + else + { + nRet = SetProperty("SpuriousNoiseFilter", "None"); + if (nRet != DEVICE_OK) + return nRet; + } + + SetProperty("SpuriousNoiseFilter", "None"); + vector CCValues; + CCValues.push_back("None"); + CCValues.push_back("Median"); + CCValues.push_back("Level Above"); + nRet = SetAllowedValues("SpuriousNoiseFilter", CCValues); + + if (nRet != DEVICE_OK) + return nRet; + + + // SpuriousNoiseFilterThreshold + if(!HasProperty("SpuriousNoiseFilterThreshold")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnSpuriousNoiseFilterThreshold); + nRet = CreateProperty("SpuriousNoiseFilterThreshold", "0.0", MM::Float, false, pAct); + } + else + { + nRet = SetProperty("SpuriousNoiseFilterThreshold", "0.0"); + } + + // Description + if (!HasProperty("SpuriousNoiseFilterDescription")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnSpuriousNoiseFilterDescription); + nRet = CreateProperty("SpuriousNoiseFilterDescription", "Recommended Range", MM::String, true, pAct); + } + + assert(nRet == DEVICE_OK); + } + + //OptAcquire + if(caps.ulFeatures&AC_FEATURES_OPTACQUIRE) //some cameras might not support this + { + unsigned int ui_numberOfModes = 0; + char * pc_acqModes; + vector OAModeNames; + unsigned int ui_retVal = 0; + try + { + ui_retVal = ::OA_Initialize("C:\\userconfig.xml", (unsigned int) strlen("C:\\userconfig.xml")); + + //Get the number of available Preset modes for the current camera + ui_retVal = ::OA_GetNumberOfPreSetModes(&ui_numberOfModes); + if(ui_retVal == DRV_SUCCESS && ui_numberOfModes > 0) { + //Allocate enough memory to hold the list of Mode names remembering to add space for the delimiter + pc_acqModes = static_cast(malloc((ui_numberOfModes*MAX_PATH) + (ui_numberOfModes + 1))); + //Get a list of Preset mode names + ui_retVal = OA_GetPreSetModeNames(pc_acqModes); + + if(ui_retVal == DRV_SUCCESS) { + + if(!HasProperty("OptAcquireMode")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnOptAcquireMode); + nRet = CreateProperty("OptAcquireMode", "NoMode", MM::String, false, pAct); + assert(nRet == DEVICE_OK); + } + else + { + nRet = SetProperty("OptAcquireMode", "NoMode"); + if (nRet != DEVICE_OK) + return nRet; + } + + SetProperty("OptAcquireMode", "NoMode"); + //Add Preset mode names to list + char * pc_result = strtok( pc_acqModes, "," ); + for(unsigned int i = 0; i < ui_numberOfModes; i++){ + if (NULL != pc_result) { + OAModeNames.push_back(pc_result); + } + pc_result = strtok(NULL, "," ); + } + } + nRet = SetAllowedValues("OptAcquireMode", OAModeNames); + free(pc_acqModes); + } + if (nRet != DEVICE_OK) + return nRet; + + // Description + if (!HasProperty("OptAcquireMode Description")) + { + pAct = new CPropertyAction (this, &AndorCamera::OnOADescription); + nRet = CreateProperty("OptAcquireMode Description", "Selected OptAcquireMode Description", MM::String, true, pAct); + } + assert(nRet == DEVICE_OK); + + } + catch (...) + { + LogMessage("Caught an exception in the Andor driver while calling OA_Initialize"); + } + + } + + //DMA parameters + //if(caps.ulSetFunctions & AC_SETFUNCTION_DMAPARAMETERS) + { + int NumFramesPerDMA = 1; + float SecondsPerDMA = 0.001f; + ret = SetDMAParameters(NumFramesPerDMA, SecondsPerDMA); + if (DRV_SUCCESS != ret) + return (int)ret; + } + + + pAct = new CPropertyAction (this, &AndorCamera::OnTimeOut); + nRet = CreateProperty(g_TimeOut, CDeviceUtils::ConvertToString(imageTimeOut_ms_), MM::Integer, false, pAct); + + + // synchronize all properties + // -------------------------- + /* + nRet = UpdateStatus(); + if (nRet != DEVICE_OK) + return nRet; + */ + + // setup the buffer + // ---------------- + nRet = ResizeImageBuffer(); + if (nRet != DEVICE_OK) + return nRet; + + // explicitely set properties which are not readable from the camera + nRet = SetProperty(MM::g_Keyword_Binning, "1"); + if (nRet != DEVICE_OK) + return nRet; + + if(bShutterIntegrated_) + { + nRet = SetProperty("InternalShutter", g_ShutterMode_Open); + if (nRet != DEVICE_OK) + return nRet; + } + if(mb_canSetTemp) { + nRet = SetProperty(MM::g_Keyword_CCDTemperatureSetPoint, strTempSetPoint.c_str()); + if (nRet != DEVICE_OK) { + return nRet; + } + } + + + nRet = SetProperty(MM::g_Keyword_Exposure, "10.0"); + if (nRet != DEVICE_OK) + return nRet; + + nRet = SetProperty(MM::g_Keyword_ReadoutMode, readoutModes_[0].c_str()); + if (nRet != DEVICE_OK) + return nRet; + if(mb_canUseFan) { + nRet = SetProperty("FanMode", g_FanMode_Full); + if (nRet != DEVICE_OK) + return nRet; + } + + if(((caps.ulAcqModes & AC_ACQMODE_FRAMETRANSFER) == AC_ACQMODE_FRAMETRANSFER) + || ((caps.ulAcqModes & AC_ACQMODE_OVERLAP) == AC_ACQMODE_OVERLAP)){ + + nRet = SetProperty(m_str_frameTransferProp.c_str(), g_FrameTransferOff); + if (nRet != DEVICE_OK) + return nRet; + } + if(mb_canSetTemp) { + nRet = SetProperty("CoolerMode", g_CoolerMode_FanOffAtShutdown); + if (nRet != DEVICE_OK) { + return nRet; + } + ret = CoolerON(); //turn on the cooler at startup + if (DRV_SUCCESS != ret) { + return (int)ret; + } + } + if(HasProperty(g_EMGainValue)) { + if((EmCCDGainHigh_>=300) && ((caps.ulSetFunctions&AC_SETFUNCTION_EMADVANCED) == AC_SETFUNCTION_EMADVANCED)) + { + ret = SetEMAdvanced(1); //Enable extended range of EMGain + if (DRV_SUCCESS != ret) + return (int)ret; + } + + UpdateEMGainRange(); + currentGain_ = EmCCDGainLow_; + ret = SetEMCCDGain(static_cast(currentGain_)); + if(ret != DRV_SUCCESS) { + return (int)ret; + } + } + GetReadoutTime(); + + nRet = UpdateStatus(); + if (nRet != DEVICE_OK) + return nRet; + + initialized_ = true; + + if (bSoftwareTriggerSupported_) + { + iCurrentTriggerMode_ = SOFTWARE; + strCurrentTriggerMode_ = "Software"; + UpdateSnapTriggerMode(); + } + + PrepareSnap(); + + return DEVICE_OK; + } + + void AndorCamera::GetName(char* name) const + { + CDeviceUtils::CopyLimitedString(name, g_AndorName); + } + + /** + * Deactivate the camera, reverse the initialization process. + */ + int AndorCamera::Shutdown() + { + DriverGuard dg(this); + + int ret; + + if (initialized_) + { + SetToIdle(); + int ShutterMode = 2; //0: auto, 1: open, 2: close + SetShutter(1, ShutterMode, 20,20);//0, 0); + if(mb_canSetTemp) {CoolerOFF();} //Daigang 24-may-2007 turn off the cooler at shutdown + ret = ShutDown(); + } + + initialized_ = false; + return DEVICE_OK; + } + + + double AndorCamera::GetExposure() const + { + char Buf[MM::MaxStrLength]; + Buf[0] = '\0'; + GetProperty(MM::g_Keyword_Exposure, Buf); + return atof(Buf); + } + + void AndorCamera::SetExposure(double dExp) + { + SetProperty(MM::g_Keyword_Exposure, CDeviceUtils::ConvertToString(dExp)); + } + + + void AndorCamera::LogStatus() + { + int status; + char statStr[20]; + GetStatus(&status); + sprintf(statStr,"%d",status); + LogMessage(statStr,false); + } + + + int AndorCamera::PrepareSnap() + { + DriverGuard dg(this); + + int ret; + if (initialized_ && !sequenceRunning_ && !sequencePaused_) { + LogMessage("PrepareSnap();",false); + if(iCurrentTriggerMode_ == SOFTWARE) + ret = SetFrameTransferMode(0); //Software trigger mode can not be used in FT mode + + if(!IsAcquiring()) + { + SetIsolatedCropMode(0, currentCropHeight_, currentCropWidth_, 1, 1); + SetImage(binSize_, binSize_, roi_.x+1, roi_.x+roi_.xSize, roi_.y+1, roi_.y+roi_.ySize); + GetReadoutTime(); + if (iCurrentTriggerMode_ == SOFTWARE || iCurrentTriggerMode_ == EXTERNAL) + { + ret = StartAcquisition(); + CATCH(ret) + } + else // iCurrentTriggerMode_ == INTERNAL + { + PrepareAcquisition(); + } + } + } + return DEVICE_OK; + } + + + //added to use RTA + /** + * Acquires a single frame. + * Micro-Manager expects that this function blocks the calling thread until the exposure phase is over. + * This wait is implemented by sleeping ActualInterval_ms_ - ReadoutTime_ + 0.99 ms. + * Note that this is likely not long enough when using internal triggering. + */ + int AndorCamera::SnapImage() + { + { // scope for driver guard + DriverGuard dg(this); + + if (sequenceRunning_) // If we are in the middle of a SequenceAcquisition + return ERR_BUSY_ACQUIRING; + + if(iCurrentTriggerMode_ == SOFTWARE) + { + /* int ret = */ PrepareSnap(); + SendSoftwareTrigger(); + } + else if (iCurrentTriggerMode_ == INTERNAL) + { + AbortAcquisition(); + int status = DRV_ACQUIRING; + int error = DRV_SUCCESS; + while (error == DRV_SUCCESS && status == DRV_ACQUIRING) { + error = GetStatus(&status); + } + SetIsolatedCropMode(0, currentCropHeight_, currentCropWidth_, 1, 1); + SetImage(binSize_, binSize_, roi_.x+1, roi_.x+roi_.xSize, roi_.y+1, roi_.y+roi_.ySize); + StartAcquisition(); + } + } + + CDeviceUtils::SleepMs((long) (ActualInterval_ms_ - ReadoutTime_ + 0.99)); + + return DEVICE_OK; + } + + + const unsigned char* AndorCamera::GetImageBuffer() + { + DriverGuard dg(this); + + if (IsAcquiring() ) + { + int ret = WaitForAcquisitionByHandleTimeOut(myCameraID_, imageTimeOut_ms_); + if (ret != DRV_SUCCESS) + return 0; + } + + pImgBuffer_ = GetAcquiredImage(); + assert(img_.Depth() == 2); + assert(pImgBuffer_!=0); + unsigned char* rawBuffer = pImgBuffer_; + + PrepareSnap(); + return (unsigned char*)rawBuffer; + } + + + unsigned char* AndorCamera::GetAcquiredImage() { + assert(fullFrameBuffer_ != 0); + int array_Length = roi_.xSize/binSize_ * roi_.ySize/binSize_; + + unsigned int ret = GetMostRecentImage16((WORD*)fullFrameBuffer_, array_Length); + if(ret != DRV_SUCCESS) { + std::ostringstream os; + os << "Andor driver reports error #: " << ret; + LogMessage(os.str().c_str(), false); + return 0; + } + + return (unsigned char*)fullFrameBuffer_; + } + + + /** + * Readout time + */ + long AndorCamera::GetReadoutTime() + { + + at_32 ReadoutTime; + float fReadoutTime; + if(fpGetReadOutTime!=0 && (iCurrentTriggerMode_ == SOFTWARE)) + { + fpGetReadOutTime(&fReadoutTime); + ReadoutTime = long(fReadoutTime * 1000); + } + else + { + unsigned ret = SetExposureTime(0.0); + if (DRV_SUCCESS != ret) + return (int)ret; + float fExposure, fAccumTime, fKineticTime; + GetAcquisitionTimings(&fExposure,&fAccumTime,&fKineticTime); + ReadoutTime = long(fKineticTime * 1000.0); + ret = SetExposureTime((float)(expMs_ / 1000.0)); + if (DRV_SUCCESS != ret) + return (int)ret; + } + if(ReadoutTime<=0) + ReadoutTime=35; + ReadoutTime_ = ReadoutTime; + + float fExposure, fAccumTime, fKineticTime; + GetAcquisitionTimings(&fExposure,&fAccumTime,&fKineticTime); + ActualInterval_ms_ = fKineticTime * 1000.0f; + SetProperty(MM::g_Keyword_ActualInterval_ms, CDeviceUtils::ConvertToString(ActualInterval_ms_)); + + //whenever readout needs update, keepcleantime also needs update + at_32 KeepCleanTime; + float fKeepCleanTime; + if(fpGetKeepCleanTime!=0 && (iCurrentTriggerMode_ == SOFTWARE)) + { + fpGetKeepCleanTime(&fKeepCleanTime); + KeepCleanTime = long(fKeepCleanTime * 1000); + } + else + KeepCleanTime=10; + if(KeepCleanTime<=0) + KeepCleanTime=10; + KeepCleanTime_ = KeepCleanTime; + + + return ReadoutTime_; + } + + + /** + * Sets the image Region of Interest (ROI). + * The internal representation of the ROI uses the full frame coordinates + * in combination with binning factor. + */ + int AndorCamera::SetROI(unsigned uX, unsigned uY, unsigned uXSize, unsigned uYSize) + { + DriverGuard dg(this); + + if (Busy()) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + ROI oldRoi = roi_; + + roi_.x = uX * binSize_; + roi_.y = uY * binSize_; + roi_.xSize = uXSize * binSize_; + roi_.ySize = uYSize * binSize_; + + if (roi_.x + roi_.xSize > fullFrameX_ || roi_.y + roi_.ySize > fullFrameY_) + { + roi_ = oldRoi; + return ERR_INVALID_ROI; + } + + // adjust image extent to conform to the bin size + roi_.xSize -= roi_.xSize % binSize_; + roi_.ySize -= roi_.ySize % binSize_; + + unsigned uret = SetImage(binSize_, binSize_, roi_.x+1, roi_.x+roi_.xSize, + roi_.y+1, roi_.y+roi_.ySize); + if (uret != DRV_SUCCESS) + { + roi_ = oldRoi; + return uret; + } + + GetReadoutTime(); + + int ret = ResizeImageBuffer(); + if (ret != DEVICE_OK) + { + roi_ = oldRoi; + return ret; + } + + PrepareSnap(); + + return DEVICE_OK; + } + + unsigned AndorCamera::GetBitDepth() const + { + DriverGuard dg(this); + + int depth; + // TODO: channel 0 hardwired ??? + unsigned ret = ::GetBitDepth(ADChannelIndex_, &depth); + if (ret != DRV_SUCCESS) + depth = 0; + return depth; + } + + int AndorCamera::GetBinning () const + { + return binSize_; + } + + int AndorCamera::SetBinning (int binSize) + { + ostringstream os; + os << binSize; + return SetProperty(MM::g_Keyword_Binning, os.str().c_str()); + } + + int AndorCamera::GetROI(unsigned& uX, unsigned& uY, unsigned& uXSize, unsigned& uYSize) + { + uX = roi_.x / binSize_; + uY = roi_.y / binSize_; + uXSize = roi_.xSize / binSize_; + uYSize = roi_.ySize / binSize_; + + return DEVICE_OK; + } + + int AndorCamera::ClearROI() + { + DriverGuard dg(this); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + roi_.x = 0; + roi_.y = 0; + roi_.xSize = fullFrameX_; + roi_.ySize = fullFrameY_; + + // adjust image extent to conform to the bin size + roi_.xSize -= roi_.xSize % binSize_; + roi_.ySize -= roi_.ySize % binSize_; + unsigned uret = SetImage(binSize_, binSize_, roi_.x+1, roi_.x+roi_.xSize, + roi_.y+1, roi_.y+roi_.ySize); + if (uret != DRV_SUCCESS) + return uret; + + + GetReadoutTime(); + + int ret = ResizeImageBuffer(); + if (ret != DEVICE_OK) + return ret; + + PrepareSnap(); + + return DEVICE_OK; + } + + + /////////////////////////////////////////////////////////////////////////////// + // Action handlers + // ~~~~~~~~~~~~~~~ + + /** + * Set the directory for the Andor native driver dll. + */ + /*int AndorCamera::OnDriverDir(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::BeforeGet) + { + pProp->Set(driverDir_.c_str()); + } + else if (eAct == MM::AfterSet) + { + pProp->Get(driverDir_); + } + return DEVICE_OK; + } + */ + + /** + * Set binning. + */ + int AndorCamera::OnBinning(MM::PropertyBase* pProp, MM::ActionType eAct) + { + DriverGuard dg(this); + if (eAct == MM::AfterSet) + { + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + long bin; + pProp->Get(bin); + if (bin <= 0) + return DEVICE_INVALID_PROPERTY_VALUE; + + // adjust roi to accomodate the new bin size + ROI oldRoi = roi_; + roi_.xSize = fullFrameX_; + roi_.ySize = fullFrameY_; + roi_.x = 0; + roi_.y = 0; + + // adjust image extent to conform to the bin size + roi_.xSize -= roi_.xSize % bin; + roi_.ySize -= roi_.ySize % bin; + + // setting the binning factor will reset the image to full frame + unsigned aret = SetImage(bin, bin, roi_.x+1, roi_.x+roi_.xSize, + roi_.y+1, roi_.y+roi_.ySize); + if (aret != DRV_SUCCESS) + { + roi_ = oldRoi; + return aret; + } + + GetReadoutTime(); + + + // apply new settings + binSize_ = (int)bin; + int ret = ResizeImageBuffer(); + if (ret != DEVICE_OK) + { + roi_ = oldRoi; + return ret; + } + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set((long)binSize_); + } + return DEVICE_OK; + } + + /** + * Set camera exposure (milliseconds). + */ + int AndorCamera::OnExposure(MM::PropertyBase* pProp, MM::ActionType eAct) + { + // exposure property is stored in milliseconds, + // while the driver returns the value in seconds + if (eAct == MM::BeforeGet) + { + DriverGuard dg(this); + pProp->Set(currentExpMS_); + } + else if (eAct == MM::AfterSet) + { + double exp; + pProp->Get(exp); + + if(fabs(exp-currentExpMS_)>0.001) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + { + DriverGuard dg(this); + currentExpMS_ = exp; + + unsigned ret = SetExposureTime((float)(exp / 1000.0)); + if (DRV_SUCCESS != ret) + return (int)ret; + expMs_ = exp; + + UpdateHSSpeeds(); + } + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + } + } + return DEVICE_OK; + } + + + /** + * Set camera pixel type. + * We support only 16-bit mode here. + */ + int AndorCamera::OnPixelType(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::BeforeGet) + pProp->Set(g_PixelType_16bit); + return DEVICE_OK; + } + + /** + * Set readout mode. + */ + int AndorCamera::OnReadoutMode(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string mode; + pProp->Get(mode); + for (unsigned i=0; iSet(readoutModes_[HSSpeedIdx_].c_str()); + } + return DEVICE_OK; + } + + /** + * Provides information on readout time. + * TODO: Not implemented + */ + int AndorCamera::OnReadoutTime(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::BeforeGet) + { + pProp->Set(ReadoutTime_); + } + + return DEVICE_OK; + } + + + /** + * Set camera "regular" gain. + */ + int AndorCamera::OnGain(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + long gain; + pProp->Get(gain); + + { + DriverGuard dg(this); + + if (!EMSwitch_) { + currentGain_ = gain; + return DEVICE_OK; + } + if(gain == currentGain_) + return DEVICE_OK; + } //need to release driver guard to allow AcqSequenceThread to terminate + + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + { + DriverGuard dg(this); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + if (gain!=0 && gain < (long) EmCCDGainLow_ ) + gain = (long)EmCCDGainLow_; + if (gain > (long) EmCCDGainHigh_ ) + gain = (long)EmCCDGainHigh_; + pProp->Set(gain); + + //added to use RTA + if(!(iCurrentTriggerMode_ == SOFTWARE)) + SetToIdle(); + + unsigned ret = SetEMCCDGain((int)gain); + if (DRV_SUCCESS != ret) + return (int)ret; + currentGain_ = gain; + + int retCode = UpdatePreampGains(); + if (DRV_SUCCESS != retCode) + return retCode; + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + + PrepareSnap(); + } + } + else if (eAct == MM::BeforeGet) + { + DriverGuard dg(this); //not even sure this is needed + pProp->Set(currentGain_); + } + return DEVICE_OK; + } + + /** + * Set camera "regular" gain. + */ + int AndorCamera::OnEMSwitch(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + std::string EMSwitch; + { + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + pProp->Get(EMSwitch); + if (EMSwitch == "Off" && !EMSwitch_) + return DEVICE_OK; + if (EMSwitch == "On" && EMSwitch_) + return DEVICE_OK; + } + + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + { + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + if(!(iCurrentTriggerMode_ == SOFTWARE)) + SetToIdle(); + + unsigned ret = DRV_SUCCESS; + if (EMSwitch == "On") { + ret = SetEMCCDGain((int)currentGain_); + // Don't change EMGain property limits here -- causes errors. + EMSwitch_ = true; + } else { + ret = SetEMCCDGain(0); + // Don't change EMGain property limits here -- causes errors. + EMSwitch_ = false; + + } + + //if (initialized_) { + // OnPropertiesChanged(); + //} + + if (DRV_SUCCESS != ret) + return (int)ret; + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + + PrepareSnap(); + } + } + else if (eAct == MM::BeforeGet) + { + if (EMSwitch_) + pProp->Set("On"); + else + pProp->Set("Off"); + } + return DEVICE_OK; + } + + + /** + * Enable or Disable Software Trigger. + */ + int AndorCamera::OnSelectTrigger(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + std::string trigger; + pProp->Get(trigger); + if(trigger == strCurrentTriggerMode_) + return DEVICE_OK; + + SetToIdle(); + + if(trigger == "Software") + { + if (softwareTriggerUsed_) + return ERR_SOFTWARE_TRIGGER_IN_USE; + iCurrentTriggerMode_ = SOFTWARE; + softwareTriggerUsed_ = true; + } + else if(trigger == "External") + { + iCurrentTriggerMode_ = EXTERNAL; + if (strCurrentTriggerMode_ == "Software") + softwareTriggerUsed_ = false; + } + else + { + iCurrentTriggerMode_ = INTERNAL; + if (strCurrentTriggerMode_ == "Software") + softwareTriggerUsed_ = false; + } + + strCurrentTriggerMode_ = trigger; + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + else + { + UpdateSnapTriggerMode(); + PrepareSnap(); + } + + } + else if (eAct == MM::BeforeGet) + { + DriverGuard dg(this); + pProp->Set(strCurrentTriggerMode_.c_str()); + } + return DEVICE_OK; + } + + //Daigang 24-may-2007 + /** + * Set camera pre-amp-gain. + */ + int AndorCamera::OnPreAmpGain(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string PreAmpGain; + pProp->Get(PreAmpGain); + for (unsigned i=0; iSet(PreAmpGain_.c_str()); + } + return DEVICE_OK; + } + //eof Daigang + + /** + * Set camera Vertical Clock Voltage + */ + int AndorCamera::OnVCVoltage(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string VCVoltage; + pProp->Get(VCVoltage); + for (unsigned i=0; iSet(VCVoltage_.c_str()); + } + return DEVICE_OK; + } + + /** + * Set camera Baseline Clamp. + */ + int AndorCamera::OnBaselineClamp(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string BaselineClampValue; + pProp->Get(BaselineClampValue); + for (unsigned i=0; iSet(BaselineClampValue_.c_str()); + } + return DEVICE_OK; + } + + + /** + * Set camera vertical shift speed. + */ + int AndorCamera::OnVSpeed(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string VSpeed; + pProp->Get(VSpeed); + for (unsigned i=0; iSet(VSpeed_.c_str()); + } + return DEVICE_OK; + } + + /** + * Obtain temperature in Celsius. + */ + int AndorCamera::OnTemperature(MM::PropertyBase* pProp, MM::ActionType eAct) + { + DriverGuard dg(this); + if (eAct == MM::AfterSet) + { + + /* //Daigang 23-may-2007 removed for readonly + //jizhen 05.10.2007 + long temp; + pProp->Get(temp); + if (temp < (long) minTemp_ ) temp = (long)minTemp_; + if (temp > (long) maxTemp_ ) temp = (long)maxTemp_; + unsigned ret = SetTemperature((int)temp); + if (DRV_SUCCESS != ret) + return (int)ret; + ret = CoolerON(); + if (DRV_SUCCESS != ret) + return (int)ret; + // eof jizhen + */ + } + else if (eAct == MM::BeforeGet) + { + int temp; + //Daigang 24-may-2007 + //GetTemperature(&temp); + unsigned ret = GetTemperature(&temp); + if(ret == DRV_TEMP_STABILIZED) + ThermoSteady_ = true; + else if(ret == DRV_TEMP_OFF || ret == DRV_TEMP_NOT_REACHED) + ThermoSteady_ = false; + //eof Daigang + + pProp->Set((long)temp); + } + return DEVICE_OK; + } + + //Daigang 23-May-2007 + /** + * Set temperature setpoint in Celsius. + */ + int AndorCamera::OnTemperatureSetPoint(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + long temp; + pProp->Get(temp); + if (temp < (long) minTemp_ ) + temp = (long)minTemp_; + if (temp > (long) maxTemp_ ) + temp = (long)maxTemp_; + unsigned ret = SetTemperature((int)temp); + if (DRV_SUCCESS != ret) + return (int)ret; + ostringstream strTempSetPoint; + strTempSetPoint<Set(TemperatureSetPoint_.c_str()); + } + return DEVICE_OK; + } + + + + //jizhen 05.11.2007 + /** + * Set cooler on/off. + */ + int AndorCamera::OnCooler(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string mode; + pProp->Get(mode); + int modeIdx = 0; + if (mode.compare(g_CoolerMode_FanOffAtShutdown) == 0) + modeIdx = 0; + else if (mode.compare(g_CoolerMode_FanOnAtShutdown) == 0) + modeIdx = 1; + else + return DEVICE_INVALID_PROPERTY_VALUE; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + ret = SetCoolerMode(modeIdx); + CATCH(ret) + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + + } + return DEVICE_OK; + } + // eof jizhen + + //jizhen 05.16.2007 + /** + * Set fan mode. + */ + int AndorCamera::OnFanMode(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string mode; + pProp->Get(mode); + int modeIdx = 0; + if (mode.compare(g_FanMode_Full) == 0) + modeIdx = 0; + else if (mode.compare(g_FanMode_Low) == 0) + modeIdx = 1; + else if (mode.compare(g_FanMode_Off) == 0) + modeIdx = 2; + else + return DEVICE_INVALID_PROPERTY_VALUE; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + ret = SetFanMode(modeIdx); + CATCH(ret) + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + } + return DEVICE_OK; + } + // eof jizhen + + int AndorCamera::OnInternalShutter(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string mode; + pProp->Get(mode); + int modeIdx = 0; + if (mode.compare(g_ShutterMode_Auto) == 0) + modeIdx = 0; + else if (mode.compare(g_ShutterMode_Open) == 0) + modeIdx = 1; + else if (mode.compare(g_ShutterMode_Closed) == 0) + modeIdx = 2; + else + return DEVICE_INVALID_PROPERTY_VALUE; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + // the first parameter in SetShutter, must be "1" in order for + // the shutter logic to work as described in the documentation + ret = SetShutter(1, modeIdx, 20,20);//0, 0); + CATCH(ret) + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + + } + else if (eAct == MM::BeforeGet) + { + } + return DEVICE_OK; + } + + +int AndorCamera::OnSpuriousNoiseFilter(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + string spuriousNoiseFilterStr; + long spuriousNoiseFilter = 0; + pProp->Get(spuriousNoiseFilterStr); + + if(spuriousNoiseFilterStr.compare("None") == 0) + { + spuriousNoiseFilter = 0; + spuriousNoiseFilterDescriptionStr_ = "Recommended Range"; + } + else if(spuriousNoiseFilterStr.compare("Median") == 0) + { + spuriousNoiseFilter = 1; + spuriousNoiseFilterDescriptionStr_ = "Recommended Range 2-10"; + } + else if(spuriousNoiseFilterStr.compare("Level Above") == 0) + { + spuriousNoiseFilter = 2; + spuriousNoiseFilterDescriptionStr_ = "Recommended Range 10-50"; + } + + if(spuriousNoiseFilterStr == spuriousNoiseFilter_) + return DEVICE_OK; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned int ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + ret = Filter_SetMode(spuriousNoiseFilter); + if (ret != DRV_SUCCESS) + { + return DEVICE_CAN_NOT_SET_PROPERTY; + } + + pProp->Set(spuriousNoiseFilterStr.c_str()); + spuriousNoiseFilter_ = spuriousNoiseFilterStr; + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + + SetProperty("SpuriousNoiseFilterDescription", spuriousNoiseFilterDescriptionStr_.c_str()); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(spuriousNoiseFilter_.c_str()); + } + return DEVICE_OK; + } + + int AndorCamera::OnSpuriousNoiseFilterThreshold(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + double spuriousNoiseFilterThreshold = 0; + pProp->Get(spuriousNoiseFilterThreshold); + + if(spuriousNoiseFilterThreshold == spuriousNoiseFilterThreshold_) + return DEVICE_OK; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned int ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + ret = Filter_SetThreshold(static_cast(spuriousNoiseFilterThreshold)); + if (ret != DRV_SUCCESS) + { + return DEVICE_CAN_NOT_SET_PROPERTY; + } + + pProp->Set(spuriousNoiseFilterThreshold); + spuriousNoiseFilterThreshold_ = spuriousNoiseFilterThreshold; + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(spuriousNoiseFilterThreshold_); + } + return DEVICE_OK; + } + + int AndorCamera::OnSpuriousNoiseFilterDescription(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::BeforeGet) + { + pProp->Set(spuriousNoiseFilterDescriptionStr_.c_str()); + } + + return DEVICE_OK; + } + + int AndorCamera::OnCountConvert(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + string countConvertModeStr; + long countConvertMode = 0; + pProp->Get(countConvertModeStr); + + if(countConvertModeStr.compare("Counts") == 0) + { + countConvertMode = 0; + } + else if(countConvertModeStr.compare("Electrons") == 0) + { + countConvertMode = 1; + } + else if(countConvertModeStr.compare("Photons") == 0) + { + countConvertMode = 2; + } + if(countConvertModeStr == countConvertMode_) + return DEVICE_OK; + + //added to use RTA + SetToIdle(); + + unsigned int ret = SetCountConvertMode(countConvertMode); + if (ret != DRV_SUCCESS) + { + return DEVICE_CAN_NOT_SET_PROPERTY; + } + + pProp->Set(countConvertModeStr.c_str()); + countConvertMode_ = countConvertModeStr; + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(countConvertMode_.c_str()); + } + return DEVICE_OK; + } + + int AndorCamera::OnCountConvertWavelength(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + double countConvertWavelength = 0; + pProp->Get(countConvertWavelength); + + if(countConvertWavelength == countConvertWavelength_) + return DEVICE_OK; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned int ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + ret = SetCountConvertWavelength(static_cast(countConvertWavelength)); + if (ret != DRV_SUCCESS) + { + return DEVICE_CAN_NOT_SET_PROPERTY; + } + + pProp->Set(countConvertWavelength); + countConvertWavelength_ = countConvertWavelength; + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(countConvertWavelength_); + } + return DEVICE_OK; + } + + int AndorCamera::OnOADescription(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::BeforeGet) + { + pProp->Set(optAcquireDescriptionStr_.c_str()); + } + + return DEVICE_OK; + } + + int AndorCamera::OnOptAcquireMode(MM::PropertyBase* pProp, MM::ActionType eAct) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + //added to use RTA + SetToIdle(); + + if (eAct == MM::AfterSet) + { + string optAcquireModeStr; + pProp->Get(optAcquireModeStr); + + if(optAcquireModeStr == optAcquireModeStr_) + return DEVICE_OK; + + // wait for camera to finish acquiring + int status = DRV_IDLE; + unsigned int ret = GetStatus(&status); + while (status == DRV_ACQUIRING && ret == DRV_SUCCESS) + ret = GetStatus(&status); + + ret = OA_EnableMode(optAcquireModeStr.c_str()); + if (ret != DRV_SUCCESS) + { + return DEVICE_CAN_NOT_SET_PROPERTY; + } + + pProp->Set(optAcquireModeStr.c_str()); + optAcquireModeStr_ = optAcquireModeStr; + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + PrepareSnap(); + UpdateOAParams(optAcquireModeStr.c_str()); + + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(optAcquireModeStr_.c_str()); + } + + + return DEVICE_OK; + } + + + /////////////////////////////////////////////////////////////////////////////// + // Utility methods + /////////////////////////////////////////////////////////////////////////////// + + int AndorCamera::ResizeImageBuffer() + { + // resize internal buffers + // NOTE: we are assuming 16-bit pixel type + const int bytesPerPixel = 2; + img_.Resize(roi_.xSize / binSize_, roi_.ySize / binSize_, bytesPerPixel); + return DEVICE_OK; + } + + void AndorCamera::UpdateOAParams(const char* OAModeName) + { + unsigned int ui_retVal; + int i_temp; + float f_temp; + char c_temp[256]; + memset(c_temp, '\0', 256); + + ui_retVal = ::OA_GetString(OAModeName, "mode_description", &c_temp[0], 256); + optAcquireDescriptionStr_ = c_temp; + SetProperty("OptAcquireMode Description", c_temp); + ui_retVal = ::OA_GetString(OAModeName, "frame_transfer", &c_temp[0], 256); + if (0 == stricmp(c_temp, "ON")){ + SetProperty("FrameTransfer", "On"); + } + else { + SetProperty("FrameTransfer", "Off"); + } + + ui_retVal = ::OA_GetInt(OAModeName, "electron_multiplying_gain", &i_temp); + sprintf(c_temp, "%d", i_temp); + + SetProperty("Gain",c_temp); + ui_retVal = ::OA_GetInt(OAModeName, "readout_rate", &i_temp); + f_temp = static_cast(i_temp); + + sprintf(c_temp, "%.3f MHz", f_temp); + + //check if Readout rate is valid + int numADChannels; + ui_retVal = GetNumberADChannels(&numADChannels); + + for(int i = 0; i < numADChannels; ++i) { + char * buffer = new char[64]; + int depth; + ::GetBitDepth(i, &depth); + sprintf(buffer, "%d. %dbit",(i+1), depth); + + char speedBuf[100]; + int numSpeeds; + unsigned ret = GetNumberHSSpeeds(i, OutputAmplifierIndex_, &numSpeeds); + for (int j=0; jSet((long)EmCCDGainHigh_); + } + return DEVICE_OK; + } + + + /** + * ActualInterval_ms + */ + int AndorCamera::OnActualIntervalMS(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + double ActualInvertal_ms; + pProp->Get(ActualInvertal_ms); + if(ActualInvertal_ms == ActualInterval_ms_) + return DEVICE_OK; + pProp->Set(ActualInvertal_ms); + ActualInterval_ms_ = (float)ActualInvertal_ms; + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(CDeviceUtils::ConvertToString(ActualInterval_ms_)); + } + return DEVICE_OK; + } + + + /** + * EMGain Range Max + */ + int AndorCamera::OnEMGainRangeMin(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + } + else if (eAct == MM::BeforeGet) + { + pProp->Set((long)EmCCDGainLow_); + } + return DEVICE_OK; + } + + + int AndorCamera::OnTimeOut(MM::PropertyBase* pProp, MM::ActionType eAct) + { + if (eAct == MM::AfterSet) + { + long imageTimeOut_ms; + pProp->Get(imageTimeOut_ms); + if(imageTimeOut_ms == imageTimeOut_ms_) + return DEVICE_OK; + pProp->Set(imageTimeOut_ms); + imageTimeOut_ms_ = imageTimeOut_ms; + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(CDeviceUtils::ConvertToString(imageTimeOut_ms_)); + } + return DEVICE_OK; + } + + + /** + * Frame transfer mode ON or OFF. + */ + int AndorCamera::OnFrameTransfer(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) { + StopSequenceAcquisition(true); + } + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) { + return ERR_BUSY_ACQUIRING; + } + + bool bOldFTMode = bFrameTransfer_; + string mode; + pProp->Get(mode); + int modeIdx = 0; + if (mode.compare(g_FrameTransferOn) == 0) + { + modeIdx = 1; + bFrameTransfer_ = true; + } + else if (mode.compare(g_FrameTransferOff) == 0) + { + modeIdx = 0; + bFrameTransfer_ = false; + } + else { + return DEVICE_INVALID_PROPERTY_VALUE; + } + + if (bFrameTransfer_ == false){ + SetProperty(g_cropMode, "Off"); + } + + // wait for camera to finish acquiring + SetToIdle(); + + if(bOldFTMode != bFrameTransfer_) { + + unsigned int ret = SetFrameTransferMode(modeIdx); + CATCH(ret) + int noAmps; + ret = ::GetNumberAmp(&noAmps); + CATCH(ret) + + ::PrepareAcquisition(); + if(HasProperty(g_OutputAmplifier)) { + bool changeAmp(false); + if(ui_swVersion > 283) { + std::map::iterator iter, iterLast; + iterLast = mapAmps.end(); + vAvailAmps.clear(); + for(iter = mapAmps.begin(); iter != iterLast; ++iter) { + unsigned int status = IsAmplifierAvailable(iter->second); + if(status == DRV_SUCCESS) { + vAvailAmps.push_back(iter->first); + } + else { + if(OutputAmplifierIndex_ == iter->second) { + changeAmp = true; + } + } + } + } + SetAllowedValues(g_OutputAmplifier, vAvailAmps); + UpdateProperty(g_OutputAmplifier); + + if (initialized_) { + OnPropertiesChanged(); + } + + if(changeAmp) { + if(vAvailAmps.size() > 0) { + OutputAmplifierIndex_ = mapAmps[vAvailAmps[0]]; + int nRet = SetProperty(g_OutputAmplifier, vAvailAmps[0].c_str()); + assert(nRet == DEVICE_OK); + if (nRet != DEVICE_OK) { + return nRet; + } + } + else { + return ERR_NO_AVAIL_AMPS; + } + } + UpdateHSSpeeds(); + ret = UpdatePreampGains(); + if(DRV_SUCCESS!=ret) + return ret; + } + + if (acquiring) + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + + } + + + + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + // use cached value + } + return DEVICE_OK; + } + + + + /** + * Set caemra to idle + */ + void AndorCamera::SetToIdle() + { + if(!initialized_ || !IsAcquiring()) + return; + unsigned ret = AbortAcquisition(); + if (ret != DRV_SUCCESS) + CheckError(ret); + + int status = DRV_ACQUIRING; + int error = DRV_SUCCESS; + while (error == DRV_SUCCESS && status == DRV_ACQUIRING) { + error = GetStatus(&status); + } + } + + + /** + * check if camera is acquiring + */ + bool AndorCamera::IsAcquiring() + { + DriverGuard dg(this); + if(!initialized_) + return 0; + + int status = DRV_IDLE; + GetStatus(&status); + if (status == DRV_ACQUIRING) + return true; + else + return false; + + } + + + + /** + * check if camera is thermosteady + */ + bool AndorCamera::IsThermoSteady() + { + return ThermoSteady_; + } + + void AndorCamera::CheckError(unsigned int /*errorVal*/) + { + } + + /** + * Set output amplifier. + */ + int AndorCamera::OnOutputAmplifier(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + SetToIdle(); + + string strAmp; + pProp->Get(strAmp); + if(strAmp.compare(strCurrentAmp) != 0 ) { + strCurrentAmp = strAmp; + OutputAmplifierIndex_ = mapAmps[strAmp]; + + + unsigned ret = SetOutputAmplifier(OutputAmplifierIndex_); + CATCH(ret) + + UpdateHSSpeeds(); + int retCode = UpdatePreampGains(); + if(DRV_SUCCESS!=retCode) + return retCode; + + if (initialized_) { + OnPropertiesChanged(); + } + + if (acquiring) { + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + } + PrepareSnap(); + return DEVICE_OK; + + } + } + else if (eAct == MM::BeforeGet) + { + } + return DEVICE_OK; + } + + + + /** + * Set output amplifier. + */ + int AndorCamera::OnADChannel(MM::PropertyBase* pProp, MM::ActionType eAct) + { + DriverGuard dg(this); + if (eAct == MM::AfterSet) + { + bool acquiring = sequenceRunning_; + if (acquiring) { + StopSequenceAcquisition(true); + } + if (sequenceRunning_) { + return ERR_BUSY_ACQUIRING; + } + + SetToIdle(); + + string strADChannel; + pProp->Get(strADChannel); + int ADChannelIdx = 0; + if(strCurrentChannel.compare(strADChannel) != 0) { + if (strADChannel.compare(vChannels[0]) == 0) { + ADChannelIdx = 0; + } + else if (strADChannel.compare(vChannels[1]) == 0) { + ADChannelIdx = 1; + } + else { + return DEVICE_INVALID_PROPERTY_VALUE; + } + + ADChannelIndex_ = ADChannelIdx; + + unsigned int ret = SetADChannel(ADChannelIdx); + CATCH(ret) + + if(HasProperty(g_OutputAmplifier)) + { + bool changeAmp(false); + if(ui_swVersion > 283) { + std::map::iterator iter, iterLast; + iterLast = mapAmps.end(); + vAvailAmps.clear(); + for(iter = mapAmps.begin(); iter != iterLast; ++iter) { + unsigned int status = IsAmplifierAvailable(iter->second); + if(status == DRV_SUCCESS) { + vAvailAmps.push_back(iter->first); + } + else { + if(OutputAmplifierIndex_ == iter->second) { + changeAmp = true; + } + } + } + } + int nRet = SetAllowedValues(g_OutputAmplifier, vAvailAmps); + if (nRet != DEVICE_OK) { + return nRet; + } + + if(changeAmp) { + if(vAvailAmps.size() > 0) { + OutputAmplifierIndex_ = mapAmps[vAvailAmps[0]]; + int nRet = SetProperty(g_OutputAmplifier, vAvailAmps[0].c_str()); + assert(nRet == DEVICE_OK); + if (nRet != DEVICE_OK) { + return nRet; + } + } + else { + return ERR_NO_AVAIL_AMPS; + } + } + UpdateHSSpeeds(); + + + } + ret = UpdatePreampGains(); + if(DRV_SUCCESS != ret) + return ret; + + if (initialized_) { + OnPropertiesChanged(); + } + + if (acquiring) { + StartSequenceAcquisition(sequenceLength_ - imageCounter_, intervalMs_, stopOnOverflow_); + } + PrepareSnap(); + return DEVICE_OK; + + } + } + else if (eAct == MM::BeforeGet) { + } + return DEVICE_OK; + } + + + void AndorCamera::UpdateHSSpeeds() + { + int numSpeeds; + unsigned ret = GetNumberHSSpeeds(ADChannelIndex_, OutputAmplifierIndex_, &numSpeeds); + if (ret != DRV_SUCCESS) + return; + + char speedBuf[100]; + readoutModes_.clear(); + for (int i=0; i= (int)readoutModes_.size()) + { + HSSpeedIdx_ = 0; + } + ret = SetHSSpeed(OutputAmplifierIndex_, HSSpeedIdx_); + if (ret == DRV_SUCCESS) + SetProperty(MM::g_Keyword_ReadoutMode,readoutModes_[HSSpeedIdx_].c_str()); + + GetReadoutTime(); + + } + + /* + Updates the PreAmpGains List with the allowed preamp gains for the current settings, + if an invalid PAG is selected a valid preamp gain is selected. + */ + int AndorCamera::UpdatePreampGains() + { + if(HasProperty("Pre-Amp-Gain")) + { + int channel = ADChannelIndex_; + int amplifier = OutputAmplifierIndex_; + int channelSpeedIndex = HSSpeedIdx_; + int ret; + int numPreAmpGain; + + ret = GetNumberPreAmpGains(&numPreAmpGain); + if (ret != DRV_SUCCESS) + return ret; + + if (numPreAmpGain > 0 ) + { + //check current PAG is valid, otherwise select first valid one for this mode + for (int i=0; i= 292) + { + ret = GetPreAmpGainText(i, PreAmpGainBuf, sizeof(PreAmpGainBuf)); + } + else + { + float pag; + ret = GetPreAmpGain(i, &pag); + sprintf(PreAmpGainBuf, "%.2f", pag); + } + CATCH(ret) + + PreAmpGains_.push_back(PreAmpGainBuf); + } + } + SetAllowedValues("Pre-Amp-Gain", PreAmpGains_); + + if (PreAmpGains_.empty()) + return ERR_INVALID_PREAMPGAIN; + + } + } + return DRV_SUCCESS; + } + + + + + + /////////////////////////////////////////////////////////////////////////////// + // Continuous acquisition + // + + /** + * Continuous acquisition thread service routine. + * Starts acquisition on the AndorCamera and repeatedly calls PushImage() + * to transfer any new images to the MMCore circularr buffer. + */ + int AcqSequenceThread::svc(void) + { + at_32 acc; + at_32 series(0); + at_32 seriesInit; + unsigned ret; + + printf("Starting Andor svc\n"); + + long timePrev = GetTickCount(); + long imageWait = 0; + + std::ostringstream os; + + { + DriverGuard dg(camera_); + ret = GetAcquisitionProgress(&acc, &seriesInit); + + os << "GetAcquisitionProgress returned: " << acc << " and: " << seriesInit; + printf ("%s\n", os.str().c_str()); + os.str(""); + + if (ret != DRV_SUCCESS) + { + camera_->StopCameraAcquisition(); + os << "Error in GetAcquisitionProgress: " << ret; + printf("%s\n", os.str().c_str()); + //core_->LogMessage(camera_, os.str().c_str(), true); + return ret; + } + } + + /* + float fExposure, fAccumTime, fKineticTime; + printf ("Before GetAcquisition timings\n"); + ret = GetAcquisitionTimings(&fExposure,&fAccumTime,&fKineticTime); + if (ret != DRV_SUCCESS) + printf ("Error in GetAcquisition Timings\n"); + os << "Exposure: " << fExposure << " AcummTime: " << fAccumTime << " KineticTime: " << fKineticTime; + printf ("%s\n", os.str().c_str()); + os.str("") + float ActualInterval_ms = fKineticTime * 1000.0f; + waitTime = (long) (ActualInterval_ms / 5); + + os << "WaitTime: " << waitTime; + //core_->LogMessage(camera_, os.str().c_str(), true); + printf("%s\n", os.str().c_str()); + os.str(""); + */ + + // wait for frames to start coming in + do + { + { + DriverGuard dg(camera_); + ret = GetAcquisitionProgress(&acc, &series); + } + if (ret != DRV_SUCCESS) + { + camera_->StopCameraAcquisition(); + os << "Error in GetAcquisitionProgress: " << ret; + printf("%s\n", os.str().c_str()); + os.str(""); + return ret; + } + + CDeviceUtils::SleepMs(waitTime_); + + } while (series == seriesInit && !stop_); + os << "Images appearing"; + printf("%s\n", os.str().c_str()); + os.str(""); + + at_32 seriesPrev = 0; + at_32 frmcnt = 0; + + do + { + { + DriverGuard dg(camera_); + //GetStatus(&status); + ret = GetAcquisitionProgress(&acc, &series); + } + + + if (ret == DRV_SUCCESS) + { + if (series > seriesPrev) + { + // new frame arrived + int retCode = camera_->PushImage(); + if (retCode != DEVICE_OK) + { + os << "PushImage failed with error code " << retCode; + printf("%s\n", os.str().c_str()); + os.str(""); + //camera_->StopSequenceAcquisition(); + //return ret; + } + + // report time elapsed since previous frame + //printf("Frame %d captured at %ld ms!\n", ++frameCounter, GetTickCount() - timePrev); + + + //camera_->LogMessage("Aquire Thread: Aquired Frame!", true); + seriesPrev = series; + frmcnt++; + timePrev = GetTickCount(); + // kdb 7/30/2009 + } else + { + imageWait = GetTickCount() - timePrev; + if (imageWait > imageTimeOut_) { + os << "Time out reached at frame " << frmcnt; + camera_->LogMessage("Time out reached", true); + printf("%s\n", os.str().c_str()); + os.str(""); + camera_->StopCameraAcquisition(); + return 0; + } + } + + CDeviceUtils::SleepMs(waitTime_); + + } + + + } + + while (ret == DRV_SUCCESS && frmcnt < numImages_ && !stop_); + + + + if (ret != DRV_SUCCESS && series != 0) + { + camera_->StopCameraAcquisition(); + + os << "Error: " << ret; + printf("%s\n", os.str().c_str()); + os.str(""); + + return ret; + } + + if (stop_) + { + printf ("Acquisition interrupted by the user!\n"); + return 0; + } + + if ((series-seriesInit) == numImages_) + { + printf("Did not get the intended number of images\n"); + camera_->StopCameraAcquisition(); + return 0; + } + + os << "series: " << series << " seriesInit: " << seriesInit << " numImages: "<< numImages_; + printf("%s\n", os.str().c_str()); + camera_->LogMessage("Aquire Thread: We can get here if we are not fast enough", true); + camera_->StopCameraAcquisition(); + return 3; // we can get here if we are not fast enough. Report? + } + + /** + * Starts continuous acquisition. + */ + int AndorCamera::StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow) + { + DriverGuard dg(this); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + sequencePaused_ = false; + stopOnOverflow_ = stopOnOverflow; + sequenceLength_ = numImages; + intervalMs_ = interval_ms; + + if(IsAcquiring()) + { + SetToIdle(); + } + LogMessage("Setting Trigger Mode", true); + int ret0; + if (iCurrentTriggerMode_ == SOFTWARE) + ret0 = SetTriggerMode(0); //set internal trigger for sequence acquisition. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + + ostringstream os; + os << "Started sequence acquisition: " << numImages << "images at " << interval_ms << " ms" << endl; + LogMessage(os.str().c_str()); + + // prepare the camera + int ret = SetAcquisitionMode(5); // run till abort + CATCH(ret) + LogMessage("Set acquisition mode to 5", true); + + LogMessage("Setting Frame Transfer mode on", true); + if(bFrameTransfer_ && (iCurrentTriggerMode_ == SOFTWARE)) + ret0 = SetFrameTransferMode(1); //FT mode might be turned off in SnapImage when Software trigger mode is used. Resume it here + + + ret = SetReadMode(4); // image mode + CATCH(ret) + LogMessage("Set Read Mode to 4", true); + + // set AD-channel to 14-bit + // ret = SetADChannel(0); + CATCH(ret) + + SetExposureTime((float) (expMs_/1000.0)); + + LogMessage ("Set Exposure time", true); + ret = SetNumberAccumulations(1); + if (ret != DRV_SUCCESS) + { + SetAcquisitionMode(1); + return ret; + } + LogMessage("Set Number of accumulations to 1", true); + + ret = SetKineticCycleTime((float)(interval_ms / 1000.0)); + if (ret != DRV_SUCCESS) + { + SetAcquisitionMode(1); + return ret; + } + LogMessage("Set Kinetic cycle time", true); + + at_32 size; + ret = GetSizeOfCircularBuffer(&size); + if (ret != DRV_SUCCESS) + { + SetAcquisitionMode(1); + return ret; + } + LogMessage("Get Size of circular Buffer", true); + + // re-apply the frame transfer mode setting + char ftMode[MM::MaxStrLength]; + if(HasProperty(m_str_frameTransferProp.c_str())) + { + ret = GetProperty(m_str_frameTransferProp.c_str(), ftMode); + assert(ret == DEVICE_OK); + int modeIdx = 0; + if (strcmp(g_FrameTransferOn, ftMode) == 0) + modeIdx = 1; + else if (strcmp(g_FrameTransferOff, ftMode) == 0) + modeIdx = 0; + else + return DEVICE_INVALID_PROPERTY_VALUE; + os.str(""); + os << "Set Frame transfer mode to " << modeIdx; + LogMessage(os.str().c_str(), true); + + ret = SetFrameTransferMode(modeIdx); + + if (modeIdx == 1 && cropModeSwitch_) { + SetIsolatedCropMode(1, currentCropHeight_, currentCropWidth_, 1, 1); + cropModeSwitch_ = true; + } + } + if (ret != DRV_SUCCESS) + { + SetAcquisitionMode(1); + return ret; + } + + // start thread + imageCounter_ = 0; + + os.str(""); + os << "Setting thread length to " << numImages << " Images"; + LogMessage(os.str().c_str(), true); + seqThread_->SetLength(numImages); + + float fExposure, fAccumTime, fKineticTime; + GetAcquisitionTimings(&fExposure,&fAccumTime,&fKineticTime); + SetProperty(MM::g_Keyword_ActualInterval_ms, CDeviceUtils::ConvertToString((double)fKineticTime * 1000.0)); + ActualInterval_ms_ = fKineticTime * 1000.0f; + os.str(""); + os << "Exposure: " << fExposure << " AcummTime: " << fAccumTime << " KineticTime: " << fKineticTime; + LogMessage(os.str().c_str()); + float ActualInterval_ms = fKineticTime * 1000.0f; + seqThread_->SetWaitTime((at_32) (ActualInterval_ms / 5)); + seqThread_->SetTimeOut(imageTimeOut_ms_); + // prepare the core + ret = GetCoreCallback()->PrepareForAcq(this); + if (ret != DEVICE_OK) + { + SetAcquisitionMode(1); + return ret; + } + LogMessage("Starting acquisition in the camera", true); + startTime_ = GetCurrentMMTime(); + ret = ::StartAcquisition(); + + if (ret != DRV_SUCCESS) + { + std::ostringstream os; + os << "Andor driver returned error value: " << ret; + LogMessage(os.str().c_str(), false); + SetAcquisitionMode(1); + return ret; + } else + { + seqThread_->Start(); + sequenceRunning_ = true; + } + + return DEVICE_OK; + } + + /** + * Stop Seq sequence acquisition + * This is the function for internal use and can/should be called from the thread + */ + int AndorCamera::StopCameraAcquisition() + { + { + + DriverGuard dg(this); + if (!sequenceRunning_) + return DEVICE_OK; + + LogMessage("Stopped sequence acquisition"); + AbortAcquisition(); + int status = DRV_ACQUIRING; + int error = DRV_SUCCESS; + while (error == DRV_SUCCESS && status == DRV_ACQUIRING) { + error = GetStatus(&status); + } + + sequenceRunning_ = false; + + UpdateSnapTriggerMode(); + } + + + MM::Core* cb = GetCoreCallback(); + if (cb) + return cb->AcqFinished(this, 0); + else + return DEVICE_OK; + } + + /** + * Stops Sequence acquisition + * This is for external use only (if called from the sequence acquisition thread, deadlock will ensue! + */ + int AndorCamera::StopSequenceAcquisition() + { + return StopSequenceAcquisition(false); + } + + + int AndorCamera::StopSequenceAcquisition(bool temporary) + { + { + DriverGuard dg(this); + sequencePaused_ = temporary; + StopCameraAcquisition(); + } + + seqThread_->Stop(); + seqThread_->wait(); + + if (!temporary) + PrepareSnap(); + + return DEVICE_OK; + } + + /** + * Waits for new image and inserts it in the circular buffer. + * This method is called by the acquisition thread AcqSequenceThread::svc() + * in an infinite loop. + * + * In case of error or if the sequence is finished StopSequenceAcquisition() + * is called, which will raise the stop_ flag and cause the thread to exit. + */ + int AndorCamera::PushImage() + { + unsigned int width; + unsigned int height; + unsigned int bytesPerPixel; + + { + DriverGuard dg(this); + unsigned ret; + // get the top most image from the driver + if (stopOnOverflow_) + ret = GetOldestImage16((WORD*)fullFrameBuffer_, roi_.xSize/binSize_ * roi_.ySize/binSize_); + else + ret = GetMostRecentImage16((WORD*)fullFrameBuffer_, roi_.xSize/binSize_ * roi_.ySize/binSize_); + CATCH(ret) + + width = GetImageWidth(); + height = GetImageHeight(); + bytesPerPixel = GetImageBytesPerPixel(); + + } + + // process image + // imageprocesssor now called from core + + // create metadata + char label[MM::MaxStrLength]; + this->GetLabel(label); + + + MM::MMTime timestamp = this->GetCurrentMMTime(); + Metadata md; + // Copy the metadata inserted by other processes: + std::vector keys = metadata_.GetKeys(); + for (unsigned int i= 0; i < keys.size(); i++) { + md.put(keys[i], metadata_.GetSingleTag(keys[i].c_str()).GetValue().c_str()); + } + + md.put("Camera", label); + md.put(MM::g_Keyword_Metadata_StartTime, CDeviceUtils::ConvertToString(startTime_.getMsec())); + md.put(MM::g_Keyword_Elapsed_Time_ms, CDeviceUtils::ConvertToString((timestamp - startTime_).getMsec())); + md.put(MM::g_Keyword_Metadata_ImageNumber, CDeviceUtils::ConvertToString(imageCounter_)); + md.put(MM::g_Keyword_Binning, binSize_); + + MetadataSingleTag mstStartTime(MM::g_Keyword_Metadata_StartTime, label, true); + mstStartTime.SetValue(CDeviceUtils::ConvertToString(startTime_.getMsec())); + md.SetTag(mstStartTime); + + MetadataSingleTag mst(MM::g_Keyword_Elapsed_Time_ms, label, true); + mst.SetValue(CDeviceUtils::ConvertToString(timestamp.getMsec())); + md.SetTag(mst); + + MetadataSingleTag mstCount(MM::g_Keyword_Metadata_ImageNumber, label, true); + mstCount.SetValue(CDeviceUtils::ConvertToString(imageCounter_)); + md.SetTag(mstCount); + + MetadataSingleTag mstB(MM::g_Keyword_Binning, label, true); + mstB.SetValue(CDeviceUtils::ConvertToString(binSize_)); + md.SetTag(mstB); + + imageCounter_++; + + // This method inserts new image in the circular buffer (residing in MMCore) + int retCode = GetCoreCallback()->InsertImage(this, (unsigned char*) fullFrameBuffer_, + width, + height, + bytesPerPixel, + md.Serialize().c_str()); + + if (!stopOnOverflow_ && retCode == DEVICE_BUFFER_OVERFLOW) + { + // do not stop on overflow - just reset the buffer + GetCoreCallback()->ClearImageBuffer(this); + return GetCoreCallback()->InsertImage(this, (unsigned char*) fullFrameBuffer_, + GetImageWidth(), + GetImageHeight(), + GetImageBytesPerPixel(), + md.Serialize().c_str()); + } else + return DEVICE_OK; + } + + std::string AndorCamera::getCameraType() { + std::string retVal(""); + AndorCapabilities caps; + { + DriverGuard dg(this); + caps.ulSize = sizeof(AndorCapabilities); + GetCapabilities(&caps); + } + + unsigned long camType = caps.ulCameraType; + switch(camType) { + case(AC_CAMERATYPE_PDA): + retVal = "PDA"; + break; + case(AC_CAMERATYPE_IXON): + retVal = "iXon"; + break; + case(AC_CAMERATYPE_INGAAS): + retVal = "inGaAs"; + break; + case(AC_CAMERATYPE_ICCD): + retVal = "ICCD"; + break; + case(AC_CAMERATYPE_EMCCD): + retVal = "EMICCD"; + break; + case(AC_CAMERATYPE_CCD): + retVal = "CCD"; + break; + case(AC_CAMERATYPE_ISTAR): + retVal = "iStar"; + break; + case(AC_CAMERATYPE_VIDEO): + retVal = "Video"; + break; + case(AC_CAMERATYPE_IDUS): + retVal = "iDus"; + break; + case(AC_CAMERATYPE_NEWTON): + retVal = "Newton"; + break; + case(AC_CAMERATYPE_SURCAM): + retVal = "Surcam"; + break; + case(AC_CAMERATYPE_USBICCD): + retVal = "USB ICCD"; + break; + case(AC_CAMERATYPE_LUCA): + retVal = "Luca"; + break; + case(AC_CAMERATYPE_RESERVED): + retVal = "Reserved"; + break; + case(AC_CAMERATYPE_IKON): + retVal = "iKon"; + break; + case(AC_CAMERATYPE_IVAC): + retVal = "iVac"; + break; + case(17): // Should say AC_CAMERATYPE_CLARA but this only defined in versions > 2.83 [01/04/2009] + retVal = "Clara"; + break; + case(AC_CAMERATYPE_IXONULTRA): + retVal = "iXon Ultra"; + break; + case(AC_CAMERATYPE_UNPROGRAMMED): + retVal = "Unprogrammed"; + break; + default: + retVal = "Unknown"; + break; + } + + return retVal; + } + + unsigned int AndorCamera::createGainProperty(AndorCapabilities * caps) { + DriverGuard dg(this); + unsigned int retVal(DRV_SUCCESS); + bEMGainSupported = ((caps->ulSetFunctions & AC_SETFUNCTION_EMCCDGAIN) == AC_SETFUNCTION_EMCCDGAIN); + + int state = 1; // for setting the em gain advanced state + int mode = 0; // for setting the em gain mode + + if(bEMGainSupported) { + if((caps->ulEMGainCapability&AC_EMGAIN_REAL12) == AC_EMGAIN_REAL12) + { + mode = 3; //Real EM gain + } + else if((caps->ulEMGainCapability&AC_EMGAIN_LINEAR12) == AC_EMGAIN_LINEAR12) + { + mode = 2; //Linear mode + } + else if((caps->ulEMGainCapability&AC_EMGAIN_12BIT) == AC_EMGAIN_12BIT) + { + mode = 1; //The EM Gain is controlled by DAC settings in the range 0-4095 + } + else if((caps->ulEMGainCapability&AC_EMGAIN_8BIT) == AC_EMGAIN_8BIT) + { + state = 0; //Disable access + mode = 0; //The EM Gain is controlled by DAC settings in the range 0-255. Default mode + } + + if((caps->ulSetFunctions&AC_SETFUNCTION_EMADVANCED) == AC_SETFUNCTION_EMADVANCED) { + retVal = SetEMAdvanced(state); + if(retVal != DRV_SUCCESS) { + return retVal; + } + } + retVal = SetEMGainMode(mode); + if(retVal != DRV_SUCCESS) { + return retVal; + } + + int i_gainLow, i_gainHigh; + retVal = GetEMGainRange(&i_gainLow, &i_gainHigh); + if (retVal != DRV_SUCCESS) { + return retVal; + } + + if(!HasProperty(g_EMGainValue)) { + CPropertyAction *pAct = new CPropertyAction(this, &AndorCamera::OnGain); + int nRet = CreateProperty(g_EMGainValue,"0", MM::Integer,false, pAct); + assert(nRet == DEVICE_OK); + nRet = SetPropertyLimits(g_EMGainValue, 0, i_gainHigh); + assert(nRet == DEVICE_OK); + } + } + if(bEMGainSupported) { + CPropertyAction *pAct = new CPropertyAction(this, &AndorCamera::OnEMSwitch); + int nRet = CreateProperty(g_EMGain, "On", MM::String, false, pAct); + if (nRet != DEVICE_OK) { + return nRet; + } + AddAllowedValue(g_EMGain, "On"); + AddAllowedValue(g_EMGain, "Off"); + } + + return retVal; +} + + + /** + * Set camera crop mode on/off. + */ + int AndorCamera::OnCropModeSwitch(MM::PropertyBase* pProp, MM::ActionType eAct) + { + + if (eAct == MM::AfterSet) + { + std::string Switch; + + { + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + pProp->Get(Switch); + if (Switch == "Off" && !cropModeSwitch_) + return DEVICE_OK; + if (Switch == "On" && cropModeSwitch_) + return DEVICE_OK; + } + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + { + DriverGuard dg(this); //moved driver guard to here to allow AcqSequenceThread to terminate properly + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + if (Switch == "On"){ + SetProperty("FrameTransfer", "On"); + } + + //added to use RTA + SetToIdle(); + + unsigned ret = DRV_SUCCESS; + if (Switch == "On") { + SetAcquisitionMode(5); + SetFrameTransferMode(1); + ret = SetIsolatedCropMode(1, currentCropHeight_, currentCropWidth_, 1, 1); + SetAcquisitionMode(1); + fullFrameX_ = currentCropWidth_; + fullFrameY_ = currentCropHeight_; + cropModeSwitch_ = true; + } + else { + fullFrameX_ = tempFrameX_; + fullFrameY_ = tempFrameY_; + ret = SetIsolatedCropMode(0, currentCropHeight_, currentCropWidth_, 1, 1); + cropModeSwitch_ = false; + } + + if (initialized_) { + OnPropertiesChanged(); + } + + if (DRV_SUCCESS != ret) + return (int)ret; + + ROI oldRoi = roi_; + roi_.xSize = fullFrameX_; + roi_.ySize = fullFrameY_; + roi_.x = 0; + roi_.y = 0; + + // adjust image extent to conform to the bin size + roi_.xSize -= roi_.xSize % binSize_; + roi_.ySize -= roi_.ySize % binSize_; + + /* unsigned aret = */ SetImage(binSize_, binSize_, roi_.x+1, roi_.x+roi_.xSize, + roi_.y+1, roi_.y+roi_.ySize); + + GetReadoutTime(); + + ResizeImageBuffer(); + + PrepareSnap(); + } + } + else if (eAct == MM::BeforeGet) + { + if (cropModeSwitch_) + pProp->Set("On"); + else + pProp->Set("Off"); + } + return DEVICE_OK; + } + + + /** + * Set camera crop mode width. + */ + int AndorCamera::OnCropModeWidth(MM::PropertyBase* pProp, MM::ActionType eAct) + { + DriverGuard dg(this); + if (eAct == MM::AfterSet) + { + long cropWidth; + pProp->Get(cropWidth); + if (!cropModeSwitch_) { + currentCropWidth_ = cropWidth; + return DEVICE_OK; + } + if(cropWidth == currentCropWidth_) + return DEVICE_OK; + + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + if (cropWidth < 1 ) + cropWidth = 1; + if (cropWidth > tempFrameX_ ) + cropWidth = tempFrameX_; + pProp->Set(cropWidth); + + //added to use RTA + SetToIdle(); + + unsigned ret = DRV_SUCCESS; + if (cropModeSwitch_) { + SetAcquisitionMode(5); + SetFrameTransferMode(1); + ret = SetIsolatedCropMode(1, currentCropHeight_, cropWidth, 1, 1); + SetAcquisitionMode(1); + fullFrameX_ = cropWidth; + + if (DRV_SUCCESS != ret) + return (int)ret; + + currentCropWidth_ = cropWidth; + } + + if (initialized_) { + OnPropertiesChanged(); + } + + + ROI oldRoi = roi_; + roi_.xSize = fullFrameX_; + roi_.ySize = fullFrameY_; + roi_.x = 0; + roi_.y = 0; + + // adjust image extent to conform to the bin size + roi_.xSize -= roi_.xSize % binSize_; + roi_.ySize -= roi_.ySize % binSize_; + + /* unsigned aret = */ SetImage(binSize_, binSize_, roi_.x+1, roi_.x+roi_.xSize, + roi_.y+1, roi_.y+roi_.ySize); + + GetReadoutTime(); + + ResizeImageBuffer(); + + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(currentCropWidth_); + } + return DEVICE_OK; + } + + /** + * Set camera crop mode height. + */ + int AndorCamera::OnCropModeHeight(MM::PropertyBase* pProp, MM::ActionType eAct) + { + DriverGuard dg(this); + if (eAct == MM::AfterSet) + { + long cropHeight; + pProp->Get(cropHeight); + if (!cropModeSwitch_) { + currentCropHeight_ = cropHeight; + return DEVICE_OK; + } + if(cropHeight == currentCropHeight_) + return DEVICE_OK; + + bool acquiring = sequenceRunning_; + if (acquiring) + StopSequenceAcquisition(true); + + if (sequenceRunning_) + return ERR_BUSY_ACQUIRING; + + if (cropHeight < 1 ) + cropHeight = 1; + if (cropHeight > tempFrameY_ ) + cropHeight = tempFrameY_; + pProp->Set(cropHeight); + + //added to use RTA + SetToIdle(); + + unsigned ret = DRV_SUCCESS; + if (cropModeSwitch_) { + SetAcquisitionMode(5); + SetFrameTransferMode(1); + ret = SetIsolatedCropMode(1, cropHeight, currentCropWidth_, 1, 1); + SetAcquisitionMode(1); + fullFrameY_ = cropHeight; + + if (DRV_SUCCESS != ret) + return (int)ret; + + currentCropHeight_ = cropHeight; + } + + if (initialized_) { + OnPropertiesChanged(); + } + + ROI oldRoi = roi_; + roi_.xSize = fullFrameX_; + roi_.ySize = fullFrameY_; + roi_.x = 0; + roi_.y = 0; + + SetImage(1, 1, roi_.x+1, roi_.x+roi_.xSize, + roi_.y+1, roi_.y+roi_.ySize); + + GetReadoutTime(); + + ResizeImageBuffer(); + + PrepareSnap(); + } + else if (eAct == MM::BeforeGet) + { + pProp->Set(currentCropHeight_); + } + return DEVICE_OK; + } + +unsigned int AndorCamera::createIsolatedCropModeProperty(AndorCapabilities * caps) { + + DriverGuard dg(this); + unsigned int ret(DRV_SUCCESS); + + if((caps->ulSetFunctions&AC_SETFUNCTION_CROPMODE) == AC_SETFUNCTION_CROPMODE) { + CPropertyAction *pAct = new CPropertyAction(this, &AndorCamera::OnCropModeSwitch); + int nRet = CreateProperty(g_cropMode, "Off", MM::String, false, pAct); + if (nRet != DEVICE_OK) { + return nRet; + } + AddAllowedValue(g_cropMode, "On"); + AddAllowedValue(g_cropMode, "Off"); + + if(!HasProperty(g_cropModeWidth)) { + CPropertyAction *pAct = new CPropertyAction(this, &AndorCamera::OnCropModeWidth); + int nRet = CreateProperty(g_cropModeWidth,"64", MM::Integer,false, pAct); + assert(nRet == DEVICE_OK); + nRet = SetPropertyLimits(g_cropModeWidth, 1, tempFrameX_); + assert(nRet == DEVICE_OK); + } + + if(!HasProperty(g_cropModeHeight)) { + CPropertyAction *pAct = new CPropertyAction(this, &AndorCamera::OnCropModeHeight); + int nRet = CreateProperty(g_cropModeHeight,"64", MM::Integer,false, pAct); + assert(nRet == DEVICE_OK); + nRet = SetPropertyLimits(g_cropModeHeight, 1, tempFrameY_); + assert(nRet == DEVICE_OK); + } + } + + return ret; +} + + unsigned int AndorCamera::createTriggerProperty(AndorCapabilities * caps) { + DriverGuard dg(this); + vTriggerModes.clear(); + unsigned int retVal = DRV_SUCCESS; + if(caps->ulTriggerModes & AC_TRIGGERMODE_CONTINUOUS) + { + if(iCurrentTriggerMode_ == SOFTWARE) { + retVal = SetTriggerMode(10); //set software trigger. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + if (retVal != DRV_SUCCESS) + { + ShutDown(); + LogMessage("Could not set trigger mode"); + return retVal; + } + strCurrentTriggerMode_ = "Software"; + } + vTriggerModes.push_back("Software"); + bSoftwareTriggerSupported_ = true; + } + if(caps->ulTriggerModes & AC_TRIGGERMODE_EXTERNAL) { + if(iCurrentTriggerMode_ == EXTERNAL) { + retVal = SetTriggerMode(1); //set software trigger. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + if (retVal != DRV_SUCCESS) + { + ShutDown(); + LogMessage("Could not set external trigger mode"); + return retVal; + } + strCurrentTriggerMode_ = "External"; + } + vTriggerModes.push_back("External"); + } + if(caps->ulTriggerModes & AC_TRIGGERMODE_INTERNAL) { + if(iCurrentTriggerMode_ == INTERNAL) { + retVal = SetTriggerMode(0); //set software trigger. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + if (retVal != DRV_SUCCESS) + { + ShutDown(); + LogMessage("Could not set software trigger mode"); + return retVal; + } + strCurrentTriggerMode_ = "Internal"; + } + vTriggerModes.push_back("Internal"); + } + if(!HasProperty("Trigger")) + { + CPropertyAction *pAct = new CPropertyAction (this, &AndorCamera::OnSelectTrigger); + int nRet = CreateProperty("Trigger", "Trigger Mode", MM::String, false, pAct); + if (nRet != DEVICE_OK) { + return nRet; + } + } + int nRet = SetAllowedValues("Trigger", vTriggerModes); + assert(nRet == DEVICE_OK); + nRet = SetProperty("Trigger", strCurrentTriggerMode_.c_str()); + assert(nRet == DEVICE_OK); + + + return retVal; + } + + + unsigned int AndorCamera::UpdateSnapTriggerMode() + { + DriverGuard dg(this); + int ret; + + if(iCurrentTriggerMode_ == SOFTWARE) + { + ret = SetTriggerMode(10); //set software trigger. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + //if (ret != DRV_SUCCESS) //not check to allow call of AcqFinished + // return ret; + ret = SetAcquisitionMode(5);//set RTA non-iCam camera + //if (ret != DRV_SUCCESS) + // return ret; + } + else if(iCurrentTriggerMode_ == EXTERNAL) + { + ret = SetTriggerMode(1); //set software trigger. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + //if (ret != DRV_SUCCESS) + // return ret; + ret = SetAcquisitionMode(5);//set SingleScan non-iCam camera + //if (ret != DRV_SUCCESS) + // return ret; + } + else + { + ret = SetTriggerMode(0); //set software trigger. mode 0:internal, 1: ext, 6:ext start, 7:bulb, 10:software + //if (ret != DRV_SUCCESS) + // return ret; + ret = SetAcquisitionMode(1);//set SingleScan non-iCam camera + //if (ret != DRV_SUCCESS) + // return ret; + } + return ret; + } + + + + DriverGuard::DriverGuard(const AndorCamera * cam) + { + + g_AndorDriverLock.Lock(); + if (cam != 0 && cam->GetNumberOfWorkableCameras() > 1) + { + // must be defined as 32bit in order to compile on 64bit systems since GetCurrentCamera + // only takes 32bit -kdb + at_32 currentCamera; + GetCurrentCamera(¤tCamera); + if (currentCamera != cam->GetMyCameraID()) + { + int ret = SetCurrentCamera(cam->GetMyCameraID()); + if (ret != DRV_SUCCESS) + { + printf("Error switching active camera"); + } + } + } + } + + DriverGuard::~DriverGuard() + { + g_AndorDriverLock.Unlock(); + } diff --git a/sci-biology/micro-manager/files/Andor.h b/sci-biology/micro-manager/files/Andor.h new file mode 100644 index 0000000..8b4132a --- /dev/null +++ b/sci-biology/micro-manager/files/Andor.h @@ -0,0 +1,394 @@ +/////////////////////////////////////////////////////////////////////////////// +// FILE: Andor.h +// PROJECT: Micro-Manager +// SUBSYSTEM: DeviceAdapters +//----------------------------------------------------------------------------- +// DESCRIPTION: Andor camera module +// +// AUTHOR: Nenad Amodaj, nenad@amodaj.com, 06/30/2006 +// COPYRIGHT: University of California, San Francisco, 2006 +// 100X Imaging Inc, 2008 +// +// LICENSE: This file is distributed under the BSD license. +// License text is included with the source distribution. +// +// This file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES. +// +// REVISIONS: May 21, 2007, Jizhen Zhao, Andor Technologies +// Temerature control and other additional related properties added, +// gain bug fixed, refernce counting fixed for shutter adapter. +// +// May 23 & 24, 2007, Daigang Wen, Andor Technology plc added/modified: +// Cooler is turned on at startup and turned off at shutdown +// Cooler control is changed to cooler mode control +// Pre-Amp-Gain property is added +// Temperature Setpoint property is added +// Temperature is resumed as readonly +// EMGainRangeMax and EMGainRangeMin are added +// +// FUTURE DEVELOPMENT: From September 1 2007, the development of this adaptor is taken over by Andor Technology plc. Daigang Wen (d.wen@andor.com) is the main contact. Changes made by him will not be labeled. +// +// CVS: $Id: Andor.h 10061 2012-10-09 15:38:57Z normanglasgow $ +// +#ifndef _ANDOR_H_ +#define _ANDOR_H_ + +#include "../../MMDevice/DeviceBase.h" +#include "../../MMDevice/MMDevice.h" +#include "../../MMDevice/ImgBuffer.h" +#include "../../MMDevice/DeviceUtils.h" +#include "../../MMDevice/DeviceThreads.h" +#include +#include +#include + +// error codes +#define ERR_BUFFER_ALLOCATION_FAILED 101 +#define ERR_INCOMPLETE_SNAP_IMAGE_CYCLE 102 +#define ERR_INVALID_ROI 103 +#define ERR_INVALID_READOUT_MODE_SETUP 104 +#define ERR_CAMERA_DOES_NOT_EXIST 105 +#define ERR_BUSY_ACQUIRING 106 +#define ERR_INVALID_PREAMPGAIN 107 +#define ERR_INVALID_VSPEED 108 +#define ERR_TRIGGER_NOT_SUPPORTED 109 +#define ERR_OPEN_OR_CLOSE_SHUTTER_IN_ACQUISITION_NOT_ALLOWEDD 110 +#define ERR_NO_AVAIL_AMPS 111 +#define ERR_SOFTWARE_TRIGGER_IN_USE 112 + +class AcqSequenceThread; + +////////////////////////////////////////////////////////////////////////////// +// Implementation of the MMDevice and MMCamera interfaces +// +class AndorCamera : public CCameraBase +{ +public: + friend class AcqSequenceThread; + static AndorCamera* GetInstance(); + + ~AndorCamera(); + + // MMDevice API + int Initialize(); + int Shutdown(); + + void GetName(char* pszName) const; + bool Busy() {return false;} + + // MMCamera API + int SnapImage(); + const unsigned char* GetImageBuffer(); + unsigned GetImageWidth() const {return img_.Width();} + unsigned GetImageHeight() const {return img_.Height();} + unsigned GetImageBytesPerPixel() const {return img_.Depth();} + long GetImageBufferSize() const {return img_.Width() * img_.Height() * GetImageBytesPerPixel();} + unsigned GetBitDepth() const; + int GetBinning() const; + int SetBinning(int binSize); + double GetExposure() const; + void SetExposure(double dExp); + int SetROI(unsigned uX, unsigned uY, unsigned uXSize, unsigned uYSize); + int GetROI(unsigned& uX, unsigned& uY, unsigned& uXSize, unsigned& uYSize); + int ClearROI(); + int IsExposureSequenceable(bool& isSequenceable) const {isSequenceable = false; return DEVICE_OK;} + + // high-speed interface + int PrepareSequenceAcqusition() + { + return DEVICE_OK; + } + int StartSequenceAcquisition(long numImages, double interval_ms, bool stopOnOverflow); + /** + * Continuous sequence acquisition. + * Default to sequence acquisition with a high number of images + */ + int StartSequenceAcquisition(double interval) + { + return StartSequenceAcquisition(LONG_MAX, interval, false); + } + + int StopSequenceAcquisition(); // temporary=true + int StopSequenceAcquisition(bool temporary); + + bool IsCapturing(){return sequenceRunning_;}; + + // action interface for the camera + int OnBinning(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnExposure(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnPixelType(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnGain(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnEMSwitch(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnReadoutMode(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnReadoutTime(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnOffset(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnTemperature(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnDriverDir(MM::PropertyBase* pProp, MM::ActionType eAct); + //int OnShutterMode(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnCooler(MM::PropertyBase* pProp, MM::ActionType eAct);// jizhen 05.11.2007 + int OnFanMode(MM::PropertyBase* pProp, MM::ActionType eAct);// jizhen 05.16.2007 + int OnTemperatureSetPoint(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 23-May-2007 + int OnEMGainRangeMax(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 24-May-2007 + int OnEMGainRangeMin(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 24-May-2007 + int OnPreAmpGain(MM::PropertyBase* pProp, MM::ActionType eAct);// Daigang 24-May-2007 + int OnFrameTransfer(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnVSpeed(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnInternalShutter(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnOutputAmplifier(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnADChannel(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnCamera(MM::PropertyBase* pProp, MM::ActionType eAct);//for multiple camera support + int OnCameraName(MM::PropertyBase* pProp, MM::ActionType eAct); + int OniCamFeatures(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnTemperatureRangeMin(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnTemperatureRangeMax(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnVCVoltage(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnBaselineClamp(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnCropModeSwitch(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnCropModeWidth(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnCropModeHeight(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnActualIntervalMS(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnSelectTrigger(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnTimeOut(MM::PropertyBase* pProp, MM::ActionType eAct); // kdb July-30-2009 + int OnCountConvert(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnCountConvertWavelength(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnSpuriousNoiseFilter(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnSpuriousNoiseFilterThreshold(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnSpuriousNoiseFilterDescription(MM::PropertyBase* pProp, MM::ActionType eAct); + int OnOptAcquireMode(MM::PropertyBase* pProp, MM::ActionType eAct); + void UpdateOAParams(const char* OAModeName); + int OnOADescription(MM::PropertyBase* pProp, MM::ActionType eAct); + + + // custom interface for the thread + int PushImage(); + + //static void ReleaseInstance(AndorCamera * AndorCamera); + + int GetNumberOfWorkableCameras() const { return NumberOfWorkableCameras_; } + int GetMyCameraID() const { return myCameraID_; } + +private: + AndorCamera(); + int ResizeImageBuffer(); + int StopCameraAcquisition(); + void UpdateEMGainRange(); + void CheckError(unsigned int errorVal); + bool IsThermoSteady(); + void SetToIdle(); + bool IsAcquiring(); + + void LogStatus(); + int PrepareSnap(); + unsigned int UpdateSnapTriggerMode(); + + + bool EMSwitch_; + + unsigned int ui_swVersion; + + static AndorCamera* instance_; + static unsigned refCount_; + static bool softwareTriggerUsed_; + ImgBuffer img_; + bool initialized_; + bool snapInProgress_; + bool sequenceRunning_; + long imageCounter_; + MM::MMTime startTime_; + long imageTimeOut_ms_; + long sequenceLength_; + bool stopOnOverflow_; + double intervalMs_; + std::string countConvertMode_; + double countConvertWavelength_; + std::string spuriousNoiseFilter_; + double spuriousNoiseFilterThreshold_; + std::string spuriousNoiseFilterDescriptionStr_; + std::string optAcquireModeStr_; + std::string optAcquireDescriptionStr_; + + long lSnapImageCnt_; + std::vector PreAmpGains_; + long currentGain_; + + bool cropModeSwitch_; + long currentCropWidth_; + long currentCropHeight_; + std::vector VSpeeds_; + + + double currentExpMS_; + + long ReadoutTime_, KeepCleanTime_; + + long GetReadoutTime(); + +// kdb 2/27/2009 +#ifdef WIN32 + HMODULE hAndorDll; + typedef unsigned int (CALLBACK *FPGetReadOutTime)(float *_fReadoutTime); + typedef unsigned int (CALLBACK *FPGetKeepCleanTime)(float *_ftime); +#else + HDEVMODULE hAndorDll; + typedef unsigned int (*FPGetReadOutTime)(float *_fReadoutTime); + typedef unsigned int (*FPGetKeepCleanTime)(float *_ftime); +#endif +// end of kdb + FPGetReadOutTime fpGetReadOutTime; + //typedef unsigned int (CALLBACK *FPGetKeepCleanTime)(float *_ftime); + FPGetKeepCleanTime fpGetKeepCleanTime; + //typedef unsigned int (CALLBACK *FPSendSoftwareTrigger)(); + //FPSendSoftwareTrigger fpSendSoftwareTrigger; + + bool busy_; + + struct ROI { + int x; + int y; + int xSize; + int ySize; + + ROI() : x(0), y(0), xSize(0), ySize(0) {} + ~ROI() {} + + bool isEmpty() {return x==0 && y==0 && xSize==0 && ySize == 0;} + }; + + ROI roi_; + int binSize_; + double expMs_; //value used by camera + std::string driverDir_; + int fullFrameX_; + int fullFrameY_; + int tempFrameX_; + int tempFrameY_; + short* fullFrameBuffer_; + std::vector readoutModes_; + + int EmCCDGainLow_, EmCCDGainHigh_; + int minTemp_, maxTemp_; + //Daigang 24-may-2007 + bool ThermoSteady_; + + AcqSequenceThread* seqThread_; + + bool bShutterIntegrated_; + int ADChannelIndex_, OutputAmplifierIndex_; + void UpdateHSSpeeds(); + int UpdatePreampGains(); + + int HSSpeedIdx_; + + bool bSoftwareTriggerSupported_; + int iCurrentTriggerMode_; + + enum { + INTERNAL, + EXTERNAL, + SOFTWARE + }; + + at_32 myCameraID_; + at_32 NumberOfAvailableCameras_; + at_32 NumberOfWorkableCameras_; + std::vector cameraName_; + std::vector cameraSN_; + std::vector cameraID_; + int GetListOfAvailableCameras(); + std::string CameraName_; + std::string iCamFeatures_; + std::string TemperatureRangeMin_; + std::string TemperatureRangeMax_; + std::string PreAmpGain_; + std::string VSpeed_; + std::string TemperatureSetPoint_; + std::vector VCVoltages_; + std::string VCVoltage_; + std::vector BaselineClampValues_; + std::string BaselineClampValue_; + float ActualInterval_ms_; + + std::string strCurrentTriggerMode_; + std::vector vTriggerModes; + + std::string strCurrentAmp; + std::vector vAvailAmps; + std::map mapAmps; + + std::string strCurrentChannel; + std::vector vChannels; + + bool bFrameTransfer_; + + std::string m_str_frameTransferProp; + std::string m_str_camType; + std::vector vCameraType; + + unsigned char* pImgBuffer_; + unsigned char* GetAcquiredImage(); + std::string getCameraType(); + unsigned int createGainProperty(AndorCapabilities * caps); + unsigned int createTriggerProperty(AndorCapabilities * caps); + unsigned int createIsolatedCropModeProperty(AndorCapabilities * caps); + + bool mb_canUseFan; + bool mb_canSetTemp; + bool bEMGainSupported; + + bool sequencePaused_; + +}; + + +/** + * Acquisition thread + */ +class AcqSequenceThread : public MMDeviceThreadBase +{ +public: + AcqSequenceThread(AndorCamera* pCam) : + intervalMs_(100.0), + numImages_(1), + waitTime_(10), + busy_(false), + stop_(false) + { + camera_ = pCam; + }; + ~AcqSequenceThread() {} + + int svc(void); + + void SetInterval(double intervalMs) {intervalMs_ = intervalMs;} + void SetWaitTime (long waitTime) { waitTime_ = waitTime;} + void SetTimeOut (long imageTimeOut) { imageTimeOut_ = imageTimeOut;} + void SetLength(long images) {numImages_ = images;} + void Stop() {stop_ = true;} + void Start() {stop_ = false; activate();} + +private: + AndorCamera* camera_; + double intervalMs_; + long numImages_; + long waitTime_; + long imageTimeOut_; + bool busy_; + bool stop_; +}; + + +class DriverGuard +{ +public: + DriverGuard(const AndorCamera * cam); + ~DriverGuard(); + +}; + +#endif //_ANDOR_H_ diff --git a/sci-biology/micro-manager/files/andor_camera_detection.patch b/sci-biology/micro-manager/files/andor_camera_detection.patch new file mode 100644 index 0000000..1fa351e --- /dev/null +++ b/sci-biology/micro-manager/files/andor_camera_detection.patch @@ -0,0 +1,20 @@ +--- DeviceAdapters/configure.in.orig 2012-10-12 18:35:21.972213090 -0400 ++++ DeviceAdapters/configure.in 2012-10-12 18:38:07.693141288 -0400 +@@ -131,13 +131,13 @@ + + # Andor cameras on linux + AC_MSG_CHECKING(for Andor cameras) +-AM_CONDITIONAL([BUILD_ANDOR],[test -f "/usr/local/include/atmcdLXd.h"]) +-if test -f "/usr/local/include/atmcdLXd.h" ; then ++AC_SEARCH_LIBS([SaveAsSif], [andor], ANDORFOUND=yes, AC_MSG_RESULT([not found])) ++AM_CONDITIONAL([BUILD_ANDOR], [test x$ANDORFOUND = xyes]) ++if test x$ANDORFOUND = xyes ; then + AC_MSG_RESULT([found]) +-else +- AC_MSG_RESULT([not found]) + fi + ++ + # Andor laser combiner on linux + AC_MSG_CHECKING(for Andor laser combiner) + AM_CONDITIONAL([BUILD_ANDORLASERCOMBINER],[test -f "/usr/local/include/ALC_REV.h"]) diff --git a/sci-biology/micro-manager/files/arduino_detection.patch b/sci-biology/micro-manager/files/arduino_detection.patch new file mode 100644 index 0000000..d1ab35d --- /dev/null +++ b/sci-biology/micro-manager/files/arduino_detection.patch @@ -0,0 +1,11 @@ +--- DeviceAdapters/SerialManager/SerialManager.cpp.orig 2012-12-10 17:58:08.166318377 -0500 ++++ DeviceAdapters/SerialManager/SerialManager.cpp 2012-12-10 18:00:00.672911852 -0500 +@@ -195,7 +195,7 @@ + struct dirent *pent; + if (pdir) { + while (pent = readdir(pdir)) { +- if ( (strstr(pent->d_name, "ttyS") != 0) || (strstr(pent->d_name, "ttyUSB") != 0) ) { ++ if ( (strstr(pent->d_name, "ttyS") != 0) || (strstr(pent->d_name, "ttyUSB") != 0) || (strstr(pent->d_name, "ttyACM") != 0) ) { + std::string p = ("/dev/"); + p.append(pent->d_name); + if (portAccessible(p.c_str())) diff --git a/sci-biology/micro-manager/files/boost_ipc_detail.patch b/sci-biology/micro-manager/files/boost_ipc_detail.patch new file mode 100644 index 0000000..33520bb --- /dev/null +++ b/sci-biology/micro-manager/files/boost_ipc_detail.patch @@ -0,0 +1,24 @@ +--- MMCore/FastLogger.cpp.orig 2012-09-28 21:38:41.510071984 -0400 ++++ MMCore/FastLogger.cpp 2012-09-28 21:41:08.738231368 -0400 +@@ -39,6 +39,12 @@ + #else + #endif + #include "boost/interprocess/detail/os_thread_functions.hpp" ++#include "boost/version.hpp" ++#if BOOST_VERSION >= 104800 ++# define BOOST_IPC_DETAIL boost::interprocess::ipcdetail ++#else ++# define BOOST_IPC_DETAIL boost::interprocess::detail ++#endif + + using namespace std; + const char* g_textLogIniFiled = "Logging initialization failed\n"; +@@ -469,7 +475,7 @@ + } + + // display the process id +- boost::interprocess::detail::OS_process_id_t pidd = boost::interprocess::detail::get_current_process_id(); ++ BOOST_IPC_DETAIL::OS_process_id_t pidd = BOOST_IPC_DETAIL::get_current_process_id(); + + std::ostringstream percentPReplacement; + percentPReplacement << pidd; diff --git a/sci-biology/micro-manager/files/disable_prefs_during_clojure_builds.patch b/sci-biology/micro-manager/files/disable_prefs_during_clojure_builds.patch new file mode 100644 index 0000000..759ece3 --- /dev/null +++ b/sci-biology/micro-manager/files/disable_prefs_during_clojure_builds.patch @@ -0,0 +1,10 @@ +--- a/buildscripts/buildprops.xml 2015-04-29 15:18:04.808204789 -0400 ++++ b/buildscripts/buildprops.xml 2015-04-29 15:17:38.118204302 -0400 +@@ -133,6 +133,7 @@ + + + ++ + + + diff --git a/sci-biology/micro-manager/files/drop_direct_junit_paths.patch b/sci-biology/micro-manager/files/drop_direct_junit_paths.patch new file mode 100644 index 0000000..0e47498 --- /dev/null +++ b/sci-biology/micro-manager/files/drop_direct_junit_paths.patch @@ -0,0 +1,17 @@ +--- buildscripts/buildprops.xml 2015-01-30 14:24:07.000000000 -0500 ++++ buildscripts/buildprops.xml.new 2015-04-28 17:56:34.096801301 -0400 +@@ -17,10 +17,12 @@ + + + ++ ++ + + +- +- ++ ++ + + + diff --git a/sci-biology/micro-manager/files/makefile.am-typo.patch b/sci-biology/micro-manager/files/makefile.am-typo.patch new file mode 100644 index 0000000..40ec3cf --- /dev/null +++ b/sci-biology/micro-manager/files/makefile.am-typo.patch @@ -0,0 +1,11 @@ +--- Makefile.am 2015-04-29 16:49:53.848305346 -0400 ++++ Makefile.am.new 2015-04-29 18:29:52.548414841 -0400 +@@ -123,7 +123,7 @@ + $(MMCOREPY_DIR) \ + $(JAVA_APP_DIRS) \ + DeviceAdapters \ +- $(SYSTEMTEST_DIR) ++ $(SYSTEMTEST_DIR) \ + bindist + + diff --git a/sci-biology/micro-manager/files/mmcorepy_setup_add_zlib.patch b/sci-biology/micro-manager/files/mmcorepy_setup_add_zlib.patch new file mode 100644 index 0000000..3e42350 --- /dev/null +++ b/sci-biology/micro-manager/files/mmcorepy_setup_add_zlib.patch @@ -0,0 +1,10 @@ +--- MMCorePy_wrap/setup.py.orig 2013-07-06 09:51:46.956669810 -0400 ++++ MMCorePy_wrap/setup.py 2013-07-06 09:54:03.096967822 -0400 +@@ -26,6 +26,7 @@ + '../MMCore/MMCore.cpp', + '../MMCore/PluginManager.cpp'], + language = "c++", ++ libraries = ['z'], + extra_objects = [], + include_dirs = ["/Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/numpy/core/include/numpy"] + ) diff --git a/sci-biology/micro-manager/files/secretdevice.patch b/sci-biology/micro-manager/files/secretdevice.patch new file mode 100644 index 0000000..465044e --- /dev/null +++ b/sci-biology/micro-manager/files/secretdevice.patch @@ -0,0 +1,40 @@ +--- a/Makefile.am 2015-01-30 14:24:07.000000000 -0500 ++++ b/Makefile.am 2015-03-27 12:30:07.113123642 -0400 +@@ -22,9 +22,6 @@ + MMCOREPY_DIR = MMCorePy_wrap + endif + +-if BUILD_SECRETDEVICEADAPTERS +-SECRETDEVICEADAPTERS = SecretDeviceAdapters +-endif + + + if BUILD_JAVA_APP +@@ -126,7 +123,6 @@ + $(MMCOREPY_DIR) \ + $(JAVA_APP_DIRS) \ + DeviceAdapters \ +- $(SECRETDEVICEADAPTERS) \ + $(SYSTEMTEST_DIR) + bindist + +--- a/configure.ac 2015-01-30 14:24:07.000000000 -0500 ++++ b/configure.ac 2015-03-27 12:30:19.193123863 -0400 +@@ -370,16 +370,8 @@ + ## Subdirectory configuration + ## + +-AC_MSG_CHECKING([for proprietary device adapter source]) +-AS_IF([test -f "$srcdir/SecretDeviceAdapters/configure"], +- [build_secretdeviceadapters=yes], [build_secretdeviceadapters=no]) +-AM_CONDITIONAL([BUILD_SECRETDEVICEADAPTERS], +- [test "x$build_secretdeviceadapters" = xyes]) +- ++build_secretdeviceadapters=no + AC_CONFIG_SUBDIRS([DeviceAdapters]) +-AS_IF([test "x$build_secretdeviceadapters" = xyes], [ +- AC_CONFIG_SUBDIRS([SecretDeviceAdapters]) +-]) + AC_CONFIG_SUBDIRS([DeviceKit]) + + diff --git a/sci-biology/micro-manager/micro-manager-1.4.10.ebuild b/sci-biology/micro-manager/micro-manager-1.4.10.ebuild new file mode 100755 index 0000000..5aea850 --- /dev/null +++ b/sci-biology/micro-manager/micro-manager-1.4.10.ebuild @@ -0,0 +1,177 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=4 + +inherit eutils subversion autotools java-pkg-opt-2 flag-o-matic java-utils-2 + +DESCRIPTION="The Open Source Microscopy Software" +HOMEPAGE="http://valelab.ucsf.edu/~MM/MMwiki/" +ESVN_REPO_URI="https://valelab.ucsf.edu/svn/micromanager2/trunk" +ESVN_BOOTSTRAP="mmUnixBuild.sh" +ESVN_REVISION=9309 + +SLOT="0" +LICENSE="BSD" +KEYWORDS="~amd64 ~x86" +IUSE="+java clojure_editor ieee1394 andor" + +RDEPEND="java? ( + >=virtual/jre-1.5 + ) + ieee1394? ( media-libs/libdc1394 )" + +DEPEND="dev-lang/swig + dev-libs/boost + java? ( + >=virtual/jdk-1.5 + >=sci-biology/imagej-1.46e[plugins] + dev-java/bsh + dev-java/commons-math:2 + dev-java/swingx:1.6 + dev-java/swing-layout:1 + dev-java/absolutelayout + dev-java/jfreechart:1.0 + dev-lang/clojure + clojure_editor? ( dev-util/clooj ) + sci-libs/TSFProto + ) + andor? ( sci-libs/andor-camera-driver:2 )" + +src_unpack() { + subversion_src_unpack +} + +src_prepare() { + # fix zlib detection + for file in configure.in DeviceKit/configure.in; do + sed -i -e "s/libz.a/libz.so/g" $file + done + + epatch ${FILESDIR}/andor_camera_detection.patch + + subversion_bootstrap + + # ESVN_PATCHES won't apply after bootstrap, so must use epatches + epatch ${FILESDIR}/boost_ipc_detail.patch + + einfo "Patching to prevent imagej removal" + sed -i -e '/rm -rf/d' scripts/Makefile.am + einfo "Patching to prevent imagej collision" + sed -i -e '/cp $(IJJARPATH)/d' mmstudio/Makefile.am + + einfo "Patching Andor camera driver for return code debugging" + sed -i -e '/end of kdb/a \ +\ +// macro for finding the source of unsuccessful return error code\ +#define CATCH(err) if (err != DRV_SUCCESS) { \\\ + LogMessage("Return code %u instead of DRV_SUCCESS at %s/%s:%d\\n", \\\ + err, __FILE__, __FUNCTION__, __LINE__); \\\ + return (int)ret; \\\ +}' DeviceAdapters/Andor/Andor.cpp + sed -i -e + + if use java; then + # making and clearing a single `build' directory prevents + # multiple plugins from being built simultaneously + sed -i -e 's/build/build_$@/g' plugins/Makefile.am + + # TODO Make ebuilds for lwm, gaussian + # Removing plugins requiring these deps until ebuilds made + REMOVE_MM_PLUGINS="DataBrowser Gaussian" + if ! use clojure_editor ; then + REMOVE_MM_PLUGINS="${REMOVE_MM_PLUGINS} ClojureEditor" + fi + for PLUGIN in ${REMOVE_MM_PLUGINS}; do + einfo "Removing ${PLUGIN} plugin" + sed -i -e "/^all:/s/$PLUGIN\.jar//g" \ + -e "/^\tcp $PLUGIN\.jar/d" \ + plugins/Makefile.am + done + + eautoconf + # FIXME eautoreconf should replace eautoconf and + # subversion_bootstrap lines, but dies because + # ./Makefile.am searches for the non-existent + # SecretDeviceAdapters directory + #eautoreconf + fi +} + +src_configure() { + if use java; then + append-cppflags $(java-pkg_get-jni-cflags) + + IMAGEJ_DIR=$(dirname `java-pkg_getjar imagej ij.jar`) \ + + ebegin 'Creating symlinks to .jar dependencies...' + mkdir -p ../3rdpartypublic/classext/ + pushd ../3rdpartypublic/classext/ + java-pkg_jar-from bsh bsh.jar bsh-2.0b4.jar + java-pkg_jar-from swingx-1.6 swingx.jar swingx-0.9.5.jar + java-pkg_jar-from commons-math-2 commons-math.jar commons-math-2.0.jar + java-pkg_jar-from swing-layout-1 swing-layout.jar swing-layout-1.0.4.jar + java-pkg_jar-from absolutelayout absolutelayout.jar AbsoluteLayout.jar + java-pkg_jar-from jfreechart-1.0 jfreechart.jar jfreechart-1.0.13.jar + java-pkg_jar-from jcommon-1.0 jcommon.jar jcommon-1.0.16.jar + java-pkg_jar-from imagej + java-pkg_jar-from clojure-1.4 + if use clojure_editor; then + java-pkg_jar-from clooj clooj-0.3.4-standalone.jar clooj.jar + fi + java-pkg_jar-from protobuf protobuf.jar gproto.jar + java-pkg_jar-from TSFProto + + # TODO: Make these dep ebuilds and symlinks for plugins: + # lwm, gaussian + popd + eend + else + IMAGEJ_DIR='no' + fi + + econf --with-imagej=${IMAGEJ_DIR} +} + +src_compile() { + emake +} + +src_install() { + emake DESTDIR="${D}" install + + if use java; then + # FIXME java-pkg_dolauncher should replace this bash script. + # Problems encountered when attempting this were: + # 1. dolauncher uses the same name for the launcher and + # the package (gjl_package). What we want for this + # package is: + # /usr/bin/micro-manager + # to contain: + # gjl_package=imagej + # 2. Fixing issue #1 above by editing the output file + # creates unusual behavior with Micro-Manager, always + # asking to select a dataset to open on startup. + cat <<-EOF > "${T}"/${PN} + #!/bin/bash + + ( + # MM plugins won't load without changing to this path + cd /usr/share/imagej/lib + + $(java-config --java) \\ + -mx1024m \\ + -cp \$(java-config -p imagej,libreadline-java) \\ + ij.ImageJ -run "Micro-Manager Studio" + ) 2>&1 | tee >(logger -t micro-manager) - + + exit 0 + EOF + + make_desktop_entry "${PN}" "Micro-Manager Studio" imagej \ + "Graphics;Science;Biology" + + dobin "${T}"/${PN} + fi +} diff --git a/sci-biology/micro-manager/micro-manager-1.4.13.ebuild b/sci-biology/micro-manager/micro-manager-1.4.13.ebuild new file mode 100644 index 0000000..40bd068 --- /dev/null +++ b/sci-biology/micro-manager/micro-manager-1.4.13.ebuild @@ -0,0 +1,203 @@ +# Copyright 1999-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 +PYTHON_COMPAT=( python{2_6,2_7,3_1,3_2,3_3} ) +PYTHON_SINGLE_TARGET="python2_7" + +inherit eutils autotools python-single-r1 java-pkg-opt-2 flag-o-matic java-utils-2 linux-info vcs-snapshot + +MY_PN="micromanager-upstream" +MY_P="${MY_PN}-${PV}" + +DESCRIPTION="The Open Source Microscopy Software" +HOMEPAGE="http://www.micro-manager.org/" +SRC_URI="http://github.com/mdcurtis/${MY_PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" + +SLOT="0" +LICENSE="LGPL-2.1 BSD GPL-1 GPL-3" +KEYWORDS="~x86 ~amd64" +IUSE="+java python clojure_editor ieee1394 andor" +RESTRICT="mirror" + +RDEPEND="java? ( + >=virtual/jre-1.5 + ) + ieee1394? ( media-libs/libdc1394 )" + +DEPEND="dev-lang/swig + dev-libs/boost + java? ( + >=virtual/jdk-1.5 + >=sci-biology/imagej-1.46e + dev-java/bsh + dev-java/commons-math:2 + dev-java/swingx:1.6 + dev-java/swing-layout:1 + dev-java/absolutelayout + dev-java/jfreechart:1.0 + dev-lang/clojure + clojure_editor? ( dev-util/clooj ) + sci-libs/TSFProto + sci-libs/bioformats + ) + python? ( + ${PYTHON_DEPS} + dev-python/numpy + ) + andor? ( sci-libs/andor-camera-driver:2 )" + +pkg_setup() { + if linux_config_exists; then + linux_chkconfig_string VIDEO_V4L2 + if ! linux_chkconfig_present VIDEO_V4L2; then + einfo "Enable MEDIA_CAMERA_SUPPORT in kernel to install v4l DeviceAdapter." + fi + else + ewarn "Could not confirm that v4l is compiled in kernel, so video4linux" + ewarn "DeviceAdapter may silently fail to compile." + fi + + use java && java-pkg-opt-2_pkg_setup + use python && python-single-r1_pkg_setup +} + +src_prepare() { + einfo "Patching zlib detection" + for file in configure.in DeviceKit/configure.in; do + sed -i -e "s/libz.a/libz.so/g" $file + done + epatch ${FILESDIR}/mmcorepy_setup_add_zlib.patch + einfo "Patching v4l detection" + sed -i -e "s/libv4l2.h/linux\/videodev2.h/g" DeviceAdapters/configure.in + epatch ${FILESDIR}/andor_camera_detection.patch + epatch ${FILESDIR}/arduino_detection.patch + + ebegin "Bootstrap started. This can take several minutes" + sh mmUnixBuild.sh + eend + + einfo "Patching to prevent imagej collision" + sed -i -e '/cp $(IJJARPATH)/d' mmstudio/Makefile.am + einfo "Patching to prevent scripts removal" + sed -i -e '/rm -rf $(IJPATH)\/scripts.*$/d' scripts/Makefile.am + + if use python; then + einfo "Patching numpy include directory" + local numpy_sitedir + numpy_includedir=$(python_get_sitedir)/numpy/core/include/numpy + sed -i -e "/include_dirs/s~=.*~= \[\"${numpy_includedir}\"\]~" MMCorePy_wrap/setup.py + + einfo "Patching Python bindings to respect DESTDIR" + sed -i -e 's: $(DEVICEADAPTERPATH): $(DESTDIR)\/$(DEVICEADAPTERPATH):' MMCorePy_wrap/Makefile.am + fi + + if use java; then + einfo "Patching to allow parallel compilations of plugins" + # making and clearing a single `build' directory prevents + # multiple plugins from being built simultaneously + sed -i -e 's/build/build_$@/g' plugins/Makefile.am + + # TODO Make ebuilds for lwm, gaussian + # Removing plugins requiring these deps until ebuilds made + REMOVE_MM_PLUGINS="DataBrowser Gaussian" + if ! use clojure_editor ; then + REMOVE_MM_PLUGINS="${REMOVE_MM_PLUGINS} ClojureEditor" + fi + einfo "Removing unsupported Clojure plugins: ${REMOVE_MM_PLUGINS}" + for PLUGIN in ${REMOVE_MM_PLUGINS}; do + einfo "Removing ${PLUGIN} plugin" + sed -i -e "/^all:/s/$PLUGIN\.jar//g" \ + -e "/^\tcp $PLUGIN\.jar/d" \ + plugins/Makefile.am + done + + eautoconf + # FIXME eautoreconf should replace eautoconf and + # subversion_bootstrap lines, but dies because + # ./Makefile.am searches for the non-existent + # SecretDeviceAdapters directory + #eautoreconf + fi +} + +src_configure() { + if use java; then + append-cppflags $(java-pkg_get-jni-cflags) + + IMAGEJ_DIR=$(dirname `java-pkg_getjar imagej ij.jar`) \ + + ebegin 'Creating symlinks to .jar dependencies...' + mkdir -p ../3rdpartypublic/classext/ + pushd ../3rdpartypublic/classext/ + java-pkg_jar-from bsh bsh.jar bsh-2.0b4.jar + java-pkg_jar-from swingx-1.6 swingx.jar swingx-0.9.5.jar + java-pkg_jar-from commons-math-2 commons-math.jar commons-math-2.0.jar + java-pkg_jar-from swing-layout-1 swing-layout.jar swing-layout-1.0.4.jar + java-pkg_jar-from absolutelayout absolutelayout.jar AbsoluteLayout.jar + java-pkg_jar-from jfreechart-1.0 jfreechart.jar jfreechart-1.0.13.jar + java-pkg_jar-from jcommon-1.0 jcommon.jar jcommon-1.0.16.jar + java-pkg_jar-from imagej + java-pkg_jar-from clojure-1.4 + if use clojure_editor; then + java-pkg_jar-from clooj clooj-0.3.4-standalone.jar clooj.jar + fi + java-pkg_jar-from protobuf protobuf.jar gproto.jar + java-pkg_jar-from TSFProto + java-pkg_jar-from bioformats + + # TODO: Make these dep ebuilds and symlinks for plugins: + # lwm, gaussian + popd + eend + else + IMAGEJ_DIR='no' + fi + + econf \ + --with-imagej=${IMAGEJ_DIR} \ + $(use_enable python) +} + +src_compile() { + emake +} + +src_install() { + emake DESTDIR="${D}" install + + if use java; then + # FIXME java-pkg_dolauncher should replace this bash script. + # Problems encountered when attempting this were: + # 1. dolauncher uses the same name for the launcher and + # the package (gjl_package). What we want for this + # package is: + # /usr/bin/micro-manager + # to contain: + # gjl_package=imagej + # 2. Fixing issue #1 above by editing the output file + # creates unusual behavior with Micro-Manager, always + # asking to select a dataset to open on startup. + cat <<-EOF > "${T}"/${PN} + #!/bin/bash + + ( + # MM plugins won't load without changing to this path + cd /usr/share/imagej/lib + + \$(java-config --java) \\ + -mx1024m \\ + -cp \$(java-config -p imagej,libreadline-java) \\ + ij.ImageJ -run "Micro-Manager Studio" + ) 2>&1 | tee >(logger -t micro-manager) - + + exit 0 + EOF + + make_desktop_entry "${PN}" "Micro-Manager Studio" imagej \ + "Graphics;Science;Biology" + + dobin "${T}"/${PN} + fi +} diff --git a/sci-biology/micro-manager/micro-manager-1.4.21-r1.ebuild b/sci-biology/micro-manager/micro-manager-1.4.21-r1.ebuild new file mode 100644 index 0000000..6689b24 --- /dev/null +++ b/sci-biology/micro-manager/micro-manager-1.4.21-r1.ebuild @@ -0,0 +1,189 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 + +PYTHON_COMPAT=( python{2_6,2_7,3_1,3_2,3_3,3_4} ) +DISTUTILS_OPTIONAL=1 +CONFIG_CHECK="VIDEO_V4L2" +JAVA_ANT_DISABLE_ANT_CORE_DEP=1 +inherit autotools java-pkg-opt-2 java-ant-2 distutils-r1 linux-info vcs-snapshot + +MY_PN="micromanager-upstream" + +DESCRIPTION="The Open Source Microscopy Software" +HOMEPAGE="http://www.micro-manager.org/" +if [[ ${PV} == 9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://github.com/mdcurtis/${MY_PN}.git" + SRC_URI="" +else + SRC_URI="http://github.com/mdcurtis/${MY_PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" +fi + +SLOT="0" +LICENSE="GPL-3 BSD LGPL-2.1" +KEYWORDS="~amd64 ~x86" +IUSE_proprietary="andor andorsdk3" +IUSE="+X +java python doc ${IUSE_proprietary}" +REQUIRED_USE="X? ( java ) python? ( ${PYTHON_REQUIRED_USE} )" + +CAMERA_DEPS=" + dev-libs/hidapi + dev-libs/libusb-compat + media-libs/freeimage + media-libs/libdc1394 + media-libs/libgphoto2 + media-libs/opencv +" +PROPRIETARY_DEPS=" + andor? ( sci-libs/andor-camera-driver:2 ) + andorsdk3? ( sci-libs/andor-camera-driver:3 ) +" +COMMON_DEPS=" + ${CAMERA_DEPS} + ${PROPRIETARY_DEPS} + X? ( + dev-java/commons-math:2 + sci-libs/TSFProto:0 + sci-libs/bioformats:0 + dev-java/absolutelayout + dev-java/bsh:0 + dev-java/gson:2.2.2 + dev-java/guava:18 + dev-java/jcommon:1.0 + dev-java/jfreechart:1.0 + dev-java/joda-time:0 + dev-java/miglayout:0 + dev-java/rsyntaxtextarea:0 + dev-java/swing-layout:1 + dev-java/swingx:1.6 + dev-lang/clojure:1.6 + dev-java/clojure-core-cache:0 + dev-java/clojure-core-memoize:0 + dev-java/clojure-data-json:0 + dev-libs/protobuf:0=[java] + >=sci-biology/imagej-1.48:0= + ) + python? ( dev-python/numpy[${PYTHON_USEDEP}] ${PYTHON_DEPS} ) +" +RDEPEND=" + ${COMMON_DEPS} + java? ( >=virtual/jre-1.6 ) +" +DEPEND=" + ${COMMON_DEPS} + dev-libs/boost + doc? ( app-doc/doxygen ) + java? ( + >=virtual/jdk-1.6 + dev-lang/swig + dev-java/ant-core + >=dev-java/ant-contrib-1.0_beta3:0 + dev-java/hamcrest-core:1.3 + >=dev-java/junit-4.11:4 + ) + python? ( dev-lang/swig ) +" + +JAVA_ANT_REWRITE_CLASSPATH=1 +JAVA_ANT_CLASSPATH_TAGS="mm-javac javac xjavac" +EANT_GENTOO_CLASSPATH="bsh,imagej,clojure-1.6,joda-time,bioformats,commons-math-2,gson-2.2.2,guava-18,jcommon-1.0,jfreechart-1.0,miglayout,rsyntaxtextarea,swingx-1.6,TSFProto,protobuf" +ECLJ_GENTOO_CLASSPATH="clojure-core-cache,clojure-core-memoize,clojure-data-json" + +pkg_setup() { + java-pkg-opt-2_pkg_setup + linux-info_pkg_setup +} + +src_prepare() { + epatch "${FILESDIR}"/secretdevice.patch + epatch "${FILESDIR}"/drop_direct_junit_paths.patch + epatch "${FILESDIR}"/disable_prefs_during_clojure_builds.patch + epatch "${FILESDIR}"/makefile.am-typo.patch + + # Disable build of plugins that are impossible to satisfy the dependencies of + local ech + for ech in ClojureEditor ; do + sed -i -e "/${ech}.jar/d" plugins/Makefile.am || die + mv plugins/${ech}/build.xml{,.donotbuild} || die + done + + eautoreconf + + java-pkg-opt-2_src_prepare + use python && distutils-r1_src_prepare +} + +src_configure() { + local conf_opts my_ant_flags=() + + if use X ; then + local ij_jar=$(java-pkg_getjar imagej ij.jar) + local ij_dir=$(dirname ${ij_jar}) + else + conf_opts+=" --disable-java-app" + fi + + if use java ; then + local jdk_home=$(java-config -O) + # ./configure fails when it sees eselect-java's bash scripts. + conf_opts+=" JAVA_HOME=${jdk_home}" + conf_opts+=" JAVA=$(java-config -J)" + conf_opts+=" JAVAC=$(java-config -c)" + conf_opts+=" JAR=$(java-config -j)" + my_ant_flags+=( -Dmm.build.java.lib.ant-contrib=$(java-pkg_getjar --build-only ant-contrib ant-contrib.jar) ) + my_ant_flags+=( -Dmm.build.java.lib.junit=$(java-pkg_getjar --build-only junit-4 junit.jar) ) + my_ant_flags+=( -Dmm.build.java.lib.hamcrest-core=$(java-pkg_getjar --build-only hamcrest-core-1.3 hamcrest-core.jar) ) + my_ant_flags+=( -Dgentoo.classpath=$(java-pkg_getjars ${EANT_GENTOO_CLASSPATH}):$(java-pkg_getjars --with-dependencies ${ECLJ_GENTOO_CLASSPATH}) ) + fi + + if use python ; then + python_setup + local python_home=$(python_get_library_path) + fi + + ANTFLAGS="${my_ant_flags[@]}" \ + CC="$(tc-getCC)" CXX="$(tc-getCXX)" LD="$(tc-getLD)" AR="$(tc-getAR)" RANLIB="$(tc-getRANLIB)" \ + econf \ + $(use_enable X imagej-plugin ${ij_dir}) \ + --disable-install-dependency-jars \ + $(use_with java java ${jdk_home}) \ + $(use_with python python ${python_home}) \ + $(use_with X ij-jar ${ij_jar}) \ + ${conf_opts} + + java-ant-2_src_configure + java-ant_rewrite-classpath buildscripts/javabuild.xml + java-ant_rewrite-classpath autofocus/buildscripts/autofocusbuild.xml + # manually hack gentoo.classpath into the clojure classpath + sed -i -e 's#.*.*#\n&#' \ + buildscripts/clojurebuild.xml || die +} + +src_install() { + emake DESTDIR="${D}" install + + # TODO doc. + # TODO source. + # TODO examples. + use java && java-pkg_regjar /usr/share/imagej/lib/plugins/Micro-Manager/{MMCoreJ,MMJ_,MMAcqEngine}.jar + + if use X; then + java-pkg_dolauncher ${PN}-standalone \ + --main org.micromanager.MMStudio \ + --pwd /usr/share/imagej/lib \ + --java_args '-Xmx1024M -XX:MaxDirectMemorySize=1000G' \ + --pkg_args '-Dmmcorej.library.loading.stderr.log=yes -Dmmcorej.library.path="/usr/share/imagej/lib" -Dorg.micromanager.plugin.path="/usr/share/imagej/lib/mmplugins" -Dorg.micromanager.autofocus.path="/usr/share/imagej/lib/mmautofocus" -Dorg.micromanager.default.config.file="/usr/share/imagej/lib/MMConfig_demo.cfg" -Dorg.micromanager.corelog.dir=/tmp' \ + + java-pkg_dolauncher ${PN} \ + --main ij.ImageJ \ + --pwd /usr/share/imagej/lib \ + --java_args '-Xmx1024M -XX:MaxDirectMemorySize=1000G' \ + --pkg_args '-Dmmcorej.library.loading.stderr.log=yes -Dmmcorej.library.path="/usr/share/imagej/lib" -Dorg.micromanager.plugin.path="/usr/share/imagej/lib/mmplugins" -Dorg.micromanager.autofocus.path="/usr/share/imagej/lib/mmautofocus" -Dorg.micromanager.default.config.file="/usr/share/imagej/lib/MMConfig_demo.cfg" -Dorg.micromanager.corelog.dir=/tmp' \ + + make_desktop_entry "${PN} -eval 'run(\"Micro-Manager Studio\");'" "Micro-Manager Studio" ImageJ \ + "Graphics;Science;Biology" + fi +} diff --git a/sci-biology/micro-manager/micro-manager-1.4.22.ebuild b/sci-biology/micro-manager/micro-manager-1.4.22.ebuild new file mode 100644 index 0000000..4dae6e0 --- /dev/null +++ b/sci-biology/micro-manager/micro-manager-1.4.22.ebuild @@ -0,0 +1,190 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 + +PYTHON_COMPAT=( python{2_6,2_7,3_1,3_2,3_3,3_4} ) +DISTUTILS_OPTIONAL=1 +CONFIG_CHECK="VIDEO_V4L2" +JAVA_ANT_DISABLE_ANT_CORE_DEP=1 +inherit autotools java-pkg-opt-2 java-ant-2 distutils-r1 linux-info vcs-snapshot + +MY_PN="micromanager-upstream" + +DESCRIPTION="The Open Source Microscopy Software" +HOMEPAGE="http://www.micro-manager.org/" +if [[ ${PV} == 9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://github.com/mdcurtis/${MY_PN}.git" + SRC_URI="" +else + SRC_URI="http://github.com/mdcurtis/${MY_PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" +fi + +SLOT="0" +LICENSE="GPL-3 BSD LGPL-2.1" +KEYWORDS="~amd64 ~x86" +IUSE_proprietary="andor andorsdk3" +IUSE="+X +java python doc ${IUSE_proprietary}" +REQUIRED_USE="X? ( java ) python? ( ${PYTHON_REQUIRED_USE} )" + +CAMERA_DEPS=" + dev-libs/hidapi + dev-libs/libusb-compat + media-libs/freeimage + media-libs/libdc1394 + media-libs/libgphoto2 + media-libs/opencv +" +PROPRIETARY_DEPS=" + andor? ( sci-libs/andor-camera-driver:2 ) + andorsdk3? ( sci-libs/andor-camera-driver:3 ) +" +COMMON_DEPS=" + ${CAMERA_DEPS} + ${PROPRIETARY_DEPS} + X? ( + dev-java/commons-math:2 + dev-java/commons-math:3 + sci-libs/TSFProto:0 + sci-libs/bioformats:0 + dev-java/absolutelayout + dev-java/bsh:0 + dev-java/gson:2.2.2 + dev-java/guava:18 + dev-java/jcommon:1.0 + dev-java/jfreechart:1.0 + dev-java/joda-time:0 + dev-java/miglayout:0 + dev-java/rsyntaxtextarea:0 + dev-java/swing-layout:1 + dev-java/swingx:1.6 + dev-lang/clojure:1.6 + dev-java/clojure-core-cache:0 + dev-java/clojure-core-memoize:0 + dev-java/clojure-data-json:0 + dev-libs/protobuf:0=[java] + >=sci-biology/imagej-1.48:0= + ) + python? ( dev-python/numpy[${PYTHON_USEDEP}] ${PYTHON_DEPS} ) +" +RDEPEND=" + ${COMMON_DEPS} + java? ( >=virtual/jre-1.6 ) +" +DEPEND=" + ${COMMON_DEPS} + dev-libs/boost + doc? ( app-doc/doxygen ) + java? ( + >=virtual/jdk-1.6 + dev-lang/swig + dev-java/ant-core + >=dev-java/ant-contrib-1.0_beta3:0 + dev-java/hamcrest-core:1.3 + >=dev-java/junit-4.11:4 + ) + python? ( dev-lang/swig ) +" + +JAVA_ANT_REWRITE_CLASSPATH=1 +JAVA_ANT_CLASSPATH_TAGS="mm-javac javac xjavac" +EANT_GENTOO_CLASSPATH="bsh,imagej,clojure-1.6,joda-time,bioformats,commons-math-2,commons-math-3,gson-2.2.2,guava-17,jcommon-1.0,jfreechart-1.0,miglayout,rsyntaxtextarea,swingx-1.6,TSFProto,protobuf" +ECLJ_GENTOO_CLASSPATH="clojure-core-cache,clojure-core-memoize,clojure-data-json" + +pkg_setup() { + java-pkg-opt-2_pkg_setup + linux-info_pkg_setup +} + +src_prepare() { + epatch "${FILESDIR}"/secretdevice.patch + epatch "${FILESDIR}"/drop_direct_junit_paths.patch + epatch "${FILESDIR}"/disable_prefs_during_clojure_builds.patch + epatch "${FILESDIR}"/makefile.am-typo.patch + + # Disable build of plugins that are impossible to satisfy the dependencies of + local ech + for ech in ClojureEditor ; do + sed -i -e "/${ech}.jar/d" plugins/Makefile.am || die + mv plugins/${ech}/build.xml{,.donotbuild} || die + done + + eautoreconf + + java-pkg-opt-2_src_prepare + use python && distutils-r1_src_prepare +} + +src_configure() { + local conf_opts my_ant_flags=() + + if use X ; then + local ij_jar=$(java-pkg_getjar imagej ij.jar) + local ij_dir=$(dirname ${ij_jar}) + else + conf_opts+=" --disable-java-app" + fi + + if use java ; then + local jdk_home=$(java-config -O) + # ./configure fails when it sees eselect-java's bash scripts. + conf_opts+=" JAVA_HOME=${jdk_home}" + conf_opts+=" JAVA=$(java-config -J)" + conf_opts+=" JAVAC=$(java-config -c)" + conf_opts+=" JAR=$(java-config -j)" + my_ant_flags+=( -Dmm.build.java.lib.ant-contrib=$(java-pkg_getjar --build-only ant-contrib ant-contrib.jar) ) + my_ant_flags+=( -Dmm.build.java.lib.junit=$(java-pkg_getjar --build-only junit-4 junit.jar) ) + my_ant_flags+=( -Dmm.build.java.lib.hamcrest-core=$(java-pkg_getjar --build-only hamcrest-core-1.3 hamcrest-core.jar) ) + my_ant_flags+=( -Dgentoo.classpath=$(java-pkg_getjars ${EANT_GENTOO_CLASSPATH}):$(java-pkg_getjars --with-dependencies ${ECLJ_GENTOO_CLASSPATH}) ) + fi + + if use python ; then + python_setup + local python_home=$(python_get_library_path) + fi + + ANTFLAGS="${my_ant_flags[@]}" \ + CC="$(tc-getCC)" CXX="$(tc-getCXX)" LD="$(tc-getLD)" AR="$(tc-getAR)" RANLIB="$(tc-getRANLIB)" \ + econf \ + $(use_enable X imagej-plugin ${ij_dir}) \ + --disable-install-dependency-jars \ + $(use_with java java ${jdk_home}) \ + $(use_with python python ${python_home}) \ + $(use_with X ij-jar ${ij_jar}) \ + ${conf_opts} + + java-ant-2_src_configure + java-ant_rewrite-classpath buildscripts/javabuild.xml + java-ant_rewrite-classpath autofocus/buildscripts/autofocusbuild.xml + # manually hack gentoo.classpath into the clojure classpath + sed -i -e 's#.*.*#\n&#' \ + buildscripts/clojurebuild.xml || die +} + +src_install() { + emake DESTDIR="${D}" install + + # TODO doc. + # TODO source. + # TODO examples. + use java && java-pkg_regjar /usr/share/imagej/lib/plugins/Micro-Manager/{MMCoreJ,MMJ_,MMAcqEngine}.jar + + if use X; then + java-pkg_dolauncher ${PN}-standalone \ + --main org.micromanager.MMStudio \ + --pwd /usr/share/imagej/lib \ + --java_args '-Xmx1024M -XX:MaxDirectMemorySize=1000G' \ + --pkg_args '-Dmmcorej.library.loading.stderr.log=yes -Dmmcorej.library.path="/usr/share/imagej/lib" -Dorg.micromanager.plugin.path="/usr/share/imagej/lib/mmplugins" -Dorg.micromanager.autofocus.path="/usr/share/imagej/lib/mmautofocus" -Dorg.micromanager.default.config.file="/usr/share/imagej/lib/MMConfig_demo.cfg" -Dorg.micromanager.corelog.dir=/tmp' \ + + java-pkg_dolauncher ${PN} \ + --main ij.ImageJ \ + --pwd /usr/share/imagej/lib \ + --java_args '-Xmx1024M -XX:MaxDirectMemorySize=1000G' \ + --pkg_args '-Dmmcorej.library.loading.stderr.log=yes -Dmmcorej.library.path="/usr/share/imagej/lib" -Dorg.micromanager.plugin.path="/usr/share/imagej/lib/mmplugins" -Dorg.micromanager.autofocus.path="/usr/share/imagej/lib/mmautofocus" -Dorg.micromanager.default.config.file="/usr/share/imagej/lib/MMConfig_demo.cfg" -Dorg.micromanager.corelog.dir=/tmp' \ + + make_desktop_entry "${PN} -eval 'run(\"Micro-Manager Studio\");'" "Micro-Manager Studio" ImageJ \ + "Graphics;Science;Biology" + fi +} diff --git a/sci-biology/micro-manager/micro-manager-9999.ebuild b/sci-biology/micro-manager/micro-manager-9999.ebuild new file mode 100644 index 0000000..5b0c37b --- /dev/null +++ b/sci-biology/micro-manager/micro-manager-9999.ebuild @@ -0,0 +1,190 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=5 + +PYTHON_COMPAT=( python{2_6,2_7,3_1,3_2,3_3,3_4} ) +DISTUTILS_OPTIONAL=1 +CONFIG_CHECK="VIDEO_V4L2" +JAVA_ANT_DISABLE_ANT_CORE_DEP=1 +inherit autotools java-pkg-opt-2 java-ant-2 distutils-r1 linux-info vcs-snapshot + +MY_PN="micromanager-upstream" + +DESCRIPTION="The Open Source Microscopy Software" +HOMEPAGE="http://www.micro-manager.org/" +if [[ ${PV} == 9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://github.com/mdcurtis/${MY_PN}.git" + SRC_URI="" +else + SRC_URI="http://github.com/mdcurtis/${MY_PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" +fi + +SLOT="0" +LICENSE="GPL-3 BSD LGPL-2.1" +KEYWORDS="~amd64 ~x86" +IUSE_proprietary="andor andorsdk3" +IUSE="+X +java python doc ${IUSE_proprietary}" +REQUIRED_USE="X? ( java ) python? ( ${PYTHON_REQUIRED_USE} )" + +CAMERA_DEPS=" + dev-libs/hidapi + dev-libs/libusb-compat + media-libs/freeimage + media-libs/libdc1394 + media-libs/libgphoto2 + media-libs/opencv +" +PROPRIETARY_DEPS=" + andor? ( sci-libs/andor-camera-driver:2 ) + andorsdk3? ( sci-libs/andor-camera-driver:3 ) +" +COMMON_DEPS=" + ${CAMERA_DEPS} + ${PROPRIETARY_DEPS} + X? ( + dev-java/commons-math:2 + dev-java/commons-math:3 + sci-libs/TSFProto:0 + sci-libs/bioformats:0 + dev-java/absolutelayout + dev-java/bsh:0 + dev-java/gson:2.2.2 + dev-java/guava:17 + dev-java/jcommon:1.0 + dev-java/jfreechart:1.0 + dev-java/joda-time:0 + dev-java/miglayout:0 + dev-java/rsyntaxtextarea:0 + dev-java/swing-layout:1 + dev-java/swingx:1.6 + dev-lang/clojure:1.6 + dev-java/clojure-core-cache:0 + dev-java/clojure-core-memoize:0 + dev-java/clojure-data-json:0 + dev-libs/protobuf:0=[java] + >=sci-biology/imagej-1.48:0= + ) + python? ( dev-python/numpy[${PYTHON_USEDEP}] ${PYTHON_DEPS} ) +" +RDEPEND=" + ${COMMON_DEPS} + java? ( >=virtual/jre-1.6 ) +" +DEPEND=" + ${COMMON_DEPS} + dev-libs/boost + doc? ( app-doc/doxygen ) + java? ( + >=virtual/jdk-1.6 + dev-lang/swig + dev-java/ant-core + >=dev-java/ant-contrib-1.0_beta3:0 + dev-java/hamcrest-core:1.3 + >=dev-java/junit-4.11:4 + ) + python? ( dev-lang/swig ) +" + +JAVA_ANT_REWRITE_CLASSPATH=1 +JAVA_ANT_CLASSPATH_TAGS="mm-javac javac xjavac" +EANT_GENTOO_CLASSPATH="bsh,imagej,clojure-1.6,joda-time,bioformats,commons-math-2,commons-math-3,gson-2.2.2,guava-17,jcommon-1.0,jfreechart-1.0,miglayout,rsyntaxtextarea,swingx-1.6,TSFProto,protobuf" +ECLJ_GENTOO_CLASSPATH="clojure-core-cache,clojure-core-memoize,clojure-data-json" + +pkg_setup() { + java-pkg-opt-2_pkg_setup + linux-info_pkg_setup +} + +src_prepare() { + epatch "${FILESDIR}"/secretdevice.patch + epatch "${FILESDIR}"/drop_direct_junit_paths.patch + epatch "${FILESDIR}"/disable_prefs_during_clojure_builds.patch + epatch "${FILESDIR}"/makefile.am-typo.patch + + # Disable build of plugins that are impossible to satisfy the dependencies of + local ech + for ech in ClojureEditor ; do + sed -i -e "/${ech}.jar/d" plugins/Makefile.am || die + mv plugins/${ech}/build.xml{,.donotbuild} || die + done + + eautoreconf + + java-pkg-opt-2_src_prepare + use python && distutils-r1_src_prepare +} + +src_configure() { + local conf_opts my_ant_flags=() + + if use X ; then + local ij_jar=$(java-pkg_getjar imagej ij.jar) + local ij_dir=$(dirname ${ij_jar}) + else + conf_opts+=" --disable-java-app" + fi + + if use java ; then + local jdk_home=$(java-config -O) + # ./configure fails when it sees eselect-java's bash scripts. + conf_opts+=" JAVA_HOME=${jdk_home}" + conf_opts+=" JAVA=$(java-config -J)" + conf_opts+=" JAVAC=$(java-config -c)" + conf_opts+=" JAR=$(java-config -j)" + my_ant_flags+=( -Dmm.build.java.lib.ant-contrib=$(java-pkg_getjar --build-only ant-contrib ant-contrib.jar) ) + my_ant_flags+=( -Dmm.build.java.lib.junit=$(java-pkg_getjar --build-only junit-4 junit.jar) ) + my_ant_flags+=( -Dmm.build.java.lib.hamcrest-core=$(java-pkg_getjar --build-only hamcrest-core-1.3 hamcrest-core.jar) ) + my_ant_flags+=( -Dgentoo.classpath=$(java-pkg_getjars ${EANT_GENTOO_CLASSPATH}):$(java-pkg_getjars --with-dependencies ${ECLJ_GENTOO_CLASSPATH}) ) + fi + + if use python ; then + python_setup + local python_home=$(python_get_library_path) + fi + + ANTFLAGS="${my_ant_flags[@]}" \ + CC="$(tc-getCC)" CXX="$(tc-getCXX)" LD="$(tc-getLD)" AR="$(tc-getAR)" RANLIB="$(tc-getRANLIB)" \ + econf \ + $(use_enable X imagej-plugin ${ij_dir}) \ + --disable-install-dependency-jars \ + $(use_with java java ${jdk_home}) \ + $(use_with python python ${python_home}) \ + $(use_with X ij-jar ${ij_jar}) \ + ${conf_opts} + + java-ant-2_src_configure + java-ant_rewrite-classpath buildscripts/javabuild.xml + java-ant_rewrite-classpath autofocus/buildscripts/autofocusbuild.xml + # manually hack gentoo.classpath into the clojure classpath + sed -i -e 's#.*.*#\n&#' \ + buildscripts/clojurebuild.xml || die +} + +src_install() { + emake DESTDIR="${D}" install + + # TODO doc. + # TODO source. + # TODO examples. + use java && java-pkg_regjar /usr/share/imagej/lib/plugins/Micro-Manager/{MMCoreJ,MMJ_,MMAcqEngine}.jar + + if use X; then + java-pkg_dolauncher ${PN}-standalone \ + --main org.micromanager.MMStudio \ + --pwd /usr/share/imagej/lib \ + --java_args '-Xmx1024M -XX:MaxDirectMemorySize=1000G' \ + --pkg_args '-Dmmcorej.library.loading.stderr.log=yes -Dmmcorej.library.path="/usr/share/imagej/lib" -Dorg.micromanager.plugin.path="/usr/share/imagej/lib/mmplugins" -Dorg.micromanager.autofocus.path="/usr/share/imagej/lib/mmautofocus" -Dorg.micromanager.default.config.file="/usr/share/imagej/lib/MMConfig_demo.cfg" -Dorg.micromanager.corelog.dir=/tmp' \ + + java-pkg_dolauncher ${PN} \ + --main ij.ImageJ \ + --pwd /usr/share/imagej/lib \ + --java_args '-Xmx1024M -XX:MaxDirectMemorySize=1000G' \ + --pkg_args '-Dmmcorej.library.loading.stderr.log=yes -Dmmcorej.library.path="/usr/share/imagej/lib" -Dorg.micromanager.plugin.path="/usr/share/imagej/lib/mmplugins" -Dorg.micromanager.autofocus.path="/usr/share/imagej/lib/mmautofocus" -Dorg.micromanager.default.config.file="/usr/share/imagej/lib/MMConfig_demo.cfg" -Dorg.micromanager.corelog.dir=/tmp' \ + + make_desktop_entry "${PN} -eval 'run(\"Micro-Manager Studio\");'" "Micro-Manager Studio" ImageJ \ + "Graphics;Science;Biology" + fi +}