Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventProcessor_invariant_mass_hists.cc
Go to the documentation of this file.
1 // $Id: DEventProcessor_invariant_mass_hists.cc 1816 2006-06-06 14:38:18Z davidl $
2 //
3 // File: DEventProcessor_invariant_mass_hists.cc
4 // Created: Thur Jan 11 15:42:21 EDT 2005
5 // Creator: davidl
6 //
7 
8 #include <iostream>
9 #include <cmath>
10 using namespace std;
11 
12 #include <TThread.h>
13 #include <TDirectoryFile.h>
14 #include <TLorentzVector.h>
15 
16 #include <JANA/JApplication.h>
17 #include <JANA/JEventLoop.h>
18 using namespace jana;
19 
20 #include <TRACKING/DMCThrown.h>
21 #include <PID/DKinematicData.h>
22 #include <PID/DChargedTrack.h>
23 #include <PID/DPhoton.h>
24 #include <PID/DBeamPhoton.h>
25 
27 
28 //==========================================================================
29 // This file contains code for a plugin that will create a few histograms
30 // based on the reconstructed data. It can mainly serve as an example
31 // of how one could access the reconstructed data in their own analysis
32 // program.
33 //
34 // Histograms are created in the init() method and they are filled in
35 // the evnt() method.
36 //==========================================================================
37 
38 // Routine used to create our JEventProcessor
39 extern "C"{
40 void InitPlugin(JApplication *app){
41  InitJANAPlugin(app);
42  app->AddProcessor(new DEventProcessor_invariant_mass_hists());
43 }
44 }
45 
46 
47 //------------------
48 // init
49 //------------------
51 {
52  // Create INV_MASS directory
53  TDirectory *dir = new TDirectoryFile("INV_MASS","INV_MASS");
54  dir->cd();
55 
56  // Create histograms
57  mm_gp_to_pX = new TH1D("mm_gp_to_pX","Missing mass from #gamma p -> p X",4001, 0.0, 4.0);
58  mm_gp_to_pX->SetXTitle("Missing mass (GeV)");
59 
60  mass_2gamma = new TH1D("mass_2gamma","2 #gamma invariant mass",4001, 0.0, 4.0);
61  mass_2gamma->SetXTitle("Invariant Mass (GeV/c^{2})");
62 
63  mass_4gamma = new TH1D("mass_4gamma","4 #gamma invariant mass",4001, 0.0, 4.0);
64  mass_4gamma->SetXTitle("Invariant Mass (GeV/c^{2})");
65 
66  mass_pip_pim = new TH1D("mass_pip_pim","invariant mass of #pi^{+} and #pi^{-}",4001, 0.0, 4.0);
67  mass_pip_pim->SetXTitle("Invariant Mass (GeV/c^{2})");
68 
69  t_pX = new TH1D("t_pX","-t for #gammap->pX",20, 0.0, 6.0);
70  t_pX->SetXTitle("-t (GeV)");
71 
72  sqrt_s = new TH1D("sqrt_s","Center of mass energy #sqrt{s}",2001, 0.0, 6.0);
73  sqrt_s->SetXTitle("#sqrt{s} C.M. energy (GeV)");
74 
75  // Go back up to the (ROOT) parent directory
76  dir->cd("../");
77 
78  pthread_mutex_init(&mutex, NULL);
79 
80  return NOERROR;
81 }
82 
83 //------------------
84 // evnt
85 //------------------
86 jerror_t DEventProcessor_invariant_mass_hists::evnt(JEventLoop *loop, uint64_t eventnumber)
87 {
88  // Get reconstructed objects
89  vector<const DBeamPhoton*> beam_photons;
90  vector<const DPhoton*> photons;
91  vector<const DChargedTrack*> chargedtracks;
92 
93  loop->Get(beam_photons); // from truth info
94  loop->Get(photons); // all reconstructed photons (BCAL and FCAL)
95  loop->Get(chargedtracks); // all reconstructed charged (CDC and FDC)
96 
97  // Target is proton at rest in lab frame
98  TLorentzVector target(0.0, 0.0, 0.0, 0.93827);
99 
100  // Create TLorentzVectors for reconstructed photons
101  vector<TLorentzVector> rec_photons;
102  for(unsigned int j=0; j<photons.size(); j++)rec_photons.push_back(MakeTLorentz(photons[j], 0.0));
103 
104  // Create TLorentzVectors for reconstructed charged particles
105  vector<TLorentzVector> rec_piplus;
106  vector<TLorentzVector> rec_piminus;
107  vector<TLorentzVector> rec_protons;
108 
109  // Loop over charged particles turning them into TLorentzVector objects
110  // and sorting them into various containers declared just above.
111  for(unsigned int j=0; j<chargedtracks.size(); j++){
112  if(chargedtracks[j]->hypotheses.size()<1)continue;
113  const DTrackTimeBased *trk = chargedtracks[j]->hypotheses[0];
114 
115  // Use particle mass to decide the type
116  int type = 0;
117  if(fabs(trk->mass()-0.13957)<0.01){
118  type = trk->charge()<0.0 ? 9:8; // initialize to pi-(=9) or pi+(=8)
119  }else if(fabs(trk->mass()-0.93827)<0.01 && trk->charge()==1.0){
120  type=14;
121  }
122 
123  // Add TLorentzVector to appropriate container based on charged particle type
124  switch(type){
125  case 8: rec_piplus.push_back(MakeTLorentz(trk, 0.13957)); break;
126  case 9: rec_piminus.push_back(MakeTLorentz(trk, 0.13957)); break;
127  case 14: rec_protons.push_back(MakeTLorentz(trk, 0.93827)); break;
128  default:
129  cout<<"Unknown particle mass: "<<trk->mass()<<" for charge "<<trk->charge()<<endl;
130  break;
131  }
132  } // chargedtracks
133 
134  // Some generators don't supply information on the beam photon. If there
135  // are no DBeamPhoton objects, then create a 9GeV one here
136  if(beam_photons.size()==0){
137  DBeamPhoton beam;
138  DVector3 mom(0.0, 0.0, 9.0);
139  DVector3 pos(0.0, 0.0, 65.0); // center of target
140  beam.setMomentum(mom);
141  beam.setPosition(pos);
142  beam.setMass(0.0);
143  beam.setCharge(0.0);
144  beam_photons.push_back(&beam);
145  }
146 
147  //--------------------------------------------------------------------
148  // Fill histograms below here using values in the rec_XXX containers.
149 
150  pthread_mutex_lock(&mutex);
151 
152  // Loop over beam photons and fill histos for each "tagged" photon for this event
153  for(unsigned int i=0; i<beam_photons.size(); i++){
154 
155  // Make TLorentzVector for beam photon
156  TLorentzVector beam_photon = MakeTLorentz(beam_photons[i], 0.0);
157 
158  // Center of mass energy
159  sqrt_s->Fill((beam_photon+target).M()); // Fill Center of Mass energy histo
160 
161  // Missing mass from gamma + p -> p + X
162  if(rec_protons.size()==1){
163  TLorentzVector missing = beam_photon + target - rec_protons[0];
164  mm_gp_to_pX->Fill(missing.M());
165  }
166 
167  } // beam_photons
168 
169 
170  //-------------------------------------------------------------------
171  // Below here are the histos that do not depend on the tagged photon
172  // energy and so should be filled outside of the above loop.
173 
174  // 2gamma invariant mass. Loop over all possible combinations
175  for(unsigned int j=1; j<rec_photons.size(); j++){
176  for(unsigned int k=0; k<j; k++){
177  TLorentzVector sum = rec_photons[j] + rec_photons[k];
178  mass_2gamma->Fill(sum.M());
179  }
180  }
181 
182  // 4gamma invariant mass. Loop over all possible combinations
183  for(unsigned int j=3; j<rec_photons.size(); j++){
184  for(unsigned int k=2; k<j; k++){
185  for(unsigned int l=1; l<k; l++){
186  for(unsigned int m=0; m<l; m++){
187  TLorentzVector sum = rec_photons[j] + rec_photons[k] + rec_photons[l] + rec_photons[m];
188  mass_4gamma->Fill(sum.M());
189  }
190  }
191  }
192  }
193 
194  // pi+, pi- invariant mass. Loop over all possible combinations
195  for(unsigned int j=0; j<rec_piplus.size(); j++){
196  for(unsigned int k=0; k<rec_piminus.size(); k++){
197  mass_pip_pim->Fill( (rec_piplus[j] + rec_piminus[k]).M() );
198  }
199  }
200 
201  // Calculate Mandelstam t=(p1-p3)^2
202  if(rec_protons.size()==1){
203  TLorentzVector beam_photon = beam_photons.size()>0 ? MakeTLorentz(beam_photons[0], 0.0):TLorentzVector(0.0, 0.0, 0.0, 9.0);
204  TLorentzVector &proton = rec_protons[0];
205  TLorentzVector p3 = beam_photon + target - proton;
206  double t = (beam_photon - p3).Mag2();
207  t_pX->Fill(-t);
208  }
209 
210  pthread_mutex_unlock(&mutex);
211 
212  return NOERROR;
213 }
214 
215 //------------------
216 // MakeTLorentz
217 //------------------
219 {
220  // Create a ROOT TLorentzVector object out of a Hall-D DKinematic Data object.
221  // Here, we have the mass passed in explicitly rather than use the mass contained in
222  // the DKinematicData object itself. This is because right now (Feb. 2009) the
223  // PID code is not mature enough to give reasonable guesses. See above code.
224 
225  double p = kd->momentum().Mag();
226  double theta = kd->momentum().Theta();
227  double phi = kd->momentum().Phi();
228  double px = p*sin(theta)*cos(phi);
229  double py = p*sin(theta)*sin(phi);
230  double pz = p*cos(theta);
231  double E = sqrt(mass*mass + p*p);
232 
233  return TLorentzVector(px,py,pz,E);
234 }
235 
236 //------------------
237 // erun
238 //------------------
240 {
241  return NOERROR;
242 }
243 
244 //------------------
245 // fini
246 //------------------
248 {
249  // Histograms are automatically written to file by hd_root program (or equivalent)
250  // so we don't need to do anything here.
251 
252  return NOERROR;
253 }
void setMomentum(const DVector3 &aMomentum)
jerror_t init(void)
Invoked via DEventProcessor virtual method.
TVector3 DVector3
Definition: DVector3.h:14
InitPlugin_t InitPlugin
TLorentzVector MakeTLorentz(const DKinematicData *track, double mass)
jerror_t fini(void)
Invoked via DEventProcessor virtual method.
jerror_t evnt(JEventLoop *loop, uint64_t eventnumber)
Invoked via DEventProcessor virtual method.
double charge(void) const
TH1D * py[NCHANNELS]
double sqrt(double)
double sin(double)
const DVector3 & momentum(void) const
jerror_t erun(void)
Invoked via DEventProcessor virtual method.
void setPosition(const DVector3 &aPosition)
TDirectory * dir
Definition: bcal_hist_eff.C:31
double mass(void) const