BTX Gemini X2#

The BTX Gemini X2 is a twin-waveform electroporator. PyLabRobot controls it through a USB serial connection: protocol and log transfer use the Gemini file-transfer interface, while run-screen actions use GhostTouch on the instrument touchscreen.

See the installation instructions before connecting the instrument.

Protocol and run-result models are provided by the Gemini X2 package.

BTX
Gemini X2
Mostlyv1
electroporator
electroporation
APIpylabrobot.thermo_fisher.btx.gemini.X2.BTXGeminiX2

Setup#

Identify the serial port on your control computer and create the device. On macOS this is often /dev/cu.usbmodem...; on Windows it is usually a COM port.

from pylabrobot.thermo_fisher.btx.gemini.X2 import BTXGeminiX2

gemini = BTXGeminiX2(port="/dev/cu.usbmodemXXXX")
await gemini.setup()

Device information#

The Gemini X2 exposes device identity, the temporary protocol prefix, and plate-handler support.

info = await gemini.request_device_info()
print(info["model"], info["version"], info["serial_number"])

Define a protocol#

Square-wave protocols use duration_us; exponential-decay protocols use resistance_ohms and capacitance_uf.

from pylabrobot.thermo_fisher.btx.gemini.X2 import ElectroporationProtocol

protocol = ElectroporationProtocol(
  protocol_type="square",
  pulse_amplitude_volts=250,
  gap_mm=2.0,
  pulse_count=1,
  pulse_interval_seconds=0.0,
  duration_us=1000,
)

Prepare a temporary run#

prepare_temporary_protocol writes a temporary !PLR_... user protocol, opens it on the Gemini touchscreen, sets plate-handler columns when requested, and leaves the device on the run screen.

When using the HT-200 plate handler, first record its configured pulse count and column adjustment. plate_columns also requires an explicit plate_handler_reset_state. Use reset_confirmed only after manually returning the handler to column 1; use continue_current_position only when intentionally continuing from the current handler position.

gemini.plate_handler.configure_manual_state(pulse_count=1, column_adjust=0)

prepared = await gemini.prepare_temporary_protocol(
  protocol=protocol,
  plate_columns=3,
  plate_handler_reset_state="reset_confirmed",
)
prepared.protocol_name

The prepared run can be serialized and passed to a later process. The serialized payload includes the temporary protocol name and baseline log listing used to match the new BTXDATA log after GO.

prepared_payload = prepared.as_dict()
prepared_payload["protocol_name"]

Start the prepared run#

The next cell presses GO on the prepared run screen and delivers the configured pulse. Confirm that the plate, electrodes, samples, safety cover, and plate-handler state are correct before running it.

result = await gemini.start_prepared_run(
  prepared_run=prepared,
  home_after=True,
)
result.log_capture.summary

Cancel before pulse delivery#

If a run has been prepared but should not be started, cancel it. This returns the Gemini to a safe screen and deletes the temporary protocol.

# cancelled = await gemini.cancel_prepared_run(prepared)
# cancelled.cleanup.deleted

Teardown#

await gemini.stop()