// $Id$ // // File: DEventSourceEVIO.cc // Created: Sat May 8 13:54:35 EDT 2010 // Creator: davidl (on Darwin Amelia.local 9.8.0 i386) // #include using namespace std; #include #include "DEventSourceEVIO.h" //--------------------------------- // DEventSourceEVIO (Constructor) //--------------------------------- DEventSourceEVIO::DEventSourceEVIO(const char* source_name):JEventSource(source_name) { // Open the EVIO file, catching any exceptions try { chan = new evioFileChannel(source_name,"r", 65536); chan->open(); jout << "Opened EVIO file \""<(11500,0); tagMap["DTrackTimeBased.objId"] = pair(11500, 1); tagMap["DTrackTimeBased.chisq"] = pair(11500, 2); tagMap["DTrackTimeBased.Ndof"] = pair(11500, 3); tagMap["DTrackTimeBased.FOM"] = pair(11500, 4); tagMap["DTrackTimeBased.x"] = pair(11500, 5); tagMap["DTrackTimeBased.y"] = pair(11500, 6); tagMap["DTrackTimeBased.z"] = pair(11500, 7); tagMap["DTrackTimeBased.px"] = pair(11500, 8); tagMap["DTrackTimeBased.py"] = pair(11500, 9); tagMap["DTrackTimeBased.pz"] = pair(11500, 10); tagMap["DTrackTimeBased.q"] = pair(11500, 11); tagMap["DTrackTimeBased.E"] = pair(11500, 12); tagMap["DTrackTimeBased.mass"] = pair(11500, 13); tagMap["DTrackTimeBased.t0"] = pair(11500, 14); tagMap["DTrackTimeBased.assocObjectBanks"] = pair(11500, 254); tagMap["DTrackTimeBased.assocObjects"] = pair(11500, 255); }catch (evioException e) { jerr << e.toString() << endl; chan = NULL; } catch (...) { jerr << "?unknown exception" << endl; chan = NULL; } // Used for reference trajectories pthread_mutex_init(&rt_mutex, NULL); } //--------------------------------- // ~DEventSourceEVIO (Destructor) //--------------------------------- DEventSourceEVIO::~DEventSourceEVIO() { // Close EVIO file, catching any exceptions try { if(chan){ chan->close(); delete(chan); } }catch (evioException e) { jerr << e.toString() << endl; chan = NULL; } catch (...) { jerr << "?unknown exception" << endl; chan = NULL; } } //--------------------------------- // GetEvent //--------------------------------- jerror_t DEventSourceEVIO::GetEvent(JEvent &event) { if(chan==NULL)return NO_MORE_EVENTS_IN_SOURCE; if(chan->read()){ evioDOMTree *evt = new evioDOMTree(chan); // Copy the reference info into the JEvent object event.SetJEventSource(this); event.SetEventNumber(++Nevents_read); event.SetRunNumber(1); event.SetRef(evt); }else{ return NO_MORE_EVENTS_IN_SOURCE; } return NOERROR; } //--------------------------------- // FreeEvent //--------------------------------- void DEventSourceEVIO::FreeEvent(JEvent &event) { evioDOMTree *evt = (evioDOMTree*)event.GetRef(); if(evt)delete evt; // Check for DReferenceTrajectory objects we need to delete pthread_mutex_lock(&rt_mutex); map >::iterator iter = rt_by_event.find(evt); if(iter != rt_by_event.end()){ vector &rts = iter->second; for(unsigned int i=0; i(loop->GetJApplication()); if(dapp){ bfield = dapp->GetBfield(event.GetRunNumber()); geom = dapp->GetDGeometry(event.GetRunNumber()); } } // Get name of data class we're trying to extract string dataClassName = factory->GetDataClassName(); if(dataClassName =="DTrackTimeBased") return Extract_DTrackTimeBased(evt, dynamic_cast*>(factory)); return OBJECT_NOT_AVAILABLE; } //--------------------------------- // Extract_DTrackTimeBased //--------------------------------- jerror_t DEventSourceEVIO::Extract_DTrackTimeBased(evioDOMTree *evt, JFactory *factory) { // Note: Since this is a reconstructed factory, we want to generally return OBJECT_NOT_AVAILABLE // rather than NOERROR. The reason being that the caller interprets "NOERROR" to mean "yes I // usually can provide objects of that type, but this event has none." This will cause it to // skip any attempt at reconstruction. On the other hand, a value of "OBJECT_NOT_AVAILABLE" tells // it "I cannot provide those type of objects for this event. if(factory==NULL)return OBJECT_NOT_AVAILABLE; vector data; vector rts; bool event_had_tracktimebaseds = false; // Get list of DTrackTimeBased banks. At this level, there should usually be // only one but we get the list and loop over them since that is how it is formatted. // The actual DTrackTimeBased objects are contained in child banks of this (these). evioDOMNodeListP bList = evt->getNodeList(tagNumEquals(tagMap["DTrackTimeBased"])); // loop over all banks in list (should only be one) evioDOMNodeList::const_iterator iter1; for(iter1=bList->begin(); iter1!=bList->end(); iter1++) { evioDOMNodeList *members = (*iter1)->getChildList(); try{ const vector &v_objId = GetVector(members, "DTrackTimeBased.objId"); const vector &v_chisq = GetVector(members, "DTrackTimeBased.chisq"); const vector &v_Ndof = GetVector(members, "DTrackTimeBased.Ndof"); const vector &v_FOM = GetVector(members, "DTrackTimeBased.FOM"); const vector &v_x = GetVector(members, "DTrackTimeBased.x"); const vector &v_y = GetVector(members, "DTrackTimeBased.y"); const vector &v_z = GetVector(members, "DTrackTimeBased.z"); const vector &v_px = GetVector(members, "DTrackTimeBased.px"); const vector &v_py = GetVector(members, "DTrackTimeBased.py"); const vector &v_pz = GetVector(members, "DTrackTimeBased.pz"); const vector &v_q = GetVector(members, "DTrackTimeBased.q"); //const vector &v_E = GetVector(members, "DTrackTimeBased.E"); const vector &v_mass = GetVector(members, "DTrackTimeBased.mass"); //const vector &v_t0 = GetVector(members, "DTrackTimeBased.t0"); // Get enough DReferenceTrajectory objects for all of the DTrackTimeBased Objects // we're about to read in. This seems a little complicated, but that's because it // is expensive to allocate these things so we recycle as much as possible. list my_rts; pthread_mutex_lock(&rt_mutex); while(my_rts.size() < v_objId.size()){ if(rt_pool.size()>0){ my_rts.push_back(rt_pool.back()); rt_pool.pop_back(); }else{ my_rts.push_back(new DReferenceTrajectory(bfield)); } } pthread_mutex_unlock(&rt_mutex); // Loop over DTrackTimeBased objects event_had_tracktimebaseds = true; for(unsigned int i=0; isetMomentum(mom); track->setPosition(pos); track->setCharge(v_q[i]); track->setMass(v_mass[i]); track->chisq = v_chisq[i]; track->Ndof = v_Ndof[i]; track->FOM = v_FOM[i]; track->id = v_objId[i]; // Use DReferenceTrajectory objects (either recycled or new) DReferenceTrajectory *rt = my_rts.back(); my_rts.pop_back(); if(rt){ rt->SetMass(track->mass()); rt->SetDGeometry(geom); rt->Swim(pos, mom, track->charge()); rts.push_back(rt); } track->rt = rt; data.push_back(track); } }catch(JException &e){ cout<CopyTo(data); // Add DReferenceTrajectory objects to rt_by_event so they can be deleted later. // The rt_by_event maintains lists indexed by the hddm_s pointer since multiple // threads may be calling us. Note that we first look to see if a list already // exists for this event and append to it if it does. This is so we can the // same list for all objects that use DReferenceTrajectories. pthread_mutex_lock(&rt_mutex); map >::iterator iter = rt_by_event.find(evt); if(iter != rt_by_event.end()){ vector &my_rts = iter->second; my_rts.insert(my_rts.end(), rts.begin(), rts.end()); }else{ rt_by_event[evt] = rts; } pthread_mutex_unlock(&rt_mutex); // If the event had a s_Tracktimebased_t pointer, then report back that // we read them in from the file. Otherwise, report OBJECT_NOT_AVAILABLE return NOERROR; } // If we get to here then there was not even a placeholder in the HDDM file. // Return OBJECT_NOT_AVAILABLE to indicate reconstruction should be tried. return OBJECT_NOT_AVAILABLE; }