ひらおかゆみのなげやりブログ

もう、なげやりです…

B-V色指数から天体の色温度を求める

このエントリはJavaFX Advent Calendar 2016の事前準備で、タイトルの通りB-V色指数から天体の色温度を求める方法に関する考察です。

12月19日に公開予定の本編ではJavaFXの3Dモデルで小惑星を描くことになっており、そのための準備を進めています。小惑星の大きさ、扁平率、アルベドなど、3Dモデル作成に当たって調べなければならないことがたくさんありましたが、中でも小惑星の色をどのように表現するかが一番の問題でした。

Wikipediaなどで得られる小惑星の色はB-V色指数で表されていて、これを最終的にRGB(場合によってはHSB)に変換しなければならないのですが、その変換式が見つかりません。ケレスのようなメインベルト天体であれば分かっている組成から色をある程度推測することは可能なのですが、遠く離れた太陽系外縁天体ではそうもいきません。

天体の色指数は、2つのバンド・パス・フィルタを透過する光(電磁波)の強さの差として定義されます。多くの天体の色表現に用いられるB-V色指数はBバンド・フィルタ(青色を透過する)とVバンド・フィルタ(緑色を透過する)を用いるもので、Bバントの値からVバンドの値を差し引いた値であることからその名があります。主な恒星(主系列星)ではB-V色指数を用いますが、南十字星のアクルックスや乙女座のスピカのように青みの強い星ではUバンド・フィルタ(紫外線を透過する)とBバンド・フィルタを用いたU-V色指数も組み合わせて用いられます。

色指数はあくまで波長の異なる光の強さの差分であり、人間が認識できる色ではありません。光の色を表す尺度としては色温度が広く用いられています。色温度は、外部の光や熱をすべて吸収し自身が発する光や熱を全くロスしない「黒体」という仮想の物質を想定し、黒体の温度とその時に黒体が発する(「黒体放射」といいます)色の対応から、色を黒体の温度で表すものです。黒体放射から求めた太陽光の色温度は概ね5,000~6,500 [K]程度となります。太陽の表面温度は5778 [K]ですから、恒星の色温度はその表面温度に近い値であることがわかります。つまり恒星の色と表面温度については、概算レベルでは黒体放射を仮定することで求めることができます(恒星は厳密には黒体ではないため、当然ながら誤差は生じます)。

色温度は有力な指標ですが、それだけでは光の三原色(赤・緑・青)との対応までは分かりません。そこで特定の色温度を白色光として定め、そこから三原色に分解します。なお、白色光が三原色の各成分とどのように対応するのかは、実験的に明らかにされています。基準となる白色光を発するものを標準光源といい、現在ではD65光源(6504 [K])とA光源(2856 [K])が主に用いられています。他にも用途によってはC光源(6774 [K])、D50光源(5003 [K])、D55光源(5503 [K])、D75光源(7504 [K])が用いられることもあります。

さて、小惑星の色を求めるのに当たって、既に分かっているものは小惑星のB-V色指数だけであり、そこから色温度を算出する数式が必要になります。小惑星についても恒星同様に黒体放射を仮定して(小惑星は黒体からかけ離れているためあまりよい方法ではないのですが)、恒星のB-V色指数と表面温度の関係式を小惑星に当てはめればそれなりの値は得られると思うのですが、肝心のB-V色指数と表面温度が見当たりませんでした。それでも1ヶ月以上かけてようやくそれらしき情報を掲載しているWebページ ヒッパルコス星表で太陽近傍恒星のHR図を描こう を探し当てました。こちらでは表面温度Tの計算として、以下の2式が紹介されています。

(a) T = 9000 / ((B-V) + 0.85)

(b) log T = 3.939654 - 0.395361(B-V) + 0.282113(B-V)2 - 0.0604097(B-V)3

※(b)式はWebページでは T = ... となっていますが、原典によると log T = ... が正しいです

(a)式は簡単で、そのWebページでも恒星の表面温度の算出に使用しているものです。試しに太陽のB-V色指数0.65を入れてみると、T = 6000 [K]が得られます。太陽の実際の表面温度は5778 [K]ですので、まあまあの値といえるのではないでしょうか。肝心の(a)式の出典ですが、はっきりとはわかりませんでした。出典に書かれているはずの前提条件まで確認しないと、本当にこの式を小惑星のB-V色指数に適用してもよいのかわからないのです。断片的な情報では、(a)式はベガのデータからはじき出した近似式らしいことまではわかったのですが…

一方、(b)式は論文 A Study of the B−V Color-Temperature Relation - IOPscience からの引用で、元の式はもっと複雑です。

log T = c0 + c1(B-V) + c2(B-V)2 + c3(B-V)3 + f1[Fe/H] + f2[Fe/H]2 + g1 log g + h1(B-V) log g

ただし、(B-V) : B-V色指数、[Fe/H] : 金属量、log g : 表面重力(cgs単位系)とし、定数c0、c1、c2、c3、f1、f2、g1、h1は以下の通り。

  • c0=3.939654±0.0115
  • c1=-0.395361±0.0263
  • c2=0.2082113±0.0293
  • c3=-0.0604097±0.0107
  • f1=0.027153±0.00166
  • f2=0.005036±0.000972
  • g1=0.007367±0.00231
  • h1=-0.01069±0.00224

さらに前提として、論文の冒頭に "In this paper we confine our further analysis to the range Teff < 7000, i.e., F0 or later." とあります。7000 [K]未満(スペクトル型F0以降)でないとこの近似式は成り立たないと。

実際に一等星のデータを使って試してみたら、確かにスペクトル型BやAの星では大きくずれました。特に20,000 [K]を優に超えるアクルックス(B0.5、B-V: -0.24)やスピカ(B1、B-V: -0.23)だと半分の10,000 [K]くらいになってしまいました。一方で太陽(G2、B-V:+0.65)やプロキオン(F5、B-V:+0.421)はかなり正確な値が算出できました。小惑星のB-V色指数は高めなので、小惑星を黒体放射とみなす前提が大きく間違っていなければ、この式は適用できそうです。

さて、この式を使うに当たって、私にはいくつか懸案がありました。

[1] 紹介していたWebページでは5項(f1[Fe/H])以降を省略していたが、本当に問題ないのか?(5項以降がほぼ0になる前提で省略したと思われるが、それは妥当な判断か?)

[2] 論文の冒頭では7,000 [K]未満(スペクトル型F0以降)の恒星にしか適用できないとあるが、7,000 [K]以上(スペクトル型O0~A9)の恒星に当てはめたらどのくらいの誤差が生じるのか?

これらを解決?するため、私は全天にある21の一等星のデータを使って、検証してみることにしました。計算はGoogle先生で(笑)

JavaFX Advent Calendarの準備なのだからJavaでプログラム書けと言われそうですが、別にいいんです、本職じゃないから。

準備

まず、使用する式を具体的なものにします(またの名を、Google先生対応(笑))。定数は±をゼロにして、すべての項を揃えたものと5項以降を省略したものの2つを作ります。

log(T) = 3.939654 - 0.395361*(B-V) + 0.2082113*(B-V)^2 - 0.0604097*(B-V)^3 + 0.027153*[Fe/H] + 0.005036*[Fe/H]^2 + 0.007367*log(g) - 0.01069*(B-V)*log(g) ―(1)

log(T) = 3.939654 - 0.395361*(B-V) + 0.2082113*(B-V)^2 - 0.0604097*(B-V)^3 ―(2)

あとは変数(B-V)、[Fe/H]、log(g)に一等星のデータを入れていけばよいわけです。ちなみに、今回使う一等星のデータがこちら。

StarSpectralTeff(B-V)[Fe/H]log(g)
Acrux B0.5 IV 24,000 K -0.25 N/A N/A
Mimosa B1 IV 27,000 K -0.23 -0.08 3.6
Spica B1 III-IV 22,400 K -0.23 N/A 3.7
Hadar B1 III 25,000 K -0.23 N/A 3.5
Achernar B6 Vep 15,000 K -0.16 N/A 3.5
Rigel B8 Ia 12,100 K -0.03 -0.06 1.75
Regulus B8 IVn 12,460 K -0.11 N/A 3.54
Vega A0 Va 9,602 K 0.00 -0.5 4.1
Sirius A1 Vm 9,940 K 0.00 0.50 4.33
Deneb A2 Ia 8,525 K +0.09 -0.25 1.10
Fomalhaut A4 V 8,590 K +0.09 -0.03 4.21
Altair A7 V 6,900 to 8,500 K +0.22 -0.2 4.29
Canopus A9 II 6,998 K +0.15 -0.07 1.64
Procyon F5 IV-V 6,530 K +0.421 -0.05 3.96
Rigil Kentaurus G2 V 5,790 K +0.71 0.20 4.30
Capella K0 III 4,970 K +0.80 N/A 2.691
Arcturus K0 III 4,286 K +1.23 -0.52 1.66
Pollux K0 III 4,666 K +1.00 -0.07 to +0.19 2.685
Aldebaran K5 III 3,910 K +1.44 -0.34 1.59
Antares M1.5 Iab 3,400 K +1.83 N/A 0.1
Betelgeuse M1-M2 Ia-ab 3,590 K +1.85 +0.05 -0.5

懸案 [1] に対する検証

ご覧の通りデータに抜けがあるので、検証に使えるのはミモサ(ベクルックス)、リゲル、ベガ、シリウス、デネブ、フォーマルハウト、アルタイル、カノープスプロキオン、リギル・ケンタウルスケンタウルスα)、アークトゥルスアルデバランベテルギウスの13星です。

StarSpectralTeff(B-V)[Fe/H]log(g)Teff (1)Teff (2)
Acrux B0.5 IV 24,000 K -0.25 N/A N/A N/A --
Mimosa B1 IV 27,000 K -0.23 -0.08 3.6 11,901 K 11,024 K
Spica B1 III-IV 22,400 K -0.23 N/A 3.7 N/A --
Hadar B1 III 25,000 K -0.23 N/A 3.5 N/A --
Achernar B6 Vep 15,000 K -0.16 N/A 3.5 N/A --
Rigel B8 Ia 12,100 K -0.03 -0.06 1.75 9,195 K 8,948 K
Regulus B8 IVn 12,460 K -0.11 N/A 3.54 N/A --
Vega A0 Va 9,602 K 0.00 -0.5 4.1 9,069 K 8,073 K
Sirius A1 Vm 9,940 K 0.00 0.50 4.33 N/A 8,073 K
Deneb A2 Ia 8,525 K +0.09 -0.25 1.10 8,059 K 8,048 K
Fomalhaut A4 V 8,590 K +0.09 -0.03 4.21 8,548 K 8,048 K
Altair A7 V 6,900 to 8,500 K +0.22 -0.2 4.29 7,558 K 7,280 K
Canopus A9 II 6,998 K +0.15 -0.07 1.64 7,806 K 7,671 K
Procyon F5 IV-V 6,530 K +0.421 -0.05 3.96 6,540 K 6,392 K
Rigil Kentaurus G2 V 5,790 K +0.71 0.20 4.30 5,584 K 5,524 K
Capella K0 III 4,970 K +0.80 N/A 2.691 N/A --
Arcturus K0 III 4,286 K +1.23 -0.52 1.66 4,301 K 4,528 K
Pollux K0 III 4,666 K +1.00 -0.07 to +0.19 2.685 N/A --
Aldebaran K5 III 3,910 K +1.44 -0.34 1.59 4,921 K 4,185 K
Antares M1.5 Iab 3,400 K +1.83 N/A 0.1 N/A --
Betelgeuse M1-M2 Ia-ab 3,590 K +1.85 +0.05 -0.5 3,515 K 3,454 K

(1) 式の結果 Teff (1) と (2) の結果 Teff (2) を実際の表面温度 Teff と比較してみると、スペクトル型 A4 のフォーマルハウト以降、(2) 式が非常に良好な値を出していることが分かると思います。また、(1) 式は精度こそ (2) 式には及ばないものの、B-V色指数のみの1変数式ながら比較的良い結果となっています。スペクトル型 A2 のデネブまでの白~青の星では実際の表面温度との乖離は大きいものの、論文の前提条件においては (1) (2) 式とも良好な値を示すことがわかりました。 

懸案 [2] に対する検証

先の検証で、(2)式を用いても十分な結果が得られるとわかりました。そこで、こちらでは(2)式を残るアクルックス、スピカ、ハダル(ケンタウルスβ)、アケルナル、レグルス、カペラ、ポルックス、アンタレスの8星にも当てはめてみます。

StarSpectralTeff(B-V)[Fe/H]log(g)Teff (1)Teff (2)
Acrux B0.5 IV 24,000 K -0.25 N/A N/A N/A 11,284 K
Mimosa B1 IV 27,000 K -0.23 -0.08 3.6 11,901 K 11,024 K
Spica B1 III-IV 22,400 K -0.23 N/A 3.7 N/A 11,024 K
Hadar B1 III 25,000 K -0.23 N/A 3.5 N/A 11,024 K
Achernar B6 Vep 15,000 K -0.16 N/A 3.5 N/A 10,197 K
Rigel B8 Ia 12,100 K -0.03 -0.06 1.75 9,195 K 8,948 K
Regulus B8 IVn 12,460 K -0.11 N/A 3.54 N/A 9,677 K
Vega A0 Va 9,602 K 0.00 -0.5 4.1 9,069 K 8,073 K
Sirius A1 Vm 9,940 K 0.00 0.50 4.33 N/A 8,073 K
Deneb A2 Ia 8,525 K +0.09 -0.25 1.10 8,059 K 8,048 K
Fomalhaut A4 V 8,590 K +0.09 -0.03 4.21 8,548 K 8,048 K
Altair A7 V 6,900 to 8,500 K +0.22 -0.2 4.29 7,558 K 7,280 K
Canopus A9 II 6,998 K +0.15 -0.07 1.64 7,806 K 7,671 K
Procyon F5 IV-V 6,530 K +0.421 -0.05 3.96 6,540 K 6,392 K
Rigil Kentaurus G2 V 5,790 K +0.71 0.20 4.30 5,584 K 5,524 K
Capella K0 III 4,970 K +0.80 N/A 2.691 N/A 5,317 K
Arcturus K0 III 4,286 K +1.23 -0.52 1.66 4,301 K 4,528 K
Pollux K0 III 4,666 K +1.00 -0.07 to +0.19 2.685 N/A 4,921 K
Aldebaran K5 III 3,910 K +1.44 -0.34 1.59 4,921 K 4,185 K
Antares M1.5 Iab 3,400 K +1.83 N/A 0.1 N/A 3,493 K
Betelgeuse M1-M2 Ia-ab 3,590 K +1.85 +0.05 -0.5 3,515 K 3,454 K

全体傾向は懸案[1]に対する検証の結果とほぼ同様です。結論として、

  • (1) (2) 式とも概ね 8,000~8,500 [K] 以下において適用可能である。
  • B-V色指数、金属量、表面重力がすべて分かっている場合には (1) 式で高精度な結果が得られる。
  • B-V色指数だけでも分かっていれば (2) 式で表面温度を概算できる。

と言えます。

(1) 式または (2) 式を小惑星に当てはめる場合、恒星と小惑星では組成が全く異なるため金属量は該当するものがなく、また規模の違いから表面重力がそのままでは適用できない恐れがあります。そこで、B-V色指数のみを変数とする (2) 式を使用することで、大まかな色温度を算出できるものと考えます。

それでは、19日の本編をお楽しみに。

JavaFX Advent Calendar 2016にエントリーしました

ここ数年の流れで、JavaFX Advent Calendar 2016にエントリーしてしまいました。今年は青江(@aoetk)さんを差し置いて誕生日枠を確保した手前、中途半端なものは出せないというプレッシャーが日に日に強まっています。

私の中で最優先としているのは、TNO(太陽系外縁天体)の取り扱い。TNOの軌道計算を行うシミュレーターか、あるいはTNOの色や明るさをスペクトル型やアルベドからRGBまたはHSVに変換してみたり(そのためには Color クラスをフル活用する必要がありそうです)。

小惑星のデータからJavaFXの色に変換する過程は意外と難しそうですが、やってみる価値はありそうです。

大学卒業しました

事後になりますが(この表現、なんか微妙よね…)、7年間通った大学を卒業しました。前もっていっておきますけど、3留ではなくて、学部4年間+修士3年間ですから。そこ、修士は普通2年だとか言わない!

7年間、これといった思い出はありません。M1までずっと仮面浪人してましたから。

本当は博士課程で本当にやりたかった天文関係の研究へ進みたかったのですが、在学中何度も病気をして体力が持たないので、しばらく自宅でお休みすることにしました。何ヶ月になるか、何年になるか、あるいは再起不能になるかはわかりませんけど、自分が望む道はまだ閉ざしたくないので、それまでの充電期間にします。

恒例の欲しいものリストはないのですが、@btnrouge にはSurface Pro 4を一日も早く買ってほしいです。私が拠出したSurface Pro 3の代わりに。

「帰ってきたGlassFish Users Group Japan勉強会」の未発表資料

このエントリはJava EE Advent Calendar 2015の19日目です。昨日は@aforarshさんでした。明日は@kokuzawaさんです。

今年の9月に帰ってきたGlassFish Users Group Japan勉強会というのがありました。最後の登壇者@btnrougeが会長就任宣言をしたとか後で聞きましたが、当初最後の枠にはなぜか私が指名されていました。最終的にはいろいろあって私は逃げたのですが、発表スライドは作成してそのままお蔵入りになっていたので、このエントリで発表します。 

GlassFishというと、Oracleの商用サポート打ち切りでマイナスのイメージを持ってしまっている人が少なくないと思うのですが、もっとプラスに捉えた方がいいんじゃないかなと思ってスライドを作りました。先々月に最新のGlassFish 4.1.1がリリースされましたし、GlassFishの商用サポートもコミュニティの手によって続けられています。

コミュニティで生まれ、紆余曲折を経てコミュニティに戻ってきたGlassFishを、温かく迎えてあげたいと思いませんか?

技術的なことは去年のGlassFish Advent Calendarで自分がにわかだと思い知ったので、もう少し勉強してから。 

JavaFXで画面解像度を調べてみる

ご無沙汰してます。

これはJavaFX Advent Calendar 2015の18日目のエントリです。

昨日は@skrbさんの「黒字に黄色のクローラー」でした。明日はお誕生日枠の@aoetkさんです。本当は私も明日誕生日なのですけど、BBA言う人がいるので…

さて、今回はJavaFXのドキュメントから偶然見つけたjavafx.stage.Screenクラスを調べてみました。このクラスは、

  • 公開APIである(非公開APIにもScreenクラスがあってメソッドも違う)
  • メインディスプレイと、環境によっては他のディスプレイの情報も取れる
  • 取れる情報は、DPI、ディスプレイの幅と高さ、表示領域(タスクバーを除いた領域)の幅と高さ、など

という特徴があります。JavaFX 2.0の頃からあるようですが、その割には情報が少ないと思うのは、私だけでしょうか?

以前、JavaFXのHiDPI対応について調べたことがあり、気になったので実験してみました。ScreenクラスからDPI、ディスプレイの幅と高さ、表示領域の幅と高さの計5項目を取得してGridPaneで表示するサンプルを作成してみました。その結果が以下の通りです。

f:id:yumix_h:20151218224027p:plain

私はSurface Pro 3を使っているのですが、そうするとディスプレイの幅と高さは2160×1440ピクセルとなっていいはず。はて…

ちなみに、上記の値を1.5倍(150%)すると、2160×1440ピクセルになります。Surface Pro 3はデフォルトで拡大率150%でした。実行環境はJava 8 Update 66だったので、HiDPI対応で拡大率が考慮されていると考えて良さそうです。

念のため、Java 8 Update 51を再度インストールして、HiDPI非対応の場合も試してみました。

f:id:yumix_h:20151218224948p:plain

Surface Pro 3の実際の幅と高さになりました。あと、細かいことですがウィンドウのレイアウトも少し変わりました(余白がいくらか小さくなっている)。

この結果から、Java 8 Update 60で本当にDevice Independent Pixel(DIP)対応が(拡大率125%に対応していないとは言え)入ったことが分かります。

今年はWebViewで遊んでみようと思ったら、思わぬところで脱線してしまいました修論やり直しの件は触れるな)。でも、WebViewはちょうど1年前にやったからいいよね?

Windows版JavaFXでHiDPI対応をやってみた その1

こんにちは。

昨年12月のJavaFX Advent Calendarで果たせなかった(詳しくはこちら)、JavaFXのHiDPI対応をやってみました。まずは出来上がりから。


yumix/javafx-dpi-scaling · GitHub

実はちゃんとしたテストをしていないのですが、ローンチ・カスタマーの @btnrouge が彼の会社の製品に適用したところ全然問題なかったというので、それなりに動くとは思っています。

アプリケーションから使うのは基本的には org.yumix.javafx.scaling パッケージ、その中でも Scaling クラスになります。

package hidpi;

import org.yumix.javafx.scaling.Scaling;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class AppMain extends Application {

  @Override
  public void start(Stage stage) throws Exception {
    AnchorPane root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
    
    // Scaling.getDefault() でインスタンスを取得
    // Scaling.compute(root) で root とその子のサイズを解像度に合わせて調整
    Scene scene = new Scene(Scaling.getDefault().compute(root));
    
    stage.setScene(scene);
    stage.show();
  }

  public static void main(String[] args) {
    launch(args);
  }

}

現状、まだShapeに対応していないとか、テストほとんどやっていないとか、課題は残っていますが、根となるPaneを指定するだけでよろしくやってくれるようになりました。

 

今回やったことは、javafx.scene.Nodeと既知のすべてのサブクラスについて、スケーリングの影響がありそうな位置、サイズ、マージン、パディングに関するプロパティの値を補正するようなプログラムを組んで、それを再帰呼び出しでノードのツリー全体に適用するようにしたことです。この調査自体は私でなく @btnrouge がやってくれたのですが、彼が送ってくれた実装があまりにひどかった(全部staticメソッドにしていた)ので、調査結果だけ拝借して私が全部作り直しました。

GlassFishユーザー会の副会長さんが、まさか全部staticのC言語みたいなJavaプログラムを送ってくるとは思わなかったよ…)

 

次回は、Shape対応が終わったころに、設計みたいなことをまとめようと思ってます。

 

ではでは。