見出し画像

146日間に渡る、Geant4を利用したUnity製 素粒子シミュアプリの開発記録

この度、Geant4を利用したUnity製素粒子物理シミュレーションアプリケーションを作りまして、Boothにてリリースさせていただきました。

この記事では、アプリ自体の説明ではなく、個人的につけていた開発日記(?)のダイジェストをお送りしつつ、やってよかったこととかも紹介できたらと思います。

(ざっくり日付が書いてありますが、大抵その日を開始として数日間にわたってその開発は行われています)

開発日記のダイジェスト

「よし作ろう!」と思ったのは去年(2022年)の12月13日です。

当時はUnity Japanの公式動画(keijiroさんとかがUnityの機能を色々紹介してくれるやつ)を色々見ていて、Unity2021以降の開発体験が気になっており、いい題材ないかなあと思っていたのがそもそものきっかけでした。

私は以前理学部物理学科に所属しており(学部1年で辞めてしまいましたが…)、せっかくなら物理学となんか絡めて作りたいなと思っていました。

「Geant4」というライブラリの存在は名前だけは聞いたことがあり、なんとなくイベントディスプレイのシミュレーションとかに使える…という理解だったのですが、これをUnityで動かせたらなにかしら面白いものができるんじゃないかという漠然とした思いから、まずはGeant4自体の理解からはじめることにしました。

私がよく入り浸ってるDiscordの個人チャンネルの投稿

12月13日(Geant4自体の学習)

初日は「Geant4 初心者講習会 2022」の資料を読み漁っていました。

この資料は初心者講習といえど実用的な範囲はあらかた網羅されており、あらゆるところで助けられました。
この取り組みをしている方々には感謝しかありません。

Geant4構築済みの仮想環境も配布されており、環境構築で詰まりがちな私のような初心者に優しい仕様になっています。

最初の一歩
初日の成果

初日は90分ぐらい触った程度ですが、さっそくそれっぽいシミュレーションが動いて楽しい気持ちになりました。

12月15日(ネイティブプラグイン自体の学習)

Geant4自体についての理解がある程度深まったので、このあたりからUnity連携を試みます。

私はUnityのネイティブプラグインを開発したことがなく、上の画像中にもありますが、こちらの記事が非常に参考になりました。

気づき

12月17日(Geant4をC++で動かす)

ちょうどこの頃はChatGPTがリリースされたところで、なんとChatGPTはGeant4のことをばっちり知っていたので、かなり助けられました(神の一手すぎる!)

色々生成してもらった
ちゃんと動いた!

C++自体(というかプログラミングそれ自体)そんなに詳しくないので、こちらも並行しつつ勉強しました。

Marshal、仕事でたまに聞いたりする単語で、こういうことね、ってなりました

12月19日(ネイティブプラグインの最初のつまづき)

Geant4をネイティブプラグイン化してUnity上で動かすことには成功したのですが、なぜか1回目のPlayでは問題ないのに、一度Playを停止して、もう一度Playすると2回目は必ず落ちる、という現象に遭遇しました。

このあたりからDiscordではなくTwitterの鍵垢で開発日記をつけ始めました

正直結構意味がわからず、デバッグもしにくかったので困ったのですが、そもそもネイティブプラグインについての理解が間違っていたことに気づきました。

❌ ネイティブプラグインはUnityのPlayとともに毎回実行される
⭕ ネイティブプラグインはUnityのPlayとは無関係に常に動き続けている

結局この問題はG4RunManagerというクラスが複数回作られることが原因だったため、次のように解決されました。

ここでのUnityネイティブプラグイン制作における非常に重要な気付きとして、Unityが絡むとそれだけで複雑なので一旦Visual Studio C++だけで状況が再現できるか?をしっかり検証することが解決への近道だと実感しました(それはそう!)

12月25日(ビジュアライズの基盤ができてくる)

シミュレーション結果をUnityで表示する、というところまでこぎつけました

Unity、こういうところがお手軽で最高!

せっかくならURPとかVFX Graphつかってみようってことで、…

アニメーションも再生できるようにしました。

もはやこれだけでもう満足です!
VFX GraphやGraphics Bufferも始めて触ったのですが、とても良さげですね

12月28日(VisualScriptingをやってみるが…)

そもそもUnityでの開発体験目的で始めたプロジェクトでもあったので、積極的にUnityの新機能に触れてみようということで、VisualScriptingとも連携させてみました。

スペースキーを押すとシミュレーションが実行できる、というデモ

が、途中で「あれ、これC#と同じことをやってるな?一人で開発するぶんにはただ面倒なだけでは…?」と気づいて、結局これはボツになりました

1月1日~1月6日(開発休止)

なんだかんだ実は毎日継続して開発していたのですが、お正月は帰省していたので開発はお休みしていました

1月8日(ものが配置できるようになった)

ジオメトリの構築ができるようになりました。
もはやこの時点でだいぶ遊べます。

今見るとバグがあるんですが、
少なくとも粒子の挙動が物体の境界面で変わっているのが確認できました

ちなみに同日、磁場も扱えるようになりました。

1月11日(センサーができた)

ものがどれぐらいエネルギーを吸収するか、という情報が拾えたので、センサーとして表示できるようにしました

我ながら、かっこよくて素敵だと思います!

1月19日(検出器のパーツを作る画面を作り始める)

のちにボツになってしまうのですが、検出器のパーツを作成するUIをつくろうとしていました。

宣言
進捗(名前、材質、大きさを設定して登録するだけ)

1月23日(検出器をいい感じに配置UIができた)

これも結局ボツになってしまったのですが、測定器と距離だけ指定していい感じに自動配置してくれるUIも作っていました。

これも今から見るとちょっとバグがあります

このあたりからシミュレーターとしてのUI/UXのことを考える必要が出てきました

自由度を高め過ぎると面倒になり、
かといってシンプルすぎると、自由度がなくなってしまう

どちらをとるべきか、両立するいいアイデアはないか、試行錯誤していました。

その中でも、このとき実装していたのはわりといいバランスのように思えるのですが、測定器の種類ごとに自由度の高い配置をさせたい気持ちそれを叶えるための実装すべきことの量を鑑みて、唸っていました…

もういっそシンプルに仕切りだけ作ってあとはユーザーに自由に配置させるとかでいいんじゃないかと思って、思い切ったデザインにしたのが皆さんにお見せした最終形です。(後述)

その方針転換自体は最近になってのことなので、しばらくは円形に対称的に並べるUIでの開発が続きます。

めっちゃそれっぽい画面が作れて嬉しい図

このあたりで、「中性子」の存在のウザさに悩まされることになります。

中性子は密度が大きめの物質があると容易に発生するので、まともに全部追っていると処理に時間かかるわ見た目もぐちゃぐちゃだわで、どうにかならないものか、と悩んでいました。

2月2日(先人の知恵を借りる)

中性子に悩まされるのは僕だけではないはずで、実際に研究している人はどうしているのだろうと調べたところ、basf2(Belle2実験のソフトウェア)のDocumentationにたどり着きました。(これ一般に公開されてるのありがたすぎる!)

このDocumentationは素粒子実験オタクの私としては隅から隅まで面白い内容なのですが、今回特に参考になったのはSimulationの「Belle2PhysicsList」のページです。

https://software.belle2.org/development/sphinx/simulation/doc/Belle2PhysicsList.html

大歓喜

PhysicsListというのは、シミュレーションの前提となる物理法則のリストです。

そもそも前提として、シミュレーションというのは現実の物理を完全に再現するものではなく、計算量と精度などを鑑みつつ適切に手を抜けるところは手を抜いてもっと本質的な部分を調べることに注力するものです。

この記事は、どういうところでどういう理由でどう手を抜いているのか事細かに記載されているという点で、非常に嬉しい内容になっています。

Belle2PhysicsList also offers the option to use the Geant4 high precision neutron package below 20 MeV. This option is useful if background or beamline issues are being studied, but would not be used in the standard simulation due to the large amount of CPU time required.

basf2 development documentation - Belle2 Physics List - Hadronic physics

これによると、バックグラウンドやビームラインの研究でもない限り、20MeV以下の中性子は切り捨ててしまうのが標準なようでした。

納得

実際に低速中性子をカットしてみると、求めていたものになりました

先人の知恵は偉大

2月8日(少し脱線)

ここで、Unityアプリではない、別のアイデアがよぎります。

要するに、UnityアプリではなくGeant4を動かし続けるWebサーバー作ってみたい、というお話です。

Web開発の知識は一切ないのですが、今ならChatGPTとかあるし、いけるやろ!という見切り発車です。

はじめてのDocker

めちゃ便利で感動しました

いちいち環境構築方法をNotionとかに書かなくてももDocker Imageさえあればええんや

react-three-fiberというThree.jsをReactっぽく書けるライブラリがある、という情報をChatGPTが教えてくれたので、これを利用してUnityの代わりに使えば同じことできるやろという算段です。

r3fにおけるHello world的なやつ

しかし、結局1週間ぐらい模索して、これはとりあえず先にUnityで完成させるべきだぞ、と気づきました(えらい!)(それはそう!

でも、いいアイデアなので将来的にはやりたいです。
Webの勉強にもなりそうですし…

2月23日(デザインの大幅見直し)

先述のUIの複雑さについての見直しがここできます。

区切ったマスに測定器を配置する、というアイデア

正直このアイデアによって失われるものも多いのですが、わかりやすさの点で優れていると感じて、この方針で進めていくことにしました。

しかし、Geant4には六角柱のソリッド形状がありません。(厳密に言えば四角柱を3つ合成することで実現自体はできますが、1個で3つ分の立体を使うことになるのでコスパは悪そう…)

正直、この方針でいくなら単位が立方体となるような格子状に区切るのが一番コスパが良いのではないか、と思われるし恐らく実際そうなのですが、「これ見た目がMinecraftっぽくなっちゃうな…」という気持ちになりました。

これはパッと見の印象の問題なのですが、六角形がたくさんならんでいるほうがかっこいいな!と思うので、なんとかこれを押し通したかったです。

物理知らない人にこそ触ってもらいたいという思いがあるので、
パッと見のかっこよさを大事にしたかった

というわけでデザインを変更して構築し直すことにしました

2月25日19時
2月27日5時
今に至るデザインの原型ができました

3月7日~4月9日(開発休止)

別で作りたいもの(モーキャプカメラ、Discord Bot、VRoidモデル制作、Rustプログラミング、Blenderで円周率求める…など)がでてきてしまって、まるまる1ヶ月以上開発を休止していました

4月10日(完成させることに全力を注ぐ)

結構長く休んでしまって、
あれ、このままだと一生リリースしないぞ???」と思いまして、…

ここからは機能を追加したりすることよりも、リリースすることに全力を注ぐことにしました。(えらい!

UnityくさいUIを、すぐ排除できるところは排除して整えて、一応4月11日時点でクローズドアルファを鍵アカウント上ではありましたが、公開しました(しかし、多分誰も触ってないです。)

4月23日~5月1日(開発休止)

StableDiffusion web UI の個人的ブームが来てしまい、また開発が止まってしまいました。

5月2日(最終調整)

ゴールデンウィークということもあり、今度こそ完成させるぞという心持ちになりました。

TODOの書き出し

5月5日(いよいよ完成!?)

ようやく満足いくところまで到達しまして、ようやくリリースか!?と思われました

しかし問題発生です。

友人に試しに使ってみてもらったところ、どうやら動かないらしいことが判明しました。

環境依存!!!

色々調べたり試行錯誤したところGeant4のdllを、自作のGeant4 Wrapper dllと同じディレクトリに置いたら解決して、事なきを得ました

よかった~

5月6日(紹介動画)

せっかくアプリリリースするなら紹介動画作らんと損だろうということで、紹介動画を作り始めました。

紹介したいことを箇条書きにして、順番を整理して、以前買っておいたVOICEPEAK 6ナレーターセットを使ってナレーションを読んでもらいました。

自分はAdobeの契約はしていないので、動画編集どうしようとなって、DaVinci Resolveが良いらしいと最近聞いていたので使ってみることにしました。

かなりいい感じでした!

1分の動画なので、それなりに(?)すぐ作れました

5月7日(最後の問題)

事なきも得たし、はずだった…のですが、

まだ問題が残っていました。

Geant4は「データセット」というデータファイルを参照しており、これは環境変数経由で場所をみているようなのですが、つまり当然これは環境変数を設定しないことにはGeant4は動かないということになります。

つまり、単純にzipファイルを配布するだけでは動きませんし、かといってユーザーに環境変数を設定してもらうのもえぐい!ということでインストーラーの作成が必須という結論になりました。

ここでまたまたChatGPTにお世話になるのですが、Inno Setupというインストーラー作成ソフト用のスクリプトを、ほぼ全部ChatGPTに書いてもらいました。(そもそもInno Setup自体もChatGPTに教えてもらいました。)

助かる;;
ChatGPTがあって、よかった~!

完成したインストーラーがちゃんと動くかどうかのテストに関しても、昔からの友人であるところのmkcさんが「Windows Sandbox」を使うと良いぞ、ということを教えてくれたのでこれで動作確認もできました。

そして5月7日の9時、ようやくリリースを果たしました🎉

実に146日間、休止期間などを除くとだいたい90日間でどうにかたどり着くことができました。こういうのは勢いが大事ですね…

やってよかったこと・反省など

Geant4について

  • Geant4の学習は初心者講習会の資料が一番いいです

  • ChatGPTもGeant4知っているので色々聞くとはかどります

  • 物理屋はすでに知ってる人多いと思いますが、ハドロンのDecay ModeはPDG Liveで調べるのが良いです

  • basf2のDocumentationは実践的な情報がかなり良い情報がまとまっているので、素粒子実験オタク必見です

ネイティブプラグイン開発について

  • ネイティブプラグインのプロジェクトとは別に、コンソールアプリとしてSandbox的に試せるプロジェクトを別途立てるとがあるとデバッグしやすい

Unity開発について

  • UnityのVisualScriptingは正直微妙で少なくとも1人で開発する場合恩恵が全然ないと思うので、早々に切り捨てて正解だったと思う

便利ツール

  • とにかくあらゆる面でChatGPTが助かる。課金はやり得

  • Davinci Resolveは最高!UIもイケてるし、なんでもできる

  • VOICEPEAKもあってよかった。VOICEBOXでも良かった気もするけど…

  • Windows Sandboxでまっさらな環境で動くかどうかテストするの便利!

メンタル面

  • DiscordとかTwitterとかで進捗を常に貼ってあると、こういう感じでいつなにやってたか遡って俯瞰できていい。進捗も目に見えてわかるし、次に何をすればいいかもわかりやすい。

  • 脱線して沼にハマりそうになったけど1週間で軌道修正したのはえらいと思う!

  • 新しい技術にチャレンジすることも大事だが、新しい技術同士を並列で同時にやろうとすると効率が悪い。慣れているものと組み合わせる形でやった方がいい

  • 完璧を目指すよりまず終わらせろ」だなと…

  • とにかく終盤は最速でリリースすることだけを考えていたのが良かった

  • 開発が止まっていたとき、知り合いにめちゃくちゃケツを叩いてもらいました……ありがとうございました……頭が上がりません

今後の予定

リリースしたてではありますが、今一番優先度高いなと思っているのはオープンソース化することです。

物理屋さんはMacやLinux使ってる人も多いと思うので、クロスプラットフォーム化もやりたいですが、これは比較的重いタスクになりそうなので、優先度は低めです。声が大きければ早めに対応するかもです。

公開からすぐ、崩壊過程を同定する遊びをやってくれた人がTwitterでいたのですが、こういう遊びが楽しめるように、種類を表示したり、あえて隠したりを制御できるようにもしたいですね。

シミュレーションアプリと言いつつ、まだそんなに自由度が高くないので自由度ももう少し高めたいです。(測定器の材質を変えたりとか)

その他UI/UX向上も頑張りたいです。

教育目的での利用を念頭に置いて開発しているので、もしこういう現場で使いたいです、みたいなのがあったらお気軽にお声掛けください(それ用の機能を優先的に実装したりとかできると思うので)

その他ご連絡、ご要望、ご意見、あればTwitter( @MelvilleTw )かマシュマロなどでどうぞよろしくお願いします。


この記事が気に入ったらサポートをしてみませんか?