Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventSourceEVIO.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DEventSourceEVIO.cc
4 // Created: Sat May 8 13:54:35 EDT 2010
5 // Creator: davidl (on Darwin Amelia.local 9.8.0 i386)
6 //
7 
8 #include <iostream>
9 using namespace std;
10 
11 #include <DANA/DApplication.h>
12 
13 #include "DEventSourceEVIO.h"
14 
15 
16 //---------------------------------
17 // DEventSourceEVIO (Constructor)
18 //---------------------------------
19 DEventSourceEVIO::DEventSourceEVIO(const char* source_name):JEventSource(source_name)
20 {
21  // Open the EVIO file, catching any exceptions
22  try {
23  chan = new evioFileChannel(source_name,"r", 65536);
24  chan->open();
25  jout << "Opened EVIO file \""<<source_name<<"\" for reading"<<endl;
26 
27  // Fill in tagMap
28  // We do this by hand for now, but will eventually get it from the XML dictionary file
29  tagMap["DTrackTimeBased"] = pair<int, int>(11500,0);
30  tagMap["DTrackTimeBased.objId"] = pair<int, int>(11500, 1);
31  tagMap["DTrackTimeBased.chisq"] = pair<int, int>(11500, 2);
32  tagMap["DTrackTimeBased.Ndof"] = pair<int, int>(11500, 3);
33  tagMap["DTrackTimeBased.FOM"] = pair<int, int>(11500, 4);
34  tagMap["DTrackTimeBased.x"] = pair<int, int>(11500, 5);
35  tagMap["DTrackTimeBased.y"] = pair<int, int>(11500, 6);
36  tagMap["DTrackTimeBased.z"] = pair<int, int>(11500, 7);
37  tagMap["DTrackTimeBased.px"] = pair<int, int>(11500, 8);
38  tagMap["DTrackTimeBased.py"] = pair<int, int>(11500, 9);
39  tagMap["DTrackTimeBased.pz"] = pair<int, int>(11500, 10);
40  tagMap["DTrackTimeBased.q"] = pair<int, int>(11500, 11);
41  tagMap["DTrackTimeBased.E"] = pair<int, int>(11500, 12);
42  tagMap["DTrackTimeBased.mass"] = pair<int, int>(11500, 13);
43  tagMap["DTrackTimeBased.t0"] = pair<int, int>(11500, 14);
44  tagMap["DTrackTimeBased.assocObjectBanks"] = pair<int, int>(11500, 254);
45  tagMap["DTrackTimeBased.assocObjects"] = pair<int, int>(11500, 255);
46 
47  }catch (evioException e) {
48  jerr << e.toString() << endl;
49  chan = NULL;
50  } catch (...) {
51  jerr << "?unknown exception" << endl;
52  chan = NULL;
53  }
54 
55  // Used for reference trajectories
56  pthread_mutex_init(&rt_mutex, NULL);
57 }
58 
59 //---------------------------------
60 // ~DEventSourceEVIO (Destructor)
61 //---------------------------------
63 {
64  // Close EVIO file, catching any exceptions
65  try {
66  if(chan){
67  chan->close();
68  delete(chan);
69  }
70  }catch (evioException e) {
71  jerr << e.toString() << endl;
72  chan = NULL;
73  } catch (...) {
74  jerr << "?unknown exception" << endl;
75  chan = NULL;
76  }
77 }
78 
79 //---------------------------------
80 // GetEvent
81 //---------------------------------
82 jerror_t DEventSourceEVIO::GetEvent(JEvent &event)
83 {
84  if(chan==NULL)return NO_MORE_EVENTS_IN_SOURCE;
85  if(chan->read()){
86 
87  evioDOMTree *evt = new evioDOMTree(chan);
88 
89  // Copy the reference info into the JEvent object
90  event.SetJEventSource(this);
91  event.SetEventNumber(++Nevents_read);
92  event.SetRunNumber(1);
93  event.SetRef(evt);
94 
95  }else{
96  return NO_MORE_EVENTS_IN_SOURCE;
97  }
98 
99  return NOERROR;
100 }
101 
102 //---------------------------------
103 // FreeEvent
104 //---------------------------------
105 void DEventSourceEVIO::FreeEvent(JEvent &event)
106 {
107  evioDOMTree *evt = (evioDOMTree*)event.GetRef();
108  if(evt)delete evt;
109 
110  // Check for DReferenceTrajectory objects we need to delete
111  pthread_mutex_lock(&rt_mutex);
112  map<evioDOMTree*, vector<DReferenceTrajectory*> >::iterator iter = rt_by_event.find(evt);
113  if(iter != rt_by_event.end()){
114  vector<DReferenceTrajectory*> &rts = iter->second;
115  for(unsigned int i=0; i<rts.size(); i++)rt_pool.push_back(rts[i]);
116  rt_by_event.erase(iter);
117  }
118  pthread_mutex_unlock(&rt_mutex);
119 }
120 
121 //---------------------------------
122 // GetObjects
123 //---------------------------------
124 jerror_t DEventSourceEVIO::GetObjects(JEvent &event, JFactory_base *factory)
125 {
126  /// This gets called through the virtual method of the
127  /// JEventSource base class. It creates the objects of the type
128  /// on which factory is based. It uses the evioDOMTree object
129  /// kept in the ref field of the JEvent object passed.
130 
131  // We must have a factory to hold the data
132  if(!factory)throw RESOURCE_UNAVAILABLE;
133 
134  evioDOMTree *evt = (evioDOMTree*)event.GetRef();
135  if(!evt)throw RESOURCE_UNAVAILABLE;
136 
137  // Get pointer to the B-field object and Geometry object
138  JEventLoop *loop = event.GetJEventLoop();
139  if(loop){
140  DApplication *dapp = dynamic_cast<DApplication*>(loop->GetJApplication());
141  if(dapp){
142  bfield = dapp->GetBfield(event.GetRunNumber());
143  geom = dapp->GetDGeometry(event.GetRunNumber());
144  }
145  }
146 
147  // Get name of data class we're trying to extract
148  string dataClassName = factory->GetDataClassName();
149 
150  if(dataClassName =="DTrackTimeBased")
151  return Extract_DTrackTimeBased(evt, dynamic_cast<JFactory<DTrackTimeBased>*>(factory));
152 
153  return OBJECT_NOT_AVAILABLE;
154 }
155 
156 //---------------------------------
157 // Extract_DTrackTimeBased
158 //---------------------------------
159 jerror_t DEventSourceEVIO::Extract_DTrackTimeBased(evioDOMTree *evt, JFactory<DTrackTimeBased> *factory)
160 {
161  // Note: Since this is a reconstructed factory, we want to generally return OBJECT_NOT_AVAILABLE
162  // rather than NOERROR. The reason being that the caller interprets "NOERROR" to mean "yes I
163  // usually can provide objects of that type, but this event has none." This will cause it to
164  // skip any attempt at reconstruction. On the other hand, a value of "OBJECT_NOT_AVAILABLE" tells
165  // it "I cannot provide those type of objects for this event.
166 
167  if(factory==NULL)return OBJECT_NOT_AVAILABLE;
168 
169  vector<DTrackTimeBased*> data;
170  vector<DReferenceTrajectory*> rts;
171 
172  bool event_had_tracktimebaseds = false;
173 
174  // Get list of DTrackTimeBased banks. At this level, there should usually be
175  // only one but we get the list and loop over them since that is how it is formatted.
176  // The actual DTrackTimeBased objects are contained in child banks of this (these).
177  evioDOMNodeListP bList = evt->getNodeList(tagNumEquals(tagMap["DTrackTimeBased"]));
178 
179  // loop over all banks in list (should only be one)
180  evioDOMNodeList::const_iterator iter1;
181  for(iter1=bList->begin(); iter1!=bList->end(); iter1++) {
182 
183  evioDOMNodeList *members = (*iter1)->getChildList();
184 
185  try{
186  const vector<uint64_t> &v_objId = GetVector<uint64_t>(members, "DTrackTimeBased.objId");
187  const vector<float> &v_chisq = GetVector<float>(members, "DTrackTimeBased.chisq");
188  const vector<int> &v_Ndof = GetVector<int>(members, "DTrackTimeBased.Ndof");
189  const vector<float> &v_FOM = GetVector<float>(members, "DTrackTimeBased.FOM");
190  const vector<float> &v_x = GetVector<float>(members, "DTrackTimeBased.x");
191  const vector<float> &v_y = GetVector<float>(members, "DTrackTimeBased.y");
192  const vector<float> &v_z = GetVector<float>(members, "DTrackTimeBased.z");
193  const vector<float> &v_px = GetVector<float>(members, "DTrackTimeBased.px");
194  const vector<float> &v_py = GetVector<float>(members, "DTrackTimeBased.py");
195  const vector<float> &v_pz = GetVector<float>(members, "DTrackTimeBased.pz");
196  const vector<float> &v_q = GetVector<float>(members, "DTrackTimeBased.q");
197  //const vector<float> &v_E = GetVector<float>(members, "DTrackTimeBased.E");
198  const vector<float> &v_mass = GetVector<float>(members, "DTrackTimeBased.mass");
199  //const vector<float> &v_t0 = GetVector<float>(members, "DTrackTimeBased.t0");
200 
201  // Get enough DReferenceTrajectory objects for all of the DTrackTimeBased Objects
202  // we're about to read in. This seems a little complicated, but that's because it
203  // is expensive to allocate these things so we recycle as much as possible.
204  list<DReferenceTrajectory*> my_rts;
205  pthread_mutex_lock(&rt_mutex);
206  while(my_rts.size() < v_objId.size()){
207  if(rt_pool.size()>0){
208  my_rts.push_back(rt_pool.back());
209  rt_pool.pop_back();
210  }else{
211  my_rts.push_back(new DReferenceTrajectory(bfield));
212  }
213  }
214  pthread_mutex_unlock(&rt_mutex);
215 
216  // Loop over DTrackTimeBased objects
217  event_had_tracktimebaseds = true;
218  for(unsigned int i=0; i<v_objId.size(); i++){
219 
220  DVector3 pos(v_x[i], v_y[i], v_z[i]);
221  DVector3 mom(v_px[i], v_py[i], v_pz[i]);
222 
224 
225  track->setMomentum(mom);
226  track->setPosition(pos);
227  track->setCharge(v_q[i]);
228  track->setMass(v_mass[i]);
229  track->chisq = v_chisq[i];
230  track->Ndof = v_Ndof[i];
231  track->FOM = v_FOM[i];
232  track->id = v_objId[i];
233 
234  // Use DReferenceTrajectory objects (either recycled or new)
235  DReferenceTrajectory *rt = my_rts.back();
236  my_rts.pop_back();
237  if(rt){
238  rt->SetMass(track->mass());
239  rt->SetDGeometry(geom);
240  rt->Swim(pos, mom, track->charge());
241  rts.push_back(rt);
242  }
243  track->rt = rt;
244 
245  data.push_back(track);
246  }
247 
248  }catch(JException &e){
249  cout<<e.toString()<<endl;
250  }
251  }
252 
253  // Copy into factory
254  if(event_had_tracktimebaseds){
255  factory->CopyTo(data);
256 
257  // Add DReferenceTrajectory objects to rt_by_event so they can be deleted later.
258  // The rt_by_event maintains lists indexed by the hddm_s pointer since multiple
259  // threads may be calling us. Note that we first look to see if a list already
260  // exists for this event and append to it if it does. This is so we can the
261  // same list for all objects that use DReferenceTrajectories.
262  pthread_mutex_lock(&rt_mutex);
263  map<evioDOMTree*, vector<DReferenceTrajectory*> >::iterator iter = rt_by_event.find(evt);
264  if(iter != rt_by_event.end()){
265  vector<DReferenceTrajectory*> &my_rts = iter->second;
266  my_rts.insert(my_rts.end(), rts.begin(), rts.end());
267  }else{
268  rt_by_event[evt] = rts;
269  }
270  pthread_mutex_unlock(&rt_mutex);
271 
272  // If the event had a s_Tracktimebased_t pointer, then report back that
273  // we read them in from the file. Otherwise, report OBJECT_NOT_AVAILABLE
274  return NOERROR;
275  }
276 
277  // If we get to here then there was not even a placeholder in the HDDM file.
278  // Return OBJECT_NOT_AVAILABLE to indicate reconstruction should be tried.
279  return OBJECT_NOT_AVAILABLE;
280 }
281 
Definition: track.h:16
void setMomentum(const DVector3 &aMomentum)
DApplication * dapp
float chisq
Chi-squared for the track (not chisq/dof!)
DEventSourceEVIO(const char *source_name)
TVector3 DVector3
Definition: DVector3.h:14
void FreeEvent(JEvent &event)
DMagneticFieldMap * GetBfield(unsigned int run_number=1)
void SetMass(double mass)
void Swim(const DVector3 &pos, const DVector3 &mom, double q=-1000.0, const TMatrixFSym *cov=NULL, double smax=2000.0, const DCoordinateSystem *wire=NULL)
void SetDGeometry(const DGeometry *geom)
jerror_t Extract_DTrackTimeBased(evioDOMTree *evt, JFactory< DTrackTimeBased > *factory)
DMagneticFieldMap * bfield
TEllipse * e
map< evioDOMTree *, vector< DReferenceTrajectory * > > rt_by_event
DGeometry * GetDGeometry(unsigned int run_number)
int Ndof
Number of degrees of freedom in the fit.
double charge(void) const
pthread_mutex_t rt_mutex
virtual ~DEventSourceEVIO()
list< DReferenceTrajectory * > rt_pool
jerror_t GetEvent(JEvent &event)
void setPosition(const DVector3 &aPosition)
evioFileChannel * chan
jerror_t GetObjects(JEvent &event, JFactory_base *factory)
map< string, pair< int, int > > tagMap
double mass(void) const