Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DRFTime_factory.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DRFTime_factory.cc
4 // Created: Mon Mar 30 10:51:29 EDT 2015
5 // Creator: pmatt (on Linux pmattdesktop.jlab.org 2.6.32-504.12.2.el6.x86_64 x86_64)
6 //
7 
8 #include "DRFTime_factory.h"
9 
10 //------------------
11 // init
12 //------------------
13 jerror_t DRFTime_factory::init(void)
14 {
16  return NOERROR;
17 }
18 
19 //------------------
20 // brun
21 //------------------
22 jerror_t DRFTime_factory::brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
23 {
24  //RF Period
25  vector<double> locBeamPeriodVector;
26  locEventLoop->GetCalib("PHOTON_BEAM/RF/beam_period", locBeamPeriodVector);
27  dBeamBunchPeriod = locBeamPeriodVector[0];
28 
29  //Time Offsets
30  map<string, double> locCCDBMap;
31  map<string, double>::iterator locIterator;
32  if(locEventLoop->GetCalib("/PHOTON_BEAM/RF/time_offset", locCCDBMap))
33  jout << "Error loading /PHOTON_BEAM/RF/time_offset !" << endl;
34  for(locIterator = locCCDBMap.begin(); locIterator != locCCDBMap.end(); ++locIterator)
35  {
36  DetectorSystem_t locSystem = NameToSystem(locIterator->first.c_str());
37  dTimeOffsetMap[locSystem] = locIterator->second;
38  }
39 
40  //Time Offset Variances
41  if(locEventLoop->GetCalib("/PHOTON_BEAM/RF/time_offset_var", locCCDBMap))
42  jout << "Error loading /PHOTON_BEAM/RF/time_offset_var !" << endl;
43  for(locIterator = locCCDBMap.begin(); locIterator != locCCDBMap.end(); ++locIterator)
44  {
45  DetectorSystem_t locSystem = NameToSystem(locIterator->first.c_str());
46  dTimeOffsetVarianceMap[locSystem] = locIterator->second;
47  }
48 
49  //Time Resolution Squared
50  if(locEventLoop->GetCalib("/PHOTON_BEAM/RF/time_resolution_sq", locCCDBMap))
51  jout << "Error loading /PHOTON_BEAM/RF/time_resolution_sq !" << endl;
52  for(locIterator = locCCDBMap.begin(); locIterator != locCCDBMap.end(); ++locIterator)
53  {
54  DetectorSystem_t locSystem = NameToSystem(locIterator->first.c_str());
55  dTimeResolutionSqMap[locSystem] = locIterator->second;
56  }
57 
58  string locSystemName = "NULL";
59  gPARMS->SetDefaultParameter("RF:SOURCE_SYSTEM", locSystemName);
60  dOverrideRFSourceSystem = NameToSystem(locSystemName.c_str());
61 
62  return NOERROR;
63 }
64 
65 //------------------
66 // evnt
67 //------------------
68 jerror_t DRFTime_factory::evnt(JEventLoop *locEventLoop, uint64_t eventnumber)
69 {
70  //The RF Time is defined at the center of the target
71  //The time offset needed to line it up to the center of the target is absorbed into the calibration constants.
72 
73  vector<const DRFTDCDigiTime*> locRFTDCDigiTimes;
74  locEventLoop->Get(locRFTDCDigiTimes);
75 
76  const DTTabUtilities* locTTabUtilities = NULL;
77  locEventLoop->GetSingle(locTTabUtilities);
78 
79  //Get All RF Times
80  map<DetectorSystem_t, vector<double> > locRFTimesMap;
81 
82  //F1TDC's
83  for(size_t loc_i = 0; loc_i < locRFTDCDigiTimes.size(); ++loc_i)
84  {
85  const DRFTDCDigiTime* locRFTDCDigiTime = locRFTDCDigiTimes[loc_i];
86  DetectorSystem_t locSystem = locRFTDCDigiTime->dSystem;
87  if(dTimeOffsetMap.find(locSystem) == dTimeOffsetMap.end())
88  continue; //system not recognized
89  double locRFTime = Convert_TDCToTime(locRFTDCDigiTime, locTTabUtilities);
90  locRFTimesMap[locSystem].push_back(locRFTime);
91  }
92 
93  if(locRFTimesMap.empty())
94  return NOERROR; //No RF signals, will try to emulate RF bunch time from timing from other systems
95 
96  //Prefer to use the system with the best timing resolution (TOF if present)
97  //Seems to be an additional jitter when averaging times between systems
98 
99  //Find the best system present in the data
100  DetectorSystem_t locBestSystem = SYS_NULL;
101  if(locRFTimesMap.find(dOverrideRFSourceSystem) != locRFTimesMap.end())
102  locBestSystem = dOverrideRFSourceSystem; //Overriden on command line: use this system
103  else
104  {
105  //Not overriden or not present, search for the system with the best resolution
106  map<DetectorSystem_t, double>::iterator locResolutionIterator = dTimeResolutionSqMap.begin();
107  double locBestResolution = 9.9E9;
108  for(; locResolutionIterator != dTimeResolutionSqMap.end(); ++locResolutionIterator)
109  {
110  DetectorSystem_t locSystem = locResolutionIterator->first;
111  if(locRFTimesMap.find(locSystem) == locRFTimesMap.end())
112  continue; // this system is not in the data stream for this event
113  if(locResolutionIterator->second >= locBestResolution)
114  continue;
115  locBestResolution = locResolutionIterator->second;
116  locBestSystem = locResolutionIterator->first;
117  }
118  }
119 
120  //Use it (remove the others)
121  map<DetectorSystem_t, vector<double> >::iterator locTimeIterator = locRFTimesMap.begin();
122  while(locTimeIterator != locRFTimesMap.end())
123  {
124  if(locTimeIterator->first != locBestSystem)
125  locRFTimesMap.erase(locTimeIterator++);
126  else
127  ++locTimeIterator;
128  }
129 
130  if(locRFTimesMap.empty())
131  return NOERROR; //No RF signals, will try to emulate RF bunch time from timing from other systems
132 
133  //Calculate the average RF time
134  double locRFTimeVariance = 0.0;
135  double locAverageRFTime = Calc_WeightedAverageRFTime(locRFTimesMap, locRFTimeVariance);
136 
137  DRFTime* locRFTime = new DRFTime();
138  locRFTime->dTime = locAverageRFTime; //This time is defined at the center of the target (offsets with other detectors center it)
139  locRFTime->dTimeVariance = locRFTimeVariance;
140  _data.push_back(locRFTime);
141 
142  return NOERROR;
143 }
144 
145 double DRFTime_factory::Step_TimeToNearInputTime(double locTimeToStep, double locTimeToStepTo) const
146 {
147  return Step_TimeToNearInputTime(locTimeToStep, locTimeToStepTo, dBeamBunchPeriod);
148 }
149 
150 double DRFTime_factory::Step_TimeToNearInputTime(double locTimeToStep, double locTimeToStepTo, double locPeriod) const
151 {
152  double locDeltaT = locTimeToStepTo - locTimeToStep;
153  int locNumBucketsToShift = (locDeltaT > 0.0) ? int(locDeltaT/locPeriod + 0.5) : int(locDeltaT/locPeriod - 0.5);
154  return (locTimeToStep + locPeriod*double(locNumBucketsToShift));
155 }
156 
157 double DRFTime_factory::Convert_TDCToTime(const DRFTDCDigiTime* locRFTDCDigiTime, const DTTabUtilities* locTTabUtilities) const
158 {
159  double locRFTime = 0.0;
160  if(locRFTDCDigiTime->dIsCAENTDCFlag)
161  locRFTime = locTTabUtilities->Convert_DigiTimeToNs_CAEN1290TDC(locRFTDCDigiTime);
162  else
163  locRFTime = locTTabUtilities->Convert_DigiTimeToNs_F1TDC(locRFTDCDigiTime);
164 
165  map<DetectorSystem_t, double>::const_iterator locIterator = dTimeOffsetMap.find(locRFTDCDigiTime->dSystem);
166  if(locIterator != dTimeOffsetMap.end())
167  locRFTime -= locIterator->second;
168  return locRFTime;
169 }
170 
171 double DRFTime_factory::Calc_WeightedAverageRFTime(map<DetectorSystem_t, vector<double> >& locRFTimesMap, double& locRFTimeVariance) const
172 {
173  //returns the average (and the variance by reference)
174 
175  //will line up the first time near zero, then line up subsequent times to the first time
176  //cannot line up all times to zero: if first time is near +/- beam_period/2 (e.g. +/- 2.004 ns),
177  //may end up with some times near 2.004 and some near -2.004!
178 
179  map<DetectorSystem_t, vector<double> >::iterator locTimeIterator = locRFTimesMap.begin();
180  double locFirstTime = (locTimeIterator->second)[0];
181  locFirstTime = Step_TimeToNearInputTime(locFirstTime, 0.0);
182 
183  //take weighted average of times
184  //avg = Sum(w_i * x_i) / Sum (w_i)
185  //w_i = 1/varx_i
186  //avg = Sum(x_i / varx_i) / Sum (1 / varx_i)
187  //var_avg = 1 / Sum (1 / varx_i)
188  //avg = Sum(x_i / varx_i) * var_avg
189 
190  double locSumOneOverTimeVariance = 0.0;
191  double locSumTimeOverTimeVariance = 0.0;
192  for(; locTimeIterator != locRFTimesMap.end(); ++locTimeIterator)
193  {
194  DetectorSystem_t locSystem = locTimeIterator->first;
195  vector<double>& locRFTimes = locTimeIterator->second;
196 
197  double locSingleTimeVariance = dTimeResolutionSqMap.find(locSystem)->second + dTimeOffsetVarianceMap.find(locSystem)->second;
198  if(!(locSingleTimeVariance > 0.0))
199  continue;
200  locSumOneOverTimeVariance += double(locRFTimes.size()) / locSingleTimeVariance;
201 
202  for(size_t loc_i = 0; loc_i < locRFTimes.size(); ++loc_i)
203  {
204  double locShiftedRFTime = Step_TimeToNearInputTime(locRFTimes[loc_i], locFirstTime);
205  locSumTimeOverTimeVariance += locShiftedRFTime / locSingleTimeVariance;
206  }
207  }
208 
209  if(!(locSumOneOverTimeVariance > 0.0))
210  {
211  locRFTimeVariance = numeric_limits<double>::quiet_NaN();
212  return locRFTimesMap.begin()->second.front();
213  }
214 
215  locRFTimeVariance = 1.0 / locSumOneOverTimeVariance;
216  double locAverageRFTime = locSumTimeOverTimeVariance * locRFTimeVariance;
217  return locAverageRFTime;
218 }
219 
220 //------------------
221 // erun
222 //------------------
223 jerror_t DRFTime_factory::erun(void)
224 {
225  return NOERROR;
226 }
227 
228 //------------------
229 // fini
230 //------------------
231 jerror_t DRFTime_factory::fini(void)
232 {
233  return NOERROR;
234 }
double Convert_DigiTimeToNs_F1TDC(const JObject *locTDCDigiHit) const
DetectorSystem_t dOverrideRFSourceSystem
Definition: GlueX.h:16
jerror_t init(void)
Called once at program start.
double dTimeVariance
Definition: DRFTime.h:25
double dTime
Definition: DRFTime.h:24
double Convert_DigiTimeToNs_CAEN1290TDC(const JObject *locTDCDigiHit) const
double Convert_TDCToTime(const DRFTDCDigiTime *locRFTDCDigiTime, const DTTabUtilities *locTTabUtilities) const
jerror_t fini(void)
Called after last event of last event source has been processed.
DetectorSystem_t
Definition: GlueX.h:15
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
map< DetectorSystem_t, double > dTimeOffsetMap
double Calc_WeightedAverageRFTime(map< DetectorSystem_t, vector< double > > &locRFTimesMap, double &locRFTimeVariance) const
DetectorSystem_t NameToSystem(const char *locSystemName)
Definition: GlueX.h:105
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
DetectorSystem_t dSystem
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
map< DetectorSystem_t, double > dTimeResolutionSqMap
map< DetectorSystem_t, double > dTimeOffsetVarianceMap
double Step_TimeToNearInputTime(double locTimeToStep, double locTimeToStepTo) const