IRAF講習会
IRAF講習会〜CL Script入門
Script入門〜〜

国立天文台
天文データセンター
古荘 玲子
2011年
2011
年2月1616日
日

1

謝辞
過去のADC講習会テキスト（特に、大藪さん、吉田さん）のテキストと、2010年度第3回IRAFソフト開発講習会（2日目）の板さんのト開発講習会（2 目）の板さんのテキストを、非常に参考にさせていただきました。有難うございました。

2

凡例• IRAF(ecl)コマンドラインでの入力
ecl> !ds9 &• ファイルの内容（編集すべき内容）
print(“imcopy”)• その他（IRAFタスクのcompute mode記載例。動作確認のため、eclでコマンドとして入力してもよいだろう）
display(“hoge.fits”, 1, ztrans=“log”)
3

なぜIRAFを使うかメリット• 無料（重要）• 多くの人が使っている（重要）• 豊富な解析タスク・パッケージ– タスクを知ってさえいれば大抵のことはできるデメリット• ドキュメントがない（に等しい）• メモリを上手に使えない（らしい）
私はあまり困ったことがない。←大作を作ったことがないから(^^;;;• スクリプト開発では・・・– デバッガがない。エラーは大抵、意味不明

4

CL-script？
eclで必要なタスクを利用すれば、充分解析出来るでしょ。
でも・・・• いつもいつも同じ手順でやる作業ならば、スクリプトを組んだ方が効率がいい• 自分の開発した（カワイイ）装置には、解析パイプラインも用意したい• IRAFの豊富な解析タスクを利用して少しは楽をしたい（ほんと？）
5

CL-Script• IRAFのcl（command language）で動かせるスクリプト言語• １つのファイルに１つのスクリプト（関数）を記述する。
– Ｃ言語のように１つのファイルにいくつも関数を記述できる訳ではない。

• デバッガは無いので覚悟しましょう– えっと思うような些細な事でエラーを吐く– エラーの場所がわかりにくい
6Reference• An Introductory User’s Guide to IRAF Scrips– http://iraf.noao.edu/iraf/ftp/iraf/docs/script.pdf– 古い（V2.8用）が今でも有効
古い（V .8用）が今でも有効• IRAF CL Script Tips & Tricks– http://iraf.noao.edu/iraf/ftp/iraf/docs/script_intro.pdf– 比較的新しい（2003年）。プレゼンファイル。例が豊富• Host CL Scripting Capability– http://iraf.noao.edu/iraf/web/new_stuff/cl_host.html– CLを外から利用する方法• help language• IRAF開発講習会シリーズの過去のテキスト(ADC, NAOJ)– http://www.adc.nao.ac.jp/J/cc/public/koshu_shiryo.html#iraf_prog
7

本日の講習の流れ
0. 準備
1. 簡易CLスクリプト2. CLスクリプトの基本
クリプトの基本
3. CLスクリプトの機能
4. 実習：解析スクリプトを作ってみよう
余裕があれば余裕があれば・・・
5. さらに先へ

8

0. 準備をしよう
A) ワークディレクトリ（作業環境）と、必要な物を用意しよう
配布物
1. img/KCC*.fits
実習でつかうFITSデータ

2. img2/KCD*.fits
実習でつかうFITSデータ（自習用）

3. loginuser.cl
ユ ザ用の環境設定ファイル
ユーザ用の環境設定ファイル

4. printit.cl, prompttest.cl, taroex*.cl
実習用サンプルスクリプト

5. ans/*.cl
実習課題の解答例

6. panda.cl
パッケージ化プログラム（自習用）

9

0. 準備をしよう
B) IRAFの環境を準備しよう
1. mkiraf を実行
2. loginuser.cl を作成しよう（※）(※) login.clで読み込まれるユーザ環境を記述した設定ファイル
自分の環境設定にlogin.cl自体を変更するかloginuser.clを利用するかは、趣味の問題（だと思う）。
なお、今回は配布されたサンプルスクリプトの中にあります。
とりあえず、中身を眺めてみてください。環境準備の時点で重要（かもしれない）設定は以下の3行です
reset imextn = "oif:imh fxf:fits,fit,fts,FIT,FTS"
reset imtype = fits
reset stdimage=imt4096
100. Magic Word
• 動作がおかしい時は・・・– unlearn
CLでパラメータキャッシュをクリアする。task登録したCLスクリプトを書いている途中にパラメータを変えたら、必ずunlearnせよ。

– flprcache
プロセスの使ったキャッシュを掃除する。

• それでもダメなら・・・あきらめる

一旦logoutしてcl再起動
11

1. 簡易CLスクリプト• タスクを羅列してもCLスクリプトとして利用できる（ コマンドを羅列したシェルスクリプト）（cf.
ドを羅たプ ）• パラメータなし型のCLスクリプトecl> vi taroex0.cl ←taroex0.cl を作成する
print(“imcopy”)

内容

imcopy img/KCC00003.fits test.fits ↲改行し忘れにecl> task $taro0 = taro0.cl ←タスクとして登録
注意$ を頭につける（パラメータなし型の場合）
ecl> taro0

12

タスクの記述• command modeとcompute mode
• command modeecl> taskname arg1 ... argN par1=val1 par2=val2 ...

• compute modetaskname(arg1, ..., argN, par1=val1, par2=val2 ...)

13

スクリプトのお作法など• 1タスクは1行に書く
1つのタスクについて、パラメータが多くて長い記述を2行にわた て書きたい場合は ╲ (バックスラッシュ)
2行にわたって書きたい場合は、(バックスラッシ )で改行コードをエスケープする• タスクはcompute modeで記述した方が良いようです
なぜか・・・• 最後の行にも改行を入れる【重要】
最後の行に改行がないために動かない！ということが、意外とあります
14mkscript• 簡易CLスクリプトを作成するタスク
ecl> mkscript
Script file name (scr.cl): tarotmp.cl
Task name of command to be added to script: imcopy
このあと、imcopyのepar画面が出る。
適当に編集して、:wqで抜ける。

Is the command ok? (yes): yes
Add another command? (yes): no ←他にタスクを足したかったらyesと入力して繰り返し
Is the script ok? (yes): yes
Submit the script as a background job? (yes): yes

CLスクリプトの作成例が欲しい時に便利・・・
15

2. CLスクリプトの基本
基本構成（パラメータあり型）
1. procedure宣言
2. 明示パラメータ（スクリプト引数）宣言
3. 隠しパラメータ宣言
4. list directed parameters宣言
5 begin
5.
6. スクリプトの中身
7. end16

パラメータ(変数)のデータ型
int
realbool

整数型 32bit実数型。指数はEで表す ex.) 2.5E+2bool型(真偽値) yes / no真＝1, 偽＝0

stringfilestruct

文字列型
ファイル型(stringと変わらないらしい？)
特殊な文字列型

空白も文字列の一部として扱う

gcur, imcur カーソルパラメータ17

サンプルコード：printit.clprocedure printit (file_name)  始まりはprocedure
string file_namestruct *flist これは隠しパラメータ スクリプト引数の宣言
 list directed parameterの宣言

begin スクリプトの始まり
struct line これは内部変数
flist = file_namewhile( fscan( flist, line ) != EOF )print(line)
end

スクリプトの終わり
18printit.clを実行してみる• タスクの登録
ecl> task printit = printit.cl
パラメータあり型の場合、頭に$はつけない• 実行ecl> printit printit.cl printit.cl自身を表示させてみる

19

パラメータの読み取り
procedure printit (file_name)  始まりはprocedure
string file_namestruct *flist これは隠しパラメータ スクリプト引数の宣言
 list directed parameterの宣言

begin スクリプトの始まり
struct line これは内部変数
flist = file_namewhile( fscan(fscan flist, line ) != EOF )print(line)
end

スクリプトの終わり
20

パラメータの読み取り• scan ( p1, p2, … )– 標準入力から読み取って内部変数に格納
ecl> string ss1
ecl> =scan( ss1 )何か文字列を打ち込む。

ecl> =ss1• fscan( pp, p1, p2, … )– 内部変数ppから読み取って別の内部変数に格納
ecl> string ss2
ecl> =fscan( ss1, ss2 )ecl> =ss2
21

stringとstructの違い
ecl> string origstr = “Hello world”
ecl> string ss3
ecl>
l struct st1
ecl> =fscan ( origstr, ss3 )ecl> =ss3
ecl> =fscan ( origstr, st1 )ecl> =st1

22

3. CLスクリプトの機能
1. prompting
2. mktempp
3. list directed parameters (LDP)
4. ワイルドカードの取り扱いとsections

23

prompting• 実行時にパラメータへの入力を促す• パラメータ宣言のところに記述 propmttest.cl
procedure prompttest (file_name)string file_name {prompt = “Input file name”}
プロンプトのメッセージ内容
struct *flist
begin
struct line
flist = file_name  内部変数へ代入されるときにプロンプトが出る:
end24mktemp• 一時使用ファイル（temporary file）を作るコマンド• ファイル名を自動生成する• スクリプト中で大変便利• 片づけるのを忘れずに• 例）
ecl> tmpfile = mktemp( “hoge.” ) hoge.xxxx（xxxxは数字）というファイル名が自動生成されてtmpfileにアサインされる。
25

list directed parameters(LDP)• テキストファイルの中身を、改行で区切られた文字列の順序リストとして格納してくれる• CLスクリプト中での宣言：必ずbeginの前で、CLスクリプト中での宣言 必ずb i の前でstruct *ppp あるいは string *ppp
• テキストファイルをLDPに格納するやり方
ppp = file_name• CLスクリプト中でファイルの中身を順序読み出しするときは、必ずこれを使う。

26

ワイルドカードとsectionsコマンド• ワイルドカード– UNIXワイルドカード（*, ?, …）– IRAFの@付ファイルリスト• sectionsコマンド– ワイルドカードはsectionsコマンドで展開して標準出力に書き出す– 例）
sections( “*.fits”, option=“full” )sections( “@list”, option=“root” )27

LDPとsectionsを組み合わせてワイル
ドカードを展開してファイルを読む
infileに格納されたワイルドカード

struct *flistを展開して、tmpfileにファイル名展開、 pリストとして入れる
string infile, junktmpfile = mktemp(“hoge.”)sections( infile, option=“full”, > tmpfile)
flist = tmpfile
tmpfileをLDPに格納
while(hil ( fscan(f( flist,fli t junkj k ) !=! EOF ){ ・・・ }
fscanでLDPから一つずつファイル名をjunkに読み込んでいく

28

4 実習
4.
実習のサンプルスクリプトプログラムのタスク登録と実行例）
ecl> task taroex1 = taroex1.cl
ecl> taroex1
とりあえず、サンプルスクリプトを眺め、実行してみよう
29

FITS画像のヘッダをよむ
FITS画像リスト(img/KCC*.fits)を入力して、FITSファイル名と天体名(OBJECT)のリストを出力する（taroex1.cl）
をす （）FITSヘッダを読むには？
–使うタスク：imgetswhile( fcan( flist, inname ) != EOF ) {imgets( inname,inname ‘title’ )obj = imgets.value}

30

課題（1）
taroex1.cl を改訂して、FITS画像リスト(img/KCC*.fits)を入力して、FITSファイル名、天体名、露出時間、画像の平均値(mean)、画像のモード(mode)を出力する
スクリプトを作成しなさい画像の平均値等？ ファイル名iminfo.clで作成–使うタスク：imgets,使うタスク：imgets imstat

出力例
img/KCC00003.fits (1943)Anteros 300.0 7311.04 7250.83
img/KCC00004.fits (1943)Anteros 300.0 7289.13 7227.56:
31

タスクの結果をscanに渡す(パイプ)real mn, md:

1タスクを2行にわたって書きたいときは╲(バックスラッシュ)で行末をエスケ プする╲(バックスラッシュ)で行末をエスケープする

imstat( img, field=“mean, mode”, format‐) | ╲scan (mn, md) Imstat で img の mean, mode を表示⇒パイプで表示結果を scan に渡す
scan はパイプで渡された値を mn, md に格納

32

FITSデータを仕分ける
FITS画像のヘッダキーワードDATA-TYPをもとに画像ファイルを分類し、リストファイル（テキスト）に書き出す（taroex2.cl）（） 書す（）FITSヘッダの情報を得るには？
–使うタスク：hselect (例えば)※imgetsでも可能–結果をファイルに出力する
結果をファイルに出力する
outfiles = datatyp//"."//title //は文字列連結
print( param, >> outfiles )33

標準入力を読み取る
標準入力の文字列を読み取ってbool型変数に入れる（taroex3.cl）
 nが入力されるまで繰り返す
y か n 以外は無視される
bool flg = yes
While( flg ){print( “‐‐> Continue? <y/n>” )while( scan( flg ) == 0 ) {}if ( ! flg ) breakelse print( flg//“ Continue.” )}bye34

画像をds9に表示させる
画像を指定してds9に表示（taroex4.cl）–使うタスク：displayecl> !ds9 &String image_name {prompt = “Input image name”}
begin
string filename
filename = image_namedisplay(filename, 1, contras=0.0005, 実際はztrans = “log”, nsample=100000)
１行で書く
end35

隠しパラメータを変更可能に隠しパラメータを実行時に変更できるようにする：taroex4n.cl
displayタスクのパラメータztrans=“linear”も選べるように
String image_name {prompt = “Input image name”}
String ztrans=“log” {prompt = “ztrans for display”,enum=“log|linear"}

実際は１行で書く

beginstring filename,zt
filename = image_namezt = ztransdisplay(filename, 1, contras=0.0005, ztrans = zt,
nsample=100000)
実際は
end
１行で書く
36

課題（２）
① taroex1.cl と taroex4.cl を組み合わせて、FITS画像リスト(img/KCC0*.fits)を入力
して画像を順にds9に表示するスクリプ
像を表 す
プトを作成しなさい② さらに、(taroex3.cl を参考にして)標準入力からの入力で、次の画像を表示するタイミングを制御できるようにしなさい（yを入力すると次の画像を表示する）
seqdisplay.cl37

ds9の座標値を読み取る
ds9のカーソルの座標値をfscanで読み取って変数に入れる（taroex5.cl）カーソル変数imcurを使う
ds9は起動しておくこと
While( fscan( imcur, xx, yy, wcs, command ) != EOF ){key = substr( command, 1, 1 )if ( key == “q” ){  カーソル上での入力が q ならば抜ける
break} else {print( xx, yy )}
}
38

課題（３）
ds9上で画像の左下と右上2点を指定して、その矩形領域の統計情報（ピクセル数、mean、modeなど）を表示するスクリプトな ）を表 す
プを作成しなさい– 使うタスク： imstatistics
ファイル名imreqtstat.clで作成【余裕がある人は】スクリプトを、画像1枚ではな【余裕がある人は】スクリプトを画像1枚ではな
く画像リストを引数として入力するように改造しなさい。また、表示した矩形領域および統計情報をファイルに出力するようにしなさい39インタラクティブな画像位置合わせカーソル座標値をfscanで読み取って変数に入れ、reference画像とのshift量を一時ファイルに格納。
結果ファイル名リストは事前に作成（taroex6.cl）string tmpfile1, tmpfile2, tmpfile3
実行したら、位置合わせ
tmpfile1 = mktemp( “tmp$shiftimg1.” )結果を seqdisplay.cl で表(...snip...)示してみましょう。
while( fscan( flist, fname ) != EOF ) {⇒ 小惑星は見つかりましdisplay( fname, 1 )たか・・・？
if( fscan( imcur, xx, yy ) == 2 ){sx = refx – xxsy = refy – yy
print( sx, sy, >> tmpfile3 )}}imalign( inimg, refimg, tmpfile2, “@”//outlist, shifts=tmpfile3)
実行のしかたは次ページ

40

インタラクティブな画像位置合わせ
準備（imalignの結果ファイルのファイル名リストを作成）ecl> sections(“img/KCC0*%.fits%_sh.fits%”, > “shiftfile.lst”)

入力

結果画像のファイル名リストを作る。
%で囲まれた文字列を置換

ecl> task taroex6 = taroex6.cl
ecl> taroex6 img/KCC0*.fits img/KCC00003.fits shiftfile.lst
reference画像

Imalign結果の画像ファイル

動作
名リスト• 最初に、reference画像として指定した画像をds9に表示
 適当な星(※)にカーソルを合わせて何かキー（“q”以外）を打つと、その位置をreference座標として記録• 次に、画像リストとして入力した画像(img/KCC0*.fits)を順にds9に表示
 カーソルを※と同じ星に合わせてキーを打つ
 今表示している画像の星の座標とreference座標との差分を記録
 imalignを実行。結果は引数で与えたファイルリストに記載され41ているFITSファイルへ課題（４）taroex6.clをもとに、特定の天体に位置を合わせて画像を合成するスクリプトを作りなさい（ヒント：シフト結果のファイル名もmktempで作成し、終わったら消去する）– 使うタスク： imalign, imcombine
ファイル名imshiftcomb.clで作成【余裕がある人は】imalign, imcombineのパラメータを隠しパラメータとして設定したうえで、実行時に変更できるように改造してみよう。
42

5. さらに先へ

43

パッケージ登録• panda.clを参考にして、パッケージを作成してみよう
おまけ• 自作CLスクリプトをIRAF CLログイン時に常にタスクとして登録するには？
loginuser.clg
set mycls = “/full/path/to/clscriptfilesdir/”
CLスクリプトファイルが置かれているディレクトリへの絶対パス

task taroex0 = mycls$taroex0.cl

44

解析パイプラインを作ってみよう• img2/ のデータを解析するパイプラインを作りなさい
1. FITSヘッダキーワードDATA-TYPで、オブジェクト、フラット、バイアスに分類
2. バイアスを合成する
3. オブジェクト・フラットフレームからバイアスを引く
4. フラットを合成して、オブジェクトフレームをフラット補正する
5. オブジェクトフレームを位置合わせし合成する（インタラクティブに）※45

その他、知っていると便利なコマンド• byeスクリプトを途中終了する• next繰り返しの制御構造（for, while等）で次ターンとしてループ
先頭へ– C言語の continue; と同等• goto指定したラベルの行へジャンプ（ラベルは末尾にコロン“:”をつける）• access
ファイルが存在するかどうか判定（存在すれば真=1）–例
if( access( infile ) == 0 ) bye
46

IRAF外部からCLを利用• 明日の板さんの講義をお楽しみに！

47