# データベースについて このリポジトリは、PS BoardのQAQC結果を主に管理するデータベースを扱ってる。 ```@contents Pages = ["index.md"] Depth = 4 ``` ## データベースの特徴 現時点(2024-09-13)でQAQC試験は[Google Sheetsで作成したデータベース](https://docs.google.com/spreadsheets/d/128qOseOy4QDotehYe4Wf2jj88tnwiXGVdR3NHrjcDYU/edit)でデータが管理されているが、主にデータを統合して参照するときに手作業が多く必要となり、エラーが発生する問題があった。 そこで[リレーショナルデータベース](https://ja.wikipedia.org/wiki/関係データベース)の形式にすることでより体系的にデータを扱えるようにしたのがこのリポジトリである。 データベースは[SQLite](https://www.sqlite.org/index.html)で実装されており[^1]、軽量かつ様々な手段によるアクセスが可能となっている。 [^1]: Why SQLite?: (クライアント・サーバーの形式ではなく)Cライブラリであるという点でシンプルでありながら、れっきとしたRDBMSであり、[非常に多くの場所で使われている](https://www.sqlite.org/mostdeployed.html)(例えばブラウザの履歴やブックマーク管理)。依存も少なく([SQLite is a Self Contained System](https://www.sqlite.org/selfcontained.html)にあるが、C stdlibのうち10個ほどしか使用しない)、気軽に使うことができる。 ## アクセス方法 データベースはファイルとして存在するので、そのファイルにアクセスできればよい。[^2][^3] ファイルは _TODO_ で手に入る。 データベースを読み書きするためにはライブラリが必要で、問い合わせは[SQL](https://ja.wikipedia.org/wiki/SQL)によって行うが、ラッパーを使うこともできる。 以下に使いやすいであろうライブラリ/パッケージを列挙する。[^4] - [sqlite3(コマンドラインプログラム)](https://www.sqlite.org/cli.html): 公式の提供するCLI。どこでも動く。CSVでのエクスポートもできる。 - [DB Browser for SQLite](https://sqlitebrowser.org): クロスプラットフォームなデスクトップアプリケーション。最も簡単。 - [Python sqlite3](https://docs.python.org/ja/3/library/sqlite3.html): Pythonの標準ライブラリ。すなわち(C)Pythonが入ってるならたいてい入っている。 - [SQLite Viewer Web App](https://sqliteviewer.app/), [beta版](https://beta.sqliteviewer.app/psboard_qaqc.db/table/qaqc_runs): ブラウザで動く。最も手軽。 - [SQLite.jl](https://github.com/JuliaDatabases/SQLite.jl/tree/master): Juliaのパッケージ。[Tables.jl](https://github.com/JuliaData/Tables.jl)準拠なため、[DataFrame](https://github.com/JuliaData/DataFrames.jl)やCSVに/から変換できる。 _この実装で用いられている。_ - [SQLite Studio](https://sqlitestudio.pl): デスクトップアプリケーション。 - [ROOT TSQLFile Class](https://root.cern.ch/doc/master/classTSQLFile.html): ROOTのTFile派生クラス。[チュートリアル](https://root.cern.ch/doc/master/group__tutorial__sql.html) 他にも[diesel](https://diesel.rs)や[SQLAlchemy](https://www.sqlalchemy.org)のようなORM、C/C++, tcl(いずれも[公式のチュートリアル](https://sqlite.org/quickstart.html)に載っている)、[LuaSQLite3](http://lua.sqlite.org/index.cgi/index)、[ODBCドライバ](http://www.ch-werner.de/sqliteodbc/)とODBCでアクセスできるソフト([LibreOffice Base](https://www.libreoffice.org/DISCOVER/BASE/)や[Microsoft Access](https://support.microsoft.com/ja-jp/topic/odbc-データ-ソースを管理する-b19f856b-5b9b-48c9-8b93-07484bfab5a7))でもアクセスできる。 [^2]: 大抵の関係データベース(たとえばPostgres)はサーバーでホストし、TCPでアクセスする [^3]: [sqlsync](https://github.com/orbitinghail/sqlsync)によるオンラインアクセスやRESTサーバーなどによるアクセスの案もある [^4]: このようなプログラムはいくらでもある ## データベースの構造 ![db structure](./assets/sqlite-db.svg) 四角がテーブル、その中にコラム、線でつながっているのが*FOREIGN KEY*制約を表している。 データベース作成SQLは`src/sql/create_table.sql`にある。 ## 例 ### 本番1回試験のテーブルを再現する [本番1回試験のテーブル](https://docs.google.com/spreadsheets/d/128qOseOy4QDotehYe4Wf2jj88tnwiXGVdR3NHrjcDYU/edit?pli=1&gid=408695746#gid=408695746)の情報は、 このデータベースでは主にQAQCのrunのテーブル`qaqc_runs`と一回試験結果のテーブル`qaqc_single_run_results`を参照することで得られる。 そのためのSQLは ```sql SELECT qaqc_single_run_results.psboard_id, qaqc_single_run_results.runid AS runid, qaqc_runs.run_datetime AS run_timestamp, qaqc_runs.shifter, qaqc_runs.note AS run_note, qaqc_single_run_results.qspip, qaqc_single_run_results.recov, qaqc_single_run_results.power, qaqc_single_run_results.clock, qaqc_single_run_results.asdtp, qaqc_single_run_results.reset, qaqc_single_run_results.qaqc_result, qaqc_runs.shifter, qaqc_single_run_results.note AS result_note FROM qaqc_single_run_results, qaqc_runs WHERE qaqc_single_run_results.runid = qaqc_runs.id ORDER BY qaqc_runs.run_datetime LIMIT 10; ``` である。 sqlite3 cliで試してみる。 ```sh $ sqlite3 psboard_qaqc.db SQLite version 3.46.1 2024-08-13 09:16:08 Enter ".help" for usage hints. sqlite> SELECT qaqc_single_run_results.psboard_id, qaqc_single_run_results.runid AS runid, qaqc_runs.run_datetime AS run_timestamp, qaqc_runs.shifter, qaqc_runs.note AS run_note, qaqc_single_run_results.qspip, qaqc_single_run_results.recov, qaqc_single_run_results.power, qaqc_single_run_results.clock, qaqc_single_run_results.asdtp, qaqc_single_run_results.reset, qaqc_single_run_results.qaqc_result, qaqc_runs.shifter, qaqc_single_run_results.note AS result_note FROM qaqc_single_run_results, qaqc_runs WHERE qaqc_single_run_results.runid = qaqc_runs.id ORDER BY qaqc_runs.run_datetime LIMIT 10; 76|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|0|1|hashimoto|BCID fail, BCID shift, BCID failは1回, PP ASIC 2のPLLLDが0なのにreset counterが0が1回, PPconfig_doneが立っていないが1回→新基準でクリア 75|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|2|0|2|hashimoto|always_hit_flag が立つが1回 74|24|2024-07-24T04:18:46|hashimoto||1|1|2|1|1|0|2|hashimoto|DAC read = 0 73|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|0|1|hashimoto| 68|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|0|1|hashimoto| 67|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|1|1|hashimoto|PP ASIC 3でhit efficiencyが99%が29回 66|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|0|1|hashimoto|PLLLDが0なのにreset counterが0が1回 65|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|0|1|hashimoto| 60|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|6|1|hashimoto|PPconfig_doneが 立っていないが1回 59|24|2024-07-24T04:18:46|hashimoto||1|1|1|1|1|0|1|hashimoto|PPconfig_doneが 立っていないが1回 sqlite> ``` より複雑なものが`VIEW qaqc_single_run_results`として用意されているので、`select * from qaqc_single_run_results;`をすれば結果が見れる。 ### 特定のrunでテストしたPSBoard IDをすべて表示 90以上93以下のrunidで試験したPSBoardのIDをrunidとpsboard_idの昇順で表示する。 出力はCSVで行う。 ```fish $ bat src/sql/get_psbids_for_run.sql ───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── │ File: src/sql/get_psbids_for_run.sql ───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ WITH 2 │ single AS ( 3 │ SELECT 4 │ qaqc_single_run_results.psboard_id, 5 │ qaqc_single_run_results.runid 6 │ FROM 7 │ qaqc_single_run_results 8 │ UNION 9 │ SELECT 10 │ qaqc_extra_run_results.psboard_id, 11 │ qaqc_extra_run_results.runid 12 │ FROM 13 │ qaqc_extra_run_results 14 │ ) 15 │ SELECT * 16 │ FROM single 17 │ WHERE single.runid BETWEEN 90 AND 93 18 │ ORDER BY runid, psboard_id ───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────── $ sqlite3 psboard_qaqc.db < (echo ".headers on .mode csv .once test.csv .read src/sql/get_psbids_for_run.sql" | psub) $ cat test.csv psboard_id,runid 44,90 62,90 74,90 103,90 127,90 132,90 137,90 149,90 160,90 164,90 196,90 204,90 270,90 280,90 305,90 322,90 335,90 356,90 44,93 62,93 74,93 103,93 127,93 132,93 137,93 149,93 160,93 164,93 196,93 204,93 270,93 280,93 305,93 322,93 335,93 356,93 ``` ### Juliaでの例 Juliaで試してみる。 まずは環境を有効化(このリポジトリのルートで)。 ```julia julia> pwd() |> splitpath |> last "PSBoardDataBase" (@v1.10) pkg> activate . ... (PSBoardDataBase) pkg> instantiate Precompiling project... ✓ PSBoardDataBase 1 dependency successfully precompiled in 3 seconds. 58 already precompiled. 1 dependency precompiled but a different version is currently loaded. Restart julia to access the new version ``` パッケージの読み込み。 ```julia julia> using DataFrames, SQLite, DBInterface ``` データベースへの接続とSQLの実行。 [`DataFrames.DataFrame`](@extref)で出力している。 ```julia julia> db = DBInterface.connect(SQLite.DB, "psboard_qaqc.db") SQLite.DB("psboard_qaqc.db") julia> DBInterface.execute( db, sql""" SELECT qaqc_single_run_results.psboard_id, qaqc_single_run_results.runid AS runid, qaqc_runs.run_datetime AS run_timestamp, qaqc_runs.shifter, qaqc_runs.note AS run_note, qaqc_single_run_results.qspip, qaqc_single_run_results.recov, qaqc_single_run_results.power, qaqc_single_run_results.clock, qaqc_single_run_results.asdtp, qaqc_single_run_results.reset, qaqc_single_run_results.qaqc_result, qaqc_runs.shifter, qaqc_single_run_results.note AS result_note FROM qaqc_single_run_results, qaqc_runs WHERE qaqc_single_run_results.runid = qaqc_runs.id ORDER BY qaqc_runs.run_datetime LIMIT 10; """ ) |> DataFrame 10×14 DataFrame Row │ psboard_id runid run_timestamp shifter run_note qspip recov power clock asdtp reset qaqc_result ⋯ │ Int64 Int64 String String String Int64 Int64 Int64 Int64 Int64 Int64 Int64 ⋯ ─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 76 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 0 1 ⋯ 2 │ 75 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 2 0 2 3 │ 74 24 2024-07-24T04:18:46 hashimoto 1 1 2 1 1 0 2 4 │ 73 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 0 1 5 │ 68 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 0 1 ⋯ 6 │ 67 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 1 1 7 │ 66 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 0 1 8 │ 65 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 0 1 9 │ 60 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 6 1 ⋯ 10 │ 59 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 1 0 1 2 columns omitted ``` #### 特定のpositionの結果だけをまとめ、shifterごとの数を数える。 まずはパラメーターを埋め込んだクエリを用意(コンパイル)する。 ```julia julia> stmt = DBInterface.prepare( db, sql""" SELECT qaqc_single_run_results.psboard_id, qaqc_single_run_results.runid AS runid, qaqc_runs.run_datetime AS run_timestamp, qaqc_runs.shifter, qaqc_runs.note AS run_note, qaqc_single_run_results.qspip, qaqc_single_run_results.recov, qaqc_single_run_results.power, qaqc_single_run_results.clock, qaqc_single_run_results.asdtp, qaqc_single_run_results.reset, qaqc_single_run_results.qaqc_result, qaqc_runs.shifter, qaqc_single_run_results.note AS result_note FROM qaqc_single_run_results, qaqc_runs WHERE qaqc_single_run_results.runid = qaqc_runs.id AND qaqc_single_run_results.position = (:position) ORDER BY qaqc_runs.run_datetime """ ) SQLite.Stmt(SQLite.DB("psboard_qaqc.db"), Base.RefValue{Ptr{SQLite.C.sqlite3_stmt}}(Ptr{SQLite.C.sqlite3_stmt} @0x0000000026ab73b8), Dict{Int64, Any}()) ``` 次にそのクエリをパラメーターとともに実行する。 ```julia julia> df = DBInterface.execute(stmt, (; position = 3)) |> DataFrame 34×14 DataFrame Row │ psboard_id runid run_timestamp shifter run_note qspip recov po ⋯ │ Int64 Int64 String String String Int64 Int64 In ⋯ ─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 51 24 2024-07-24T04:18:46 hashimoto 1 1 ⋯ 2 │ 47 25 2024-07-24T05:15:02 Hashimoto,Otsubo,Sube 1 1 3 │ 80 29 2024-07-24T10:12:44 Otsubo,Kondo 1 1 4 │ 180 30 2024-07-24T11:08:10 sube 1 1 5 │ 113 32 2024-07-25T00:25:45 Izumiyama,Sube 1 1 ⋯ 6 │ 171 35 2024-07-25T02:35:01 Izumiyama,Sube 1 1 7 │ 129 39 2024-07-25T05:19:04 sube Run 38 後に station1 系統を再起 … 1 1 8 │ 150 41 2024-07-25T06:53:20 Airu Makita 1 1 9 │ 212 43 2024-07-25T08:22:25 amakita 1 1 ⋯ 10 │ 232 47 2024-07-25T10:54:11 hashimoto 1 1 11 │ 165 51 2024-07-25T12:45:19 hashimoto Only Clock試験を実施 0 0 12 │ 321 66 2024-08-06T03:49:29 hashimoto QA/QC第1弾でFirmwareだけ書いてい… 1 1 13 │ 338 71 2024-08-06T08:02:09 sube ソフトウェアリセット修正版のFirm… 1 1 ⋯ 14 │ 277 72 2024-08-06T08:42:13 sube 通常の1回試験 1 1 15 │ 357 75 2024-08-06T11:05:22 sube 通常の1回試験 1 1 16 │ 346 78 2024-08-07T00:33:06 hashimoto 通常の1回試験 1 1 17 │ 383 81 2024-08-07T03:21:13 hashimoto 通常の1回試験 1 1 ⋯ 18 │ 241 83 2024-08-07T04:39:42 skondo 通常の1回試験 1 1 19 │ 255 85 2024-08-07T06:18:09 makita 通常の1回試験 3 1 20 │ 375 87 2024-08-07T07:44:16 makita 通常の1回試験 1 1 21 │ 44 89 2024-08-08T02:49:55 sube B-0-3, B-1-3, B-0-2, B-1-2はDAC=… 1 1 ⋯ 22 │ 393 94 2024-08-09T01:08:51 kondo 追試(1回試験) 1 1 23 │ 403 98 2024-09-10T03:49:53 otsubo 通常の1回試験 のつもりがSDカード… 1 1 24 │ 421 100 2024-09-10T06:15:35 tagami 通常の1回試験 1 1 25 │ 439 103 2024-09-10T07:32:45 tagami 通常の1回試験 1 1 ⋯ 26 │ 457 105 2024-09-10T08:38:26 tagami 通常の1回試験 1 1 27 │ 475 107 2024-09-10T10:03:58 tagami 通常の1回試験 1 1 28 │ 493 117 2024-09-11T02:13:40 tagami 通常の1回試験(station 1 JatHub … 1 1 29 │ 511 120 2024-09-11T03:41:25 tagami 通常の1回試験 1 1 ⋯ 30 │ 529 122 2024-09-11T05:04:29 kmaki 通常の1回試験 1 1 31 │ 547 126 2024-09-11T06:30:42 tagami 通常の1回試験 1 1 32 │ 564 128 2024-09-11T07:32:48 tagami 通常の1回試験 1 1 33 │ 582 130 2024-09-11T08:25:46 muzuochi 通常の1回試験 1 1 ⋯ 34 │ 491 132 2024-09-12T02:31:20 tagami 1回試験追試。メザニン交換5台+cl… 1 1 7 columns omitted ``` 日付の型を変換する。 ```julia julia> transform!(df, :run_timestamp => ByRow(DateTime) => :run_timestamp) 34×14 DataFrame Row │ psboard_id runid run_timestamp shifter run_note qspip recov po ⋯ │ Int64 Int64 DateTime String String Int64 Int64 In ⋯ ─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 51 24 2024-07-24T04:18:46 hashimoto 1 1 ⋯ 2 │ 47 25 2024-07-24T05:15:02 Hashimoto,Otsubo,Sube 1 1 3 │ 80 29 2024-07-24T10:12:44 Otsubo,Kondo 1 1 4 │ 180 30 2024-07-24T11:08:10 sube 1 1 5 │ 113 32 2024-07-25T00:25:45 Izumiyama,Sube 1 1 ⋯ 6 │ 171 35 2024-07-25T02:35:01 Izumiyama,Sube 1 1 7 │ 129 39 2024-07-25T05:19:04 sube Run 38 後に station1 系統を再起 … 1 1 8 │ 150 41 2024-07-25T06:53:20 Airu Makita 1 1 9 │ 212 43 2024-07-25T08:22:25 amakita 1 1 ⋯ 10 │ 232 47 2024-07-25T10:54:11 hashimoto 1 1 11 │ 165 51 2024-07-25T12:45:19 hashimoto Only Clock試験を実施 0 0 12 │ 321 66 2024-08-06T03:49:29 hashimoto QA/QC第1弾でFirmwareだけ書いてい… 1 1 13 │ 338 71 2024-08-06T08:02:09 sube ソフトウェアリセット修正版のFirm… 1 1 ⋯ 14 │ 277 72 2024-08-06T08:42:13 sube 通常の1回試験 1 1 15 │ 357 75 2024-08-06T11:05:22 sube 通常の1回試験 1 1 16 │ 346 78 2024-08-07T00:33:06 hashimoto 通常の1回試験 1 1 17 │ 383 81 2024-08-07T03:21:13 hashimoto 通常の1回試験 1 1 ⋯ 18 │ 241 83 2024-08-07T04:39:42 skondo 通常の1回試験 1 1 19 │ 255 85 2024-08-07T06:18:09 makita 通常の1回試験 3 1 20 │ 375 87 2024-08-07T07:44:16 makita 通常の1回試験 1 1 21 │ 44 89 2024-08-08T02:49:55 sube B-0-3, B-1-3, B-0-2, B-1-2はDAC=… 1 1 ⋯ 22 │ 393 94 2024-08-09T01:08:51 kondo 追試(1回試験) 1 1 23 │ 403 98 2024-09-10T03:49:53 otsubo 通常の1回試験 のつもりがSDカード… 1 1 24 │ 421 100 2024-09-10T06:15:35 tagami 通常の1回試験 1 1 25 │ 439 103 2024-09-10T07:32:45 tagami 通常の1回試験 1 1 ⋯ 26 │ 457 105 2024-09-10T08:38:26 tagami 通常の1回試験 1 1 27 │ 475 107 2024-09-10T10:03:58 tagami 通常の1回試験 1 1 28 │ 493 117 2024-09-11T02:13:40 tagami 通常の1回試験(station 1 JatHub … 1 1 29 │ 511 120 2024-09-11T03:41:25 tagami 通常の1回試験 1 1 ⋯ 30 │ 529 122 2024-09-11T05:04:29 kmaki 通常の1回試験 1 1 31 │ 547 126 2024-09-11T06:30:42 tagami 通常の1回試験 1 1 32 │ 564 128 2024-09-11T07:32:48 tagami 通常の1回試験 1 1 33 │ 582 130 2024-09-11T08:25:46 muzuochi 通常の1回試験 1 1 ⋯ 34 │ 491 132 2024-09-12T02:31:20 tagami 1回試験追試。メザニン交換5台+cl… 1 1 7 columns omitted ``` シフターごとにグループ化。 ```julia julia> gdf = groupby(df, :shifter) GroupedDataFrame with 14 groups based on key: shifter First Group (6 rows): shifter = "hashimoto" Row │ psboard_id runid run_timestamp shifter run_note qspip recov power clock ⋯ │ Int64 Int64 DateTime String String Int64 Int64 Int64 Int64 ⋯ ─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 51 24 2024-07-24T04:18:46 hashimoto 1 1 1 1 ⋯ 2 │ 232 47 2024-07-25T10:54:11 hashimoto 1 1 1 1 ⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋱ 5 │ 346 78 2024-08-07T00:33:06 hashimoto 通常の1回試験 1 1 1 1 6 │ 383 81 2024-08-07T03:21:13 hashimoto 通常の1回試験 1 1 1 1 5 columns and 2 rows omitted ⋮ Last Group (1 row): shifter = "muzuochi" Row │ psboard_id runid run_timestamp shifter run_note qspip recov power clock asdtp reset qaqc_re ⋯ │ Int64 Int64 DateTime String String Int64 Int64 Int64 Int64 Int64 Int64 Int64 ⋯ ⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋱ 3 columns and 1 row omitted ``` グループごとに行数を数えて集計。 ```julia julia> combine(gdf, nrow) 14×2 DataFrame Row │ shifter nrow │ String Int64 ─────┼────────────────────────────── 1 │ hashimoto 6 2 │ Hashimoto,Otsubo,Sube 1 3 │ Otsubo,Kondo 1 4 │ sube 6 5 │ Izumiyama,Sube 2 6 │ Airu Makita 1 7 │ amakita 1 8 │ skondo 1 9 │ makita 2 10 │ kondo 1 11 │ otsubo 1 12 │ tagami 9 13 │ kmaki 1 14 │ muzuochi 1 ``` #### 8月以降かつ試験をパスしなかったものを表示 8月以降の結果を取得(データフレームを上書き)。 ```julia julia> filter!(:run_timestamp => >(Date(2024, 8)), df) 23×14 DataFrame Row │ psboard_id runid run_timestamp shifter run_note qspip recov power clock ⋯ │ Int64 Int64 DateTime String String Int64 Int64 Int64 Int64 ⋯ ─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 321 66 2024-08-06T03:49:29 hashimoto QA/QC第1弾でFirmwareだけ書いてい… 1 1 1 1 ⋯ 2 │ 338 71 2024-08-06T08:02:09 sube ソフトウェアリセット修正版のFirm… 1 1 1 1 3 │ 277 72 2024-08-06T08:42:13 sube 通常の1回試験 1 1 1 1 4 │ 357 75 2024-08-06T11:05:22 sube 通常の1回試験 1 1 1 1 5 │ 346 78 2024-08-07T00:33:06 hashimoto 通常の1回試験 1 1 1 1 ⋯ 6 │ 383 81 2024-08-07T03:21:13 hashimoto 通常の1回試験 1 1 1 1 7 │ 241 83 2024-08-07T04:39:42 skondo 通常の1回試験 1 1 1 1 8 │ 255 85 2024-08-07T06:18:09 makita 通常の1回試験 3 1 2 3 9 │ 375 87 2024-08-07T07:44:16 makita 通常の1回試験 1 1 1 1 ⋯ 10 │ 44 89 2024-08-08T02:49:55 sube B-0-3, B-1-3, B-0-2, B-1-2はDAC=… 1 1 1 1 11 │ 393 94 2024-08-09T01:08:51 kondo 追試(1回試験) 1 1 1 1 12 │ 403 98 2024-09-10T03:49:53 otsubo 通常の1回試験 のつもりがSDカード… 1 1 1 1 13 │ 421 100 2024-09-10T06:15:35 tagami 通常の1回試験 1 1 1 1 ⋯ 14 │ 439 103 2024-09-10T07:32:45 tagami 通常の1回試験 1 1 1 1 15 │ 457 105 2024-09-10T08:38:26 tagami 通常の1回試験 1 1 1 1 16 │ 475 107 2024-09-10T10:03:58 tagami 通常の1回試験 1 1 1 1 17 │ 493 117 2024-09-11T02:13:40 tagami 通常の1回試験(station 1 JatHub … 1 1 1 1 ⋯ 18 │ 511 120 2024-09-11T03:41:25 tagami 通常の1回試験 1 1 1 1 19 │ 529 122 2024-09-11T05:04:29 kmaki 通常の1回試験 1 1 1 1 20 │ 547 126 2024-09-11T06:30:42 tagami 通常の1回試験 1 1 1 1 21 │ 564 128 2024-09-11T07:32:48 tagami 通常の1回試験 1 1 1 1 ⋯ 22 │ 582 130 2024-09-11T08:25:46 muzuochi 通常の1回試験 1 1 1 1 23 │ 491 132 2024-09-12T02:31:20 tagami 1回試験追試。メザニン交換5台+cl… 1 1 1 1 5 columns omitted ``` 列名を取得。 ```julia julia> names(df) 14-element Vector{String}: "psboard_id" "runid" "run_timestamp" "shifter" "run_note" "qspip" "recov" "power" "clock" "asdtp" "reset" "qaqc_result" "shifter_1" "result_note" ``` 試験をパスしなかったものを選択。 ```julia julia> filter(:qaqc_result => !=(1), df) 1×14 DataFrame Row │ psboard_id runid run_timestamp shifter run_note qspip recov power clock asdtp reset qaqc_res ⋯ │ Int64 Int64 DateTime String String Int64 Int64 Int64 Int64 Int64 Int64 Int64 ⋯ ─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 255 85 2024-08-07T06:18:09 makita 通常の1回試験 3 1 2 3 2 2 ⋯ 3 columns omitted ```