TDRのデータをMac OS Xで取り込む方法
譲り受けたちょっと古いTDRの装置(HP54120B(オシロ本体),HP51421T(サンプリングヘッド))を動かすのに、用意されたGPIBインターフェースが、NI社のGPIB-USBやそれ以降の製品だと、Mac OS 9用のドライバが存在しない。このため、現状ではclassic環境でしか動作しないTDRppcで直接データを持ってくることができない。
幸いにして、Igor Proを使うと、OS XからでもNI社のドライバを叩くことができる。
TDRppcは、プログラムとしては後発なので、この分野の「老舗」の東海大学の研究室で使われているデータファイルフォーマットにも対応している。Igor Proで、装置からデータを読み込んで、東海大フォーマットで保存すれば、classic環境でTDRppcを動かし、フーリエ変換して誘電スペクトルを計算することができる。
誘電スペクトルを得た後は、モデルを仮定してフィッティングし、緩和時間を出すといったことが必要になるので、どっちみちIgor Proが大変役立つ状況になる。それならば、計測をIgor Proでやってしまうという解決策も有りだろう。
まあ、TDRppcのCarbon対応をとっととやる、というのが一番正しい解なのだが、なかなか……(汗)。時間稼ぎも必要なので、とりあえず、スクリプトを公開しておく。
装置依存の部分(データ点が500など)を決め打ちで書いてるけれど、若干の変更で、もっと新しい機種でも動作はするはず。HP(現アジレントテクノロジー)は、新しい計測器でも、古い計測器のコマンドが通るように設計してくれているようだ。
#pragma rtGlobals=1 // Use modern global access method.
// 東海大学と同じデーターフォーマットで測定結果のファイルを書き出す。
// NI社のGPIBインターフェース利用。
// Mac OS Xで動かす場合は、Igor Pro Folder/Igor Extensionsの中に、Igor Pro Folder/More Extensions/Data Acquisition/NIGPIB2_OSX.xop
// をコピーした後、Igorを一旦終了し、再度走らせる。
// Preambleを入れたwaveの内容
// pre[0] format
// pre[1] type
// pre[2] points データ点(横軸)の数
// pre[3] count 積算回数
// pre[4] xincrement 時間軸の間隔
// pre[5] xorigin
// pre[6] xreference
// pre[7] yincrement 電圧軸のスケールファクター。ASCII等で読み出した値にこれをかけると電圧の値になる
// pre[8] yorigin
// pre[9] yreference
// pre[10] yrange
// インターフェース回りの初期化と、グローバル変数として持ち回る変数の宣言および初期化
Macro InitializeInterface()
Variable/G BoadAddr = 0 // パソコン側のGPIBインターフェースのアドレス。通常0とか1とか
Variable/G TDRAddr = 7 // 計測器のGPIBインターフェースのアドレス
Variable/G DVTDR // 計測器の識別子
String/G cmdstr //コマンドラインで実行する文字列を作る
String/G resultstr // 結果を一時的に格納する
Variable/G len // 文字列の長さなどの格納用
// Preamble格納用 _sとあるのは標準試料、_xとあるのは未知試料、_dcとあるのはDC補正用試料にそれぞれ対応。
Make/O/N=11 preamble_s
Make/O/N=11 preamble_x
Make/O/N=11 preamble_dc
//Memory1-3を読み出した内容を格納する文字列
String/G s_sample
String/G s_dc
String/G s_standard
//保存前にwaveで受ける
// 東海大のフォーマットは歴史的理由で1つの時間領域データが1024点のデータからなる。
// 54120Bを使った場合に有効なデータは、最初の500点のみである。
Make/O/N=1024 w_sample
Make/O/N=1024 w_dc
Make/O/N=1024 w_standard
// インターフェースクリア等
sprintf cmdstr, "NI4882 ibdev={%d,%d,0,13,1,0}", BoadAddr, TDRAddr
Execute cmdstr
DVTDR = V_flag // 以後はこの数で計測器を特定する。
// ifc
sprintf cmdstr, "NI4882 ibclr={DVTDR}"
Execute cmdstr
End
// DC成分が無い場合の測定。
// Memory1に標準試料、Memory2に未知試料のデータをいれておくこと。
// 保存の時にできるファイルは1つ。
Macro Standard_Sample()
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":SYSTEM:HEADER OFF;:EOI ON¥", 26}"
Execute cmdstr
// memory 1の読み出し
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:SOURCE WMEMORY1;FORMAT ASCII¥", 38}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:PREAMBLE?¥", 19}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 256}"
Execute cmdstr
resultstr = S_Value // Preambleの文字列を得る
sprintf cmdstr, "preamble_s = {%s}", resultstr
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:DATA?¥", 15}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 3200}" // 数字5桁にカンマなので1つの数字につき6文字、500点あるので3000で足りるが、多めに読んでみる。
Execute cmdstr
s_standard = S_value // 標準試料の測定結果。カンマで区切った整数値。
ReadDataToWave(s_standard, w_standard)
w_standard[500,1023] = w_standard[499] // 穴埋め
// memory 2の読み出し
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:SOURCE WMEMORY2;FORMAT ASCII¥", 38}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:PREAMBLE?¥", 19}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 256}"
Execute cmdstr
resultstr = S_Value // Preambleの文字列を得る
sprintf cmdstr, "preamble_x = {%s}", resultstr
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:DATA?¥", 15}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 3200}" // 数字5桁にカンマなので1つの数字につき6文字、500点あるので3000で足りるが、多めに読んでみる。
Execute cmdstr
s_sample = S_value // 未知試料の測定結果。カンマで区切った整数値。
ReadDataToWave(s_sample, w_sample)
w_sample[500,1023] = w_sample[499] // 穴埋め
// 東海大互換フォーマットでの書き出し
// time interval(改行)
// スタンダードの電圧軸スケールファクター(改行)
// 未知試料の電圧軸スケールファクター(改行)
// 1行に8個スペース区切りで、合計1024個(128行)のスタンダードのデータ
// 1行に8個スペース区切りで、合計1024個(128行)の未知試料のデータ
Variable FileRefNum
Variable i
Close/A
Open/C="????"/T="TEXT" FileRefNum
fprintf FileRefNum, "%e¥r¥n", preamble_s[4]
fprintf FileRefNum, "%e¥r¥n", preamble_s[7]
fprintf FileRefNum, "%e¥r¥n", preamble_x[7]
// 標準試料の書き出し
i = 0
do
fprintf FileRefNum, " %e ", w_standard[i]
i += 1
if (mod(i, 8) == 0)
fprintf FileRefNum, "¥r¥n"
endif
while(i < 1024)
// 未知試料の書き出し
i = 0
do
fprintf FileRefNum, " %e ", w_sample[i]
i += 1
if (mod(i, 8) == 0)
fprintf FileRefNum, "¥r¥n"
endif
while(i < 1024)
Close FileRefNum
End
// DC成分が有る場合の測定。
// Memory1に標準試料、Memory2にDC補正用試料、Memory3に未知試料のデータをいれておくこと。
// 保存の時にできるファイルは3つ。
Macro Standard_DC_Sample()
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":SYSTEM:HEADER OFF;:EOI ON¥", 26}"
Execute cmdstr
// memory 1の読み出し
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:SOURCE WMEMORY1;FORMAT ASCII¥", 38}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:PREAMBLE?¥", 19}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 256}"
Execute cmdstr
resultstr = S_Value // Preambleの文字列を得る
sprintf cmdstr, "preamble_s = {%s}", resultstr
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:DATA?¥", 15}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 3200}" // 数字5桁にカンマなので1つの数字につき6文字、500点あるので3000で足りるが、多めに読んでみる。
Execute cmdstr
s_standard = S_value // 標準試料の測定結果。カンマで区切った整数値。
ReadDataToWave(s_standard, w_standard)
w_standard[500,1023] = w_standard[499] // 穴埋め
// memory 2の読み出し
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:SOURCE WMEMORY2;FORMAT ASCII¥", 38}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:PREAMBLE?¥", 19}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 256}"
Execute cmdstr
resultstr = S_Value // Preambleの文字列を得る
sprintf cmdstr, "preamble_dc = {%s}", resultstr
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:DATA?¥", 15}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 3200}" // 数字5桁にカンマなので1つの数字につき6文字、500点あるので3000で足りるが、多めに読んでみる。
Execute cmdstr
s_dc = S_value // 未知試料の測定結果。カンマで区切った整数値。
ReadDataToWave(s_dc, w_dc)
w_dc[500,1023] = w_dc[499] // 穴埋め
// memory 3の読み出し
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:SOURCE WMEMORY3;FORMAT ASCII¥", 38}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:PREAMBLE?¥", 19}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 256}"
Execute cmdstr
resultstr = S_Value // Preambleの文字列を得る
sprintf cmdstr, "preamble_x = {%s}", resultstr
Execute cmdstr
sprintf cmdstr, "NI4882 ibwrt={DVTDR, ¥":WAVEFORM:DATA?¥", 15}"
Execute cmdstr
sprintf cmdstr, "NI4882 ibrd={DVTDR, 3200}" // 数字5桁にカンマなので1つの数字につき6文字、500点あるので3000で足りるが、多めに読んでみる。
Execute cmdstr
s_sample = S_value // 未知試料の測定結果。カンマで区切った整数値。
ReadDataToWave(s_sample, w_sample)
w_sample[500,1023] = w_sample[499] // 穴埋め
// 東海大互換フォーマットでの書き出し
// time interval(改行)
// スタンダードの電圧軸スケールファクター(改行)
// 未知試料の電圧軸スケールファクター(改行)
// 1行に8個スペース区切りで、合計1024個(128行)のスタンダードのデータ
// 1行に8個スペース区切りで、合計1024個(128行)の未知試料のデータ
Variable FileRefNum
Variable i
Close/A
// DCなし標準と、DC有り標準の書き出し
Open/C="????"/T="TEXT"/M="DCなし標準とDC補正データの保存" FileRefNum
fprintf FileRefNum, "%e¥r¥n", preamble_s[4]
fprintf FileRefNum, "%e¥r¥n", preamble_s[7]
fprintf FileRefNum, "%e¥r¥n", preamble_dc[7]
// DCなし標準試料の書き出し
i = 0
do
fprintf FileRefNum, " %e ", w_standard[i]
i += 1
if (mod(i, 8) == 0)
fprintf FileRefNum, "¥r¥n"
endif
while(i < 1024)
// DCあり標準試料の書き出し
i = 0
do
fprintf FileRefNum, " %e ", w_dc[i]
i += 1
if (mod(i, 8) == 0)
fprintf FileRefNum, "¥r¥n"
endif
while(i < 1024)
Close FileRefNum
// DCあり標準試料と、未知試料の書き出し
Close/A
Open/C="????"/T="TEXT"/M="DC補正データと未知試料の保存" FileRefNum
fprintf FileRefNum, "%e¥r¥n", preamble_dc[4]
fprintf FileRefNum, "%e¥r¥n", preamble_dc[7]
fprintf FileRefNum, "%e¥r¥n", preamble_x[7]
// DCあり標準試料の書き出し
i = 0
do
fprintf FileRefNum, " %e ", w_dc[i]
i += 1
if (mod(i, 8) == 0)
fprintf FileRefNum, "¥r¥n"
endif
while(i < 1024)
// 未知試料の書き出し
i = 0
do
fprintf FileRefNum, " %e ", w_sample[i]
i += 1
if (mod(i, 8) == 0)
fprintf FileRefNum, "¥r¥n"
endif
while(i < 1024)
Close FileRefNum
End
// 読み出したデータ(カンマ区切り文字列)を、waveに入れる
// dstr:文字列
// dwave:読み込み先のwave
Function ReadDataToWave(dstr, dwave)
String dstr
WAVE dwave
variable ss, es, i, len, dpos, n_dwave
len = strlen(dstr)
n_dwave = numpnts(dwave)
i = 0
ss=0
do
dpos = strsearch(dstr,",",ss)
if(dpos == -1) // last
dwave[i] = str2num(dstr[es, len-1])
i = i+1
break;
endif
es = dpos
dwave[i] = str2num(dstr[ss, es-1])
ss = es+1
es = es + 1
i = i + 1
while (i < n_dwave)
return i
End
