simepidemic HTTP Server版仕様書 ver. 1.4.0

著者:畝見達夫,作成:令和3年8月27日,修正:10月14日

このドキュメントでは,感染シミュレータ SimEpidemic の HTTP server 版における,起動オプション,クライアントとの間のプロトコル等の仕様について述べる。以前のバージョンについてはつぎのリンクを参照されたい。 1.3.61.3.51.3.41.3.31.3.21.31.2.2

SimEpidemic 個体ベース感染シミュレータ 技術文書

サーバプロセスの起動と終了

サーバソフトウェアは macOS 10.14 以降で動作するコマンドライン・アプリケーションである。 UNIX の標準的な起動方法によりバックグラウンドで実行することを想定している。 終了させるには,kill pid コマンド等によりプロセスに TERM シグナルを送る。 実行モジュールの標準的なファイル名は simepidemic である。

コマンドオプション

ポートを他のプロセスが使用していたり,サーバプロセスの停止から数秒以内に再起動した場合などでポートの確保に失敗すると,即座に停止し終了コード 2 を返す。

例:ポート番号 8001番を使用し、JSONのフォーマットに段つけと辞書キーのソートを指定して、 バックグラウンドで実行を開始する。(bash, tcsh などの場合。zsh では末尾を &! にする。)

$ simepidemic -p 8001 -f 3 &

サーバプロセスを起動したマシンで Webブラウザから http://localhost:ポート番号/ へアクセスすると, index.htmlがあれば,その内容が描画される。

ログとプロセスID

UNIX の syslog 機能の拡張である macOS の os_log を利用して,実行状況の記録を取る。 同時に情報記録用ディレクトリの直下の log_p.txt と名付けられたファイルにも出力される。 p は,10進数4桁のポート番号で,999以下の場合,左側に0が必要個数付け加わる。 例えばポート番号が 80 なら 0080,8001 ならそのまま 8001 である。 ログファイルの大きさが 1MByte を超えた場合は, その時点でのファイル名を log_p_t.txt に変更し,新たな空の log_p.txt に次のログを書き込む。 t はファイル名変更時点の年月日時刻を表す14桁の数字列で,4桁の西暦年,4桁の月日,6桁の時分秒からなる。

このディレクトリ直下の pid_p と名付けられたテキストファイルにプロセスIDを示す10進数が書き込まれる。 p はログファイルと同じく4桁のポート番号である。 サーバプログラムをコマンドで停止する場合にプロセスIDを ps コマンドなどで調べずとも, 例えばポート番号が 8000 なら下記のコマンドを使うことができる。

$ kill `cat pid_8000`

HTTP 要求と応答

クライアント側からの要求にサーバが応答する。 クライアントはエンドユーザに対してGUIなどの操作・表示手段を提供するものであり, javascript 等で書かれたコードにより制御されるWEBブラウザ等を想定する。 多くのブラウザでは,HTTPプロトコルに規定されるいくつかのヘッダが自動的に構成されるため, 以下ではプロトコルの詳細は省略し,ブラウザ上で動くプログラムの開発に必要な情報だけを記述する。

パラメータ設定実行制御など,応答としてデータを返す必要のない要求に 対しては,サーバは text/plain 型のエラー等の情報を示すデータを返す。 特に以下の説明で記述がない場合データは OK のみである。

シミュレータへの要求コマンドではなく、.html.css.js.jpg などのファイル拡張子を伴うパスが指定された場合は. 該当するファイルがホスト側に存在すれば,通常の WEB サーバと同様その内容を応答する。 ただし,動画や音声などのためのストリーミングによる発信は実装されておらず, これらのファイルを指定した場合は 415 (Unsupported Media Type) エラーになる。 .cgi.php などのサーバサイドプログラムも同様のエラーになる。 HEAD, GET, POST 以外の PUT その他のメソッドの要求は 405 (Method not allowed) エラーになる。

サーバのトップディレクトリを含め,/ で終わるパスの GET 要求に対しては,そのディレクトリに index.html ファイルが存在すれば,その内容を応答する。 トップディレクトリは,既定値では simepidemic コマンドが起動された状態での作業ディレクトリになる。 ディレクトリの位置は コマンドライン・オプション -d で, サーバプロセスの起動時に指定可能である。

稼働中のサーバソフトウェアのバージョン情報の取得 GET /version

応答として,バージョンを表現する text/plain タイプの文字列を返す。

サーバ情報の取得 GET /sysInfo

応答として,サーバの情報を含む JSON 形式の文字列を返す。 情報は辞書形式で表現され,含まれる情報は以下の表のとおりである。

情報 キー 値の形式
モデル名 model 文字列
OSバージョン os 文字列
論理コア数 ncpu 整数
実装メモリサイズ memsize 整数 (バイト数)
システム起動からの経過時間 uptime 実数 (秒)
サーバプロセスの消費メモリサイズ rss 整数 (バイト数)
CPU負荷 loadaverage 3つの実数からなる配列
温度の状態 thermalState 0〜4 の整数,大きい方が温度が高い

サーバプロセス起動時設定の取得 GET /getConfig

応答として,サーバプロセス起動時の設定情報を含む JSON 形式の文字列を返す。 情報は辞書形式で表現され,含まれるキーは, コマンドオプション に挙げた先頭に -- が付く各キーワードである。 ただし,portversion は除く。

無用なアクセスのブロック

クローラや DoS 攻撃など,外部からの無用なアクセスを抑止するため, 連続するエラーを検知した場合,その種類と頻度に応じて当該 IP アドレスからの接続を一定期間拒否する。

シミュレーション世界の生成と消去

1つのシミュレーション環境をここでは 世界 と呼ぶ。 アクセス元のブラウザまたは IP アドレス1つにつき1つの世界が既定値として割り当てられる。 1つの世界を複数のアクセス元から操作したり,1つのアクセス元での複数の世界の操作を可能とするため, 各世界には固有の文字列で表現される 世界ID が割り当てられ, 操作時にこの世界IDを指定することで,対象となる世界を特定する。 次節以降で述べるパラメータ設定などは,すべて指定されたあるいは既定値の世界に対して実行される。 複数の世界を同時に扱うのでなければ,既定値として割り当てられた世界を用いればよいので, 新たに世界を生成する必要はない。

無用な世界の増加を防ぐため,最後の操作または動作から 一定時間が経過した時点で, 世界を閉じデータを消去する。時間の既定値は20分であるが,サーバ起動時のコマンドオプション -t または --documentTimeout で指定することができる。 その後に同じブラウザまたは IP アドレスからの既定値世界に対する操作の要求があった場合は, 新たに世界が生成される。すでに消去された世界IDを伴う操作要求はエラーになる。

ブラウザの区別は既定値の世界に対するコマンドの問い合わせの中に me=文字列 を含めることで実現される。 文字列 は,他と重複のない適当な文字列でよい。 この情報がない場合はアクセス元の IP アドレスで代替されるが, NAT ルータを介した IP マスカレード等により,サーバ側から見た場合, 複数のマシンが同じ IP アドレスを共有する場合があるため注意が必要である。

既定値の世界IDの取得 GET /getWorldID

既定値世界の ID を表す文字列をテキスト text/plain として応答する。 得られた 世界ID を使って,既定値の世界を他のマシンから操作することができる。

世界の生成 GET /newWorld

新たな世界を1つ生成し,その世界 ID を表す文字列をテキスト text/plain として応答する。

世界の消去 GET /closeWorld

指定された世界IDを持つ世界を消去する。ただし,既定値世界は消去できない。

パラメータ値の取得と設定

パラメータ値の取得 GET /getParams

パラメータ名 をキー,設定するパラメータ値を値とする辞書形式の JSON データが応答される。

例:JSON の辞書形式のデータを myParams.json に保存する。

<form method="get" action="getParams" target="saveResult">
<input type="hidden" name="format" value=0>
<input type="text" name="save" value="myParams">
<input type="submit" value="保存">
</form>
応答: <iframe name="saveResult" height=20></iframe>

パラメータ値の設定 POST /setParams

シミュレーションを実行するときに使われるパラメータ値を設定する。 パラメータは,世界移動発症機序対策検査ワクチン の6種類に分類される。 詳細は,パラメータ名と型を参照。 このうち世界に分類されるパラメータは,シミュレーション開始前でなければ適用できない。 シミュレーションの途中で世界パラメータの設定を行うと,新たに指定された値は予約として記録され, 次に世界を初期化したときに反映される。

積載情報: Content-type: multipart/form-data

パラメータ名 をキー,設定するパラメータ値を値とする 辞書形式の JSON データのパートを含まなければならない。このパートのヘッダは例えば,

Content-Disposition: form-data; name="ABCDFEG"; filename="myParams.json"
Content-Type: application/json

のような形式である。ここで "ABCDEFG" は 世界ID を表す文字列である。 文字列が "default" の場合は,既定値世界が操作の対象となる。

例:ユーザが指定したファイルからパラメータを読み込み,"ABCDEFG" というIDを持つ世界に設定する。

<form method="post" action="setParams"
  enctype="multipart/form-data" target="loadParamResult">
<input type="file" name="ABCDEFG" accept="application/json">
<input type="submit" value="読み込む">
</form>
応答: <iframe name="loadParamResult"></iframe>

積載情報: Content-type: application/x-www-form-urlencoded

例:初期人口と世界の広さを設定する。

<form method="post" action="setParams">
<table>
<tr><td align="right">人口</td>
    <td><input type="number" name="populationSize"></td></tr>
<tr><td align="right">世界の大きさ</td>
    <td><input type="number" name="worldSize"></td></tr>
</table><br/>
<input type="submit" value="設定"/>
</form>

パラメータ名と型

分布は最小値,最大値,最頻値の3つの数の組で表現され, JSON形式では3つの要素からなる配列で表現される。

パラメータ名 日本語名 分類 単位 既定値 範囲 備考
populationSize 初期人口 世界 整数 10000 100-999900
worldSize 世界の大きさ 世界 整数 距離単位 360 10-999999 一辺の長さ
mesh メッシュ 世界 整数 - 18 1-999 縦横の各分割数
stepsPerDay 1日当たりステップ数 世界 整数 ステップ 16 1-999
initialInfectedRate 初期感染者の割り合い 世界 実数 % 0.1 0.-100.
initialRecovered 初期快復者の割り合い 世界 実数 % 0 0.-100.
quarantineAsymptomatic 初期無症状者の隔離率 世界 実数 % 20 0.-100.
quarantineSymptomatic 初期有症状者の隔離率 世界 実数 % 50 0.-100.
workPlaceMode 拠点位置設定 世界 整数 - 0 0-3 *1
antiVaxClusterRate 非接種者クラスタ率 世界 実数 % 60. 0.-100.
antiVaxClusterGranularity 非接種者クラスタ粒度 世界 実数 % 50. 0.-100.
antiVaxTestRate 非接種者検査率 世界 実数 % 50. 0.-100.
recoveryBias 快復開始期間と年齢の係数 世界 実数 % 150. 0.-200. \(\zeta \times 100\) v1.4
recoveryTemp 快復開始期間と年齢の係数 世界 実数 - 50. 1.-100. \(\eta\) v1.4
recoveryUpperRate 快復開始期間上限値の比 世界 実数 % 500. 100.-900. 最頻値との比 v1.4
recoveryLowerRate 快復開始期間下限値の比 世界 実数 % 40. 0.-100. 最頻値との比 v1.4
mass 質量 移動 実数 % 20. 1.-100. 個体加速度の係数
friction 摩擦 移動 実数 % 80. 0.-100. 個体速度の減衰係数
avoidance 衝突回避 移動 実数 % 50. 0.-100. 個体間の斥力
maxSpeed 制限速度 移動 実数 20距離単位/日 50. 10.-100. 短距離移動の速さ
activenessMode 活発さ最頻値 移動 実数 % 50. 0.-100. 分布の最頻値
activenessKurtosis 活発さの尖度 移動 実数 % 0. -100.-100. 分布の尖度
massBias 質量への影響 移動 実数 - 4. 0.-10. 活発さの影響
mobilityBias 移動への影響 移動 実数 % 50. 0.-100. 活発さの影響
gatheringBias 集会参加への影響 移動 実数 % 50. 0.-100. 活発さの影響
incubationBias 潜伏期間への影響 移動 実数 % 0. -100.-100. 活発さとの相関
fatalityBias 死亡期間への影響 移動 実数 % 0. -100.-100.
immunityBias 免疫有効期間への影響 移動 実数 % 0. -100.-100.
infectionProberbility 感染確率 発症機序 実数 % 50. 0.-100.
infectionDistance 感染距離 発症機序 実数 距離単位 3. .1-10.
contagionDelay 感染性の遅れ 発症機序 実数 .5 0.-10. 感染からの期間 
contagionPeak 感染性のピーク 発症機序 実数 3. 1.-10. 感染からの期間
incubation 潜伏期間 発症機序 分布 [1.,14.,5.]
fatality 発症から死亡まで 発症機序 分布 [4.,20.,16.]
therapyEfficacy 治療法の効果 発症機序 実数 % 0. 0.-100. v1.4
immuneMaxPeriod 獲得免疫最長有効期間 発症機序 実数 200. 50.-500.
immuneMaxPrdSeverity 最長になる重症度 発症機序 実数 % 50. 0.-100.
immuneMaxEfficacy 獲得免疫の最大効果 発症機序 実数 % 90. 0.-100.
immuneMaxEffcSeverity 最大効果になる重症度 発症機序 実数 % 20. 0.-100.
distancingStrength 社会的距離の強さ 対策 実数 % 50. 0.-100.
distancingObedience 社会的距離協力率 対策 実数 % 20. 0.-100.
mobilityFrequency 移動頻度 対策 分布 [40.,100.,70.]
mobilityDistance 移動距離 対策 分布 % [10.,80.,30.] 世界の大きさとの比
backHomeRate 帰宅率 対策 実数 % / 日 75. 0.-100. 長距離移動から戻る確率
gatheringFrequency 集会の頻度 対策 実数 個/面積/日 50. 0.-100.
gatheringSize 集会の大きさ 対策 分布 距離単位 [5.,20.,10.]
gatheringDuration 集会の持続時間 対策 分布 時間 [6.,24.,12.]
gatheringStrength 集会の強さ 対策 分布 % [50.,100.,80.]
gatheringParticipation 集会への参加率 対策 分布 % [40.,100.,70.]
contactTracing 接触者追跡 対策 実数 % 20. 0.-100. 捕捉率
testDelay 検査の遅れ 検査 実数 1. 0.-10.
testProcess 処理期間 検査 実数 1. 0.-10. 検査から判明まで
testInterval 検査間隔 検査 実数 2. 0.-10. 次の検査まで
testSensitivity 感度 検査 実数 % 70. 0.-100.
testSpecificity 特異度 検査 実数 % 99.8 0.-100.
subjectAsymptomatic 疑症状検査対象者 検査 実数 % 1. 0.-100.
subjectSymptomatic 有症状検査対象者 検査 実数 % 99. 0.-100.
tracingOperation 追跡後の処置 検査 整数 0 0-2 *2
vaccineTypeForTracingVaccination 追跡接種用のワクチンの種類 検査 整数 0 0-N *3
vaccinationInfo ワクチン接種 ワクチン 配列 ワクチン接種戦略
vaccineFirstDoseEfficacy 1回目接種の効果 ワクチン 実数 % 30. 0.-100. 感染リスク抑制率
vaccineMaxEfficacy ワクチン最大効果  ワクチン 実数 % 90. 0.-100.
vaccineEfficacySymp 発症防止効果 ワクチン 実数 % 95. 0.-100.
vaccineEffectDelay ワクチン効果の遅れ ワクチン 実数 14. 0.-30. 2回目接種から最大効果までの日数
vaccineEffectPeriod ワクチン有効期間 ワクチン 実数 200. 50.-500. 最大効果維持期間
vaccineEffectDecay 効果減衰期間 ワクチン 実数 100. 0.-500. 1回目接種から効果減衰開始まで
vaccineFinalRate 最終ワクチン接種率 ワクチン 配列 歳, % *4 *4 区間と率の配列

*1: 0=設定無し,1=一様分布,2=中央集中,3=人口密度地図に従う。 *2: 0=検査,1=ワクチン接種,2=両方。 *3: ワクチンの種類リストの番号 0以上。 *4: 区間の終わりを表す年齢とその区間の接種率を交互に並べた配列。 既定値は [2, 0, 12, 0, 15, 90, 20, 70, 50, 80, 65, 85, 200, 90]。 つまり,2歳以下,12歳以下は接種なし。13歳から15歳と86歳以上は 90% 接種など。

ワクチン接種戦略 は,ワクチンの種類ごとの接種戦略を表すパラーメータ辞書の配列であり, 配列要素のになる辞書は下記の項目から成る。

パラメータ名 日本語名 単位 既定値 範囲 備考
performRate 接種実施速度 実数 0. 0.-100. 1日当たり接種実施人数比
regularity 優先順位の規則性 実数 % 100. 0.-100.
priority ワクチン接種の優先順 整数 0 0-3 *4

*4: 0=ランダム,1=高齢者優先,2=中央優先,3=密集地優先。

変異ウイルスとワクチン

個々の変異ウイルスとワクチンは名前と効果を含む辞書形式のデータで表現される。 変異ウイルスの一覧,および,ワクチンの一覧がそれぞれ配列で表現される。 ここでいう効果とは,それに感染し完治した後に得られる,あるいは,接種した後に得られる免疫による感染予防効果の標準的な強さである。 個々の変異ウイルスには増殖力,個々のワクチンには2回接種の場合の接種間隔日数の情報も含まれる。

ワクチンリストの取得 GET /getVaccineList

各ワクチン情報を示す辞書形式からなる配列形式の JSON データが応答される。 辞書形式に含まれる項目は以下のとおり。

キー 値の型 意味
name 文字列 ワクチンの名称
intervalDays 整数 1回目と2回目接種の間隔(単位は日 )
intervalOn 真偽値 偽の場合は1回接種のみ
変異ウイルス名称 実数 変異ウイルスに対する予防効果の強さ係数 *

ワクチンリストの設定 POST /setVaccineList

積載情報: Content-type: multipart/form-data

ワクチン情報を要素とする配列形式の JSON データのパートを含まなければならない。 JSONデータ以外の仕様はパラメータ値の設定と同じである。

変異ウイルスリストの取得 GET /getVariantList

各変異ウイルスの情報を示す辞書形式からなる配列形式の JSON データが応答される。 辞書形式に含まれる項目は以下のとおり。

キー 値の型 意味
name 文字列 変異ウイルスの名称
reproductivity 実数 ウイルスの増殖力
変異ウイルス名称 実数 感染による獲得免疫の変異ウイルスに対する予防効果の強さ係数 *

* 1回目接種の最大効果,2回目接種後の最大効果など, ワクチンの効果に関するパラメータにこの係数を乗じた値を用いてシミュレーションが実行される。 登録されている変異ウイルスの種類数に応じて項目数は増減する。

変異ウイルスリストの設定 POST /setVariantList

積載情報: Content-type: multipart/form-data

変異ウイルスの情報を要素とする配列形式の JSON データのパートを含まなければならない。 JSONデータ以外の仕様はパラメータ値の設定と同じである。

変異ウイルスとワクチン情報の読み込み GET /loadVariantsAndVaccines

サーバ上のデータ格納用ディレクトリの直下の VariantsAndVaccines というサブディレクトリの下にあらじめ保存された変異ウイルスとワクチンの情報を, 指定された名前のファイルから読み込む。ファイルの内容は辞書の JSON 形式であり, vaccineList というキーに対応する項目に配列形式のワクチンリスト, variantList というキーに対応する項目に配列形式の変異ウイルスリストが書かれている。

対話型の実行制御

シミュレーションの実行の 開始,停止,および,初期化のコマンド1つを, 要求行に入れた GET メソッドによりクライアントからサーバへ指示する。 サーバからの応答として,問題がなければ OK がテキストとして返る。 操作対象の世界を指定するため, 以下の3つコマンドでは共通して下記の2つの問い合わせ項目のいずれかを含める。

開始: GET /start

感染者がいない状態でこのコマンドを実行した場合は,世界を初期化した後に実行を開始する。

停止: GET /stop

対象の世界が実行中の場合は,実行を中断する。再度,start コマンドを発効すると, 中断された状態から続きの実行が開始される。

初期化: GET /reset

世界を初期化し,実行前の状態にする。ただし,個体はランダムに再配置されるので, 以前とは異なる配置となり,まったく同じ実行プロセスが再現されることはない。

例:開始,停止、初期化の3つのボタン

<form method="get" target="result">
<input type="submit" value="開始" formaction="start">
<input type="submit" value="停止" formaction="stop">
<input type="submit" value="初期化" formaction="reset">
</form>
応答: <iframe name="result" width=100 height=20></iframe>

感染個体の追加 GET /addInfected

集団内の未感染個体の中からランダムに n 個体を選択し, 指定されたウイルスに感染した無症状感染者に変更する。 その時点で感染したものとし.症状の亢進が開始される。

実行の監視と結果の取得

現在のサーバ側での実行の状況あるいは実行開始からの履歴を取得する。 実行制御と同様に,操作対象の世界を指定するため, 以下の3つコマンドでは共通して me または world を問い合わせ項目のいずれかを含めることができる。

数値情報の取得 GET /getIndexes

統計指標名 をキー,指標値を値とする辞書形式の JSON データが応答される。

例:経過日数と各健康状態の現在の人数を取得し、iframe の内容として格納する。

<form method="get" action="/getIndexes" target="currentIndexes">
<input type="hidden" name="day" value=1>
<input type="hidden" name="susceptible" value=1>
<input type="hidden" name="asymptomatic" value=1>
<input type="hidden" name="symptomatic" value=1>
<input type="hidden" name="recovered" value=1>
<input type="hidden" name="died" value=1>
<input type="submit" value="現在の人口構成">
</form>
<iframe name="currentIndexes"></iframe>

分布情報の取得 GET /getDistribution

統計指標名 をキー,指標値のベクトルを値とする辞書形式の JSON データが応答される。 各ベクトルの第1要素は横軸の最小値,第2要素以降に刻みごとの値が入る。 例えば {"recoveryPeriod":[4,2,5,10,6,3,0,1]} は,快復期間の分布が 4日2人,5日5人,6日10人,7日6人,8日3人,9日0人,10日1人であることを表す。

例:潜伏期間と快復期間の分布を取得し、iframe の内容として格納する。

<form method="get" action="/getDistribution" target="distribution">
<input type="hidden" name="incubasionPeriod" value=1>
<input type="hidden" name="recoveryPeriod" value=1>
<input type="submit" value="日数の分布">
</form>
<iframe name="distribution"></iframe>

実行状況の定期的取得

Server-sent Events の機能を利用しサーバから定期的に実行状況をストリーミングにより送信する。 ストリーミングのプロセスは世界と結び付けられ,1つの世界に複数のプロセスを設定することもできる。

定期的取得の開始 GET /periodicReport

実行の状況を定期的にサーバから受け取る。 報告は実行中にのみ行い,一時停止中には報告しない。 その後に実行を再開すると,以前と同じ定期的報告も再開される。 実行制御と同様に,操作対象の世界を指定するため, me または world を問い合わせ項目のいずれかを含めることができる。

サーバからの応答は Content-Type: text/event-stream をヘッダとし, それに続き,イベントタイプ process のデータとしてストリーミングプロセスの識別子となる文字列が送信され, 続いて,指定した時間間隔でデータフィールドに JSON データが入ったイベントタイプのない情報を定期的に送信する。 JSON データの内容は report で指定した統計指標名をキー,指標値の配列を値とする辞書形式になる。 数値情報および日ごとの数値情報の場合は, すべての未送信のステップまたは日付のデータが入った配列になる。 ただし,数値情報の取得 と同様に \(1,280\times 2^n (n = 0, 1, 2,\ldots)\) ステップ(または日)を超えた場合は, \(2^n\) ステップ(または日)ごとの平均値の配列となる。 分布情報の場合は分布情報の取得 の応答と同じ形式である。 個体群の位置と健康状態の情報は,イベントタイプが population であるデータとして送信する。 データの形式は 個体の位置と健康状態の取得 の節にあるものと同じであり, 最新の状態のみを送信する。 ヘッダ送信後のストリーミングでは,サーバは圧縮されたデータを送信する。

すでに状態の定期的取得が設定されている世界に対して,このコマンドを発行した場合は, 新たな報告のストリーミングが開始される。

定期的取得の廃止 GET /quitReport

プロセスID で指定された定期的報告を中止する。 ストリーミングのための接続を切るには,ブラウザ側で EventSource.close() を実行する。

定期的取得指標の変更 GET /changeReport

プロセスID で指定された定期的報告の内容を,reportintervalpopFormat で指定されたものに変更する。省略された項目は変更されない。

例: javascript の EventSource オブジェクトを利用した報告の受け取り

<script type="text/javascript">
const browserID = "" + Date.now();
function startMonitor() {
    let request = "periodicReport?report=";
    const cboxes = document.getElementById("checkBoxes").children;
    for (var i = 0; i < cboxes.length; i ++)
        if (cboxes[i].checked)
            request += ((i == 0)? "[" : ",") + '"' + cboxes[i].name + '"';
    request += "]&interval=" + document.getElementById("interval").value
        + "&me=" + browserID;
    const evntSrc = new EventSource(request);
    evntSrc.onmessage = function (e) {
        document.getElementById("monitorText").innerHTML = e.data;
    } }
</script>
<button onclick="startMonitor()">監視開始</button>
時間間隔:<input id="interval" type="number" value="0.2" step="0.1">秒
<div id="checkBoxes">監視指標:
    <input type="checkbox" name="days" checked>日&nbsp;
    <input type="checkbox" name="asymptomatic" checked>未発症&nbsp;
    <input type="checkbox" name="symptomatic" checked>発症&nbsp;
    <input type="checkbox" name="recovered" checked>快復&nbsp;
    <input type="checkbox" name="died" checked>死亡
</div>
<div id="monitorText" width="95%" style="overflow-wrap:anywhere">
Received data will be shown here.</div>

統計指標名と型

シミュレーション過程で得られる統計指標には,ステップあるいは日ごとに変化する数値情報と, 過程開始以来の指標の分布を表す分布情報がある。

数値情報

指標の性質により,履歴,日ごと,現在数,累積に利用可能性の違いがある。

統計指標名 日本語名 単位 範囲 履歴 日ごと 現在数 累積
isRunning 実行中 真偽値 - true/false
step ステップ数 整数 - > 0
days 経過日数 実数 > 0
susceptible 未感染者数 整数 < 初期人口
asymptomatic 無症状感染者数 整数 < 初期人口
symptomatic 発症感染者数 整数 < 初期人口
recovered 快復者数 整数 < 初期人口
died 死亡者数 整数 < 初期人口
vaccinated ワクチン接種者数 整数 < 初期人口
quarantineAsymptomatic 無症状隔離数 整数 < 初期人口
quarantineSymptomatic 有症状隔離数 整数 < 初期人口
tests 検査数 整数 < 初期人口
testAsSymptom 発症者検査数 整数 < 初期人口
testAsContact 接触者検査数 整数 < 初期人口
testAsSuspected 擬症状者検査数 整数 < 初期人口
testPositive 陽性者数 整数 < 初期人口
testNegative 陰性者数 整数 < 初期人口
testPositiveRate 陽性率 実数 % 0 - 100

分布情報

全数累積統計による。 横軸の各値に該当した個体がそれまでに合計何人であったを示すベクトルで表現される。

統計指標名 日本語名 横軸 縦軸 備考
incubasionPeriod 潜伏期間 発症者の内,感染から発症まで
recoveryPeriod 快復期間 発症から快復まで
fatalPeriod 生存期間 発症から死亡まで
infects 伝染数 感染させた人数
contacts 接触者数 人日 未実装

重症度分布の推移

隔離中の個体の重症度を 均等な50段階に分類し,それぞれの区間にあてはまる個体数をベクトルとし, 経過日数分のベクトルをさらにベクトルにしたデータで表現される。 重症度 とは, 発症からその時点までの日数を各個体に割り振られた発症から死亡までの日数で割った実数値である。 統計指標名は severityStats

変異ウイルス分布の推移

隔離中の個体に感染している変異ウイルスについて, 種類別の各時点での感染者数をベクトルで表現し, それらをさらに時系列を表すベクトルにしたデータで表現される。 統計指標名は variantsStats

個体の位置と健康状態の取得

WorldMap 現在の全個体の位置と健康状態の一覧を取得する。

要求 GET /getPopulation

応答 Content-type: application/json

個体の XY座標と健康状態の種類を表す計3つの整数からなる配列を個体数分含む配列の形式で表現される。 XおよびYの値は,世界の大きさを 10,000 としたときの座標を表す整数。 健康状態は 0=未感染,1=無症状感染,2=発症,3=快復,4=死亡。 世界はフィールド病院墓地 の3つの領域に分かれており, フィールドは一辺の長さが 10,000 の正方形で,その右側に病院と墓地が配置される。 病院と墓地は,横 2,000,縦 5,000 の長方形で,病院が上,墓地が下に隣接した配置である。 病院と墓地の中の X座標は 10,000 以上,病院内の Y 座標は 5,000 以上,墓地内のY 座標は 5,000 未満である。 さらに移動中の個体についは,上の3つの整数に加え,目標位置の XY 座標を表す2つの整数と, 移動モードを表す1つの整数が加わった計6個の整数の配列で表現される。 移動モードの値の意味は,0=フィールド内移動,1=入院,2=フィールドから埋葬,3=病院から埋葬,4=退院 である。

例:現在の全個体の位置と健康状態を iframe に取り込む。

<form method="get" action="getPopulation" target="populationData">
<input type="submit" value="個体情報">
</form>
<iframe name="populationData"></iframe>

人口の大きさに比例してデータサイズが増加する。 サーバからは deflate 形式で圧縮されたデータが送られてくるが, ほとんどのブラウザでは受け取った時点で圧縮を解いてくれるので, クライアント側のプログラムは解凍処理を行う必要はない。 サーバから送出されるデータのサイズは人口1万人の場合,48〜58kバイト程度である。

要求 GET /getPopulation2

問い合わせ情報および応答ともに /getPopulation と同様であるが, 応答データにおける JSON の形式はつぎのようになる。 データ全体は5つの配列からなる配列であり,それぞれの配列は順番に 未感染,無症状感染,発症,快復,死亡に該当する個体の情報で構成される。 移動中の個体は,現在の XY座標,目標地点の XY 座標,移動モードの5つの整数からなる配列で表現される。 移動中でない個体は XY座標を表す 2つの整数からなる配列で表現される。

健康状態を個別に含む代わりに,健康状態ごとの集団として表現するので, 全体のデータ量は 2% ほど少なくなる。 また,健康状態ごとに色分けして表示する場合の計算効率の向上にも役立つ。

集団状態の保存と読み込み

シミュレーション実行を途中停止した状態で,その時点での集団の状態をサーバ内に保存し, 後にその内容を読み込みシミュレーションを続行することができる。 例えば,途中から様々に異なるパラメータ値を設定したときの推移の違いを観る場合などに役立つ。 保存の対象は,集団の状態,初期パラメータ値,および,統計指標の現在までの履歴である。 シナリオが設定されている場合は,シナリオ,シナリオの現在位置,および,現在のパラメータ値も保存される。

サーバ上に保存された状態の情報は,保存あるいは最後のアクセスから一定期間後に消去される。 この期間の長さはサーバプロセスの起動コマンド-E または --stateExprHours オプションで指定する。 既定値は1週間である。 長期間保存したい場合は,ダウンロード機能を使いクライアント側のマシンに保存し, 使用するときにアップロード機能を用いてサーバ上に保存する。 サーバが複数ある場合,あるサーバからダウンロードした状態の情報を別のサーバにアップロードすることで,複製が可能である。 アップロードされた情報のサーバ上での保持期間も同様にサーバ上で保存された場合と同じである。

サーバ上での保存: GET /saveState

保存した 状態 ID を表す文字列をテキスト text/plain として応答する。

読み込み: GET /loadState

シミュレーションが実行中の場合はエラーになる。 それ以前の状態は,読み込まれた情報で上書きされる。

サーバ上の保存情報の消去: GET /removeState

[an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive]

シナリオの設定

統計指標の変化を調べる条件とパラメータ値変更等の操作の列で表現される シナリオ を設定する。 シナリオが実行されるとパラメータ値が変化する。シミュレーション開始時点でのパラメータ値は, シナリオを設定した時点でのパラメータ値が初期値として記録され, 世界の初期化が行われるたびに,パラメータ値もその記録された値に戻る。 シナリオの設定は,世界が初期状態で停止中のときにだけ適用され, 実行が進んだ状態の場合はエラーになる。

要求 POST /setScenario

積載情報: Content-type: multipart/form-data

シナリオを表現する JSON データを含む。

例:ユーザが指定したファイルからパラメータを読み込み設定する。

<form method="post" action="setScenario"
     enctype="multipart/form-data" target="loadScenario">
<input type="file" name="upload" accept="application/json">
<input type="submit" value="読み込む">
</form>
応答: <iframe name="loadScenario" height=20></iframe>

積載情報: Content-type: x-www-form-urlencoded

上記2種類の積載情報のいずれの場合も,シナリオを表現する JSON データが空配列 [] である場合は, シナリオは消去される。

シナリオのデータ表現

シナリオは複数の,条件追加感染者数,または,操作を要素とする配列である。

追加感染者数または操作の要素が配列内で連続して存在する場合は, それらの先頭に制御が移った時点で一気にそれらすべての要素が実行される。 制御がシナリオの最後に達した場合は,それ以上シナリオは実行されない。 世界が初期化された場合は,シナリオの制御は先頭に戻る。

アプリ版の SimEpidemic バージョン 1.6.2 以降では,シナリオを JSON 形式でも保存・読込が可能になっているので、 そのシナリオパネルで編集した内容をファイルに保存し利用することが可能である。 SimEpidemic のシナリオパネルで JSON 形式で保存するには,保存先のファイル名の拡張子を json にする。

条件用の統計指標

シナリオの条件として使える統計指標は以下の表のとおり。

統計指標名 日本語名 単位 備考
days 経過日数
susceptible 未感染者数 現在数
infected 感染者数 無症状者と発症者の現在数の合計
symptomatic 発症者数 現在数
recovered 快復者数 免疫保持者の現在数
died 死亡者数 現在数=累積
quarantine 隔離数 現在数
dailyInfection 当日の新規感染者数 実数。検査とは無関係
dailySymptomatic 当日の新規発症者数
dailyRecovery 当日の新規快復者数
dailyDeath 当日の死亡者数
weeklyPositive 週間陽性数 過去7日間の陽性判明件数の合計
weeklyPositiveRate 週間陽性率 率 0.0〜1.0 過去7日間の陽性判明数を検査数で割った値

バッチジョブの投入,監視,結果の取得

1つの ジョブ は,複数の 試行 からなる。ジョブごとにパラメータとシナリオと試行の数を指定する。 同じジョブに含まれる各試行は,同じパラメータとシナリオを用いて実行される。 ただし,試行はそれぞれ独立した乱数系列が使われるため,異なる実行結果となる。 試行に使う世界は,システムが必要に応じて生成し,不要になった時点で自動的に消去される。

同時に実行可能な試行の数は,サーバプロセスの実行開始時のコマンドオプション -T あるいは --maxTrials で指定する。 既定値は4である。ジョブは投入された順に実行される。

サーバの混雑度に合わせて適応的に並列化を使えるとよい。 また,ジョブごとの優先度を制御できるとよい。

投入: POST /submitJob

指定されたジョブを投入し,ジョブIDをテキストで返す。

積載情報: Content-type: multipart/form-data

投入したいジョブを表現する JSON データを含む。

積載情報: Content-type: x-www-form-urlencoded

ジョブのデータ表現

<form method="post" action="submitJob" target="submission">
    <textarea name="job" rows="10" cols="60">
{"stopAt":100,"n":3,
"params":{"stepsPerDay":4},
"out":[
    "asymptomatic","symptomatic","recovered","died",
    "dailyTestPositive","dailyTestNegative",
    "incubasionPeriod","recoveryPeriod","fatalPeriod","infects"]}
    </textarea>
    <input type="submit" value="投入">
    </form>
<iframe name="submission" height=24 onload="getJobID(this);"></iframe>

ジョブ投入時情報の取得: GET /getJobInfo

指定したジョブが投入されたときに指定したパラメータ情報を応答する。

待ち行列の監視: GET /getJobQueueStatus

投入されたがまだ実行されていないジョブについての情報を応答する。 応答の形式は {"runningTrials": \(T\), "length": \(L\), ジョブID\(_1\): \(l_1\), ジョブID\(_2\): \(l_2,\ldots\), ジョブID\(_n\): \(l_n\)}。 \(T\) は現在実行中の試行数。\(L\) は待ち行列の長さ。つまり,未実行のジョブの数。 \(l_i\) は,ジョブID\(_i\) の待ち行列の中での位置で, 先頭の場合 0 である。問い合わせ情報に指定されたジョブが,存在しないか,終了済みか,実行中の場合は, 応答には含まれない。

ジョブの監視: GET /getJobStatus

指定したジョブの進捗を応答する。 進捗: {"notYet":\(B\), "nowProcessed":\(C\), "finished":\(F\)} それぞれ \(B\)=未開始の試行の数,\(C\)=実行中の試行のステップ数の配列,\(F\)=終了の試行の数。 \(B+|C|+F=N\) である。

ジョブの中止: GET /stopJob

指定されたジョブが実行中であれば,実行中および未実行の試行を廃棄する。 終了済みの結果は取得可能。

例:状態と実行中止ボタン

<form method="get" target="jobStatus">
    Job ID: <input class="JobID" type="text" name="job">
    <input type="submit" value="状態" formaction="getJobStatus">
    <input type="submit" value="実行中止" formaction="stopJob">
</form>
<iframe name="jobStatus" height=24 width=400></iframe>

結果の取得: GET /getJobResults

表形式データの内容

先頭行は各欄の表題の並びである。左端の欄はデータの内容により, 現在数および累積の場合は経過ステップ数,日ごとデータの場合は経過日数, 分布情報の場合は横軸の値であり,日数または人数である。その他のセルには対応する数値が入る。

JSON データでは {"jobID": ジョブID, "n": \(i\), "type": タイプ, "table": \(T\)} の形式をとる。 \(i\) は \(1\)〜\(N\) の試行番号,タイプ は上述の3つのうちの1つで表のタイプを表す。 \(T\) は表の本体であり,各行を1つの配列とし,それを行数分含む配列の形式になる。 先頭行の左端の要素は,便宜的に空文字列 "" が入る。 CSV データは,上述のとおり表ごとに別々のファイルに保存されるが, JSON データは表の配列の形式となる。

例:結果の JSON データを iframe に表示する。

<form method="get" action="getJobResults" target="jobResults">
    Job ID: <input class="JobID" type="text" name="job">
    <input type="submit" value="結果">
</form>
<iframe name="jobResults" width=400></iframe>

例:結果の CSV ファイルをダウンロードする。

<form method="get" action="getJobResults" target="jobResultSave">
    Job ID: <input class="JobID" type="text" name="job">
    File to save: <input type="text" name="save" value="MyResult">
    <input type="submit" value="保存">
</form>
<iframe name="jobResultSave" height=24></iframe>

結果記録の消去: GET /deleteJob

JSONフォーマットオプション


© Tatsuo Unemi, 2020, 2021. All rights reserved.