// $Id$ // // File: JEventSource_EVIO_FCALTEST2011.cc // Created: Mon Nov 28 16:07:15 EST 2011 // Creator: davidl (on Linux ifarm1102 2.6.18-128.7.1.el5 x86_64) // #include "JEventSource_EVIO_FCALTEST2011.h" using namespace jana; //---------------- // Constructor //---------------- JEventSource_EVIO_FCALTEST2011::JEventSource_EVIO_FCALTEST2011(const char* source_name):JEventSource(source_name) { // open event source (e.g. file) here chan = new evioFileChannel(source_name); if(chan)chan->open(); } //---------------- // Destructor //---------------- JEventSource_EVIO_FCALTEST2011::~JEventSource_EVIO_FCALTEST2011() { // close event source here if(chan){ chan->close(); delete chan; } } //---------------- // GetEvent //---------------- jerror_t JEventSource_EVIO_FCALTEST2011::GetEvent(JEvent &event) { if(chan==NULL)return NO_MORE_EVENTS_IN_SOURCE; if(!chan->read())return NO_MORE_EVENTS_IN_SOURCE; evioDOMTree *evt = new evioDOMTree(chan); event.SetJEventSource(this); event.SetEventNumber(++Nevents_read); event.SetRunNumber(1); event.SetRef(evt); return NOERROR; } //---------------- // FreeEvent //---------------- void JEventSource_EVIO_FCALTEST2011::FreeEvent(JEvent &event) { evioDOMTree *evt = (evioDOMTree*)event.GetRef(); if(evt)delete evt; } //---------------- // GetObjects //---------------- jerror_t JEventSource_EVIO_FCALTEST2011::GetObjects(JEvent &event, JFactory_base *factory) { // This will get called when the first object of the event is // requested (regardless of the type of object). Instead of // pulling out objects only of the type requested, we instead // parse the data for all objects and copy them into the respective // factories. Subsequent requests for objects for this same // event will get them from the factories. Thus, this should // only get called once per event. evioDOMTree *evt = (evioDOMTree*)event.GetRef(); if(!evt)throw RESOURCE_UNAVAILABLE; // Get bank list evioDOMNodeListP bankList = evt->getNodeList(); // Analyze each bank evioDOMNodeList::iterator iter = bankList->begin(); for(; iter!=bankList->end(); iter++)AnalyzeBank(*iter, event); // We need to return either NOERROR if this object is a type // we can supply (whether there are any of this type for this // event or not) or OBJECT_NOT_AVAILABLE if we can't supply // objects of the requested type. if(factory){ string dataClassName = factory->GetDataClassName(); if(dataClassName == "D250EventTime")return NOERROR; if(dataClassName == "D250WindowRawData")return NOERROR; if(dataClassName == "D250WindowSum")return NOERROR; if(dataClassName == "D250PulseRawData")return NOERROR; if(dataClassName == "D250PulseIntegral")return NOERROR; if(dataClassName == "D250PulseTime")return NOERROR; if(dataClassName == "D250StreamingRawData")return NOERROR; } return OBJECT_NOT_AVAILABLE; } //---------------- // AnalyzeBank //---------------- void JEventSource_EVIO_FCALTEST2011::AnalyzeBank(evioDOMNodeP bankPtr, JEvent &event) { // For the FCAL2011 beam test data, tag==5. In general, the // exact tag/num scheme for the GlueX data has not been worked // out, but it will need to include the crate number somehow. // // Details of the data format can be found in the FADC format manual // available on the GlueX wiki in: // // Trigger/DAQ/Monitoring/Controls -> Level 1 Trigger -> FADC250 Data Format v1 // // For now, assume tag==5 is fADC250 data and ignore everything else if( bankPtr->tag != 5 ) return; // Get all data words for this bank const vector *vec = bankPtr->getVector(); if(vec==NULL) {cerr << "?unable to get vector for FADC data bank" << endl; return;} if(vec->size()<3)return; // not enough data to try parsing // Some variables to hold extracted info D250EventTime *eventTime = NULL; vector eventTimes; vector windowRawData; D250WindowSum *wsum; vector windowSum; // Loop over data words const uint32_t *iptr = &(*vec)[0]; const uint32_t *iend = &(*vec)[vec->size()]; for(; iptr>31) & 0x1) == 0)continue; uint32_t data_type = (*iptr>>27) & 0x0F; switch(data_type){ case 0: // Block Header eventTime = new D250EventTime(); eventTime->slot = (*iptr>>22) & 0x1F; eventTime->Nblock_events = (*iptr>>11) & 0x7FF; eventTime->iblock = (*iptr>>0) & 0x7FF; eventTimes.push_back(eventTime); break; case 1: // Block Trailer eventTime->slot_trailer = (*iptr>>22) & 0x1F; eventTime->Nwords_in_block = (*iptr>>0) & 0x1FFFFF; break; case 2: // Event Header eventTime->trig_num_A = (*iptr>>0) & 0x7FFFFFF; if(((iptr[1]>>31) & 0x1) == 0x0){ // data type continuation cerr<<"MISALIGNED TRIGGER NUMBERS IN MODULE!"<trig_num_B = (*iptr>>0) & 0x7FFFFFF; }else{ eventTime->trig_num_B = eventTime->trig_num_A; } break; case 3: // Trigger Time eventTime->trig_time_A = ((*iptr)&0xFFFFFF)<<24; iptr++; eventTime->trig_time_A += (*iptr)&0xFFFFFF; if(((iptr[1]>>31) & 0x1) == 0x0){ // data type continuation iptr++; eventTime->trig_time_B = ((*iptr)&0xFFFFFF)<<24; iptr++; eventTime->trig_time_B += (*iptr)&0xFFFFFF; }else{ eventTime->trig_time_B = eventTime->trig_time_A; } break; case 4: // Window Raw Data // iptr passed by reference and so will be updated automatically windowRawData.push_back(MakeWindowRawData(iptr, eventTime)); break; case 5: // Window Sum wsum = new D250WindowSum(); wsum->chan = (*iptr>>23) & 0x0F; wsum->overflow = (*iptr>>22) & 0x1; wsum->sum = (*iptr>>0) & 0x3FFFFF; windowSum.push_back(wsum); break; // Data types 5-9 do not appear to be present in the // 2011 FCAL beam test data so develop stops here for now. case 6: // Pulse Raw Data case 7: // Pulse Integral case 8: // Pulse Time case 9: // Streaming Raw Data case 10: // User Defined case 11: // User Defined case 12: // User Defined break; case 13: // Event Trailer case 14: // Data not valid (empty module) case 15: // Filler (non-data) word break; } } // Get pointers to factories JEventLoop *loop = event.GetJEventLoop(); JFactory *fac_eventTime = (JFactory*)loop->GetFactory("D250EventTime"); JFactory *fac_windowRawData = (JFactory*)loop->GetFactory("D250WindowRawData"); JFactory *fac_windowSum = (JFactory*)loop->GetFactory("D250WindowSum"); // Copy data objects into factories fac_eventTime->CopyTo(eventTimes); fac_windowRawData->CopyTo(windowRawData); fac_windowSum->CopyTo(windowSum); } //---------------- // MakeWindowRawData //---------------- D250WindowRawData* JEventSource_EVIO_FCALTEST2011::MakeWindowRawData(const uint32_t* &iptr, D250EventTime *eventTime) { D250WindowRawData *wrd = new D250WindowRawData(); wrd->chan = (*iptr>>23) & 0x0F; wrd->window_width = (*iptr>>0) & 0x0FFF; for(uint32_t isample=0; isamplewindow_width; isample +=2){ if(((iptr[1]>>31) & 0x1) != 0x0)break; iptr++; bool invalid_1 = (*iptr>>29) & 0x1; bool invalid_2 = (*iptr>>13) & 0x1; uint32_t sample_1 = 0; uint32_t sample_2 = 0; if(!invalid_1)sample_1 = (*iptr>>16) & 0x1FFF; if(!invalid_2)sample_2 = (*iptr>>0) & 0x1FFF; wrd->samples.push_back(sample_1); if((isample+2) == wrd->window_width && invalid_2)break; // skip last sample if flagged as invalid wrd->samples.push_back(sample_2); } wrd->AddAssociatedObject(eventTime); return wrd; }