Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventRFBunch_factory_Calibrations.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DEventRFBunch_factory_Calibrations.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 
10 using namespace jana;
11 
12 //------------------
13 // init
14 //------------------
16 {
17  dMinTrackingFOM = 0.001;
18  dRFTDCSourceSystem = SYS_TOF;
19  dMinHitRingsPerCDCSuperlayer = 2;
20  dMinHitPlanesPerFDCPackage = 4;
21 
22  string locSystemName = "";
23  gPARMS->SetDefaultParameter("RF_CALIB:SOURCE_SYSTEM", locSystemName);
24  if(locSystemName != "")
25  dRFTDCSourceSystem = NameToSystem(locSystemName.c_str());
26 
27 
28  return NOERROR;
29 }
30 
31 //------------------
32 // brun
33 //------------------
34 jerror_t DEventRFBunch_factory_Calibrations::brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
35 {
36  DApplication* locApplication = dynamic_cast<DApplication*>(locEventLoop->GetJApplication());
37  DGeometry* locGeometry = locApplication->GetDGeometry(runnumber);
38 
39  vector<double> locBeamPeriodVector;
40  locEventLoop->GetCalib("PHOTON_BEAM/RF/beam_period", locBeamPeriodVector);
41  dBeamBunchPeriod = locBeamPeriodVector[0];
42 
43  double locTargetCenterZ;
44  locGeometry->GetTargetZ(locTargetCenterZ);
45  dTargetCenter.SetXYZ(0.0, 0.0, locTargetCenterZ);
46 
47  locEventLoop->GetSingle(dParticleID);
48 
49  dCutAction_TrackHitPattern = new DCutAction_TrackHitPattern(NULL, dMinHitRingsPerCDCSuperlayer, dMinHitPlanesPerFDCPackage);
50  dCutAction_TrackHitPattern->Initialize(locEventLoop);
51 
52  return NOERROR;
53 }
54 
55 //------------------
56 // evnt
57 //------------------
58 jerror_t DEventRFBunch_factory_Calibrations::evnt(JEventLoop* locEventLoop, uint64_t eventnumber)
59 {
60  //There should ALWAYS be one and only one DEventRFBunch created.
61  //If there is not enough information, time is set to NaN
62 
63  //This factory is designed for calibrating the timing offsets between the tagger & SC.
64  //It gets one RF time signal from the F1TDC system of choice, and tries to select the correct bunch using tracks hitting the SC.
65  //It uses wire-based tracks instead of time-based tracks since the timing has not yet been calibrated.
66 
67  //Select Good Tracks
68  vector<const DTrackWireBased*> locTrackWireBasedVector;
69  Select_GoodTracks(locEventLoop, locTrackWireBasedVector);
70 
71  //Get RF Time
72  vector<const DRFTDCDigiTime*> locRFTDCDigiTimes;
73  locEventLoop->Get(locRFTDCDigiTimes);
74 
75  const DTTabUtilities* locTTabUtilities = NULL;
76  locEventLoop->GetSingle(locTTabUtilities);
77 
78  double locRFTime = numeric_limits<double>::quiet_NaN();
79  bool locHitFoundFlag = false;
80  for(size_t loc_i = 0; loc_i < locRFTDCDigiTimes.size(); ++loc_i)
81  {
82  const DRFTDCDigiTime* locRFTDCDigiTime = locRFTDCDigiTimes[loc_i];
83  if(locRFTDCDigiTime->dSystem != dRFTDCSourceSystem)
84  continue;
85 
86  if(locRFTDCDigiTime->dIsCAENTDCFlag)
87  locRFTime = locTTabUtilities->Convert_DigiTimeToNs_CAEN1290TDC(locRFTDCDigiTime);
88  else
89  locRFTime = locTTabUtilities->Convert_DigiTimeToNs_F1TDC(locRFTDCDigiTime);
90 
91  locHitFoundFlag = true;
92  break;
93  }
94 
95  if(!locHitFoundFlag)
96  return Create_NaNRFBunch();
97 
98  //Select RF Bunch:
99  return Select_RFBunch(locEventLoop, locTrackWireBasedVector, locRFTime);
100 }
101 
102 void DEventRFBunch_factory_Calibrations::Select_GoodTracks(JEventLoop* locEventLoop, vector<const DTrackWireBased*>& locSelectedWireBasedTracks) const
103 {
104  //Select tracks:
105  //For each particle (DTrackWireBased::candidateid), use the DTrackWireBased with the best tracking FOM
106  //Only use DTrackWireBased's with tracking FOM > dMinTrackingFOM
107 
108  locSelectedWireBasedTracks.clear();
109 
110  vector<const DTrackWireBased*> locTrackWireBasedVector;
111  locEventLoop->Get(locTrackWireBasedVector);
112 
113  //select the best DTrackWireBased for each track: of tracks with good hit pattern, use best tracking FOM
114  map<JObject::oid_t, const DTrackWireBased*> locBestTrackWireBasedMap; //lowest tracking chisq/ndf for each candidate id
115  for(size_t loc_i = 0; loc_i < locTrackWireBasedVector.size(); ++loc_i)
116  {
117  if(locTrackWireBasedVector[loc_i]->FOM < dMinTrackingFOM)
118  continue;
119  if(!dCutAction_TrackHitPattern->Cut_TrackHitPattern(dParticleID, locTrackWireBasedVector[loc_i]))
120  continue;
121  JObject::oid_t locCandidateID = locTrackWireBasedVector[loc_i]->candidateid;
122  if(locBestTrackWireBasedMap.find(locCandidateID) == locBestTrackWireBasedMap.end())
123  locBestTrackWireBasedMap[locCandidateID] = locTrackWireBasedVector[loc_i];
124  else if(locTrackWireBasedVector[loc_i]->FOM > (dynamic_cast<const DTrackWireBased*>(locBestTrackWireBasedMap[locCandidateID]))->FOM)
125  locBestTrackWireBasedMap[locCandidateID] = locTrackWireBasedVector[loc_i];
126  }
127 
128  //Save to the vector
129  map<JObject::oid_t, const DTrackWireBased*>::iterator locIterator;
130  for(locIterator = locBestTrackWireBasedMap.begin(); locIterator != locBestTrackWireBasedMap.end(); ++locIterator)
131  locSelectedWireBasedTracks.push_back(locIterator->second);
132 }
133 
134 jerror_t DEventRFBunch_factory_Calibrations::Select_RFBunch(JEventLoop* locEventLoop, vector<const DTrackWireBased*>& locTrackWireBasedVector, double locRFTime)
135 {
136  //If RF Time present:
137  //Use tracks with matching SC hits, if any
138  //If None: set DEventRFBunch::dTime to NaN
139 
140  vector<const DDetectorMatches*> locDetectorMatchVector;
141  locEventLoop->Get(locDetectorMatchVector, "WireBased");
142  if(locDetectorMatchVector.empty())
143  {
144  cout << "WARNING: WIREBASED TRACKS NOT PRESENT IN DEventRFBunch_factory_Calibrations(). RETURNING NaN." << endl;
145  return Create_NaNRFBunch();
146  }
147  const DDetectorMatches* locDetectorMatches = locDetectorMatchVector[0];
148 
149  vector<pair<double, const JObject*> > locTimes;
150  int locBestRFBunchShift = 0, locHighestNumVotes = 0;
151 
152  //Use tracks with matching SC hits, if any
153  if(Find_TrackTimes_SC(locDetectorMatches, locTrackWireBasedVector, locTimes))
154  locBestRFBunchShift = Conduct_Vote(locEventLoop, locRFTime, locTimes, locHighestNumVotes);
155  else //SET NaN
156  return Create_NaNRFBunch();
157 
158  DEventRFBunch* locEventRFBunch = new DEventRFBunch;
159  locEventRFBunch->dTime = locRFTime + dBeamBunchPeriod*double(locBestRFBunchShift);
160  locEventRFBunch->dTimeVariance = 0.0;
161  locEventRFBunch->dNumParticleVotes = locHighestNumVotes;
162  locEventRFBunch->dTimeSource = SYS_RF;
163  _data.push_back(locEventRFBunch);
164 
165  return NOERROR;
166 }
167 
168 bool DEventRFBunch_factory_Calibrations::Find_TrackTimes_SC(const DDetectorMatches* locDetectorMatches, const vector<const DTrackWireBased*>& locTrackWireBasedVector, vector<pair<double, const JObject*> >& locTimes) const
169 {
170  locTimes.clear();
171  for(size_t loc_i = 0; loc_i < locTrackWireBasedVector.size(); ++loc_i)
172  {
173  const DTrackWireBased* locTrackWireBased = locTrackWireBasedVector[loc_i];
174 
175  shared_ptr<const DSCHitMatchParams> locSCHitMatchParams;
176  if(!dParticleID->Get_BestSCMatchParams(locTrackWireBased, locDetectorMatches, locSCHitMatchParams))
177  continue;
178 
179  double locPropagatedTime = locSCHitMatchParams->dHitTime - locSCHitMatchParams->dFlightTime + (dTargetCenter.Z() - locTrackWireBased->z())/29.9792458;
180  locTimes.push_back(pair<double, const JObject*>(locPropagatedTime, locTrackWireBased));
181  }
182 
183  return (!locTimes.empty());
184 }
185 
186 int DEventRFBunch_factory_Calibrations::Conduct_Vote(JEventLoop* locEventLoop, double locRFTime, vector<pair<double, const JObject*> >& locTimes, int& locHighestNumVotes)
187 {
188  map<int, vector<const JObject*> > locNumBeamBucketsShiftedMap;
189  set<int> locBestRFBunchShifts;
190 
191  locHighestNumVotes = Find_BestRFBunchShifts(locRFTime, locTimes, locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
192  if(locBestRFBunchShifts.size() == 1)
193  return *locBestRFBunchShifts.begin();
194 
195  //break tie with total track hits (ndf), else break with total tracking chisq
196  return Break_TieVote_Tracks(locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
197 }
198 
199 int DEventRFBunch_factory_Calibrations::Find_BestRFBunchShifts(double locRFHitTime, const vector<pair<double, const JObject*> >& locTimes, map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
200 {
201  //then find the #beam buckets the RF time needs to shift to match it
202  int locHighestNumVotes = 0;
203  locNumBeamBucketsShiftedMap.clear();
204  locBestRFBunchShifts.clear();
205 
206  for(unsigned int loc_i = 0; loc_i < locTimes.size(); ++loc_i)
207  {
208  double locDeltaT = locTimes[loc_i].first - locRFHitTime;
209  int locNumBeamBucketsShifted = (locDeltaT > 0.0) ? int(locDeltaT/dBeamBunchPeriod + 0.5) : int(locDeltaT/dBeamBunchPeriod - 0.5);
210  locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].push_back(locTimes[loc_i].second);
211 
212  int locNumVotesThisShift = locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].size();
213  if(locNumVotesThisShift > locHighestNumVotes)
214  {
215  locHighestNumVotes = locNumVotesThisShift;
216  locBestRFBunchShifts.clear();
217  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
218  }
219  else if(locNumVotesThisShift == locHighestNumVotes)
220  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
221  }
222 
223  return locHighestNumVotes;
224 }
225 
226 int DEventRFBunch_factory_Calibrations::Break_TieVote_Tracks(map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
227 {
228  //Select the bunch with the most total track hits (highest total tracking NDF)
229  //If still a tie:
230  //Select the bunch with the lowest total chisq
231 
232  int locBestRFBunchShift = 0;
233  pair<int, double> locBestTrackingTotals(-1, 9.9E99); //ndf, chisq
234 
235  set<int>::const_iterator locSetIterator = locBestRFBunchShifts.begin();
236  for(; locSetIterator != locBestRFBunchShifts.end(); ++locSetIterator)
237  {
238  int locRFBunchShift = *locSetIterator;
239  int locTotalTrackingNDF = 0;
240  double locTotalTrackingChiSq = 0.0;
241 
242  const vector<const JObject*>& locVoters = locNumBeamBucketsShiftedMap[locRFBunchShift];
243  for(size_t loc_i = 0; loc_i < locVoters.size(); ++loc_i)
244  {
245  const DTrackWireBased* locTrackWireBased = dynamic_cast<const DTrackWireBased*>(locVoters[loc_i]);
246  if(locTrackWireBased == NULL)
247  continue;
248  locTotalTrackingNDF += locTrackWireBased->Ndof;
249  locTotalTrackingChiSq += locTrackWireBased->chisq;
250  }
251 
252  if(locTotalTrackingNDF > locBestTrackingTotals.first)
253  {
254  locBestTrackingTotals = pair<int, double>(locTotalTrackingNDF, locTotalTrackingChiSq);
255  locBestRFBunchShift = locRFBunchShift;
256  }
257  else if((locTotalTrackingNDF == locBestTrackingTotals.first) && (locTotalTrackingChiSq < locBestTrackingTotals.second))
258  {
259  locBestTrackingTotals = pair<int, double>(locTotalTrackingNDF, locTotalTrackingChiSq);
260  locBestRFBunchShift = locRFBunchShift;
261  }
262  }
263 
264  return locBestRFBunchShift;
265 }
266 
268 {
269  DEventRFBunch* locEventRFBunch = new DEventRFBunch;
270  locEventRFBunch->dTime = numeric_limits<double>::quiet_NaN();
271  locEventRFBunch->dTimeVariance = numeric_limits<double>::quiet_NaN();
272  locEventRFBunch->dNumParticleVotes = 0;
273  locEventRFBunch->dTimeSource = SYS_NULL;
274  _data.push_back(locEventRFBunch);
275 
276  return NOERROR;
277 }
278 
279 //------------------
280 // erun
281 //------------------
283 {
284  return NOERROR;
285 }
286 
287 //------------------
288 // fini
289 //------------------
291 {
292  return NOERROR;
293 }
294 
jerror_t brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
Called everytime a new run number is detected.
int Find_BestRFBunchShifts(double locRFHitTime, const vector< pair< double, const JObject * > > &locTimes, map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t eventnumber)
Called every event.
int Conduct_Vote(JEventLoop *locEventLoop, double locRFTime, vector< pair< double, const JObject * > > &locTimes, int &locHighestNumVotes)
double Convert_DigiTimeToNs_F1TDC(const JObject *locTDCDigiHit) const
jerror_t Select_RFBunch(JEventLoop *locEventLoop, vector< const DTrackWireBased * > &locTrackWireBasedVector, double locRFTime)
float chisq
Chi-squared for the track (not chisq/dof!)
Definition: GlueX.h:30
double z(void) const
Definition: GlueX.h:16
jerror_t fini(void)
Called after last event of last event source has been processed.
double Convert_DigiTimeToNs_CAEN1290TDC(const JObject *locTDCDigiHit) const
Definition: GlueX.h:20
DetectorSystem_t NameToSystem(const char *locSystemName)
Definition: GlueX.h:105
DGeometry * GetDGeometry(unsigned int run_number)
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
void Select_GoodTracks(JEventLoop *locEventLoop, vector< const DTrackWireBased * > &locSelectedWireBasedTracks) const
double dTimeVariance
Definition: DEventRFBunch.h:31
DetectorSystem_t dSystem
int Ndof
Number of degrees of freedom in the fit.
DetectorSystem_t dTimeSource
Definition: DEventRFBunch.h:28
bool Find_TrackTimes_SC(const DDetectorMatches *locDetectorMatches, const vector< const DTrackWireBased * > &locTrackWireBasedVector, vector< pair< double, const JObject * > > &locTimes) const
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 init(void)
Called once at program start.
int Break_TieVote_Tracks(map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)