kuroの覚え書き

96の個人的覚え書き

おんどとりをwindows以外でどうにかするための調査

別途公開の通信プロトコルを使用し、お客様ご自身でソフトウェアを作成していただければシリアル通信が可能となります。その場合、オプションのシリアル通信ケーブル( T R - 0 7 C )が 必 要 で す 。
と取説には書かれているが、どこにも公開されている感じがない。問い合わせれば教えてくれるのか。

gwwiki.icrr.u-tokyo.ac.jp
Macでwineを使ってWindowsアプリを使う試みらしいのだが、USBで接続してコントロールができないとか言っている。そもそもTR-7Uiシリーズではないような。

github.com
普通にUSBで繋いでシリアル通信できるということなんだろうか。

mi2yo4.blog136.fc2.com
シリアルケーブル経由が一番簡単なんだろうな。別売りケーブルが4000円以上するのがいかがなものか。あとUSBーシリアル変換は色々と面倒な気もする。


www.silabs.com
とりあえずMac用のUSB-シリアルドライバはここからダウンロードしてインストールできるっぽい。と思ったが、どうも最近のVenturaとかの新しめのOSには対応してないとか。

Rのベンチマーク

#パッケージのインストール
install.packages("devtools")
devtools::install_github("csgillespie/benchmarkme")

注:色々とエラーが出て、それを一つずつ潰していく必要がある。
あまりに色々やったのでなにがクリティカルだったのかわからん。
Ubuntuの情報が豊富で、なんとかなったが、Alma Linux8.7とMacではそもそもインストールがまだ成功していない。
なのでこのマシンの速度が速いのかなんなのか比較できていない。

#パッケージの読み込み
library("benchmarkme")

> res<-benchmark_std()
# Programming benchmarks (5 tests):
	3,500,000 Fibonacci numbers calculation (vector calc): 0.231 (sec).
	Grand common divisors of 1,000,000 pairs (recursion): 0.485 (sec).
	Creation of a 3,500 x 3,500 Hilbert matrix (matrix calc): 0.37 (sec).
	Creation of a 3,000 x 3,000 Toeplitz matrix (loops): 1.17 (sec).
	Escoufier's method on a 60 x 60 matrix (mixed): 0.699 (sec).
# Matrix calculation benchmarks (5 tests):
	Creation, transp., deformation of a 5,000 x 5,000 matrix: 0.595 (sec).
	2,500 x 2,500 normal distributed random matrix^1,000: 0.18 (sec).
	Sorting of 7,000,000 random values: 0.536 (sec).
	2,500 x 2,500 cross-product matrix (b = a' * a): 1.05 (sec).
	Linear regr. over a 5,000 x 500 matrix (c = a \ b'): 0.11 (sec).
# Matrix function benchmarks (5 tests):
	Cholesky decomposition of a 3,000 x 3,000 matrix: 0.638 (sec).
	Determinant of a 2,500 x 2,500 random matrix: 0.761 (sec).
	Eigenvalues of a 640 x 640 random matrix: 0.369 (sec).
	FFT over 2,500,000 random values: 0.294 (sec).
	Inverse of a 1,600 x 1,600 random matrix: 0.635 (sec).

> plot(res)
You are ranked 43 out of 749 machines.
Press return to get next plot 
You are ranked 33 out of 747 machines.
Press return to get next plot 
You are ranked 48 out of 747 machines.

> get_cpu()
$vendor_id
[1] "GenuineIntel"

$model_name
[1] "Intel(R) Xeon(R) CPU E3-1281 v3 @ 3.70GHz"

$no_of_cores
[1] 8

> get_r_version()
$platform
[1] "x86_64-pc-linux-gnu"

$arch
[1] "x86_64"

$os
[1] "linux-gnu"

$system
[1] "x86_64, linux-gnu"

$status
[1] ""

$major
[1] "4"

$minor
[1] "3.1"

$year
[1] "2023"

$month
[1] "06"

$day
[1] "16"

$`svn rev`
[1] "84548"

$language
[1] "R"

$version.string
[1] "R version 4.3.1 (2023-06-16)"

$nickname
[1] "Beagle Scouts"


Alma Linux8.7でもできた。

> res <- benchmark_std()
# Programming benchmarks (5 tests):
	3,500,000 Fibonacci numbers calculation (vector calc): 0.39 (sec).
	Grand common divisors of 1,000,000 pairs (recursion): 0.416 (sec).
	Creation of a 3,500 x 3,500 Hilbert matrix (matrix calc): 0.226 (sec).
	Creation of a 3,000 x 3,000 Toeplitz matrix (loops): 1.05 (sec).
	Escoufier's method on a 60 x 60 matrix (mixed): 0.805 (sec).
# Matrix calculation benchmarks (5 tests):
	Creation, transp., deformation of a 5,000 x 5,000 matrix: 0.389 (sec).
	2,500 x 2,500 normal distributed random matrix^1,000: 0.35 (sec).
	Sorting of 7,000,000 random values: 0.758 (sec).
	2,500 x 2,500 cross-product matrix (b = a' * a): 0.0517 (sec).
	Linear regr. over a 5,000 x 500 matrix (c = a \ b'): 0.201 (sec).
# Matrix function benchmarks (5 tests):
	Cholesky decomposition of a 3,000 x 3,000 matrix: 1.09 (sec).
	Determinant of a 2,500 x 2,500 random matrix: 0.729 (sec).
	Eigenvalues of a 640 x 640 random matrix: 15.7 (sec).
	FFT over 2,500,000 random values: 0.102 (sec).
	Inverse of a 1,600 x 1,600 random matrix: 1.26 (sec).
> plot(res)
You are ranked 18 out of 93 machines.
Press return to get next plot 
You are ranked 24 out of 93 machines.
Press return to get next plot 
You are ranked 93 out of 93 machines.
> get_cpu()
$vendor_id
[1] "AuthenticAMD"

$model_name
[1] "AMD EPYC 7413 24-Core Processor"

$no_of_cores
[1] 48


Rは基本シングルコアで動作するから、24コアだけどクロックの遅いAMD EPYCより4コアでクロックの速いHaswellのXeonのほうが、ある部分では優っているかもしれない。

AlmaLinux8.7にRStudioをインストール

あんまりRは得意ではないんですが、入れてくれという希望があったためAlmaLinuxに入れてみる。

CentOS8にインストールした事例をいくつかみてみたところ

$ sudo dnf install epel-release
$ sudo dnf config-manager --set-enabled PowerTools

としろ、と書かれていたが、うまくいかない。

$ sudo dnf config-manager --set-enabled powertools

こちらに変わった模様。で、

$ sudo dnf install R-core-devel
$ R

R version 4.3.1 (2023-06-16) -- "Beagle Scouts"
Copyright (C) 2023 The R Foundation for Statistical Computing
Platform: x86_64-redhat-linux-gnu (64-bit)
以下略

$ which R
/usr/bin/R

これでいいようだ。

次にRStudio server
MacなどのデスクトップアプリではなくLinux用にはWebアプリとして作られているようで、サーバアプリをインストールして、Webブラウザ経由で操作するらしい。

$ sudo curl -O https://download2.rstudio.org/server/rhel8/x86_64/rstudio-server-rhel-2023.06.1-524-x86_64.rpm
$ sudo dnf install rstudio-server-rhel-2023.06.1-524-x86_64.rpm
$ sudo firewall-cmd --permanent --add-port=8787/tcp
$ sudo firewall-cmd --reload

これでサーバは自動で起動されているので
http://localhost:8787/
にアクセスすればRStudioが使えるはず。


このようにログインを促されるので一般ユーザでログインし

このような見慣れた画面にたどり着く。
ただ、一般ユーザではモジュールのインストールができないっぽいのでちょっと不便かな。
追記:一般ユーザでもインストールはできるが、場合によってはシステムの方に不足があってインストールがエラーになる場合がある。その時は管理者権限が必要になってくる

WSL2でwindows10にext4フォーマットのHDDをマウント

自宅サーバはほぼラボサーバのデータバックアップ用でしかなかったので、Windowsに置き換えることにした。データバックアップディスクをwindowsのフォーマットにしてもいいといえばいいが、ext4のままのほうが楽といえば楽なのでそのままマウントできる方法を模索した。
結果、結構面倒くさいことが判明。
手順を覚えていられる自信がないので書いておく。

まずext4のディスクをつなぐ。今回biosをいじってsataのホットプラグを有効にしたので、HDDをラックにガチャンとはめ込んでやる。その状態では全くマウントされないのでまずはWindowsに認識されるようにする。
powershellを管理者で開き、

> GET-CimInstance -query "SELECT * from Win32_DiskDrive"
DeviceID           Caption              Partitions Size          Model
--------           -------              ---------- ----          -----
\\.\PHYSICALDRIVE1 ST4000VN008-2DR166   1          4000784417280 ST4000VN008-2DR166
\\.\PHYSICALDRIVE0 WDC WD10EARX-32N0YB0 3          1000202273280 WDC WD10EARX-32N0YB0

\\.\PHYSICALDRIVE1がホットプラグしたHDDなので

>wsl --mount \\.\PHYSICALDRIVE1 --bare
この操作を正しく終了しました。

このようにマウントする。しかしこの状態ではext4フォーマットは読めるようにはなっておらず、続いてUbuntuでマウントしてやる。
Ubuntuを起動し、プロンプトに

$ sudo fdisk -l
[sudo] password for kkuro:
Disk /dev/ram0: 64 MiB, 67108864 bytes, 131072 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

中略

Disk /dev/sdc: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: ST4000VN008-2DR1
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 7ACA6F87-4951-4650-BD60-48A486258E88

Device     Start        End    Sectors  Size Type
/dev/sdc1   2048 7814035455 7814033408  3.6T Linux filesystem


Disk /dev/sdd: 1 TiB, 1099511627776 bytes, 2147483648 sectors
Disk model: Virtual Disk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

このようになっている。ここで/dev/sddがWindowsの起動ディスクで、/dev/sdcがext4のHDD

$ sudo mkdir /media/hdd1
$ sudo mount /dev/sdc1 /media/hdd1

という風にマウントしてやる。
これでやっとファイルエクスプローラーのLinux>Ubuntu>media>hdd1にHDDの中身が出てくる。

なお/etc/fstabで自動マウントはできないっぽい。

HDDを取り外すときはまずUbuntu

$sudo umount /media/hdd1

とし、powershell

> wsl --unmount  \\.\PHYSICALDRIVE1

これで多分引っこ抜いても大丈夫なんじゃないかな。

INGOR.1.0.0

理研の玉田さんのSiGN-BNによるベイジアンネットワーク解析を利用させてもらっている。

データサンプルとしてRNA-seqデータを投入しているのだが、久々にやり直してみようと思ったらうまく動かない。
実行履歴をもとに同じコマンドを投げても動かないのだ。

どうやらこの間にスパコンのCPUがIntel XeonからAMD EPYCに置き換わり、AVX等の環境が変わったために以前のバイナリsignbnnnsr.0.16.7がエラーを吐いて止まってしまうのだ。


以下はとりあえずの覚書

qsub -o so -e se -pe mpi-fillup 2 ~tamada/sign/signmpi.sh ~tamada/sign/signbnnnsr.0.16.7 -o result all.edf.txt

qstatでモニターしているとすぐにランが終わってしまい、

$ cat result.log 
! ABSOLUTELY NO WARRANTY.  ALL RIGHTS RESERVED.
! THIS BINARY IS PERMITTED FOR HGC Supercomputer System Shirokane5 ONLY.

SiGN-BN NNSR Rel. 0.16.7
  rank=0, processes=2, threads=1
THIS IS THE ROOT PROCESS.
Initialization finished at Tue Jul 7 17:59:06 2023
HOSTNAME: gc275i
Random Seed:	1689065946
Random Walk Interval: 1280
Exchange Interval: 1280
1-to-1 Interval: --
Reading the input data matrix.
  file: all.edf.txt
  84526 nodes  x  36 samples read.
  Requires 24,343,488 [bytes] (23 [MiB])
  nodes = 84526, samples = 36
Broadcasting the input data matrix  at Tue Jul 7 17:59:26 2023
Sent the input matrix size.
  at Tue Jul 11 17:59:27 2023
Broadcasting input values.
  Done at Tue Jul 11 17:59:27 2023

というところでとまってしまっている。
そして

$ cat so
-catch_rsh /var/spool/ge/gc275i/active_jobs/78340293.1/pe_hostfile
gc275i
gc335i
-------------------------------------------------------
Primary job  terminated normally, but 1 process returned
a non-zero exit code. Per user-direction, the job has been aborted.
-------------------------------------------------------

となる。
なにも言わずに終わることもあれば、

  • pe mpi-fillup 8

とかにすると更にcoreを吐き始める。

あれ?
THIS BINARY IS PERMITTED FOR HGC Supercomputer System Shirokane5 ONLY.
ってもしかして今のシステムはShirokane6になってEPYCにCPUも替わっているよね。それで?

ということで玉田さんのディレクトリを見るとingor.1.0.0-MPIというバイナリがおいてある。これか?
ってことで

qsub -e se2 -o so2 -pe mpi-fillup 4 ~tamada/sign/ingor_mpi.sh ~tamada/sign/ingor.1.0.0-MPI -a nnsr all0.edf.txt

としてみるも

$ cat result.log 
INGOR release 1.0.0 (hash: f5e3722) (Thu Nov 17 20:10:45 2022)
  Copyright (C) 2018-2022 Yoshinori Tamada
MPI enabled: size=4, rank=0
Random seed:	1689069008
input file: nbn_all0.edf.txt
Max memory: 1,048,576,000 [Byte] (1,000 [MiB])
candidates: 10
maxParents: 10
Reading input data file: all0.edf.txt
  Done.  # of missing values=0.
[MPI] Broadcasting the read data...
[MPI] Finished.
WARNING: zero minimum value detected for ID=159 (s00160g00730)
ID=159; s00160g00730 (real); min=0.000, max=1153.841, mean=438.254, var=74813.518, sd=273.521, mv=0

・・・・

WARNING: zero minimum value detected for ID=52739 (s00060g00410)
ID=52739; s00060g00410 (real); min=0.000, max=0.001, mean=0.000, var=0.000, sd=0.000, mv=0
  variables = 52740,   samples = 36
  varialbe types:
    real: 52740
  Variable attributes: (Nothing)
Continuous variables: 52740
Discrete variables: 0
candidates: 10
candidatesCont: 0
candidatesDisc: 0
maxParents: 10
maxParentsCont: -1
maxParentsDisc: 2
Output file type: nodelist
Algorithm: nnsr
NNSR{0}: subNodes=13185, mrows=52737, subNodesMax=13185
NNSR{0}: sub graph 1: 2,781,349,380 [bytes]
FATAL ERROR (999999): NNSRWork_alloc: Memory allocation failed.
  algo/NNSR.c:558; 2,781,349,380 [bytes]

一筋縄でいかないな。
zero minimum value detectedてことは数値が0はだめなんだったっけ。
てことですべての項目に1を足すというこの手の処理でよくやる前処理をしてみる。

$ qsub -pe mpi-fillup 4 -e se3 -o so3 ~tamada/sign/ingor_mpi.sh ~tamada/sign/ingor.1.0.0-MPI -a nnsr -o result all1.edf

だめっぽい

$ cat result.log 
INGOR release 1.0.0 (hash: f5e3722) (Thu Nov 17 20:10:45 2022)
  Copyright (C) 2018-2022 Yoshinori Tamada
MPI enabled: size=4, rank=0
Random seed:	1689069627
input file: nbn_all1.edf
Max memory: 1,048,576,000 [Byte] (1,000 [MiB])
candidates: 10
maxParents: 10
Reading input data file: nbn_all1.edf
  Done.  # of missing values=0.
[MPI] Broadcasting the read data...
[MPI] Finished.
  variables = 52740,   samples = 36
  varialbe types:
    real: 52740
  Variable attributes: (Nothing)
Continuous variables: 52740
Discrete variables: 0
candidates: 10
candidatesCont: 0
candidatesDisc: 0
maxParents: 10
maxParentsCont: -1
maxParentsDisc: 2
Output file type: nodelist
Algorithm: nnsr
NNSR{0}: subNodes=13185, mrows=52737, subNodesMax=13185
NNSR{0}: sub graph 1: 2,781,349,380 [bytes]
FATAL ERROR (999999): NNSRWork_alloc: Memory allocation failed.
  algo/NNSR.c:558; 2,781,349,380 [bytes]

$ cat se3
--------------------------------------------------------------------------
Primary job  terminated normally, but 1 process returned
a non-zero exit code. Per user-direction, the job has been aborted.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
mpirun detected that one or more processes exited with non-zero status, thus causing
the job to be terminated. The first process to do so was:

  Process name: [[64572,1],0]
  Exit code:    63
--------------------------------------------------------------------------

あかんね。

この件、結局未解決で、かわりといっちゃーなんだが、signbnnnsr.0.16.8のLinuxバイナリをオンプレミスにダウンロードしてやると見事MPI環境で3ノード72スロットで動作させることができたため、一旦は良しとすることにした。

UbuntuでSlurm

ローカルで運用しているUbuntu20.04にジョブスケジューラを入れよう、ということで最初Torqueを入れようとした。

sudo apt install torque-server torque-mom

しかしそんなものはないと言われる。aptのほうでももうメンテナンスされてないんだね。
ということでAlma Linuxに入れたSlurmを入れることにする。
まずは下ごしらえでユーザー設定など。

sudo groupadd -g 5000 slurm
sudo useradd -M -d /var/lib/slurm -s /sbin/nologin -u 5000 -g slurm slurm
sudo groupadd -g 5001 munge
sudo  useradd -M -d /var/lib/munge -s /bin/bash -u 5001 -g munge munge

sudo mkdir -p /var/lib/slurm/spool
sudo mkdir -p /var/log/slurm

sudo chown -R slurm:slurm /var/log/slurm
sudo chown -R slurm:slurm /var/lib/slurm

そしてmungeのインストール

sudo apt install -y munge libmunge-dev

Alma Linuxのほうではここでmunge-keyをゴニョゴニョしたと思うんだけど、
qiita.com
参考にさせていただいたこちらのページではそんなことはやっていないので、要らないんだろうか。
で、Slurmはソースを取ってきてビルド。

sudo apt install -y build-essential

wget https://download.schedmd.com/slurm/slurm-23.02.3.tar.bz2
tar -jxvf slurm-23.02.3.tar.bz2
cd slurm-23.02.3/

./configure
make
sudo make install

次にslurm.confを作る。
slurm.schedmd.com
こちらのページに必要事項を入力するといい感じにconfigファイルを作ってくれるらしい。
できたファイルを以下にコピーして、ちょっとだけ追加修正してやる。

sudo nano /usr/local/etc/slurm.conf

# slurm.conf file generated by configurator easy.html.
# Put this file on all nodes of your cluster.
# See the slurm.conf man page for more information.
#
ClusterName=guilty8
SlurmctldHost=guilty8-e5800t110fe
#
#MailProg=/bin/mail
MpiDefault=none
#MpiParams=ports=#-#
ProctrackType=proctrack/cgroup
ReturnToService=1
SlurmctldPidFile=/var/run/slurmctld.pid
#SlurmctldPort=6817
SlurmdPidFile=/var/run/slurmd.pid
#SlurmdPort=6818
SlurmdSpoolDir=/var/spool/slurmd
SlurmUser=slurm
#SlurmdUser=root
StateSaveLocation=/var/spool/slurmctld
SwitchType=switch/none
TaskPlugin=task/affinity,task/cgroup
#
#
# TIMERS
#KillWait=30
#MinJobAge=300
#SlurmctldTimeout=120
#SlurmdTimeout=300
#
#
# SCHEDULING
SchedulerType=sched/backfill
SelectType=select/cons_tres
#
#
# LOGGING AND ACCOUNTING
AccountingStorageType=accounting_storage/none
#JobAcctGatherFrequency=30
JobAcctGatherType=jobacct_gather/none
#SlurmctldDebug=info
SlurmctldLogFile=/var/log/slurmctld.log
#SlurmdDebug=info
SlurmdLogFile=/var/log/slurmd.log
#
#
# COMPUTE NODES
NodeName=guilty8-e5800t110fe CPUs=8 Sockets=1 CoresPerSocket=4 ThreadsPerCore=2 State=UNKNOWN
PartitionName=debug Nodes=ALL Default=YES MaxTime=INFINITE State=UP

これでいいはずなので

sudo cp etc/slurmctld.service /etc/systemd/system
sudo cp etc/slurmd.service /etc/systemd/system

sudo systemctl start slumctld slums

と起動してやったがどちらもActive: failed と言われる。
slumctldのほうは権限がなくて/var/spool/slurmctldが作れないとのことなので

sudo mkdir -p /var/spool/slurmctld
sudo chmod 777 /var/spool/slurmctld/

としてやることで無事起動した。
一方、slurmdは

sudo systemctl status slurmd
× slurmd.service - Slurm node daemon
     Loaded: loaded (/etc/systemd/system/slurmd.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sun 2023-07-02 13:40:10 JST; 5min ago
    Process: 6779 ExecStart=/usr/local/sbin/slurmd -D -s $SLURMD_OPTIONS (code=exited, status=1/FAILURE)
   Main PID: 6779 (code=exited, status=1/FAILURE)
        CPU: 4ms

 7月 02 13:40:10 guilty8-e5800t110fe systemd[1]: Started Slurm node daemon.
 7月 02 13:40:10 guilty8-e5800t110fe slurmd[6779]: slurmd: error: Couldn't find the specified plugin name for cgroup/v2 looking at all files
 7月 02 13:40:10 guilty8-e5800t110fe slurmd[6779]: slurmd: error: cannot find cgroup plugin for cgroup/v2
 7月 02 13:40:10 guilty8-e5800t110fe slurmd[6779]: slurmd: error: cannot create cgroup context for cgroup/v2
 7月 02 13:40:10 guilty8-e5800t110fe slurmd[6779]: slurmd: error: Unable to initialize cgroup plugin
 7月 02 13:40:10 guilty8-e5800t110fe slurmd[6779]: slurmd: error: slurmd initialization failed
 7月 02 13:40:10 guilty8-e5800t110fe systemd[1]: slurmd.service: Main process exited, code=exited, status=1/FAILURE
 7月 02 13:40:10 guilty8-e5800t110fe systemd[1]: slurmd.service: Failed with result 'exit-code'.

で、Stackoverflowあたりをさまようとlibdbus-1-devを入れとけや、と言われるので

sudo apt install libdbus-1-dev

としたけど変わらない。
結局、libdbus-1-devをインストールしたあとmakeからやり直さないとだめなようで、

./configure
make
sudo make install

とすると

sudo systemctl status slurmd
● slurmd.service - Slurm node daemon
     Loaded: loaded (/etc/systemd/system/slurmd.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2023-07-02 13:45:56 JST; 30min ago
   Main PID: 26767 (slurmd)
      Tasks: 1
     Memory: 1.1M
        CPU: 15ms
     CGroup: /system.slice/slurmd.service
             └─26767 /usr/local/sbin/slurmd -D -s

 7月 02 13:45:56 guilty8-e5800t110fe systemd[1]: Started Slurm node daemon.
 7月 02 13:45:56 guilty8-e5800t110fe slurmd[26767]: slurmd: slurmd version 23.02.3 started
 7月 02 13:45:56 guilty8-e5800t110fe slurmd[26767]: slurmd: slurmd started on Sun, 02 Jul 2023 13:45:56 +0900
 7月 02 13:45:56 guilty8-e5800t110fe slurmd[26767]: slurmd: CPUs=8 Boards=1 Sockets=1 Cores=4 Threads=2 Memory=15931 TmpDisk=936080 Uptime=5890 CPUSpec>

と無事に起動した。めでたし。

Raspberry Pi 3BにMX Linux

Raspberry Piの市場流通が減り、明らかに割高な価格で取引されてきたが、最近になってようやくちょっとまともな値段に戻ってきている。とはいえ現在主流のPi4ではもともと定価ベースでもそれなりに高額になってきており、単なるIoT制御基板としてはちょっとなあ、という感じになっている。
ということで未だにPi3Bを使い続けているのだが、こちらは4と並行して流通しているはずだが、まだ市場価格は落ち着いてきていない。
まあ、それはいいとして、Pi4が主流となっているせいか、公式OSであるRaspbianはなんだかどんどん肥大して、3BでGUIを動かすにはちょっと厳しくなってきているように思う。
3Bを使い続けている層はおそらくはデスクトップ環境とかには興味がなく、ただ組み込みLinux環境が動けばそれで十分、ということなんだろうか。わたしもPi3Bをデスクトップマシンとして常用する気はさらさらないのだが、実機で開発するときにはGUIも多少動いたほうがちょっと便利なきょくめんもあるよな、ということで純正Raspbianに見切りをつけて軽量なOSを探すこととした。
目についた候補はDietPiなんだが、アイコンがちょっとどうなの?というデザインで・・・(そこか!
で、ふと目に止まったMX Linuxを試してみることにした。
Pi Imagerには登録されていないので、まずはサイトからダウンロードしてくるところから。
MX-Linux - Browse /Community_Respins/Raspberry Pi at SourceForge.net
このMXRPi_22.03.08.imgをPi Imagerの「カスタムイメージを使う」、で選択して、インストールするだけ。
インストールに先立って歯車マークをクリックし、ホスト名とか、ユーザ、無線ネットワーク関係を前もって設定しておくと、インストールと同時にその設定もやってくれるのは便利だね。

さて、インストールが完了すると自動ログインでさっき作っておいたユーザでログインしてデスクトップが表示される。確かに動作は比較的キビキビした感じではある。ブラウザを開くとかそれなりに重い動作もあるけど、ターミナルを開いたり、設定を開いたりというくらいの動作ならサクサク動く。まあ基本ネットワークの設定とかsshの設定ができてしまえば、あとはリモートからsshとかVScodeとかでアクセスしてGUIは切ってしまってもいいんだけどね。

普通のRaspberry Pi Configもあるけど

MX Toolsというユーザー管理などができるツール

さらにツールバーにはsetting managerなんてのもあり、色々設定を操作できるがちょっとややこしい。

システム関連だと、タスクマネージャがあるのはちょっといいかも。

ちょっと気になったのはターミナルのフォントが幅広すぎて見にくいくらい、ロケールの変更に伴って使われている日本語フォントのせいかな。

ssh 鍵認証

ssh鍵認証でログインしようとしたら、

% ssh hogehoge
Unable to negotiate with xxx.xxx.xxx.xxx port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
kex_exchange_identification: Connection closed by remote host
Connection closed by UNKNOWN port 65535

と出て、繋いでもらえなかった。

どうやらサーバ側はSHA-1RSA認証を使っていて、ローカル(クライアント)は廃止してしまっている、ということらしいので、
~/.ssh/configに

Host *
   HostKeyAlgorithms=+ssh-rsa
   PubkeyAcceptedAlgorithms=+ssh-rsa

この3行を追加したところ接続できるようになった。サーバ側もアップデートしたほうがセキュリティ上はいいだろうな。

ラズパイを無線ホストにする


ネット環境のない部屋にてラズパイによるデータ取得をする場合、データの回収にこまることがある。これまではそのためだけに無線ホスト(簡単には無線ルーター)をおいて、ラズパイをそこに無線または有線でつないで、別の無線端末(スマホとか)からホスト経由でsshとかウェブインターフェースで接続し、データ回収していた。ラズパイが無線ホストになってくれれば万事解決で話は早いんだけど、これまでラズパイのホスト化には成功していなかった。
今回久しぶりにトライしたところ、無事に構築できた。オマケとしてラズパイ自体をルーターとしてつかうことも可能となったので記録しておく。

やることは

  • dhcpcdを設定して無線LAN(wlan0)をstaticアドレスにする。
  • hostapdをインストールしてアクセスポイントにする。
  • dnsmasqをインストールしてDHCPサーバを建てる。
  • iptablesでポートフォワーディングすることでルーター化する。

最後の部分は今回の目的ではあくまでオマケだ。

設定としては無線ホストのアドレスを192.168.10.1とし、クライアントは192.168.10.11から192.168.10.50までにする。
DNSサーバはgoogleの8.8.8.8を利用。

使用したラズパイはRaspberry Pi 3B+
OSはRaspberry OS (64bitバージョン)Debian Bullseye

まずはdhcpcd
/etc/dhcpcd.confを編集

interface wlan0
static ip_address=192.168.10.1/24

次にhosted

$ sudo apt install hostapd 
$ sudo cp /usr/share/doc/hostapd/examples/hostapd.conf /etc/hostapd/hostapd.conf

/etc/hostapd/hostapd.confを編集

hw_mode=g
channel=6
wpa=2
auth_algs=1
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
ssid=kurotest
wpa_passphrase=Hogehoge

かなかな長大なファイルだが、入力した&確認した&コメントを外したのは上記くらいだった。

/etc/default/hostapdを編集

DAEMON_CONF="/etc/hostapd/hostapd.conf"

hostapdを起動

$ sudo systemctl unmask hostapd
$ sudo systemctl restart hostapd 

DHCPサーバーとしてはisc-dhcp-serverをインストールして使っているページが多かったのだが、うちの環境ではうまく動かなかった。(起動に失敗する)代わりにdnsmasqを使う

$ sudo apt install -y dnsmasq

/etc/dnsmasq.d/wlan0.confを編集

interface = wlan0
dhcp-range = 192.168.10.11, 192.168.10.50, 255.255.255.0, 24h
dhcp-option = option:router, 192.168.10.1
dhcp-option = option:dns-server, 8.8.8.8
listen-address = 127.0.0.1
log-queries
log-dhcp
$ sudo systemctl restart dnsmasq

ここまででラズパイを無線LANアクセスポイントかつDHCPサーバとして使えるようになったので、他の端末からラズパイに無線で直接つながって、アドレスも自動で配布してもらってアクセスできるようになった。

以下はついでなのでルーターとして有線LANの側とも橋渡ししてもらえるようにしておく。有線側がネットワークにつながっていなくてもDHCPを割り振ってもらえるようにしている都合でブリッジではなくルーターモードだ。

まずは/etc/sysctl.confを編集

net.ipv4.ip_forward=1

ここのコメントを外す。
次に

$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

これでつながったはずなのだが、これでは起動するたびに同じコマンドを入れる必要があるため、

$ sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

として
/etc/rc.localの最後の行「exit 0」の前に

iptables-restore < /etc/iptables.ipv4.nat

を入れておく。

以上。

追記
iptablesの設定をrc.localに入れるとどうもhostapdがうまく機能しなくなる。
一旦は外しておく。
外に出ることが必要なときだけコマンドであとから設定してやることにする。あくまでルーター化はおまけなので。

PythonでGO解析

これまでGO解析はDAVIDを使ってきた。特に理由はないが、まあ老舗だし。しかしインターフェースがあんまり使いやすいとは言い難く、植物のデータベースもシロイヌナズナにしか対応していない。ということでAgriGOとか他のサービスを利用してもいいのだけれど、せっかくなのでローカル(もしくは自前サーバ)で使えるツールを構築してしまおう、ということにした。

PythonでGO解析をするツールとしてはGOATOOLSくらいしか見つからなかったし、結構使えそうなので、まずはこちらを試してみる。

github.com

インストールはpython moduleなので

$ python3 -m pip install goatools

とするだけ。
ただし、これだけではだめで、GO解析に必要なGOデータを記述したOBOファイルというものがいる

wget http://geneontology.org/ontology/go-basic.obo
wget http://www.geneontology.org/ontology/subsets/goslim_generic.obo

go-basic.oboがあればとりあえず良くて、goslim_generic.oboを使うと選択されるGOが抑えられるらしい。詳細は未調査。
このOBOファイルはデフォルトではスクリプトを実行するカレントディレクトリに置いておく必要があるが、オプションでファイルを指定することも可能そうだ。

スクリプトもインストールされるので

$ find_enrichment.py
usage: 
python find_enrichment.py study.file population.file gene-association.file

This program returns P-values for functional enrichment in a cluster of study
genes using Fisher's exact test, and corrected for multiple testing (including
Bonferroni, Holm, Sidak, and false discovery rate).

About significance cutoff:
--alpha: test-wise alpha; for each GO term, what significance level to apply
        (most often you don't need to change this other than 0.05 or 0.01)
--pval: experiment-wise alpha; for the entire experiment, what significance
        level to apply after Bonferroni correction

       [-h] [--annofmt {gene2go,gaf,gpad,id2gos}] [--taxid TAXID] [--alpha ALPHA] [--pval PVAL] [--pval_field PVAL_FIELD]
       [--outfile OUTFILE] [--ns NS] [--id2sym ID2SYM] [--sections SECTIONS] [--outfile_detail OUTFILE_DETAIL] [--compare]
       [--ratio RATIO] [--prt_study_gos_only] [--indent] [--obo OBO] [--no_propagate_counts] [-r]
       [--relationships [RELATIONSHIPS ...]] [--method METHOD] [--pvalcalc {fisher_scipy_stats}] [--min_overlap MIN_OVERLAP]
       [--goslim GOSLIM] [--ev_inc EV_INC] [--ev_exc EV_EXC] [--ev_help] [--ev_help_short]
       filenames filenames filenames

positional arguments:
  filenames             data/study data/population data/association

optional arguments:
  -h, --help            show this help message and exit
  --annofmt {gene2go,gaf,gpad,id2gos}
                        Annotation file format. Not needed if type can be determined using filename (default: None)
  --taxid TAXID         When using NCBI's gene2go annotation file, specify desired taxid (default: 9606)
  --alpha ALPHA         Test-wise alpha for multiple testing (default: 0.05)
  --pval PVAL           Only print results with uncorrected p-value < PVAL. Print all results, significant and otherwise, by setting
                        --pval=1.0 (default: 0.05)
  --pval_field PVAL_FIELD
                        Only print results when PVAL_FIELD < PVAL. (default: None)
  --outfile OUTFILE     Write enrichment results into xlsx or tsv file (default: None)
  --ns NS               Limit GOEA to specified branch categories. BP=Biological Process; MF=Molecular Function; CC=Cellular
                        Component (default: BP,MF,CC)
  --id2sym ID2SYM       ASCII file containing one geneid and its symbol per line (default: None)
  --sections SECTIONS   Use sections file for printing grouped GOEA results. Example SECTIONS values:
                        goatools.test_data.sections.gjoneska_pfenning goatools/test_data/sections/gjoneska_pfenning.py
                        data/gjoneska_pfenning/sections_in.txt (default: None)
  --outfile_detail OUTFILE_DETAIL
                        Write enrichment results into a text file containing the following information: 1) GOEA GO terms, grouped
                        into sections 2) List of genes and ASCII art showing section membership 3) Detailed list of each gene and GO
                        terms w/their P-values (default: None)
  --compare             the population file as a comparison group. if this flag is specified, the population is used as the study
                        plus the `population/comparison` (default: False)
  --ratio RATIO         only show values where the difference between study and population ratios is greater than this. useful for
                        excluding GO categories with small differences, but containing large numbers of genes. should be a value
                        between 1 and 2. (default: None)
  --prt_study_gos_only  Print GO terms only if they are associated with study genes. This is useful if printng all GO results
                        regardless of their significance (--pval=1.0). (default: False)
  --indent              indent GO terms (default: False)
  --obo OBO             Specifies location and name of the obo file (default: go-basic.obo)
  --no_propagate_counts
                        Do not propagate counts to parent terms (default: False)
  -r, --relationship    Propagate counts up all relationships, (default: False)
  --relationships [RELATIONSHIPS ...]
                        Propagate counts up user-specified relationships, which include: part_of regulates negatively_regulates
                        positively_regulates (default: None)
  --method METHOD       Available methods: local( bonferroni sidak holm fdr ) statsmodels( sm_bonferroni sm_sidak holm_sidak sm_holm
                        simes_hochberg hommel fdr_bh fdr_by fdr_tsbh fdr_tsbky fdr_gbs ) (default: bonferroni,sidak,holm,fdr_bh)
  --pvalcalc {fisher_scipy_stats}
                        fisher_scipy_stats (default: fisher_scipy_stats)
  --min_overlap MIN_OVERLAP
                        Check that a minimum amount of study genes are in the population (default: 0.7)
  --goslim GOSLIM       The GO slim file is used when grouping GO terms. (default: goslim_generic.obo)
  --ev_inc EV_INC       Include specified evidence codes and groups separated by commas (default: None)
  --ev_exc EV_EXC       Exclude specified evidence codes and groups separated by commas (default: None)
  --ev_help             Print all Evidence codes, with descriptions (default: True)
  --ev_help_short       Print all Evidence codes (default: True)

このような感じ。
ちなみにスクリプト

/home/linuxbrew/.linuxbrew/bin/find_enrichment.py

ここに入っている。
オプションが色々あるが基本的には

$ find_enrichment.py ./data/at_gene_list.txt ./data/at_all_gene_list.txt ./data/at_go_association.txt  --outfile=at_go_enrichment.tsv

がデフォルトセッティングで投げるフォーマットになる。
カレントディレクトリから一つ下がったdataディレクトリに入力する遺伝子のリストat_all_gene_list.txtと全遺伝子が一列に入っているat_all_gene_list.txtと遺伝子→GOの対応付けされたファイルat_go_association.txtを入れてある。
基本的に入力する遺伝子は全遺伝子リストに載っていないとだめで、全遺伝子リストに載っている遺伝子全部についてGOが対応付けされている必要があるらしい。
シロイヌナズナならまあ問題はないが情報の充実していない種ではすべての遺伝子にGOが割り振られているとは限らないので、まずはGOのついている遺伝子だけのリストを作成し、そのリストに載っている遺伝子だけを抽出して解析にかける必要がある。

import pandas as pd
df1 = pd.read_csv('/home/kuro/goatools/data/at_gene_list.txt', header=None)
df2 = pd.read_csv('/home/kuro/goatools/data/at_all_gene_list.txt', header=None)
df = pd.concat([df1,df2],axis=0)
df3 = df[df.duplicated()]
df3.to_csv('/home/kuro/goatools/data/at_gene_list1.txt', header=None, index=False)

このようなかんたんなPythonによる処理でGOのついている遺伝子だけを取り出してやる。

あとはhelpを見ながらオプションを色々いじってみる。p-valueを設定してリストするにしてもいろいろな統計方法のp-valueが選べるし、リストに表示する統計結果も増やしたり減らしたりできる。
デフォルトの統計方法はbonferroni,sidak,holm,fdr_bhの4つとなっており、まあデフォルトでほぼ問題はなさそうではある。
デフォルトではp_uncorrected<0.05となっているようで、ここをfdr_bhのp value <0.05にしてみたり、もっと数値を上げ下げしてみるといい場合があるだろう。

$ find_enrichment.py ./data/at_gene_list.txt ./data/at_all_gene_list.txt ./data/at_go_association.txt--pval=0.01 --method bonferroni,fdr_bh --pval_field fdr_bh --outfile=at_go_enrichment.tsv, at_go_enrichment.xlsx

みたいな感じだ。
ちなみに結果はtsv、xlsxをえらべ、両方を出力することも可能。結構柔軟だ。