Skip to content

Commit

Permalink
Merged old with new
Browse files Browse the repository at this point in the history
  • Loading branch information
Lars-Kool committed Jun 24, 2024
2 parents f4a5ddb + 1103f5d commit ebd65a1
Show file tree
Hide file tree
Showing 11 changed files with 556 additions and 9 deletions.
1 change: 1 addition & 0 deletions MMCore/Devices/DeviceInstances.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "ImageProcessorInstance.h"
#include "SignalIOInstance.h"
#include "MagnifierInstance.h"
#include "PumpInstance.h"
#include "SLMInstance.h"
#include "GalvoInstance.h"
#include "HubInstance.h"
Expand Down
42 changes: 42 additions & 0 deletions MMCore/Devices/PumpInstance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// PROJECT: Micro-Manager
// SUBSYSTEM: MMCore
//
// DESCRIPTION: Pump device instance wrapper
//
// COPYRIGHT: Institut Pierre-Gilles de Gennes, Paris, 2024,
// All Rights reserved
//
// LICENSE: This file is distributed under the "Lesser GPL" (LGPL) 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.
//
// AUTHOR: Lars Kool, Institut Pierre-Gilles de Gennes

#include "PumpInstance.h"

// Volume controlled pump functions
int PumpInstance::Home() { return GetImpl()->Home(); }
int PumpInstance::Stop() { return GetImpl()->Stop(); }
int PumpInstance::invertDirection(bool state) { return GetImpl()->InvertDirection(state); }
int PumpInstance::isDirectionInverted(bool& state) { return GetImpl()->IsDirectionInverted(state); }
int PumpInstance::setVolumeUl(double volume) { return GetImpl()->SetVolumeUl(volume); }
int PumpInstance::getVolumeUl(double& volume) { return GetImpl()->GetVolumeUl(volume); }
int PumpInstance::setMaxVolumeUl(double volume) { return GetImpl()->SetMaxVolumeUl(volume); }
int PumpInstance::getMaxVolumeUl(double& volume) { return GetImpl()->GetMaxVolumeUl(volume); }
int PumpInstance::setFlowrateUlPerSec(double flowrate) { return GetImpl()->SetFlowrateUlPerSecond(flowrate); }
int PumpInstance::getFlowrateUlPerSec(double& flowrate) { return GetImpl()->GetFlowrateUlPerSecond(flowrate); }
int PumpInstance::Dispense() { return GetImpl()->Dispense(); }
int PumpInstance::DispenseDuration(double durSec) { return GetImpl()->DispenseDuration(durSec); }
int PumpInstance::DispenseVolume(double volUl) { return GetImpl()->DispenseVolume(volUl); }

// Pressure controlled pump functions
int PumpInstance::Calibrate() { return GetImpl()->Calibrate(); }
int PumpInstance::setPressure(double pressure) { return GetImpl()->SetPressure(pressure); }
int PumpInstance::getPressure(double& pressure) { return GetImpl()->GetPressure(pressure); }
59 changes: 59 additions & 0 deletions MMCore/Devices/PumpInstance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// PROJECT: Micro-Manager
// SUBSYSTEM: MMCore
//
// DESCRIPTION: Pump device instance wrapper
//
// COPYRIGHT: Institut Pierre-Gilles de Gennes, Paris, 2024,
// All Rights reserved
//
// LICENSE: This file is distributed under the "Lesser GPL" (LGPL) 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.
//
// AUTHOR: Lars Kool, Institut Pierre-Gilles de Gennes

#pragma once

#include "DeviceInstanceBase.h"

class PumpInstance : public DeviceInstanceBase<MM::Pump>
{
public:
PumpInstance(CMMCore* core,
std::shared_ptr<LoadedDeviceAdapter> adapter,
const std::string& name,
MM::Device* pDevice,
DeleteDeviceFunction deleteFunction,
const std::string& label,
mm::logging::Logger deviceLogger,
mm::logging::Logger coreLogger) :
DeviceInstanceBase<MM::Pump>(core, adapter, name, pDevice, deleteFunction, label, deviceLogger, coreLogger)
{}

// Volume controlled pump specific
int Home();
int Stop();
int invertDirection(bool state);
int isDirectionInverted(bool& state);
int setVolumeUl(double volUl);
int getVolumeUl(double& volUl);
int setMaxVolumeUl(double volUl);
int getMaxVolumeUl(double& volUl);
int setFlowrateUlPerSec(double flowrate);
int getFlowrateUlPerSec(double& flowrate);
int Dispense();
int DispenseDuration(double durSec);
int DispenseVolume(double volUl);

// Pressure controller specific
int Calibrate();
int setPressure(double pressure);
int getPressure(double& pressure);
};
2 changes: 2 additions & 0 deletions MMCore/LoadableModules/LoadedDeviceAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ LoadedDeviceAdapter::LoadDevice(CMMCore* core, const std::string& name,
return std::make_shared<GalvoInstance>(core, shared_this, name, pDevice, deleter, label, deviceLogger, coreLogger);
case MM::HubDevice:
return std::make_shared<HubInstance>(core, shared_this, name, pDevice, deleter, label, deviceLogger, coreLogger);
case MM::PumpDevice:
return std::make_shared<PumpInstance>(core, shared_this, name, pDevice, deleter, label, deviceLogger, coreLogger);
default:
deleter(pDevice);
throw CMMError("Device " + ToQuotedString(name) +
Expand Down
256 changes: 256 additions & 0 deletions MMCore/MMCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3228,6 +3228,19 @@ std::string CMMCore::getAutoFocusDevice()
return std::string();
}

/**
* Returns the label of the currently selected pump device.
*/
std::string CMMCore::getPumpDevice()
{
std::shared_ptr<PumpInstance> camera = currentPumpDevice_.lock();
if (camera)
{
return camera->GetLabel();
}
return std::string();
}

/**
* Sets the current auto-focus device.
*/
Expand Down Expand Up @@ -6214,6 +6227,249 @@ std::string CMMCore::getGalvoChannel(const char* deviceLabel) throw (CMMError)
return pGalvo->GetChannel();
}

/* Pump device */

/**
* Sets the current pump device.
* @param pump the shutter device label
*/
void CMMCore::setPumpDevice(const char* deviceLabel) throw (CMMError)
{
if (!deviceLabel || strlen(deviceLabel) > 0) // Allow empty label
CheckDeviceLabel(deviceLabel);

// Nothing to do if this is the current shutter device:
if (getPumpDevice().compare(deviceLabel) == 0)
return;

if (strlen(deviceLabel) > 0)
{
currentPumpDevice_ =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);

LOG_INFO(coreLogger_) << "Default shutter set to " << deviceLabel;
}
else
{
currentPumpDevice_.reset();
LOG_INFO(coreLogger_) << "Default pump unset";
}
properties_->Refresh(); // TODO: more efficient
std::string newPumpLabel = getPumpDevice();
{
MMThreadGuard scg(stateCacheLock_);
stateCache_.addSetting(PropertySetting(MM::g_Keyword_CoreDevice, MM::g_Keyword_CorePump, newPumpLabel.c_str()));
}
}

/**
* Homes the pump
*/
void CMMCore::PumpHome(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->Home();

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

/**
* Stops the pump
*/
void CMMCore::PumpStop(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->Stop();

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

/**
* Sets whether the pump direction needs to be inverted
*/
void CMMCore::invertPumpDirection(const char* deviceLabel, bool invert) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->invertDirection(invert);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

/**
* Gets whether the pump direction needs to be inverted
*/
bool CMMCore::isPumpDirectionInverted(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

bool invert = false;
int ret = pPump->isDirectionInverted(invert);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
return invert;
}

/**
* Sets the volume of fluid in the pump in uL. Note it does not withdraw upto
* this amount. It is merely to inform MM of the volume in a prefilled pump.
*/
void CMMCore::setPumpVolume(const char* deviceLabel, double volUl) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->setVolumeUl(volUl);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

/**
* Get the fluid volume in the pump in uL
*/
double CMMCore::getPumpVolume(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

double volUl = 0;
int ret = pPump->getVolumeUl(volUl);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
return volUl;
}

/**
* Sets the max volume of the pump in uL
*/
void CMMCore::setPumpMaxVolume(const char* deviceLabel, double volUl) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->setMaxVolumeUl(volUl);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

/**
* Gets the max volume of the pump in uL
*/
double CMMCore::getPumpMaxVolume(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

double volUl = 0;
int ret = pPump->getMaxVolumeUl(volUl);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
return volUl;
}

/**
* Sets the flowrate of the pump in uL per second
*/
void CMMCore::setPumpFlowrate(const char* deviceLabel, double UlperSec) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->setFlowrateUlPerSec(UlperSec);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

/**
* Gets the flowrate of the pump in uL per second
*/
double CMMCore::getPumpFlowrate(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

double UlperSec = 0;
int ret = pPump->getFlowrateUlPerSec(UlperSec);

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
return UlperSec;
}

/**
* Start dispensing at the set flowrate until syringe is empty, or manually
* stopped (whichever occurs first).
*/
void CMMCore::PumpDispense(const char* deviceLabel) throw (CMMError)
{
std::shared_ptr<PumpInstance> pPump =
deviceManager_->GetDeviceOfType<PumpInstance>(deviceLabel);
mm::DeviceModuleLockGuard guard(pPump);

int ret = pPump->Dispense();

if (ret != DEVICE_OK)
{
logError(deviceLabel, getDeviceErrorText(ret, pPump).c_str());
throw CMMError(getDeviceErrorText(ret, pPump));
}
}

///////////////////////////////////////////////////////////////////////////////
// Pressure Pump methods
///////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit ebd65a1

Please sign in to comment.