今回も FlexPro のスクリプトの便利な使い方をご紹介したいと思います。
インポートした大きな生の波形データやそれにフィルタをかけた結果、あるいは解析をした結果をエクスポートした場合、大きすぎると Excel などではインポートできなくなってしまうことがあります。Excel も 2007 で取り扱える列数が従来のバージョンに比べると大幅に拡張されてはいますが、長時間に亘って計測、あるいは非常に高いサンプリング間隔で計測した場合は容易にその制限を超えてしまうことがあります。
一般的には Reduce 関数や Resample 関数を使用してデータを間引いてから解析をし、エクスポートしているケースが多いようです。Reduce 関数では ReductionFactor として指定した n 番目毎の値を抽出します。Resample 関数はサンプリングレートを変更します。Factor として 1 より小さい数を指定するとサンプリングレートが下がり、結果的にデータを間引くことができます。Resample 関数ではリサンプリングに使用する手法を線形補間と FFT のどちらか指定することができます。
ただ、どうしても間引かずに全点を解析、あるいはエクスポートしたい場合もあるかもしれません。ある周期時間ごとにデータを分割してそれぞれ個別に解析を行うにはどうしたらよいか、など実際にお客様からお問い合わせをいただくことがあります。この場合、たとえば二つや三つくらいに分けるだけならインデックス演算子を使用して非常にシンプルな、一行の公式を二つあるいは三つ作成するだけで実現できます。後のほうでご紹介する条件式を使用したものよりもこのインデックス演算子を使用するほうが圧倒的に計算負荷が低く、ゆえに計算速度も速くなるので可能であればこの方法を使用されることをお勧めします。
たとえば、5,000 点のデータを持つデータセット mySignal を二つに分割するのであれば、
mySignal[0, 2499] mySignal[2500, 4999]
という二つの公式を作成します。
簡単でしょ。注意しなければいけないことは、FlexPro はデータに対してインデックスを内部的に割り当てていますが、それが 0 から始まっているということです。上の式でも分割される一つ目のデータの開始点は 0 で指定し、二つ目の最後の点は 4999 で指定しています。
もう一つ、公式を使用する上で注意しなければならないのは、基本的には公式の最後で行われた処理の結果一つだけを FlexPro の公式は返すことです。中間結果を返させることは (デバッガでは観察することはできますが) できず、また二つ以上の結果を返させることもできません。この基本原則ゆえに上の例ではオリジナルデータの前半部分を返す公式と後半部分を返す公式と二つの公式を作る必要があるのです。
この基本原則のために、とてつもなく大きなデータで、二つや三つではなく十、二十に分割しなければならないなどという場合はかなり煩雑な作業になります。VBA を使って上のようなインデックス演算子を使用した公式を作らせることも可能ではありますが、VB のスクリプトを書くのが苦手なので ここではあえて FPScript を使用する方法をご紹介します。
そこで、Reshape 関数を使って、例えば 20,000 点からなるデータセットをそれぞれ 1,000 点ずつのデータ点からなる 20 のデータセットに分割してみます。
まず以下のような公式を作成します。20,000 点からなるデータセットの名前をたとえば mySignal とします。
Dim y = Reshape(mySignal.Y, {20, NumberOfRows(mySignal.Y)/ 20})
Dim x = Reshape(mySignal.X, {20, NumberOfRows(mySignal.X)/ 20})
Signal(y,x)
この公式の名前をたとえば mySigSeries とします。
次のような公式を作成します。
mySigSeries[0]
これで最初の 1,000 点を抽出したデータセットが出来上がりです。
この公式オブジェクトをコピーし、オブジェクトリストで 19 回ペーストします。ペーストした最初の公式の式を以下のように書き換えます。
mySigSeries[1]
以下同様にペーストした二つ目の公式の式を
mySigSeries[2]
といったように mySigSeries[19] まで合計 20 個の公式を編集します。
きれいに分割できる場合はこれで OK です。ただし、分割したい数でデータ点数が割り切れない場合の処理を考えると、そのための処理が必要になります。このために、条件式を含むスクリプトを作成します。前回 作成したのはたった一行のスクリプト、上でご紹介しているのは三行のスクリプトでしたが、今回は条件式を使用するためそこまで簡単ではありません。次のような公式を作成します。
Arguments sig, n, i
Dim sl, tmp, ep, noe
noe = NumberOfElements(sig)
tmp = (FloatingPoint64 noe) / n
sl = Integer32 tmp + Integer32 (tmp <> Integer32 tmp)
ep = i*sl - 1
If noe <= ep Then
ep = -1
End
sig[(i-1)*sl, ep]
オブジェクトリストで分割するオブジェクトを上で作成した公式オブジェクト上にドラッグアンドドロップします。
「以後の引数を置換」ボックスが現れるので、分割する個数を入力します。5 つに分割するのであれば 5 を入力して OK ボタンをクリックします。
もう一度ボックスが現れるので、分割した何番目のデータを作成するか指定します。データの先頭から使用するのであれば 1 を入力し OK をクリックします。
オブジェクトリストに「データセット名」+「公式」の組み合わせの名前が付いた新しい公式オブジェクトが作成されているはずです。
ダブルクリックして開くと、以下のような公式が書かれているはずです。
'公式'('データセット名', 5, 1)
「データセット名」という名前のデータセットを 5 つに分割した 1 つ目のデータセットを作成するという意味です。
5 つに分割していますので、ここではあと四つ同様の公式が必要になります。
「データセット名」+「公式」の組み合わせの名前が付いた公式オブジェクトをコピーし、オブジェクトリストに四つペーストします。
ペーストした最初の公式の内容を、
'公式'('データセット名', 5, 2)
ペーストした二番目、「データセット名」+「公式」の組み合わせの名前がついた公式のシリーズとしては三つ目の公式の内容を、
'公式'('データセット名', 5, 3)
と変更します。同様に四つ目、五つ目も変更します。
これで分割されます。
Excel のマクロをいじるなど、多少でも VB のスクリプトを書いたことがある方であれば FlexPro のスクリプトが VB に似ていて、かつ比較にならないほど簡潔であることに驚かれるかもしれません。これは FlexPro のスクリプトがもともと時系列のデータを扱うことを念頭において設計されているためです。
Arguments は引数を宣言するステートメント、Dim はローカル変数を宣言するステートメントです。こういったステートメントや関数も VB を触ったことがある方であればなじみやすいと思います。
私も含め、スクリプトというと難しそうとか覚えるのが大変とか敷居が高く感じる方も少なくないと思います。また、デジタルフィルタや FFT など一般的でよく使用する機能は GUI で使用できるのでそこまで使い込む必要は無いと思われる方も少なからずいらっしゃるでしょう。
それでも、前回および今回ご紹介したようにちょっとスクリプトを使用するだけで GUI だけでは難しいことも比較的簡単に実現できるようになります。
是非お試しを。
ちなみに、データをマージするのは非常に簡単です。連結演算子 : を使用するたった一行のスクリプトでマージすることができます。
たとえば SignalA、SignalB、SignalC の三つのデータをその順番で連結することは以下のような非常にシンプルなスクリプトで実現できます。
SignalA : SignalB : SignalC
びっくりするぐらい簡単でしょ。


