// =====================================================================
//  $Id: OFFmanualcutsp.cc,v 1.3 2003/10/06 16:28:17 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: OFFmanualcutsp.cc,v $
//  Revision 1.3  2003/10/06 16:28:17  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:15:51  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include <TROOT.h>
#include <TSystem.h>
#include <TApplication.h> 
#include <TStyle.h>
#include <TGraph.h>
#include <TH1.h>
#include <TH2.h>
#include <TCanvas.h>
#include <TNtuple.h>
#include <TFile.h>
#include <TPad.h>
#include <TFrame.h>
#include <TF1.h>
#include <TPaveText.h>
#include <TLegend.h>

#include "TEnvironmentVariableTable.hh"
#include "St00SinglePixelInterface.hh"
#include "St00CtiSolution.hh"

int main( int argc, char** argv, char** envv )
{
  enum { INPUT_DATARECORD, INPUT_ASCII_DATASET, INPUT_UNKNOWN = -1 };
  Tint inmode = INPUT_UNKNOWN;

  if ( argc != 2 && argc != 3 ) {
    Tcerr << "usage: " << argv[ 0 ] << Tspace << "<dataset>" << Tendl;
    Tcerr << "usage: " << argv[ 0 ] << Tspace << "<dark> <source>" << Tendl;
    return -1;
  } else if ( argc == 2 ) {
    inmode = INPUT_ASCII_DATASET;
  } else if ( argc == 3 ) {
    inmode = INPUT_DATARECORD;
  }


  TApplication* theApplication = new TApplication( "root-analyser", 0, 0 );
  gROOT -> Reset( 0 );
  gStyle -> SetStatColor( 42 );
  gStyle -> SetTitleColor( 42 );
  gStyle -> SetFrameFillColor( 21 );
  gStyle -> SetFrameFillStyle( 1 );
  gStyle -> SetMarkerStyle( 7 );
  gStyle -> SetFuncColor( 4 );
  gStyle -> SetOptStat( 1111110 );
  gStyle -> SetOptFit( 1111 );
  gStyle -> SetPadGridX( kTRUE );
  gStyle -> SetPadGridY( kTRUE );

  TCanvas CV2x3( "CV2x3", "Single Pixel View", 300*2, 200*3 );
  CV2x3.Divide( 2, 3 );
  TH1D signal( "signal", "Single", 50, 0.0, 500.0 );
  TH1D dark( "dark", "Dark", 50, -100.0, 500.0 );
  signal.SetFillColor( 45 );
  dark.SetFillColor( 43 );



  // make single pixel
  St00SinglePixelInterface* spif = 0;
  if ( inmode == INPUT_DATARECORD ) {
    spif = new St00SinglePixelInterface( argv[ 1 ], argv[ 2 ] );
  } else if ( inmode == INPUT_ASCII_DATASET ) {
    spif = new St00SinglePixelInterface( argv[ 1 ] );
  }
  St00SinglePixelList spl = spif -> GetSinglePixelList();
  delete spif;

  Tofstream ofs;
  ofs.open( "beforecut.dat" );
  for ( Tsize_t i = 0; i < spl.size(); i ++ ) {
    signal.Fill( spl[ i ].GetSignal() );
    dark.Fill( spl[ i ].GetDark() );
    ofs << spl[ i ] << Tendl;
  }
  ofs.close();


  CV2x3.cd( 1 );
  signal.Draw();

  CV2x3.cd( 2 );
  dark.Draw();
  CV2x3.cd( 1 );

  Tcout << "********************************************" << Tendl;
  Tcout << "********************************************" << Tendl;
  Tcout << "********************************************" << Tendl;
  Tcout << "shakehand mode begin!" << Tendl;
  Tstring answer;
  Tdouble mean;
  Tdouble sigma;
  Tdouble xmin;
  Tdouble xmax;
  do {
    gSystem -> ProcessEvents();
    Tcout << "set Xmin --> ";
    Tcin >> xmin;
    Tcout << "set Xmax --> ";
    Tcin >> xmax;
    TF1 gaussignal( "gaussignal", "gaus", xmin, xmax );
    CV2x3.cd( 1 );
    signal.Fit( "gaussignal", "qr", "same" );
    CV2x3.Update();

    mean = gaussignal.GetParameter( "Mean" );
    sigma = gaussignal.GetParameter( "Sigma" );

    Tcout << Tendl << Tendl;
    Tcout << "** Mean: " << mean << Tendl;
    Tcout << "** Sigma: " << sigma << Tendl;
    Tcout << Tendl << Tendl;

    Tcout << "OK?[n/y] --> ";
    Tcin >> answer;
  } while ( answer != "y" );
  Tcout << "********************************************" << Tendl;
  Tcout << "********************************************" << Tendl;
  Tcout << "********************************************" << Tendl;


  TEnvironmentVariableTable envtable( "setenvrc" );
  Tdouble factor = envtable.GetDoubleValue( "ST00_MANUALCUT_SIGMA" );
  const Tdouble cutlow = mean - ( factor * sigma );
  const Tdouble cutupp = mean + ( factor * sigma );

  // cut
  St00SinglePixelList newsplist;
  for ( Tsize_t i = 0; i < spl.size(); i ++ ) {
    Tdouble signal = spl[ i ].GetSignal();
    if ( signal > cutlow && signal < cutupp ) {
      newsplist.push_back( spl[ i ] );
    }
  }
  St00CtiSolution analyser( newsplist );



  TH1D cutoffsignal( "cutoffsignal", "Single Pixel Distribution", 50, 0.0, 500.0 );
  cutoffsignal.SetFillColor( 45 );
  ofs.open( "aftercut.dat" );
  for ( Tsize_t i = 0; i < newsplist.size(); i ++ ) {
    Tdouble signal = newsplist[ i ].GetSignal();
    cutoffsignal.Fill( signal );
    ofs << newsplist[ i ] << Tendl;
  }
  ofs.close();
  CV2x3.cd( 3 );
  cutoffsignal.Fit( "gaus", "q" );



  // Graph
  TGraph h50;
  h50.SetName( "h50" );
  TGraph v50;
  v50.SetName( "v50" );
  Tint hcnt = 0;
  Tint vcnt = 0;
  for ( Tsize_t i = 0; i < newsplist.size(); i ++ ) {
    Tint h = newsplist[ i ].GetHorizontalID() ;
    Tint v = newsplist[ i ].GetVerticalID();
    Tdouble signal = newsplist[ i ].GetSignal();
    if ( h < 50 ) {
      h50.SetPoint( hcnt, (Tdouble)v, log( signal ) );
      hcnt ++;
    }
    if ( v < 50 ) {
      v50.SetPoint( vcnt, (Tdouble)h, log( signal ) );
      vcnt ++;
    }
  }



  CV2x3.cd( 4 );
  gPad -> DrawFrame( 0.0, 0.0, 264.0, 10.0 ) -> SetTitle( "ADC(H<50) VS V" );
  h50.Draw( "p" );
  h50.Fit( "pol1", "q", "same" );

  CV2x3.cd( 5 );
  gPad -> DrawFrame( 0.0, 0.0, 276.0, 10.0 ) -> SetTitle( "ADC(V<50) VS H" );
  v50.Draw( "p" );
  v50.Fit( "pol1", "q", "same" );
  

  // summarise
  Tcout << "HCTI: " << analyser.GetHorizontalCTI() << Tendl;
  Tcout << "VCTI: " << analyser.GetVerticalCTI() << Tendl;
  Tcout << "Q0: " << analyser.GetInitialValue() << Tendl;
  Tcout << "E(HCTI): " << analyser.GetErrorOfHorizontalCTI() << Tendl;
  Tcout << "E(VCTI): " << analyser.GetErrorOfVerticalCTI() << Tendl;
  Tcout << "E(Q0): " << analyser.GetErrorOfInitialValue() << Tendl;
  Tcout << "====" << Tendl;

  TF1* vcti50 = h50.GetFunction( "pol1" );
  Tdouble q0h50 = exp( vcti50 -> GetParameter( 0 ) );
  Tdouble q0h50_e = q0h50 * ( vcti50 -> GetParError( 0 ) );
  Tdouble vcti = 1.0 - exp( vcti50 -> GetParameter( 1 ) );
  Tdouble vcti_e = exp( vcti50 -> GetParameter( 1 ) ) * ( vcti50 -> GetParError( 1 ) );

  TF1* hcti50 = v50.GetFunction( "pol1" );
  Tdouble q0v50 = exp( hcti50 -> GetParameter( 0 ) );
  Tdouble q0v50_e = q0v50 * ( hcti50 -> GetParError( 0 ) );
  Tdouble hcti = 1.0 - exp( hcti50 -> GetParameter( 1 ) );
  Tdouble hcti_e = exp( hcti50 -> GetParameter( 1 ) ) * ( hcti50 -> GetParError( 1 ) );

  Tcout << "Q0: " << q0v50 << "  " << q0v50_e << " | HCTI: " << hcti << "  " << hcti_e << Tendl;
  Tcout << "Q0: " << q0h50 << "  " << q0h50_e << " | VCTI: " << vcti << "  " << vcti_e << Tendl;

  //define dirname, filename
  //Tstring dir( ifname );
  //dir.erase( dir.begin(), dir.begin() + dir.find( "/" ) + 1 );
  //dir.erase( dir.begin() + dir.find( "/" ), dir.end() );
  //Tstring file( ifname );
  //file.erase( file.begin(), file.begin() + file.rfind( "/" ) + 1 );


  CV2x3.cd( 6 );
  TPaveText summary( 0.1, 0.1, 0.9, 0.9 );
  summary.SetFillColor( 44 );
  summary.SetTextAlign( 12 );
  summary.SetTextSize( 0.06 );

  Tstring line1 = "DIR: xxx";
  Tstring line2 = "FILE: xxx";
  Tstring line3 = "CTI_{H}: " + dtostr( analyser.GetHorizontalCTI() ) + " #pm " + dtostr( fabs( analyser.GetErrorOfHorizontalCTI() ) );
  Tstring line4 = "CTI_{V}: " + dtostr( analyser.GetVerticalCTI() ) + " #pm " + dtostr( fabs( analyser.GetErrorOfVerticalCTI() ) );
  Tstring line5 = "Q_{0}: " + dtostr( analyser.GetInitialValue() ) + " #pm " + dtostr( fabs( analyser.GetErrorOfInitialValue() ) );
  Tstring line6 = "CTI_{H}: " + dtostr( hcti ) + " #pm " + dtostr( hcti_e );
  Tstring line7 = "Q_{0}: " + dtostr( q0v50 ) + " #pm " + dtostr( q0v50_e );
  Tstring line8 = "CTI_{V}: " + dtostr( vcti ) + " #pm " + dtostr( vcti_e );
  Tstring line9 = "Q_{0}: " + dtostr( q0h50 ) + " #pm " + dtostr( q0h50_e );

  summary.AddText( line1.c_str() );
  summary.AddText( line2.c_str() );
  summary.AddText( "" );
  summary.AddText( line3.c_str() );
  summary.AddText( line4.c_str() );
  summary.AddText( line5.c_str() );
  summary.AddText( "" );
  summary.AddText( line6.c_str() );
  summary.AddText( line7.c_str() );
  summary.AddText( line8.c_str() );
  summary.AddText( line9.c_str() );
  summary.Draw();
  
  CV2x3.Update();
  CV2x3.cd( 0 );

  theApplication -> Run();

  return 0;
}
