mcpField
O
opentrons-integration

opentrons-integration

github.com/jackspaceその他1635 回インストール12 週間前に更新
リポジトリ

opentrons-integration について

opentrons-integrationは、Opentrons FlexおよびOT-2のラボ自動化ロボット向けにPythonプロトコルを作成するスキルです。液体処理、ラボウェアやモジュールの制御、一般的な分注ワークフロー、実行前のシミュレーションを扱います。

主な機能

  1. 01Protocol API v2プロトコルの作成
  2. 02ピペット、ラボウェア、デッキ配置の設定
  3. 03液体処理操作の自動化
  4. 04温度、磁気などのモジュール制御
  5. 05ロボット実行前のプロトコルシミュレーション

活用シーン

  1. 01段階希釈プロトコルの作成
  2. 02PCRワークフローの構築
  3. 03プレート間のサンプル複製
  4. 04シミュレーションによる分注プロトコルのテスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jackspace/claudeskillz --skill opentrons-integration

インストール後、Claude Code で/opentrons-integrationを入力して読み込まれたか確認します。

同梱ファイルSKILL.json

詳細

Opentrons 連携

概要

Opentrons は、Flex および OT-2 ロボット向けの Python ベースのラボオートメーションプラットフォームです。Protocol API v2 でプロトコルを作成し、液体ハンドリング、ハードウェアモジュール(ヒーターシェイカー、サーマルサイクラー)の制御、ラボware の管理を行い、自動ピペッティングワークフローを実現できます。

このスキルの使用場面

このスキルは次の場合に使用してください:

  • Python で Opentrons Protocol API v2 のプロトコルを作成する場合
  • Flex または OT-2 ロボットで液体ハンドリングのワークフローを自動化する場合
  • ハードウェアモジュール(温度、磁気、ヒーターシェイカー、サーマルサイクラー)を制御する場合
  • ラボウェアの構成とデッキレイアウトを設定する場合
  • 複雑なピペッティング操作(段階希釈、プレート複製、PCR セットアップ)を実装する場合
  • チップの使用を管理し、プロトコルの効率を最適化する場合
  • 96 ウェルプレートの操作に多チャンネルピペットを使用する場合
  • ロボットでの実行前にプロトコルをシミュレーションしてテストする場合

主な機能

1. プロトコルの構造とメタデータ

すべての Opentrons プロトコルは、次の標準的な構造に従います:

from opentrons import protocol_api

# Metadata
metadata = {
    'protocolName': 'My Protocol',
    'author': 'Name <[email protected]>',
    'description': 'Protocol description',
    'apiLevel': '2.19'  # Use latest available API version
}

# Requirements (optional)
requirements = {
    'robotType': 'Flex',  # or 'OT-2'
    'apiLevel': '2.19'
}

# Run function
def run(protocol: protocol_api.ProtocolContext):
    # Protocol commands go here
    pass

主な要素:

  • opentrons から protocol_api をインポートする
  • protocolName、author、description、apiLevel を含む metadata 辞書を定義する
  • ロボットの種類と API バージョンを指定する、任意の requirements 辞書
  • ProtocolContext を引数に受け取る run() 関数を実装する
  • プロトコルのすべてのロジックは run() 関数の内部に記述する
2. ハードウェアの読み込み

機器(ピペット)の読み込み:

def run(protocol: protocol_api.ProtocolContext):
    # Load pipette on specific mount
    left_pipette = protocol.load_instrument(
        'p1000_single_flex',  # Instrument name
        'left',               # Mount: 'left' or 'right'
        tip_racks=[tip_rack]  # List of tip rack labware objects
    )

一般的なピペット名:

  • Flex: p50_single_flex、p1000_single_flex、p50_multi_flex、p1000_multi_flex
  • OT-2: p20_single_gen2、p300_single_gen2、p1000_single_gen2、p20_multi_gen2、p300_multi_gen2

ラボウェアの読み込み:

# Load labware directly on deck
plate = protocol.load_labware(
    'corning_96_wellplate_360ul_flat',  # Labware API name
    'D1',                                # Deck slot (Flex: A1-D3, OT-2: 1-11)
    label='Sample Plate'                 # Optional display label
)

# Load tip rack
tip_rack = protocol.load_labware('opentrons_flex_96_tiprack_1000ul', 'C1')

# Load labware on adapter
adapter = protocol.load_adapter('opentrons_flex_96_tiprack_adapter', 'B1')
tips = adapter.load_labware('opentrons_flex_96_tiprack_200ul')

モジュールの読み込み:

# Temperature module
temp_module = protocol.load_module('temperature module gen2', 'D3')
temp_plate = temp_module.load_labware('corning_96_wellplate_360ul_flat')

# Magnetic module
mag_module = protocol.load_module('magnetic module gen2', 'C2')
mag_plate = mag_module.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')

# Heater-Shaker module
hs_module = protocol.load_module('heaterShakerModuleV1', 'D1')
hs_plate = hs_module.load_labware('corning_96_wellplate_360ul_flat')

# Thermocycler module (takes up specific slots automatically)
tc_module = protocol.load_module('thermocyclerModuleV2')
tc_plate = tc_module.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')
3. 液体ハンドリング操作

基本操作:

# Pick up tip
pipette.pick_up_tip()

# Aspirate (draw liquid in)
pipette.aspirate(
    volume=100,           # Volume in µL
    location=source['A1'] # Well or location object
)

# Dispense (expel liquid)
pipette.dispense(
    volume=100,
    location=dest['B1']
)

# Drop tip
pipette.drop_tip()

# Return tip to rack
pipette.return_tip()

複合操作:

# Transfer (combines pick_up, aspirate, dispense, drop_tip)
pipette.transfer(
    volume=100,
    source=source_plate['A1'],
    dest=dest_plate['B1'],
    new_tip='always'  # 'always', 'once', or 'never'
)

# Distribute (one source to multiple destinations)
pipette.distribute(
    volume=50,
    source=reservoir['A1'],
    dest=[plate['A1'], plate['A2'], plate['A3']],
    new_tip='once'
)

# Consolidate (multiple sources to one destination)
pipette.consolidate(
    volume=50,
    source=[plate['A1'], plate['A2'], plate['A3']],
    dest=reservoir['A1'],
    new_tip='once'
)

応用テクニック:

# Mix (aspirate and dispense in same location)
pipette.mix(
    repetitions=3,
    volume=50,
    location=plate['A1']
)

# Air gap (prevent dripping)
pipette.aspirate(100, source['A1'])
pipette.air_gap(20)  # 20µL air gap
pipette.dispense(120, dest['A1'])

# Blow out (expel remaining liquid)
pipette.blow_out(location=dest['A1'].top())

# Touch tip (remove droplets on tip exterior)
pipette.touch_tip(location=plate['A1'])

流量制御:

# Set flow rates (µL/s)
pipette.flow_rate.aspirate = 150
pipette.flow_rate.dispense = 300
pipette.flow_rate.blow_out = 400
4. ウェルとロケーションへのアクセス

ウェルへのアクセス方法:

# By name
well_a1 = plate['A1']

# By index
first_well = plate.wells()[0]

# All wells
all_wells = plate.wells()  # Returns list

# By rows
rows = plate.rows()  # Returns list of lists
row_a = plate.rows()[0]  # All wells in row A

# By columns
columns = plate.columns()  # Returns list of lists
column_1 = plate.columns()[0]  # All wells in column 1

# Wells by name (dictionary)
wells_dict = plate.wells_by_name()  # {'A1': Well, 'A2': Well, ...}

ロケーションメソッド:

# Top of well (default: 1mm below top)
pipette.aspirate(100, well.top())
pipette.aspirate(100, well.top(z=5))  # 5mm above top

# Bottom of well (default: 1mm above bottom)
pipette.aspirate(100, well.bottom())
pipette.aspirate(100, well.bottom(z=2))  # 2mm above bottom

# Center of well
pipette.aspirate(100, well.center())
5. ハードウェアモジュールの制御

温度モジュール:

# Set temperature
temp_module.set_temperature(celsius=4)

# Wait for temperature
temp_module.await_temperature(celsius=4)

# Deactivate
temp_module.deactivate()

# Check status
current_temp = temp_module.temperature  # Current temperature
target_temp = temp_module.target  # Target temperature

磁気モジュール:

# Engage (raise magnets)
mag_module.engage(height_from_base=10)  # mm from labware base

# Disengage (lower magnets)
mag_module.disengage()

# Check status
is_engaged = mag_module.status  # 'engaged' or 'disengaged'

ヒーターシェイカーモジュール:

# Set temperature
hs_module.set_target_temperature(celsius=37)

# Wait for temperature
hs_module.wait_for_temperature()

# Set shake speed
hs_module.set_and_wait_for_shake_speed(rpm=500)

# Close labware latch
hs_module.close_labware_latch()

# Open labware latch
hs_module.open_labware_latch()

# Deactivate heater
hs_module.deactivate_heater()

# Deactivate shaker
hs_module.deactivate_shaker()

サーマルサイクラーモジュール:

# Open lid
tc_module.open_lid()

# Close lid
tc_module.close_lid()

# Set lid temperature
tc_module.set_lid_temperature(celsius=105)

# Set block temperature
tc_module.set_block_temperature(
    temperature=95,
    hold_time_seconds=30,
    hold_time_minutes=0.5,
    block_max_volume=50  # µL per well
)

# Execute profile (PCR cycling)
profile = [
    {'temperature': 95, 'hold_time_seconds': 30},
    {'temperature': 57, 'hold_time_seconds': 30},
    {'temperature': 72, 'hold_time_seconds': 60}
]
tc_module.execute_profile(
    steps=profile,
    repetitions=30,
    block_max_volume=50
)

# Deactivate
tc_module.deactivate_lid()
tc_module.deactivate_block()

吸光度プレートリーダー:

# Initialize and read
result = plate_reader.read(wavelengths=[450, 650])

# Access readings
absorbance_data = result  # Dict with wavelength keys
6. 液体の追跡とラベリング

液体の定義:

# Define liquid types
water = protocol.define_liquid(
    name='Water',
    description='Ultrapure water',
    display_color='#0000FF'  # Hex color code
)

sample = protocol.define_liquid(
    name='Sample',
    description='Cell lysate sample',
    display_color='#FF0000'
)

ウェルへの液体の充填:

# Load liquid into specific wells
reservoir['A1'].load_liquid(liquid=water, volume=50000)  # µL
plate['A1'].load_liquid(liquid=sample, volume=100)

# Mark wells as empty
plate['B1'].load_empty()
7. プロトコルの制御とユーティリティ

実行制御:

# Pause protocol
protocol.pause(msg='Replace tip box and resume')

# Delay
protocol.delay(seconds=60)
protocol.delay(minutes=5)

# Comment (appears in logs)
protocol.comment('Starting serial dilution')

# Home robot
protocol.home()

条件分岐:

# Check if simulating
if protocol.is_simulating():
    protocol.comment('Running in simulation mode')
else:
    protocol.comment('Running on actual robot')

レールライト(Flex のみ):

# Turn lights on
protocol.set_rail_lights(on=True)

# Turn lights off
protocol.set_rail_lights(on=False)
8. 多チャンネルおよび 8 チャンネルのピペッティング

多チャンネルピペットを使用する場合:

# Load 8-channel pipette
multi_pipette = protocol.load_instrument(
    'p300_multi_gen2',
    'left',
    tip_racks=[tips]
)

# Access entire column with single well reference
multi_pipette.transfer(
    volume=100,
    source=source_plate['A1'],  # Accesses entire column 1
    dest=dest_plate['A1']       # Dispenses to entire column 1
)

# Use rows() for row-wise operations
for row in plate.rows():
    multi_pipette.transfer(100, reservoir['A1'], row[0])
9. 一般的なプロトコルのパターン

段階希釈:

def run(protocol: protocol_api.ProtocolContext):
    # Load labware
    tips = protocol.load_labware('opentrons_flex_96_tiprack_200ul', 'D1')
    reservoir = protocol.load_labware('nest_12_reservoir_15ml', 'D2')
    plate = protocol.load_labware('corning_96_wellplate_360ul_flat', 'D3')

    # Load pipette
    p300 = protocol.load_instrument('p300_single_flex', 'left', tip_racks=[tips])

    # Add diluent to all wells except first
    p300.transfer(100, reservoir['A1'], plate.rows()[0][1:])

    # Serial dilution across row
    p300.transfer(
        100,
        plate.rows()[0][:11],  # Source: wells 0-10
        plate.rows()[0][1:],   # Dest: wells 1-11
        mix_after=(3, 50),     # Mix 3x with 50µL after dispense
        new_tip='always'
    )

プレート複製:

def run(protocol: protocol_api.ProtocolContext):
    # Load labware
    tips = protocol.load_labware('opentrons_flex_96_tiprack_1000ul', 'C1')
    source = protocol.load_labware('corning_96_wellplate_360ul_flat', 'D1')
    dest = protocol.load_labware('corning_96_wellplate_360ul_flat', 'D2')

    # Load pipette
    p1000 = protocol.load_instrument('p1000_single_flex', 'left', tip_racks=[tips])

    # Transfer from all wells in source to dest
    p1000.transfer(
        100,
        source.wells(),
        dest.wells(),
        new_tip='always'
    )

PCR セットアップ:

def run(protocol: protocol_api.ProtocolContext):
    # Load thermocycler
    tc_mod = protocol.load_module('thermocyclerModuleV2')
    tc_plate = tc_mod.load_labware('nest_96_wellplate_100ul_pcr_full_skirt')

    # Load tips and reagents
    tips = protocol.load_labware('opentrons_flex_96_tiprack_200ul', 'C1')
    reagents = protocol.load_labware('opentrons_24_tuberack_nest_1.5ml_snapcap', 'D1')

    # Load pipette
    p300 = protocol.load_instrument('p300_single_flex', 'left', tip_racks=[tips])

    # Open thermocycler lid
    tc_mod.open_lid()

    # Distribute master mix
    p300.distribute(
        20,
        reagents['A1'],
        tc_plate.wells(),
        new_tip='once'
    )

    # Add samples (example for first 8 wells)
    for i, well in enumerate(tc_plate.wells()[:8]):
        p300.transfer(5, reagents.wells()[i+1], well, new_tip='always')

    # Run PCR
    tc_mod.close_lid()
    tc_mod.set_lid_temperature(105)

    # PCR profile
    tc_mod.set_block_temperature(95, hold_time_seconds=180)

    profile = [
        {'temperature': 95, 'hold_time_seconds': 15},
        {'temperature': 60, 'hold_time_seconds': 30},
        {'temperature': 72, 'hold_time_seconds': 30}
    ]
    tc_mod.execute_profile(steps=profile, repetitions=35, block_max_volume=25)

    tc_mod.set_block_temperature(72, hold_time_minutes=5)
    tc_mod.set_block_temperature(4)

    tc_mod.deactivate_lid()
    tc_mod.open_lid()

ベストプラクティス

  1. API レベルを必ず指定する: メタデータには最新の安定版 API バージョンを使用する
  2. 分かりやすいラベルを使用する: ログで識別しやすいよう、ラボウェアにラベルを付ける
  3. チップの残量を確認する: プロトコルを完了させるのに十分なチップがあることを確認する
  4. コメントを追加する: デバッグとログ記録のために protocol.comment() を使用する
  5. 先にシミュレーションする: ロボットで実行する前に、必ずシミュレーションでプロトコルをテストする
  6. エラーを適切に処理する: 必要に応じて、手動介入のための一時停止を追加する
  7. タイミングを考慮する: プロトコルにインキュベーション時間が必要な場合は、遅延を使用する
  8. 液体を追跡する: セットアップの検証を向上させるため、液体の追跡を使用する
  9. チップの使用を最適化する: 適切な場合は new_tip='once' を使用し、チップを節約する
  10. 流量を制御する: 粘性の高い液体や揮発性の液体に合わせて流量を調整する

トラブルシューティング

よくある問題:

  • チップ切れ: チップラックの容量がプロトコルの要件に合っているか確認する
  • ラボウェアの衝突: デッキレイアウトに空間的な競合がないか確認する
  • 体積エラー: 体積がウェルやピペットの容量を超えていないことを確認する
  • モジュールが応答しない: モジュールが正しく接続されており、ファームウェアが更新されているか確認する
  • 体積が不正確: ピペットを校正し、気泡がないか確認する
  • シミュレーションでプロトコルが失敗する: API バージョンの互換性とラボウェア定義を確認する

リソース

詳細な API ドキュメントについては、このスキルディレクトリ内の references/api_reference.md を参照してください。

プロトコルのテンプレート例については、scripts/ ディレクトリを参照してください。

コメント