2016年12月12日月曜日

ガンマ振動が脳内のアミロイドβを抑制する

弱っているガンマ振動の活動を戻すと、脳内のアミロイドβの蓄積を
抑制できることが報告された([1], 解説が[2,3])。

実験には、ガンマ振動の活動が弱い、アルツハイマー病のマウスモデル(5XFAD)を
使ったとのこと。これを遺伝子操作して光でガンマ振動を発生させられるようにした。
そのマウスにガンマ振動を発生させるとアミロイドβの蓄積が抑制されることが分かった。

ガンマ振動そのものがアミロイドβを消すわけではなく、
ガンマ振動によってミクログリア(microglia)がアミロイドβが蓄積している場所に集まり、
アミロイドβを食べてしまうとのこと。

ガンマ振動を非侵襲で発生させる方法[4]もあり、光で視覚野にガンマ振動を
発生させることができる。この方法を使ってガンマ振動を発生させたところ、
視覚野のアミロイドβの蓄積も抑制できたとのこと。


[1] doi: 10.1038/nature20587
[2] http://www.natureasia.com/ja-jp/nature/highlights/81380
[3] doi: 10.1038/540207a
[4] Fries, P., Nikolic D. & Singer, W. Trends Neurosci. 30, 309-316 (2007)

2016年11月12日土曜日

WiMAXとWiMAX2+のレイテンシ比較

WiMAXの回線と、WiMAX2+の回線についてpingによるレイテンシの比較を行ってみた。

測定には、Windowsのpingを用い、
  ping -l 64 -n 20 8.8.8.8
を繰り返し実行することで測定した。


WiMAXのプロバイダはauで、
tracertによる経路は
  [測定PC] → [UQ Communications] → [KDDI] → [xxx.bb.kddi.ne.jp] → [google]
である。グローバルIPが割り当てられている。8.8.8.8も含め、間は10段。

WiMAX2+のプロバイダはSo-netで、
tracertによる経路は
  [測定PC] → [ICMPを拒絶する何か] → [どこかのプライベートネット(172.25.x.x)] → [xxx.bb.kddi.ne.jp] → [google]
である。どこかのプライベートネットはSo-net内部のネットワークと思われる。
8.8.8.8も含め、間は13段。


測定結果を見ると、WiMAXのレイテンシの最頻値は、80ms〜90ms。
WiMAX2+のレイテンシの最頻値は、60ms〜70ms。
ただし、WiMAXは横向きの等間隔の縞模様が現れており、 80ms〜90msの倍数のレイテンシが測定される頻度が多いことが分かる。
どちらも上限1000msで切っているが、1000msを超えるレイテンシが
観測されることもある。

なお、測定中もふつうにネットワークを利用しているので、
何かをダウンロードしている間のレイテンシは大きめに測定されている
可能性がある。

ちなみに、図はgnuplotで作成した。

2016年10月29日土曜日

systemd-nspawn を使ってみる

Debian 8.5 (Jessie)環境でコンテナを作り、
テスト版であるDebian 9 (stretch)を入れてみる[1]。

Dockerは使わず、systemd-nspawnで行う。
これならJessieのパッケージ管理システムに異物を入れずに済む。

以下、作業ログ。

  1. debootstrapをインストール(aptitudeかapt-getで)。
  2. $ mkdir ~/container
  3. $ cd container
  4. ルート権限で
    $ debootstrap stretch ./stretch http://ftp.jp.debian.org/debian
    を実行。内部でchrootを使っているらしく、ルート権限がないと動作しない。

    なお、fakerootとfakechrootを使えば、ルート権限なしでも実行できるようだ[2]。
    しかし、試してみたところ、
    $ fakechroot
    $ fakeroot
    $ export PATH=/usr/sbin:/sbin:$PATH
    $ debootstrap --variant=fakechroot stretch ./stretch http://ftp.jp.debian.org/debian
    
    では残念ながら動作しなかった。詳しくは下のほうで。
  5. 作った環境のルートのパスワードを設定する。これもルート権限が必要。
    $ systemd-nspawn --directory=stretch passwd
    
    パスワード入力前に以下のメッセージが出るが、とりあえず無視。
    /etc/localtime is not a symlink, not updating container timezone.
  6. コンテナを起動する。ネットワークが必要なければ、
    $ systemd-nspawn --directory=stretch --boot
    
    を実行すればよい。

    実行すると以下のようなログが流れる。仮想マシンで起動しているかのようだ!
    Spawning container stretch on /home/xxx/container/stretch.
    Press ^] three times within 1s to kill container.
    /etc/localtime is not a symlink, not updating container timezone.
    systemd 231 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
    Detected virtualization systemd-nspawn.
    Detected architecture x86-64.
    
    Welcome to Debian GNU/Linux stretch/sid!
    
    Set hostname to <debian64>.
    [  OK  ] Listening on Syslog Socket.
    [  OK  ] Reached target Swap.
    [  OK  ] Listening on Journal Socket.
    [  OK  ] Listening on Journal Socket (/dev/log).
    [  OK  ] Started Dispatch Password Requests to Console Directory Watch.
    [  OK  ] Created slice System Slice.
    Mounting POSIX Message Queue File System...
    Starting Remount Root and Kernel File Systems...
    Starting Journal Service...
    [  OK  ] Created slice system-getty.slice.
    Mounting FUSE Control File System...
    [  OK  ] Reached target Encrypted Volumes.
    [  OK  ] Listening on /dev/initctl Compatibility Named Pipe.
    [  OK  ] Reached target Sockets.
    [  OK  ] Reached target Remote File Systems.
    [  OK  ] Started Forward Password Requests to Wall Directory Watch.
    [  OK  ] Reached target Paths.
    Mounting Huge Pages File System...
    [  OK  ] Reached target Slices.
    [  OK  ] Started Remount Root and Kernel File Systems.
    [  OK  ] Reached target Local File Systems (Pre).
    [  OK  ] Reached target Local File Systems.
    Starting Raise network interfaces...
    Starting Load/Save Random Seed...
    [  OK  ] Mounted POSIX Message Queue File System.
    [  OK  ] Mounted FUSE Control File System.
    [  OK  ] Mounted Huge Pages File System.
    [  OK  ] Started Journal Service.
    Starting Flush Journal to Persistent Storage...
    [  OK  ] Started Load/Save Random Seed.
    [  OK  ] Started Flush Journal to Persistent Storage.
    Starting Create Volatile Files and Directories...
    [  OK  ] Started Create Volatile Files and Directories.
    Starting Update UTMP about System Boot/Shutdown...
    [  OK  ] Reached target System Time Synchronized.
    [  OK  ] Started Update UTMP about System Boot/Shutdown.
    [  OK  ] Reached target System Initialization.
    [  OK  ] Reached target Basic System.
    [  OK  ] Started Regular background program processing daemon.
    Starting System Logging Service...
    [  OK  ] Started Daily apt activities.
    [  OK  ] Started Daily Cleanup of Temporary Directories.
    [  OK  ] Reached target Timers.
    [  OK  ] Started Raise network interfaces.
    [  OK  ] Reached target Network.
    Starting Permit User Sessions...
    [  OK  ] Started Permit User Sessions.
    [  OK  ] Started Console Getty.
    [  OK  ] Reached target Login Prompts.
    [  OK  ] Started System Logging Service.
    [  OK  ] Reached target Multi-User System.
    [  OK  ] Reached target Graphical Interface.
    Starting Update UTMP about System Runlevel Changes...
    [  OK  ] Started Update UTMP about System Runlevel Changes.
    
    Debian GNU/Linux stretch/sid debian64 console
    
    debian64 login: root  
    Password: ←ここで先ほど設定したパスワードを入力
    Linux debian64 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64
    
    The programs included with the Debian GNU/Linux system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.
    
    Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
    permitted by applicable law.
    
  7. 終了するときは、ログの最初に書かれているように、
    Press ^] three times
    とすればよい。つまり Ctrl+] を3回連続で押す。
さて、以降の内容は、通常ユーザー権限によるコンテナ起動に関するメモである。
結論から言うと、通常ユーザーでコンテナは起動できず、ルート権限が必要である。

こんなことを試したのは、単に起動するたびにルート権限がいるのは面倒だというだけのこと。
まず、
$ fakeroot
$ systemd-nspawn --directory=stretch --boot
を実行してみたが、
Press ^] three times within 1s to kill container.
clone() failed: Operation not permitted
が表示されて起動できない。

というわけで、4.からfakechrootとfakerootを使った環境で作業をしてみる。
$ fakechroot
$ fakeroot
$ export PATH=/usr/sbin:/sbin:$PATH
$ debootstrap --variant=fakechroot stretch ./fake-stretch http://ftp.jp.debian.org/debian

最後に次のメッセージを出力して止まってしまった。
W: Failure trying to run: chroot /home/xxx/container/fake-stretch dpkg --force-depends --install /var/cache/apt/archives/base-passwd_3.5.40_amd64.deb
W: See /home/xxx/container/fake-stretch/debootstrap/debootstrap.log for details (possibly the package matches is at fault)
debootstrap.logには、
Setting up base-passwd (3.5.40) ...
Can't load '/usr/lib/x86_64-linux-gnu/perl-base/auto/POSIX/POSIX.so' for module POSIX: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.23' not found (required by /home/xxx/container/fake-stretch/usr/lib/x86_64-linux-gnu/perl-base/auto/POSIX/POSIX.so) at /usr/lib/x86_64-linux-gnu/perl-base/XSLoader.pm line 96.
^@ at /usr/lib/x86_64-linux-gnu/perl-base/POSIX.pm line 36.
Compilation failed in require at /usr/share/perl5/Debconf/Template.pm line 7.
BEGIN failed--compilation aborted at /usr/share/perl5/Debconf/Template.pm line 7.
Compilation failed in require at /usr/share/perl5/Debconf/Question.pm line 8.
BEGIN failed--compilation aborted at /usr/share/perl5/Debconf/Question.pm line 8.
Compilation failed in require at /usr/share/perl5/Debconf/Config.pm line 7.
BEGIN failed--compilation aborted at /usr/share/perl5/Debconf/Config.pm line 7.
Compilation failed in require at /usr/share/perl5/Debconf/Log.pm line 10.
Compilation failed in require at /usr/share/perl5/Debconf/Db.pm line 7.
BEGIN failed--compilation aborted at /usr/share/perl5/Debconf/Db.pm line 7.
Compilation failed in require at /usr/share/debconf/frontend line 6.
BEGIN failed--compilation aborted at /usr/share/debconf/frontend line 6.
dpkg: error processing package base-passwd (--install):
subprocess installed post-installation script returned error exit status 255
Errors were encountered while processing:
base-passwd
が出力されていた。

無視して、そのまま(fakeroot環境のまま)
systemd-nspawn --directory=stretch --boot
を実行してみたが、
Press ^] three times within 1s to kill container.
clone() failed: Operation not permitted
と表示され、やはり実行できない。

コマンドの実行方法を替えてみる[3]。
$ fakechroot fakeroot debootstrap stretch ./fake-stretch http://ftp.jp.debian.org/debian
しかし、同じエラーで停止する。

そこで、debootstrapの代わりにcdebootstrapを使ってみる。
$ fakechroot fakeroot cdebootstrap stretch ./fake-stretch http://ftp.jp.debian.org/debian 

stretchがないといわれる。testingに替えても、結局、
E: Unknown suite stretch
といわれる。

[4]によると、/usr/share/cdebootstrap/suitesを修正すればよいらしい。
Suite: stretch
Config: generic
Keyring: debian-archive-keyring.gpg
を追加した。これでstretchのパッケージの取得は動作するようになったが、結局、
...
P: Validating wget
P: Retrieving whiptail
P: Validating whiptail
E: Failed to unshare: Operation not permitted
が表示されて、停止。

仕方がないので、ルート権限で
$ cp -r stretch stretch2
$ chown -R xxx stretch2
として、ルート権限で作ったstretchのディレクトリを一般ユーザーxxxに変更して、
$ fakeroot systemd-nspawn --directory=stretch2 --boot
を試してみたが、だめ。
$ fakechroot fakeroot systemd-nspawn --directory=stretch2 --boot
もだめ。
clone() failed: Operation not permitted
というエラーが出る。

[5]によると、cloneには、CAP_SYS_ADMINが必要らしい。
さらに[6]によると、
# Linux 3.8 以降では、ユーザー名前空間の作成にどのケーパビリティも必要としない
ということなので、カーネルのバージョンを見てみると、
$ uname -r
3.16.0-4-amd64
であった。あれ? 3.8以上のように見えるが…。

とりあえず、systemd-nspawnにCAP_SYS_ADMINを付与してみる。
$ setcap "CAP_SYS_ADMIN=eip" /usr/bin/systemd-nspawn

設定されたか確認してみると、
$ getcap /usr/bin/systemd-nspawn
/usr/bin/systemd-nspawn = cap_sys_admin+eip
となっており、設定された。

この状態で一般ユーザーで実行してみる。

$ fakeroot systemd-nspawn --directory=stretch2 --boot
ERROR: ld.so: object 'libfakeroot-sysv.so' from LD_PRELOAD cannot be preloaded (cannot     open shared object file): ignored.
Need to be root.
となり、残念ながら起動できない。

fakeroot-ng [7]というパッケージがあるので、それをfakerootの代わりに使ってみた。
しかし、CAP_SYS_ADMINの設定の有無に関わらず、

$ fakeroot-ng systemd-nspawn --directory=stretch2 --boot
Spawning container stretch on /home/xxx/container/stretch.
Press ^] three times within 1s to kill container.
clone() failed: Operation not permitted
となり、やはり起動できない。

CAP_SYS_ADMINはあきらめ、[8]を参考に、

$ echo 1 > /proc/sys/kernel/unprivileged_userns_clone
を設定してみたが、
$ systemd-nspawn --directory=stretch2 --boot
$ fakeroot systemd-nspawn --directory=stretch2 --boot
$ fakeroot-ng systemd-nspawn --directory=stretch2 --boot
の3つとも動作しない。

やはりルート権限が必要なようだ。


--- 参考 ---
[1] https://lindenberg.io/blog/post/debian-containers-with-systemd-nspawn/
[2] http://rail.hatenablog.jp/entry/2012/10/25/234638
[3] https://github.com/dex4er/fakechroot/wiki
[4] http://d.hatena.ne.jp/embedded/20150926/p1
[5] http://systemd-devel.freedesktop.narkive.com/GchaIOxs/systemd-nspawn-create-container-under-unprivileged-user
[6] https://linuxjm.osdn.jp/html/LDP_man-pages/man7/capabilities.7.html
[7] https://fakeroot-ng.lingnu.com/index.php/Home_Page
[8] http://systemd-devel.freedesktop.narkive.com/GchaIOxs/systemd-nspawn-create-container-under-unprivileged-user

2016年7月10日日曜日

uniq でフィールド指定をする方法

uniqで特定のフィールドに対して重複するものを除去するには、
オプション -f と -w を使えばよい。

フィールドは、スペースかタブで区切られた文字列。
-wは比較に使用するフィールドのバイト数。
-fが行頭から順に取り除くフィールドの数。

取り除いたフィールドとその次のフィールドとの間のスペースまたはタブは取り除かれない
そのため、-wと組み合わせるときは、-wのバイト数の計算に注意が必要である。

[a.txt]
11 abc ABC
12 abc xXx
234  abb  XXX
456 bbb XXX
234 bbbc YYY

2個目のフィールドの重複を取り除くには、
$ uniq -f1 -w5 a.txt
11 abc ABC
234  abb  XXX
456 bbb XXX
234 bbbc YYY
とする。-w5は、a.txtの5行目の2番目のフィールドとその直前のセパレータを合わせたバイト数が5であるため。

uniqではフィールド幅が可変長のフィールドの重複除去は行いにくい。
仮に-w6にすると、
$ uniq -f1 -w6 a.txt
11 abc ABC
12 abc xXx
234  abb  XXX
456 bbb XXX
234 bbbc YYY
のようになる。これは、比較に使用される文字が
 abc A
 abc x
  abb 
 bbb X
 bbb c
となるため(行頭にスペースが1個入っていることに注意)。

したがって、
[b.txt]
11 abc ABC
12 abc DEF
13 abcd xXx
14 abcde XXX
15 abcde YYY
に対して、2番目のフィールドで重複除去をしようとしても、
$ uniq -f1 -w6 b.txt
11 abc ABC
12 abc DEF
13 abcd xXx
14 abcde XXX
のようになってしまう。これを避けるには、対象とするフィールドを
行末にコピーしてuniqを行ったあと、それを除去すればよい。
例えば、
$ awk '{print $0" "$2}' b.txt | uniq -f3 | sed 's/ [[:graph:]]*$//'
11 abc ABC
13 abcd xXx
14 abcde XXX
のようにする。

日本語も処理できるが、-wがバイト数のため指定しにくい。
[c.txt (UTF-8)]
11 abc ABC
12 abc DEF
13 あさ xXx
14 あさ XXX
15 あみ YYY

例えば、2番目のフィールドの幅を4バイトとすると、
$ uniq -f1 -w4 c.txt
11 abc ABC
13 あさ xXx
となり、「あ」しか比較対象にならない。
なので、
$ awk '{print $0" "$2}' c.txt | uniq -f3 | sed 's/ [[:graph:]]*$//'
11 abc ABC
13 あさ xXx
15 あみ YYY
のように、後ろに移動させてからuniqするのが簡単。

2016年5月28日土曜日

フォントの高さの修復方法

TeXで使われているフォントをWindowsで使おうとすると、
行の高さ(line-space)が壊れていることがあるので修復してみた。

TeXで使われているフォントは、
https://www.ctan.org/
で入手できるものが多い。

TeXでデフォルトで使われるフォントはComputer Modern Unicode
https://www.ctan.org/pkg/cm-unicode
で、このフォントの高さは正常なのでそのままWindowsのフォントとして使用できる。

しかし、すべての文字についてデフォルトがComputer Modernだというわけではない。
数式で使用されるギリシャ文字にはLatin Modern Math (LM Math)
http://www.gust.org.pl/projects/e-foundry/lm-math
https://www.ctan.org/tex-archive/fonts/lm-math
が用いられている。

残念ながら、この記事を書く時点では、このLatin Modern Mathの
フォントファイルに記録されている行の高さ情報は正しくなく、
上下におよそ3行分ずつ余分な空白が入ってしまう。
WordやLibreOfficeで使おうとするととても使いにくい。


そこで、FontForge
https://fontforge.github.io/en-US/
を使ってフォントの高さの修復を行う。

なお、FontForgeで検索すると日本語で書かれている
http://fontforge.github.io/ja/
がヒットするが、そこからたどりつく
https://sourceforge.net/projects/fontforge/files/fontforge-executables/
にある
FontForgeSetup_2012-07-31_Windows.exe
は使わないほうがよい。古く、日本語が正常に表示されない。

一方、Cygwin版
fontforge_cygwin-20090914.tar.bz2
なら表示が崩れることはない。しかし、fontforgeのGUI表示用にCygwinのXが必要になるので
CygwinのXをインストールしなければならず、また、FontForge自体が古い。


さて、FontForgeの準備ができたら、起動して修正したいフォントを読み込み、
次の手順にしたがってフォントを修正する。

  1. エレメント→フォント情報と進み、設定画面を表示させる。Cygwin版ならElement→Font Infoと進む。 
  2. 左側の一覧から「一般情報(General)」を選択する。 
  3. 高さ(Ascent)と深さ(Descent)の値を覚える。
  4. 左側の一覧から「OS/2」を選択し、「メトリック(Metrics)」タブを選択する。
  5. 「オフセットを指定(Is Offset)」のチェックボックスをすべてはずす。
  6. Win AscentとWin Descentの値をそれぞれ3.で覚えた値に設定する。
  7. 組版上の高さ(Typo Ascent)とhheaテーブルでの高さ(HHead Ascent)を3.で覚えた高さの値に設定する。
  8. 組版上の深さ(Typo Descent)とhheaテーブルでの深さ(HHead Descent)を3.で覚えた深さの値を負にした値に設定する。例えば、深さが194であれば-194を設定する。
  9. OKボタンを押す。
  10. ファイル(File)→フォントを出力(Generate Fonts)と進む。
  11. 出力形式を指定する。今、修正しようとしているLatin Modern MathはOpenTypeフォントなので、OpenTypeを選択する。
  12. 生成ボタンを押す(フォントによっては途中で警告表示がでるかもしれない)。
  13. 生成したフォントファイルのプレビュー(エクスプローラで右クリック→プレビュー)を表示すると、無駄な行間スペースがなくなっていることが確認できる(はず)。

以上で行の高さを修正したフォントが得られるので後はシステムにインストールするだけである。

フォントの高さの設定に関しては、以下を参考にした。
http://fontforge.github.io/faq.html#linespace
https://fontforge.github.io/ja/fontinfo.html#TTF-Metrics
http://designwithfontforge.com/en-US/Line_Spacing.html

2016年5月15日日曜日

d3.jsで横向きの棒グラフ

JavaScriptで棒グラフを作成してみた。
d3.jsを使う。使い方は、主に、
http://ja.d3js.info/alignedleft/tutorials/d3/
を参考にした。

まずはデータを準備する。ファイル名は、test.datとする。
スペース区切りのデータである。1列目が項目名、2列目が棒グラフにする値である。
3列目は棒にマウスが移動すると表示される値とする。

Tokyo 300 0.1
Kyoto 100 0.5
Osaka 150 1.2
Nagoya 200 0.3
Yokohama 250 0.7
このデータから横向きの棒グラフ

を作成する。

そのためのHTMLファイルは以下の通りである。
ファイル名は任意で、test.datと同じディレクトリに作成する。
このファイルをブラウザで表示すると、横向きの棒グラフが表示される。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>D3 Test</title>
    <script type="text/javascript" src="d3/d3.js"></script>
    <style type="text/css">
      .axis path, .axis line {
        fill: none;
        stroke: black;
      }
      .axis text {
        font-family: sans-serif;
        font-size: 11px;
      }
    </style>
  </head>
  <body>
    <script type="text/javascript">
      var w = 500; // Width of a SVG canvas
      var h = 100; // Height of a SVG canvas
      var axisHeight = 20; // Height of a horizontal axis
      var barPadding = 3;  // Padding between bars
      var svg = d3.select("body")
        .append("div")
        .append("svg")
        .attr("width", w)
        .attr("height", h);
      d3.text("./test.dat", function(error, text) { // load a data file
        // Parse space-separated values
        var data = d3.dsv(" ", "text/plain").parseRows(text, function(d) {
          return { name: d[0], value: d[1], ratio: d[2] }; // Parse one line
        });
        
        // Make a tooltip showing data.ratio as text when mouseover
        var tip = svg.append("text")
          .attr("font-size", "11px")
          .attr("text-anchor", "start")
          .attr("dominant-baseline", "middle")
          .attr("visibility", "hidden");

        // Draw region of y-label
        var yLabelOffset = 5; // Padding between a label and a bar
        var yLabelMaxWidth = 0;
        var yLabel = svg.selectAll("text")
          .data(data, function(d, i){
            if(d === undefined){
              return i;
            }
            return i+1;
          })
          .enter()
          .append("text")
          .text(function(d) {
            return d["name"];
          })
          .attr("y", function(d, i){
            return (i+0.5)*(h-axisHeight)/data.length;
          })
          .attr("font-size", "11px")
          .attr("text-anchor", "end")
          .attr("dominant-baseline", "middle")
          .each(function(d){
            yLabelMaxWidth = Math.max(this.getBBox().width, yLabelMaxWidth);
          })
          .attr("x", yLabelMaxWidth);
        yLabelMaxWidth += yLabelOffset;

        // Make a horizontal scale
        // (last '-10' makes room for drawing axis labels)
        var xScale = d3.scale.linear()
          .domain([0, 500])
          .range([0, w - yLabelMaxWidth - 10]);
        
        // Make an axis with xScale
        var xAxis = d3.svg.axis().scale(xScale).orient("bottom");

        // Make horizontal bars
        svg.selectAll("rect")
          .data(data) // Load data
          .enter()    // Make placeholders
          .append("rect")
          .attr("x", yLabelMaxWidth)
          .attr("y", function(d, i) {
            return i*(h - axisHeight)/data.length + barPadding/2;
          })
          .attr("width", function(d){return xScale(d["value"])})
          .attr("height", (h - axisHeight)/data.length - barPadding)
          .attr("stroke", function(d) {
            return "rgb(0, 0, " + (d["value"]) + 50 + ")";
          })
          .attr("stroke-width", 1)
          .attr("fill", function(d) {
            return "rgb(0, 0, " + (d["value"]) + ")";
          })
          .on("mouseover", function(d, i){
            return tip.attr("visibility", "visible")
            .text(d["ratio"])
            .attr("x", yLabelMaxWidth + xScale(d["value"]) + 3 + "px")
            .attr("y", ((i + 0.5)*(h - axisHeight)/data.length) + "px");
          })
          .on("mouseout", function(d){
            return tip.attr("visibility", "hidden");
          });
        svg.append("g")
          .attr("class", "axis")  // Define the class "axis"
          .attr("transform", "translate(" + yLabelMaxWidth + ","
            + (h - axisHeight + barPadding/2) + ")")
          .call(xAxis);
      });
    </script>
  </body>
</html>

2016年1月20日水曜日

マグネシア

マグネシウムの語源は、地名の「マグネシア」だそうだ。

マグネシアの名前は
・ギリシャのマグネシア半島
・小アジアのマグネシア地方(現在のトルコのマニサ)
の2箇所にみられる。

小アジアのマグネシアは、古代ギリシャのテミストクレスが
晩年(紀元前466〜459年)に過ごした都市だ。

紀元前190年に「マグネシアの戦い」があった場所でもある。

ちなみに、そのころ日本は弥生時代。
https://ja.wikipedia.org/wiki/%E5%BC%A5%E7%94%9F%E6%99%82%E4%BB%A3

2016年1月13日水曜日

Mercurial largefiles の管理下のファイルの確認方法

Mercurialのlargefilesエクステンションを使用しているリポジトリで、
ラージファイルとして扱われているファイルは、

$ hg locate

で確認できます。ファイルのパスの最初が .hglf であれば、
それがラージファイルです。それ以外が通常のファイルですので、
簡単に区別できます。


.hglfだけを一覧表示したい場合は、

$ hg locate "set:.hglf**"

で表示できます。