// =====================================================================
//  $Id: st02signalview.cc,v 1.6 2003/10/14 22:49:23 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: st02signalview.cc,v $
//  Revision 1.6  2003/10/14 22:49:23  goiwai
//  別々のアップデートサイクルを参照するようにしました.
//
//  Revision 1.5  2003/10/12 22:55:30  goiwai
//  オンラインストリームの採用
//
//  Revision 1.4  2003/10/06 16:28:19  goiwai
//  *** empty log message ***
//
//  Revision 1.3  2003/09/07 02:30:01  goiwai
//  完全に手違いで,これまで,Run終了時に生成されるオブジェクトにはキャンバ
//  スオブジェクトしか含まれていませんでした.
//  この更新でRun終了時にディスプレイされている様々なヒストグラムオブジェ
//  クトが書き込まれるようになりました.
//    f = new TFile("run001256.root");
//    H1Dsub -> Draw();
//  とかでオブジェクト表示します.
//
//  Revision 1.2  2003/07/30 16:16:35  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TDataRecord.hh"
#include "TDataSection.hh"
#include "TDataSegment.hh"
#include "TDataElement.hh"
#include "TInputObjectFileOnline.hh"
#include "TDataMultiplicity.hh"
#include "St02DataRecordConversion.hh"
#include "St02BadChannelMap.hh"
#include "St02OfflineDarkAverageMap.hh"
#include "St02OfflineDarkRmsMap.hh"
#include "Trootinit.h"

// T = 1.36375e-05*R*R + 0.234333*R - 248.124
static const Tstring _rcpath = "st02setup";

Tvoid localsetup( Tint srcid, 
                  Tstring& srcf, Tstring& drkf,
                  Tstring& htsub, Tstring& htorg, 
                  Tstring& htdrk, Tstring& hthoc, 
                  Tstring& httmp, Tstring& hthit, Tstring& htsig,
                  Tstring& rootf, Tstring& macrof,
                  Tstring& giff, Tstring& psf,
                  Tbool& hitaverage,
                  Tdouble& hitmin,
                  Tdouble& hitmax,
                  Tstring& drawopt,
                  Tint& ncluster,
                  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 srcid = strtol( argv[ 1 ], 0, 10 );
  Tstring srcf, drkf, rootf, macrof, giff, psf;
  Tstring htsub, htorg, htdrk, hthoc, httmp, hthit, htsig;
  Tbool hitaverage;
  Tdouble hitmin, hitmax;
  Tstring drawopt;
  Tint ncluster, modperiod;
  Tbool overwrite, autoprint;
  localsetup(srcid,
             srcf,drkf,
             htsub,htorg,htdrk,hthoc,httmp,hthit,htsig,
             rootf,macrof,giff,psf,
             hitaverage, hitmin, hitmax, drawopt, ncluster, modperiod,
             overwrite,autoprint);




  //ROOT関係準備
  TApplication* theApplication = rootinit();
  TCanvas CVsignalview( "CVsignalview", "Signal Viewer", 1080, 810 );
  CVsignalview.ToggleEventStatus();
  CVsignalview.Divide( 3, 3 );

  TH1D H1Dsub( "H1Dsub", htsub.c_str(), 300, -1000.0, 2000.0 );
  TH1D H1Dsig1( "H1Dsig1", htsig.c_str(), 300, -1000.0, 2000.0 );
  TH1D H1Dsig2( "H1Dsig2", htsig.c_str(), (Tint)((hitmax-hitmin)/10), hitmin, hitmax );
  TH1D H1Dorg( "H1Dorg", htorg.c_str(), 400, 0.0, 4096.0 );
  TH1D H1Ddrk( "H1Ddrk", htdrk.c_str(), 100, -200.0, 400.0 );
  //TH1D H1Dsig( "H1Dsig", htsig.c_str(), 300, -1000.0, 2000.0 );
  TH1D H1Dhoc( "H1Dhoc", hthoc.c_str(), 256, 0.0, 256.0 );
  TH1D H1Dtmp( "H1Dtmp", httmp.c_str(), 10, 0.0, 10.0 );
  TH2D H2Dhit( "H2Dhit", hthit.c_str(), 256/ncluster, 0.0, 256.0, 256/ncluster, 0.0, 256.0 );
  TPaveText PTdinfo( 0.1, 0.1, 0.9, 0.9 );
  PTdinfo.SetName("PTdinfo");


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

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

  H1Dsig1.GetXaxis()->SetTitle("Pulseheight (ADU)");
  H1Dsig1.GetXaxis()->SetNoExponent();
  H1Dsig1.GetXaxis()->CenterTitle();
  H1Dsig1.GetYaxis()->SetTitle("Counts");
  H1Dsig1.GetYaxis()->CenterTitle();

  H1Dsig2.GetXaxis()->SetTitle("Pulseheight (ADU)");
  H1Dsig2.GetXaxis()->SetNoExponent();
  H1Dsig2.GetXaxis()->CenterTitle();
  H1Dsig2.GetYaxis()->SetTitle("Counts");
  H1Dsig2.GetYaxis()->CenterTitle();

  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 );

  H1Ddrk.GetXaxis()->SetTitle("Pulseheight (ADU)");
  H1Ddrk.GetXaxis()->CenterTitle();
  H1Ddrk.GetXaxis()->SetNoExponent();
  H1Ddrk.GetYaxis()->SetTitle("Counts");
  H1Ddrk.GetYaxis()->CenterTitle();

  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);


  H2Dhit.SetStats(0);
  H2Dhit.GetXaxis() -> SetTitle( "Horizontal Pixel Number in Sensitive Region" );
  H2Dhit.GetXaxis() -> SetNoExponent();
  H2Dhit.GetXaxis() -> CenterTitle();
  H2Dhit.GetYaxis() -> SetTitle( "Vertical Pixel Number in Sensitive Region" );
  H2Dhit.GetYaxis() -> SetNoExponent();
  H2Dhit.GetYaxis() -> CenterTitle();
  H2Dhit.GetZaxis()->SetTitle("Pulseheight (ADU)");
  H2Dhit.GetZaxis()->CenterTitle();
  H2Dhit.GetZaxis() -> SetNoExponent();

  PTdinfo.SetFillColor( 10 );
  PTdinfo.SetFillStyle( 0 );
  PTdinfo.SetBorderSize( 0 );
  PTdinfo.SetTextAlign( 12 );




  St02BadChannelMap badmap( drkf );
  TDataMultiplicity ave = 
    badmap.GetOfflineDarkRmsMap().GetOfflineDarkAverageMap().GetMap();
  for ( Tint row = 0; row < ave.num_row(); row ++ ) {
    for ( Tint col = 0; col < ave.num_col(); col ++ ) {
      //if ( badmap.IsGoodChannel( row, col ) ) {
        H1Ddrk.Fill( ave[ row ][ col ] );
        //}
    }
  }
  CVsignalview.cd( 1 );
  H1Ddrk.Draw();


  //ORIGINAL
  CVsignalview.cd( 2 );
  gPad -> SetLogy();
  H1Dorg.Draw();


  //TEMP
  CVsignalview.cd( 3 );
  H1Dtmp.Draw( "pe" );


  //H.O.C.
  CVsignalview.cd( 4 );
  H1Dhoc.Draw();


  //ORIGINAL-H.O.C.
  CVsignalview.cd( 5 );
  H1Dsub.Draw();
  gPad -> SetLogy();


  //hitmap
  CVsignalview.cd( 6 );
  gPad->SetLeftMargin( 0.218 );
  gPad->SetRightMargin( 0.218 );
  gPad->SetTopMargin( 0.125 );
  gPad->SetBottomMargin( 0.125 );
  H2Dhit.Draw( drawopt.c_str() );



  //ORIGINAL-HOC-DARK
  CVsignalview.cd( 7 );
  H1Dsig1.Draw();
  gPad -> SetLogy();


  //ORIGINAL-HOC-DARK
  CVsignalview.cd( 8 );
  H1Dsig2.Draw();
  //gPad -> SetLogy();


  //INFO
  CVsignalview.cd( 9 );
  PTdinfo.Draw();





  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" };

  Tint nevent = 0;
  Tdouble totalT = 0.0;
  Tint ntemp = 0;
  Tdouble maxhoc = DBL_MIN;
  Tdouble minhoc = DBL_MAX;
  TInputObjectFileOnline ifile( srcf );
  while ( ifile.Read( record ) ) {

    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" ) {


      // ORIGINAL fill
      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 ] );
      }


      // temperature fill
      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;
      ntemp ++;

      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" );




      // make a map
      TDataMultiplicity& map = conversion.Convert( record );
      if ( ! conversion.IsSuccess() ) {
	continue;
      }


      // H.O.C. fill
      TdoubleList h = conversion.GetHOCaverage();
      H1Dhoc.Reset();
      for ( Tsize_t row = 0; row < h.size(); row ++ ) {
        H1Dhoc.Fill( row, h[ row ] );
        if ( maxhoc < h[ row ] ) {
          maxhoc = h[ row ];
        }
        if ( minhoc > h[ row ] ) {
          minhoc = h[ row ];
        }
      }





      // signal, hitmap fill
      // ORG - H.O.C が map
      // map から 直前のランの DARK をピクセル毎に引く
      TDataMultiplicity sig = map - ave;
      H2Dhit.Reset();
      for ( Tint row = 0; row < map.num_row(); row ++ ) {
        for ( Tint col = 0; col < map.num_col(); col ++ ) {
          H1Dsub.Fill( map[ row ][ col ] );
          H1Dsig1.Fill( sig[ row ][ col ] );
          H1Dsig2.Fill( sig[ row ][ col ] );
          H2Dhit.Fill( row, col, sig[ row ][ col ] );
        }
      }
      if ( hitaverage ) {
        Tdouble f = 1.0/(Tdouble)(ncluster);
        H2Dhit = H2Dhit * f;
      }
      H2Dhit.SetMinimum( hitmin );
      H2Dhit.SetMaximum( hitmax );


      //INFO, (SIGNAL PEAK,HOC MAX&MIN,TEMP AVERAGE)
      Tdouble peak = (Tdouble)(H1Dsig2.GetXaxis()->GetBinCenter(H1Dsig2.GetMaximumBin()));
      totalT += T;
      Tdouble tempave = totalT / ntemp;
      PTdinfo.Clear();
      Tstring sbuf;
      sbuf = "X-ray Peak (ADU): " + dtostr( peak );
      PTdinfo.AddText( sbuf.c_str() );
      sbuf = "Temperature ({}^{#circ}C): " + dtostr( tempave, 3 );
      PTdinfo.AddText( sbuf.c_str() );
      sbuf = "Max H.O.C. (ADU): " + dtostr( maxhoc, 4 );
      PTdinfo.AddText( sbuf.c_str() );
      sbuf = "Min H.O.C. (ADU): " + dtostr( minhoc, 4 );
      PTdinfo.AddText( sbuf.c_str() );



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


      //CVsignalview.Modified();
      //CVsignalview.Update();
    } else if ( recid == "RUN END" ) {

      const Tint npad = 9;
      for ( Tint i = 0; i < npad; i ++ ) {
        CVsignalview.GetPad(i+1)->Modified();
        CVsignalview.GetPad(i+1)->Update();
      }
      CVsignalview.cd();


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

        H1Dsub.Write();
        H1Dsig1.Write();
        H1Dsig2.Write();
        H1Dorg.Write();
        H1Ddrk.Write();
        H1Dhoc.Write();
        H1Dtmp.Write();
        H2Dhit.Write();
        PTdinfo.Write();
        CVsignalview.Write();

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

      break;

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

  theApplication -> Run();

  return 0;
}



Tvoid localsetup( Tint srcid,
                  Tstring& srcf,
                  Tstring& drkf,
                  Tstring& htsub, 
                  Tstring& htorg, 
                  Tstring& htdrk, 
                  Tstring& hthoc, 
                  Tstring& httmp, 
                  Tstring& hthit,
                  Tstring& htsig,
                  Tstring& rootf, Tstring& macrof,
                  Tstring& giff, Tstring& psf,
                  Tbool& hitaverage,
                  Tdouble& hitmin,
                  Tdouble& hitmax,
                  Tstring& drawopt,
                  Tint& ncluster,
                  Tint& modperiod,
                  Tbool& overwrite,
                  Tbool& autoprint )
{
  Tint drkid = srcid - 1;
  Tstring srcidstr = itostr( srcid );
  Tstring drkidstr = itostr( drkid );

  htsub = "Subtracted H.O.C., Run ID: " + srcidstr;
  htorg = "Original, Run ID: " + srcidstr;
  htdrk = "Dark Current, Run ID: " + drkidstr;
  hthoc = "H.O.C. by Line, Run ID: " + srcidstr;
  httmp = "Temperature, Run ID: " + srcidstr;
  hthit = "X-ray Distribution, Run ID: " + srcidstr;
  htsig = "Subtracted H.O.C. and D.C., Run ID: " + srcidstr;

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

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


  hitaverage = (Tbool)envtable.GetIntegerValue( "ST02_HITMAP_AVERAGE" );
  hitmin = envtable.GetDoubleValue( "ST02_HITMAP_MIN" );
  hitmax = envtable.GetDoubleValue( "ST02_HITMAP_MAX" );
  drawopt = envtable.GetEnvironmentValue( "ST02_HITMAP_DRAWOPTION" );
  ncluster = envtable.GetIntegerValue( "ST02_HITMAP_CLUSTERING" );
  modperiod = envtable.GetIntegerValue( "ST02_MODIFIED_PERIOD_SOURCE" );

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

  return;
}
