Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_FDC_Efficiency.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: JEventProcessor_FDC_Efficiency.cc
4 // Created: Thu May 26 15:57:38 EDT 2016
5 // Creator: aaustreg
6 //
7 
9 using namespace jana;
11 #include "HistogramTools.h"
12 
13 static TH1D *fdc_wire_measured_cell[25]; //Filled with total actually detected before division at end
14 static TH1D *fdc_wire_expected_cell[25]; // Contains total number of expected hits by DOCA
15 
16 static TH2D *fdc_pseudo_measured_cell[25]; //Filled with total actually detected before division at end
17 static TH2D *fdc_pseudo_expected_cell[25]; // Contains total number of expected hits by DOCA
18 
19 //For extraction of magnetic field slope, split the detectors into bins in radius
20 const unsigned int rad = 1; // 1, 5 or 9
21 
22 static TH1I *hChi2OverNDF;
23 static TH1I *hChi2OverNDF_accepted;
24 static TH1I *hPseudoRes;
25 // static TH1I *hPseudoResX[25];
26 // static TH1I *hPseudoResY[25];
27 static TH1I *hPseudoResU[25];
28 static TH1I *hPseudoResV[25];
29 static TH2I *hPseudoResUvsV[25][rad];
30 static TH2I *hPseudoResVsT[25];
31 static TH2I *hResVsT[25];
32 static TH1I *hMom;
33 static TH1I *hMom_accepted;
34 static TH1I *hTheta;
35 static TH1I *hTheta_accepted;
36 static TH1I *hPhi;
37 static TH1I *hPhi_accepted;
38 static TH1I *hCellsHit;
39 static TH1I *hCellsHit_accepted;
40 static TH1I *hRingsHit;
41 static TH1I *hRingsHit_accepted;
42 static TH2I *hRingsHit_vs_P;
43 
44 static TH1I *hWireTime[25];
45 static TH1I *hWireTime_accepted[25];
46 static TH1I *hCathodeTime[25];
47 static TH1I *hCathodeTime_accepted[25];
48 static TH1I *hPseudoTime[25];
49 static TH1I *hPseudoTime_accepted[25];
50 static TH1I *hPullTime[25];
51 static TH1I *hDeltaTime[25];
52 
53 // Routine used to create our JEventProcessor
54 #include <JANA/JApplication.h>
55 #include <JANA/JFactory.h>
56 extern "C"{
57 void InitPlugin(JApplication *app){
58  InitJANAPlugin(app);
59  app->AddProcessor(new JEventProcessor_FDC_Efficiency());
60 }
61 } // "C"
62 
63 
64 //------------------
65 // JEventProcessor_FDC_Efficiency (Constructor)
66 //------------------
68 {
69  ;
70 }
71 
72 //------------------
73 // ~JEventProcessor_FDC_Efficiency (Destructor)
74 //------------------
76 {
77  ;
78 }
79 
80 //------------------
81 // init
82 //------------------
84 {
85  // create root folder for fdc and cd to it, store main dir
86  TDirectory *main = gDirectory;
87  gDirectory->mkdir("FDC_Efficiency")->cd();
88  gDirectory->mkdir("FDC_View")->cd();
89 
90  for(int icell=0; icell<24; icell++){
91 
92  char hname_measured[256];
93  char hname_expected[256];
94  sprintf(hname_measured, "fdc_wire_measured_cell[%d]", icell+1);
95  sprintf(hname_expected, "fdc_wire_expected_cell[%d]", icell+1);
96  fdc_wire_measured_cell[icell+1] = new TH1D(hname_measured, "", 96, 0.5, 96.5);
97  fdc_wire_expected_cell[icell+1] = new TH1D(hname_expected, "", 96, 0.5, 96.5);
98 
99  sprintf(hname_measured, "fdc_pseudo_measured_cell[%d]", icell+1);
100  sprintf(hname_expected, "fdc_pseudo_expected_cell[%d]", icell+1);
101  fdc_pseudo_measured_cell[icell+1] = new TH2D(hname_measured, "", 100, -50, 50, 100, -50, 50);
102  fdc_pseudo_expected_cell[icell+1] = new TH2D(hname_expected, "", 100, -50, 50, 100, -50, 50);
103 
104  }
105 
106  gDirectory->cd("/FDC_Efficiency");
107  gDirectory->mkdir("Track_Quality")->cd();
108  hChi2OverNDF = new TH1I("hChi2OverNDF","hChi2OverNDF", 500, 0.0, 1.0);
109  hChi2OverNDF_accepted = new TH1I("hChi2OverNDF_accepted","hChi2OverNDF_accepted", 500, 0.0, 1.0);
110  hMom = new TH1I("hMom","Momentum", 500, 0.0, 10);
111  hMom_accepted = new TH1I("hMom_accepted","Momentum (accepted)", 500, 0.0, 10);
112  hTheta = new TH1I("hTheta","Theta of Track", 500, 0.0, 50);
113  hTheta_accepted = new TH1I("hTheta_accepted","Theta of Track (accepted)", 500, 0.0, 50);
114  hPhi = new TH1I("hPhi","Phi of Track", 360, -180, 180);
115  hPhi_accepted = new TH1I("hPhi_accepted","Phi of Track (accepted)", 360, -180, 180);
116  hCellsHit = new TH1I("hCellsHit", "Cells of FDC Contributing to Track", 25, -0.5, 24.5);
117  hCellsHit_accepted = new TH1I("hCellsHit_accepted", "Cells of FDC Contributing to Track (accepted)", 25, -0.5, 24.5);
118  hRingsHit = new TH1I("hRingsHit", "Rings of CDC Contributing to Track", 29, -0.5, 28.5);
119  hRingsHit_accepted = new TH1I("hRingsHit_accepted", "Rings of CDC Contributing to Track (accepted)", 25, -0.5, 24.5);
120 
121  hRingsHit_vs_P = new TH2I("hRingsHit_vs_P", "Rings of CDC Contributing to Track vs P (accepted)", 25, -0.5, 24.5, 34, 0.6, 4);
122 
123  gDirectory->cd("/FDC_Efficiency");
124  gDirectory->mkdir("Residuals")->cd();
125  hPseudoRes = new TH1I("hPseudoRes","Pseudo Residual in R", 500, 0, 5);
126 
127  for(int icell=0; icell<24; icell++){
128 
129  char hname_X[256];
130  char hname_Y[256];
131  char hname_XY[256];
132 
133  // sprintf(hname_X, "hPseudoResX_cell[%d]", icell+1);
134  // sprintf(hname_Y, "hPseudoResY_cell[%d]", icell+1);
135  // hPseudoResX[icell+1] = new TH1I(hname_X,"Pseudo Residual in X", 600, -3, 3);
136  // hPseudoResY[icell+1] = new TH1I(hname_Y,"Pseudo Residual in Y", 600, -3, 3);
137 
138  sprintf(hname_X, "hPseudoResU_cell[%d]", icell+1);
139  sprintf(hname_Y, "hPseudoResV_cell[%d]", icell+1);
140  hPseudoResU[icell+1] = new TH1I(hname_X,"Pseudo Residual along Wire", 600, -3, 3);
141  hPseudoResV[icell+1] = new TH1I(hname_Y,"Pseudo Residual perp. to Wire", 600, -3, 3);
142  for (unsigned int r=0; r<rad; r++){
143  sprintf(hname_XY, "hPseudoResUvsV_cell[%d]_radius[%d]", icell+1, (r+1)*45/rad);
144  hPseudoResUvsV[icell+1][r] = new TH2I(hname_XY,"Pseudo Residual 2D", 200, -1, 1, 200, -1, 1);
145  }
146 
147  sprintf(hname_X, "hResVsT_cell[%d]", icell+1);
148  sprintf(hname_Y, "hPseudoResVsT[%d]", icell+1);
149  hResVsT[icell+1] = new TH2I(hname_X,"Tracking Residual (Biased) Vs Wire Drift Time; DOCA (cm); Drift Time (ns)", 100, 0, 0.5, 400, -100, 300);
150  hPseudoResVsT[icell+1] = new TH2I(hname_Y,"Tracking Residual (Biased) Vs Pseudo Time; Residual (cm); Drift Time (ns)", 200, -0.5, 0.5, 400, -100, 300);
151 
152  sprintf(hname_X, "hWireTime_cell[%d]", icell+1);
153  sprintf(hname_Y, "hWireTime_acc_cell[%d]", icell+1);
154  hWireTime[icell+1] = new TH1I(hname_X, "Timing of Hits", 600, -200, 400);
155  hWireTime_accepted[icell+1] = new TH1I(hname_Y, "Timing of Hits (accepted)", 600, -200, 400);
156 
157  sprintf(hname_X, "hCathodeTime_cell[%d]", icell+1);
158  sprintf(hname_Y, "hCathodeTime_acc_cell[%d]", icell+1);
159  hCathodeTime[icell+1] = new TH1I(hname_X, "Timing of Cathode Clusters", 600, -200, 400);
160  hCathodeTime_accepted[icell+1] = new TH1I(hname_Y, "Timing of Cathode Clusters (accepted)", 600, -200, 400);
161 
162  sprintf(hname_X, "hPseudoTime_cell[%d]", icell+1);
163  sprintf(hname_Y, "hPseudoTime_acc_cell[%d]", icell+1);
164  hPseudoTime[icell+1] = new TH1I(hname_X, "Timing of Pseudos", 600, -200, 400);
165  hPseudoTime_accepted[icell+1] = new TH1I(hname_Y, "Timing of Pseudos (accepted)", 600, -200, 400);
166 
167  sprintf(hname_X, "hPullTime_cell[%d]", icell+1);
168  hPullTime[icell+1] = new TH1I(hname_X, "Timing of Wire Hits (from pulls)", 600, -200, 400);
169 
170  sprintf(hname_X, "hDeltaTime_cell[%d]", icell+1);
171  hDeltaTime[icell+1] = new TH1I(hname_X, "Time Difference between Wires and Cathode Clusters", 200, -50, 50);
172 
173  }
174 
175  main->cd();
176 
177  return NOERROR;
178 }
179 
180 //------------------
181 // brun
182 //------------------
183 jerror_t JEventProcessor_FDC_Efficiency::brun(JEventLoop *eventLoop, int32_t runnumber)
184 {
185  // This is called whenever the run number changes
186  DApplication* dapp=dynamic_cast<DApplication*>(eventLoop->GetJApplication());
187  dIsNoFieldFlag = (dynamic_cast<const DMagneticFieldMapNoField*>(dapp->GetBfield(runnumber)) != NULL);
188  //JCalibration *jcalib = dapp->GetJCalibration(runnumber);
189  dgeom = dapp->GetDGeometry(runnumber);
190  //bfield = dapp->GetBfield();
191 
192  // Get the position of the FDC wires from DGeometry
193  dgeom->GetFDCWires(fdcwires);
194 
195  // Get the z position of the FDC planes from DGeometry
196  dgeom->GetFDCZ(fdcz);
197 
198  // Get inner radii for FDC packages
199  dgeom->GetFDCRmin(fdcrmin);
200 
201  // Get outer radius of FDC
202  dgeom->GetFDCRmax(fdcrmax);
203  fdcrmax = 48; // fix to 48cm from DFDCPseudo_factory
204 
205  return NOERROR;
206 }
207 
208 //------------------
209 // evnt
210 //------------------
211 jerror_t JEventProcessor_FDC_Efficiency::evnt(JEventLoop *loop, uint64_t eventnumber){
212 
213  vector< const DFDCHit *> locFDCHitVector;
214  loop->Get(locFDCHitVector);
215  vector< const DFDCPseudo *> locFDCPseudoVector;
216  loop->Get(locFDCPseudoVector);
217 
218  //Pre-sort Hits to save time
219  //only need to search within the given cell, wire
220  map<int, map<int, set<const DFDCHit*> > > locSortedFDCHits; //first int: cell //second int: wire
221  for( unsigned int hitNum = 0; hitNum < locFDCHitVector.size(); hitNum++){
222  const DFDCHit * locHit = locFDCHitVector[hitNum];
223  if (locHit->plane != 2) continue; // only wires!
224 
225  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
226  hWireTime[locHit->gLayer]->Fill(locHit->t);
227  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
228 
229  // cut on timing of hits
230  //if (-100 > locHit->t || locHit->t > 300) continue;
231 
232  locSortedFDCHits[locHit->gLayer][locHit->element].insert(locHit);
233 
234  }
235 
236  //Pre-sort PseudoHits to save time
237  //only need to search within the given cell
238  map<int, set<const DFDCPseudo*> > locSortedFDCPseudos; // int: cell
239  for( unsigned int hitNum = 0; hitNum < locFDCPseudoVector.size(); hitNum++){
240  const DFDCPseudo * locPseudo = locFDCPseudoVector[hitNum];
241  locSortedFDCPseudos[locPseudo->wire->layer].insert(locPseudo);
242 
243  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
244  hPseudoTime[locPseudo->wire->layer]->Fill(locPseudo->time);
245  hCathodeTime[locPseudo->wire->layer]->Fill(locPseudo->t_u);
246  hCathodeTime[locPseudo->wire->layer]->Fill(locPseudo->t_v);
247  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
248 
249  }
250 
251  const DDetectorMatches *detMatches;
252  vector<shared_ptr<const DSCHitMatchParams>> SCMatches;
253  vector<shared_ptr<const DTOFHitMatchParams>> TOFMatches;
254  vector<shared_ptr<const DBCALShowerMatchParams>> BCALMatches;
255 
256  if(!dIsNoFieldFlag){
257  loop->GetSingle(detMatches);
258  }
259 
260  vector <const DChargedTrack *> chargedTrackVector;
261  loop->Get(chargedTrackVector);
262 
263  for (unsigned int iTrack = 0; iTrack < chargedTrackVector.size(); iTrack++){
264 
265  const DChargedTrackHypothesis* bestHypothesis = chargedTrackVector[iTrack]->Get_BestTrackingFOM();
266 
267  // Cut very loosely on the track quality
268  auto thisTimeBasedTrack = bestHypothesis->Get_TrackTimeBased();
269 
270  // First loop over the FDC/CDC hits of the track to find out how many cells/rings were hit
271  // For the first track selection, use already pseudo hits from fdc
272  // Determine how many cells (FDC) and rings (CDC) contribute to track in total, and in which package
273  vector< int > cellsHit;
274  vector< int > ringsHit;
275  vector<DTrackFitter::pull_t> pulls = thisTimeBasedTrack->pulls;
276  for (unsigned int i = 0; i < pulls.size(); i++){
277  const DFDCPseudo * thisTrackFDCHit = pulls[i].fdc_hit;
278  if (thisTrackFDCHit != NULL){
279  hPullTime[thisTrackFDCHit->wire->layer]->Fill(pulls[i].tdrift);
280  if ( find(cellsHit.begin(), cellsHit.end(), thisTrackFDCHit->wire->layer) == cellsHit.end())
281  cellsHit.push_back(thisTrackFDCHit->wire->layer);
282  }
283 
284  const DCDCTrackHit * thisTrackCDCHit = pulls[i].cdc_hit;
285  if (thisTrackCDCHit != NULL){
286  if ( find(ringsHit.begin(), ringsHit.end(), thisTrackCDCHit->wire->ring) == ringsHit.end())
287  ringsHit.push_back(thisTrackCDCHit->wire->ring);
288  }
289  }
290  unsigned int cells = cellsHit.size();
291  unsigned int rings = ringsHit.size();
292 
293  if (cells == 0) continue;
294 
295  double theta_deg = thisTimeBasedTrack->momentum().Theta()*TMath::RadToDeg();
296  double phi_deg = thisTimeBasedTrack->momentum().Phi()*TMath::RadToDeg();
297  double tmom = thisTimeBasedTrack->pmag();
298 
299  // Fill Histograms for all Tracks
300  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
301  hCellsHit->Fill(cells);
302  hRingsHit->Fill(rings);
303  hChi2OverNDF->Fill(thisTimeBasedTrack->FOM);
304  hMom->Fill(tmom);
305  hTheta->Fill(theta_deg);
306  hPhi->Fill(phi_deg);
307  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
308 
309  // All Cuts on Track Quality:
310 
311  // if (thisTimeBasedTrack->FOM < 5.73303E-7)
312  // continue; // 5 sigma cut from Paul
313  if (thisTimeBasedTrack->FOM < 1E-20)
314  continue; // from CDC analysis
315 
316  if(!dIsNoFieldFlag){ // Quality cuts for Field on runs.
317  if(tmom < 0.6)
318  continue; // Cut on the reconstructed momentum below 600MeV, no curlers
319 
320  // TRY TO IMPROVE RECONSTUCTION FOR LOW MOMENTA WITH CDC INFO, DISABLED
321  // Tuned on 1345A data, not tuned for 1200A
322  // if (tmom < 1.2 && rings < 12)
323  // continue; // for Low-Momentum Tracks < 2 GeV, check number of hits in CDC
324  // if (tmom < 1.4 && rings < 10)
325  // continue; // for Low-Momentum Tracks < 2 GeV, check number of hits in CDC
326  // if (tmom < 1.6 && rings < 8)
327  // continue; // for Low-Momentum Tracks < 2 GeV, check number of hits in CDC
328  // if (tmom < 1.8 && rings < 6)
329  // continue; // for Low-Momentum Tracks < 2 GeV, check number of hits in CDC
330  // if (tmom < 2 && rings < 4)
331  // continue; // for Low-Momentum Tracks < 2 GeV, check number of hits in CDC
332 
333 
334  if(!detMatches->Get_SCMatchParams(thisTimeBasedTrack, SCMatches)) {
335  continue; // At least one match to the Start Counter
336  }
337 
338  if(!detMatches->Get_TOFMatchParams(thisTimeBasedTrack, TOFMatches) && !detMatches->Get_BCALMatchParams(thisTimeBasedTrack,BCALMatches)) {
339  continue; // At least one match either to the Time-Of-Flight (forward) OR the BCAL (large angles)
340  }
341  }
342  else return NOERROR; // Field off not supported for now !!
343 
344  // count how many hits in each package (= 6 cells)
345  unsigned int packageHit[4] = {0,0,0,0};
346  for (unsigned int i = 0; i < cells; i++)
347  packageHit[(cellsHit[i] - 1) / 6]++;
348 
349  unsigned int minCells = 4; //At least 4 cells hit in any package for relatively "unbiased" efficiencies
350  if (packageHit[0] < minCells && packageHit[1] < minCells && packageHit[2] < minCells && packageHit[3] < minCells) continue;
351 
352  // Fill Histograms for accepted Tracks
353  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
354  hCellsHit_accepted->Fill(cells);
355  //if (tmom < 2)
356  hRingsHit_accepted->Fill(rings);
357  hChi2OverNDF_accepted->Fill(thisTimeBasedTrack->FOM);
358  hMom_accepted->Fill(tmom);
359  hTheta_accepted->Fill(theta_deg);
360  hPhi_accepted->Fill(phi_deg);
361  hRingsHit_vs_P->Fill(rings, tmom);
362  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
363 
364  // Start efficiency computation with these tracks
365 
366  // Loop over cells (24)
367  for (unsigned int cellIndex = 0; cellIndex < fdcwires.size(); cellIndex ++){
368  unsigned int cellNum = cellIndex +1;
369  vector< DFDCWire * > wireByNumber = fdcwires[cellIndex];
370 
371  // Use only tracks that have at least 4 (or other # of) hits in the package this cell is in
372  // OR 12 hits in total
373  if (packageHit[cellIndex / 6] < minCells /*&& cells < 12*/) continue;
374 
375  // Interpolate track to layer
376  DVector3 plane_origin(0.0, 0.0, fdcz[cellIndex]);
377  DVector3 plane_normal(0.0, 0.0, 1.0);
378  DVector3 interPosition,trackDirection;
379  vector<DTrackFitter::Extrapolation_t>extrapolations=thisTimeBasedTrack->extrapolations.at(SYS_FDC);
380  for (unsigned int i=0;i<extrapolations.size();i++){
381  double dz=plane_origin.z()-extrapolations[i].position.z();
382  if (fabs(dz)<0.5){
383  trackDirection=extrapolations[i].momentum;
384  trackDirection.SetMag(1.);
385  interPosition=extrapolations[i].position;
386  break;
387  }
388  }
389 
390  // cut out central hole and intersections at too large radii
391  int packageIndex = (cellNum - 1) / 6;
392  if (interPosition.Perp() < fdcrmin[packageIndex] || interPosition.Perp() > fdcrmax) continue;
393 
394 
395  /////////////////// WIRE ANALYSIS /////////////////////////////////
396 
397  for (unsigned int wireIndex = 0; wireIndex < wireByNumber.size(); wireIndex++){
398  unsigned int wireNum = wireIndex+1;
399  DFDCWire * wire = wireByNumber[wireIndex];
400  double dz=wire->origin.z()-interPosition.z();
401  interPosition+=(dz/trackDirection.z())*trackDirection;
402  double distanceToWire = (interPosition-wire->origin).Perp();
403  bool expectHit = false;
404 
405  // starting from here, only histograms with distance to wire < 0.5, maybe change later
406  if (distanceToWire < 0.5 )
407  expectHit = true;
408 
409  //SKIP IF NOT CLOSE (from Paul)
410  if(distanceToWire > 50.0)
411  {
412  wireIndex += 30;
413  continue;
414  }
415  if(distanceToWire > 20.0)
416  {
417  wireIndex += 10;
418  continue;
419  }
420  if(distanceToWire > 10.0)
421  {
422  wireIndex += 5;
423  continue;
424  }
425 
426 
427  if (expectHit && fdc_wire_expected_cell[cellNum] != NULL && cellNum < 25){
428  Fill1DHistogram("FDC_Efficiency", "Offline", "Expected Hits Vs DOCA", distanceToWire, "Expected Hits", 100, 0 , 0.5);
429  Fill1DHistogram("FDC_Efficiency", "Offline", "Expected Hits Vs Tracking FOM", thisTimeBasedTrack->FOM, "Expected Hits", 100, 0 , 1.0);
430  Fill1DHistogram("FDC_Efficiency", "Offline", "Expected Hits Vs theta", theta_deg, "Expected Hits", 100, 0, 180);
431  Fill1DHistogram("FDC_Efficiency", "Offline", "Expected Hits Vs phi", phi_deg, "Measured Hits", 100, -180, 180);
432  Fill1DHistogram("FDC_Efficiency", "Offline", "Expected Hits Vs p", tmom, "Expected Hits", 100, 0 , 10.0);
433  Fill1DHistogram("FDC_Efficiency", "Offline", "Expected Hits Vs Hit Cells", cells, "Expected Hits", 25, -0.5 , 24.5);
434 
435  Double_t w, v;
436  if(fdc_wire_expected_cell[cellNum] != NULL && cellNum < 25){
437  // FILL HISTOGRAMS
438  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
439  w = fdc_wire_expected_cell[cellNum]->GetBinContent(wireNum, 1) + 1.0;
440  fdc_wire_expected_cell[cellNum]->SetBinContent(wireNum, 1, w);
441  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
442  }
443 
444  // look in the presorted FDC Hits for a match
445  if(!locSortedFDCHits[cellNum][wireNum].empty() || !locSortedFDCHits[cellNum][wireNum-1].empty() || !locSortedFDCHits[cellNum][wireNum+1].empty()){
446  // Look not only in one wire, but also in adjacent ones (?)
447  // This can remove the dependence on the track error
448 
449  // Fill the histograms only for the cell in the center
450  if(!locSortedFDCHits[cellNum][wireNum].empty()){
451  // Loop over multiple hits in the wire
452  for(set<const DFDCHit*>::iterator locIterator = locSortedFDCHits[cellNum][wireNum].begin(); locIterator != locSortedFDCHits[cellNum][wireNum].end(); ++locIterator){
453  const DFDCHit* locHit = * locIterator;
454  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
455  hWireTime_accepted[cellNum]->Fill(locHit->t);
456  hResVsT[cellNum]->Fill(distanceToWire, locHit->t);
457  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
458  }
459  }
460 
461  Fill1DHistogram("FDC_Efficiency", "Offline", "Measured Hits Vs DOCA", distanceToWire, "Measured Hits", 100, 0 , 0.5);
462  Fill1DHistogram("FDC_Efficiency", "Offline", "Measured Hits Vs Tracking FOM", thisTimeBasedTrack->FOM, "Measured Hits", 100, 0 , 1.0);
463  Fill1DHistogram("FDC_Efficiency", "Offline", "Measured Hits Vs theta", theta_deg, "Measured Hits", 100, 0, 180);
464  Fill1DHistogram("FDC_Efficiency", "Offline", "Measured Hits Vs phi", phi_deg, "Measured Hits", 100, -180, 180);
465  Fill1DHistogram("FDC_Efficiency", "Offline", "Measured Hits Vs p", tmom, "Measured Hits", 100, 0 , 10.0);
466  Fill1DHistogram("FDC_Efficiency", "Offline", "Measured Hits Vs Hit Cells", cells, "Measured Hits", 25, -0.5 , 24.5);
467 
468  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
469  v = fdc_wire_measured_cell[cellNum]->GetBinContent(wireNum, 1) + 1.0;
470  fdc_wire_measured_cell[cellNum]->SetBinContent(wireNum, 1, v);
471  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
472  }
473 
474  break; // break if 1 expected hit was found, 2 are geometrically not possible (speedup!)
475 
476  } // End expected
477  } // End wire loop
478 
479  // END WIRE ANALYSIS
480 
481 
482 
483  ///////////// START PSEUDO ANALYSIS /////////////////////////////////////////
484 
485 
486  if(fdc_pseudo_expected_cell[cellNum] != NULL && cellNum < 25){
487  // FILL HISTOGRAMS
488  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
489  fdc_pseudo_expected_cell[cellNum]->Fill(interPosition.X(), interPosition.Y());
490  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
491  }
492 
493  bool foundPseudo = false;
494  if(!locSortedFDCPseudos[cellNum].empty()){
495 
496  set<const DFDCPseudo*>& locPlanePseudos = locSortedFDCPseudos[cellNum];
497  // loop over the FDC Pseudo Hits in that cell to look for a match
498  for(set<const DFDCPseudo*>::iterator locIterator = locPlanePseudos.begin(); locIterator != locPlanePseudos.end(); ++locIterator)
499  {
500  const DFDCPseudo * locPseudo = * locIterator;
501  if (locPseudo == NULL) continue;
502 
503  DVector2 pseudoPosition = locPseudo->xy;
504  DVector2 interPosition2D(interPosition.X(), interPosition.Y());
505 
506  DVector2 residual2D = (pseudoPosition - interPosition2D);
507  double residualR = residual2D.Mod();
508  // double residualX = pseudoPosition.X() - interPosition2D.X();
509  // double residualY = pseudoPosition.Y() - interPosition2D.Y();
510 
511  // rotate to wire coordinate system
512  const DFDCWire * wire = locPseudo->wire;
513  double residualU = -1*(residual2D.Rotate(wire->angle)).X();
514  double residualV = -1*(residual2D.Rotate(wire->angle)).Y();
515 
516  // these can be used for background studies/correction
517  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
518  hPseudoRes->Fill(residualR);
519  // hPseudoResX[cellNum]->Fill(residualX);
520  // hPseudoResY[cellNum]->Fill(residualY);
521  hPseudoResU[cellNum]->Fill(residualU);
522  hPseudoResV[cellNum]->Fill(residualV);
523  unsigned int radius = interPosition2D.Mod()/(45/rad);
524  if (radius<rad)
525  hPseudoResUvsV[cellNum][radius]->Fill(residualU, residualV);
526  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
527 
528  if (foundPseudo) continue;
529  // to avoid double conting
530 
531  //if (residualR < 1.6){ // = 5 sigma in x and in y
532  if (residualR < 2){ // = to account for non-gaussian tails and tracking/extrapolation errors
533  foundPseudo = true;
534 
535  if(fdc_pseudo_measured_cell[cellNum] != NULL && cellNum < 25){
536  // fill histogramms with the predicted, not with the measured position
537  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
538  fdc_pseudo_measured_cell[cellNum]->Fill(interPosition.X(), interPosition.Y());
539  hPseudoTime_accepted[cellNum]->Fill(locPseudo->time);
540  hCathodeTime_accepted[cellNum]->Fill(locPseudo->t_u);
541  hCathodeTime_accepted[cellNum]->Fill(locPseudo->t_v);
542  hDeltaTime[cellNum]->Fill(locPseudo->time - locPseudo->t_u);
543  hDeltaTime[cellNum]->Fill(locPseudo->time - locPseudo->t_v);
544  hPseudoResVsT[cellNum]->Fill(residualU, locPseudo->time);
545  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
546  }
547  }
548 
549 
550  } // End Pseudo Hit loop
551  }
552 
553  // END PSEUDO ANALYSIS
554 
555  } // End cell loop
556  } // End track loop
557 
558  return NOERROR;
559 }
560 
561 //------------------
562 // erun
563 //------------------
565 {
566  // This is called whenever the run number changes, before it is
567  // changed to give you a chance to clean up before processing
568  // events from the next run number.
569  return NOERROR;
570 }
571 
572 //------------------
573 // fini
574 //------------------
576 {
577  return NOERROR;
578 }
579 
static TH1I * hChi2OverNDF
DVector2 xy
rough x,y coordinates in lab coordinate system
Definition: DFDCPseudo.h:100
static TH1I * hChi2OverNDF_accepted
DApplication * dapp
static TH2D * fdc_pseudo_expected_cell[25]
static TH1I * hMom
static TH1I * hRingsHit
static TH1I * hTheta_accepted
bool Get_TOFMatchParams(const DTrackingData *locTrack, vector< shared_ptr< const DTOFHitMatchParams > > &locMatchParams) const
const DCDCWire * wire
Definition: DCDCTrackHit.h:37
static TH2I * hPseudoResVsT[25]
TVector2 DVector2
Definition: DVector2.h:9
float angle
radians
Definition: DFDCWire.h:19
bool Get_SCMatchParams(const DTrackingData *locTrack, vector< shared_ptr< const DSCHitMatchParams > > &locMatchParams) const
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
TVector3 DVector3
Definition: DVector3.h:14
static TH1I * hPseudoResU[25]
double t_v
time of the two cathode clusters
Definition: DFDCPseudo.h:86
sprintf(text,"Post KinFit Cut")
static TH1I * hPhi_accepted
static vector< vector< DFDCWire * > > fdcwires
DMagneticFieldMap * GetBfield(unsigned int run_number=1)
const unsigned int rad
int gLayer
Definition: DFDCHit.h:28
const DTrackTimeBased * Get_TrackTimeBased(void) const
const DFDCWire * wire
DFDCWire for this wire.
Definition: DFDCPseudo.h:92
static TH1I * hPseudoTime_accepted[25]
class DFDCPseudo: definition for a reconstructed point in the FDC
Definition: DFDCPseudo.h:74
static TH1I * hTheta
#define X(str)
Definition: hddm-c.cpp:83
jerror_t fini(void)
Called after last event of last event source has been processed.
JApplication * japp
static TH1I * hWireTime_accepted[25]
int layer
1-24
Definition: DFDCWire.h:16
static TH1I * hCellsHit_accepted
double t_u
Definition: DFDCPseudo.h:86
static TH1I * hPullTime[25]
static TH1D * fdc_wire_expected_cell[25]
static TH1I * hMom_accepted
InitPlugin_t InitPlugin
static TH1I * hDeltaTime[25]
Definition: GlueX.h:18
static TH2D * fdc_pseudo_measured_cell[25]
static TH2I * hPseudoResUvsV[25][rad]
DGeometry * GetDGeometry(unsigned int run_number)
static TH1I * hPhi
int plane
Definition: DFDCHit.h:26
jerror_t init(void)
Called once at program start.
void Fill1DHistogram(const char *plugin, const char *directoryName, const char *name, const double value, const char *title, int nBins, double xmin, double xmax, bool print=false)
static TH1D * fdc_wire_measured_cell[25]
static TH2I * hResVsT[25]
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
static TH1I * hPseudoResV[25]
static TH1I * hCathodeTime_accepted[25]
int element
Definition: DFDCHit.h:25
static TH1I * hRingsHit_accepted
double time
time corresponding to this pseudopoint.
Definition: DFDCPseudo.h:93
vector< DTrackFitter::pull_t > pulls
Holds pulls used in chisq calc. (not including off-diagonals)
static TH1I * hCellsHit
bool Get_BCALMatchParams(const DTrackingData *locTrack, vector< shared_ptr< const DBCALShowerMatchParams > > &locMatchParams) const
static TH1I * hWireTime[25]
float t
Definition: DFDCHit.h:32
int ring
Definition: DCDCWire.h:80
bool GetFDCWires(vector< vector< DFDCWire * > > &fdcwires) const
Definition: DGeometry.cc:1078
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
static TH2I * hRingsHit_vs_P
static TH1I * hPseudoRes
int main(int argc, char *argv[])
Definition: gendoc.cc:6
static TH1I * hCathodeTime[25]
static TH1I * hPseudoTime[25]
class DFDCHit: definition for a basic FDC hit data type.
Definition: DFDCHit.h:20