// ----------------------------------------------------------------------------
// $Id: root_GoJetsCal.C,v 1.8 2001/09/20 01:45:56 toshi Exp $
// ----------------------------------------------------------------------------
//
// Read root data, and Run Fast MC interactively with Root
// Sample program using JetFinder (using Clusters)
//           
//                            04/26/2001 Toshi
//
// :: How to run ::
// 
// 1) to call the root, type   
//    
//     root
//
// 2)
//     root [0]  .x root_GoJetsCal.C
// 
// .. that's it.
//
// For example, if you like to run 300 events, type like
//     root [0]  .x root_GoJetsCal.C(300)
//


#include <stdlib.h>

Int_t root_GoJetsCal(Int_t nEvent=100)
{

  gROOT->Reset();

  TString parfile_dir;
  parfile_dir += gSystem->Getenv("LCDROOT")   ;parfile_dir += "/";
  parfile_dir += "ParFiles/";

  // In order to refer to shareable libraries in this simple form,
  // include their paths in a .rootrc file.

  // Now Using dev version Event Classes
  gSystem->Load("libLCDEvent");
  gSystem->Load("libLCDRootAppsUtil");
  gSystem->Load("libLCDFastMC");
  gSystem->Load("libLCDPhUtil");

  LCDEvent event;

  // Input generator level root data 
  Char_t* rootFile = "test.root";
  LCDreadRootFile source(rootFile,&event);

  // Open detector parameter file
  Char_t* geomFile = 
    "SDMar01.par"; // SD
  //"LDMar01.par"; // LD
  TString s_geomFile(parfile_dir);
  s_geomFile += geomFile;
  FILE* m_geomfile =  fopen(s_geomFile.Data(),"r");
  LCDGetParameters gp(m_geomfile);
  fclose(m_geomfile);

  // If you want to change some detector parameter(s) for FastMC 
  // do here
  // For example..
  //gp.SetMagneticField(2.);  // Change Magnetif field

  // Tracking smearing parameter file
  Char_t* smearFile = 
    "lookup_silicon.nobmcon";
  //"lookup_large.nobmcon";
  TString s_smearFile(parfile_dir);
  s_smearFile += smearFile;

  // Initialize FastMC
  LCDFastMC fmc(&gp,s_smearFile.Data(),&event); 
  // If you don't want the Cluster merging
  //fmc.SetNoClusterMerge();

  // Define histograms
  TH1F *nJets   = new TH1F("nJets","# of Jets per Event (y=0.004)",20,0.,20);
  TH1F *nJets_1 = new TH1F("nJets_1","# of Jets per Event(y=0.006)",20,0.,20);
  TH1F *nJets_2 = new TH1F("nJets_2","# of Jets per Event(y=0.006, JADE)",20,0.,20);
  TH1F *JetP    = new TH1F("JetP","Jet momentum",100,0.,200);
  TH1F *JetPhi  = new TH1F("JetPhi","JetPhi Angle",100,0.,3.14);
  TH1F *JetCosTh= new TH1F("JetCosTh","Jet Cos Theta",50,-1.0,1.0);

  // Setup of JetFinder
  LCDJetFinder jetfind(0.004);  // Default.. DURHAM algorithm

  TClonesArray veclist("TLorentzVector",100);

  // Event loop
  Int_t iEvent;
  for (iEvent = 0; iEvent < nEvent; iEvent++) {
    if (!source.GetEvent()) break; // Read an event from the ROOT file.

    fmc.Doit();                    // Through FastMC
    
    if (iEvent == 0){
      // List Event Header information, for example
      LCDEventHeader* header = (LCDEventHeader*)event.EventHeader();
      printf("\n");
      printf("Process:: %s\n",header->GetProcessName());

      // List beam parameters 
      LCDBeam* beam = (LCDBeam*)event.BEAM();
      printf("Ecm = %f\n",beam->GetEcm());
      printf("electron polarization : %f  positron polarization : %f\n",
	     beam->GetPolElec(), beam->GetPolPosi());
      printf("==> effective polarization for electron : %f \n\n",
	     beam->GetEffectivePol());
    }

    // Look at tracks. Can access them by the [] operator.
    Int_t nClusters = event->ClusterLst()->GetEntries();
        
    // Event cut # cluster >= 2
    if (nClusters < 2) continue;

    veclist.Delete(); // Clean up veclist

    // Track loop    
    Int_t ncls=0;
    for (Int_t icls=0 ; icls < nClusters ; icls++) {
      LCDCluster* cls = (LCDCluster*)event->ClusterLst()->At(icls);

      Double_t     e     = cls->GetEnergy();

      if (e < 0.2 ) continue;  // Reject small Energy particles

      Double_t Phi   = cls->GetEnergyPhi();
      Double_t Theta = cls->GetEnergyTheta();
      Double_t ex    = e*TMath::Sin(Theta)*TMath::Cos(Phi);
      Double_t ey    = e*TMath::Sin(Theta)*TMath::Sin(Phi);
      Double_t ez    = e*TMath::Cos(Theta);
      
      TLorentzVector* p4=new(veclist[ncls++]) TLorentzVector();
      p4.SetXYZT(ex,ey,ez,e);

    }
    
//  Do Jet Finding
    jetfind.SetPartList(&veclist); // Input particle 4-vector list
    jetfind.SetDURHAM();          // Use DURHAM algorithm
    jetfind.SetYCut(0.004);       // Set YCut value
    jetfind.doFindJets();         // JetFindig
    
    Int_t numjets = jetfind.njets();
    nJets->Fill(numjets);

    for(Int_t j = 0; j < numjets; j++){

	TLorentzVector* Jet_vec = jetfind.jet4vec(j);
	TVector3        Pjet    = Jet_vec ->Vect();   // Jet 3 vector

	Double_t  Jet_mom = Pjet->Mag();
	Double_t  Jet_cos = (Pjet->Z())/Jet_mom;
	Double_t  Jet_phi = Pjet->Phi();

	JetP    ->Fill(Jet_mom);
	JetPhi  ->Fill(Jet_phi);
	JetCosTh->Fill(Jet_cos);
    }
    

//  Example 1  ... Do JetFindong with different Y-cut
    jetfind.SetYCut(0.0060);  // Set different YCut value
    jetfind.doFindJets();     // JetFinding

    Int_t numjets_1 = jetfind.njets();
    nJets_1->Fill(numjets_1);


//  Example 2  ... Do JetFindong with different Algorithm
    jetfind.SetJADE();      // Use JADE algorithm
    jetfind.doFindJets();    // JetFinding

    Int_t numjets_2 = jetfind.njets();
    nJets_2->Fill(numjets_2);

  }
  veclist.Delete();

  nJets   ->SetFillColor(4);
  nJets_1 ->SetFillColor(4);
  nJets_2 ->SetFillColor(4);
  JetP    ->SetFillColor(4);
  JetPhi  ->SetFillColor(4);
  JetCosTh->SetFillColor(4);

  TCanvas *c1 = new TCanvas("c1", "c1", 600,600);
  c1->Divide(2,3);
  c1->cd(1); nJets->Draw("B");
  c1->cd(2); nJets_1->Draw("B");
  c1->cd(3); nJets_2->Draw("B");
  c1->cd(4); JetP->Draw("B");
  c1->cd(5); JetPhi->Draw("B");
  c1->cd(6); JetCosTh->Draw("B");

  return iEvent;
}
