Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 87 additions & 43 deletions deapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,10 @@ def connect(self, host: str = "127.0.0.1", port: int = 13240, read_only=False):

version = [int(part) for part in server_version[:4]]
temp = version[2] + version[1] * 1000 + version[0] * 1000000

if temp >= 2007004:
if temp >= 2007005:
## version after 2.7.5
self.commandVersion = 15
elif temp >= 2007004:
## version after 2.7.4
self.commandVersion = 13
elif temp >= 2007003:
Expand Down Expand Up @@ -1410,37 +1412,48 @@ def get_result(
log.debug(" Prepare Time: %.1f ms", lapsed)
step_time = self.GetTime()

histo_min = histogram.min
histo_max = histogram.max
histo_bins = histogram.bins

if self.width * self.height == 0:
log.error(" Image size is 0! ")
else:
bytesize = 0
command = self._addSingleCommand(
self.GET_RESULT,
None,
# Account for different command versions
params = [
frame_type.value,
pixel_format.value,
attributes.centerX,
attributes.centerY,
attributes.zoom,
attributes.windowWidth,
attributes.windowHeight,
attributes.fft,
]
if commandVersion >= 10:
params.extend(
[
frame_type.value,
pixel_format.value,
attributes.centerX,
attributes.centerY,
attributes.zoom,
attributes.windowWidth,
attributes.windowHeight,
attributes.fft,
attributes.stretchType,
attributes.manualStretchMin,
attributes.manualStretchMax,
attributes.manualStretchGamma,
attributes.outlierPercentage,
attributes.timeoutMsec,
histo_min,
histo_max,
histo_bins,
],
]
)
else:
params.append(attributes.linearStretch)
params.append(attributes.outlierPercentage)
if commandVersion > 2 and commandVersion < 10:
params.append(attributes.buffered)
if commandVersion > 3:
params.append(attributes.timeoutMsec)
params.extend([histogram.min, histogram.max, histogram.bins])
if commandVersion >= 15:
params.extend(
[
attributes.output_binning_x,
attributes.output_binning_y,
attributes.output_binning_method,
]
)

if self.width * self.height == 0:
log.error(" Image size is 0! ")
else:
bytesize = 0
command = self._addSingleCommand(self.GET_RESULT, None, params=params)

if logLevel == logging.DEBUG:
lapsed = (self.GetTime() - step_time) * 1000
Expand Down Expand Up @@ -2119,38 +2132,69 @@ def wait_for_saving_files(self, quiet=True):
print(" %.1fs" % duration)
sys.stdout.flush()

# Start acquisition and get a single image
# fileName: the image will be saved to disk if a file name is provided
# textSize: a text file with pixel values will be saved if textSize is given, for debugging/test
def get_image(self, pixelFormat=PixelFormat.AUTO, fileName=None, textSize=0):
def _get_auto_attributes(self, frame_type: FrameType):
"""
Get automatic attributes for the current acquisition settings.
Returns
-------
Attributes
The automatic attributes for the current acquisition settings.
"""
attributes = Attributes()
scan_images = [17, 18, 19, 20, 21, 22, 23, 24, 25]
if frame_type.value in scan_images:
attributes.windowWidth = self.scan_sizex
attributes.windowHeight = self.scan_sizey
else:
attributes.windowWidth = self.image_sizex
attributes.windowHeight = self.image_sizey
return attributes

@deprecated_argument("pixelFormat", alternative="pixel_format", since="5.2.1")
@deprecated_argument("fileName", alternative="file_name", since="5.2.1")
@deprecated_argument("textSize", alternative="text_size", since="5.2.1")
def get_image(
self,
frame_type: Union[FrameType, str] = FrameType.SUMTOTAL,
pixel_format: Union[PixelFormat, str] = PixelFormat.AUTO,
attributes: Union[Attributes, str] = "auto",
file_name: str = None,
text_size: int = 0,
):
Comment on lines +2156 to +2163
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CoolFanyu I did change this slightly to allow any attribute to be passed to the get_image function.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that should be better. I noticed some old scripts used this function. In most cases, it just calls GetImage(). But it also added some other parameters in some scripts, and I noticed they are also not compatible with SDK 5.2. I guess we should just use the new one and change the old script if it passes parameters.

"""
Get a single image and save it to disk if a file name is provided

Parameters
----------
pixelFormat : PixelFormat, optional
frame_type : FrameType or str, optional
The frame type of the image, by default FrameType.SUMTOTAL
pixel_format : PixelFormat, optional
The pixel format of the image, by default PixelFormat.AUTO
fileName : str, optional
file_name : str, optional
The file name to save the image, by default None
textSize : int, optional
attributes : Attributes or "auto", optional
The attributes of the image, by default "auto"
text_size : int, optional
The text size, by default 0
"""
if isinstance(frame_type, str):
frame_type = getattr(FrameType, frame_type.upper())
if attributes == "auto":
attributes = self._get_auto_attributes(frame_type)

self.StartAcquisition(1)
frameType = FrameType.SUMTOTAL

if pixelFormat == "float32":
pixelFormat = PixelFormat.FLOAT32
if pixel_format == "float32":
pixel_format = PixelFormat.FLOAT32

elif pixelFormat == "uint16":
pixelFormat = PixelFormat.UINT16
elif pixel_format == "uint16":
pixel_format = PixelFormat.UINT16

attributes = Attributes()
histogram = Histogram()
image = self.GetResult(frameType, pixelFormat, attributes, histogram)[0]
image = self.GetResult(frame_type, pixel_format, attributes, histogram)[0]

if fileName and len(fileName) > 0:
self.SaveImage(image, fileName, textSize)
if file_name and len(file_name) > 0:
self.SaveImage(image, file_name, text_size)

return image

Expand Down
88 changes: 86 additions & 2 deletions deapi/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ class ContrastStretchType(IntEnum):
WIDERANGE = 7


class BinningMethod(IntEnum):
NONE = 0
AVERAGE = 1
SUM = 2
FOURIERCROP = 3


class Attributes:
"""Class to hold attributes for getting the result of an image acquisition

Expand Down Expand Up @@ -164,8 +171,79 @@ class Attributes:
Maximum value for manual contrast stretching
manual_stretch_gamma : float, optional
Gamma value for manual contrast stretching


outlier_percentage : float, optional
Percentage of outliers to ignore in the image
buffered : bool, optional
Whether the image is buffered
timeout_msec : float, optional
Timeout in milliseconds for retrieving the image
frame_width : int, optional
Width of the frame in pixels
frame_height : int, optional
Height of the frame in pixels
dataset_name : str, optional
Name of the dataset to retrieve the image from
acq_index : int, optional
Index of the acquisition. Returned by the server with a get_result call.
acq_finished : bool, optional
Whether the acquisition is finished. Returned by the server with a get_result call.
image_index : int, optional
Index of the image in the acquisition. Returned by the server with a get_result call.
frame_count : int, optional
Number of frames in the acquisition. Returned by the server with a get_result call.
image_min : float, optional
Minimum value of the image data
image_max : float, optional
Maximum value of the image data
image_mean : float, optional
Mean value of the image data
image_std : float, optional
Standard deviation of the image data
eppix : float, optional
Electrons per pixel in the image
eps : float, optional
Electrons per second in the image
eppixps : float, optional
Electrons per pixel per second in the image
epa2 : float, optional
Electrons per area squared in the image
eppixpf : float, optional
Electrons per pixel per frame in the image
red_sat_warning_value : float, optional
Red saturation warning value for the image
orange_sat_warning_value : float, optional
Orange saturation warning value for the image
eppix_incident : float, optional
Electrons per pixel incident in the image
eps_incident : float, optional
Electrons per second incident in the image
eppixps_incident : float, optional
Electrons per pixel per second incident in the image
epa2_incident : float, optional
Electrons per area squared incident in the image
eppixpf_incident : float, optional
Electrons per pixel per frame incident in the image
under_exposure_rate : float, optional
Under exposure rate of the image
over_exposure_rate : float, optional
Over exposure rate of the image
timestamp : float, optional
Timestamp of the image acquisition
auto_stretch_min : float, optional
Minimum value for automatic contrast stretching
auto_stretch_max : float, optional
Maximum value for automatic contrast stretching
auto_stretch_gamma : float, optional
Gamma value for automatic contrast stretching
saturation : float, optional
Saturation level of the image
output_binning_x : int, optional
Binning factor in the x direction for the output image
output_binning_y : int, optional
Binning factor in the y direction for the output image
output_binning_method : int, optional
Method used for binning the output image. Defaults to BinningMethod.AVERAGE,
other options are BinningMethod.NONE, BinningMethod.SUM, and BinningMethod.FOURIERCROP.
"""

def __init__(
Expand Down Expand Up @@ -214,6 +292,9 @@ def __init__(
auto_stretch_max=0.0,
auto_stretch_gamma=1.0,
saturation=0.0,
output_binning_x: int = 1,
output_binning_y: int = 1,
output_binning_method: int = 1, # BinningMethod.AVERAGE
):

self.centerX = center_x
Expand Down Expand Up @@ -260,6 +341,9 @@ def __init__(
self.autoStretchMax = auto_stretch_max
self.autoStretchGamma = auto_stretch_gamma
self.saturation = saturation
self.output_binning_x = output_binning_x
self.output_binning_y = output_binning_y
self.output_binning_method = output_binning_method


class Histogram:
Expand Down
2 changes: 1 addition & 1 deletion deapi/prop_dump.json
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@
"get": "((hardware_roi_size_y / hardware_binning_y)/ binning_y)-crop_offset_y"
},
"Server Software Version":{
"value":"2.7.4.1352",
"value":"2.7.5.1352",
"data_type":"String",
"value_type":"ReadOnly",
"category":"Basic",
Expand Down
2 changes: 1 addition & 1 deletion deapi/tests/test_fake_server/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ def test_set_virtual_image_calculation(self, fake_server):
assert fake_server["Scan - Virtual Detector 1 Calculation"] == "Sum"

def test_server_software_version(self, fake_server):
assert fake_server["Server Software Version"] == "2.7.4.1352"
assert fake_server["Server Software Version"] == "2.7.5.1352"
5 changes: 3 additions & 2 deletions deapi/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version = "5.2.2"
version = "5.3.0"
versionInfo = list(map(int, version.split(".")))
commandVersion = (versionInfo[0] - 4) * 10 + versionInfo[1] + 1
commandVersion = (versionInfo[0] - 4) * 10 + versionInfo[1] + 2
print(f"DEAPI Version: {version} (Command Version: {commandVersion})")
Loading