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