(執筆完了時削除 --> 執筆責任者: 洲波泥 太郎, 執筆締め切り: 2024/xx/xx)
ここでは、DAQシステムを動かす上で最低限理解しておきたい NestDAQ の概要を説明する。さらに、NestDAQ関連情報へのリンクを示す。詳しい情報は各リンクを参照のこと。
NestDAQ は連続読み出し FEE のために開発された DAQ ソフトウェアフレームワークである。高いスケーラビリティを持つことを目標に設計されており、データ処理のプロセスをネットワーク上のコンピュータに分散可能な、いわゆるネットワーク分散型の DAQ ソフトウェアである。小規模実験から中規模実験の加速器物理実験における連続読み出し型 DAQ システムを念頭に設計されているが、汎用のフレームワークであるため、連続読み出しを行いたい計測機器やトリガー型 DAQ にも対応可能であると考えられる。
NestDAQ は GSI FAIR で開発されている DAQ フレームワーク FairMQ をベースにしている。DAQ プロセス間の接続トポロジーの管理には、in-memory key-value データベースである Redis を用いる。さらに、NestDAQ では DAQ のスタータス情報、メトリックス情報といった情報を取得するための各種プラグインが用意されている。非常に単純化した場合、"NestDAQ = FairMQ + Redis + 各種プラグイン"と言うことができる。ここで、FairMQ は ZeroMQ と呼ばれるライブラリを用いて作られており、FAIR + ZeroMQ = FairMQ ということでこの名前になったと予想される。
NestDAQ はネットワーク分散型の DAQ であり、1 つまたは複数の計算機において DAQ プログラムのプロセスを走らせ、Redis データベース経由で各プロセスの制御を行う。 NestDAQ では、各プロセスのことを FairMQ デバイスと呼ぶ。また、Redisデータベースでは DAQ の状態 (Runが走っているか、または止まっているかなどの状態) の情報も保持している。この情報をもとに NestDAQ は DAQ の状態管理を行っている。各 FairMQ デバイスは Redis と通信を行うことが可能であり (?) 、Redis に対してコマンドが発行されると、そのコマンドは各 FairMQ デバイスに転送される。例えば Run をスタートさせる場合、Redis に対して Run スタートのコマンドを発行 (Publish) すると、Redis が各プロセスに Run スタートの情報を伝達し、すべての DAQ プロセスが Run 状態に遷移して、データ収集が開始する。ランストップといった他のコントロールも同様にして行われる。通常、DAQ のコントロールは、Web ブラウザ上の DAQ コントローラと呼ばれるユーザーインターフェースから行う。Web コントローラでは、グラフィカルにスタートボタンやストップボタンといったボタンをクリックすることで、簡単に DAQ のコントロールが可能となっている。ただ、必ずしもこのコントローラを使用する必要はなく、Linux のコマンドライン上から redis-cli というコマンドを用いて直接 Publish コマンドを Redis に対して発行することで DAQ のコントロールが可能である。つまり、最低限 FairMQ デバイスと Redis データベースが立ち上がっていればデータ収集が可能であり、言い換えると DAQ ソフトウェアの最小構成は FairMQ デバイスと Redis データベースであると言える。場合によっては Web コントローラを用いず、DAQ の ランスタート、ランストップのシェルスクリプトを用いて DAQ の制御を行うこともある。FairMQ デバイスと Redis、もしくは Redis と Web コントローラはそれぞれ弱く結合するように設計されており、これによってシステムの堅牢性を確保している。(一般に、強く結合したシステムは一箇所に不具合が起きただけで全体に影響がおよぶため、堅牢性が低下し、脆弱なシステムとなる。)
各 FairMQ デバイスはデータを前段の FairMQ デバイス (Sampler の場合は FEE) からデータを受け取り、なんらかの処理を行なって後段のFiarMQ デバイス (Sink の場合はストレージ) に送る。ここで、どのデバイスがどのデバイスにデータを送るかという送信元と送信先の接続情報を、すべてのデバイスに対して決めたものをトポロジーと呼ぶ。一般に、トポロジーとは要素間の接続のされ方を端的に表現したものであり、例えば、スター型接続、デイジーチェーン(数珠つなぎ)接続、網目状(蜘蛛の巣状)接続といった幾何学的な接続の様式を一言で表したものである。NestDAQでは、各FairMQデバイス間の接続が 1 対 1 であったり、n 対 m であったりするが、すべてのデバイスをどのように接続するかを決めたものをトポロジーと呼んでいる。具体的にトポロジーを設定するには、設定スクリプトを書き、それを走らせることで、トポロジーの設定を行う。実際のスクリプトの書き方については、チュートリアルを参照のこと。
各 FairMQ デバイスに対して、しばしば何らかの値、すなわちパラメータを渡したいことがある。このパラメータも Redis データベースによって管理されており、ランのスタート、もしくはストップの前後のタイミングで Redis データベースからパラメータの値を読み込んで利用する。例えば、FEEの IPアドレスなどの設定もパラメータを用いて設定している。一方、Redis経由でパラメータを設定する他に、FairMQ 起動時にパラメータを設定することも可能である。具体的にパラメータを設定するには、設定スクリプトを書き、それを走らせることで、パラメータの設定を行う。実際のスクリプトの書き方についてはチュートリアルを参照のこと。FairMQデバイスにおいてどのようなパラメータが存在するかは、FairMQ デバイスを実行する際に、--help オプションをつけて実行するとパラメータの一覧とその役割が確認できる。ただ、網羅されていない場合もあり、--help オプションで見つけられないパラメータはソースコードを読んでパラメータの役割を理解し、値を設定する。
NestDAQ では Front End Electronics (FEE) から止めどなく (Stream のように) 流れてくるデータを Sampler プロセス (FairMQ デバイス) が受けとり、処理を行なって次の FairMQ デバイスに流し、さらにその FairMQ デバイスで処理をして次の FairMQ デバイスに流すということを繰り返して、止めどなく処理を行っていく。(このように、データを処理するプロセッサを直列につなぎ、あるプロセッサの出力があるプロセッサの入力になるように処理することをパイプライン処理と呼ぶ(あってる?)。)FairMQデバイス間の通信は具体的には ZeroMQ ライブラリが管理しており、データのバッファリング処理などは ZeroMQ がよしなに処理している。(ただ、ZeroMQのブラックボックス的な仕様のため、キューに詰まっているデータの量といった基本的な情報が取得できないようで、NestDAQ 開発陣は苦労しているとのこと。)以下では、 NestDAQ で用いられているそれぞれの FairMQ デバイスの役割を説明する。
Sampler は AMANEQ、CIRASAME といった FEE に TCP/IP プロトコルで接続し、TDC データ、及びデリミタデータを TCP 通信で読み出すための FairMQ デバイスである。https://github.com/spadi-alliance/nestdaq-user-impl のソースコードでは、AmQStrTdcSampler というデバイス名になっている。CIRASAME の出力データ構造は AMANEQ と同一であるため、CIRASAME のデータは AmQStrTdcSampler を用いて読み出すことが可能である。Sampler は各 FEE ボードと 1 対 1で通信を行うため、FEE ボード 1 台につき 1 つの Sampler を立ち上げる必要がある。AmQStrTdcSampler に与えるパラメータは Front End Electronics の IP アドレスと FEM (Front End Module) type と呼ばれる番号である。FEM type は現状で以下のように設定するのが慣例である。(ユーザーが定義することもできるが、混乱を招かないように、新しい番号を利用する場合は SPADI Alliance で議論することが望ましい。)
Firmware | データ構造 | FEM type |
AMANEQ LR-TDC v1.? 以前 | AMANEQ LR-TDC v1.? 以前のデータ構造 | 1? |
AMANEQ HR-TDC v1.? 以前 | AMANEQ HR-TDC v1.? 以前のデータ構造 | 2? |
AMANEQ LR-TDC v2.? 以降 | AMANEQ LR-TDC v2.? 以降のデータ構造 | 3? |
AMANEQ HR-TDC v2.? 以降 | AMANEQ HR-TDC v2.? 以降のデータ構造 | 4? |
AMANEQ MIKUMARI Primary v2.? 以降 | AMANEQ LR-TDC v2.? 以降のデータ構造と compatible | 4? |
AMANEQ MIKUMARI Hub v2.? 以降 | AMANEQ LR-TDC v2.? 以降のデータ構造と compatible | 4? |
CIRASAME v?.? 以降 | AMANEQ LR-TDC v2.? 以降のデータ構造と compatible | 4? |
Sub-Time Frame Builder (STFB) は sampler からのデータを Time Frame ごとに切り分け (?)、ヘッダー情報を付加するための FairMQ デバイスである。https://github.com/spadi-alliance/nestdaq-user-impl のソースコードでは、STFBuilder というデバイス名になっている。Sampler に 1 対 1 で接続してデータを受けとり、処理を行って後段の FairMQ デバイスにデータを出力する。FEE - Sampler - STFB の接続はすべて 1 対 1 の接続となるため、例えば FEE が 10 台ある場合、Sampler は 10 プロセス、STFB も 10 プロセス立ち上げる必要がある。一方で、STFB 以降の FairMQ デバイスは、N 対 M (N 対 1 もしくは 1 対 N を含む) で接続可能である。
Time Frame Builder は各 Sub-Time Frame Builder の出力を受けとり、同じ Time Frame のデータをすべての FEE から集め、ひとまとまりの Time Frame Build されたデータとする。https://github.com/spadi-alliance/nestdaq-user-impl のソースコードでは、TimeFrameBuilder というデバイス名になっている。このひとまとまりの Time Frame データに Time Frame Header と呼ばれる Header 情報を付加し、下流の FairMQ デバイスに出力される。一つの Time Frame Build されたデータには、すべての FEE における同一 Time Frame のデータが含まれている。Sampler と STFB は、FEE の数と同じ数だけ立ち上げる必要があるが、Time Frame Builder を立ち上げる数は FEE の数と同じである必要はない。処理が間に合えば Time Frame Builder は 1 つでも構わない。Time Frame Builder を 2 つ以上立ち上げる場合は、Sub-Time Frame Builder からのデータが適切に各 Time Frame Builder に割り振られるように FairMQ デバイスの auto sub channel のパラメータを true に設定する必要がある(?要確認)。
このデバイスの理解を深めるため、例をもとに説明しよう。例えば、Sub-Time Frame Builder が 2 つ (STFB A, STFB B)、Time Frame Builder が 3 つ (TFB A, TFB B, TFB C) あったと仮定しよう。STFB A, STFB B にはそれぞれ上流の 2 つの FEE からのデータが流れてきている。ここで、各 STFB の各 Time Frame に対して番号が 1 から順番に割り振られるとしよう。このとき、STFB A, STFB B からの Time Frame 番号 1 番のデータが TFB A に行き、Time Frame 番号 2 番のデータが TFB B, Time Frame 番号 3 番のデータが TFB C、Time Frame 番号 4 番のデータが TFB A に行きというように順番に流れていけば、TFB A では Time Frame 番号が 1, 4, 7, 10, ...、TFB B では Time Frame 番号が 2, 5, 8, 11, ... 、TFB C では Time Frame 番号が 3, 6, 9, 12, ... というようにSTFB A, STFB B の同一 Time Frame 番号のデータをビルドできる。一方、STFB A と STFB B の出力先をうまく設定できていない場合、例えば、STFB A の Time Frame 番号 1 番のデータが TFB A に行き、STFB B の Time Frame 番号 1 番のデータが TFB B に行った場合、TFB A では STFB B からの Time Frame 番号 1 番のデータが来ないために正しくTime Frame build できないことになるし、TFB B でも同じ問題が生じる。このように、Sub-Time Frame Builder と Time Frame Builder の接続は注意して正しく設定しないと、Time Frame Build ができないことになる。
また、Time Frame Builder はこのプロセスの負荷に応じて処理が間に合うように立ち上げる数を調整する必要がある。処理が間に合っているかどうかという判断は経験が必要な場合があるが、Time Frame Builder の Elapsed time を調べたり、CPU 使用率、メモリ使用率、DAQが止まらないかといったことを見て判断する。
Logic Filter は Time Frame Builder から出力されたデータを受け取り、コインシデンス条件といった情報に基づいて、Time Frame データにコインシデンスのフラグを挿入するための FairMQ デバイスである (?)。https://github.com/spadi-alliance/nestdaq-user-impl のソースコードでは、LogicFilter というデバイス名になっている。このデバイス名には Filter とついているが、実際にこのデバイスでデータが減らされているわけではなく (?要確認)、実際にデータが削減されるのは、下流に接続されるTimeFrameSlicerByLogicTiming である。このデバイスが出力するデータには、?? Header と呼ばれる Header 情報が付加され、下流の FairMQ デバイスに出力される。
このデバイスの理解を深めるため、例をもとに説明しよう。FEE のボードが 2 つ (FEE A, FEE B)、Sampler が 2 つ (Sampler A, Sampler B)、 Sub Time Frame Builder が 2 つ (STFB A, STFB B) 、Time Frame Builder が 1 つ (TFB A) あったと仮定しよう。さらに、FEE A は Sampler A を経由して STFB A にデータを送っており、FEE B は Sampler B を経由して STFB B にデータを送っていると仮定しよう。測定したいイベントがもし 10 kHz 程度であった場合、TFB A で Time Frame Build されたデータにおいて、1 つの Time Frame あたり、?? 回のイベントが記録されている。ここで、測定したいイベントが発生した際は、必ずあるプラスチックシンチレータのスタートカウンターが鳴ると仮定しよう。さらに、このプラスチックは両読みになっており、FEE A からのデータのチャンネル 0 とチャンネル 1 に信号が入っていると仮定しよう。このとき、FEE A のチャンネル 0 とチャンネル 1 がある時間幅の中で同時に鳴ったときに、測定したいイベントが発生したと考える。Logic Filter では、コインシデンス判定を行う時間幅(コインシデンスウィンドウ)を設定し、さらに、コインシデンスの判定を行うチャンネルの設定も行う。このような条件に基づいて Logic Filter ではデータの処理を行い、FEE A のチャンネル 0 とチャンネル 1 がコインシデンスウィンドウ内で同時に鳴った場合、フラグビットを True にして、その付加情報を Header に加え、下流の FairMQ デバイスに送る。
コインシデンスの判定方法のアルゴリズムをもう少し正確に説明しておこう。現在の Logic Filter の仕様では、
Time Frame Slicer は Logic Filter が付加した情報をもとに、
NestDAQ は RedHat 系の Linux 上での運用を想定しており、現時点 (2024年9月) における推奨実行環境は AlmaLinux 最新版の AlmaLinux 9.4 である。CentOS 7, AlmaLinux 8, AlmaLinux 9 などの RedHat Enterprise Linux (RHEL) のクローンにおいて稼働実績があり、最近の RedHat 系 Linux ではだいたい運用可能であると考えられる。また、Ubuntu 22.04.3 LTS といった Ubuntu/Debian 系の Linux でもコンパイル実績はあるが、本番実験で使用された例はない。また、ソースコードの軽微な修正を行うことで MacOS (Intel CPU) でも clang を用いてコンパイルが通ることがわかっているが、詳しく動作確認された例はない。最近では Windows において Windows Subsystem for Linux (WSL) を用いることで Linux が利用可能になっており、おそらく NestDAQ も動くと考えられるが、検証された例はない。
NestDAQ は ZeroMQ、Boost といったライブラリが必要であり、NestDAQ をインストールする際は事前に各種ライブラリをインストールしておく必要がある。詳細はインストールのインストラクションを参照のこと。C++ のコンパイラとして比較的新しい GCC の g++ が必要である。clang によるコンパイルはあまり実績がないため、g++ によるコンパイルが望ましい。
また、KEK INPS の千代氏が Apptainer 用のコンテナを用意しており、これを用いることでOS非依存にインストールを行わずに NestDAQ を利用可能である。
2024/xx/xx 洲波泥 太郎 (SPADI大学), 脱九 花子 (SPADI大学)
2024/xx/xx 脱九 花子 (SPADI大学)