Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventRFBunch_factory.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DEventRFBunch_factory.cc
4 // Created: Thu Dec 3 17:27:55 EST 2009
5 // Creator: pmatt (on Linux ifarml6 2.6.18-128.el5 x86_64)
6 //
7 
9 #include "BCAL/DBCALShower.h"
10 #include "FCAL/DFCALShower.h"
11 
12 using namespace jana;
13 
14 //------------------
15 // init
16 //------------------
18 {
19  dMinTrackingFOM = 0.0;
20  OVERRIDE_TAG = "";
21 
22  gPARMS->SetDefaultParameter("EVENTRFBUNCH:USE_TAG", OVERRIDE_TAG, "Use a particular tag for the general RF bunch calculation instead of the default calculation.");
23  return NOERROR;
24 }
25 
26 //------------------
27 // brun
28 //------------------
29 jerror_t DEventRFBunch_factory::brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
30 {
31  DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
32  DGeometry* locGeometry = locApplication->GetDGeometry(runnumber);
33 
34  vector<double> locBeamPeriodVector;
35  locEventLoop->GetCalib("PHOTON_BEAM/RF/beam_period", locBeamPeriodVector);
36  dBeamBunchPeriod = locBeamPeriodVector[0];
37 
38  double locTargetCenterZ;
39  locGeometry->GetTargetZ(locTargetCenterZ);
40  dTargetCenter.SetXYZ(0.0, 0.0, locTargetCenterZ);
41 
42  locEventLoop->GetSingle(dParticleID);
43 
44  return NOERROR;
45 }
46 
47 //------------------
48 // evnt
49 //------------------
50 jerror_t DEventRFBunch_factory::evnt(JEventLoop* locEventLoop, uint64_t eventnumber)
51 {
52  //There should ALWAYS be one and only one DEventRFBunch created.
53  //If there is not enough information, time is set to NaN
54 
55  if(OVERRIDE_TAG != "") {
56  vector<const DEventRFBunch *> rfBunchVec;
57  locEventLoop->Get(rfBunchVec, OVERRIDE_TAG.c_str());
58 
59  if(rfBunchVec.size() > 0) {
60  DEventRFBunch *rfBunchCopy = new DEventRFBunch(*rfBunchVec[0]);
61  _data.push_back(rfBunchCopy);
62  return NOERROR;
63  } else {
64  jerr << "Could not find DEventRFBunch objects with tag " << OVERRIDE_TAG
65  << ", falling back to default calculation ..." << endl;
66  }
67  }
68 
69 
70  //Select Good Tracks
71  vector<const DTrackTimeBased*> locTrackTimeBasedVector;
72  Select_GoodTracks(locEventLoop, locTrackTimeBasedVector);
73 
74  //Select RF Bunch:
75  vector<const DRFTime*> locRFTimes;
76  locEventLoop->Get(locRFTimes);
77  if(!locRFTimes.empty())
78  return Select_RFBunch(locEventLoop, locTrackTimeBasedVector, locRFTimes[0]);
79  else
80  return Select_RFBunch_NoRFTime(locEventLoop, locTrackTimeBasedVector);
81 }
82 
83 void DEventRFBunch_factory::Select_GoodTracks(JEventLoop* locEventLoop, vector<const DTrackTimeBased*>& locSelectedTimeBasedTracks) const
84 {
85  //Select tracks:
86  //For each particle (DTrackTimeBased::candidateid), use the DTrackTimeBased with the best tracking FOM
87  //Only use DTrackTimeBased's with tracking FOM > dMinTrackingFOM
88 
89  locSelectedTimeBasedTracks.clear();
90 
91  vector<const DTrackTimeBased*> locTrackTimeBasedVector;
92  locEventLoop->Get(locTrackTimeBasedVector);
93 
94  //select the best DTrackTimeBased for each track: use best tracking FOM
95  map<JObject::oid_t, const DTrackTimeBased*> locBestTrackTimeBasedMap; //lowest tracking chisq/ndf for each candidate id
96  for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
97  {
98  JObject::oid_t locCandidateID = locTrackTimeBasedVector[loc_i]->candidateid;
99  if(locBestTrackTimeBasedMap.find(locCandidateID) == locBestTrackTimeBasedMap.end())
100  locBestTrackTimeBasedMap[locCandidateID] = locTrackTimeBasedVector[loc_i];
101  else if(locTrackTimeBasedVector[loc_i]->FOM > locBestTrackTimeBasedMap[locCandidateID]->FOM)
102  locBestTrackTimeBasedMap[locCandidateID] = locTrackTimeBasedVector[loc_i];
103  }
104 
105  //Select tracks with good tracking FOM
106  map<JObject::oid_t, const DTrackTimeBased*>::iterator locIterator;
107  for(locIterator = locBestTrackTimeBasedMap.begin(); locIterator != locBestTrackTimeBasedMap.end(); ++locIterator)
108  {
109  const DTrackTimeBased* locTrackTimeBased = locIterator->second;
110  if(locTrackTimeBased->FOM >= dMinTrackingFOM)
111  locSelectedTimeBasedTracks.push_back(locTrackTimeBased);
112  }
113 }
114 
115 jerror_t DEventRFBunch_factory::Select_RFBunch(JEventLoop* locEventLoop, vector<const DTrackTimeBased*>& locTrackTimeBasedVector, const DRFTime* locRFTime)
116 {
117  //If RF Time present:
118  // Use track matches in the following order: SC, TOF, BCAL, FCAL.
119  // If none: Let neutral showers vote (assume PID = photon) on RF bunch
120  // If None: set DEventRFBunch::dTime to NaN
121 
122  //Voting when RF time present:
123  //Propagate track/shower times to vertex
124  //Compare times to possible RF bunches, select the bunch with the most votes
125  //If there is a tie: let DBeamPhoton's vote to break tie
126  //If still a tie, and voting with tracks:
127  //Select the bunch with the most total track hits (highest total tracking NDF)
128  //If still a tie:
129  //Select the bunch with the lowest total chisq
130  //If still a tie, and voting with neutral showers:
131  //Select the bunch with the highest total shower energy
132 
133  const DDetectorMatches* locDetectorMatches = NULL;
134  locEventLoop->GetSingle(locDetectorMatches);
135 
136  vector<pair<double, const JObject*> > locTimes;
137  int locBestRFBunchShift = 0, locHighestNumVotes = 0;
138 
139  if(Find_TrackTimes_All(locDetectorMatches, locTrackTimeBasedVector, locTimes))
140  locBestRFBunchShift = Conduct_Vote(locEventLoop, locRFTime->dTime, locTimes, true, locHighestNumVotes);
141  else if(Find_NeutralTimes(locEventLoop, locTimes))
142  locBestRFBunchShift = Conduct_Vote(locEventLoop, locRFTime->dTime, locTimes, false, locHighestNumVotes);
143  else //PASS-THROUGH, WILL HAVE TO RESOLVE WHEN COMBOING
144  locBestRFBunchShift = 0;
145 
146  DEventRFBunch* locEventRFBunch = new DEventRFBunch();
147  locEventRFBunch->dTime = locRFTime->dTime + dBeamBunchPeriod*double(locBestRFBunchShift);
148  locEventRFBunch->dTimeVariance = locRFTime->dTimeVariance;
149  locEventRFBunch->dNumParticleVotes = locHighestNumVotes;
150  locEventRFBunch->dTimeSource = SYS_RF;
151  _data.push_back(locEventRFBunch);
152 
153  return NOERROR;
154 }
155 
156 int DEventRFBunch_factory::Conduct_Vote(JEventLoop* locEventLoop, double locRFTime, vector<pair<double, const JObject*> >& locTimes, bool locUsedTracksFlag, int& locHighestNumVotes)
157 {
158  map<int, vector<const JObject*> > locNumBeamBucketsShiftedMap;
159  set<int> locBestRFBunchShifts;
160 
161  locHighestNumVotes = Find_BestRFBunchShifts(locRFTime, locTimes, locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
162  if(locBestRFBunchShifts.size() == 1)
163  return *locBestRFBunchShifts.begin();
164 
165  //tied: break with beam photons
166  vector<const DBeamPhoton*> locBeamPhotons;
167  locEventLoop->Get(locBeamPhotons);
168  if(Break_TieVote_BeamPhotons(locBeamPhotons, locRFTime, locNumBeamBucketsShiftedMap, locBestRFBunchShifts, locHighestNumVotes))
169  return *locBestRFBunchShifts.begin();
170 
171  //still tied
172  if(locUsedTracksFlag)
173  {
174  //break tie with total track hits (ndf), else break with total tracking chisq
175  return Break_TieVote_Tracks(locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
176  }
177  else //neutrals
178  {
179  //break tie with highest total shower energy
180  return Break_TieVote_Neutrals(locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
181  }
182 }
183 
184 bool DEventRFBunch_factory::Find_TrackTimes_SCTOF(const DDetectorMatches* locDetectorMatches, const vector<const DTrackTimeBased*>& locTrackTimeBasedVector, vector<pair<double, const JObject*> >& locTimes) const
185 {
186  locTimes.clear();
187  for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
188  {
189  const DTrackTimeBased* locTrackTimeBased = locTrackTimeBasedVector[loc_i];
190  double locP = locTrackTimeBased->momentum().Mag();
191 
192  //TOF resolution = 80ps, 3sigma = 240ps
193  //max PID delta-t = 762ps (assuming 499 MHz and no buffer)
194  //for pion-proton: delta-t is ~750ps at ~170 MeV/c or lower: cannot have proton this slow anyway
195  //for pion-kaon delta-t is ~750ps at ~80 MeV/c or lower: won't reconstruct these anyway, and not likely to be forward-going anyway
196  shared_ptr<const DTOFHitMatchParams> locTOFHitMatchParams;
197  if((locP > 0.5) && dParticleID->Get_BestTOFMatchParams(locTrackTimeBased, locDetectorMatches, locTOFHitMatchParams))
198  {
199  double locPropagatedTime = locTOFHitMatchParams->dHitTime - locTOFHitMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
200  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackTimeBased));
201  continue;
202  }
203 
204  //Prefer TOF over SC in nose region because hard to tell which SC counter should have been hit
205  shared_ptr<const DSCHitMatchParams> locSCHitMatchParams;
206  if(!dParticleID->Get_BestSCMatchParams(locTrackTimeBased, locDetectorMatches, locSCHitMatchParams))
207  continue;
208 
209  double locPropagatedTime = locSCHitMatchParams->dHitTime - locSCHitMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
210  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackTimeBased));
211  }
212 
213  return (!locTimes.empty());
214 }
215 
216 bool DEventRFBunch_factory::Find_TrackTimes_All(const DDetectorMatches* locDetectorMatches, const vector<const DTrackTimeBased*>& locTrackTimeBasedVector, vector<pair<double, const JObject*> >& locTimes)
217 {
218  locTimes.clear();
219 
220  //Use TOF/BCAL time to match to RF bunches:
221  //FCAL time resolution not good enough (right?)
222  //max can be off = rf-frequency/2 ns (if off by more, will pick wrong beam bunch)
223  for(size_t loc_i = 0; loc_i < locTrackTimeBasedVector.size(); ++loc_i)
224  {
225  const DTrackTimeBased* locTrackTimeBased = locTrackTimeBasedVector[loc_i];
226 
227  // start with SC: closest to target, minimal dependence on particle type
228  shared_ptr<const DSCHitMatchParams> locSCHitMatchParams;
229  if(dParticleID->Get_BestSCMatchParams(locTrackTimeBased, locDetectorMatches, locSCHitMatchParams))
230  {
231  double locPropagatedTime = locSCHitMatchParams->dHitTime - locSCHitMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
232  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackTimeBased));
233  continue;
234 
235  }
236 
237  // Next use the TOF (best timing resolution for outer detectors
238  //TOF resolution = 80ps, 3sigma = 240ps
239  //max PID delta-t = 762ps (assuming 499 MHz and no buffer)
240  //for pion-proton: delta-t is ~750ps at ~170 MeV/c or lower: cannot have proton this slow anyway
241  //for pion-kaon delta-t is ~750ps at ~80 MeV/c or lower: won't reconstruct these anyway, and not likely to be forward-going anyway
242  shared_ptr<const DTOFHitMatchParams> locTOFHitMatchParams;
243  if(dParticleID->Get_BestTOFMatchParams(locTrackTimeBased, locDetectorMatches, locTOFHitMatchParams))
244  {
245  double locPropagatedTime = locTOFHitMatchParams->dHitTime - locTOFHitMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
246  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackTimeBased));
247  continue;
248  }
249 
250  // Else match to BCAL if fast enough (low time resolution for slow particles)
251  double locP = locTrackTimeBased->momentum().Mag();
252  //at 250 MeV/c, BCAL t-resolution is ~310ps (3sigma = 920ps), BCAL delta-t error is ~40ps: ~960 ps < 1 ns: OK!!
253  //at 225 MeV/c, BCAL t-resolution is ~333ps (3sigma = 999ps), BCAL delta-t error is ~40ps: ~1040ps: bad at 499 MHz
254  if((locP < 0.25) && (dBeamBunchPeriod < 2.005))
255  continue; //too slow for the BCAL to distinguish RF bunch
256 
257  shared_ptr<const DBCALShowerMatchParams> locBCALShowerMatchParams;
258  if(dParticleID->Get_BestBCALMatchParams(locTrackTimeBased, locDetectorMatches, locBCALShowerMatchParams))
259  {
260  const DBCALShower* locBCALShower = locBCALShowerMatchParams->dBCALShower;
261  double locPropagatedTime = locBCALShower->t - locBCALShowerMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
262  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackTimeBased));
263  continue;
264  }
265 
266  // If all else fails, use FCAL
267  shared_ptr<const DFCALShowerMatchParams> locFCALShowerMatchParams;
268  if(dParticleID->Get_BestFCALMatchParams(locTrackTimeBased, locDetectorMatches, locFCALShowerMatchParams))
269  {
270  const DFCALShower* locFCALShower = locFCALShowerMatchParams->dFCALShower;
271  double locPropagatedTime = locFCALShower->getTime() - locFCALShowerMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackTimeBased->z())/29.9792458;
272  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackTimeBased));
273  continue;
274  }
275 
276 
277  }
278 
279  return (!locTimes.empty());
280 }
281 
282 bool DEventRFBunch_factory::Find_NeutralTimes(JEventLoop* locEventLoop, vector<pair<double, const JObject*> >& locTimes)
283 {
284  locTimes.clear();
285 
286  vector< const DFCALShower* > fcalShowers;
287  locEventLoop->Get( fcalShowers );
288 
289  for( size_t i = 0; i < fcalShowers.size(); ++i ){
290 
291  DVector3 locHitPoint = fcalShowers[i]->getPosition();
292  DVector3 locPath = locHitPoint - dTargetCenter;
293  double locPathLength = locPath.Mag();
294  if(!(locPathLength > 0.0))
295  continue;
296 
297  double locFlightTime = locPathLength/29.9792458;
298  double locHitTime = fcalShowers[i]->getTime();
299  locTimes.push_back( pair< double, const JObject*>( locHitTime - locFlightTime, fcalShowers[i] ) );
300  }
301 
302  vector< const DBCALShower* > bcalShowers;
303  locEventLoop->Get( bcalShowers );
304 
305  for( size_t i = 0; i < bcalShowers.size(); ++i ){
306 
307  DVector3 locHitPoint( bcalShowers[i]->x, bcalShowers[i]->y, bcalShowers[i]->z );
308  DVector3 locPath = locHitPoint - dTargetCenter;
309  double locPathLength = locPath.Mag();
310  if(!(locPathLength > 0.0))
311  continue;
312 
313  double locFlightTime = locPathLength/29.9792458;
314  double locHitTime = bcalShowers[i]->t;
315  locTimes.push_back( pair< double, const JObject*>( locHitTime - locFlightTime, bcalShowers[i] ) );
316  }
317 
318  return (locTimes.size() > 1);
319 }
320 
321 int DEventRFBunch_factory::Find_BestRFBunchShifts(double locRFHitTime, const vector<pair<double, const JObject*> >& locTimes, map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
322 {
323  //then find the #beam buckets the RF time needs to shift to match it
324  int locHighestNumVotes = 0;
325  locNumBeamBucketsShiftedMap.clear();
326  locBestRFBunchShifts.clear();
327 
328  for(unsigned int loc_i = 0; loc_i < locTimes.size(); ++loc_i)
329  {
330  double locDeltaT = locTimes[loc_i].first - locRFHitTime;
331  int locNumBeamBucketsShifted = (locDeltaT > 0.0) ? int(locDeltaT/dBeamBunchPeriod + 0.5) : int(locDeltaT/dBeamBunchPeriod - 0.5);
332  locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].push_back(locTimes[loc_i].second);
333 
334  int locNumVotesThisShift = locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].size();
335  if(locNumVotesThisShift > locHighestNumVotes)
336  {
337  locHighestNumVotes = locNumVotesThisShift;
338  locBestRFBunchShifts.clear();
339  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
340  }
341  else if(locNumVotesThisShift == locHighestNumVotes)
342  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
343  }
344 
345  return locHighestNumVotes;
346 }
347 
348 bool DEventRFBunch_factory::Break_TieVote_BeamPhotons(vector<const DBeamPhoton*>& locBeamPhotons, double locRFTime, map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts, int locHighestNumVotes)
349 {
350  //locHighestNumVotes intentionally passed-in as value-type (non-reference)
351  //beam photons are only used to BREAK the tie, not count as equal votes
352 
353  set<int> locInputRFBunchShifts = locBestRFBunchShifts; //only test these RF bunch selections
354  for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
355  {
356  double locDeltaT = locBeamPhotons[loc_i]->time() - locRFTime;
357  int locNumBeamBucketsShifted = (locDeltaT > 0.0) ? int(locDeltaT/dBeamBunchPeriod + 0.5) : int(locDeltaT/dBeamBunchPeriod - 0.5);
358  if(locInputRFBunchShifts.find(locNumBeamBucketsShifted) == locInputRFBunchShifts.end())
359  continue; //only use beam votes to break input tie, not contribute to other beam buckets
360 
361  locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].push_back(locBeamPhotons[loc_i]);
362 
363  int locNumVotesThisShift = locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].size();
364  if(locNumVotesThisShift > locHighestNumVotes)
365  {
366  locHighestNumVotes = locNumVotesThisShift;
367  locBestRFBunchShifts.clear();
368  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
369  }
370  else if(locNumVotesThisShift == locHighestNumVotes)
371  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
372  }
373 
374  return (locBestRFBunchShifts.size() == 1);
375 }
376 
377 int DEventRFBunch_factory::Break_TieVote_Tracks(map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
378 {
379  //Select the bunch with the most total track hits (highest total tracking NDF)
380  //If still a tie:
381  //Select the bunch with the lowest total chisq
382 
383  int locBestRFBunchShift = 0;
384  pair<int, double> locBestTrackingTotals(-1, 9.9E99); //ndf, chisq
385 
386  set<int>::const_iterator locSetIterator = locBestRFBunchShifts.begin();
387  for(; locSetIterator != locBestRFBunchShifts.end(); ++locSetIterator)
388  {
389  int locRFBunchShift = *locSetIterator;
390  int locTotalTrackingNDF = 0;
391  double locTotalTrackingChiSq = 0.0;
392 
393  const vector<const JObject*>& locVoters = locNumBeamBucketsShiftedMap[locRFBunchShift];
394  for(size_t loc_i = 0; loc_i < locVoters.size(); ++loc_i)
395  {
396  const DTrackTimeBased* locTrackTimeBased = dynamic_cast<const DTrackTimeBased*>(locVoters[loc_i]);
397  if(locTrackTimeBased == NULL)
398  continue;
399  locTotalTrackingNDF += locTrackTimeBased->Ndof;
400  locTotalTrackingChiSq += locTrackTimeBased->chisq;
401  }
402 
403  if(locTotalTrackingNDF > locBestTrackingTotals.first)
404  {
405  locBestTrackingTotals = pair<int, double>(locTotalTrackingNDF, locTotalTrackingChiSq);
406  locBestRFBunchShift = locRFBunchShift;
407  }
408  else if((locTotalTrackingNDF == locBestTrackingTotals.first) && (locTotalTrackingChiSq < locBestTrackingTotals.second))
409  {
410  locBestTrackingTotals = pair<int, double>(locTotalTrackingNDF, locTotalTrackingChiSq);
411  locBestRFBunchShift = locRFBunchShift;
412  }
413  }
414 
415  return locBestRFBunchShift;
416 }
417 
418 int DEventRFBunch_factory::Break_TieVote_Neutrals(map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
419 {
420  //Break tie with highest total shower energy
421 
422  int locBestRFBunchShift = 0;
423  double locHighestTotalEnergy = 0.0;
424 
425  set<int>::const_iterator locSetIterator = locBestRFBunchShifts.begin();
426  for(; locSetIterator != locBestRFBunchShifts.end(); ++locSetIterator)
427  {
428  int locRFBunchShift = *locSetIterator;
429  double locTotalEnergy = 0.0;
430 
431  const vector<const JObject*>& locVoters = locNumBeamBucketsShiftedMap[locRFBunchShift];
432  for(size_t loc_i = 0; loc_i < locVoters.size(); ++loc_i)
433  {
434  // the pointers in locVoters that we care about will either be those to DBCALShower
435  // or DFCALShower objects -- figure out which and record the energy
436 
437  const DFCALShower* fcalShower = dynamic_cast< const DFCALShower* >( locVoters[loc_i] );
438  if( fcalShower != NULL ){
439 
440  locTotalEnergy += fcalShower->getEnergy();
441  }
442  else{
443 
444  const DBCALShower* bcalShower = dynamic_cast< const DBCALShower* >( locVoters[loc_i] );
445  if( bcalShower != NULL ){
446 
447  locTotalEnergy += bcalShower->E;
448  }
449  }
450  }
451 
452  if(locTotalEnergy > locHighestTotalEnergy)
453  {
454  locHighestTotalEnergy = locTotalEnergy;
455  locBestRFBunchShift = locRFBunchShift;
456  }
457  }
458 
459  return locBestRFBunchShift;
460 }
461 
462 jerror_t DEventRFBunch_factory::Select_RFBunch_NoRFTime(JEventLoop* locEventLoop, vector<const DTrackTimeBased*>& locTrackTimeBasedVector)
463 {
464  //If no RF time:
465  //Use SC hits that have a track match to compute RF time guess, if any
466  //Times could be modulo the rf-frequency still: line them up (after propagating to beamline)
467  //Use RF time guess to vote, just as in found-rf-time case
468  //If none:
469  //Set RF time as NaN
470 
471  const DDetectorMatches* locDetectorMatches = NULL;
472  locEventLoop->GetSingle(locDetectorMatches);
473 
474  vector<pair<double, const JObject*> > locTimes;
475  if(!Find_TrackTimes_SCTOF(locDetectorMatches, locTrackTimeBasedVector, locTimes))
476  return Create_NaNRFBunch();
477  DetectorSystem_t locTimeSource = SYS_START;
478 
479  double locRFTimeGuess, locTimeVariance;
480  Get_RFTimeGuess(locTimes, locRFTimeGuess, locTimeVariance);
481 
482  //OK, now have RF time guess: vote
483  int locHighestNumVotes = 0;
484  int locBestRFBunchShift = Conduct_Vote(locEventLoop, locRFTimeGuess, locTimes, true, locHighestNumVotes);
485 
486  DEventRFBunch *locEventRFBunch = new DEventRFBunch;
487  locEventRFBunch->dTime = locRFTimeGuess + dBeamBunchPeriod*double(locBestRFBunchShift);
488  locEventRFBunch->dTimeVariance = locTimeVariance;
489  locEventRFBunch->dNumParticleVotes = locHighestNumVotes;
490  locEventRFBunch->dTimeSource = locTimeSource;
491  _data.push_back(locEventRFBunch);
492 
493  return NOERROR;
494 }
495 
496 bool DEventRFBunch_factory::Get_RFTimeGuess(JEventLoop* locEventLoop, double& locRFTimeGuess, double& locRFVariance, DetectorSystem_t& locTimeSource) const
497 {
498  //Meant to be called externally
499 
500  //Only call if no RF time:
501  //Use SC hits that have a track match to compute RF time guess, if any
502  //Times could be modulo the rf-frequency still: line them up
503 
504  vector<const DTrackTimeBased*> locTrackTimeBasedVector;
505  Select_GoodTracks(locEventLoop, locTrackTimeBasedVector);
506 
507  const DDetectorMatches* locDetectorMatches = NULL;
508  locEventLoop->GetSingle(locDetectorMatches);
509 
510  locTimeSource = SYS_NULL;
511  vector<pair<double, const JObject*> > locTimes;
512  if(!Find_TrackTimes_SCTOF(locDetectorMatches, locTrackTimeBasedVector, locTimes))
513  return false;
514  locTimeSource = SYS_START;
515 
516  Get_RFTimeGuess(locTimes, locRFTimeGuess, locRFVariance);
517  return true;
518 }
519 
520 void DEventRFBunch_factory::Get_RFTimeGuess(vector<pair<double, const JObject*> >& locTimes, double& locRFTimeGuess, double& locRFVariance) const
521 {
522  //Only call if no RF time:
523  //Use SC hits that have a track match to compute RF time guess, if any
524  //Times could be modulo the rf-frequency still: line them up
525 
526  locRFTimeGuess = locTimes[0].first;
527  for(size_t loc_i = 1; loc_i < locTimes.size(); ++loc_i)
528  {
529  double locDeltaT = locTimes[loc_i].first - locTimes[0].first;
530  double locNumBeamBucketsShifted = (locDeltaT > 0.0) ? floor(locDeltaT/dBeamBunchPeriod + 0.5) : floor(locDeltaT/dBeamBunchPeriod - 0.5);
531  locRFTimeGuess += locTimes[loc_i].first - locNumBeamBucketsShifted*dBeamBunchPeriod;
532  }
533  locRFTimeGuess /= double(locTimes.size());
534 
535  locRFVariance = 0.3*0.3/double(locTimes.size()); //Un-hard-code SC time resolution!!
536 }
537 
539 {
540  DEventRFBunch* locEventRFBunch = new DEventRFBunch;
541  locEventRFBunch->dTime = numeric_limits<double>::quiet_NaN();
542  locEventRFBunch->dTimeVariance = numeric_limits<double>::quiet_NaN();
543  locEventRFBunch->dNumParticleVotes = 0;
544  locEventRFBunch->dTimeSource = SYS_NULL;
545  _data.push_back(locEventRFBunch);
546 
547  return NOERROR;
548 }
549 
550 //------------------
551 // erun
552 //------------------
554 {
555  return NOERROR;
556 }
557 
558 //------------------
559 // fini
560 //------------------
562 {
563  return NOERROR;
564 }
565 
jerror_t Select_RFBunch_NoRFTime(JEventLoop *locEventLoop, vector< const DTrackTimeBased * > &locTrackTimeBasedVector)
double getEnergy() const
Definition: DFCALShower.h:156
jerror_t brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
Called everytime a new run number is detected.
jerror_t init(void)
Called once at program start.
float chisq
Chi-squared for the track (not chisq/dof!)
Definition: GlueX.h:30
bool Get_RFTimeGuess(JEventLoop *locEventLoop, double &locRFTimeGuess, double &locRFVariance, DetectorSystem_t &locTimeSource) const
double z(void) const
TVector3 DVector3
Definition: DVector3.h:14
Definition: GlueX.h:16
bool Break_TieVote_BeamPhotons(vector< const DBeamPhoton * > &locBeamPhotons, double locRFTime, map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts, int locHighestNumVotes)
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
double dTimeVariance
Definition: DRFTime.h:25
double getTime() const
Definition: DFCALShower.h:161
#define y
int Find_BestRFBunchShifts(double locRFHitTime, const vector< pair< double, const JObject * > > &locTimes, map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)
double dTime
Definition: DRFTime.h:24
bool Find_NeutralTimes(JEventLoop *locEventLoop, vector< pair< double, const JObject * > > &locTimes)
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t eventnumber)
Called every event.
jerror_t fini(void)
Called after last event of last event source has been processed.
DetectorSystem_t
Definition: GlueX.h:15
DGeometry * GetDGeometry(unsigned int run_number)
int Conduct_Vote(JEventLoop *locEventLoop, double locRFTime, vector< pair< double, const JObject * > > &locTimes, bool locUsedTracksFlag, int &locHighestNumVotes)
int Ndof
Number of degrees of freedom in the fit.
double dTimeVariance
Definition: DEventRFBunch.h:31
int Break_TieVote_Neutrals(map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)
bool Find_TrackTimes_SCTOF(const DDetectorMatches *locDetectorMatches, const vector< const DTrackTimeBased * > &locTrackTimeBasedVector, vector< pair< double, const JObject * > > &locTimes) const
int Break_TieVote_Tracks(map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)
const DVector3 & momentum(void) const
void Select_GoodTracks(JEventLoop *locEventLoop, vector< const DTrackTimeBased * > &locSelectedTimeBasedTracks) const
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
DetectorSystem_t dTimeSource
Definition: DEventRFBunch.h:28
unsigned int dNumParticleVotes
Definition: DEventRFBunch.h:32
bool GetTargetZ(double &z_target) const
z-location of center of target
Definition: DGeometry.cc:1933
jerror_t Select_RFBunch(JEventLoop *locEventLoop, vector< const DTrackTimeBased * > &locTrackTimeBasedVector, const DRFTime *locRFTime)
bool Find_TrackTimes_All(const DDetectorMatches *locDetectorMatches, const vector< const DTrackTimeBased * > &locTrackTimeBasedVector, vector< pair< double, const JObject * > > &locTimes)