// =====================================================================
//  $Id: rs01OFFped.cc,v 1.5 2003/10/16 07:56:43 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: rs01OFFped.cc,v $
//  Revision 1.5  2003/10/16 07:56:43  goiwai
//  若干の修正をしました
//
//  Revision 1.4  2003/10/12 22:52:22  goiwai
//  秋のビームテストにむけての若干の修正.
//  パラメーターやROOTオブジェクトの出力.
//  WEB閲覧用に毎イベントGIFの出力.
//  オンラインストリームの採用.
//
//  Revision 1.3  2003/10/06 16:28:15  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/09/17 09:58:53  goiwai
//  ペデスタル用のファイルを生成します.
//  使われた測定点のプロットも行ないます.
//  でき上がったデータファイルは rs01OFFvsecview, rs01OFFvsecview16,
//  rs01OFFvsecview3x3 の実行時に使って下さい.
//  引数は 3つ必要で,
//  % rs01OFFped 123 10 100
//  Run123(run000123.drec)のEvent ID:10からEvent ID: 109までの100イベント
//  を評価して,平均を1行32列のデータファイル run000123ped.dat にダンプしま
//  す.
//
// =====================================================================
#include "TDataRecord.hh"
#include "TDataSection.hh"
#include "TDataSegment.hh"
#include "TDataElement.hh"
#include "TEnvironmentVariableTable.hh"
#include "TInputObjectFile.hh"
#include "Trootinit.h"
#include "TArgument.hh"

static const Tstring rcpath = "rs01setup";
static const Tint npin = 32;
static Tint pinpos[ npin ] = {
           3,  4, 5,   6,  7,
      10, 11, 12, 13, 14, 15, 16,
  17, 18, 19, 20, 21, 22, 23, 24,
      26, 27, 28, 29, 30, 31, 32,
          35, 36, 37, 38, 39
};

TInputObjectFile* ifile = 0;
TEnvironmentVariableTable* envtable = 0;
TDataRecord record;
TDataElement element;
Tdouble vdc[ npin ];
Tdouble ped[ npin ];
Tint elapsed[ npin ];
//
TApplication* theApplication = 0;
TCanvas* CVvdc = 0;
static const Tint nx = 8;
static const Tint ny = 5;
static const Tint npadvdc = nx * ny;
TH1D** H1Dvdc;

Tstring htvdc[ npin ];
Tstring hnamevdc[ npin ];
Tstring fpath, macrof, giff, psf, rootf, datf;
static Tint modperiod, beginid, nevent;
static Tint totalevent = 0;

static Tvoid initialize( Tint argc, Tchar** argv );
static Tvoid event();
static Tvoid runbegin();
static Tvoid runend();

int main( int argc, char** argv, char** envv )
{
  initialize( argc, argv );

  while ( ifile -> Read( record ) ) {
    Tstring recid = record.GetID();
    if ( recid == "RUN BEGIN" ) {
      runbegin();
      continue;
    } else if ( recid == "EVENT" ) {
      event();
    } else if ( recid == "RUN END" ) {
      runend();
      break;
    } else {
      Tcerr << "unknown tag: " << recid << Tendl;
      break;
    }
    gSystem -> ProcessEvents();
  }

  theApplication -> Terminate();
  return 0;
}

Tvoid initialize( Tint argc, Tchar** argv )
{
  if ( argc != 4 ) {
    Tcerr << "usage: " << argv[ 0 ] << " <run#> <begin> <nevent>" << Tendl;
    Tcout << "ex) " << argv[ 0 ] << " 123 10 100" << Tendl;
    Tcout << "Run123のEvent10からEvent109までの100イベントを評価" << Tendl;
    exit( -1 );
  }

  Tint runid = (Tint)strtol( argv[ 1 ], 0, 0 );
  Tstring runidstr = itostr( runid );

  beginid = (Tint)strtol( argv[ 2 ], 0, 0 );
  nevent = (Tint)strtol( argv[ 3 ], 0, 0 );


  envtable = new TEnvironmentVariableTable ( rcpath );
  Tstring rechead = envtable -> GetEnvironmentValue( "RS01_RECORD_HEAD" );
  Tstring recpath = envtable -> GetEnvironmentValue( "RS01_RECORD_DIR" );
  fpath = recpath + Tslash + rechead + runidstr + ".drec";
  ifile = new TInputObjectFile( fpath );

  rootf = rechead + runidstr + "ped.root";
  macrof = rechead + runidstr + "ped.C";
  giff = rechead + runidstr + "ped.gif";
  psf = rechead + runidstr + "ped.ps";
  datf = rechead + runidstr + "ped.dat";

  modperiod = envtable -> GetIntegerValue( "RS01_UPDATE_PERIOD" );



  theApplication = rootinit();
  TGaxis::SetMaxDigits( 2 );


  // 電圧 VS 時間 キャンバス
  CVvdc = new TCanvas( "CVvdc", "VDC VS Time", 960, 720 );
  CVvdc -> ToggleEventStatus();
  CVvdc -> Divide( nx, ny );


  // 電圧 VS 時間の初期設定
  H1Dvdc = new TH1D*[npin];
  for ( Tint ch = 0; ch < npin; ch ++ ) {
    htvdc[ ch ] = "Channel: " + itostr( ch, 2 ) + ", Run ID: " + runidstr;
    hnamevdc[ ch ] = "H1Dvdc" + itostr( ch, 2 );

    H1Dvdc[ ch ] = 
      new TH1D( hnamevdc[ ch ].c_str(), htvdc[ ch ].c_str(), 10, 0.0, 10.0 );

    H1Dvdc[ ch ] -> SetStats( 0 );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTimeDisplay( 1 );
    H1Dvdc[ ch ] -> SetMarkerStyle( 1 );
    H1Dvdc[ ch ] -> SetLineColor( 10 );
    H1Dvdc[ ch ] -> SetLineStyle( 0 );
    H1Dvdc[ ch ] -> SetLineWidth( 0 );
    
    H1Dvdc[ ch ] -> GetXaxis() -> SetNdivisions( 504 );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTimeFormat( "%H:%M:%S" );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTitle( "Time (H:M:S)" );
    H1Dvdc[ ch ] -> GetXaxis() -> CenterTitle();

    H1Dvdc[ ch ] -> GetYaxis() -> SetTitle( "DC Voltage (V)" );
    H1Dvdc[ ch ] -> GetYaxis() -> SetNoExponent();
    H1Dvdc[ ch ] -> GetYaxis() -> CenterTitle();

    CVvdc -> cd( pinpos[ ch ] );
    H1Dvdc[ ch ] -> Draw( "pe" );

    ped[ch]=0.0;
  }

  return;
}

Tvoid event()
{
  element = record[ 0 ][ 0 ][ 0 ];
  Tint eventid;
  element.StorePrimitives( &eventid );

  if ( eventid < beginid || eventid >= beginid + nevent ) {
    return;
  }



  for ( Tint ch = 0; ch < npin; ch ++ ) {
    // VDCのスナップショット
    element = record[ 1 ][ ch ][ 0 ];
    element.StorePrimitives( &vdc[ ch ] );

    // ラン開始からの経過秒数(sec)
    element = record[ 1 ][ ch ][ 3 ];
    element.StorePrimitives( &elapsed[ ch ] );

    //電圧 VS 時間
    H1Dvdc[ ch ] -> SetBinContent( elapsed[ ch ], vdc[ ch ] );

    H1Dvdc[ ch ] -> GetXaxis() -> SetNdivisions( 504 );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTimeFormat( "%H:%M:%S" );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTitle( "Time (H:M:S)" );
    H1Dvdc[ ch ] -> GetXaxis() -> CenterTitle();
    H1Dvdc[ ch ] -> GetYaxis() -> SetTitle( "DC Voltage (V)" );
    H1Dvdc[ ch ] -> GetYaxis() -> SetNoExponent();
    H1Dvdc[ ch ] -> GetYaxis() -> CenterTitle();

    H1Dvdc[ ch ] -> SetDrawOption( "pe" );

    ped[ch]+=vdc[ch];
  }
  totalevent ++;



  // update
  if ( eventid % modperiod == 0 ) {
    for ( Tint i = 0; i < npadvdc; i ++ ) {
      CVvdc -> GetPad(i+1)->Modified();
      CVvdc -> GetPad(i+1)->Update();
    }
  }


  return;
}

Tvoid runbegin()
{
  element = record[ 0 ][ 1 ][ 1 ];
  Tint secbuf;
  element.StorePrimitives( &secbuf );
  gStyle -> SetTimeOffset( secbuf );
  return;
}

Tvoid runend()
{
  // update
  for ( Tint i = 0; i < npadvdc; i ++ ) {
    CVvdc -> GetPad(i+1)->Modified();
    CVvdc -> GetPad(i+1)->Update();
  }

  // printout
  CVvdc -> cd();

  TFile* file = new TFile( rootf.c_str(), "RECREATE", "VDC VIEW OFFLINE" );
  for ( Tint ch = 0; ch < npin; ch ++ ) {
    H1Dvdc[ ch ] -> Write();
  }
  CVvdc -> Write();
  file -> Close();


  CVvdc -> Print( giff.c_str() );
  CVvdc -> Print( psf.c_str() );



  Tcout << "INPUT BEGIN: " << beginid << Tendl;
  Tcout << "INPUT NEVENT: " << nevent << Tendl;
  Tcout << "TOTAL USED EVENT: " << totalevent << Tendl;
  Tofstream ofs(datf.c_str());
  for ( Tint ch = 0; ch < npin; ch ++ ) {
    Tdouble p = ped[ ch ] / (Tdouble)totalevent;

    Tcout << "RS01_PEDESTAL_" << itostr(ch,2) << " " << p << Tendl;

    ofs << p;
    if ( ch == npin - 1 ) {
      ofs << Tendl;
    } else {
      ofs << Ttab;
    }
  }
  ofs.close();

  return;
}
