Skip to content
Snippets Groups Projects
Analysis.cxx 12 KiB
Newer Older
/*****************************************************************************
 * Copyright (C) 2009-2014    this file is part of the NPTool Project        *
 *                                                                           *
 * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
 * For the list of contributors see $NPTOOL/Licence/Contributors             *
 *****************************************************************************/

/*****************************************************************************
 * Original Author: Adrien MATTA  contact address: a.matta@surrey.ac.uk      *
 *                                                                           *
Adrien Matta's avatar
Adrien Matta committed
 * Creation Date  : july  2020                                               *
 * Last update    :                                                          *
 *---------------------------------------------------------------------------*
 * Decription:                                                               *
 * Class describing the property of an Analysis object                       *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * Comment:                                                                  *
 *                                                                           *
 *                                                                           *
 *****************************************************************************/
#include<iostream>
using namespace std;
#include"Analysis.h"
#include"NPAnalysisFactory.h"
#include"NPDetectorManager.h"
#include"NPOptionManager.h"
#include"NPFunction.h"
#include"NPTrackingUtility.h"
#include"NPPhysicalConstants.h"
////////////////////////////////////////////////////////////////////////////////
Analysis::Analysis(){
}
////////////////////////////////////////////////////////////////////////////////
Analysis::~Analysis(){
}

////////////////////////////////////////////////////////////////////////////////
void Analysis::Init(){
  IC= new TInitialConditions;
  DC= new TInteractionCoordinates;
  RC= new TReactionConditions;
  
  InitOutputBranch();
  InitInputBranch();
  
  Strasse = (TStrassePhysics*)  m_DetectorManager -> GetDetector("Strasse");
  Catana = (TCatanaPhysics*)  m_DetectorManager -> GetDetector("Catana");
  // reaction properties
  m_QFS = new NPL::QFS();
  m_QFS->ReadConfigurationFile(NPOptionManager::getInstance()->GetReactionFile());
  // reaction properties
  myBeam = new NPL::Beam();
  myBeam->ReadConfigurationFile(NPOptionManager::getInstance()->GetReactionFile());
  InitialBeamEnergy = myBeam->GetEnergy()/* * myBeam->GetA()*/;
  // target thickness
  TargetThickness = m_DetectorManager->GetTargetThickness();
  string TargetMaterial = m_DetectorManager->GetTargetMaterial();
  // EnergyLoss Tables
  string BeamName = NPL::ChangeNameToG4Standard(myBeam->GetName());
  BeamTarget = NPL::EnergyLoss(BeamName+"_"+TargetMaterial+".G4table","G4Table",100);
  protonTarget = NPL::EnergyLoss("proton_"+TargetMaterial+".G4table","G4Table",100);
  protonAl = NPL::EnergyLoss("proton_Al.G4table","G4Table",100);
  protonSi = NPL::EnergyLoss("proton_Si.G4table","G4Table",100);
  LV_T.SetVectM(TVector3(0,0,0),NPUNITS::proton_mass_c2);
} 

////////////////////////////////////////////////////////////////////////////////
void Analysis::TreatEvent(){
  // Reinitiate calculated variable
  ReInitValue();
  unsigned int size = Strasse->GetEventMultiplicity();
  if(size==2){ // 2 proton detected
    // Proton 1
    TVector3 InnerPos1 = Strasse->GetInnerPositionOfInteraction(0);
    TVector3 OuterPos1 = Strasse->GetOuterPositionOfInteraction(0);
    TVector3 Proton1 = OuterPos1-InnerPos1;
    Proton1=Proton1.Unit();
    // Proton 2
    TVector3 InnerPos2 = Strasse->GetInnerPositionOfInteraction(1);
    TVector3 OuterPos2 = Strasse->GetOuterPositionOfInteraction(1);
    TVector3 Proton2 = OuterPos2-InnerPos2;
    Proton2=Proton2.Unit();
Adrien Matta's avatar
Adrien Matta committed
    deltaPhi = abs(Proton1.Phi()/deg-Proton2.Phi()/deg);
    sumTheta = Proton1.Theta()/deg+Proton2.Theta()/deg;
    Theta12  = Proton1.Angle(Proton2)/deg;

    // reject event that make no physical sense
    /*if(deltaPhi<170 && sumTheta<80){
    // computing minimum distance of the two lines
    TVector3 Vertex;
    Distance = NPL::MinimumDistanceTwoLines(InnerPos1,OuterPos1,InnerPos2,OuterPos2,Vertex,delta);
    VertexX=Vertex.X();
    VertexY=Vertex.Y();
    VertexZ=Vertex.Z();
    deltaX=delta.X();
    deltaY=delta.Y();
    deltaZ=delta.Z();
    
    // Look for associated Catana event
    double d1,d2;
    unsigned int i1,i2;
    i1 = Catana->FindClosestHitToLine(InnerPos1,OuterPos1,d1);
    i2 = Catana->FindClosestHitToLine(InnerPos2,OuterPos2,d2);
    //if(i1!=i2){
    if(true){
      double TA = BeamTarget.Slow(InitialBeamEnergy,abs(VertexZ-75),RC->GetBeamDirection().Angle(TVector3(0,0,1)));
       
      ////////////////////////////////////
      // From Reaction Conditions
      double E1s = RC->GetKineticEnergy(0); 
      double E2s = RC->GetKineticEnergy(1); 
      TVector3 Proton1s=RC->GetParticleMomentum(0).Unit();
      TVector3 Proton2s=RC->GetParticleMomentum(1).Unit();
      // Matching the right energy with the right proton
      if((Proton1s-Proton1).Mag()<(Proton1s-Proton2).Mag()){
        E1=E1s;
        E2=E2s;
        alpha=Proton1s.Angle(Proton1)/deg;
        Theta1=Proton1.Theta();
        Phi1=Proton1.Phi();
        Theta2=Proton2.Theta();
        Phi2=Proton2.Phi();
        Theta1s=Proton1s.Theta();
        Phi1s=Proton1s.Phi();
        Theta2s=Proton2s.Theta();
        Phi2s=Proton2s.Phi();
        
        }
      else{
        E2=E1s;
        E1=E2s;
        alpha=Proton2s.Angle(Proton1)/deg;
        Theta1=Proton1.Theta()/deg;
        Phi1=Proton1.Phi()/deg;
        Theta2=Proton2.Theta()/deg;
        Phi2=Proton2.Phi()/deg;
        Theta1s=Proton2s.Theta()/deg;
        Phi1s=Proton2s.Phi()/deg;
        Theta2s=Proton1s.Theta()/deg;
        Phi2s=Proton1s.Phi()/deg;
        }
      // From detectors
      E1 = ReconstructProtonEnergy(Vertex,Proton1,Catana->Energy[i1]); 
      E2 = ReconstructProtonEnergy(Vertex,Proton2,Catana->Energy[i2]);

     // Vertex = RC->GetVertexPosition();  
      //TA = RC->GetBeamEnergy();
      //////////////////////////////////// 
     // setting up Lorentz Vector from measured trajectories and energies
     // TVector3 PA(0,0,sqrt(TA*(TA+2*m_QFS->GetParticleA()->Mass()))); // for like there is no BDC
     double beam_mom=sqrt(TA*(TA+2*m_QFS->GetParticleA()->Mass()));
    // TVector3 PA(0,0,beam_mom); // for like there is no BDC
       TVector3 PA=beam_mom*RC->GetBeamDirection().Unit();

      LV_A.SetVectM(PA,m_QFS->GetParticleA()->Mass());
      double P1= sqrt(E1*(E1+2*NPUNITS::proton_mass_c2));
      double P2= sqrt(E2*(E2+2*NPUNITS::proton_mass_c2));
      LV_p1.SetVectM(Proton1.Unit()*P1,NPUNITS::proton_mass_c2); 
      LV_p2.SetVectM(Proton2.Unit()*P2,NPUNITS::proton_mass_c2); 
      // computing Ex from Missing Mass
      LV_B = LV_A + LV_T - LV_p1 - LV_p2;
      //LV_B = RC->GetParticleMomentum(2);
      Ex = LV_B.M() - m_QFS->GetParticleB()->Mass();
////////////////////////////////////////////////////////////////////////////////
double Analysis::ReconstructProtonEnergy(const TVector3& x0, const TVector3& dir,const double& Ecatana){
    TVector3 Normal = TVector3(0,1,0);
    Normal.SetPhi(dir.Phi());
    double Theta = dir.Angle(Normal);  
    // Catana Al housing 
    double E = protonAl.EvaluateInitialEnergy(Ecatana,0.5*mm,Theta);
    // Strasse Chamber
    E = protonAl.EvaluateInitialEnergy(E,3*mm,Theta);
    // Outer Barrel
    E = protonSi.EvaluateInitialEnergy(E,300*micrometer,Theta);
    // Inner Barrel
    E = protonSi.EvaluateInitialEnergy(E,200*micrometer,Theta);
    // LH2 target
    static TVector3 x1;
    x1= x0+dir;
    TVector3 T1(0,15,0);
    TVector3 T2(0,15,1);
    T1.SetPhi(dir.Phi());
    T2.SetPhi(dir.Phi());
    double d = NPL::MinimumDistancePointLine(T1,T2,x0);
    E = protonTarget.EvaluateInitialEnergy(E,d,Theta);
  }


////////////////////////////////////////////////////////////////////////////////
TVector3 Analysis::InterpolateInPlaneZ(TVector3 V0, TVector3 V1, double Zproj){
    TVector3 Vproj(-999,-999,-999);
    double t = (Zproj - V1.Z()) / (V1.Z()-V0.Z());
    double Xproj= V1.X() + (V1.X()-V0.X()) * t;
    double Yproj= V1.Y() + (V1.Y()-V0.Y()) * t; 
    Vproj.SetXYZ(Xproj,Yproj,Zproj);
    return Vproj;
}

////////////////////////////////////////////////////////////////////////////////
void Analysis::End(){
}
////////////////////////////////////////////////////////////////////////////////
void Analysis::InitOutputBranch() {
  RootOutput::getInstance()->GetTree()->Branch("Ex",&Ex,"Ex/D");
  RootOutput::getInstance()->GetTree()->Branch("E1",&E1,"E1/D");
  RootOutput::getInstance()->GetTree()->Branch("E2",&E2,"E2/D");
  RootOutput::getInstance()->GetTree()->Branch("Theta12",&Theta12,"Theta12/D");
  RootOutput::getInstance()->GetTree()->Branch("ThetaCM",&ThetaCM,"ThetaCM/D");
  RootOutput::getInstance()->GetTree()->Branch("VertexX",&VertexX,"VertexX/D");
  RootOutput::getInstance()->GetTree()->Branch("VertexY",&VertexY,"VertexY/D");
  RootOutput::getInstance()->GetTree()->Branch("VertexZ",&VertexZ,"VertexZ/D");
  RootOutput::getInstance()->GetTree()->Branch("deltaX",&deltaX,"deltaX/D");
  RootOutput::getInstance()->GetTree()->Branch("deltaY",&deltaY,"deltaY/D");
  RootOutput::getInstance()->GetTree()->Branch("deltaZ",&deltaZ,"deltaZ/D");
Adrien Matta's avatar
Adrien Matta committed
  RootOutput::getInstance()->GetTree()->Branch("deltaPhi",&deltaPhi,"deltaPhi/D");
  RootOutput::getInstance()->GetTree()->Branch("sumTheta",&sumTheta,"sumTheta/D");

  RootOutput::getInstance()->GetTree()->Branch("alpha",&alpha,"alpha/D");

  RootOutput::getInstance()->GetTree()->Branch("Theta1",&Theta1,"Theta1/D");
  RootOutput::getInstance()->GetTree()->Branch("Phi1",&Phi1,"Phi1/D");
  RootOutput::getInstance()->GetTree()->Branch("Theta2",&Theta2,"Theta2/D");
  RootOutput::getInstance()->GetTree()->Branch("Phi2",&Phi2,"Phi2/D");
  RootOutput::getInstance()->GetTree()->Branch("Theta1s",&Theta1s,"Theta1s/D");
  RootOutput::getInstance()->GetTree()->Branch("Phi1s",&Phi1s,"Phi1s/D");
  RootOutput::getInstance()->GetTree()->Branch("Theta2s",&Theta2s,"Theta2s/D");
  RootOutput::getInstance()->GetTree()->Branch("Phi2s",&Phi2s,"Phi2s/D");

  RootOutput::getInstance()->GetTree()->Branch("Distance",&Distance,"Distance/D");
  RootOutput::getInstance()->GetTree()->Branch("InteractionCoordinates","TInteractionCoordinates",&DC);
  RootOutput::getInstance()->GetTree()->Branch("ReactionConditions","TReactionConditions",&RC);
}

////////////////////////////////////////////////////////////////////////////////
void Analysis::InitInputBranch(){
    RootInput:: getInstance()->GetChain()->SetBranchAddress("InteractionCoordinates",&DC);
    RootInput:: getInstance()->GetChain()->SetBranchAddress("ReactionConditions",&RC);
}
////////////////////////////////////////////////////////////////////////////////
void Analysis::ReInitValue(){
  Ex = -1000 ;
  Theta12 = -1000;
  ThetaCM = -1000;
  VertexX=-1000;
  VertexY=-1000;
  VertexZ=-1000;
  deltaX=-1000;
  deltaY=-1000;
  deltaZ=-1000;
  Distance=-1000;
Adrien Matta's avatar
Adrien Matta committed
  sumTheta=-1000;
  deltaPhi=-1000;
  alpha=-1000;
  Theta1=-1000;
  Phi1=-1000;
  Theta2=-1000;
  Phi2=-1000;
  Theta1s=-1000;
  Phi1s=-1000;
  Theta2s=-1000;
  Phi2s=-1000;
}


////////////////////////////////////////////////////////////////////////////////
//            Construct Method to be pass to the AnalysisFactory              //
////////////////////////////////////////////////////////////////////////////////
NPL::VAnalysis* Analysis::Construct(){
  return (NPL::VAnalysis*) new Analysis();
}

////////////////////////////////////////////////////////////////////////////////
//            Registering the construct method to the factory                 //
////////////////////////////////////////////////////////////////////////////////
extern "C"{
class proxy{
  public:
    proxy(){
      NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct);
    }
};

proxy p;
}