Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_FCAL_Hadronic_Eff.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: JEventProcessor_FCAL_Hadronic_Eff.cc
4 //
5 
7 
8 // Routine used to create our JEventProcessor
9 extern "C"
10 {
11  void InitPlugin(JApplication *locApplication)
12  {
13  InitJANAPlugin(locApplication);
14  locApplication->AddProcessor(new JEventProcessor_FCAL_Hadronic_Eff()); //register this plugin
15  }
16 } // "C"
17 
18 //define static local variable //declared in header file
20 
21 //------------------
22 // init
23 //------------------
25 {
26  //TRACK REQUIREMENTS
27  dMaxTOFDeltaT = 1.0;
28  dMinTrackingFOM = 5.73303E-7; // +/- 5 sigma
29  dMinNumTrackHits = 16; //e.g. 4 in each FDC plane
32  dMaxFCALThetaCut = 15.0;
33  dMaxVertexR = 1.0;
35  //action initialize not necessary: is empty
36 
37  TDirectory* locOriginalDir = gDirectory;
38  gDirectory->mkdir("FCAL_Hadronic_Eff")->cd();
39 
40  //Histograms
41  string locHistName, locHistTitle;
42 
43  locHistName = "TrackFCALYVsX_HasHit";
44  locHistTitle = "FCAL Has Hit;Projected FCAL Hit X (cm);Projected FCAL Hit Y (cm)";
45  dHist_TrackFCALYVsX_HasHit = new TH2I(locHistName.c_str(), locHistTitle.c_str(), 130, -130.0, 130.0, 130, -130.0, 130.0);
46 
47  locHistName = "TrackFCALYVsX_NoHit";
48  locHistTitle = "FCAL Total Hit;Projected FCAL Hit X (cm);Projected FCAL Hit Y (cm)";
49  dHist_TrackFCALYVsX_TotalHit = new TH2I(locHistName.c_str(), locHistTitle.c_str(), 130, -130.0, 130.0, 130, -130.0, 130.0);
50 
51  locHistName = "TrackFCALRowVsColumn_HasHit";
52  locHistTitle = "FCAL Has Hit;Projected FCAL Hit Column;Projected FCAL Hit Row";
53  dHist_TrackFCALRowVsColumn_HasHit = new TH2I(locHistName.c_str(), locHistTitle.c_str(), 59, -0.5, 58.5, 59, -0.5, 58.5);
54 
55  locHistName = "TrackFCALRowVsColumn_NoHit";
56  locHistTitle = "FCAL Total Hit;Projected FCAL Hit Column;Projected FCAL Hit Row";
57  dHist_TrackFCALRowVsColumn_TotalHit = new TH2I(locHistName.c_str(), locHistTitle.c_str(), 59, -0.5, 58.5, 59, -0.5, 58.5);
58 
59  // back to original dir
60  locOriginalDir->cd();
61 
62  //TTREE INTERFACE
63  //MUST DELETE WHEN FINISHED: OR ELSE DATA WON'T BE SAVED!!!
64  dTreeInterface = DTreeInterface::Create_DTreeInterface("fcal_hadronic_eff", "tree_fcal_hadronic_eff.root");
65 
66  //TTREE BRANCHES
67  DTreeBranchRegister locTreeBranchRegister;
68 
69  //TRACK
70  locTreeBranchRegister.Register_Single<Int_t>("PID_PDG"); //gives charge, mass, beta //is unknown if no TOF hit
71  locTreeBranchRegister.Register_Single<Float_t>("TrackVertexZ");
72  locTreeBranchRegister.Register_Single<TVector3>("TrackP3");
73  locTreeBranchRegister.Register_Single<UInt_t>("TrackCDCRings"); //rings correspond to bits (1 -> 28)
74  locTreeBranchRegister.Register_Single<UInt_t>("TrackFDCPlanes"); //planes correspond to bits (1 -> 24)
75 
76  //PROJECTED FCAL
77  locTreeBranchRegister.Register_Single<Float_t>("ProjectedFCALX");
78  locTreeBranchRegister.Register_Single<Float_t>("ProjectedFCALY");
79  locTreeBranchRegister.Register_Single<UChar_t>("ProjectedFCALRow"); //0 if projected to miss
80  locTreeBranchRegister.Register_Single<UChar_t>("ProjectedFCALColumn"); //0 if projected to miss
81 
82  //NEAREST FCAL SHOWER
83  locTreeBranchRegister.Register_Single<Float_t>("NearestFCALEnergy"); //if < 0: nothing in time: PID:OUT_OF_TIME_CUT
84  locTreeBranchRegister.Register_Single<Float_t>("NearestFCALX"); //ignore if E < 0
85  locTreeBranchRegister.Register_Single<Float_t>("NearestFCALY"); //ignore if E < 0
86  locTreeBranchRegister.Register_Single<Bool_t>("IsMatchedToTrack"); //false if not registered in DDetectorMatches
87 
88  //FOUND FCAL //only if matched: for evaluating PID quality
89  locTreeBranchRegister.Register_Single<Float_t>("FCALDeltaT"); //FCAL - RF
90  locTreeBranchRegister.Register_Single<Float_t>("FCALTimeFOM");
91 
92  //REGISTER BRANCHES
93  dTreeInterface->Create_Branches(locTreeBranchRegister);
94 
95  return NOERROR;
96 }
97 
98 //------------------
99 // brun
100 //------------------
101 jerror_t JEventProcessor_FCAL_Hadronic_Eff::brun(jana::JEventLoop* locEventLoop, int locRunNumber)
102 {
103  // This is called whenever the run number changes
104 
105  return NOERROR;
106 }
107 
108 //------------------
109 // evnt
110 //------------------
111 
112 jerror_t JEventProcessor_FCAL_Hadronic_Eff::evnt(jana::JEventLoop* locEventLoop, uint64_t locEventNumber)
113 {
114  // This is called for every event. Use of common resources like writing
115  // to a file or filling a histogram should be mutex protected. Using
116  // locEventLoop->Get(...) to get reconstructed objects (and thereby activating the
117  // reconstruction algorithm) should be done outside of any mutex lock
118  // since multiple threads may call this method at the same time.
119 
120  // This plugin is used to determine the reconstruction efficiency of hits in the BCAL
121  // Note, this is hit-level, not shower-level. Hits: By sector/layer/module/end
122 
123  //CUT ON TRIGGER TYPE
124  const DTrigger* locTrigger = NULL;
125  locEventLoop->GetSingle(locTrigger);
126  if(locTrigger->Get_L1FrontPanelTriggerBits() != 0)
127  return NOERROR;
128 
129  //SEE IF FCAL REQUIRED TO TRIGGER
130  uint32_t locTriggerBits = locTrigger->Get_L1TriggerBits();
131  if(((locTriggerBits & 4) != 4) && ((locTriggerBits & 64) != 64))
132  return NOERROR;
133 
134  const DEventRFBunch* locEventRFBunch = NULL;
135  locEventLoop->GetSingle(locEventRFBunch);
136  if(locEventRFBunch->dNumParticleVotes <= 1)
137  return NOERROR; //don't trust PID: beta-dependence
138 
139  vector<const DChargedTrack*> locChargedTracks;
140  locEventLoop->Get(locChargedTracks);
141 
142  const DParticleID* locParticleID = NULL;
143  locEventLoop->GetSingle(locParticleID);
144 
145  vector<const DFCALShower*> locFCALShowers;
146  locEventLoop->Get(locFCALShowers);
147 
148  const DDetectorMatches* locDetectorMatches = NULL;
149  locEventLoop->GetSingle(locDetectorMatches);
150 
151  //Try to select the most-pure sample of tracks possible
152  set<const DChargedTrackHypothesis*> locBestTracks;
153  for(auto& locChargedTrack : locChargedTracks)
154  {
155  //loop over PID hypotheses and find the best (if any good enough)
156  const DChargedTrackHypothesis* locBestChargedTrackHypothesis = nullptr;
157  double locBestTrackingFOM = -1.0;
158  for(auto& locChargedTrackHypothesis : locChargedTrack->dChargedTrackHypotheses)
159  {
160  if((locChargedTrackHypothesis->PID() == Electron) || (locChargedTrackHypothesis->PID() == Positron))
161  continue; //don't evaluate for these
162 
163  if(locChargedTrackHypothesis->position().Perp() > dMaxVertexR)
164  continue; //don't trust reconstruction if not close to target
165 
166  //Need PID for beta-dependence, but cannot use FCAL info: would bias
167  if(!Cut_TOFTiming(locChargedTrackHypothesis))
168  continue;
169 
170  auto locTrackTimeBased = locChargedTrackHypothesis->Get_TrackTimeBased();
171  if(locTrackTimeBased->FOM < dMinTrackingFOM)
172  continue; //don't trust tracking results: bad tracking FOM
173 
174  if(!dCutAction_TrackHitPattern->Cut_TrackHitPattern(locParticleID, locTrackTimeBased))
175  continue; //don't trust tracking results: not many grouped hits
176 
177  unsigned int locNumTrackHits = locTrackTimeBased->Ndof + 5;
178  if(locNumTrackHits < dMinNumTrackHits)
179  continue; //don't trust tracking results: not many hits
180 
181  if(locTrackTimeBased->FOM < locBestTrackingFOM)
182  continue; //not the best mass hypothesis
183 
184  locBestTrackingFOM = locTrackTimeBased->FOM;
185  locBestChargedTrackHypothesis = locChargedTrackHypothesis;
186  }
187 
188  //if passed all cuts, save the best
189  if(locBestChargedTrackHypothesis != nullptr)
190  locBestTracks.insert(locBestChargedTrackHypothesis);
191  }
192 
193  // Loop over the good tracks, using the best DTrackTimeBased object for each
194  for(auto& locChargedTrackHypothesis : locBestTracks)
195  {
196  auto locTrackTimeBased = locChargedTrackHypothesis->Get_TrackTimeBased();
197 
198  //Predict FCAL Surface Hit Location
199  DVector3 locProjectedFCALIntersection;
200  unsigned int locProjectedFCALRow = 0, locProjectedFCALColumn = 0;
201  vector<DTrackFitter::Extrapolation_t>extrapolations=locTrackTimeBased->extrapolations.at(SYS_FCAL);
202  if(!locParticleID->PredictFCALHit(extrapolations, locProjectedFCALRow, locProjectedFCALColumn, &locProjectedFCALIntersection))
203  {
204  if(locTrackTimeBased->momentum().Theta()*180.0/TMath::Pi() > dMaxFCALThetaCut)
205  continue; //not predicted to hit FCAL
206  }
207 
208  //Find closest FCAL Shower
209  const DFCALShower* locFCALShower = nullptr;
210  shared_ptr<const DFCALShowerMatchParams> locClosestMatchParams;
211  double locStartTime = locTrackTimeBased->t0();
212  if(locParticleID->Get_ClosestToTrack(extrapolations, locFCALShowers, false, locStartTime, locClosestMatchParams))
213  locFCALShower = locClosestMatchParams->dFCALShower;
214 
215  //Is match to FCAL shower?
216  auto locFCALShowerMatchParams = locChargedTrackHypothesis->Get_FCALShowerMatchParams();
217  bool locIsMatchedToTrack = (locFCALShowerMatchParams != nullptr);
218 
219  //If so, calc PID info: timing
220  double locFCALDeltaT = 0.0;
221  double locFCALTimeFOM = Calc_FCALTiming(locChargedTrackHypothesis, locParticleID, locEventRFBunch, locFCALDeltaT);
222 
223  // FILL HISTOGRAMS
224  // Since we are filling histograms local to this plugin, it will not interfere with other ROOT operations: can use plugin-wide ROOT fill lock
225  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
226  {
227  //TOFPoint
228  dHist_TrackFCALYVsX_TotalHit->Fill(locProjectedFCALIntersection.X(), locProjectedFCALIntersection.Y());
229  dHist_TrackFCALRowVsColumn_TotalHit->Fill(locProjectedFCALColumn, locProjectedFCALRow);
230 
231  //TOFPoint
232  if(locIsMatchedToTrack)
233  {
234  dHist_TrackFCALYVsX_HasHit->Fill(locProjectedFCALIntersection.X(), locProjectedFCALIntersection.Y());
235  dHist_TrackFCALRowVsColumn_HasHit->Fill(locProjectedFCALColumn, locProjectedFCALRow);
236  }
237  }
238  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
239 
240  //TRACK
241  Particle_t locPID = (locChargedTrackHypothesis->t1_detector() == SYS_TOF) ? locChargedTrackHypothesis->PID() : Unknown;
242  dTreeFillData.Fill_Single<Int_t>("PID_PDG", PDGtype(locPID));
243  dTreeFillData.Fill_Single<Float_t>("TrackVertexZ", locChargedTrackHypothesis->position().Z());
244  dTreeFillData.Fill_Single<UInt_t>("TrackCDCRings", locTrackTimeBased->dCDCRings);
245  dTreeFillData.Fill_Single<UInt_t>("TrackFDCPlanes", locTrackTimeBased->dFDCPlanes);
246  DVector3 locDP3 = locChargedTrackHypothesis->momentum();
247  TVector3 locP3(locDP3.X(), locDP3.Y(), locDP3.Z());
248  dTreeFillData.Fill_Single<TVector3>("TrackP3", locP3);
249 
250  //PROJECTED FCAL
251  dTreeFillData.Fill_Single<Float_t>("ProjectedFCALX", locProjectedFCALIntersection.X());
252  dTreeFillData.Fill_Single<Float_t>("ProjectedFCALY", locProjectedFCALIntersection.Y());
253  dTreeFillData.Fill_Single<UChar_t>("ProjectedFCALRow", locProjectedFCALRow);
254  dTreeFillData.Fill_Single<UChar_t>("ProjectedFCALColumn", locProjectedFCALColumn);
255 
256  //NEAREST FCAL SHOWER
257  if(locFCALShower != NULL)
258  {
259  dTreeFillData.Fill_Single<Float_t>("NearestFCALEnergy", locFCALShower->getEnergy());
260  dTreeFillData.Fill_Single<Float_t>("NearestFCALX", locFCALShower->getPosition().X());
261  dTreeFillData.Fill_Single<Float_t>("NearestFCALY", locFCALShower->getPosition().Y());
262  }
263  else
264  {
265  dTreeFillData.Fill_Single<Float_t>("NearestFCALEnergy", -1.0);
266  dTreeFillData.Fill_Single<Float_t>("NearestFCALX", 0.0);
267  dTreeFillData.Fill_Single<Float_t>("NearestFCALY", 0.0);
268  }
269  dTreeFillData.Fill_Single<Bool_t>("IsMatchedToTrack", locIsMatchedToTrack);
270 
271  //FOUND FCAL
272  dTreeFillData.Fill_Single<Float_t>("FCALDeltaT", locFCALDeltaT);
273  dTreeFillData.Fill_Single<Float_t>("FCALTimeFOM", locFCALTimeFOM);
274 
275  //FILL TTREE
277  }
278 
279  return NOERROR;
280 }
281 
282 double JEventProcessor_FCAL_Hadronic_Eff::Calc_FCALTiming(const DChargedTrackHypothesis* locChargedTrackHypothesis, const DParticleID* locParticleID, const DEventRFBunch* locEventRFBunch, double& locDeltaT)
283 {
284  auto locFCALShowerMatchParams = locChargedTrackHypothesis->Get_FCALShowerMatchParams();
285  if(locFCALShowerMatchParams == NULL)
286  return false;
287 
288  double locStartTime = locParticleID->Calc_PropagatedRFTime(locChargedTrackHypothesis, locEventRFBunch);
289  const DFCALShower* locFCALShower = locFCALShowerMatchParams->dFCALShower;
290  locDeltaT = locFCALShower->getTime() - locFCALShowerMatchParams->dFlightTime - locStartTime;
291 
292  double locPIDFOM = -1.0; //not able to calc this correctly yet
293  return locPIDFOM;
294 }
295 
297 {
298  if(locChargedTrackHypothesis->t1_detector() != SYS_TOF)
299  return true; //don't require TOF hit: limits reach of study
300 
301  double locDeltaT = locChargedTrackHypothesis->time() - locChargedTrackHypothesis->t0();
302  return (fabs(locDeltaT) <= dMaxTOFDeltaT);
303 }
304 
305 //------------------
306 // erun
307 //------------------
309 {
310  // This is called whenever the run number changes, before it is
311  // changed to give you a chance to clean up before processing
312  // events from the next run number.
313 
314  return NOERROR;
315 }
316 
317 //------------------
318 // fini
319 //------------------
321 {
322  // Called before program exit after event processing is finished.
323 
325  delete dTreeInterface; //saves trees to file, closes file
326 
327  return NOERROR;
328 }
329 
double getEnergy() const
Definition: DFCALShower.h:156
TVector3 DVector3
Definition: DVector3.h:14
uint32_t Get_L1TriggerBits(void) const
double getTime() const
Definition: DFCALShower.h:161
jerror_t brun(jana::JEventLoop *locEventLoop, int locRunNumber)
Called every time a new run number is detected.
void Register_Single(string locBranchName)
const DTrackTimeBased * Get_TrackTimeBased(void) const
bool Create_Branches(const DTreeBranchRegister &locTreeBranchRegister)
uint32_t Get_L1FrontPanelTriggerBits(void) const
double Calc_FCALTiming(const DChargedTrackHypothesis *locChargedTrackHypothesis, const DParticleID *locParticleID, const DEventRFBunch *locEventRFBunch, double &locDeltaT)
double Calc_PropagatedRFTime(const DKinematicData *locKinematicData, const DEventRFBunch *locEventRFBunch) const
static int PDGtype(Particle_t p)
JApplication * japp
bool PredictFCALHit(const DReferenceTrajectory *rt, unsigned int &row, unsigned int &col, DVector3 *intersection=nullptr) const
jerror_t fini(void)
Called after last event of last event source has been processed.
bool Cut_TOFTiming(const DChargedTrackHypothesis *locChargedTrackHypothesis)
double time(void) const
void Fill(DTreeFillData &locTreeFillData)
static DTreeInterface * Create_DTreeInterface(string locTreeName, string locFileName)
InitPlugin_t InitPlugin
Definition: GlueX.h:20
Definition: GlueX.h:22
bool Get_ClosestToTrack(const DReferenceTrajectory *rt, const vector< const DBCALShower * > &locBCALShowers, bool locCutFlag, double &locStartTime, shared_ptr< const DBCALShowerMatchParams > &locBestMatchParams, double *locStartTimeVariance=nullptr, DVector3 *locBestProjPos=nullptr, DVector3 *locBestProjMom=nullptr) const
int Ndof
Number of degrees of freedom in the fit.
shared_ptr< const DFCALShowerMatchParams > Get_FCALShowerMatchParams(void) const
static thread_local DTreeFillData dTreeFillData
bool Cut_TrackHitPattern(const DParticleID *locParticleID, const DKinematicData *locTrack) const
Definition: DCutActions.cc:809
unsigned int dNumParticleVotes
Definition: DEventRFBunch.h:32
DCutAction_TrackHitPattern * dCutAction_TrackHitPattern
DetectorSystem_t t1_detector(void) const
DVector3 getPosition() const
Definition: DFCALShower.h:151
jerror_t erun(void)
Called every time run number changes, provided brun has been called.
jerror_t init(void)
Called once at program start.
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t locEventNumber)
Called every event.
Particle_t
Definition: particleType.h:12
void Fill_Single(string locBranchName, const DType &locData)