アーキテクチャ#

このドキュメントでは、haniwers プロジェクトのアーキテクチャと設計の決定について説明します。

デュアルバージョンシステム#

haniwers は2つの並行実装を維持しています:

v0: プロトタイプ版(will be deprecated)#

場所: src/haniwers/v0/

特徴:

  • プロダクション対応の安定版CLI

  • 基本的な機能を提供

  • シンプルで実証済みのアーキテクチャ

主要コンポーネント:

  • cli.py: Typer ベースのメインCLIインターフェース

  • config.py: 設定管理

  • daq.py: データ取得ロジック

  • threshold.py: 閾値スキャンとフィッティング

  • preprocess.py: 生データ処理

  • postprocess.py: データ解析ユーティリティ

v1: 次世代版(in development)#

場所: src/haniwers/v1/

特徴:

  • モダンでモジュラーなアーキテクチャ

  • より優れたテスト容易性

  • 関心の分離が改善

主要コンポーネント:

  • cli/: モジュラーなCLI構造

    • main.py: エントリーポイントとグローバルオプション

    • config.py: 設定管理コマンド

    • daq.py: データ取得コマンド

    • scan.py: 閾値スキャンコマンド

  • config/: Pydantic モデルによる設定管理

  • daq/: デバイス抽象化によるデータ取得

  • log/: Loguru による構造化ロギング

バージョンの選択#

  • v0 (haniwers): デフォルトのメインCLI

  • v0 明示的 (haniwers-v0): 明示的なv0 CLI

  • v1 (haniwers-v1): 次世代v1 CLI

  • v1 エイリアス (haniwers-ng): 次世代版のエイリアス

技術スタック#

言語とランタイム#

  • Python: 3.12+

  • パッケージ管理: Poetry 2.0+

  • 仮想環境: poetry run <command> または poetry env activate

    • 注: poetry shell は非推奨

コア依存関係#

  • CLI: Typer - コマンドラインインターフェース

  • シリアル通信: pyserial - OSECHI検出器との通信

  • 設定: TOML - 設定ファイル形式

  • データ処理: Pandas/Polars - データフレーム操作

  • ロギング: Loguru (v1) - 構造化ロギング

  • バリデーション: Pydantic (v1) - 設定モデルの検証

開発ツール#

  • フォーマッター: Ruff

  • リンター: Ruff

  • テスト: pytest

  • カバレッジ: pytest-cov

  • コミット: Commitizen

  • Pre-commit: pre-commit

  • ドキュメント: Sphinx, MyST, autodoc2

v0 アーキテクチャ詳細#

モジュール構成#

haniwers/v0/cli.py#

責務: メインのCLIエントリーポイント

  • Typerベースのコマンド定義

  • サブコマンド: daq, scan, fit, vth, ports, run2csv

  • ログ設定とオプション解析

  • 統一されたエラー処理

haniwers/v0/config.py#

責務: 設定管理

  • Config, RunData, UserSettings クラス

  • TOML設定ファイルの読み込み

    • daq.toml: データ取得設定

    • scan.toml: 閾値スキャン設定

  • パス管理と環境固有設定

haniwers/v0/daq.py#

責務: データ取得(DAQ)

  • シリアル通信(pyserial)による測定器制御

  • RealEvent クラスによるイベントデータ構造

  • ファイル保存とタイムスタンプ管理

haniwers/v0/threshold.py#

責務: 閾値制御

  • scan_thresholds_in_parallel: 並列閾値測定

  • Count データクラス: 測定結果の構造化

  • フィット処理とCSV出力

haniwers/v0/dataset.py#

責務: データ処理

  • Run クラス: 測定データへのアクセス

  • パス管理とファイル操作

  • データフレーム変換

haniwers/v0/preprocess.py & haniwers/v0/postprocess.py#

責務: データ処理パイプライン

  • 生データの前処理とリサンプリング

  • 可視化とプロット機能

  • CSV形式への変換

デザインパターン#

責務の分離:

  • CLI: コマンド定義とオプション解析

  • DAQ: ハードウェア制御とデータ取得

  • Config: TOML設定の管理

  • Data Processing: 前処理・後処理・可視化

設定による柔軟性:

  • 外部設定ファイル(TOML)

  • 実験ラン管理(runs.csv)

  • 環境変数サポート

データフロー:

生データ取得 → 前処理 → CSV保存 → 可視化・解析

v1 アーキテクチャ詳細#

モジュール構成#

haniwers/v1/cli/#

モジュラーなCLI構造:

  • main.py: エントリーポイントとグローバルオプション処理

  • config.py: 設定管理コマンド(show, init)

  • daq.py: データ取得コマンド

  • scan.py: 閾値スキャンコマンド

改善点:

  • コマンドごとにファイルを分離(保守性向上)

  • テスト容易性の大幅な改善(モック戦略)

  • 新規コマンド追加が容易(main.pyは2行変更のみ)

  • 100%後方互換性を維持

詳細: CLI開発ガイドを参照

haniwers/v1/config/#

モジュラーな設定管理:

  • model.py: Pydantic モデルによる設定の定義と検証

  • loader.py: 設定ファイルの読み込みロジック

  • generator.py: 設定ファイルのテンプレート生成

改善点:

  • 型安全な設定

  • 自動バリデーション

  • より良いエラーメッセージ

haniwers/v1/daq/#

デバイス抽象化:

  • device.py: デバイス抽象化層

  • mocker.py: テスト用モックデバイス

  • sampler.py: サンプリングロジック

  • model.py: データモデル定義

改善点:

  • テスト容易性の向上(モック機能)

  • より明確な抽象化

  • デバイスの交換が容易

haniwers/v1/log/#

構造化ロギング:

  • logger.py: Loguru ベースのロガー設定

改善点:

  • JSON形式の構造化ログ

  • より良いデバッグ情報

  • ログレベルの柔軟な制御

デザインパターン#

モジュラリティ:

  • 小さく、焦点を絞ったモジュール

  • 明確なモジュール境界

  • 再利用可能なコンポーネント

テスト容易性:

  • 依存性注入

  • モック可能なインターフェース

  • 単体テストフレンドリーな設計

データフロー#

測定ワークフロー#

1. 閾値スキャン (scan)
   ↓
2. 閾値フィッティング (fit)
   ↓
3. 閾値設定 (vth)
   ↓
4. データ取得 (daq)
   ↓
5. 生データ変換 (raw2tmp)
   ↓
6. CSV変換 (run2csv)

ファイル管理#

タイムスタンプベースの命名:

  • 生データ: YYYYMMDD_HHMMSS_raw.dat

  • 処理済み: YYYYMMDD_HHMMSS_run.csv

ディレクトリ構造:

data/
├── YYYYMMDD_HHMMSS_run.csv
├── runs.csv
sandbox/
├── YYYYMMDD_HHMMSS_raw.dat
├── YYYYMMDD_HHMMSS_tmp.csv

設計原則#

1. CLI第一#

  • すべての機能はCLIから利用可能

  • スクリプト化とオートメーションが容易

  • 対話的とバッチ実行の両方をサポート

2. 設定ファイルによる制御#

  • ハードコードされた値を避ける

  • 環境固有の設定を外部化

  • バージョン管理可能な設定

3. モジュール性と再利用性#

  • 小さく、焦点を絞った関数とクラス

  • 明確な責務の分離

  • 再利用可能なコンポーネント

4. データの完全性#

  • タイムスタンプによる追跡可能性

  • 生データの保存

  • 再現可能な処理パイプライン

5. 段階的な複雑化#

  • シンプルなv0から開始

  • 段階的にv1で機能を追加

  • 両バージョンの互換性を維持

依存関係管理#

Poetry を使用する理由#

  • 決定論的なビルド: poetry.lock による再現可能なインストール

  • 依存関係の分離: 開発、ドキュメント、テスト用の分離された依存関係

  • パッケージ公開: PyPI への公開が簡単

依存関係グループ#

[tool.poetry.dependencies]
python = "^3.12"
typer = "^0.9"
# ... コア依存関係

[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
ruff = "^0.6"
# ... 開発用依存関係

[tool.poetry.group.docs.dependencies]
sphinx = "^8.0"
# ... ドキュメント用依存関係

テスト戦略#

テストの種類#

  • Unit Tests: 個別コンポーネントのテスト(tests/{version}/unit/

  • Integration Tests: マルチモジュール相互作用(tests/{version}/integrations/

  • Contract Tests: APIインターフェース

  • Manual Validation: quickstart.md のシナリオ経由

カバレッジ目標#

  • 目標: 80%以上のカバレッジ

  • 対象: プロダクションコード(v0, v1モジュール)

詳細はテストガイドラインを参照してください。

ドキュメント構造#

Sphinx + MyST#

  • フォーマット: Markdown(MyST)

  • ビルダー: Sphinx

  • テーマ: sphinx_book_theme

  • API ドキュメント: autodoc2

ドキュメントの種類#

  • ユーザー向け (docs/users/): データ取得ワークフロー

  • 協力者向け (docs/collaborators/): データ解析ワークフロー

  • 開発者向け (docs/developers/): 開発ワークフロー

  • 共有 (docs/_shared/): 用語集、コマンドリファレンス

継続的インテグレーション#

GitLab CI/CD#

  • テスト: すべてのコミットでpytestを実行

  • リンター: Ruffによる静的解析

  • カバレッジ: カバレッジレポート生成

  • ドキュメント: Sphinxビルド検証

将来の方向性#

v1 への移行#

  • v1の機能を段階的に拡張

  • v0との互換性を維持

  • 最終的にv1をデフォルトに

計画されている改善#

  • よりよいエラーハンドリング

  • パフォーマンス最適化

  • 追加のデータ形式サポート

  • リアルタイムデータ可視化


アーキテクチャ判断レコード (ADR)#

詳細なアーキテクチャ判断と設計決定については、Architecture Decision Records (ADR)を参照してください。ADRsは、プロジェクトの進化過程で下されたキー決定と、その理由を文書化しています。


アーキテクチャに関する質問や提案は、GitLab Issuesで歓迎します。