Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventRFBunch_factory_CalorimeterOnly.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DEventRFBunch_factory_CalorimeterOnly.cc
4 //
5 
7 #include "BCAL/DBCALShower.h"
8 #include "FCAL/DFCALShower.h"
9 #include "CCAL/DCCALShower.h"
10 
11 using namespace jana;
12 
13 //------------------
14 // init
15 //------------------
17 {
18  dMinTrackingFOM = 0.0;
19 
20  USE_BCAL = false;
21  USE_CCAL = true;
22  USE_FCAL = true;
23 
24  gPARMS->SetDefaultParameter("EVENTRFBUNCH_CAL:USE_BCAL_SHOWERS", USE_BCAL, "Use BCAL showers for calorimeter-only RF bunch calculation");
25  gPARMS->SetDefaultParameter("EVENTRFBUNCH_CAL:USE_CCAL_SHOWERS", USE_CCAL, "Use CCAL showers for calorimeter-only RF bunch calculation");
26  gPARMS->SetDefaultParameter("EVENTRFBUNCH_CAL:USE_FCAL_SHOWERS", USE_FCAL, "Use FCAL showers for calorimeter-only RF bunch calculation");
27 
28  return NOERROR;
29 }
30 
31 //------------------
32 // brun
33 //------------------
34 jerror_t DEventRFBunch_factory_CalorimeterOnly::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  return NOERROR;
50 }
51 
52 //------------------
53 // evnt
54 //------------------
55 jerror_t DEventRFBunch_factory_CalorimeterOnly::evnt(JEventLoop* locEventLoop, uint64_t eventnumber)
56 {
57  //There should ALWAYS be one and only one DEventRFBunch created.
58  //If there is not enough information, time is set to NaN
59 
60  //Select RF Bunch:
61  vector<const DRFTime*> locRFTimes;
62  locEventLoop->Get(locRFTimes);
63  if(!locRFTimes.empty())
64  return Select_RFBunch(locEventLoop, locRFTimes[0]);
65  else
66  return Create_NaNRFBunch(); // there should always be RFTime data, otherwise there's not enough info to choose
67 }
68 
69 jerror_t DEventRFBunch_factory_CalorimeterOnly::Select_RFBunch(JEventLoop* locEventLoop, const DRFTime* locRFTime)
70 {
71  //If RF Time present:
72  // Let neutral showers vote (assume PID = photon) on RF bunch
73  //If None: set DEventRFBunch::dTime to NaN
74 
75  //Voting when RF time present:
76  //Propagate track/shower times to vertex
77  //Compare times to possible RF bunches, select the bunch with the most votes
78  //If there is a tie: let DBeamPhoton's vote to break tie
79  //If a tie, and voting with neutral showers:
80  //Select the bunch with the highest total shower energy
81 
82  const DDetectorMatches* locDetectorMatches = NULL;
83  locEventLoop->GetSingle(locDetectorMatches);
84 
85  vector<pair<double, const JObject*> > locTimes;
86  int locBestRFBunchShift = 0, locHighestNumVotes = 0;
87 
88  if(Find_NeutralTimes(locEventLoop, locTimes))
89  locBestRFBunchShift = Conduct_Vote(locEventLoop, locRFTime->dTime, locTimes, false, locHighestNumVotes);
90  else //PASS-THROUGH, WILL HAVE TO RESOLVE WHEN COMBOING
91  locBestRFBunchShift = 0;
92 
93  DEventRFBunch* locEventRFBunch = new DEventRFBunch();
94  locEventRFBunch->dTime = locRFTime->dTime + dBeamBunchPeriod*double(locBestRFBunchShift);
95  locEventRFBunch->dTimeVariance = locRFTime->dTimeVariance;
96  locEventRFBunch->dNumParticleVotes = locHighestNumVotes;
97  locEventRFBunch->dTimeSource = SYS_RF;
98  _data.push_back(locEventRFBunch);
99 
100  return NOERROR;
101 }
102 
103 int DEventRFBunch_factory_CalorimeterOnly::Conduct_Vote(JEventLoop* locEventLoop, double locRFTime, vector<pair<double, const JObject*> >& locTimes, bool locUsedTracksFlag, int& locHighestNumVotes)
104 {
105  map<int, vector<const JObject*> > locNumBeamBucketsShiftedMap;
106  set<int> locBestRFBunchShifts;
107 
108  locHighestNumVotes = Find_BestRFBunchShifts(locRFTime, locTimes, locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
109  if(locBestRFBunchShifts.size() == 1)
110  return *locBestRFBunchShifts.begin();
111 
112  //tied: break with beam photons
113  vector<const DBeamPhoton*> locBeamPhotons;
114  locEventLoop->Get(locBeamPhotons);
115  if(Break_TieVote_BeamPhotons(locBeamPhotons, locRFTime, locNumBeamBucketsShiftedMap, locBestRFBunchShifts, locHighestNumVotes))
116  return *locBestRFBunchShifts.begin();
117 
118  //break tie with highest total shower energy
119  return Break_TieVote_Neutrals(locNumBeamBucketsShiftedMap, locBestRFBunchShifts);
120 
121 }
122 
123 
124 bool DEventRFBunch_factory_CalorimeterOnly::Find_NeutralTimes(JEventLoop* locEventLoop, vector<pair<double, const JObject*> >& locTimes)
125 {
126  locTimes.clear();
127 
128  if(USE_FCAL) {
129  vector< const DFCALShower* > fcalShowers;
130  locEventLoop->Get( fcalShowers );
131 
132  for( size_t i = 0; i < fcalShowers.size(); ++i ){
133  DVector3 locHitPoint = fcalShowers[i]->getPosition();
134  DVector3 locPath = locHitPoint - dTargetCenter;
135  double locPathLength = locPath.Mag();
136  if(!(locPathLength > 0.0))
137  continue;
138 
139  double locFlightTime = locPathLength/29.9792458;
140  double locHitTime = fcalShowers[i]->getTime();
141  locTimes.push_back( pair< double, const JObject*>( locHitTime - locFlightTime, fcalShowers[i] ) );
142  }
143  }
144 
145  if(USE_BCAL) {
146  vector< const DBCALShower* > bcalShowers;
147  locEventLoop->Get( bcalShowers );
148 
149  for( size_t i = 0; i < bcalShowers.size(); ++i ){
150 
151  DVector3 locHitPoint( bcalShowers[i]->x, bcalShowers[i]->y, bcalShowers[i]->z );
152  DVector3 locPath = locHitPoint - dTargetCenter;
153  double locPathLength = locPath.Mag();
154  if(!(locPathLength > 0.0))
155  continue;
156 
157  double locFlightTime = locPathLength/29.9792458;
158  double locHitTime = bcalShowers[i]->t;
159  locTimes.push_back( pair< double, const JObject*>( locHitTime - locFlightTime, bcalShowers[i] ) );
160  }
161  }
162 
163  if(USE_CCAL) {
164  vector< const DCCALShower* > ccalShowers;
165  locEventLoop->Get( ccalShowers );
166 
167  for( size_t i = 0; i < ccalShowers.size(); ++i ){
168  DVector3 locHitPoint(ccalShowers[i]->x, ccalShowers[i]->y, ccalShowers[i]->z);
169  DVector3 locPath = locHitPoint - dTargetCenter;
170  double locPathLength = locPath.Mag();
171  if(!(locPathLength > 0.0))
172  continue;
173 
174  double locFlightTime = locPathLength/29.9792458;
175  double locHitTime = ccalShowers[i]->time;
176  locTimes.push_back( pair< double, const JObject*>( locHitTime - locFlightTime, ccalShowers[i] ) );
177  }
178  }
179 
180 
181  return (locTimes.size() > 1);
182 }
183 
184 int DEventRFBunch_factory_CalorimeterOnly::Find_BestRFBunchShifts(double locRFHitTime, const vector<pair<double, const JObject*> >& locTimes, map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
185 {
186  //then find the #beam buckets the RF time needs to shift to match it
187  int locHighestNumVotes = 0;
188  locNumBeamBucketsShiftedMap.clear();
189  locBestRFBunchShifts.clear();
190 
191  for(unsigned int loc_i = 0; loc_i < locTimes.size(); ++loc_i)
192  {
193  double locDeltaT = locTimes[loc_i].first - locRFHitTime;
194  int locNumBeamBucketsShifted = (locDeltaT > 0.0) ? int(locDeltaT/dBeamBunchPeriod + 0.5) : int(locDeltaT/dBeamBunchPeriod - 0.5);
195  locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].push_back(locTimes[loc_i].second);
196 
197  int locNumVotesThisShift = locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].size();
198  if(locNumVotesThisShift > locHighestNumVotes)
199  {
200  locHighestNumVotes = locNumVotesThisShift;
201  locBestRFBunchShifts.clear();
202  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
203  }
204  else if(locNumVotesThisShift == locHighestNumVotes)
205  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
206  }
207 
208  return locHighestNumVotes;
209 }
210 
211 bool DEventRFBunch_factory_CalorimeterOnly::Break_TieVote_BeamPhotons(vector<const DBeamPhoton*>& locBeamPhotons, double locRFTime, map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts, int locHighestNumVotes)
212 {
213  //locHighestNumVotes intentionally passed-in as value-type (non-reference)
214  //beam photons are only used to BREAK the tie, not count as equal votes
215 
216  set<int> locInputRFBunchShifts = locBestRFBunchShifts; //only test these RF bunch selections
217  for(size_t loc_i = 0; loc_i < locBeamPhotons.size(); ++loc_i)
218  {
219  double locDeltaT = locBeamPhotons[loc_i]->time() - locRFTime;
220  int locNumBeamBucketsShifted = (locDeltaT > 0.0) ? int(locDeltaT/dBeamBunchPeriod + 0.5) : int(locDeltaT/dBeamBunchPeriod - 0.5);
221  if(locInputRFBunchShifts.find(locNumBeamBucketsShifted) == locInputRFBunchShifts.end())
222  continue; //only use beam votes to break input tie, not contribute to other beam buckets
223 
224  locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].push_back(locBeamPhotons[loc_i]);
225 
226  int locNumVotesThisShift = locNumBeamBucketsShiftedMap[locNumBeamBucketsShifted].size();
227  if(locNumVotesThisShift > locHighestNumVotes)
228  {
229  locHighestNumVotes = locNumVotesThisShift;
230  locBestRFBunchShifts.clear();
231  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
232  }
233  else if(locNumVotesThisShift == locHighestNumVotes)
234  locBestRFBunchShifts.insert(locNumBeamBucketsShifted);
235  }
236 
237  return (locBestRFBunchShifts.size() == 1);
238 }
239 
240 
241 int DEventRFBunch_factory_CalorimeterOnly::Break_TieVote_Neutrals(map<int, vector<const JObject*> >& locNumBeamBucketsShiftedMap, set<int>& locBestRFBunchShifts)
242 {
243  //Break tie with highest total shower energy
244 
245  int locBestRFBunchShift = 0;
246  double locHighestTotalEnergy = 0.0;
247 
248  set<int>::const_iterator locSetIterator = locBestRFBunchShifts.begin();
249  for(; locSetIterator != locBestRFBunchShifts.end(); ++locSetIterator)
250  {
251  int locRFBunchShift = *locSetIterator;
252  double locTotalEnergy = 0.0;
253 
254  const vector<const JObject*>& locVoters = locNumBeamBucketsShiftedMap[locRFBunchShift];
255  for(size_t loc_i = 0; loc_i < locVoters.size(); ++loc_i)
256  {
257  // the pointers in locVoters that we care about will either be those to DBCALShower
258  // or DFCALShower objects -- figure out which and record the energy
259 
260  const DFCALShower* fcalShower = dynamic_cast< const DFCALShower* >( locVoters[loc_i] );
261  if( fcalShower != NULL ){
262 
263  locTotalEnergy += fcalShower->getEnergy();
264  }
265  else{
266 
267  const DBCALShower* bcalShower = dynamic_cast< const DBCALShower* >( locVoters[loc_i] );
268  if( bcalShower != NULL ){
269 
270  locTotalEnergy += bcalShower->E;
271  }
272  else{
273 
274  const DCCALShower* ccalShower = dynamic_cast< const DCCALShower* >( locVoters[loc_i] );
275  if( ccalShower != NULL ){
276 
277  locTotalEnergy += ccalShower->E;
278  }
279  }
280  }
281  }
282 
283  if(locTotalEnergy > locHighestTotalEnergy)
284  {
285  locHighestTotalEnergy = locTotalEnergy;
286  locBestRFBunchShift = locRFBunchShift;
287  }
288  }
289 
290  return locBestRFBunchShift;
291 }
292 
294 {
295  DEventRFBunch* locEventRFBunch = new DEventRFBunch;
296  locEventRFBunch->dTime = numeric_limits<double>::quiet_NaN();
297  locEventRFBunch->dTimeVariance = numeric_limits<double>::quiet_NaN();
298  locEventRFBunch->dNumParticleVotes = 0;
299  locEventRFBunch->dTimeSource = SYS_NULL;
300  _data.push_back(locEventRFBunch);
301 
302  return NOERROR;
303 }
304 
305 //------------------
306 // erun
307 //------------------
309 {
310  return NOERROR;
311 }
312 
313 //------------------
314 // fini
315 //------------------
317 {
318  return NOERROR;
319 }
320 
double getEnergy() const
Definition: DFCALShower.h:156
bool Break_TieVote_BeamPhotons(vector< const DBeamPhoton * > &locBeamPhotons, double locRFTime, map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts, int locHighestNumVotes)
Definition: GlueX.h:30
TVector3 DVector3
Definition: DVector3.h:14
Definition: GlueX.h:16
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
double dTimeVariance
Definition: DRFTime.h:25
#define y
jerror_t Select_RFBunch(JEventLoop *locEventLoop, const DRFTime *locRFTime)
double dTime
Definition: DRFTime.h:24
int Find_BestRFBunchShifts(double locRFHitTime, const vector< pair< double, const JObject * > > &locTimes, map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)
int Break_TieVote_Neutrals(map< int, vector< const JObject * > > &locNumBeamBucketsShiftedMap, set< int > &locBestRFBunchShifts)
int Conduct_Vote(JEventLoop *locEventLoop, double locRFTime, vector< pair< double, const JObject * > > &locTimes, bool locUsedTracksFlag, int &locHighestNumVotes)
DGeometry * GetDGeometry(unsigned int run_number)
jerror_t fini(void)
Called after last event of last event source has been processed.
jerror_t brun(jana::JEventLoop *locEventLoop, int32_t runnumber)
Called everytime a new run number is detected.
double E
Definition: DCCALShower.h:38
double dTimeVariance
Definition: DEventRFBunch.h:31
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t eventnumber)
Called every event.
bool Find_NeutralTimes(JEventLoop *locEventLoop, vector< pair< double, const JObject * > > &locTimes)
jerror_t init(void)
Called once at program start.
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 erun(void)
Called everytime run number changes, provided brun has been called.