// =====================================================================
//  $Id: st02OFFdarkview.cc,v 1.2 2003/10/06 16:28:19 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: st02OFFdarkview.cc,v $
//  Revision 1.2  2003/10/06 16:28:19  goiwai
//  *** empty log message ***
//
//  Revision 1.1  2003/09/10 01:17:24  goiwai
//  st02darkview(オンライン用)のオフライン版です.
//  違いは「勝手に印刷しないこと」と「ファイルをカレントディレクトリに生成
//  すること」です.
//
//
// =====================================================================
#include "TDataRecord.hh"
#include "TDataSection.hh"
#include "TDataSegment.hh"
#include "TDataElement.hh"
#include "TInputObjectFile.hh"
#include "St02DataRecordConversion.hh"
#include "Trootinit.h"

// T = 1.36375e-05*R*R + 0.234333*R - 248.124
static const Tstring _rcpath = "st02setup";
Tvoid localsetup( Tint runid, 
                  Tstring& drkf,
                  Tstring& htsub, Tstring& htorg, 
                  Tstring& hthoc, Tstring& httmp, 
                  Tstring& rootf, Tstring& macrof,
                  Tstring& giff, Tstring& psf,
                  Tint& modperiod,
                  Tbool& overwrite,
                  Tbool& autoprint );

int main( int argc, char** argv, char** envv )
{
  if ( argc != 2 ) {
    Tcerr << "usage: " << argv[ 0 ] << " <run#>" << Tendl;
    return -1;
  }

  Tint runid = strtol( argv[ 1 ], 0, 10 );
  Tstring drkf, htsub, htorg, hthoc, httmp, rootf, macrof, giff, psf;
  Tint modperiod;
  Tbool overwrite, autoprint;
  localsetup(runid,
             drkf,
             htsub,htorg,hthoc,httmp,
             rootf,macrof,giff,psf,
             modperiod,overwrite,autoprint);


  TApplication* theApplication = rootinit();
  TCanvas CVdarkview( "CVdarkview", "Dark Current Viewer", 1000, 750 );
  CVdarkview.ToggleEventStatus();
  CVdarkview.Divide( 2, 2 );
  TH1D H1Dorg( "H1Dorg", htorg.c_str(), 400, 0.0, 4096.0 );
  TH1D H1Dsub( "H1Dsub", htsub.c_str(), 500, -1000.0, 4000.0 );
  TH1D H1Dhoc( "H1Dhoc", hthoc.c_str(), 256, 0.0, 256.0 );
  TH1D H1Dtmp( "H1Dtmp", httmp.c_str(), 10, 0.0, 10.0 );


  TGaxis::SetMaxDigits( 2 );
  H1Dorg.GetXaxis()->SetTitle("Pulseheight (ADU)");
  H1Dorg.GetXaxis()->CenterTitle();
  H1Dorg.GetXaxis()->SetNoExponent();
  H1Dorg.GetYaxis()->SetTitle("Counts");
  H1Dorg.GetYaxis()->CenterTitle();
  CVdarkview.cd( 1 );
  H1Dorg.Draw();

  H1Dsub.GetXaxis()->SetTitle("Pulseheight (ADU)");
  H1Dsub.GetXaxis()->SetNoExponent();
  H1Dsub.GetXaxis()->CenterTitle();
  H1Dsub.GetYaxis()->SetTitle("Counts");
  H1Dsub.GetYaxis()->CenterTitle();
  CVdarkview.cd( 2 );
  H1Dsub.Draw();

  H1Dhoc.GetXaxis()->SetTitle("Vertical Pixel Number in Sensitive Region");
  H1Dhoc.GetXaxis()->CenterTitle();
  H1Dhoc.GetXaxis()->SetNoExponent();
  H1Dhoc.GetYaxis()->SetTitle("H.O.C. Average (ADU)");
  H1Dhoc.GetYaxis() -> SetTitleOffset( 1.4 );
  H1Dhoc.GetYaxis()->CenterTitle();
  H1Dhoc.GetYaxis()->SetNoExponent();
  H1Dhoc.SetMaximum( 4096.0 );
  H1Dhoc.SetMinimum( 0.0 );
  CVdarkview.cd( 3 );
  H1Dhoc.Draw();


  H1Dtmp.SetMaximum( 20.0 );
  H1Dtmp.SetMinimum( -120.0 );
  H1Dtmp.SetStats( 0 );
  H1Dtmp.GetXaxis() -> SetTimeDisplay( 1 );
  H1Dtmp.SetMarkerStyle( 1 );
  H1Dtmp.SetLineColor(10);
  H1Dtmp.SetLineStyle(0);
  H1Dtmp.SetLineWidth(0);
  CVdarkview.cd( 4 );
  H1Dtmp.Draw( "pe" );


  TDataRecord record;
  St02DataRecordConversion conversion;

  Tstring fadcidset[ 3 ] = { "EVENT", "ADC", "0" };
  Tstring startsec[ 3 ] = { "INFO", "CLOCK", "1" };
  Tstring elapsed[ 3 ] = { "INFO", "CLOCK", "2" };
  Tstring ohm[ 3 ] = { "EVENT", "KEITHLEY", "0" };

  TInputObjectFile ifile( drkf );
  Tint nevent = 0;
  while ( 1 ) {
    Tint datasize = ifile.Read( record );
    if ( datasize == 0 ) {
      ifile.SetOffset( ifile.GetTotalDataSize(), SEEK_SET );
      usleep( 1000*1000 );
      gSystem -> ProcessEvents();
      continue;
    }

    TDataElement element;
    Tstring recid = record.GetID();

    if ( recid == "RUN BEGIN" ) {
      record.FindDataElement( startsec, element );
      Tint secbuf;
      element.StorePrimitives( &secbuf );
      gStyle -> SetTimeOffset( secbuf );
      continue;
    } else if ( recid == "EVENT" ) {

      record.FindDataElement( fadcidset, element );
      Tshort* data = element.GetShortData(); //fast access
      Tint ndata = element.GetNumberOfPrimitives();
      for ( Tint i = 0; i < ndata; i ++ ) {
	H1Dorg.Fill( data[ i ] );
      }

      TDataMultiplicity& map = conversion.Convert( record );
      if ( conversion.IsSuccess() ) {
	for ( Tint row = 0; row < map.num_row(); row ++ ) {
	  for ( Tint col = 0; col < map.num_col(); col ++ ) {
	    H1Dsub.Fill( map[ row ][ col ] );
	  }
	}
        TdoubleList h = conversion.GetHOCaverage();
        H1Dhoc.Reset();
	for ( Tsize_t row = 0; row < h.size(); row ++ ) {
          H1Dhoc.Fill( row, h[ row ] );
        }
      }



      record.FindDataElement( elapsed, element );
      Tint secbuf;
      element.StorePrimitives( &secbuf );

      record.FindDataElement( ohm, element );
      Tdouble R;
      element.StorePrimitives( &R );
      //T = 1.36375e-05*R*R + 0.234333*R -248.124
      Tdouble T = 1.36375e-05*R*R + 0.234333*R -248.124;


      H1Dtmp.SetBinContent( secbuf, T );
      H1Dtmp.GetXaxis() -> SetNdivisions( 504 );
      //H1Dtmp.GetXaxis() -> SetLabelOffset( 0.02 );
      //H1Dtmp.GetXaxis() -> SetTitleOffset( 1.2 );
      H1Dtmp.GetXaxis() -> SetTimeFormat( "%H:%M:%S" );
      H1Dtmp.GetXaxis() -> SetTitle( "Time (H:M:S)" );
      H1Dtmp.GetXaxis() -> CenterTitle();
      H1Dtmp.GetYaxis() -> SetTitleOffset( 1.2 );
      H1Dtmp.GetYaxis() -> SetTitle( "Temperature ({}^{#circ}C)" );
      H1Dtmp.GetYaxis() -> SetNoExponent();
      H1Dtmp.GetYaxis() -> CenterTitle();
      H1Dtmp.SetDrawOption( "pe" );


      if ( nevent % modperiod == 0 ) {
        const Tint npad = 4;
        for ( Tint i = 0; i < npad; i ++ ) {
          CVdarkview.GetPad(i+1)->Modified();
          CVdarkview.GetPad(i+1)->Update();
        }
      }
      nevent ++;


    } else if ( recid == "RUN END" ) {

      const Tint npad = 4;
      for ( Tint i = 0; i < npad; i ++ ) {
        CVdarkview.GetPad(i+1)->Modified();
        CVdarkview.GetPad(i+1)->Update();
      }
      nevent ++;

      CVdarkview.cd();
      if ( !isexist( rootf ) || overwrite ) {
        Tstring ftitle = "Run ID: " + itostr( runid );
        TFile f( rootf.c_str(), "RECREATE", ftitle.c_str() );

        H1Dorg.Write();
        H1Dsub.Write();
        H1Dhoc.Write();
        H1Dtmp.Write();
        CVdarkview.Write();

        f.Close();
      }
      if ( !isexist( macrof ) || overwrite ) {
        CVdarkview.Print( macrof.c_str() );
      }
      if ( !isexist( giff ) || overwrite ) {
        CVdarkview.Print( giff.c_str() );
      }
      if ( !isexist( psf ) || overwrite ) {
        CVdarkview.Print( psf.c_str() );
        if ( autoprint ) {
          //Tstring exec = "lpr " + psf;
          //system( exec.c_str() );
        }
      }

      break;

    } else {
      Tcerr << "unknown tag: " << recid << Tendl;
    }
    gSystem -> ProcessEvents();
  }


  theApplication -> Terminate();

  return 0;
}



Tvoid localsetup( Tint runid, 
                  Tstring& drkf,
                  Tstring& htsub, Tstring& htorg, 
                  Tstring& hthoc, Tstring& httmp, 
                  Tstring& rootf, Tstring& macrof,
                  Tstring& giff, Tstring& psf,
                  Tint& modperiod,
                  Tbool& overwrite,
                  Tbool& autoprint )
{
  Tstring drkidstr = itostr( runid );

  htorg = "Original, Run ID: " + drkidstr;
  htsub = "Subtracted H.O.C., Run ID: " + drkidstr;
  hthoc = "H.O.C. by Line, Run ID: " + drkidstr;
  httmp = "Temperature, Run ID: " + drkidstr;

  TEnvironmentVariableTable envtable( _rcpath );
  Tstring rechead = envtable.GetEnvironmentValue( "ST02_RECORD_HEAD" );
  Tstring recpath = envtable.GetEnvironmentValue( "ST02_RECORD_DIR" );
  drkf = recpath + Tslash + rechead + drkidstr + ".drec";


  //Tstring rootdir = envtable.GetEnvironmentValue( "ST02_ROOTFILE_DIR" );
  rootf = rechead + drkidstr + ".root";
  //Tstring macrodir = envtable.GetEnvironmentValue( "ST02_ROOTFILE_DIR" );
  macrof = rechead + drkidstr + ".C";
  //Tstring gifdir = envtable.GetEnvironmentValue( "ST02_FIGURE_DIR" );
  giff = rechead + drkidstr + ".gif";
  //Tstring psdir = envtable.GetEnvironmentValue( "ST02_FIGURE_DIR" );
  psf = rechead + drkidstr + ".ps";

  modperiod = envtable.GetIntegerValue( "ST02_MODIFIED_PERIOD" );
  overwrite = (Tbool)envtable.GetIntegerValue( "ST02_OVERWRITE_ENABLE" );
  autoprint = (Tbool)envtable.GetIntegerValue( "ST02_AUTO_PRINT" );

  return;
}
