PHPで太陽黒点相対数の周期変化を描く

(1/1)
世界は本当に温暖化へ向かっているのだろうか――。
地球のエネルギー収支では、入ってくる方のほぼ100%が太陽エネルギーである。これが二酸化炭素などの影響で宇宙空間へ出て行かず、温暖化が進むとされている。
では、入ってくる太陽エネルギーに変動はないのか。

観測により、太陽エネルギーの放射は周期的に変動していることが分かっている。太陽の表面にある黒点の数の変化が、これに連動している。
そこで今回は、天文台の黒点観測データを利用し、PHPを使って黒点の数の周期変化をグラフに描いてみることにする。

(2023年7月16日)キャッシュ・システム導入
(2022年11月3日)統計表を更新

目次

サンプル・プログラムの実行例

PHPで太陽黒点相対数の周期変化を描く
水色の折れ線グラフは黒点相対数を表す。後述するが、黒点相対数が多いときは太陽活動が盛んである。グラフの通り、黒点相対数は約11年周期で増減している。
だが、相対数のピークには長周期変動があることが見て取れる。そこで、区間を11年(132ヶ月)にして移動平均をとってみたのが赤い折れ線グラフである。1810年前後と直近に、活動の低下があることが見て取れる。
1810年前後はダルトン極小期と呼ばれている。この時期、日本では天明の飢饉が起きており、1816年は夏のない年とされている。しかし、この年にインドネシアのタンボラ山が大爆発を起こしており、これが寒冷化の主要因とされている。
とはいうものの、ダルトン極小期では、移動平均が急に下降して、急に上昇している点に注目したい。そして直近で、移動平均が再び急下降している。新たな極小期がやってくるかもしれない。

太陽黒点と黒点相対数

巨大黒点 2014年10月下旬(国立天文台)
巨大黒点 2014年10月下旬(国立天文台)
太陽黒点とは、太陽表面にあって周囲より温度が低いために黒く見える部分のことである。
左の写真が黒点で、群れになって出現する。大きなものでは、地球の数倍の大きさに及ぶ。
太陽活動が盛んなときには黒点の数が増えることが分かっている。
1ヶ月続いた無黒点 2009年(国立天文台)
1ヶ月続いた無黒点 2009年(国立天文台)
太陽活動が低下すると、黒点の数も減る。
左の写真は、2009年、1ヶ月間も黒点がなかったときの太陽である。

太陽黒点の群れや個々の総量を数値化するのに、18世紀のスイスの天文学者ルドルフ・ウォルフが考案した黒点相対数(ウォルフ数)を用いる。黒点数をf、黒点群数をg、観測地点家観測方法による補正係数をkとすると、黒点相対数は mimetex で表される。

サンプル・プログラム

圧縮ファイルの内容
SSN.phpサンプル・プログラム本体
pahooStat.php統計に関わるクラス pahooStat。
使い方は「PHPで相関係数と回帰直線を表示」などを参照。include_path が通ったディレクトリに配置すること。
pahooCache.phpキャッシュ処理に関わるクラス pahooCache。
キャッシュ処理に関わるクラスの使い方は「PHPで天気予報を求める」を参照。include_path が通ったディレクトリに配置すること。
SSN.php 更新履歴
バージョン 更新日 内容
1.2.0 2023/07/16 キャッシュ・システム導入:pahooCacheクラス
1.1 2022/04/17 PHP8対応,リファラ・チェック改良
1.0 2018/04/21
pahooStat.php 更新履歴
バージョン 更新日 内容
1.2 2020/08/14 LSM()追加
1.1 2018/04/22 simple_moving_average() 追加
1.0 2018/04/07
pahooCache.php 更新履歴
バージョン 更新日 内容
1.1.1 2023/02/11 コメント追記
1.1 2021/04/08 simplexml_load()メソッド追加
1.0 2021/04/02 初版

解説:準備

  35: //jqPlotのあるフォルダ
  36: define('JQPLOT', '../../../../common/jqplot/');
  37: 
  38: //データファイル:ベルギー王立天文台より
  39: define('FILE_DATA', 'https://www.sidc.be/SILSO/DATA/SN_m_tot_V2.0.txt');
  40: 
  41: //移動平均区間;12ヶ月×11年
  42: define('INTERVAL', (12 * 11));
  43: 
  44: //グラフの幅、高さ
  45: define('GRAPH_WIDTH',  600);
  46: define('GRAPH_HEIGHT', 500);
  47: 
  48: //グラフの色
  49: define('COLOR_SSN',  '#88CCFF');
  50: define('COLOR_MEAN', '#CC0000');
  51: 
  52: //太陽黒点相対数 推移グラフの名前
  53: define('GRAPH_SSN', 'jqPlot_SSN');
  54: 
  55: //統計に関わるクラス:include_pathが通ったディレクトリに配置
  56: require_once('pahooStat.php');
  57: 
  58: //キャッシュ保持時間(分) 0:キャッシュしない
  59: //ベルギー王立天文台へのアクセス負荷軽減のため,
  60: //1,440分以上のキャッシュ保持をお勧めします.
  61: define('LIFE_CACHE', 10080);
  62: 
  63: //キャッシュ・ディレクトリ
  64: //書き込み可能で,外部からアクセスされないディレクトリを指定してください.
  65: //最大約150Kバイトを消費します.
  66: define('DIR_CACHE', './scache/');
  67: 
  68: //キャッシュ処理に関わるクラス:include_pathが通ったディレクトリに配置
  69: require_once('pahooCache.php');

黒点相対数の推移グラフを描くのに、jQueryプラグイン「jqPlot」を利用する。
jqPlot の入手方法、インストール方法については、「PHPでNHK政治意識月例調査をグラフ表示」を参照してほしい。

移動平均を求めるのに、自前のクラスファイル "pahooStat.php" を利用する。利用方法については、「PHPで相関係数と回帰直線を表示」を参照してほしい。

1749年から現在までの毎月の黒点相対数の平均値を公開しているベルギー王立天文台のデータを利用することにした。Sunspot Numberからにあるテキスト・ファイルを、定数 FILE_DATA で示すURLで読み込む。
ここで、データ配置サイトに負荷をかけないようオリジナルのキャッシュシステム(pahooCacheクラス)を利用する。使用方法については、「PHPで天気予報を求める - キャッシュ・システム」を参照いただきたい。キャッシュ保持時間、キャッシュ・ディレクトリともに、自サイトの環境に応じて変更してほしい。

解説:単純移動平均

 190: /**
 191:  * 単純移動平均
 192:  * @param   int   $m 区間
 193:  * @param   array $x データ配列
 194:  * @param   array $y 移動平均を格納する配列
 195:  * @return  bool TRUE/FALSE
 196: */
 197: function simple_moving_average($m, $x, &$y) {
 198:     if (! $this->is_data($x))   return FALSE;
 199: 
 200:     //区間が奇数
 201:     if ($m % 2 == 1) {
 202:         $n = floor($m / 2);
 203:         for ($i = $n$i < count($x- $n$i++) {
 204:             $z = 0;
 205:             for ($j = $i - $n$j <$i + $n$j++)  $z +$x[$j];
 206:             $y[$i] = $z / $m;
 207:         }
 208:     //区間が偶数
 209:     } else {
 210:         $n = floor($m / 2);
 211:         for ($i = $n$i < count($x- $n$i++) {
 212:             $z1 = 0;
 213:             for ($j = $i - $n$j < $i + $n$j++)           $z1 +$x[$j];
 214:             $z2 = 0;
 215:             for ($j = $i - $n + 1$j <$i + $n$j++)  $z2 +$x[$j];
 216:             $y[$i] = (($z1 / $m+ ($z2 / $m)) / 2;
 217:         }
 218:     }
 219:     return TRUE;
 220: }

変動のあるデータをなだらかにし、全体の傾向を見るときに移動平均という統計手法を用いる。ここではデータに重み付けを行わない単純移動平均を用いることにする。

移動平均の計算方法は、移動平均を求めたい区間が奇数か偶数かによって異なる。

  • 区間が奇数( mimetex )のとき:
 mimetex 

  • 区間が偶数( mimetex )のとき:
 mimetex 

解説:データ・ファイルを読み込む

 158: /**
 159:  * データ・ファイルを読み込む.
 160:  * pahooCacheクラスを利用する.
 161:  * @param   string $fname  入力ファイル名
 162:  * @param   array  $items  データを格納する配列
 163:  * @param   object $pcc    pahooCacheオブジェクト
 164:  * @return  int データ件数/FALSE
 165: */
 166: function readDataFile($fname, &$items, $pcc) {
 167:     //データ・ファイルを読み込む.
 168:     $contents = $pcc->load($fname);
 169:     if ($contents == FALSE)     return FALSE;
 170: 
 171:     //改行を行区切りとして1行ずつ読み込んで配列へデータ格納する.
 172:     $cnt = 0;
 173:     $arr = array();
 174:     $tok = strtok($contents, "\n");
 175:     while ($tok !FALSE) {
 176:         $arr = preg_split('/[ ]+/i', $tok);
 177:         if (($arr !FALSE&& (count($arr>3)) {
 178:             $items[$cnt]['year'] = $arr[2];
 179:             $items[$cnt]['SSN']  = $arr[3];
 180:         }
 181:         $cnt++;
 182:         $tok = strtok("\n");
 183:     }
 184: 
 185:     return ($cnt - 1);
 186: }

先述のベルギー王立天文台のテキスト・データの1行は、下記のような構造になっている。
内容
1int西暦年
2int
3float西暦年月(月は小数)
4float黒点相対数(月平均)
5float標準偏差
6int観測数
ここでは列3をX軸に、列4をY軸にプロットしていくことにする。
行は固定長ではあるが、スペースで区切られていることから、組み込み関数  preg_split  で個々の要素に分離し、配列へ格納してゆくことにする。

解説:推移グラフ

 188: /**
 189:  * jqPlot用のスクリプト:年次推移グラフ
 190:  * @param   array  $items データ配列
 191:  * @param   string $name オブジェクト名
 192:  * @param   string $title グラフ・タイトル
 193:  * @return  string スクリプト
 194: */
 195: function plotProgress($items, $name, $title) {
 196:     //グラフの色
 197:     $color_ssn  = COLOR_SSN;
 198:     $color_mean = COLOR_MEAN;
 199:     //移動平均を求める区間(月)
 200:     $interval = INTERVAL;
 201: 
 202:     //移動平均
 203:     $x = array();
 204:     $y = array();
 205:     foreach ($items as $key=>$val)  $x[$key] = $val['SSN'];
 206:     //統計オブジェクト
 207:     $pst = new pahooStat();
 208:     $pst->simple_moving_average(INTERVAL, $x, $y);      //移動平均
 209:     $pst = NULL;
 210:     foreach ($y as $key=>$val)  $items[$key]['mean'] = $val;
 211: 
 212:     //X軸の最小・最大
 213:     $xmin = floor($items[0]['year'] / 10* 10;
 214:     $xmax = (floor(date('Y') / 10+ 1* 10;
 215: 
 216:     //系列の生成
 217:     $s1 = '';
 218:     foreach ($items as $key=>$val) {
 219:         if (isset($val['SSN'])) {
 220:             $s1 .sprintf('[%f, %f], ', $val['year'], $val['SSN']);
 221:         }
 222:     }
 223:     $s2 = '';
 224:     foreach ($items as $key=>$val) {
 225:         if (isset($val['mean'])) {
 226:             $s2 .sprintf('[%f, %f], ', $val['year'], $val['mean']);
 227:         }
 228:     }
 229: 
 230:     $width  = GRAPH_WIDTH;
 231:     $height = GRAPH_HEIGHT;
 232:     $js =<<< EOT
 233: <script>
 234: jQuery(function() {
 235:     jQuery.jqplot('{$name}',
 236:     [
 237:         [ {$s1} ],
 238:         [ {$s2} ]
 239:     ],
 240:     {
 241:         //ラベル
 242:         series: [
 243:         {
 244:             label: '月平均',
 245:             color: '{$color_ssn}'
 246:         },
 247:         {
 248:             label: '{$interval}ヵ月移動平均',
 249:             color: '{$color_mean}'
 250:         },
 251:         ],
 252:         legend: {
 253:             show: true,
 254:             placement: 'inside',
 255:             location: 'ne',
 256:             renderer: $.jqplot.EnhancedLegendRenderer,
 257:             rendererOptions: { numberRows: 1 }
 258:         },
 259:         //グラフ
 260:         seriesDefaults: {
 261:             showLine: true,
 262:             rendererOptions: { smooth: false },
 263:             markerOptions: { size: 0 },
 264:         },
 265:         //軸
 266:         axes: {
 267:             xaxis: {
 268:                 label: '西暦年',
 269:                 tickOptions: { formatString: '%d' },
 270:                 min: {$xmin},
 271:                 max: {$xmax},
 272:             },
 273:             yaxis: {
 274:                 label: '黒点相対数',
 275:                 tickOptions: { formatString: '%.1f' },
 276:                 min: 0.0
 277:             }
 278:         }
 279:     }
 280:     );
 281: });
 282: </script>
 283: <div id="{$name}" style="width:{$width}px; height:{$height}px;"></div>
 284: 
 285: EOT;
 286: 
 287:     return $js;
 288: }

配列に格納したデータから移動平均を求め、黒点相対数と移動平均の推移をjqPlotスクリプトへ展開し、折れ線グラフとする処理は、ユーザー関数 plotProgress で行う。

マウンダー極小期

過去400年間の黒点数
過去400年間の黒点数
観測記録が少ないものの、1645年から1715年にかけ、黒点数が著しく減少した期間があり、マウンダー極小期と呼ばれている。
イギリスではテムズ川が凍結し、アメリカではニューヨーク湾が凍結した。また、アイスランドは海氷に取り囲まれ、食糧不足で人口が半減した。日本でも、この時代に飢饉が頻発し、百姓一揆が起きるようになった。

太陽活動と小氷期の関係については、専門家による研究を待たねばならないが、地球のエネルギー収支があるのは事実だから、温暖化ガスの影響だけで温暖化や寒冷化を論じるべきではないだろう。

参考サイト

(この項おわり)
header