Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
p2pi_hists/DCustomAction_p2pi_hists.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DCustomAction_p2pi_hists.cc
4 // Created: Wed Jan 21 16:53:41 EST 2015
5 // Creator: jrsteven (on Linux ifarm1401 2.6.32-431.el6.x86_64 x86_64)
6 //
7 
9 
10 void DCustomAction_p2pi_hists::Initialize(JEventLoop* locEventLoop)
11 {
12  DApplication* dapp=dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
13  JCalibration *jcalib = dapp->GetJCalibration((locEventLoop->GetJEvent()).GetRunNumber());
14 
15  // Parameters for event selection to fill histograms
16  endpoint_energy = 12.;
17  map<string, double> photon_endpoint_energy;
18  if(jcalib->Get("/PHOTON_BEAM/endpoint_energy", photon_endpoint_energy) == false) {
19  endpoint_energy = photon_endpoint_energy["PHOTON_BEAM_ENDPOINT_ENERGY"];
20  }
21  else {
22  jout<<"No /PHOTON_BEAM/endpoint_energy for this run number: using default of 12 GeV"<<endl;
23  }
25 
26  cohmin_energy = 0.;
27  cohedge_energy = 12.;
28  map<string, double> photon_beam_param;
29  if(jcalib->Get("/ANALYSIS/beam_asymmetry/coherent_energy", photon_beam_param) == false) {
30  cohmin_energy = photon_beam_param["cohmin_energy"];
31  cohedge_energy = photon_beam_param["cohedge_energy"];
32  }
33  else {
34  jout<<"No /ANALYSIS/beam_asymmetry/coherent_energy for this run number: using default range of 0-12 GeV"<<endl;
35  }
36 
37  dEdxCut = 2.2;
38  minMMCut = 0.8;
39  maxMMCut = 1.05;
40  minMM2Cut = -0.006;
41  maxMM2Cut = 0.004;
42  missingEnergyCut = 1.0;
43  minRhoMassCut = 0.6;
44  maxRhoMassCut = 0.88;
45 
46  // get PID algos
47  const DParticleID* locParticleID = NULL;
48  locEventLoop->GetSingle(locParticleID);
49  dParticleID = locParticleID;
50 
51  locEventLoop->GetSingle(dAnalysisUtilities);
52 
53  // check if a particle is missing
54  auto locMissingPIDs = Get_Reaction()->Get_MissingPIDs();
55  dMissingPID = (locMissingPIDs.size() == 1) ? locMissingPIDs[0] : Unknown;
56 
57  //CREATE THE HISTOGRAMS
58  //Since we are creating histograms, the contents of gDirectory will be modified: must use JANA-wide ROOT lock
59  japp->RootWriteLock(); //ACQUIRE ROOT LOCK!!
60  {
61  //Required: Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this action.
62  //If another thread has already created the folder, it just changes to it.
64 
65  dEgamma = GetOrCreate_Histogram<TH1I>("Egamma", "TAGGER photon energy; E_{#gamma}", endpoint_energy_bins, 0., endpoint_energy);
66 
67  if(dMissingPID == Proton) {
68  dMM_M2pi = GetOrCreate_Histogram<TH2I>("MM_M2pi", "MM off #pi^{+}#pi^{-} vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; MM", 200, 0.0, 2.0, 200, 0., 4.);
69  dMM_M2pi_noEle = GetOrCreate_Histogram<TH2I>("MM_M2pi_noEle", "MM off #pi^{+}#pi^{-} vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; MM", 200, 0.0, 2.0, 200, 0., 4.);
70  dt_M2pi_noEle = GetOrCreate_Histogram<TH2I>("t_M2pi_noEle", "|t| vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; t", 200, 0.0, 2.0, 1000, 0., 5.);
71  dPiPlusPsi_t = GetOrCreate_Histogram<TH2I>("PiPlusPsi_t","#psi vs |t|; |t|; #pi^{+} #psi",1000,0.,5.,360,-180,180);
72  }
73  else {
74  dMM2_M2pi = GetOrCreate_Histogram<TH2I>("MM2_M2pi", "MM^{2} off #pi^{+}#pi^{-} vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; MM^{2}", 200, 0.0, 2.0, 200, -0.1, 0.1);
75  dProton_dEdx_P = GetOrCreate_Histogram<TH2I>("Proton_dEdx_P","dE/dx vs p; p; dE/dx",200,0,2,500,0,25);
76  dProton_P_Theta = GetOrCreate_Histogram<TH2I>("Proton_P_Theta","p vs #theta; #theta; p (GeV/c)",180,0,180,120,0,12);
77  dDeltaE_M2pi = GetOrCreate_Histogram<TH2I>("DeltaE_M2pi", "#DeltaE vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; #DeltaE (tagger - tracks)", 200, 0.0, 2.0, 200, -5., 5.);
78  dDeltaE_M2pi_ProtonTag = GetOrCreate_Histogram<TH2I>("DeltaE_M2pi_ProtonTag", "#DeltaE vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; #DeltaE (tagger - tracks)", 200, 0.0, 2.0, 200, -5., 5.);
79 
80  dDalitz_p2pi = GetOrCreate_Histogram<TH2I>("Dalitz_p2pi", "Dalitz p#pi^{+}#pi^{-}; M_{#pi^{+}#pi^{-}}^{2}; M_{p#pi^{+}}^{2}", 200, 0.0, 5.0, 200, 0., 5.);
81  dMppiplus_M2pi = GetOrCreate_Histogram<TH2I>("Mppiplus_M2pi", "Psuedo-Dalitz p#pi^{+}#pi^{-}; M_{#pi^{+}#pi^{-}}; M_{p#pi^{+}}", 200, 0.0, 2.0, 200, 1.0, 3.0);
82  dMppiminus_M2pi = GetOrCreate_Histogram<TH2I>("Mppiminus_M2pi", "Psuedo-Dalitz p#pi^{+}#pi^{-}; M_{#pi^{+}#pi^{-}}; M_{p#pi^{-}}", 200, 0.0, 2.0, 200, 1.0, 3.0);
83 
84  dProtonPhi_Egamma = GetOrCreate_Histogram<TH2I>("ProtonPhi_Egamma","#phi vs E_{#gamma}; E_{#gamma}; proton #phi",endpoint_energy_bins,0,endpoint_energy,360,-180,180);
85  dPiPlusPsi_Egamma = GetOrCreate_Histogram<TH2I>("PiPlusPsi_Egamma","#psi vs E_{#gamma}; E_{#gamma}; #pi^{+} #phi",endpoint_energy_bins,0,endpoint_energy,360,-180,180);
86  dPiPlusPsi_t = GetOrCreate_Histogram<TH2I>("PiPlusPsi_t","#psi vs |t|; |t|; #pi^{+} #psi",1000,0.,5.,360,-180,180);
87 
88  dEgamma_M2pi = GetOrCreate_Histogram<TH2I>("Egamma_M2pi", "E_{#gamma} vs M_{#pi^{+}#pi^{-}}; M_{#pi^{+}#pi^{-}}; E_{#gamma}", 200, 0.0, 2.0, endpoint_energy_bins,0,endpoint_energy);
89 
90  dBaryonM_CosTheta_Egamma1 = GetOrCreate_Histogram<TH2I>("BaryonM_CosTheta_Egamma1", "Baryon M_{p#pi^{+}} vs cos#theta: E_{#gamma} < 2.5; cos#theta; M_{p#pi^{+}}", 100, -1, 1, 100, 1.0, 2.5);
91  dBaryonM_CosTheta_Egamma2 = GetOrCreate_Histogram<TH2I>("BaryonM_CosTheta_Egamma2", "Baryon M_{p#pi^{+}} vs cos#theta: 2.5 < E_{#gamma} < 3.0; cos#theta; M_{p#pi^{+}}", 100, -1, 1, 100, 1.0, 2.5);
92  dBaryonM_CosTheta_Egamma3 = GetOrCreate_Histogram<TH2I>("BaryonM_CosTheta_Egamma3", "Baryon M_{p#pi^{+}} vs cos#theta: E_{#gamma} > 3.0; cos#theta; M_{p#pi^{+}}", 100, -1, 1, 100, 1.0, 2.5);
93  }
94 
95  //Return to the base directory
97  }
98  japp->RootUnLock(); //RELEASE ROOT LOCK!!
99 }
100 
101 bool DCustomAction_p2pi_hists::Perform_Action(JEventLoop* locEventLoop, const DParticleCombo* locParticleCombo)
102 {
103 
104  const DDetectorMatches* locDetectorMatches = NULL;
105  locEventLoop->GetSingle(locDetectorMatches);
106 
107  // should only have one reaction step
108  const DParticleComboStep* locParticleComboStep = locParticleCombo->Get_ParticleComboStep(0);
109 
110  // get beam photon energy and final state particles
111  auto locBeamPhoton = Get_UseKinFitResultsFlag() ? locParticleComboStep->Get_InitialParticle() : locParticleComboStep->Get_InitialParticle_Measured();
112  auto locParticles = Get_UseKinFitResultsFlag() ? locParticleComboStep->Get_FinalParticles() : locParticleComboStep->Get_FinalParticles_Measured();
113  double locBeamPhotonEnergy = locBeamPhoton->energy();
114 
115  // calculate 2pi P4
116  DLorentzVector locP4_2pi;
117  for(size_t loc_i = 0; loc_i < 3; ++loc_i) {
118  if(locParticles[loc_i] == NULL) continue; // missing particle
119  if(locParticles[loc_i]->PID() == PiPlus || locParticles[loc_i]->PID() == PiMinus)
120  locP4_2pi += locParticles[loc_i]->lorentzMomentum();
121  }
122 
123  // calculate missing P4
125 
126  // reconstructed proton variables
127  double dEdx = 0.;
128  DLorentzVector locProtonP4;
129  if(dMissingPID != Proton) {
130  const DChargedTrack* locChargedTrack = static_cast<const DChargedTrack*>(locParticleComboStep->Get_FinalParticle_SourceObject(0));
131  const DChargedTrackHypothesis* locChargedTrackHypothesis = locChargedTrack->Get_Hypothesis(Proton);
132  dEdx = locChargedTrackHypothesis->Get_TrackTimeBased()->dEdx()*1e6; // convert to keV
133  locProtonP4 = locChargedTrackHypothesis->lorentzMomentum();
134  }
135  else locProtonP4 = locMissingP4;
136 
137  // production kinematics
138  DLorentzVector locSumInitP4;
139  DLorentzVector locProtonP4Init(0,0,0,0.938);
140  locSumInitP4 += locProtonP4Init;
141  locSumInitP4 += locBeamPhoton->lorentzMomentum();
142  TLorentzVector locDelta = (locProtonP4 - locProtonP4Init);
143  double t = locDelta.M2();
144 
145  TLorentzVector locPiPlus_P4 = locParticles[1]->lorentzMomentum();
146 
147  // boost to resonance frame for angular distributions
148  TLorentzRotation resonanceBoost( -locP4_2pi.BoostVector() );
149  TLorentzVector recoil_res = resonanceBoost * locProtonP4;
150  TLorentzVector p1_res = resonanceBoost * locPiPlus_P4;
151 
152  // normal to the production plane
153  TVector3 y = (locBeamPhoton->lorentzMomentum().Vect().Unit().Cross(-locProtonP4.Vect().Unit())).Unit();
154 
155  // choose helicity frame: z-axis opposite recoil proton in rho rest frame
156  TVector3 z = -1. * recoil_res.Vect().Unit();
157  TVector3 x = y.Cross(z).Unit();
158  TVector3 angles( (p1_res.Vect()).Dot(x),
159  (p1_res.Vect()).Dot(y),
160  (p1_res.Vect()).Dot(z) );
161 
162  double cosTheta = angles.CosTheta();
163  double phi = angles.Phi();
164 
165  TVector3 eps(1.0, 0.0, 0.0); // beam polarization vector
166  double Phi = atan2(y.Dot(eps), locBeamPhoton->lorentzMomentum().Vect().Unit().Dot(eps.Cross(y)));
167 
168  double locPsi = phi - Phi;
169  if(locPsi < -1*TMath::Pi()) locPsi += 2*TMath::Pi();
170  if(locPsi > TMath::Pi()) locPsi -= 2*TMath::Pi();
171 
172  //FILL HISTOGRAMS
173  //Since we are filling histograms local to this action, it will not interfere with other ROOT operations: can use action-wide ROOT lock
174  //Note, the mutex is unique to this DReaction + action_string combo: actions of same class with different hists will have a different mutex
175  Lock_Action(); //ACQUIRE ROOT LOCK!!
176  {
177  // Fill histograms here
178  dEgamma->Fill(locBeamPhotonEnergy);
179 
180  if(dMissingPID == Proton) {
181  if(locBeamPhotonEnergy > cohmin_energy && locBeamPhotonEnergy < cohedge_energy) {
182  dMM_M2pi->Fill(locP4_2pi.M(), locMissingP4.M());
183 
184  if(locParticles[1]->lorentzMomentum().Theta()*180/TMath::Pi() > 2. && locParticles[2]->lorentzMomentum().Theta()*180/TMath::Pi() > 2.) {
185  dMM_M2pi_noEle->Fill(locP4_2pi.M(), locMissingP4.M());
186 
187  if(locMissingP4.M() > minMMCut && locMissingP4.M() < maxMMCut) {
188  dt_M2pi_noEle->Fill(locP4_2pi.M(), fabs(t));
189 
190  if(locP4_2pi.M() > minRhoMassCut && locP4_2pi.M() < maxRhoMassCut){
191  dPiPlusPsi_t->Fill(fabs(t), locPsi*180/TMath::Pi());
192  }
193  }
194  }
195  }
196  }
197  else {
198  dMM2_M2pi->Fill(locP4_2pi.M(), locMissingP4.M2());
199  dDeltaE_M2pi->Fill(locP4_2pi.M(),locMissingP4.E());
200 
201  if(locMissingP4.M2() > minMM2Cut && locMissingP4.M2() < maxMM2Cut && fabs(locMissingP4.E()) < missingEnergyCut){
202  dProton_dEdx_P->Fill(locProtonP4.Vect().Mag(), dEdx);
203  dProton_P_Theta->Fill(locProtonP4.Vect().Theta()*180/TMath::Pi(), locProtonP4.Vect().Mag());
204 
205  if(dEdx > dEdxCut) {
206 
207  dEgamma_M2pi->Fill(locP4_2pi.M(), locBeamPhotonEnergy);
208  dDeltaE_M2pi_ProtonTag->Fill(locP4_2pi.M(),locMissingP4.E());
209 
210  DLorentzVector locP4_ppiplus = locProtonP4;
211  DLorentzVector locP4_ppiminus = locProtonP4;
212  locP4_ppiplus += locParticles[1]->lorentzMomentum();
213  locP4_ppiminus += locParticles[2]->lorentzMomentum();
214  if(locBeamPhotonEnergy > cohmin_energy && locBeamPhotonEnergy < cohedge_energy){
215  dDalitz_p2pi->Fill(locP4_2pi.M2(), locP4_ppiplus.M2());
216  dMppiplus_M2pi->Fill(locP4_2pi.M(), locP4_ppiplus.M());
217  dMppiminus_M2pi->Fill(locP4_2pi.M(), locP4_ppiminus.M());
218  }
219 
220  // some p pi+ mass distributions (hunt for Delta++...)
221  if(locBeamPhotonEnergy < cohmin_energy)
222  dBaryonM_CosTheta_Egamma1->Fill(cosTheta,locP4_ppiplus.M());
223  else if(locBeamPhotonEnergy < cohedge_energy)
224  dBaryonM_CosTheta_Egamma2->Fill(cosTheta,locP4_ppiplus.M());
225  else
226  dBaryonM_CosTheta_Egamma3->Fill(cosTheta,locP4_ppiplus.M());
227 
228 
229  if(locP4_2pi.M() > minRhoMassCut && locP4_2pi.M() < maxRhoMassCut){
230  dProtonPhi_Egamma->Fill(locBeamPhotonEnergy, locProtonP4.Phi()*180/TMath::Pi());
231  dPiPlusPsi_Egamma->Fill(locBeamPhotonEnergy, locPsi*180/TMath::Pi());
232 
233  if(locBeamPhotonEnergy > cohmin_energy && locBeamPhotonEnergy < cohedge_energy){
234  dPiPlusPsi_t->Fill(fabs(t), locPsi*180/TMath::Pi());
235  }
236  }
237  }
238  }
239  }
240  }
241  Unlock_Action(); //RELEASE ROOT LOCK!!
242 
243  return true; //return false if you want to use this action to apply a cut (and it fails the cut!)
244 }
vector< const DKinematicData * > Get_FinalParticles_Measured(void) const
const DAnalysisUtilities * dAnalysisUtilities
TDirectoryFile * ChangeTo_BaseDirectory(void)
DApplication * dapp
const DReaction * Get_Reaction(void) const
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
#define y
const DTrackTimeBased * Get_TrackTimeBased(void) const
TDirectoryFile * CreateAndChangeTo_ActionDirectory(void)
const DKinematicData * Get_InitialParticle_Measured(void) const
TLorentzVector DLorentzVector
const DChargedTrackHypothesis * Get_Hypothesis(Particle_t locPID) const
Definition: DChargedTrack.h:59
bool Get_UseKinFitResultsFlag(void) const
JApplication * japp
DLorentzVector Calc_MissingP4(const DReaction *locReaction, const DParticleCombo *locParticleCombo, bool locUseKinFitDataFlag) const
void Initialize(JEventLoop *locEventLoop)
vector< const DKinematicData * > Get_FinalParticles(void) const
vector< Particle_t > Get_MissingPIDs(int locStepIndex=-1, Charge_t locCharge=d_AllCharges, bool locIncludeDuplicatesFlag=true) const
Definition: DReaction.cc:46
DLorentzVector lorentzMomentum(void) const
const JObject * Get_FinalParticle_SourceObject(size_t locFinalParticleIndex) const
const DKinematicData * Get_InitialParticle(void) const
double dEdx(void) const
const DParticleComboStep * Get_ParticleComboStep(size_t locStepIndex) const
bool Perform_Action(JEventLoop *locEventLoop, const DParticleCombo *locParticleCombo)