//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//             LOW ENERGY MUON SPIN RELAXATION, ROTATION, RADIATION 
//
//  ID    : LEMuSRMUONIUM.cc , v 1.3
//  AUTHOR: Taofiq PARAISO
//  DATE  : 2006-01-19 16:15
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//
//  &           &&&&&&&&&&                            &&&&&&&         &&&&&&&&
//  &           &                                   &&      &&       &       &&
//  &           &                   &      &       &                &       &&
//  &           &&&&&&&            &      &         &&&&&&         &&&&&&&&  
//  &           &                 &      &&                &      &      &&
//  &           &                &&     &  &     &&      &&      &        &
//  &&&&&&&&&&  &&&&&&&&&&      &  &&&&&    &&    &&&&&&&       &        &&   
//                             &
//                            &
//                           &
//                         &  
//                               MUONIUM   
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#include "LEMuSRMUONIUM.hh"
#include "G4StepStatus.hh"
#include "G4Navigator.hh"
#include "G4TransportationManager.hh"
#include "Randomize.hh"
#include "G4ProductionCutsTable.hh"


#include "meyer.h"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    
using namespace std;

LEMuSRMUONIUM::  LEMuSRMUONIUM(const G4String& name ,
			       G4ProcessType   aType )
 : G4VDiscreteProcess(name, aType)
{}


LEMuSRMUONIUM:: ~LEMuSRMUONIUM()
{}


G4VParticleChange* LEMuSRMUONIUM::PostStepDoIt(
                                               const G4Track& trackData,
                                               const G4Step& aStep )
{
  // Initialize ParticleChange  (by setting all its members equal
  //                             to corresponding members in G4Track)
  fParticleChange.Initialize(trackData);


  G4Track theNewTrack;
  if( CheckCondition(aStep))
    {
      GetDatas(&aStep);
      G4Step theStep;
      PrepareSecondary( trackData);
      
      fParticleChange.AddSecondary(aSecondary);
      fParticleChange.ProposeTrackStatus(fStopAndKill) ;
   
    }  
  else
    {
      fParticleChange.ProposeTrackStatus(trackData.GetTrackStatus()) ;
    }
  
  return &fParticleChange;
}


G4bool LEMuSRMUONIUM::CheckCondition( const G4Step& aStep)
{
  G4bool condition=false;
  p_name = aStep.GetTrack()->GetDefinition()->GetParticleName(); // particle name  
  if(p_name == "mu+"&&aStep.GetTrack()->GetVolume()->GetLogicalVolume()->GetName()=="lv_CFOIL") 
    {
      condition=true;
    }
   
  return condition;
  
}  


G4double LEMuSRMUONIUM:: GetMeanFreePath(const G4Track& ,
			   G4double  ,
			   G4ForceCondition* condition
                                                               )
{

  *condition = Forced;
  return DBL_MAX;
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....

void LEMuSRMUONIUM::GetDatas( const G4Step* aStep)
{

      // Particle generation according to yields
      particleTable=G4ParticleTable::GetParticleTable();
      rnd=G4UniformRand();
      //  std::cout<<"rnd : "<<rnd <<std::endl;
      G4double E = aStep->GetTrack()->GetDynamicParticle()
				 ->GetKineticEnergy()/keV; //LEMuSRPrimaryGeneratorAction::GetPGA()->energy/keV+LEMuSRPrimaryGeneratorAction::GetPGA()->ke_offset/keV;
      Gonin.GetYields(E,105*1000,yvector);
      
      
     G4String p_new="Mu";
      // MUON PLUS
      
     if(p_name=="mu+")
       {
	 if(rnd<yvector[0]) 
	   {
	     particle = particleTable->FindParticle(p_name) ;
	   }
	 else 
	   {
	     particle = particleTable->FindParticle(p_new);
	   }
	  
	 // Set the new dynamic particle
	  
	  
	  
	  
	 DP = new G4DynamicParticle(particle,
				    aStep->GetTrack()->GetDynamicParticle()
				    ->GetMomentumDirection(),
				     
				    aStep->GetTrack()->GetDynamicParticle()
				    ->GetKineticEnergy()
				    );
	 // IMPORTANT : COPY THOSE DATA TO GET THE SAME PARTICLE PROPERTIES!!!!
	 // SHOULD BE KEPT WHEN BUILDING A PARTICLE CHANGE  
	 DP->SetProperTime(aStep->GetTrack()->GetDynamicParticle()->GetProperTime());
	 DP->SetPolarization(aStep->GetTrack()->GetDynamicParticle()->GetPolarization().x(),aStep->GetTrack()->GetDynamicParticle()->GetPolarization().y(),aStep->GetTrack()->GetDynamicParticle()->GetPolarization().z());
	 DP->SetPreAssignedDecayProperTime(aStep->GetTrack()->GetDynamicParticle()->GetPreAssignedDecayProperTime());
       }


}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......



void LEMuSRMUONIUM::PrepareSecondary(const G4Track& track)
{
  if(p_name=="mu+")
    {
      aSecondary = new G4Track(DP,track.GetGlobalTime(),track.GetPosition());
    }

  
}
