<commit_before>///////////////////////////////////////////////////////////////////////////////
// FILE:          LeicaDMSTC.cpp
// PROJECT:       Micro-Manager
// SUBSYSTEM:     DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION:   LeicaDMSTC XY stage adapter.
//                                                                                     
// AUTHOR:        <NAME>, 27-Aug-2012
//                Based on LeicaDMR adapter by <NAME>.
//
// COPYRIGHT:     2012, Children's Hospital Los Angeles
// 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.
//

#ifdef WIN32
   //#include <windows.h>
   #define snprintf _snprintf 
#endif

#include "LeicaDMSTC.h"
#include "LeicaDMSTCHub.h"
#include <cstdio>
#include <string>
#include <math.h>
#include "../../MMDevice/ModuleInterface.h"

using namespace std;

// Device strings
const char* g_LeicaDMSTCHub = "Leica DMSTC stage hub";
const char* g_LeicaDMSTCXYDrive = "Leica DMSTC XY stage";

// global hub object, very important!
LeicaDMSTCHub g_hub;

///////////////////////////////////////////////////////////////////////////////
// Exported MMDevice API
///////////////////////////////////////////////////////////////////////////////
MODULE_API void InitializeModuleData()
{
   AddAvailableDeviceName(g_LeicaDMSTCHub,"LeicaDMSTC Controller");
   AddAvailableDeviceName(g_LeicaDMSTCXYDrive, "XY Drive");
}

MODULE_API MM::Device* CreateDevice(const char* deviceName)
{
   if (deviceName == 0)
      return 0;

   if (strcmp(deviceName, g_LeicaDMSTCHub) == 0) {
      return new Hub();
   } else if (strcmp(deviceName, g_LeicaDMSTCXYDrive) == 0 ) {
	   return new XYStage();
   }

   return 0;
}

MODULE_API void DeleteDevice(MM::Device* pDevice)
{
   delete pDevice;
}

///////////////////////////////////////////////////////////////////////////////
// LeicaDMSTC Hub
///////////////////////////////////////////////////////////////////////////////

Hub::Hub() :
   initialized_(false),
   port_("Undefined")
{
   InitializeDefaultErrorMessages();

   // custom error messages
   SetErrorText(ERR_COMMAND_CANNOT_EXECUTE, "Command cannot be executed");
   SetErrorText(ERR_NO_ANSWER, "No answer received.  Is the Leica stage connected to the correct serial port and switched on?");
   SetErrorText(ERR_NOT_CONNECTED, "No answer received.  Is the Leica stage connected to the correct serial port and switched on?");

   // create pre-initialization properties
   // ------------------------------------

   // Port
   CPropertyAction* pAct = new CPropertyAction (this, &Hub::OnPort);
   CreateProperty(MM::g_Keyword_Port, "Undefined", MM::String, false, pAct, true);

}

Hub::~Hub()
{
   Shutdown();
}

void Hub::GetName(char* name) const
{
   CDeviceUtils::CopyLimitedString(name, g_LeicaDMSTCHub);
}

bool Hub::Busy()
{
   return false;
}

int Hub::Initialize()
{
   int ret;
   if (!g_hub.Initialized()) {
      ret = g_hub.Initialize(*this, *GetCoreCallback());
      if (ret != DEVICE_OK)
         return ret;
   }

   // set property list
   // -----------------
   
   // Name
   ret = CreateProperty(MM::g_Keyword_Name, g_LeicaDMSTCHub, MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

   // Description
   ret = CreateProperty(MM::g_Keyword_Description, "LeicaDMSTC controller", MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

   // Version
   std::string version = g_hub.Version();
   ret = CreateProperty("Firmware version", version.c_str(), MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

	ret = UpdateStatus();
   if (ret != DEVICE_OK)
      return ret;

   initialized_ = true;
   
   return DEVICE_OK;
}

int Hub::Shutdown()
{
   if (initialized_) {
      initialized_ = false;
      g_hub.DeInitialize();
   }
   return DEVICE_OK;
}

///////////////////////////////////////////////////////////////////////////////
// Action handlers
///////////////////////////////////////////////////////////////////////////////
/*
 * Sets the Serial Port to be used.
 * Should be called before initialization
 */
int Hub::OnPort(MM::PropertyBase* pProp, MM::ActionType eAct)
{
   if (eAct == MM::BeforeGet)
   {
      pProp->Set(port_.c_str());
   }
   else if (eAct == MM::AfterSet)
   {
      if (initialized_)
      {
         // revert
         pProp->Set(port_.c_str());
         //return ERR_PORT_CHANGE_FORBIDDEN;
      }

      pProp->Get(port_);
      g_hub.SetPort(port_.c_str());
   }
   return DEVICE_OK;
}

///////////////////////////////////////////////////////////////////////////////
// LeicaDMSTC XYStage 
///////////////////////////////////////////////////////////////////////////////
XYStage::XYStage () :
	CXYStageBase<XYStage>(),
	busy_ (false),
	initialized_ (false),
	stepSize_um_(10),	

name_ (g_LeicaDMSTCXYDrive)

{
   InitializeDefaultErrorMessages();
   SetErrorText(ERR_DEVICE_NOT_FOUND, "No XY-Drive found in this microscope");
   SetErrorText(ERR_PORT_NOT_SET, "No serial port found.  Did you include the Leica DMSTC stage and set its serial port property?");
}

XYStage::~XYStage ()
{
   Shutdown();
}

//send two consecutive GetPosition commands to test if stage is moving/busy
bool XYStage::Busy()
{
	long posX1, posX2, posY1, posY2;
	
	int ret;

	ret = GetPositionSteps(posX1, posY1);
	if(ret != DEVICE_OK)
		return true;
	ret = GetPositionSteps(posX2, posY2);
	if(ret != DEVICE_OK)
		return true;

	if((posX1 == posX2) || (posY1 == posY2))
		return false;
	else
		return true;
}

void XYStage::GetName(char* name) const
{
   assert(name_.length() < CDeviceUtils::GetMaxStringLength());
   CDeviceUtils::CopyLimitedString(name, name_.c_str());
}

int XYStage::Initialize()
{
	int ret;
	if (!g_hub.Initialized()) {
		ret = g_hub.Initialize(*this, *GetCoreCallback());
		if (ret != DEVICE_OK)
			return ret;
	}

	//SET_ACK parameter set to 1 to echo non-response commands, for error checking in hub SetCommand() functions
	ret = g_hub.SetAcknowledge(*this, *GetCoreCallback(), 1);
	if (ret != DEVICE_OK)
		return ret;

	//move to origin (top left; x,y = 0,0) to reset position grid 
	ret = g_hub.ResetStage(*this, *GetCoreCallback());
	if (ret != DEVICE_OK)
		return ret;

	while(Busy()){
	}

	//move to bottom right to define x,y limits
	ret = g_hub.InitRange(*this, *GetCoreCallback());
	if (ret != DEVICE_OK)
		return ret;

	while(Busy()){
	}
<commit_msg>Leica DMSTC xy stage adapter no longer travels to both extreme corners of the range of travel, only to one (to define the origin).  <commit_after>///////////////////////////////////////////////////////////////////////////////
// FILE:          LeicaDMSTC.cpp
// PROJECT:       Micro-Manager
// SUBSYSTEM:     DeviceAdapters
//-----------------------------------------------------------------------------
// DESCRIPTION:   LeicaDMSTC XY stage adapter.
//                                                                                     
// AUTHOR:        <NAME>, 27-Aug-2012
//                Based on LeicaDMR adapter by <NAME>.
//				  Update 31-Oct-2012:  commented out lines 266-271
//
// COPYRIGHT:     2012, Children's Hospital Los Angeles
// 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.
//

#ifdef WIN32
   //#include <windows.h>
   #define snprintf _snprintf 
#endif

#include "LeicaDMSTC.h"
#include "LeicaDMSTCHub.h"
#include <cstdio>
#include <string>
#include <math.h>
#include "../../MMDevice/ModuleInterface.h"

using namespace std;

// Device strings
const char* g_LeicaDMSTCHub = "Leica DMSTC stage hub";
const char* g_LeicaDMSTCXYDrive = "Leica DMSTC XY stage";

// global hub object, very important!
LeicaDMSTCHub g_hub;

///////////////////////////////////////////////////////////////////////////////
// Exported MMDevice API
///////////////////////////////////////////////////////////////////////////////
MODULE_API void InitializeModuleData()
{
   AddAvailableDeviceName(g_LeicaDMSTCHub,"LeicaDMSTC Controller");
   AddAvailableDeviceName(g_LeicaDMSTCXYDrive, "XY Drive");
}

MODULE_API MM::Device* CreateDevice(const char* deviceName)
{
   if (deviceName == 0)
      return 0;

   if (strcmp(deviceName, g_LeicaDMSTCHub) == 0) {
      return new Hub();
   } else if (strcmp(deviceName, g_LeicaDMSTCXYDrive) == 0 ) {
	   return new XYStage();
   }

   return 0;
}

MODULE_API void DeleteDevice(MM::Device* pDevice)
{
   delete pDevice;
}

///////////////////////////////////////////////////////////////////////////////
// LeicaDMSTC Hub
///////////////////////////////////////////////////////////////////////////////

Hub::Hub() :
   initialized_(false),
   port_("Undefined")
{
   InitializeDefaultErrorMessages();

   // custom error messages
   SetErrorText(ERR_COMMAND_CANNOT_EXECUTE, "Command cannot be executed");
   SetErrorText(ERR_NO_ANSWER, "No answer received.  Is the Leica stage connected to the correct serial port and switched on?");
   SetErrorText(ERR_NOT_CONNECTED, "No answer received.  Is the Leica stage connected to the correct serial port and switched on?");

   // create pre-initialization properties
   // ------------------------------------

   // Port
   CPropertyAction* pAct = new CPropertyAction (this, &Hub::OnPort);
   CreateProperty(MM::g_Keyword_Port, "Undefined", MM::String, false, pAct, true);

}

Hub::~Hub()
{
   Shutdown();
}

void Hub::GetName(char* name) const
{
   CDeviceUtils::CopyLimitedString(name, g_LeicaDMSTCHub);
}

bool Hub::Busy()
{
   return false;
}

int Hub::Initialize()
{
   int ret;
   if (!g_hub.Initialized()) {
      ret = g_hub.Initialize(*this, *GetCoreCallback());
      if (ret != DEVICE_OK)
         return ret;
   }

   // set property list
   // -----------------
   
   // Name
   ret = CreateProperty(MM::g_Keyword_Name, g_LeicaDMSTCHub, MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

   // Description
   ret = CreateProperty(MM::g_Keyword_Description, "LeicaDMSTC controller", MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

   // Version
   std::string version = g_hub.Version();
   ret = CreateProperty("Firmware version", version.c_str(), MM::String, true);
   if (DEVICE_OK != ret)
      return ret;

	ret = UpdateStatus();
   if (ret != DEVICE_OK)
      return ret;

   initialized_ = true;
   
   return DEVICE_OK;
}

int Hub::Shutdown()
{
   if (initialized_) {
      initialized_ = false;
      g_hub.DeInitialize();
   }
   return DEVICE_OK;
}

///////////////////////////////////////////////////////////////////////////////
// Action handlers
///////////////////////////////////////////////////////////////////////////////
/*
 * Sets the Serial Port to be used.
 * Should be called before initialization
 */
int Hub::OnPort(MM::PropertyBase* pProp, MM::ActionType eAct)
{
   if (eAct == MM::BeforeGet)
   {
      pProp->Set(port_.c_str());
   }
   else if (eAct == MM::AfterSet)
   {
      if (initialized_)
      {
         // revert
         pProp->Set(port_.c_str());
         //return ERR_PORT_CHANGE_FORBIDDEN;
      }

      pProp->Get(port_);
      g_hub.SetPort(port_.c_str());
   }
   return DEVICE_OK;
}

///////////////////////////////////////////////////////////////////////////////
// LeicaDMSTC XYStage 
///////////////////////////////////////////////////////////////////////////////
XYStage::XYStage () :
	CXYStageBase<XYStage>(),
	busy_ (false),
	initialized_ (false),
	stepSize_um_(10),	

name_ (g_LeicaDMSTCXYDrive)

{
   InitializeDefaultErrorMessages();
   SetErrorText(ERR_DEVICE_NOT_FOUND, "No XY-Drive found in this microscope");
   SetErrorText(ERR_PORT_NOT_SET, "No serial port found.  Did you include the Leica DMSTC stage and set its serial port property?");
}

XYStage::~XYStage ()
{
   Shutdown();
}

//send two consecutive GetPosition commands to test if stage is moving/busy
bool XYStage::Busy()
{
	long posX1, posX2, posY1, posY2;
	
	int ret;

	ret = GetPositionSteps(posX1, posY1);
	if(ret != DEVICE_OK)
		return true;
	ret = GetPositionSteps(posX2, posY2);
	if(ret != DEVICE_OK)
		return true;

	if((posX1 == posX2) || (posY1 == posY2))
		return false;
	else
		return true;
}

void XYStage::GetName(char* name) const
{
   assert(name_.length() < CDeviceUtils::GetMaxStringLength());
   CDeviceUtils::CopyLimitedString(name, name_.c_str());
}

int XYStage::Initialize()
{
	int ret;
	if (!g_hub.Initialized()) {
		ret = g_hub.Initialize(*this, *GetCoreCallback());
		if (ret != DEVICE_OK)
			return ret;
	}

	//SET_ACK parameter set to 1 to echo non-response commands, for error checking in hub SetCommand() functions
	ret = g_hub.SetAcknowledge(*this, *GetCoreCallback(), 1);
	if (ret != DEVICE_OK)
		return ret;

	//move to origin (top left; x,y = 0,0) to reset position grid 
	ret = g_hub.ResetStage(*this, *GetCoreCallback());
	if (ret != DEVICE_OK)
		return ret;

	//wait while stage is moving to origin
	while(Busy()){
	}

	////////////////////////////////////////////////////////////////////////////
	//THIS IS NOT NECESSARY FOR NORMAL OPERATION IN Micro-Manager.
	//COMMENTED OUT TO MINIMIZE POTENTIALLY DANGEROUS & UNNEEDED STAGE MOVEMENT:
	//
	//Move to bottom right to define x,y limits, otherwise the commands
	//GET_LIMIT_X1/Y1 and GET_LIMIT_X2/Y2 (020 - 023) give three
	//question marks as return values
	//
	//ret = g_hub.InitRange(*this, *GetCoreCallback());
	//if (ret != DEVICE_OK)
	//	return ret;
	//
	//while(Busy()){  
	//}
	////////////////////////////////////////////////////////////////////////////

{'fraction_non_alphanumeric': 0.23276820455808783, 'fraction_numerical': 0.006392440244580322, 'mean_word_length': 1.9159238249594814, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1997320', 'n_tokens_mistral': 4374, 'n_tokens_neox': 4225, 'n_words': 1148}