class Labcom::Retriever

Authors

S.imazu

Version

22.0.0

Date

2020-07-31

[クラス名] Retriever

[メンバー]

[クラスメソッド]

[インスタンスメソッド]

[説 明]

  1. LABCOM計測データを取得する制御クラス

  2. 基本的にデストラクタが明示動作しないため、get内でopen,closeする。

  3. 例外的に、明示的にopen処理をした場合のみ、パフォーマンス重視し、get内でcloseしない。

[UPDATE履歴]

18.0.0 初版 19.0.0 部分取り出しの対応、時間軸データの取得メソッドをRetrieve.time_infoに変更。 19.1.0 共有ライブラリ(libretrieve.so)のdata_length64ビット拡張による変更。(retrieve.so) 22.0.0 rawモードを追加。

[前 提]

rubyは配列で引数に渡すと参照渡しとなる。 単純変数は値渡しとなる。

Constants

RANGE_EXP

取得範囲:実験時刻

RANGE_FRAMES

取得範囲:フレーム数

RANGE_NOSET

取得範囲なし

RANGE_SAMPLES

取得範囲:サンプル数

RANGE_TRIG

取得範囲:トリガ基準

Public Class Methods

new( timeout=0, server=nil, path=nil, port=0 ) click to toggle source
timeout (int)

データの出現を待つ時間(秒) default 0 : no wait

server (string)

データ取得ホスト(ホスト指定) default なし : INDEXのSHOTテーブルを参照する。

path (string)

データ取得時のパス(ホスト指定)default なし : INDEXのSHOTテーブルを参照する。

port (int)

データ転送サーバ(transd)のサービスポート番号 default 0 : INDEXのSHOTテーブル等を参照する。

[説  明]
コンストラクタ
# File labcom/Retriever.rb, line 110
def initialize( timeout=0, server=nil, path=nil, port=0 ) 
  @timeout = timeout
  @server = server
  @path = path
  @port = port
  @__desc = [0]   # デストラクタに変数オブジェクトを参照したいので配列とする。
  @__diag =''
  @__shot = 0
  @__sub_shot = 0
  @__n_channel = 0
  @__self_open = false
  @__range_type = RANGE_NOSET
  @__range_str = ''
  @__raw = false
  ObjectSpace.define_finalizer( self, Retriever.del_callback(@__desc) )
  
end
version() click to toggle source
引数

なし

返値

バージョン番号(String)

[説  明]
共有ライブラリのバージョン番号(String)を戻す
# File labcom/Retriever.rb, line 81
def self.version
  return Retrieve.version()
end

Public Instance Methods

close() click to toggle source
引数

なし

返値

なし

[説  明]
データ取得の終了宣言をする。(retrieveディスクリプタを閉じる。)
openされていたらcloseする。
# File labcom/Retriever.rb, line 140
def close
  
  if 0 < @__desc[0] then
    Retrieve.close(@__desc[0])
    @__desc[0] = 0
  end
end
get( diag, shot, sub_shot, channels, range_type=RANGE_NOSET, range_str=nil) click to toggle source
[ diag (string) ]      取得したいデータの計測名
[ shot (int) ]                 取得したいデータのショット番号
[ sub_shot (int) ]     取得したいデータのサブショット番号
[ channels (int, String, Range, Array(int), Array(String)) ]   取得したいデータのチャネル番号(int)または信号名(String)  複数可
range_type (int)

取得範囲の種別(RANGE_NOSET, RANGE_EXP, RANGE_TRIG, RANGE_SAMPLES, RANGE_FRAMES)

range_str (string)

取得範囲 “1:2s” “1.5:2.5ms”

返値

ArcDataオブジェクトまたはArcDataオブジェクトの配列

例外

Retrieve::RetrieveError, etc

[説  明]
チャネル単位の計測データを取得する。
内部でopenし、closeする。
# File labcom/Retriever.rb, line 232
def get( diag, shot, sub_shot, channels, range_type=RANGE_NOSET, range_str=nil) 
  
  begin
    range_str = '' if nil == range_str
    @__self_open = false
    if( 1 > @__desc[0] or shot != @__shot or sub_shot != @__sub_shot          or diag != @__diag or range_type != @__range_type or range_str != @__range_str) then
      open(diag, shot, sub_shot, range_type, range_str)
      @__self_open = true
    end
    
    is_list = false
    if( channels.is_a?(Array) ) then
      is_list = true
      l_channel = channels
    elsif( channels.is_a?(Range) ) then
      is_list = true
      l_channel = channels
    elsif( channels.is_a?(Integer) ) then
      if( 0 == channels ) then
        is_list = true
        l_channel = Range.new(1,@__n_channel)
      else
        l_channel = [channels]
      end
    elsif( channels.is_a?(String) ) then
      l_channel = [channels]
    else
      close() if @__slef_open
      raise RuntimeError, 'Illegal type(format) of channel'
    end
    
    l_channel.each {|ch|
        if( ch.is_a?(Integer) ) then
          if( 0 > ch || ch > @__n_channel ) then
            close() if @__slef_open
            raise RuntimeError, 'Illegal channel number'
          end
        end
      } 
    ret_obj = Array.new() if( is_list )
    for x_channel in l_channel do
      obj = get_ch(x_channel)
      ret_obj.push(obj) if( is_list ) 
    end
  rescue Retrieve::RetrieveError => ex
    close()
    raise ex
  end

  close() if @__slef_open
  return ret_obj if( is_list ) 
  return obj
end
get_ch( channel) click to toggle source
channel ( int, String)

取得したいチャネル番号または信号名

返値

ArcDataオブジェクト

例外

Retrieve::RetrieveError, etc

[説  明]
openされたショットのチャネル単位の計測データを取得する。
# File labcom/Retriever.rb, line 299
  def get_ch( channel) 
    
    begin
      raise "Not Retriever::open" if( 1 > @__desc[0] ) 
      raise "Illegal type of channel " unless ( channel.is_a?(Integer) || channel.is_a?(String) )
      ch_no, byte_length, comp_length, param_count, data_type,            image_type, value_len, is_nframe, c_management, c_comment              = Retrieve.ch_info(@__desc[0], channel) 
      params = Retrieve.ch_params(@__desc[0], ch_no)
      if( is_nframe == 0 ) then
        data_length, image_type = Retrieve.to_data_len( byte_length, image_type, value_len)
        begin
          syn_num = Retrieve.ch_v_synthesized_num(@__desc[0], ch_no)
          if( 0 < syn_num and !@__raw ) then
            data_length = data_length/syn_num
            block = Retrieve.ch_volts_dbl(@__desc[0], ch_no, data_length)
            image_type = 'FLT64'
          else
             block = Retrieve.ch_data(@__desc[0], ch_no, byte_length)
          end
        rescue Retrieve::RetrieveError => ex
             block = Retrieve.ch_data(@__desc[0], ch_no, byte_length)
  #                            warnings.warn("Data type is not voltage.")
        end
        begin
          sampling_cycle, trigger_delay, start_timing, num_times = Retrieve.time_info(@__desc[0], ch_no )
        rescue => ex
           sampling_cycle = nil
           start_timing = nil
           num_times = nil
        end
        ad = ArcData.new( start_timing, sampling_cycle,nil, params, num_times)
  #                ary.set_samples(image_type, block, byte_length)
        ad.set_samples(image_type, block)
      else # is_nframe
        begin
          sampling_cycle, trigger_delay, start_timing, num_times = Retrieve.time_info(@__desc[0], ch_no )
        rescue => ex
           sampling_cycle = nil
           start_timing = nil
           num_times = nil
        end
        begin
          begin_no, end_no = Retrieve.retrieve_no(@__desc[0], ch_no )
        rescue => ex
          begin_no = 1
          end_no = is_nframe
        end
        
        length, image_type, frame_x, frame_y = Retrieve.frame_info( @__desc[0], ch_no, begin_no)
        bytes = Retrieve.bytes_per_data(image_type, value_len)
        byte_length = frame_x * frame_y * bytes
        ad = ArcData.new( start_timing, sampling_cycle, nil, params, num_times)
        ad.init_frames(image_type, frame_x, frame_y)
        for fno in Range.new(begin_no, end_no) do
          length, image_type, frame_x, frame_y = Retrieve.frame_info( @__desc[0], ch_no, fno)
          block = Retrieve.frame_data(@__desc[0], ch_no, fno, length)
#                    ary.add_frame(block, length)
          ad.add_frame(block)
        end
      end  # is_nframe
    rescue Retrieve::RetrieveError => ex
      raise ex
    end
  
    return ad
  end
get_frames( diag, shot, sub_shot, channel, frames) click to toggle source
[ diag (string) ]                              取得したい計測名
[ shot (int) ]                                         取得したいショット番号
[ sub_shot (int) ]                             取得したいサブショット番号
[ channel(int, String ) ]      取得したいチャネル番号、信号名
[ frames(int, Range, Array(int) ) ]    取得したいフレーム番号
[ 返値 ]                         ArcDataオブジェクトまたはArcDataオブジェクトの配列

        [説  明]
        フレーム番号を指定して計測データ(フレーム構造)を取得する。
        内部でopenし、closeする。

時間軸データは付加しない。(間欠の場合はできない。) 部分取り出しをしたい場合は、get_chメソッドを使用する。

# File labcom/Retriever.rb, line 385
def get_frames( diag, shot, sub_shot, channel, frames) 
  
  begin
    @__self_open = false
    if( 1 > @__desc[0] or shot != @__shot or sub_shot != @__sub_shot          or diag != @__diag or RANGE_NOSET != @__range_type ) then
      open(diag, shot, sub_shot)
      @__self_open = true
    end
    
    if( channel.is_a?(Integer) ) then
      if( 0 > channel || channel > @__n_channel ) then
        close() if @__slef_open
        raise RuntimeError, 'Illegal channel number'
      end
    elsif( !channel.is_a?(String) ) then
      close() if @__slef_open
      raise RuntimeError, 'Illegal type(format) of channel'
    end
    
    ch_no, byte_length, comp_length, param_count, data_type,            image_type, value_len, is_nframe, c_management, c_comment              = Retrieve.ch_info(@__desc[0], channel)
    if( is_nframe == 0 ) then
      close() if @__slef_open
      raise RuntimeError, 'Not frame format'
    end
      
    l_frame = nil
    if( frames.is_a?(Array) ) then
      l_frame = frames
    elsif( frames.is_a?(Range) ) then
      l_frame = frames
    elsif( frames.is_a?(Integer) ) then
      if( 0 == frames ) then
        l_frame = Range.new(1, is_nframe)
      else
        l_frame = [frames]
      end
    else
      close() if @__slef_open
      raise RuntimeError, 'Illegal type(format) of frame'
    end
    
    l_frame.each { |fno| 
      if( 0 > fno || fno > is_nframe ) then
        close() if @__slef_open
        raise RuntimeError, 'Illegal frame number'
      end
     }
      
    params = Retrieve.ch_params(@__desc[0], ch_no)
    
    length, image_type, frame_x, frame_y = Retrieve.frame_info( @__desc[0], ch_no, 1)
    obj = ArcData.new( nil, nil, nil, params)
    obj.init_frames(image_type, frame_x, frame_y)
    for fno in l_frame do
        length, image_type, frame_x, frame_y = Retrieve.frame_info( @__desc[0], ch_no, fno)
        block = Retrieve.frame_data(@__desc[0], ch_no, fno, length)
        obj.add_frame(block)
      end
  rescue Retrieve::RetrieveError => ex
    close()
    raise ex
  end

  close() if @__slef_open
  return obj
end
open( diag, shot, sub_shot, range_type=RANGE_NOSET, range_str=nil) click to toggle source
diag (string)

取得したいデータの計測名

shot (int)

取得したいデータのショット番号

sub_shot (int)

取得したいデータのサブショット番号

range_type (int)

取得範囲の種別(RANGE_NOSET, RANGE_EXP, RANGE_TRIG, RANGE_SAMPLES, RANGE_FRAMES)

range_str (string)

取得範囲 “1:2s” “1.5:2.5ms”

返値

なし

例外

Retrieve::RetrieveError

[説  明]
指定された計測名、ショット番号およびサブショット番号の取り出しを宣言する。
すでに、openされていたらcloseする。
# File labcom/Retriever.rb, line 181
def open( diag, shot, sub_shot, range_type=RANGE_NOSET, range_str=nil)
  begin
    close()
    if( nil != @server and nil == @path  ) then
      @path='ShotDataFS'
    end
    if( nil == @server ) then
      range_str = '' if nil == range_str
      @__desc[0] = Retrieve.open_range(diag, '', shot, sub_shot, @timeout, range_type, range_str)
    else
      @__desc[0] = Retrieve.open_direct(                  diag, @server, @path, shot, sub_shot, @port, @timeout)
    end
    @__diag = diag
    @__shot = shot
    @__sub_shot = sub_shot
    @__range_type = range_type
    @__range_str = range_str
    
    @__n_channel, s_year, s_month, s_day, s_hour , s_min , s_sec,          s_management, s_comment, s_server = Retrieve.shot_info(@__desc[0])
    
  rescue Retrieve::RetrieveError => ex
    close()
    p ex.to_s
    raise ex
  end

  return
    
end
set_raw_mode() click to toggle source
返値

なし

例外

なし

[説  明]
取得時のデータを(電圧)変換しない。
# File labcom/Retriever.rb, line 159
def set_raw_mode
  @__raw = true
end