> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ionworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ECM パラメータ化

> 実験的なサイクリングデータから等価回路モデルの OCV、R0、RC ペアパラメータをブラウザ内でフィットします

**ECM パラメータ化**ツールは、実験的なバッテリー充放電データに対して等価回路モデル（ECM）をブラウザ上で直接フィッティングします。すでに[プロジェクト](/ja/core-concepts/projects-studies)にアップロードした測定データをフィッティングしたり、自分のファイルをアップロードしたり、組み込みのサンプルデータセットを使用したりして、セル容量、および SOC の関数としての OCV、R0、RC ペアパラメータを抽出できます。

ツールを起動する方法は 2 つあります:

* **プロジェクト内** — プロジェクトサイドバーから **ECM Fitting** ページを開きます。プロジェクトのセルのいずれかにすでに添付されている測定を選択でき、結果はプロジェクトに保存されます。
* **スタンドアロンデモ** — [studio.ionworks.com/ecm-demo](https://studio.ionworks.com/ecm-demo) に直接アクセスします。ログインは不要で、何も保存せずに例データセットを試したり、一時的なファイルをアップロードしたりできます。

## 仕組み

このツールは、開回路電圧（OCV）源、直列抵抗（R0）、および1つ以上の RC ペアで構成される回路を時系列の電圧・電流データにフィッティングします。フィッティングプロセスにより、SOC の滑らかな関数としてパラメータが抽出されると同時に、フィッティングされた OCV(SOC) 曲線を制約として、セルの実用容量を RC パラメータと共最適化します。

回路構造は次のようになります:

```
  ┌───[ R0 ]───┬───[ R_rc1 ]───┬───[ R_rc2 ]───┐
  │             │               │               │
 OCV         [ C_rc1 ]       [ C_rc2 ]         V_terminal
  │             │               │               │
  └─────────────┴───────────────┴───────────────┘
```

各 RC ペアは動的分極挙動の異なる時間スケールを捉えます。RC ペアが多いほど精度の高いフィットが得られますが、モデルの複雑さも増します。

### 容量の共最適化

充放電データは、必ずしもセルの正確な実用容量を反映しているとは限りません。測定は様々な温度、Cレート、経年状態で行われ、想定容量に小さな誤差があると、その後に続くすべての SOC 依存パラメータにバイアスが生じます。これを避けるため、フィッティングでは OCV(SOC) 曲線を自己整合性の制約として、セル容量を RC パラメータと同時に最適化します。各時刻の SOC は積算電流をフィッティングされた容量で除算して計算され、その SOC における OCV はデータの休止電圧セグメントと一致しなければなりません。

フィッティングされた容量はフィット結果のレスポンスに含まれるため、セル容量を別途見積もることなく[パラメータ化モデル](/ja/build/parameterized-models)の構築に直接利用できます。

## プロジェクト内で測定をフィッティング

特定の[プロジェクト](/ja/core-concepts/projects-studies)と[セル](/ja/core-concepts/cells)にフィットを関連付け、すでに[アップロード済み](/ja/data/uploading)の測定を使用したい場合、このワークフローを使用します。

<Steps>
  <Step title="プロジェクトから ECM Fitting を開く">
    プロジェクトを開き、サイドバーで **ECM Fitting** をクリックします。ページには、プロジェクト内のセルと各セルに添付された測定が一覧表示されます。
  </Step>

  <Step title="1 つ以上の測定を選択する">
    フィットしたいセル測定を選択します。フィットを実行する前に正しいデータかどうかを確認できるように、電圧と電流トレースのプレビュープロットが表示されます（複数選択時は各測定のプロット）。

    電圧、電流、時間データを持つ `time_series` 測定のみフィットできます。プロパティおよびファイル型の測定はピッカーに表示されません。

    **複数の測定**を選択して、1 つの ECM として一括フィットすることもできます。各測定が動作範囲の異なる部分をカバーする場合（例えば、異なる SOC でのパルス列や異なるセルインスタンスからのデータ）に有用です。フィッターは各測定を 1 つのセグメントとして扱い、すべての測定にわたって SOC 依存パラメータの単一セットを共有します。
  </Step>

  <Step title="フィットを設定して実行する">
    [ツールの使用](#ツールの使用)に記載の通り、RC ペアの数 (0–5) を設定し、**Fit OCV** を切り替えます。

    2 つ以上の測定を選択した場合、設定カードで**測定ごとに初期 SOC (0–1)** を入力する必要があります。これにより、各セグメントが SOC 軸上のどこから始まるかをフィッターに伝え、セグメントを連結できるようにします。容量は、選択したすべての測定で共有される単一の値のままです（データから推定する場合は空欄のままにします）。単一の測定の場合、初期 SOC フィールドはオプションのままで、空欄の場合は自動的に推定されます。

    **Parameterize ECM** をクリックして開始します。
  </Step>

  <Step title="結果をプロジェクトに保存する">
    フィットが完了したら、結果を確認して **Save** をクリックし、フィットされたパラメータセットをプロジェクトのセルに添付します。保存されたフィットはセルの測定履歴に表示され、[パラメータ化モデルの作成](/ja/build/parameterized-models#新しいパラメータ化モデルの作成)時の出発点として使用できます。
  </Step>
</Steps>

## ツールの使用

[studio.ionworks.com/ecm-demo](https://studio.ionworks.com/ecm-demo) のスタンドアロンデモと、プロジェクト内のフィット設定ステップは同じコントロールを共有します。

<Steps>
  <Step title="データを選択する">
    組み込みの例データセットから選択するか、独自のサイクリングデータファイルをアップロードします。（プロジェクト内では、上記のように代わりにプロジェクトのセルの 1 つに添付された測定を選択します。）

    **組み込みの例** には、公開された文献のセル（Chen 2020、Ecker 2015、Prada 2013 など）やドライブサイクルプロファイル（UDDS、mixed current）が含まれます。各例は推奨される RC ペア数を示します。

    **アップロードしたファイル** は自動的に検出され解析されます。このツールは、CSV、Excel、BaSyTec、Maccor、Biologic などの一般的なサイクラー形式をサポートします。ファイルには時間、電圧、電流の列が含まれている必要があります。`Open-circuit voltage [V]` 列が存在する場合は、OCV をフィットする代わりに直接使用できます。
  </Step>

  <Step title="フィットを設定する">
    **RC ペア** の数 (0–5) を設定します。RC ペアが多いほど速いダイナミクスを捉えられますが、複雑さも増します。推奨値はデータに依存します — 例データセットには推奨数が表示されています。

    **Fit OCV** をオン/オフに切り替えます。データに測定済み OCV 列が含まれている場合、OCV フィッティングを無効にして提供された値を直接使用し、R0 と RC パラメータのみをフィットできます。
  </Step>

  <Step title="結果を表示する">
    フィット後、次が表示されます:

    * **モデル対データ**の電圧比較プロットと RMSE
    * **OCV(SOC)** および **R0(SOC)** のパラメータ曲線
    * 各 RC ペアの **R\_rc(SOC)**、**C\_rc(SOC)**、**τ\_rc(SOC)** 曲線

    OCV(SOC) 曲線から共最適化されたフィッティング済みセル容量は、フィット結果のレスポンスに含まれます。

    <Note>
      完全な RC ペアパラメータには、組織で ECM 結果アクセスが有効になっている必要があります。アクセスのリクエストは [info@ionworks.com](mailto:info@ionworks.com) までお問い合わせください。
    </Note>
  </Step>
</Steps>

## CSV として結果をダウンロード

フィットが完了したら、結果ヘッダーの **Download CSV** ボタンをクリックして、フィットされたパラメータをエクスポートします。

CSV には次の列を持つ 200 個の補間 SOC 点が含まれます:

| 列               | 説明            |
| --------------- | ------------- |
| `SOC`           | 充電状態 (0 から 1) |
| `OCV [V]`       | 開回路電圧         |
| `R0 [mOhm]`     | 直列抵抗（ミリオーム）   |
| `R_rc_N [mOhm]` | RC ペア N の抵抗   |
| `C_rc_N [F]`    | RC ペア N の容量   |
| `tau_N [s]`     | RC ペア N の時定数  |

フィットされた各 RC ペアの列はこのパターンに従います（例: `R_rc_1`、`R_rc_2`、…）。

<Note>
  RC ペア列は、組織で ECM 結果アクセスが有効になっている場合にのみ含まれます。それ以外の場合、CSV には SOC、OCV、R0 のみが含まれます。アクセスのリクエストは [info@ionworks.com](mailto:info@ionworks.com) までお問い合わせください。
</Note>

## データ要件

サイクリングデータには次が含まれている必要があります:

* **Time \[s]** — 秒単位の時間
* **Voltage \[V]** — 端子電圧
* **Current \[A]** — 印加電流

任意で **Open-circuit voltage \[V]** を含めると、OCV フィッティングをスキップして測定された OCV を直接使用できます。

<Tip>
  このツールは形式検出に [ionworksdata](https://data.docs.ionworks.com/) を使用するため、一般的なサイクラーからエクスポートされたデータは通常自動的に認識されます。
</Tip>

## Python からフィットする

UI で利用できるフィットと同じものを、[Python API クライアント](/ja/api-client)の `client.ecm` 経由でプログラムから送信できます。認証済みのフィットはプラットフォームのワーカーで**バックグラウンドジョブ**として実行されます — `fit_*` 呼び出しはジョブハンドルを返してすぐに戻り、`wait_for_completion` が結果が準備できるまでブロックします (通常 10–60 秒)。

サポートされる入力モードは 3 つあります:

| メソッド                                    | データソース           | 認証 | 戻り値               |
| --------------------------------------- | ---------------- | -- | ----------------- |
| `client.ecm.fit_from_example(...)`      | 組み込みのデモデータセット    | 任意 | `FitResults` (同期) |
| `client.ecm.fit_from_file(...)`         | ローカルファイルのアップロード  | 必須 | `EcmFitJob` (非同期) |
| `client.ecm.fit_from_measurements(...)` | プラットフォームに保存された測定 | 必須 | `EcmFitJob` (非同期) |

### 保存された測定からフィットする

```python theme={null}
from ionworks import Ionworks

client = Ionworks()

fit_job = client.ecm.fit_from_measurements({
    "measurements": [
        {"id": "meas-id-1"},
        {"id": "meas-id-2", "start_step": 5, "end_step": 50, "initial_soc": 0.95},
    ],
    "ecm_options": {
        "num_rcs": 2,       # 0–5 RC ペア (デフォルト 2)
        "fit_ocv": True,    # データに OCV 列がある場合は False に設定
    },
})

result = client.ecm.wait_for_completion(fit_job, timeout=300)
print(f"RMSE: {result.rmse_mV:.2f} mV")
```

`result` は `FitResults` モデルで、`time`、`data_voltage`、`model_voltage` のトレース、`soc` / `ocv` / `r0` のパラメータグリッド、各 RC ペアごとの `rc_pairs[i].r/.c/.tau` カーブを含みます。

### ローカルファイルからフィットする

CSV、parquet、および `ionworksdata` が検出できるすべてのサイクラー形式を受け付けます:

```python theme={null}
fit_job = client.ecm.fit_from_file(
    "data/pulse_test.csv",
    num_rcs=2,
    fit_ocv=True,
    initial_soc=0.95,   # 任意
    capacity=4.85,      # 任意、Ah 単位
)
result = client.ecm.wait_for_completion(fit_job)
```

フィット前にファイルをプレビューする (形式を自動検出してフィットを実行せずに時系列を取得する) には、`client.ecm.detect_and_read(file)` を呼び出します。

### セグメントごとの SOC シードを使った複数測定フィット

複数の測定を結合してフィットする場合、各セグメントが独自の `initial_soc` を保持できるため、フィッターは各セグメントを正しい充電状態から開始できます:

```python theme={null}
fit_job = client.ecm.fit_from_measurements({
    "measurements": [
        {"id": "meas-fully-charged",     "initial_soc": 1.00},
        {"id": "meas-partial-discharge", "initial_soc": 0.80},
    ],
    "ecm_options": {"num_rcs": 2, "capacity": 4.85},
})
```

`initial_soc` を省略し、`ecm_options` に `ocv_soc_curve` が提供されている場合、サービスはウォームアップフィット後に `V[s] = OCV(soc0) − I[s]·R0(soc0)` を反転することで `soc0` を自動シードします。カーブがない場合、単一測定の実行はクーロンカウントにフォールバックします。

### 測定ごとの容量

複数の測定がそれぞれ異なる既知容量のセルで記録されている場合(例: 異なる劣化度で取得された測定、あるいは結合フィットする物理的に別のセル)には、容量を各測定 dict に直接付与します:

```python theme={null}
fit_job = client.ecm.fit_from_measurements({
    "measurements": [
        {"id": "meas-fresh-cell", "initial_soc": 1.00, "capacity": 4.85},
        {"id": "meas-aged-cell",  "initial_soc": 1.00, "capacity": 4.50},
    ],
    "ecm_options": {"num_rcs": 2},
})
```

ルール:

* 測定ごとの `capacity` は\*\*全部か無しか(all-or-none)\*\*です — すべての測定に指定するか、どれにも指定しないかのいずれかです。混在した構成は送信時に拒否されます。
* 各容量は `> 0` (Ah) である必要があります。
* 測定ごとの容量が指定された場合、共有の `ecm_options.capacity` は無視されます。指定されない場合は共有の値がすべてのセグメントに適用されます(共有の値も省略されている場合は、容量が推定される、あるいは `bounds_capacity` に対してフィットされます)。
* 返される `FitResults.capacity_Ah` は測定セグメントごとに 1 エントリを持つリストです。単一のセル全体の容量が使われた場合(推定、フィット、または `ecm_options.capacity` 経由で指定された場合)、その値はセグメント全体にわたって繰り返されるので、形状は常に一貫します。

<Note>
  容量のフィット(`bounds_capacity` 経由)は、依然としてセグメント全体で共有される単一のセル全体の値を生成します。測定ごとの `capacity` は、各セグメントの容量が既に**判明していて**、それぞれを固定したい場合のためのものです。
</Note>

### 平滑化正則化

`ecm_options.regularization` は R0 / RC パラメータ曲線に対して Gauss の平滑化事前分布を適用します(OCV には適用されません)。データが SOC 依存パラメータを厳密に拘束しない場合 — 例: ノイジーなパルスデータや、SOC の狭い範囲しかカバーしない短いトレース — にフィット後の曲線の振動を抑えるために値を大きくしてください。

```python theme={null}
fit_job = client.ecm.fit_from_measurements({
    "measurements": [{"id": "meas-id-1"}],
    "ecm_options": {
        "num_rcs": 2,
        "regularization": 1.0,   # 0 で無効(デフォルト); 大きいほど滑らかな曲線
    },
})
```

`regularization > 0` の場合、値は内部で `scale = 5 / regularization` にマップされるので、`1.0` は控えめな事前分布で、より大きな値ほど強い平滑化ペナルティを課します。`0.0`(デフォルト)は特別扱いされ、事前分布が完全に無効化されます — 平滑化ペナルティは追加されず、`scale = 5 / regularization` の式は評価されません(したがってゼロ除算は発生しません)。同じオプションは `fit_from_file(..., regularization=...)` でも利用可能です。

### 既知の OCV(SoC) カーブからの容量フィッティング

別途行った低レート特性評価から得た OCV カーブがある場合、`ecm_options.ocv_soc_curve` 経由で渡すことで OCV フィッティングをスキップし、明示的な範囲内で容量を共同最適化することができます:

```python theme={null}
fit_job = client.ecm.fit_from_measurements({
    "measurements": [{"id": "meas-id-1"}],
    "ecm_options": {
        "num_rcs": 2,
        "ocv_soc_curve": {
            "soc": [0.0, 0.1, 0.2, 0.5, 0.8, 1.0],
            "ocv": [3.0, 3.2, 3.4, 3.7, 4.0, 4.2],
        },
        "bounds_capacity": {"lo": 4.0, "hi": 6.0},
    },
})
```

リクエストが送信される前に SDK 側でローカル検証される制約:

* `ocv_soc_curve.soc` は厳密に増加し、`[0, 1]` の範囲内である必要があります。
* `ocv_soc_curve.soc` と `.ocv` は同じ長さ (≥ 2) である必要があります。
* `bounds_capacity` は `capacity` が `None` の場合にのみ参照されます。`hi > lo` が必要です。
* `Open-circuit voltage [V]` 列を含む入力データとは相互に排他的です — どちらか一方を渡してください。

### ノット解像度の調整

難しいトレース (長い緩和、複数のタイムスケール) では、`ecm_options` 経由で SOC ノット解像度を上げます:

```python theme={null}
"ecm_options": {
    "num_rcs": 3,
    "num_knots": 21,                    # RC ペアパラメータの SOC ノット総数
    "num_knots_r0": 7,                  # R0(SoC) の SOC ノット
    "knot_schedule": [3, 5, 9, 21],     # 多解像度の精製スケジュール
    "clamp_boundary_knots": True,       # デフォルト; 記号的な R_rc=alpha/beta では緩和
    "clamp_max_ratio": 10.0,
}
```

`knot_schedule` は `num_knots` で終わる、厳密に増加する正の整数のリストである必要があります。省略するとデフォルトが自動的に導出されます。

### フィット結果をパラメータ化モデルとして保存

フィットが完了したら、シミュレーションで使用できるようにプロジェクト内に永続化します:

```python theme={null}
saved = client.ecm.save_to_project(
    name="ECM 2RC — pulse test",
    cell_spec_id="cell-spec-id",
    fit_results=result,
    description="2026 年 5 月のパルステストからフィット",
)

print(saved.parameterized_model_id)
```

返された `parameterized_model_id` は `client.simulation.protocol(...)` で `parameterized_model` として使用できます。詳細は[パラメータ化モデル](/ja/build/parameterized-models)を参照してください。

### 認証なしで組み込みの例をフィットする

`fit_from_example` はレート制限付き (60/分) で同期 — ジョブのポーリングは不要です:

```python theme={null}
examples = client.ecm.list_examples()
result = client.ecm.fit_from_example(examples[0]["id"], num_rcs=2)
```

RC ペアパラメータは、ECM 結果アクセスが有効な認証済み呼び出し元にのみ含まれます。

## ホールドアウトデータでの検証

ECM をフィットした後、[Python API クライアント](/ja/api-client)の `client.ecm.validate(...)` を使用して、**ホールドアウト**負荷ケース（フィットに使用していない測定、レート、ドライブサイクル）に対してモデルがどれだけ正確に再現できるかを確認します。この呼び出しは、フィットが内部で使用するのと同じエンジンを使ってホールドアウトの電流トレースに対してフィットされたモデルを前方シミュレートし、整列されたモデル対データのトレースとエラーメトリクスを返します。

この呼び出しは**同期的**で（ジョブも[パイプライン](/ja/pipelines/overview)もありません）、ECM のホールドアウト検証に適したツールです — この用途で ECM を検証パイプライン経由でルーティングしないでください。

### 使用するタイミング

* フィット後に、アプリケーションにとってモデルが十分に正確かを判定するため。
* 保存済みのパラメータ化モデルを、異なるレートやドライブサイクルでの新しい測定と比較するため。
* レポート用にモデル対データのオーバーレイと残差プロットを作成するため。

### 入力

**ホールドアウトソース**を 1 つ、**モデルソース**を 1 つだけ指定します:

| 引数                       | 説明                                                                                                               |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `measurement_id`         | ホールドアウトのセル測定（フィットに使用していないもの）。`example_id` と相互排他。                                                                 |
| `example_id`             | 検証対象の組み込み例データセット。                                                                                                |
| `fit_results`            | `wait_for_completion(...)` または `fit_from_example(...)` から返されたインメモリの `FitResults`。`parameterized_model_id` と相互排他。 |
| `parameterized_model_id` | 保存済みの ECM パラメータ化モデル（例: `save_to_project` から取得したもの）。                                                              |

オプション引数:

* `start_step`、`end_step` — ホールドアウト測定に適用される包括的なステップ境界。
* `initial_soc` — ホールドアウトトレース開始時の既知の SOC (0–1)。省略された場合、フィットされた OCV(SOC) カーブを介してトレースの最初の電圧から復元されます（トレースが休止に近い状態で始まることを前提とします）。トレースが負荷中から始まる場合は明示的に指定してください。
* `capacity` — SOC 積分に使用するセル容量 \[Ah]。デフォルトはフィット/モデルの容量（カーブがフィットされた SOC 基準）で、ホールドアウトトレースから再推定されることはありません。

### 例

```python theme={null}
# `result` は ECM フィットからの FitResults です。例:
#   job = client.ecm.fit_from_example(...)
#   result = client.ecm.wait_for_completion(job)

# インメモリのフィットをホールドアウト測定に対して検証
val = client.ecm.validate(
    measurement_id="held-out-measurement-id",   # a load case NOT used in the fit
    fit_results=result,                          # from wait_for_completion(...)
)

print(f"RMSE: {val.rmse_mV:.2f} mV "
      f"(MAE {val.mae_mV:.2f}, Max {val.max_mV:.2f})")

# または、以前に保存したパラメータ化モデルを検証
val = client.ecm.validate(
    measurement_id="held-out-measurement-id",
    parameterized_model_id=saved.parameterized_model_id,
)
```

### 結果

返される `ValidationResults` オブジェクトには、エラーメトリクスに加えて、2 パネル（オーバーレイ + 残差）の図としてプロットできる整列されダウンサンプリングされたトレースが含まれます:

| フィールド                       | 説明                       |
| --------------------------- | ------------------------ |
| `rmse_mV`、`mae_mV`、`max_mV` | ミリボルト単位の電圧エラーメトリクス。      |
| `time`                      | ダウンサンプリングされた時間グリッド \[s]。 |
| `data_voltage`              | ホールドアウトの測定電圧 \[V]。       |
| `model_voltage`             | 再シミュレートされたモデル電圧 \[V]。    |
| `residual_mV`               | モデル − データの残差 \[mV]。      |
| `initial_soc`、`capacity_Ah` | SOC 積分に使用された値。           |
| `num_rcs`、`model_source`    | 検証されたモデルの RC ペア数と出所。     |

典型的なプロットは、1 行目に `model_voltage` と `data_voltage` を `time` に対してオーバーレイし、2 行目に `residual_mV` を `time` に対して x 軸を共有して表示します:

```python theme={null}
import matplotlib.pyplot as plt

fig, (ax_v, ax_e) = plt.subplots(2, 1, sharex=True, figsize=(9, 6))
ax_v.plot(val.time, val.data_voltage, label="data")
ax_v.plot(val.time, val.model_voltage, label="model", linestyle="--")
ax_v.set_ylabel("Voltage [V]")
ax_v.legend()
ax_v.set_title(f"Held-out validation — RMSE {val.rmse_mV:.1f} mV")
ax_e.plot(val.time, val.residual_mV)
ax_e.axhline(0, color="k", linewidth=0.8)
ax_e.set_ylabel("Error [mV]")
ax_e.set_xlabel("Time [s]")
fig.tight_layout()
```

## 次のステップ

* 測定を所定の場所でフィットできるように、プロジェクトに[測定をアップロード](/ja/data/uploading)します
* フィットされたパラメータで[パラメータ化モデル](/ja/build/parameterized-models)を作成します
* Ionworks Studio で利用可能な [ECM と他のモデルタイプ](/ja/build/models)について学びます
* サイクリングデータをアップロードするための[データフォーマットの要件](/ja/data/format)を探ります
