パーソナルツール
現在位置: 研究関連 / 誘電緩和 / TDRのデータをMac OS Xで取り込む方法

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