分光器のデータを加工するプログラムの解説

  1. 解析プログラムは perl で書いてある。

    STEXの/home/ohba/gnuplot 以下にあるサンプルプログラムのほとんどはperl という言語で書かれている。perl についての解説やリンクは、こちら。一般的な科学計算で用いられる FortranやC,C++が、ソースプログラムをコンパイルしてから実行する、という 二段階の手続きが必要である(コンパイラー言語)であるのに対し、perl は プログラムを書いたらすぐ実行出来る(インタープリタ言語、または、スクリ プト言語)。ただ、通常のインタープリタ言語(Basicやシェルスクリプト) が、一行ずつ翻訳しながら実行されるのに対し、perl はプログラム全体を一 旦コンパイルして中間コードを生成してから実行されるので、あまり、速度の 低下は気にならない。perlは、最近は、WEBのCGI言語として広く用いられてい る。

    perlの文法は柔軟なので、最低限の記述で行いたい操作ができるが、その反面、 文法を知らない人が見ると、(特に入出力の部分などは)暗号のようなプログ ラムに見えるかもしれない。ただ、データの演算などはCやFortranと違いがあ るわけでないので、(perlの文法を知らなくても)既存のプログラムを少し変 更するだけで、行いたいデータ処理はできる。(もちろん、自分でC言語で書 いても構わないが... )

  2. 実行できるかできないか?

    プログラムを作ったつもりなのに、そのプログラムが実行してくれないこと がある。Unix では、プログラムが実行されるためには、そのプログラム内の 処理が正しいかどうか以前に、次のふたつの条件が満たされていないといけな い。

  3. 小物を組合せて、柔軟に使う(パイプとリダイレクト)

    例えば、/usr/local/bin 以下にどのようなファイルがあり、いつ、それらが作られたかを 調べるためには、

    % ls -l /usr/local/bin
    
    と入力するが、これでは出力が画面を流れてしまい、最後の方しか見ることが できない。そこで、
    % ls -l /usr/local/bin | less 
    
    とすると、ls -l /usr/local/bin の出力を、ページャー(less)に入れてみ ると、最初からじっくりと見ることが出来る。ひとつのコマンドの標準出力を、 他の標準入力に結び付けることをパイプ(またはパイプライン)と言い、 "|" を使う。また、上の結果をファイルとして保存したい場合には、
    % ls -l /usr/local/bin > file.txt 
    
    というようにする。このように、標準出力(入力)をファイルに結び付けるこ とを、リダイレクト(またはリダイレクション)と言い、 ">",">>", "<" などの記号を使 う。詳しい解説は、 コンピューター基礎教育のテキストを参照。このように Unix では、少しの仕事をするいくつかのコマンドを組合せて使うことで、自 分が行いたい処理を簡単にかつ柔軟に行わせることが出来る。いくつかの例を 示そう。
      
    % ls -l /usr/local/bin | grep tex | less 
       (/usr/local/bin の下の tex を含むファイルを less で表示)
    % ps aux | sort > ps.txt 
       (現在、走っているすべてのプロセスを、ユーザー名でソートして、ps.txt に保存)
    % ps aux | grep -v USER | wc -l
       (現在、走っているすべてのプロセスの数を表示)
    % grep http * | grep -v stex | less
       (カレントディレクトリのすべてのファイルから、http を含み stex を含まない行を less で表示)
    
    テキストで、gnuplot でデータをプロットする際に、
    gnuplot>plot "<raw rf1500.txt"
    
    となっている部分は、予め、シェルのコマンドラインで、
    % raw rf1500.txt > rf1500.dat (または、raw < rf1500.txt > rf1500.dat でも同じ) 
    
    としてから、
    gnuplot>plot "rf1500.dat"
    
    としても同じである。

  4. もっとも簡単な入門(raw というプログラムの解説)

    raw というプログラムは、RF1500 から取り込んだ実験条件などのヘッダー付 きのファイルから、ヘッダー部分を除いて、gnuplot でプロットできる形式に 変換し、標準出力に出す。プログラムの中味は次のようになっている。行番号と 赤い字は、説明のためで、実際のプログラムにはない。また、プログラム中で、 リンクが張ってあるコマンドをクリックするとそのマニュアルページを開く。

         1  #!/usr/local/bin/perl  # perl のプログラムであるとの宣言
         2  # 目的      # 以下はコメント行(実行には無関係)
         3  #  第1引数のファイル(指定しない場合は標準入力)から
         4  # 各行の最初の列がゼロ以外の数字である行を標準出力に出す。
         5  #  つまり、数値データから余分なヘッダーを除く。
         6              # 空行も無関係
         7  # read data
         8  $n=0;     # スカラー変数は、$から始まる
         9  while(<>){  # <>はファイルハンドル。引数のファイルから一行ずつ読み込み、空になるまで続ける
        10      chop;    # 行末の改行文字を削除
        11      ($x[$n],$y[$n])=split;  # 空文字(スペース、タブ)で分けて、最初のふたつを代入、3つ以上ある場合は無視
        12      if($x[$n]!=0){$n++;}  # 最初の変数がゼロ以外の数字の場合のみ、配列要素を増やす。
                     # つまり、数字以外の場合は、次の読み込みで上書きされて消える。
        13  }
        14
        15
        16  # output
        17  for($i=0;$i<$n;$i++){
        18      print "$x[$i]\t$y[$i]\n";  # ふたつの数値配列をタブ(\t)で区切って出力する。
                         # 出力先のファイルハンドルを省略すると、標準出力に出す。\nは改行。
        19  }
    
    9〜11行目あたりが、他のプログラム経験があって、perl を知らない人には、 意味不明になるところである。
    9行目の<>で、何を対象に読み込むのか?
    通常、ファイルハンドル <ハンドル名>は、
       open(IN,"ファイル名");
       while(<IN>){
         }
       close(IN);
    
    と、ファイルをオープンするときに付けた名前に対応させる。ハンドル名が 省略された<>(ヌルファイルハンドル)に対し、perl はコマンドが呼ばれたときの引 数があるかどうかをチェックし、ある場合にはそれらを順番に開いて読み込 む。引数がない場合には、標準入力から読み込もうとする。したがって、raw コマンドの 次のふたつの使い方は、全く同じことを行う。
    	raw ファイル名
    	cat ファイル名 | raw
    
    9〜11行目で 読み込まれた行は、どこに格納されるのか?
    chop や split は何に対して実行されるのか?

    perl では、コマンドの入力と出力に対するデフォルトの変数が準備されている。 それが、 $_ である。while(<>) は、while($_=<>)と同じで、chop は chop($_) と同じである。 また、split は本来、split(/PATTERN/,EXPR,LIMIT) と使うが、すべてが省略されると、 perl は、それぞれに対し、適当なデフォルトを仮定して、11行目の例の場合には split(/[ \t\n]+/,$_,3) と同等になる。詳しくは、 こちらを見てね

    以上をふまえると、

    	while(<>){
                chop;
                ($x[$n],$y[$n])=split;
             }
    
    の部分は、
    	unshift(@ARGV, '-') if $#ARGV < $[;
    	while ($ARGV = shift) {
    	     open(ARGV, $ARGV);
    		while ($line=<ARGV>) {
    			$choped_line=chop($line);
    			($x[$n],$y[$n])=split(/[ \t\n]+/,$choped_line,3) ;
    		}
    	}
    
    と書いても同じである。どちらでも perl は同じ結果を出す。違いといえば、 最初の方が、プログラムを書く手間が省けることだけだろう。

    このように perl は、プログラマーの意図を出来る限り読み取り、意味が通じ る限りデフォルトで補って、実行可能なコードを生成しようとする。したがっ て、最小限のプログラムで、多くの仕事をさせることが出来る。もちろん、こ のようなコーディングスタイルは、大規模なプログラムを作る場合には、潜在 的にバグが潜り込む可能性が高くなる。その場合には、もっと厳密なコーディ ングをすればよいのであって、厳密なコーディングには perl はそのまま答え てくれる。この辺りのことを、「perl は、難しい仕事を不可能にす ることなしに、簡単な仕事を簡単に出来るように設計されている」 と Larry Wall(perl の作者)は書いている。

  5. ゼロ点補正のプログラム

    ここでは、実験2で用いる anisotropy というプログラムを 解説し、実験の際にゼロ点がずれたまま測定してしまった場合に、データ処理で それに最低限の補正を加えるようにプログラムを変更する方法を述べる。 (これは例として掲げているだけで、実験ではゼロ点を正しくセットしてから 行うのが基本である。)

    解説はこちら

生物物理実験のトップページへ戻る
一般物理学実験のホームへ