Open EvanKirshenbaum opened 5 months ago
This issue was referenced by the following commits before migration:
That was relatively straightforward. There's now a bilby_yaminon.Board
defined simply as
class Board(bilby.Board):
_yaminon: Final[wombat.Board]
def __init__(self) -> None:
with wombat.Config.is_yaminon >> True:
self._yaminon = wombat.Board()
super().__init__()
def _add_pads(self)->None:
self.pads.update(self._yaminon.pads)
def _add_all_wells(self) -> None:
assert len(self._well_list) == 0
self._well_list.extend(self._yaminon.wells)
def update_state(self)->None:
self._yaminon.update_state()
super().update_state()
def finish_update(self)->None:
# We don't propagate up, because we only want to infer drop motion once.
self._yaminon.finish_update()
def join_system(self, system: System)->None:
super().join_system(system)
self._yaminon.join_system(system)
That is, it inherits from bilby.Board
and contains a wombat.Board
. It initializes the Wombat board first and in its Bilby initialization, it overrides _add_pads()
and (a newly extracted) _add_all_wells()
to make our pads and wells copied over from the Wombat board. Doing this, and forwarding update_state()
and finish_update()
to the Wombat board means that all pads (including well pads and gates) will have Wombat electrodes and will be updated using the Opendrop controller.
The associated PlatformTask
similarly inherits from bilby_task.PlatformTask
but contains a YaminonPlatformTask
, and arguments from both are added.
The only things that were tricky were:
PlatformChoiceTask
now has an abstract _check_and_add_args_to()
which takes a set of type[PatformChoiceTask]
. The implementation of this should start with
if not self._args_needed(PlatformTask, processed):
return
which guarantees that we won't try to add the arguments for the same platform twice (which will cause it to fail). _args_needed()
returns False
if we've already seen this class. Otherwise it adds the class to the set and returns True
.
While working on #221, which split things so only the hybrid board owned the components, but only the internal Yaminon board owned the pads, I was seeing that heater #1 : off
wasn't ever finishing, even though it was having its effect. It turns out that the problem is that the hybrid overrode finish_update()
to say
def finish_update(self)->None:
# We don't propagate up, because we only want to infer drop motion once.
self._yaminon.finish_update()
This is wrong. Since the pads only journal to the yaminon board, it's safe to propagate (since there won't be any motion to infer), and by not doing it, the cleanup for heater operations (i.e., posting the result to the future) was just sitting in the _after_update
queue.
The code now looks like
def finish_update(self)->None:
# It's safe to call both, because inferring drop motion on super()
# (Bilby) won't do anything (because no pads journal to it). It's
# necessary because changes to heater/chiller/magnet state will leave
# callbacks to post results.
self._yaminon.finish_update()
super().finish_update()
With the addition of thermal states (#279) and ESElog (#264), which can theoretically work without the full Bilby control hardware working, @cumbiem has asked for a device model that can use Wombat/Yaminon (i.e., the Opendrop controller) to control drop movement and Bilby for everything else.
I think (hope) that I can do this simply by overriding
bilby.Board
but overriding._pad_state()
(and_well_gate/pad_state()
) to create awombat.Electrode
rather than aglider_client.Electrode
. I'll also have to overrideupdate_state()
to do thewombat
piece as well.For the
PlatformTask
, I'll want to create one that has within it abilby_client.PlatformTask
and awombat.YaminonPlatformTask
(I don't think that they need a barewombat.PlatformTask
) and adds args from both. This should probably be withinbilby_client
(or another parallel module) so that it can do the same trick of doing theimport
withinmake_board()
to avoid needing to havepyglider.pyd
on the path. It's possible that it should derive frombilby_client.PlatformTask
. In any case, the munging and adding of the dll directory should be split out into something that can be called from both.Migrated from internal repository. Originally created by @EvanKirshenbaum on Jun 27, 2023 at 11:10 AM PDT.