-
Notifications
You must be signed in to change notification settings - Fork 0
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
147 call transformers for temp #157
Conversation
@pytest.fixture() | ||
def tmp_calibration_dir(monkeypatch, tmp_path): | ||
monkeypatch.setattr(evolver.settings.settings, "ROOT_CALIBRATOR_FILE_STORAGE_PATH", tmp_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semi-unrelated, but I noticed that the tests were creating persisting calibration files.
|
||
class Output(SerialDeviceOutputBase, SensorDriver.Output): | ||
temperature: float = Field(None, description="Sensor temperature in degrees celcius") | ||
temperature: float = Field(None, description="Sensor temperature in degrees Celsius") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
smuggle
@amitschang Hey, do you mind taking a preliminary look at this, please? Main design aspect is that the vial transformers are |
input_transformer: dict[int, ConfigDescriptor | LinearTransformer | None] | None = None | ||
output_transformer: dict[int, ConfigDescriptor | LinearTransformer | None] | None = None | ||
|
||
def run_calibration_procedure(self, data: dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI this is just a place-holder.
input_transformer: dict[int, ConfigDescriptor | LinearTransformer | None] | None = None | ||
output_transformer: dict[int, ConfigDescriptor | LinearTransformer | None] | None = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Main feature.
7d8a971
to
e7d7b38
Compare
if save: | ||
calibration_data[transformer].save() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
smuggle
Codecov ReportAttention: Patch coverage is
📢 Thoughts on this report? Let us know! |
scripts/gen_default_cali_files.py
Outdated
# coefficients = np.loadtxt("/Users/jamienoss/Downloads/TEMP_20190201.txt", delimiter=',') | ||
|
||
# https://github.com/FYNCH-BIO/evolver/blob/master/evolver/calibrations.json | ||
with open("/Users/jamienoss/Downloads/calibrations.json") as fp: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to go, use requests instead.
Seems good, Just a couple impressions:
|
@amitschang thanks for the prelim review.
That's a good idea. I think it would have to do both though, allow the |
if isinstance(self.calibrator.output_transformer, dict): | ||
temperature = self.calibrator.output_transformer[vial].convert_to(raw) | ||
else: | ||
temperature = self.calibrator.output_transformer.convert_to(raw) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @jamienoss , I should have just put it here. I mean that maybe we don't need to bother with the non-vial case, the procedure really should be producing one per vial even if there is only one vial
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks. I re-read your comment and realised what you were referring to.
I thought it was more useful and extensible to allow for both. I've also factored this out to the hardware interface as:
def _transform(self, transformer, func, x, vial=None):
if self.calibrator and (_transformer := getattr(self.calibrator, transformer, None)):
if isinstance(_transformer, dict):
y = getattr(_transformer[vial], func)(x)
else:
y = getattr(_transformer, func)(x)
else:
y = x
return y
to reduce boilerplate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 ah, ok this will simplify while also being flexible
a9599a6
to
411ecce
Compare
@amitschang FYI I'm gonna punt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a couple small comments.
@@ -25,6 +26,18 @@ def __init__(self, *args, evolver=None, **kwargs): | |||
self.evolver = evolver | |||
super().__init__(*args, **kwargs) | |||
|
|||
def _transform(self, transformer: str, func: str, x: Any, vial: int = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it might be more general if we don't call the func
but rather return a transformer, and provide a signature more like transformer_in(self, vial) -> Transformer
(effectors) and transformer_out(self, vial) -> Transformer
(sensors), called like:
temp = self.transformer_out(vial).convert_to(raw)
it can be reused a bit easer since one could stash the transformer to make further calls if needed. It reads slightly more intentional (arguably)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could do, but I didn't necessarily want to add it to the hardware interface, which the above suggestion would. There'd then need to be two new funcs: transformer_in
and transformer_out
(which I think would be better suited as properties), however, this would still leave most of the boilerplate as they could both return None
and the caller would still have to check for this before calling, e.g., transformer.convert_to
, and handle the noop. So it would read:
if transformer:=self.transform_in(vial):
temp = transformer.convert_to(raw)
else:
temp = raw
or
temp = self.transformer_in(vial).convert_to(raw) if self.transformer_in(vial) else raw
Thoughts?
|
||
|
||
@pytest.fixture | ||
def tmp_calibration_dir(monkeypatch, tmp_path): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be useful as an autouse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this doesn't work as the fixture order matters.
Signed-off-by: James Noss <jnoss@jhu.edu>
Signed-off-by: James Noss <jnoss@jhu.edu>
a830528
to
9a83a81
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good, thanks!
Resolves #147