メインコンテンツへスキップ
Ionworks Studio へのデータアップロードは、3 段階の階層に従います: セル仕様(セルの設計図)を作成し、セルインスタンス(特定の物理セル)を作成し、そのインスタンスに対する測定をアップロードします。 インストールと認証については Python API クライアント ページを参照してください。データを読み取るには データの読み取り を参照してください。

アップロードワークフロー

1

セル仕様を作成または取得する

仕様はセルの材料、電気的定格、構成要素を定義します。
2

セルインスタンスを作成または取得する

仕様にリンクされた特定の物理セルです。
3

測定をアップロードする

時系列、プロパティ、ファイル測定をインスタンスに添付します。

ステップ 1: セル仕様を作成または取得する

cell_spec = client.cell_spec.create_or_get(
    {
        "name": "NCM622/Graphite Coin Cell",
        "form_factor": "R2032",
        "manufacturer": "Custom Cells",
        "ratings": {
            "capacity": {"value": 0.002, "unit": "A*h"},
            "voltage_min": {"value": 2.5, "unit": "V"},
            "voltage_max": {"value": 4.2, "unit": "V"},
        },
        "cathode": {
            "properties": {"loading": {"value": 12.3, "unit": "mg/cm**2"}},
            "material": {"name": "NCM622", "manufacturer": "BASF"},
        },
        "anode": {
            "properties": {"loading": {"value": 6.5, "unit": "mg/cm**2"}},
            "material": {"name": "Graphite", "manufacturer": "Customcells"},
        },
    }
)
セル仕様フィールドの全セットはセルを参照してください。

ステップ 2: セルインスタンスを作成または取得する

cell_instance = client.cell_instance.create_or_get(
    cell_spec.id,
    {
        "name": "NCM622-GR-001",
        "batch": "BATCH-2024-001",
        "date_manufactured": "2024-01-20",
        "measured_properties": {
            "cathode": {"loading": {"value": 12.1, "unit": "mg/cm**2"}},
            "anode": {"loading": {"value": 6.4, "unit": "mg/cm**2"}},
        },
    },
)
セルインスタンスのフィールド:
フィールド説明
nameこのセルの一意の識別子
batchバッチまたはロット番号
date_manufactured製造日(任意)
measured_properties仕様と異なるこのセル固有の測定値(実測容量、電極ローディングなど)

ステップ 3: 時系列付きで測定をアップロードする

import pandas as pd

time_series = pd.DataFrame(
    {
        "Time [s]": [0, 1, 2, 3, 4, 5],
        "Voltage [V]": [3.0, 3.2, 3.5, 3.8, 4.0, 4.2],
        "Current [A]": [-0.002, -0.002, -0.002, -0.002, -0.002, -0.002],
        "Step count": [0, 0, 0, 1, 1, 1],
        "Cycle count": [0, 0, 0, 0, 0, 0],
        "Step from cycler": [1, 1, 1, 2, 2, 2],
        "Cycle from cycler": [0, 0, 0, 0, 0, 0],
    }
)

measurement_data = {
    "measurement": {
        "name": "Formation Cycle 1",
        "protocol": {
            "name": "CC-CV charge at C/10 to 4.2V",
            "ambient_temperature_degc": 25,
        },
        "test_setup": {
            "cycler": "Biologic VMP3",
            "operator": "Jane Smith",
        },
        "notes": "Formation cycle - first charge",
    },
    "time_series": time_series,
}

bundle = client.cell_measurement.create(cell_instance.id, measurement_data)

print(f"Created measurement: {bundle.measurement.name}")
print(f"Steps created: {bundle.steps_created}")
プロパティ および ファイル 測定タイプ(およびそれらが受け入れるフィールド)については測定を参照してください。

アップロード検証

データが Ionworks Studio に送信される前に、Python クライアントはマシン上で時系列を検証します。常時オンのチェックは、最も一般的な処理ミスをキャッチします:
  • 正の電流が放電(電圧低下)に対応している。充電は負の電流を使用する。
  • 時間が 0 から始まり、単調非減少である。
  • Step count が存在し、0 から始まり、1 ずつ増加する。
  • 累積列(容量、エネルギー)が各ステップの先頭でリセットされる。
これらのいずれかが失敗すると、createcreate_or_getMeasurementValidationError を発生させ、アップロードは開始されません。それぞれの失敗を修正する方法は下記のトラブルシューティングを参照してください。

検証失敗の確認

MeasurementValidationError.errorsValidationIssue レコードのリストです。各 issue は安定した codeIssueCode 列挙)、severity"error" または "warning")、人間可読の message、ステップインデックス、列名、観測値、閾値などの詳細を含む構造化された payload 辞書を持ちます。 message を解析するのではなく code で分岐します。文言はリリース間で変わる可能性がありますが、チェック識別子は安定しています。
from ionworks import IssueCode, MeasurementValidationError

try:
    client.cell_measurement.create(cell_instance.id, measurement_data)
except MeasurementValidationError as e:
    for issue in e.errors:
        print(f"[{issue.severity}] {issue.code}: {issue.message}")
        print("  details:", issue.payload)

    if e.has_code(IssueCode.CURRENT_SIGN_REVERSED):
        # Auto-fixable: positive current was charge, not discharge.
        # Use ionworksdata.transform.set_positive_current_for_discharge(df)
        # before re-uploading.
        ...

厳格な検証

すべてのアップロードで validate_strict=True を渡すことをお勧めします。 厳格チェックは、データ処理中に発生した微妙なバグ(例えば、記録されていない大きな時間ギャップ、誤った groupbypartition_by 呼び出しで行が並び替えられた時系列など)を、データが Ionworks Studio に到達して下流のシミュレーションやフィットを汚染する前にキャッチします。
bundle = client.cell_measurement.create(
    cell_instance.id,
    measurement_data,
    validate_strict=True,
)
厳格モードは常時オンのものに加えて以下のチェックを追加します:
  • 各ステップに少なくとも 2 つのデータポイントが含まれる
  • Cycle count が各ステップ内で一定である
  • 連続する時間サンプル間のギャップが 5 時間を超えない
  • 連続する行間で電圧が連続している(voltage_window が必要)
  • 同じ方向の連続ステップ 2 つが満充電または満放電を行わない(rated_capacitymeasurement_detailsteps データフレームが必要)
  • 単一ステップが定格容量の 500 % を超えない — 発生時にエラーではなく UserWarning を発する(rated_capacitysteps が必要)
  • 報告される累積容量・エネルギー列が、電流(および電力)の台形積分とすべての行で 10 % 以内で一致する — 常時オンチェックを通過してしまうラベル付け誤り Discharge/Charge、欠落サンプル、符号規約のバグをキャッチします

より豊富なチェックのためにセルコンテキストを提供する

電圧連続性チェックとステップ容量チェックには、セルの定格電圧ウィンドウと容量が必要です。キーワード引数として渡します:
bundle = client.cell_measurement.create(
    cell_instance.id,
    measurement_data,
    validate_strict=True,
    rated_capacity=0.002,           # A.h — nominal capacity of the cell
    voltage_window=(2.5, 4.2),      # (V_min, V_max) from the cell spec
)
すでにセル仕様オブジェクトを持っている場合は、これらの値を直接読み取れます:
ratings = cell_spec.ratings
rated_capacity = ratings["capacity"]["value"]
voltage_window = (
    ratings["voltage_min"]["value"],
    ratings["voltage_max"]["value"],
)
両方の引数は任意です。voltage_window を省略すると電圧連続性チェックのみがスキップされます。rated_capacity を省略すると連続フルステップとステップごとの容量チェックのみがスキップされます。その他の厳格モードチェックはすべて実行されます。
連続フルステップとステップごとの容量チェックには、measurement_detailsteps キーの下に事前計算されたステップサマリーも必要です。提供しない場合、Ionworks Studio はアップロード後にサーバー側でステップサマリーを生成しますが、これら 2 つのクライアント側チェックはスキップされます。
create_or_get も同じ rated_capacityvoltage_window 引数を受け入れ、create に転送します。

厳格チェックを 1 つだけ緩和する

特定の厳格チェックがデータセットで既知の偽陽性である場合(例えば、5 時間の時間ギャップ閾値を超える正当な数日間の休止期間など)、厳格モードを完全に無効にするのではなく、skip_checksそのチェックのみ を緩和してください。これによりその他のすべてのガードレールは維持されます(最小権限の検証)。
bundle = client.cell_measurement.create(
    cell_instance.id,
    measurement_data,
    validate_strict=True,
    skip_checks={"time_gaps"},  # everything else still enforced
)
有効な名前(ionworks.validators.STRICT_CHECK_NAMES としても公開されています):
  • minimum_points_per_step
  • cycle_constant_within_step
  • time_gaps
  • voltage_continuity
  • consecutive_same_direction_full_steps
  • step_capacity_within_rated
  • capacity_energy_from_current_power
未知の名前は ValueError を発生させます。複数のチェックに同時に該当する文書化された理由がない限り、厳格モードを一括で無効にしないでください。

create_or_get による冪等なアップロード

3 つの create メソッドにはすべて create_or_get バリアントがあり、アップロードスクリプトを安全に再実行可能にします。同じ名前のリソースがすでに存在する場合、クライアントはエラーを発生させずに取得して返します。
# cell_spec: data only
spec = client.cell_spec.create_or_get(data)

# cell_instance: requires cell_spec_id
instance = client.cell_instance.create_or_get(cell_spec_id, data)

# cell_measurement: requires cell_instance_id
measurement = client.cell_measurement.create_or_get(cell_instance_id, data)

重複の処理

create_or_get ではなく create() を呼び出して同じ名前のリソースがすでに存在する場合、API は detail フィールドに既存リソースの ID を含めて 409 Conflict を返します:
{
  "error_code": "CONFLICT",
  "message": "Cell specification with this name already exists",
  "detail": {
    "resource_type": "cell_specification",
    "resource_name": "My Cell Spec",
    "existing_id": "abc-123"
  }
}
existing_id を使うと、独自の create-or-get ロジックを実装したい場合に別途ルックアップせずに既存レコードを取得できます。

インライン時系列のサイズ制限

インラインで渡される時系列(例: パイプライン設定内)は 1,000 行 で上限が設定されています。それより大きなデータセットは、まず測定としてアップロードする必要があります。エラークラス、回避策、db:<measurement_id> 参照形式についてはデータの読み取り — インラインサイズ制限を参照してください。

自動ペイロード圧縮

Python クライアントは、API に送信する前に 512 KB を超えるリクエストペイロードを gzip で自動的に圧縮します。これは透過的に行われ、設定は不要です。大きなシリアライズされたモデルやデータセットでは、アップロードサイズを大幅に削減できます。

トラブルシューティング

連続する行間で大きな時間ギャップがある

問題: validate_strict=True でアップロードする際に、次のようなエラーが発生する:
Time gap of 6.12 h between rows 4201 and 4202 exceeds the maximum allowed gap of 5.0 h.
解決策: 連続する 2 つの時間サンプル間で 5 時間を超えるギャップは、ほぼ常に処理中に行が削除されたことを意味します。例えば、長い休止期間がファイル内の経過時間として記録されていたが、中間の行が削除された場合などです。その後、容量積分が欠落区間を電流が流れたかのように計算してしまい、過大な値が報告されます。 フィルタリングなしで生のサイクラーファイルを再度読み込み、時間軸が連続していることを確認してください。ワークフローで意図的にデータを間引く場合は、セクション全体を削除するのではなく一様にダウンサンプリングするか、ギャップで記録を別々の測定に分割してください。

電圧連続性チェックの失敗

問題: validate_strict=Truevoltage_window を指定してアップロードする際に、次のようなエラーが発生する:
Voltage continuity check failed: 318/3599 (8.8%) of consecutive row pairs have a voltage jump greater than 80% of the rated voltage window.
解決策: Ionworks はすべての連続する行ペア間の絶対電圧変化を確認します。ペアの 5 % 超が定格電圧ウィンドウ(V_max - V_min)の 80 % を超える場合、時系列はほぼ確実に時系列順になっていません。典型的には、partition_by("Cycle_raw") のようなグループ化操作によって異なるサイクルのパルス行と休止行がインターリーブされていることが原因です。 アップロード前に DataFrame を Time [s] でソートし、自然な行順序を破る変換を避けてください:
import polars as pl

time_series = time_series.sort("Time [s]")

同方向の連続フル容量ステップ

問題: validate_strict=Truesteps データフレーム、rated_capacity を指定してアップロードする際に、次のようなエラーが発生する:
Consecutive full-capacity discharge steps detected: step 12 and step 15 each delivered more than 200% of the rated capacity.
解決策: ここでの「連続」とは、シーケンス内で最も近い同方向のステップ 2 つを意味します。つまり、ステップ 12 と 15 の間に充電ステップがあっても連続する放電です。単一の測定は単一のセルでの 1 つの連続したテストを表すべきなので、背中合わせの 2 つのフル容量放電(または充電)は、ファイルが複数の独立した実験を結合して組み立てられたことを意味することが多いです(例: 異なる C レートでの複数の CC 放電を縫い合わせたもの)。ソースデータをアップロード前に別々の測定に分割し直してください。
正当に長い単一の実験に 3 つ以上のフル充電または放電が連続して含まれる場合(まれですが可能性はあります)、measurement_detail から事前計算された steps エントリを削除するか rated_capacity を省略してこの特定のチェックをスキップし、Ionworks Studio がサーバー側でステップサマリーを再生成するようにします。

ステップ容量が定格容量を超える

問題: validate_strict=Truesteps データフレーム、rated_capacity を指定してアップロードする際に、次のような UserWarning が発生する:
3 step(s) exceed 500% of the rated capacity. First: step 47 has ‘Discharge capacity [A.h]’ = 0.031 A.h.
解決策: これはソフトな警告です(アップロードは続行されます)が、ステップ境界に問題があるか、記録されていない時間ギャップにわたって容量積分が膨張している可能性を示しています。フラグの立ったステップを確認し、それが単一の充電または放電を表していることを確認し、Step count 列のギャップを再確認してください。基本的な時間ギャップやステップ境界の問題を修正すると、通常は警告が消えます。

容量・エネルギー列が電流・電力積分と一致しない

問題: validate_strict=True でアップロードする際に、次のようなエラーが発生する:
Column ‘Discharge capacity [A.h]’ disagrees with the running integral of ‘max(I, 0)’ over time by up to 47.3% (exceeds 10% tolerance). Worst row 8421: reported = 0.0019 A.h, integrated = 0.0010 A.h.
このチェックは、報告される各累積列を、プラットフォームが累積列を報告する方法を反映したステップごとのリセットを含む、時間に対する電流(容量)または電力(エネルギー)の台形積分と比較します。Ionworks の符号規約(正の電流 = 放電)では:
  • Discharge capacity [A.h]∫ max(I, 0) dt / 3600
  • Charge capacity [A.h]∫ max(-I, 0) dt / 3600
  • Discharge energy [W.h]∫ max(P, 0) dt / 3600
  • Charge energy [W.h]∫ max(-P, 0) dt / 3600
電力は Power [W] が存在すればそれを使用し、それ以外の場合は Voltage [V] * Current [A] として計算されます。対応する issue コードは DISCHARGE_CAPACITY_INTEGRAL_MISMATCHCHARGE_CAPACITY_INTEGRAL_MISMATCHDISCHARGE_ENERGY_INTEGRAL_MISMATCHCHARGE_ENERGY_INTEGRAL_MISMATCH です。各 issue の payload には、最悪の行インデックス、その行での報告値と積分値、最大累積スケール、相対誤差が含まれます。 解決策: 不一致は通常、次の 3 つの原因のいずれかに起因します:
  1. Discharge / Charge ラベルの入れ替わり — ハーフセル出力や一部のサイクラー設定でよく発生します。放電列と充電列の両方が同程度の量だけ失敗し、それらの値が「入れ替わって見える」場合、自動修正変換を使用します:
    import ionworksdata as iwd
    
    # Confirm positive current = discharge first, then fix labels
    data = iwd.transform.set_positive_current_for_discharge(data)
    data = iwd.transform.fix_swapped_charge_discharge_columns(data)
    
  2. 符号規約の誤りCURRENT_SIGN_REVERSED も発生する場合は、まず set_positive_current_for_discharge で修正して再度検証してください。
  3. 信頼できないソース列 — それらを削除し、iwd.transform.set_capacity / set_energyCurrent [A]Voltage [V]Time [s] から累積列を再計算させます:
    data = data.drop(
        "Discharge capacity [A.h]",
        "Charge capacity [A.h]",
        "Discharge energy [W.h]",
        "Charge energy [W.h]",
        strict=False,
    )
    data = iwd.transform.set_capacity(data)
    data = iwd.transform.set_energy(data)
    
不一致がデータセットの既知の特性であり、下流解析に影響しないことを確認した場合は、skip_checks={"capacity_energy_from_current_power"} でこのチェックだけを緩和してください。

次のステップ

測定

3 つの測定タイプ — 時系列、プロパティ、ファイル — の詳細。

データの読み取り

測定データを一覧、フィルタリング、ページング、取得します。

データの準備

アップロード前にサイクラーファイルを Ionworks フォーマットに読み込みます。

データフォーマット

認識される列、数量フォーマット、符号規約。