ZenHardwareSetting in Python Script

Discuss macros to control the hardware functions of your ZEISS microscope
Post Reply
Matthew Cottrell
Posts: 10
Joined: Sat Jul 24, 2021 4:10 pm

ZenHardwareSetting in Python Script

Post by Matthew Cottrell »

How do I access the ZenHardwareSetting type in a python script.

I can record and run a macro that uses ZenHardwareSetting like this:

Code: Select all

hardwareSetting = ZenHardwareSetting()
hardwareSetting.Load("40X Objective")
Zen.Devices.ApplyHardwareSetting(hardwareSetting)

camerasetting = Zen.Acquisition.CameraSettings.GetByName("Live Dead MV Yeast Hemocytometer.czcs")
Zen.Acquisition.ActiveCamera.ApplyCameraSetting(camerasetting)
But when I try to run this as a python script like this:

Code: Select all

#! python

import win32com.client
Zen = win32com.client.GetActiveObject("Zeiss.Micro.Scripting.ZenWrapperLM")

# Set the hardware settings
hardwareSetting = ZenHardwareSetting()
hardwareSetting.Load("40X Objective")
Zen.Devices.ApplyHardwareSetting(hardwareSetting)

# Set the camera settings
camerasetting = Zen.Acquisition.CameraSettings.GetByName("Live Dead MV Yeast Hemocytometer.czcs")
Zen.Acquisition.ActiveCamera.ApplyCameraSetting(camerasetting)
I get the error:

Code: Select all

NameError: name 'ZenHardwareSetting' is not defined
I thought that declaring:

Code: Select all

Zen = win32com.client.GetActiveObject("Zeiss.Micro.Scripting.ZenWrapperLM")
would give my python script access to everything that's available in the macro python editor.
CarlZeissMicroscopy3
Posts: 107
Joined: Wed May 20, 2020 10:10 am

Re: ZenHardwareSetting in Python Script

Post by CarlZeissMicroscopy3 »

Hello Matthew Cottrell,

to start an explanation I just would like to comment your code:

Code: Select all

Zen = win32com.client.GetActiveObject("Zeiss.Micro.Scripting.ZenWrapperLM")
means that you get a pointer named Zen in your program to an object that is located within Zen blue application.

Your try with

Code: Select all

hardwareSetting = ZenHardwareSetting()
would generate an object in your program. This could be done by importing the right dll(s) but even if you get that code running it would be of little use as it is not possible to transfer an object from your program to a running Zen blue application.

In other words:

Code: Select all

Zen.Devices.ApplyHardwareSetting(hardwareSetting)
would not work as hardwareSetting is supposed to be a pointer to an object of Zen blue and not an object of your program.

So the solution is to generate an object in Zen blue and get a pointer hardwareSetting to this object in your program, something like

Code: Select all

hardwareSetting = Zen.ObjectFactory.Create("Zeiss.Micro.Scripting.ZenHardwareSetting")
I hope this is understandable ...
Matthew Cottrell
Posts: 10
Joined: Sat Jul 24, 2021 4:10 pm

Re: ZenHardwareSetting in Python Script

Post by Matthew Cottrell »

The explanation of accessing variables in Zen versus my application is very helpful.
I can see how ObjectFactory might bridge the gap.

However, I can't seem to make it work.

The script below generates this error:

Code: Select all

C:\Users\Cottrell\Documents\MicrobeCounter>py.exe C:\Users\Cottrell\Documents\MicrobeCounter\Zen_Camera_Hardware_Settings.py
Traceback (most recent call last):
  File "C:\Users\Cottrell\Documents\MicrobeCounter\Zen_Camera_Hardware_Settings.py", line 8, in <module>
    hardwareSetting.Load("40X Objective")
AttributeError: 'NoneType' object has no attribute 'Load'
This is the script that aims to set hardware settings:

Code: Select all

#! python

import win32com.client
Zen = win32com.client.GetActiveObject("Zeiss.Micro.Scripting.ZenWrapperLM")

# Set the hardware settings
hardwareSetting = Zen.ObjectFactory.Create("ZenHardwareSetting")
hardwareSetting.Load("40X Objective")
Zen.Devices.ApplyHardwareSetting(hardwareSetting)
Matthew Cottrell
Posts: 10
Joined: Sat Jul 24, 2021 4:10 pm

Re: ZenHardwareSetting in Python Script

Post by Matthew Cottrell »

I edited the ObjectFactory line that was:

Code: Select all

hardwareSetting = Zen.ObjectFactory.Create("ZenHardwareSetting")
to now read:

Code: Select all

hardwareSetting = Zen.ObjectFactory.Create("Zeiss.Micro.Scripting.ZenHardwareSetting")
That seems to help, but it's not the complete answer because the error is now:

Code: Select all

C:\Users\Cottrell\Documents\MicrobeCounter>py.exe C:\Users\Cottrell\Documents\MicrobeCounter\Zen_Camera_Hardware_Settings.py
Traceback (most recent call last):
  File "C:\Users\Cottrell\Documents\MicrobeCounter\Zen_Camera_Hardware_Settings.py", line 9, in <module>
    hardwareSetting.Load("40X Objective")
  File "<COMObject Create>", line 2, in Load
pywintypes.com_error: (-2147024809, 'The parameter is incorrect.', (0, 'mscorlib', 'Missing parameter does not have a default value.\r\nParameter name: parameters', None, 0, -2147024809), None)
Matthew Cottrell
Posts: 10
Joined: Sat Jul 24, 2021 4:10 pm

Re: ZenHardwareSetting in Python Script

Post by Matthew Cottrell »

I can't say that I figured this out, but I did find the solution.

Examining the Load method in the Object Model browser in the macro environment revealed that Load can take two arguments. After a little trial and error I found success by passing the setting file name and 0 (zero) as the first and second arguments, respectively.

This is now working for me:

Code: Select all

#! python

import win32com.client
Zen = win32com.client.GetActiveObject("Zeiss.Micro.Scripting.ZenWrapperLM")

# Set the hardware settings
hardwareSetting = Zen.ObjectFactory.Create("Zeiss.Micro.Scripting.ZenHardwareSetting")
hardwareSetting.Load("40X Objective",0)
Zen.Devices.ApplyHardwareSetting(hardwareSetting)
Cheers!
CarlZeissMicroscopy3
Posts: 107
Joined: Wed May 20, 2020 10:10 am

Re: ZenHardwareSetting in Python Script

Post by CarlZeissMicroscopy3 »

Hello Matthew Cottrell,

yes, this is because COM does not support 'method overloading'.

For a short demonstration we use the ZenImage class:

As Python supports 'method overloading' you can write the following code:

Code: Select all

image = Zen.Application.ActiveDocument

image.Save()
image.Save(fileName)
But in COM the interface has to generate 'different' function names for each overloaded function.

Code: Select all

Zen = win32com.client.GetActiveObject("Zeiss.Micro.Scripting.ZenWrapperLM")

image = Zen.Application.ActiveDocument

image.Save()
image.Save_2(fileName)
Be aware of the _2. Other overloaded function will be renamed like image.Save_3, image.Save_4, etc.

I hope this helps to clarify the situation.
Post Reply