Skip to content

Conversation

@trappitsch
Copy link
Contributor

This PR provides multichannel consistency for the optical spectrum analyzer metaclass and is associated with the discussion in #156.

It has been a while that we discussed this, but I finally started looking at it again and figured that the optical spectrum analyzer seems straight forward to get my hands on this issue. Changes in the metaclass are modeled after the function generator. Would be good to hear what you think to see if this is in the right direction. Thanks!

The only instrument dependent on this metaclass is currently the Yokogawa 6370. I have only extended the tests, but not changed the instruments test in order to ensure that there are no breaking changes.

Metaclass tests are changing a bit and I will comment in a sec on the important ones.

Let me know what you think!

…onsistency

fix tests to adjust to new metaclass refractoring

Finish optical_spectrum_analyzer channel consistency


from enum import IntEnum, Enum
import hashlib
Copy link
Contributor Author

Choose a reason for hiding this comment

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

cleanup unused import


def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._channel_count = len(self.Traces)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

now required from metaclass. see channel property below for range

@codecov
Copy link

codecov bot commented Dec 9, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.14%. Comparing base (71e2337) to head (aeb0dd2).
Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #431   +/-   ##
=======================================
  Coverage   99.14%   99.14%           
=======================================
  Files          91       91           
  Lines        9240     9251   +11     
=======================================
+ Hits         9161     9172   +11     
  Misses         79       79           
Flag Coverage Δ
unittests 99.14% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

with pytest.raises(NotImplementedError):
_ = inst.channel
ch = inst.channel[0]
assert isinstance(ch, ik.abstract_instruments.OpticalSpectrumAnalyzer.Channel)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the channel itself is automatically implemented now and - if a single channel instrument - will forward to the parent's channel. so this needed to be changed



def test_osa_channel_wavelength(osc):
@pytest.mark.parametrize("num_ch", [1, 5])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

take care of single and multichannel instruments

with expected_protocol(osa, [], []) as inst:
inst._channel_count = num_ch
ch = inst.channel[0]
with pytest.raises(NotImplementedError):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

call single/mutli channel instrument through the inst.channel ProxyList function and ensure proper forwarding

with pytest.raises(NotImplementedError):
ch.wavelength()
with pytest.raises(NotImplementedError):
inst.wavelength() # single channel instrument
Copy link
Contributor Author

Choose a reason for hiding this comment

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

use the single channel function to call (directly from instrument class) and ensure it exists and raises appropriate error



def test_osa_channel_data(osc):
@pytest.mark.parametrize("num_ch", [1, 5])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

same as above


def test_channel_is_channel_class():
inst = ik.yokogawa.Yokogawa6370.open_test()
assert inst._channel_count == len(inst.Traces)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ik.yokogawa.Yokogawa6370.Traces is 5 channels long, this is provided to the proxy list. Making sure here we set this now, as it is a new variable defined in the metaclass.

@scasagrande
Copy link
Contributor

seems reasonable to me!

@trappitsch
Copy link
Contributor Author

Sweet, there's still some cleanup to do though.
For the function generator in #206 I noticed that you removed all @abc.abstractmethod decorators, basically opening up the implementations. Is this such that specific function generators that have other methods but still fit the device "function generators" can be implemented as well in the same way and the user simply gets "NotImplementedErrors" if something is not implemented? If so (or for any other good reason), we might want to do the same for the OpticalSpectrumAnalyzer abstract class (plus others). What do you think?

@trappitsch
Copy link
Contributor Author

What do you think / was your reasoning about how the @abc.abstractmethod decorators were handled in the function generator @scasagrande? Mostly a quick ping, feel free to ignore ;)

@trappitsch
Copy link
Contributor Author

@scasagrande Happy new year! Wanted to check in if you have any info on above question on how @abc.abstractmethod decorators were handled in the function generator class...

@scasagrande
Copy link
Contributor

Sorry!

What was my reasoning? Oh goodness I don't remember the specifics. I think I removed them from the functions on the instrument class because I wanted the concrete implementation to be in the channel specific class.

@trappitsch
Copy link
Contributor Author

Thanks @scasagrande for the answer, well, I'm not that fast these days either ;) Anyway, tried to make it consistent with decorators to keep the ones that are channel associated in the channel class and the others outside in the main class.
Have a look at this refractor, I think it would be ready for a review. LMK what you think!

Copy link
Contributor

@scasagrande scasagrande left a comment

Choose a reason for hiding this comment

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

looks reasonable to me! mostly test changes, and others seem to be in line with what we've done with other multichannel classes

@scasagrande scasagrande merged commit a8f771d into instrumentkit:main Feb 12, 2025
11 checks passed
@trappitsch trappitsch deleted the optical_spectrum_analyzer_single_ch_consistency branch February 12, 2025 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants