Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventProcessor_track_hists.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DEventProcessor_track_hists.cc
4 // Created: Sun Apr 24 06:45:21 EDT 2005
5 // Creator: davidl (on Darwin Harriet.local 7.8.0 powerpc)
6 //
7 
8 #include <iostream>
9 #include <iomanip>
10 #include <cmath>
11 using namespace std;
12 
14 
15 #include <TROOT.h>
16 #include <TVector3.h>
17 
18 #include <JANA/JApplication.h>
19 #include <JANA/JEventLoop.h>
20 
21 #include <DANA/DApplication.h>
22 #include <TRACKING/DMCThrown.h>
23 #include <TRACKING/DMCTrackHit.h>
26 #include <PID/DParticle.h>
27 #include <FDC/DFDCGeometry.h>
28 #include <CDC/DCDCTrackHit.h>
29 #include <FDC/DFDCPseudo.h>
30 #include <HDGEOMETRY/DGeometry.h>
31 #include <PID/DChargedTrack.h>
33 #include <DVector2.h>
34 #include <particleType.h>
35 
36 
37 // Routine used to create our DEventProcessor
38 extern "C"{
39 void InitPlugin(JApplication *app){
40  InitJANAPlugin(app);
41  app->AddProcessor(new DEventProcessor_track_hists());
42 }
43 } // "C"
44 
45 
46 //------------------
47 // DEventProcessor_track_hists
48 //------------------
50 {
51  cdchit_ptr = &cdchit;
52  fdchit_ptr = &fdchit;
53  trk_ptr = &trk;
54 
55  target.origin.SetXYZ(0.0, 0.0, 65.0);
56  target.sdir.SetXYZ(1.0, 0.0, 0.0);
57  target.tdir.SetXYZ(0.0, 1.0, 0.0);
58  target.udir.SetXYZ(0.0, 0.0, 1.0);
59  target.L = 30.0;
60 
61  pthread_mutex_init(&mutex, NULL);
62 
63  NLRgood = 0;
64  NLRbad = 0;
65  NLRfit_unknown = 0;
66  Nevents = 0;
67 
68 
69 }
70 
71 //------------------
72 // ~DEventProcessor_track_hists
73 //------------------
75 {
76 
77 }
78 
79 //------------------
80 // init
81 //------------------
83 {
84  // Create TRACKING directory
85  TDirectory *dir = (TDirectory*)gROOT->FindObject("TRACKING");
86  if(!dir)dir = new TDirectoryFile("TRACKING","TRACKING");
87  dir->cd();
88 
89  cdchits = new TTree("cdchit","CDC hits");
90  cdchits->Branch("cdchit","dchit",&cdchit_ptr);
91 
92  fdchits = new TTree("fdchit","FDC hits");
93  fdchits->Branch("fdchit","dchit",&fdchit_ptr);
94 
95  ttrack = new TTree("track","Track");
96  ttrack->Branch("track","trackpar",&trk_ptr);
97 
98  dir->cd("../");
99 
100  return NOERROR;
101 }
102 
103 //------------------
104 // brun
105 //------------------
106 jerror_t DEventProcessor_track_hists::brun(JEventLoop *loop, int32_t runnumber)
107 {
108  DApplication* dapp = dynamic_cast<DApplication*>(loop->GetJApplication());
109  if(!dapp){
110  _DBG_<<"Cannot get DApplication from JEventLoop! (are you using a JApplication based program perhaps?)"<<endl;
111  return RESOURCE_UNAVAILABLE;
112  }
113  lorentz_def=dapp->GetLorentzDeflections();
114 
115  return NOERROR;
116 }
117 
118 //------------------
119 // erun
120 //------------------
122 {
123 
124  return NOERROR;
125 }
126 
127 //------------------
128 // fini
129 //------------------
131 {
132  char str[256];
133  sprintf(str,"%3.4f%%", 100.0*(double)NLRbad/(double)(NLRbad+NLRgood));
134 
135  cout<<endl<<setprecision(4);
136  cout<<" NLRgood: "<<NLRgood<<endl;
137  cout<<" NLRbad: "<<NLRbad<<endl;
138  cout<<" NLRfit==0: "<<NLRfit_unknown<<endl;
139  cout<<"Percentage bad: "<<str<<endl;
140  cout<<" Nevents: "<<Nevents<<endl;
141  cout<<endl;
142 
143  return NOERROR;
144 }
145 
146 //------------------
147 // evnt
148 //------------------
149 jerror_t DEventProcessor_track_hists::evnt(JEventLoop *loop, uint64_t eventnumber)
150 {
151  vector<const DChargedTrack*> chargedtracks;
152  vector<const DTrackCandidate*> candidates;
153  vector<const DMCThrown*> mcthrowns;
154  vector<const DMCTrackHit*> mctrackhits;
155 
156  loop->Get(chargedtracks);
157  loop->Get(candidates);
158  loop->Get(mcthrowns);
159  loop->Get(mctrackhits);
160 
161  Nevents++;
162 
163  // Only look at events with one thrown and one reconstructed particle
164  if(chargedtracks.size() <1 || mcthrowns.size() !=1 || candidates.size()<1 || chargedtracks[0]->hypotheses.size()<1){
165  _DBG_<<"chargedtracks.size()="<<chargedtracks.size()<<" mcthrowns.size()="<<mcthrowns.size()<<" candidates.size()="<<candidates.size()<<endl;
166  return NOERROR;
167  }
168  const DTrackCandidate *candidate = candidates[0]; // technically, this could have more than 1 candidate!
169  const DMCThrown *thrown = mcthrowns[0];
170  const DTrackTimeBased* recon = chargedtracks[0]->hypotheses[0];;
171 
172  // Loop over found reconstructed particles looking for best match to thrown
173  int min_chisq=1.0E8;
174  DVector3 mc_mom = thrown->momentum();
175  for(unsigned int i=0; i<chargedtracks.size(); i++){
176  if(chargedtracks[i]->hypotheses.size()<1)continue;
177  DVector3 mom = chargedtracks[i]->hypotheses[0]->momentum();
178 
179  if(mom.Mag()<1.0E-9)continue; // Thrown momentum should be > 1eV/c
180 
181  // Round-off errors can cause cos_phi to be outside the allowed range of -1 to +1
182  // Force it to be inside that range in necessary.
183  double cos_phi = mom.Dot(mc_mom)/mom.Mag()/mc_mom.Mag();
184  if(cos_phi>1.)cos_phi=1.0;
185  if(cos_phi<-1.)cos_phi=-1.0;
186 
187  double delta_pt = (mom.Pt()-mc_mom.Pt())/mc_mom.Pt();
188  double delta_theta = (mom.Theta() - mc_mom.Theta())*1000.0; // in milliradians
189  double delta_phi = acos(cos_phi)*1000.0; // in milliradians
190  double chisq = pow(delta_pt/0.04, 2.0) + pow(delta_theta/20.0, 2.0) + pow(delta_phi/20.0, 2.0);
191 
192  if(chisq<min_chisq){
193  min_chisq = chisq;
194  recon = chargedtracks[i]->hypotheses[0];
195  }
196  }
197 
198  // Get CDC and FDC hits for reconstructed particle
199  vector<const DCDCTrackHit *> cdctrackhits;
200  vector<const DFDCPseudo *> fdcpseudohits;
201  recon->Get(cdctrackhits);
202  recon->Get(fdcpseudohits);
203 
204  // Here, we need to cast away the const-ness of the DReferenceTrajectory so we
205  // can use it to find DOCA points for each wire. This is OK to do here even
206  // outside of the mutex lock.
207  DReferenceTrajectory *rt = const_cast<DReferenceTrajectory*>(recon->rt);
208 
209  // Although we are only filling objects local to this plugin, TTree::Fill() periodically writes to file: Global ROOT lock
210  japp->RootWriteLock(); //ACQUIRE ROOT LOCK
211 
212  // Loop over CDC hits
213  int NLRcorrect_this_track = 0;
214  int NLRincorrect_this_track = 0;
215  for(unsigned int i=0; i<cdctrackhits.size(); i++){
216  const DCDCTrackHit *cdctrackhit = cdctrackhits[i];
217 
218  // The hit info structure is used to pass info both in and out of FindLR()
219  hit_info_t hit_info;
220  hit_info.rt = (DReferenceTrajectory*)rt;
221  hit_info.wire = cdctrackhit->wire;
222  hit_info.tdrift = cdctrackhit->tdrift;
223  hit_info.FindLR(mctrackhits);
224  cdchit.eventnumber = eventnumber;
225  cdchit.wire = cdctrackhit->wire->straw;
226  cdchit.layer = cdctrackhit->wire->ring;
227  cdchit.t = cdctrackhit->tdrift;
228  cdchit.tof = hit_info.tof;
229  cdchit.doca = hit_info.doca;
230  cdchit.resi = hit_info.dist - hit_info.doca;
231  cdchit.u = 0.0;
232  cdchit.u_pseudo = 0.0;
233  cdchit.u_lorentz = 0.0;
234  cdchit.resic = 0.0;
235  cdchit.trk_chisq = recon->chisq;
236  cdchit.trk_Ndof = recon->Ndof;
237  cdchit.LRis_correct = hit_info.LRis_correct;
238  cdchit.LRfit = hit_info.LRfit;
239  cdchit.pos_doca = hit_info.pos_doca;
240  cdchit.pos_wire = hit_info.pos_wire;
241 
242  cdchits->Fill();
243 
244  if(cdchit.LRfit!=0){
245  if(cdchit.LRis_correct){
246  NLRcorrect_this_track++;
247  NLRgood++;
248  }else{
249  NLRincorrect_this_track++;
250  NLRbad++;
251  }
252  }else{
253  NLRfit_unknown++;
254  }
255 
256  }
257 
258 #if 1
259  // Loop over FDC hits
260  for(unsigned int i=0; i<fdcpseudohits.size(); i++){
261  const DFDCPseudo *fdcpseudohit = fdcpseudohits[i];
262 
263  // Lorentz corrected poisition along the wire is contained in x,y values.
264  //DVector3 wpos(fdcpseudohit->x, fdcpseudohit->y, fdcpseudohit->wire->origin.Z());
265  //DVector3 wdiff = wpos - fdcpseudohit->wire->origin;
266  //double u_corr = fdcpseudohit->wire->udir.Dot(wdiff);
267 
268  // The hit info structure is used to pass info both in and out of FindLR()
269  hit_info_t hit_info;
270  hit_info.rt = (DReferenceTrajectory*)rt;
271  hit_info.wire = fdcpseudohit->wire;
272  hit_info.tdrift = fdcpseudohit->time;
273  hit_info.FindLR(mctrackhits, lorentz_def);
274 
275  fdchit.eventnumber = eventnumber;
276  fdchit.wire = fdcpseudohit->wire->wire;
277  fdchit.layer = fdcpseudohit->wire->layer;
278  fdchit.t = fdcpseudohit->time;
279  fdchit.tof = hit_info.tof;
280  fdchit.doca = hit_info.doca;
281  fdchit.resi = hit_info.dist - hit_info.doca;
282  fdchit.u = hit_info.u;
283  fdchit.u_pseudo = fdcpseudohit->s;
284  fdchit.u_lorentz = hit_info.u_lorentz;
285  fdchit.resic = hit_info.u - (fdcpseudohit->s + hit_info.u_lorentz) ;
286  fdchit.trk_chisq = recon->chisq;
287  fdchit.trk_Ndof = recon->Ndof;
288  fdchit.LRis_correct = hit_info.LRis_correct;
289  fdchit.LRfit = hit_info.LRfit;
290  fdchit.pos_doca = hit_info.pos_doca;
291  fdchit.pos_wire = hit_info.pos_wire;
292 
293  fdchits->Fill();
294 
295  if(fdchit.LRfit!=0){
296  if(fdchit.LRis_correct){
297  NLRcorrect_this_track++;
298  NLRgood++;
299  }else{
300  NLRincorrect_this_track++;
301  NLRbad++;
302  }
303  }else{
304  NLRfit_unknown++;
305  }
306  }
307 #endif
308 
309  // Find the z vertex position of fit track using reference trajectory
310  double doca_tgt = rt->DistToRT(&target);
311  DVector3 tgt_doca = rt->GetLastDOCAPoint();
312 
313  // Convert some DVector3 objects into TVector3 objects
314  DVector3 tmp = thrown->momentum();
315  TVector3 thrown_mom(tmp.X(), tmp.Y(), tmp.Z());
316  tmp = recon->momentum();
317  TVector3 recon_mom(tmp.X(), tmp.Y(), tmp.Z());
318  tmp = thrown->position();
319  TVector3 thrown_pos(tmp.X(), tmp.Y(), tmp.Z());
320  tmp = candidate->position();
321  TVector3 can_pos(tmp.X(), tmp.Y(), tmp.Z());
322 
323  // Fill in track tree
324  trk.eventnumber = eventnumber;
325  trk.pthrown = thrown_mom;
326  trk.pfit = recon_mom;
327  trk.z_thrown = thrown_pos.Z();
328  trk.z_fit = tgt_doca.Z();
329  trk.z_can = can_pos.Z();
330  trk.r_fit = doca_tgt;
331  trk.NLRcorrect = NLRcorrect_this_track;
332  trk.NLRincorrect = NLRincorrect_this_track;
333 
334  ttrack->Fill();
335 
336  japp->RootUnLock(); //RELEASE ROOT LOCK
337 
338  return NOERROR;
339 }
340 
341 //------------------
342 // FindLR
343 //------------------
344 void DEventProcessor_track_hists::hit_info_t::FindLR(vector<const DMCTrackHit*> &mctrackhits, const DLorentzDeflections *lorentz_def)
345 {
346  /// Decided on whether or not the reference trajectory is on the correct side of the wire
347  /// based on truth information.
348  ///
349  /// Upon entry, the rt, wire, and rdrift members should be set. The remaining fields are
350  /// filled in on return from this method.
351  ///
352  /// Essentially, this will look through the DMCTrackHit objects via the
353  /// DTrackHitSelectorTHROWN::GetMCTrackHit method to find the truth point corresponding
354  /// to this hit (if any). It then compares the vector pointing from the point of
355  /// closest approach on the wire to the DOCA point so a similar vector pointing
356  /// from the same place on the wire to the truth point. If the 2 vectors are within
357  /// +/- 90 degrees, then the trajectory is said to be on the correct side of the wire.
358 
359  DVector3 pos_doca_dvec3(pos_doca.X(), pos_doca.Y(), pos_doca.Z());
360  DVector3 mom_doca_dvec3(mom_doca.X(), mom_doca.Y(), mom_doca.Z());
361 
362  double s;
363  doca = rt->DistToRT(wire, &s);
364  rt->GetLastDOCAPoint(pos_doca_dvec3, mom_doca_dvec3);
365  DVector3 shift = wire->udir.Cross(mom_doca_dvec3);
366  u = rt->GetLastDistAlongWire();
367  DVector3 pos_wire_devc3 = wire->origin + u*wire->udir;
368  pos_wire.SetXYZ(pos_wire_devc3.X(), pos_wire_devc3.Y(), pos_wire_devc3.Z());
369 
370  // Estimate TOF assuming pion
371  double mass = 0.13957;
372  double beta = 1.0/sqrt(1.0 + pow(mass/mom_doca.Mag(), 2.0))*2.998E10;
373  tof = s/beta/1.0E-9; // in ns
374  dist = (tdrift - tof)*55E-4;
375 
376  // Find the Lorentz correction based on current track (if applicable)
377  if(lorentz_def){
378  DVector3 shift = wire->udir.Cross(mom_doca_dvec3);
379  shift.SetMag(1.0);
380  double LRsign = shift.Dot(pos_doca_dvec3-pos_wire_devc3)<0.0 ? +1.0:-1.0;
381  double alpha = mom_doca.Angle(TVector3(0,0,1));
382  u_lorentz = LRsign*lorentz_def->GetLorentzCorrection(pos_doca.X(), pos_doca.Y(), pos_doca.Z(), alpha, dist);
383  }else{
384  u_lorentz = 0.0;
385  }
386 
387  // Look for a truth hit corresponding to this wire. If none is found, mark the hit as
388  // 0 (i.e. neither left nor right) and continue to the next hit.
389  const DMCTrackHit *mctrackhit = DTrackHitSelectorTHROWN::GetMCTrackHit(wire, dist, mctrackhits);
390  if(!mctrackhit){
391  LRfit = 0;
392  LRis_correct = false; // can't really tell what to set this to
393  }else{
394  TVector3 pos_truth(mctrackhit->r*cos(mctrackhit->phi), mctrackhit->r*sin(mctrackhit->phi), mctrackhit->z);
395  TVector3 pos_diff_truth = pos_truth-pos_wire;
396  TVector3 pos_diff_traj = pos_doca-pos_wire;
397 
398  TVector3 shift_tvec3(shift.X(), shift.Y(), shift.Z());
399  LRfit = shift_tvec3.Dot(pos_diff_traj)<0.0 ? -1:1;
400  LRis_correct = pos_diff_truth.Dot(pos_diff_traj)>0.0;
401  }
402 }
403 
DApplication * dapp
float chisq
Chi-squared for the track (not chisq/dof!)
const DCDCWire * wire
Definition: DCDCTrackHit.h:37
char str[256]
TVector3 DVector3
Definition: DVector3.h:14
sprintf(text,"Post KinFit Cut")
DVector3 GetLastDOCAPoint(void) const
const DVector3 & position(void) const
const DFDCWire * wire
DFDCWire for this wire.
Definition: DFDCPseudo.h:92
DLorentzDeflections * GetLorentzDeflections(unsigned int run_number=1)
class DFDCPseudo: definition for a reconstructed point in the FDC
Definition: DFDCPseudo.h:74
static const DMCTrackHit * GetMCTrackHit(const DCoordinateSystem *wire, double rdrift, vector< const DMCTrackHit * > &mctrackhits, int trackno_filter=-1)
jerror_t brun(JEventLoop *loop, int32_t runnumber)
JApplication * japp
int layer
1-24
Definition: DFDCWire.h:16
double DistToRT(double x, double y, double z) const
const double alpha
float z
coordinates of hit in cm and rad
Definition: DMCTrackHit.h:20
jerror_t evnt(JEventLoop *loop, uint64_t eventnumber)
Invoked via DEventProcessor virtual method.
InitPlugin_t InitPlugin
int straw
Definition: DCDCWire.h:81
#define _DBG_
Definition: HDEVIO.h:12
double s
&lt; wire position computed from cathode data, assuming the avalanche occurs at the wire ...
Definition: DFDCPseudo.h:91
void FindLR(vector< const DMCTrackHit * > &mctrackhits, const DLorentzDeflections *lorentz_def=NULL)
int Ndof
Number of degrees of freedom in the fit.
&lt;A href=&quot;index.html#legend&quot;&gt; &lt;IMG src=&quot;CORE.png&quot; width=&quot;100&quot;&gt; &lt;/A&gt;
double time
time corresponding to this pseudopoint.
Definition: DFDCPseudo.h:93
jerror_t fini(void)
Invoked via DEventProcessor virtual method.
double sqrt(double)
double GetLorentzCorrection(double x, double y, double z, double alpha, double dx) const
double sin(double)
double Nevents
const DVector3 & momentum(void) const
int wire
1-N
Definition: DFDCWire.h:17
int ring
Definition: DCDCWire.h:80
jerror_t erun(void)
Invoked via DEventProcessor virtual method.
jerror_t init(void)
Invoked via DEventProcessor virtual method.
TDirectory * dir
Definition: bcal_hist_eff.C:31
union @6::@8 u