Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FLIR camera device. #242

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Open

Conversation

ehpor
Copy link
Collaborator

@ehpor ehpor commented Nov 30, 2021

This PR does not contain an emulator for a FLIR camera. It can therefore not be used with the HiCAT simulator. This will be done in a separate PR.

  • Add docstrings.
  • Hardware test (worked before the rebase, and the rebase was clean as well, so just a quick check).

@ehpor ehpor self-assigned this Nov 30, 2021
Also add config_id to metadata.
@jamienoss jamienoss self-requested a review December 10, 2021 14:44
@jamienoss jamienoss marked this pull request as ready for review December 10, 2021 14:44
Copy link
Contributor

@jamienoss jamienoss left a comment

Choose a reason for hiding this comment

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

Thanks again for this, see revision comments.

'14bit': self.instrument_lib.AdcBitDepth_Bit14}

def _open(self):
serial_number = CONFIG_INI.get(self.config_id, 'serial_number')
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] We don't ref CONFIG_INI from catkit so serial_number will need to be passed in.

# Camera was not running. We can safely ignore.
pass
else:
self.log.error(f'PySpin error: {e.errorcode}')
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision?] Do we not want to raise this?

Comment on lines +194 to +198
self.cam.DeInit()
self.cam = None
self.cam_list.Clear()

self._destroy_system()
Copy link
Contributor

@jamienoss jamienoss Dec 10, 2021

Choose a reason for hiding this comment

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

[revision] These look like they should be in a finally block, perhaps even two:

...
  finally:
    self.cam.DeInit()  # <----- Can this raise?
finally:
  self.cam = None
  self.cam_list.Clear()
  self._destroy_system()

from catkit.interfaces.Camera import Camera
from catkit.catkit_types import MetaDataEntry, units, quantity
import catkit.util
from catkit.config import CONFIG_INI
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] Remove this, please, we don't ref CONFIG_INI from catkit.[revision] We don't ref CONFIG_INI from catkit.

Comment on lines +127 to +134
self.pixel_format_enum = {'mono8': self.instrument_lib.PixelFormat_Mono8,
'mono12p': self.instrument_lib.PixelFormat_Mono12p,
'mono16': self.instrument_lib.PixelFormat_Mono16}

self.adc_bit_depth_enum = {'8bit': self.instrument_lib.AdcBitDepth_Bit8,
'10bit': self.instrument_lib.AdcBitDepth_Bit10,
'12bit': self.instrument_lib.AdcBitDepth_Bit12,
'14bit': self.instrument_lib.AdcBitDepth_Bit14}
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] If we're gonna mangle "enum" semantics into the name, then I'd rather see these as actual enums, please (or remove "enum" from the attr name):

self.pixel_format_enum = Enum("pixel_format_enum", {'MONO8': self.instrument_lib.PixelFormat_Mono8,
  'MONO12_P': self.instrument_lib.PixelFormat_Mono12p,
  'MONO16': self.instrument_lib.PixelFormat_Mono16})

The reason is that the access pattern between a dict and an enum is quite different.

Copy link
Contributor

Choose a reason for hiding this comment

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

In case you read this and make alterations to un-name-mangle the "enum" before reading on, I would read on. I really get the impression that you just wanna use an Enum.

Comment on lines +253 to +258
if not type(exposure_time) in [int, float]:
exposure_time_us = exposure_time.to(units.microsecond).m
else:
exposure_time_us = exposure_time

self.exposure_time = exposure_time_us
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] Use isinstance and not type for this, please.

[revision] Conditional assignment is preferred here, please, or at least dedupe exposure_time_us.

self.exposure_time = exposure_time.to(units.microsecond).m if isinstance(exposure_time, (int, float)) else exposure_time

or

self.exposure_time = exposure_time
if not isinstance(self.exposure_time, (int, float)):
  self.exposure_time = self.exposure_time.to(units.microsecond).m

else:
meta_data.append(extra_metadata)

# try-finally shuts down the camera if the generator is stopped.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does EndAcquisition() really "shut down" the camera?

Copy link
Contributor

Choose a reason for hiding this comment

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

i.e., would _open() need to be re-called?

while frame_count < num_exposures:
try:
# Wait for image with timeout (in ms).
image_result = self.cam.GetNextImage(100)
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] Let's hoist the timeout to an instance param, please. Or perhaps a class attr if there's a reason to.

Comment on lines +287 to +290
if e.errorcode == -1011:
# The timeout was triggered. Nothing to worry about.
continue
elif e.errorcode == -1010:
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] Let's make an enum/macro for these error codes, please.

Comment on lines +277 to +280
if self.pixel_format == 'mono8':
pixel_format = self.instrument_lib.PixelFormat_Mono8
else:
pixel_format = self.instrument_lib.PixelFormat_Mono16
Copy link
Contributor

Choose a reason for hiding this comment

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

[revision] I could be wrong but this entire thing seems very circular and cries for an enum, you've implemented a similar mapping more than once now.

I would make an enum and then just assign a member to self.pixel_format and be done with it.

@jamienoss jamienoss added the progress-stalled Progress has stalled and is currently not actively being worked on. label Mar 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Adds Hardware progress-stalled Progress has stalled and is currently not actively being worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants