//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//*
//             LOW ENERGY MUON SPIN RELAXATION, ROTATION, RADIATION   Geant4 SIMULATION
//  ID    : LEMuSRScintSD.cc , v 1.0
//  AUTHOR: Taofiq PARAISO
//  DATE  : 2004-07-12 16:15
//                   
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//
//
//  &           &&&&&&&&&&                            &&&&&&&         &&&&&&&&
//  &           &                                   &&      &&       &       &&
//  &           &                   &      &       &                &       &&
//  &           &&&&&&&            &      &         &&&&&&         &&&&&&&&  
//  &           &                 &      &&                &      &      &&
//  &           &                &&     &  &     &&      &&      &        &
//  &&&&&&&&&&  &&&&&&&&&&      &  &&&&&    &&    &&&&&&&       &        &&   
//                             &
//                            &
//                           &
//                         &  
//                           INNER SCINT SD
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$//


#include "LEMuSRScintSD.hh"
#include "G4HCofThisEvent.hh"
#include "G4TouchableHistory.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ios.hh"
#include "G4VProcess.hh"

// ROOT
#include "TROOT.h"
#include "TApplication.h"
#include "TSystem.h"
#include "TH1.h"
#include "TPad.h"
#include "TCanvas.h"


LEMuSRScintSD::LEMuSRScintSD(G4String name)
:G4VSensitiveDetector(name)
{

  G4String HCname;
  collectionName.insert(HCname="InnerScintCollection");
  positionResolution = 1*mm;


  // ROOT
  BookRoot();
}

LEMuSRScintSD::~LEMuSRScintSD()
{
  // ROOT
  WriteRoot();
}

void LEMuSRScintSD::Initialize(G4HCofThisEvent* HCE)
{
  static int HCID = -1;
  ScintCollection = new LEMuSRScintHitsCollection
    (SensitiveDetectorName,collectionName[0]); 
  if(HCID<0)
    { HCID = GetCollectionID(0); }
  HCE->AddHitsCollection(HCID,ScintCollection);
}

G4bool LEMuSRScintSD::ProcessHits(G4Step* aStep, G4TouchableHistory*)
{
  p_name = aStep->GetTrack()->GetDefinition()->GetParticleName(); // particle name
  
 
  if( CheckCondition(aStep))
    {
      GetDatas(aStep);
      getHit();
      FillRoot();

    }
      aStep->GetTrack()->SetTrackStatus(fStopAndKill);
  
  //  PrintAll();
   
  
  return true;
}

void LEMuSRScintSD::EndOfEvent(G4HCofThisEvent*)
{
  //   G4int NbHits = ScintCollection->entries();
  //     G4cout << "\n-------->Hits Collection: in this event they are " << NbHits 
  //            << " hits in the inner scintillator: " << G4endl;
  //     for (G4int i=0;i<NbHits;i++) (*ScintCollection)[i]->Print();

}

G4bool LEMuSRScintSD::CheckCondition(const G4Step* aStep)
{
  G4bool condition=false;
  
  if(p_name == "e+")//&&aStep->GetTrack()->GetNextVolume()->GetLogicalVolume()->GetName()!="lv_SCIS")
    {
      condition=true;	  
      if( aStep->GetTrack()->GetCreatorProcess())      
	{
	  if( aStep->GetTrack()->GetCreatorProcess()->GetProcessName()=="Decay"|| aStep->GetTrack()->GetCreatorProcess()->GetProcessName()=="DecayWithSpin")
	    {
	      condition=true;
	    }
	}
    }
 
  return condition;
 
}  


void LEMuSRScintSD::clear()
{
  delete ScintCollection;
} 

void LEMuSRScintSD::DrawAll()
{
} 

void LEMuSRScintSD::PrintAll()
{
  // Define Hit
     
//  G4cout << "PROCESS HIT"<<G4endl;
  
  LEMuSRScintHit* aHit;
  aHit = new LEMuSRScintHit();
  
 //++++++++++++++ set hit values _______________
  aHit->SetParticleName(p_name);
  aHit->SetSpin(spin);
  
  aHit->SetMomentum( hitmom );
  aHit->SetPosition( hitpos );
  
  aHit->SetTimeOfFlight( tof);
  aHit->SetEnergyDeposition( edep );
  
  
  //  ScintCollection->insert( aHit );
  //  aHit->Print();
  //  aHit->print("Statistics/SCIS.Hits");
  //  aHit->Draw();


} 


void LEMuSRScintSD::GetDatas(const G4Step *aStep)
{
  // Get datas
  //a  Volume, name, spin
  vname =  aStep->GetPreStepPoint()->GetPhysicalVolume()->GetName();  
  spin=  aStep->GetTrack()->GetDefinition()->GetPDGSpin(); // spin in units of 1
  
  //b Position momentum
  hitpos = aStep->GetTrack()->GetPosition(); // position
  hitmom = aStep->GetTrack()->GetMomentumDirection(); // momentum
  hitvertex = aStep->GetTrack()->GetVertexPosition();// creation position
  //c Times
  tof =  aStep->GetTrack()->GetLocalTime(); // time since track creation
  globaltime =  aStep->GetTrack()->GetGlobalTime();// time since event creation
  proptime =  aStep->GetTrack()->GetProperTime(); // particle's proper time
  
  //d Energy
  edep = aStep->GetTotalEnergyDeposit(); 
  
  toten =  aStep->GetTrack()->GetTotalEnergy();
  
  kinen =  aStep->GetTrack()->GetKineticEnergy();

  //e Scint scintID
  

  //f runID
  runID=G4RunManager::GetRunManager()->GetCurrentRun()->GetRunID();

  //g parent charge: 0 for muonium and 1 for muon

}


void LEMuSRScintSD::getHit()
{
  theHit.kenergy       = kinen;
  theHit.tenergy       = toten;
  theHit.edeposit      = edep;
  theHit.localtime     = tof;
  theHit.globaltime    = globaltime;
  theHit.proptime      = proptime;
  theHit.positionx     = hitpos.x();
  theHit.positiony     = hitpos.y();
  theHit.positionz     = hitpos.z();
  theHit.momdirx       = hitmom.x();
  theHit.momdiry       = hitmom.y();
  theHit.momdirz       = hitmom.z();
  theHit.ipositionx     = hitvertex.x();
  theHit.ipositiony     = hitvertex.y();
  theHit.ipositionz     = hitvertex.z();
  theHit.runID         = runID;
  theHit.motherCharge         = runID;

  	   theHit.scLeft = 0;
	   theHit.scBottom =0 ;
	   theHit.scRight =0;
	   theHit.scTop = 0;
  
      if (vname=="pv_SCISl") 
	{
	   theHit.scLeft = 1;
	}
      else if (vname=="pv_SCISb")
	{
	   theHit.scBottom =1 ;
	}
      else if (vname=="pv_SCISr") 
	{
	   theHit.scRight =1;
	}
      else if (vname=="pv_SCISt")
	{
	   theHit.scTop = 1;
	}



 }

//                                     ROOT METHODS

void LEMuSRScintSD::BookRoot()
{
  // open root file
  myFile = new TFile("SDInnerScint.root", "RECREATE");
  //  myFile->SetCompressionLevel(1);

  tree = new TTree ("tree","Inner Scintillator Datas");

  tree->Branch("positron",&theHit.kenergy,"kenergy/F:tenergy/F:edeposit/F:localtime/F:globaltime:propertime/F:positionx/F:positiony:positionz:momentumx:momentumy:momentumz/F:initx/F:inity/F:initz/F:Left/F:Right/F:Bottom/F:Top/F:runID/I:parentCharge/F");

}

void LEMuSRScintSD::FillRoot()
{
  tree->Fill();
}

void LEMuSRScintSD::WriteRoot()
{
  myFile->Write();
  myFile->Close();
}
