SQL + スクリプトで利用する公開天文データベース

2010年8月19日 光赤天連「データ解析の新展開」用資料 [2011年12月22日更新]

山内@宇宙研


SQL編 / PHP編

注意


イントロ -- 今日のお話

カタログを使った解析は新しい時代へ…

【背景】

【研究者・サービスの開発者が直面する問題】

【上記問題に対して研究者ができる事】

今日のテーマ: 効率良く必要なカタログデータを取得するための兵器は…!?


SQL事はじめ

天文データに使われるデータベースシステムって?

SQL文でできる事

SQLって難しくない?


SQL の入力を受けつけている公開サービスを発見したら…


ビュー(View)とは…


SQL で Hello World


SQL で計算


演算子と数学関数


関数の種類


テーブルにアクセスしてみる

取得するカラムとアクセスするテーブルを指定


件数を知る


件数を制限

データベース製品によって異なる.


検索条件を指定


ソート


複数のテーブルを結合する(ナチュラルジョイン)


複数のテーブルを結合する(レフトジョイン)


いよいよ Radial Search (コーンサーチ)


サブクエリ (絞り込み検索)


登録されているカタログとカタログとのマッチアップ


AKARI-CAS で便利なストアドファンクション


史上最強の手続き言語,PHP のススメ

PHPって?

PHPの何がいいのか


PHPのインストール

Version 5 系列をご利用ください.


PHPの基本


変数

Perlに似ています.宣言は不要で,いきなり代入できます.


文字列処理


if文


ループ

C言語やPerlと同じ構文です.


コマンド引数の受け取り


関数の作成


ソースファイルの分割


実践編

Webサーバ上のHTMLを取得


SDSS SkyServerから画像を取得


SIMBADから天体の基本データを取得


AKARI-CAS に SQL でカタログの値を取得


NED から VOTable を取得して必要なデータを表示


スクリプトから AKARI-CAS の Cross-ID を利用


スクリプトから SDSS の Cross-ID を利用

SDSSの場合,application/x-www-form-urlencoded の形式では受け付けていないようなので, multipart/form-data の形式でデータを投げるようにします.例を示します:

<?php

  /* multipart/form-data 形式の送信データを作る                           */
  /*  $boundary    : 境界文字列                                           */
  /*  $prms        : フォームのパラメータ(連想配列)                       */
  /*  $upload_name : ファイルのアップロードに用いるフォームのパラメータ名 */
  /*  $upload_str  : アップロードするファイルの内容(文字列)               */
  function http_build_form_data($boundary, $prms, $upload_name, $upload_str) {
    $return_value = "";
    /* 改行コード */
    $cr = "\n";
    /* 連想配列からキーを取得 */
    $keys = array_keys($prms);
    /* パラメータ群 */
    for ( $i=0 ; $i < count($keys) ; $i++ ) {
      $return_value .= 
	"--" . $boundary . $cr .
	'Content-Disposition: form-data; name="' . $keys[$i] . '"' . $cr .
	$cr .
	$prms[$keys[$i]] . $cr;
    }
    /* 文字列 $upload_str をファイルとしてアップロード */
    $return_value .= 
      "--" . $boundary . $cr .
      'Content-Disposition: form-data; name="' . $upload_name . '"; ' . 
      'filename="' . $upload_name . '.txt"' . $cr .
      "Content-Type: text/plain" . $cr .
      $cr .
      $upload_str . $cr;
    /* 最後の境界線 */
    $return_value .= "--" . $boundary . "--" . $cr;
    return $return_value;
  }

  /* サーバのURL */
  $url = 'http://skyserver.sdss3.org/dr8/en/tools/crossid/x_crossid.asp';
  /* SQLステートメント */
  $uquery = "SELECT " . "\n" .			/* ←ここの改行は絶対必要 */
      "p.objID, p.ra, p.dec, p.run, p.rerun, p.camcol, p.field, " .
      "dbo.fPhotoTypeN(p.type) as type, ".
      "p.modelMag_u, p.modelMag_g, p.modelMag_r, p.modelMag_i, p.modelMag_z " .
      "FROM #upload u " .
      "JOIN #x x ON x.up_id = u.up_id " .
      "JOIN PhotoTag p ON p.objID = x.objID " .
      "ORDER BY x.up_id";
  /* 座標リスト */
  $upload = "name ra     dec\n" .		/* ←これも省略しない */
	    "A1   195.2  2.5\n" .
	    "A2   194.5  2.6\n" .
            "A3   193.6, 2.8\n";
  /* サーバへ送信するデータを作成 */
  $prms = array( 'searchType' 	   => 'photo', 
                 'photoScope'      => 'nearPrim',
                 'photoUpType'     => 'ra-dec',
                 'joinSpec'        => 'off',
                 'radius'          => '0.5',
                 'format'      	   => 'csv',
                 'firstcol'        => '1',
                 'uquery'          => $uquery
               );

  /* ヘッダ情報と中身を設定 */
  $boundary = 'PostgreSQL_is_the_Best-' . time();
  $content = http_build_form_data($boundary, $prms, "upload", $upload);
  $headers = array('Content-Type: multipart/form-data; boundary=' . $boundary,
  	           'Content-Length: ' . strlen($content));
  $options = array( 'http' => array( 'method' => 'POST',
                                     'header' => implode("\r\n", $headers),
                                     'content' => $content,
                                   )
                  );

  /* 結果の取得 */
  $result = file_get_contents($url, false, stream_context_create($options));
  echo $result;
?>

SDSS の SQL Search で Cross-ID を行なう

次のように UNION ALL を使って, SQL Search で Cross-ID をやってしまう方法もあります. こちらの方法では,ターゲットごとに検索半径を変える事ができます.

SELECT n.name, o.*
FROM photoobj o,
(
SELECT 'A1' as name, dbo.fgetnearestobjideq(195.2, 2.5, 0.5) AS objid
UNION ALL
SELECT 'A2' as name, dbo.fgetnearestobjideq(194.5, 2.6, 0.5) AS objid
UNION ALL
SELECT 'A3' as name, dbo.fgetnearestobjideq(193.6, 2.8, 0.5) AS objid
) n
WHERE n.objid = o.objid

タイムアウト処理


厳密な EOF の判定


スクリプトを走らせる時のエチケット