//////////////////////////////////////////////////////////////////////////////
// d050131 : GM  : TDC data histogramming, see offline/src/histTDCData.cc
//                 histos at data/sum/Sum<runnumber>TDC.root and .ps
//////////////////////////////////////////////////////////////////////////////


#ifndef HstTDCData_HH
#define HstTDCData_HH

#include <iostream>
#include <fstream>
#include <sstream>

#include "UtlPack.hh"

#include "RcdRecord.hh"
#include "SubAccessor.hh"

#include "BmlLc1176EventData.hh"

#include "TH1.h"
#include "TFile.h"
#include "TPostScript.h"
#include "TCanvas.h"
#include "TPad.h"

using namespace std; 

//output stored at <prefix><runNunber>TDC.root or .ps
const string prefix("data/sum/Sum");


class HstTDCData
{


   public:
   
   
   HstTDCData(const unsigned &runNumber) : theRun(runNumber)
   {
       

      for(int i(0);i<theN;i++)
      {  
         ostringstream soutLE, soutFE;
         soutLE << "TDC input " << i << " LeadingEdge";
         theLeadingEdge[i] = new TH1D(soutLE.str().c_str(),soutLE.str().c_str(),
	                              3000+1,0,3000);//65536+1,0,65536);// 16bits value, binsize = 1 nsec
         theLeadingEdge[i]->GetXaxis()->SetTitle("TDC value (nsec)");
         //h->GetYaxis()->SetTitle("counts");
        
         soutFE << "TDC input " << i << " FallingEdge";
         theFallingEdge[i] = new TH1D(soutFE.str().c_str(),soutFE.str().c_str(),
	                              3000+1,0,3000);//65536+1,0,65536);// 16bits value, binsize = 1 nsec
         theFallingEdge[i]->GetXaxis()->SetTitle("TDC value (nsec)");
         //h->GetYaxis()->SetTitle("counts");    
      }
      
   }
//............................................................................
   ~HstTDCData()
   {      
      
   }
//............................................................................
   void Help()
   {
   
      cout<<"//> U S E F U L >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
      cout<<"//                                                                      "<<endl;
      cout<<"//  TDC Data Format: (total = word of 32 bits)                          "<<endl; 
      cout<<"//                   bit [0]-[15] : 16 bits = time value in nsec        "<<endl;
      cout<<"//                   bit [16]     :  1 bit  = 1 for leading edge        "<<endl;
      cout<<"//				            0 for falling edge               "<<endl;    
      cout<<"//                   bit [17]-[20]:  4 bits = TDC channel (0-15)        "<<endl;
      cout<<"//                   bit [21]-[31]: do not care for the moment          "<<endl;
      cout<<"//                                                                      "<<endl;
      cout<<"//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"<<endl;

   }
//............................................................................
   void event(const RcdRecord &arena)
   {
      //do the work only for event records
      if(arena.recordType()!=RcdHeader::event) return;

      
      SubAccessor accessor(arena);
      std::vector<const BmlLc1176EventData*> v(accessor.extract< BmlLc1176EventData >());

      assert(v.size()==1); // Check for now: only 1 
      
      //for(unsigned i(0);i<v.size();i++) {
      //v[i]->print(std::cout) << std::endl;
      //}

      
      const UtlPack *p((const UtlPack*)v[0]->data());
      for(unsigned i(0);i<v[0]->numberOfWords();i++) 
      {
         unsigned chn((p[i].word()>>17)&0xf);   // Channel
         unsigned time(p[i].halfWord(0));       // TDC time
         //cout << " channel " << chn << " time " << time << endl;
         
	 if(p[i].bit(16))
	 {  
	    theLeadingEdge[chn]->Fill(time);//  leading edge
	 }
	 else
	 {  theFallingEdge[chn]->Fill(time);}//falling edge
	 
      }
   }  
//............................................................................      
   void Close()
   {      
      this->DumpFileRoot();
      this->DumpFilePS();
      this->Help();
   }
//............................................................................
 
  
   protected:
   
  
   void DumpFilePS() 
   {
      ostringstream output;
      output << prefix << theRun << "TDC.ps" ;
      
      TCanvas *c1 = new TCanvas("c1","",590,840);
      TPad *tPad0 = new TPad("p0","",0.00,0.51,  1.00,1.00,10);
      TPad *tPad1 = new TPad("p1","",0.00,0.00,  1.00,0.49,10);
    
      tPad0->Draw();
      tPad1->Draw();
    
      ostringstream startit, endit;
      startit << output.str() << "[";
      endit << output.str() << "]";
    
      c1->Print(startit.str().c_str());
    
      for(int i(0);i<theN;i++)
      {  
         tPad0->cd();
         theLeadingEdge[i]->Draw();

	 tPad1->cd();
         theFallingEdge[i]->Draw();
	 
	 c1->Update();
	 c1->Print(output.str().c_str());
      }
        
      c1->Print(endit.str().c_str());

   }
//............................................................................      
   void DumpFileRoot()
   {
   
      ostringstream output;
      output << prefix << theRun << "TDC.root";
      TFile *tRootFile = new TFile(output.str().c_str(),"RECREATE","file with histograms");
     
      for(int i(0);i<theN;i++)
      {
         theLeadingEdge[i]->Write();
         theFallingEdge[i]->Write();
      }

      tRootFile->Close();
      
      cout << "root file "<< output.str().c_str() << " has been created" << endl;
   }
//............................................................................  
   

   private:
   

   const static int theN = 16;// TDC inputs
   int theRun;   
   TH1D *theLeadingEdge[theN];
   TH1D *theFallingEdge[theN];
      
}; 

#endif
