/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 #include "RawRecordPool/RpcEventBuilder.h" 00002 #include "RawRecordPool/RecordBuffer.h" 00003 #include "RawRecordPool/RecordParser.h" 00004 #include "RawRecordPool/DaqRawEvent.h" 00005 #include "RawRecordPool/PackedRpcEvent.h" 00006 #include "RawRecordPool/RawRecordPoolUtil.h" 00007 #include <iostream> 00008 #include <cstdlib> 00009 #include <cstring> 00010 00011 using DybDaq::EventBuilder; 00012 using DybDaq::RpcEventBuilder; 00013 using DybDaq::RecordBuffer; 00014 using DybDaq::RecordParser; 00015 using DybDaq::DaqRawEvent; 00016 using DybDaq::DaqRomData; 00017 using DybDaq::PackedRpcEvent; 00018 using DybDaq::RawRecordPoolUtil::RTM_DATA_SIZE; 00019 using DybDaq::RawRecordPoolUtil::FEC_DATA_SIZE; 00020 00021 /* 00022 * EventBuilder 00023 */ 00024 EventBuilder::EventBuilder() 00025 : m_size(0) 00026 { 00027 } 00028 00029 EventBuilder::~EventBuilder() 00030 { 00031 } 00032 00033 int EventBuilder::size() 00034 { 00035 return m_size; 00036 } 00037 00038 bool EventBuilder::empty() 00039 { 00040 return (m_size == 0); 00041 } 00042 00043 int EventBuilder::add(RecordBuffer* record) 00044 { 00045 if ( record != 0 ) { 00046 m_records.push_back(record); 00047 ++m_size; 00048 } 00049 return m_size; 00050 } 00051 00052 RecordBuffer* EventBuilder::front() 00053 { 00054 RecordBuffer* result = 0; 00055 if ( m_size > 0 ) { 00056 result = m_records.front(); 00057 } 00058 return result; 00059 } 00060 00061 RecordBuffer* EventBuilder::pop_front() 00062 { 00063 RecordBuffer* result = 0; 00064 if ( m_size > 0 ) { 00065 result = m_records.front(); 00066 m_records.pop_front(); 00067 --m_size; 00068 } 00069 return result; 00070 } 00071 00072 /* 00073 * RpcEventBuilder::ElementList 00074 */ 00075 RpcEventBuilder::ElementList::ElementList(int elementSize) 00076 : m_elementsSize(elementSize) 00077 { 00078 for ( int i = 0; i < 16; ++i ) { 00079 m_elements.push_back(new uint32_t[elementSize]); 00080 } 00081 m_begin = m_elements.begin(); 00082 m_end = m_elements.begin(); 00083 } 00084 00085 RpcEventBuilder::ElementList::~ElementList() 00086 { 00087 element_iterator it = m_elements.begin(); 00088 while ( it != m_elements.end() ) { 00089 delete [] (*it); 00090 ++it; 00091 } 00092 } 00093 00094 bool RpcEventBuilder::ElementList::empty() 00095 { 00096 return (m_begin == m_end); 00097 } 00098 00099 uint32_t* RpcEventBuilder::ElementList::front() 00100 { 00101 if ( m_begin != m_end ) { 00102 return *m_begin; 00103 } 00104 return 0; 00105 } 00106 00107 uint32_t* RpcEventBuilder::ElementList::pre_front() 00108 { 00109 if ( m_begin != m_elements.begin() ) { 00110 --m_begin; 00111 uint32_t* result = *m_begin; 00112 ++m_begin; 00113 return result; 00114 } 00115 return m_elements.back(); 00116 } 00117 00118 void RpcEventBuilder::ElementList::pop_front() 00119 { 00120 if ( (m_begin != m_end) ) { 00121 ++m_begin; 00122 if ( m_begin == m_elements.end() ) { 00123 m_begin = m_elements.begin(); 00124 } 00125 } 00126 } 00127 00128 void RpcEventBuilder::ElementList::push_back(const uint32_t* element) 00129 { 00130 element_iterator bak = m_end++; 00131 if ( m_end == m_elements.end() ) { 00132 m_end = m_elements.begin(); 00133 } 00134 if ( m_end == m_begin ) { 00135 m_end = bak; 00136 bak = m_elements.insert(bak, new uint32_t[m_elementsSize]); 00137 } 00138 memcpy(*bak, element, m_elementsSize*sizeof(uint32_t)); 00139 } 00140 00141 /* 00142 * RpcEventBuilder 00143 */ 00144 RpcEventBuilder::RpcEventBuilder(RecordParser* parser) 00145 : m_totRtm(0), 00146 m_totFec(0), 00147 m_fresh(true), 00148 m_parser(parser) 00149 { 00150 int nRtmCF = parser->farSite() ? 3 : 2; 00151 int nFecCF = 2*nRtmCF; 00152 00153 m_rtm = new ElementList*[nRtmCF]; 00154 for ( int i = 0; i < nRtmCF; ++i ) { 00155 m_rtm[i] = new ElementList(RTM_DATA_SIZE); 00156 } 00157 00158 m_fec = new ElementList**[nFecCF]; 00159 for ( int i = 0; i < nFecCF; ++i ) { 00160 int nFec = 15; //for the telescope ((i%2) == 0 ) ? 15 : 12; 00161 m_fec[i] = new ElementList*[nFec]; 00162 for ( int j = 0; j < nFec; ++j ) { 00163 m_fec[i][j] = new ElementList(FEC_DATA_SIZE); 00164 } 00165 } 00166 00167 m_target = new PackedRpcEvent(m_parser->farSite()); 00168 } 00169 00170 RpcEventBuilder::~RpcEventBuilder() 00171 { 00172 int nRtmCF = m_parser->farSite() ? 3 : 2; 00173 int nFecCF = 2*nRtmCF; 00174 00175 for ( int i = 0; i < nRtmCF; ++i ) { 00176 delete m_rtm[i]; 00177 } 00178 delete [] m_rtm; 00179 00180 for ( int i = 0; i < nFecCF; ++i ) { 00181 int nFec = 15; //for the telescope ((i%2) == 0 ) ? 15 : 12; 00182 for ( int j = 0; j < nFec; ++j ) { 00183 delete m_fec[i][j]; 00184 } 00185 delete [] m_fec[i]; 00186 } 00187 delete [] m_fec; 00188 00189 if ( m_target != 0 ) delete m_target; 00190 } 00191 00192 int RpcEventBuilder::size() 00193 { 00194 return m_size; 00195 } 00196 00197 bool RpcEventBuilder::empty() 00198 { 00199 return (m_size == 0); 00200 } 00201 00202 int RpcEventBuilder::add(RecordBuffer* record) 00203 { 00204 const uint32_t* pevt = (const uint32_t*)(record->data()+16); 00205 00206 m_target->initHeader(pevt); 00207 00208 DaqRawEvent event(pevt); 00209 DaqRomData* rom = event.next_rom(); 00210 while ( rom != 0 ) { 00211 if ( rom->is_fec() ) { //FEC data 00212 const uint32_t* fec = rom->next_fec(); 00213 while ( fec != 0 ) { 00214 int _CfId = (fec[0]>>12)&0xF; 00215 int _FecId = (fec[0]>>8)&0xF; 00216 m_fec[_CfId][_FecId]->push_back(fec); 00217 ++m_totFec; 00218 fec = rom->next_fec(); 00219 } 00220 } 00221 else if ( rom->is_rtm() ) { //RTM data 00222 const uint32_t* rtm = rom->next_rtm(); 00223 while ( rtm != 0 ) { 00224 int _CfId = (rtm[0]>>12)&0xF; 00225 m_rtm[_CfId]->push_back(rtm); 00226 ++m_totRtm; 00227 m_target->updateAccumulation(rtm); 00228 rtm = rom->next_rtm(); 00229 } 00230 } 00231 else { 00232 std::cerr << "RpcEventBuilder: bad RPC block!" << std::endl; 00233 } 00234 delete rom; 00235 rom = event.next_rom(); 00236 } 00237 00238 m_fresh = true; 00239 delete [] record->data(); 00240 delete record; 00241 00242 //std::cout << "zdebug: Rtm " << m_totRtm << " Fec " << m_totFec << std::endl; 00243 00244 bool forced = ( m_totFec < 10000 ) ? false : true; 00245 tryPack(forced); 00246 00247 return m_size; 00248 } 00249 00250 RecordBuffer* RpcEventBuilder::front() 00251 { 00252 RecordBuffer* result = 0; 00253 if ( m_size > 0 ) { 00254 result = m_records.front(); 00255 } 00256 return result; 00257 } 00258 00259 RecordBuffer* RpcEventBuilder::pop_front() 00260 { 00261 RecordBuffer* result = 0; 00262 if ( m_size > 0 ) { 00263 result = m_records.front(); 00264 m_records.pop_front(); 00265 --m_size; 00266 } 00267 return result; 00268 } 00269 00270 void RpcEventBuilder::tryPack(bool forced) 00271 { 00272 while ( m_fresh && m_totRtm > 0 ) { 00273 00274 // packing a event 00275 int _RtmCfId = m_target->rtmNeeded(); 00276 while ( _RtmCfId >= 0 ) { 00277 if ( ! m_rtm[_RtmCfId]->empty() ) { 00278 if ( m_target->addRtmData(m_rtm[_RtmCfId]->front()) <= 0 ) { 00279 m_rtm[_RtmCfId]->pop_front(); 00280 --m_totRtm; 00281 } 00282 } 00283 else if ( !forced ) { 00284 m_fresh = false; 00285 return; 00286 } 00287 else { 00288 m_target->setNextRtm(); 00289 } 00290 _RtmCfId = m_target->rtmNeeded(); 00291 if ( _RtmCfId < 0 ) m_target->makeFecList(); 00292 } 00293 00294 int _FecId = m_target->fecNeeded(); 00295 while ( _FecId >= 0 ) { 00296 int _iRtm = (_FecId >> 8); 00297 int _FecCfId = (_FecId >> 4) & 0xF; 00298 _FecId &= 0xF; 00299 if ( ! m_fec[_FecCfId][_FecId]->empty() ) { 00300 int status = m_target->addFecData(m_fec[_FecCfId][_FecId]->front(), _iRtm, forced); 00301 if ( m_target->accumulationValid() || forced ) { 00302 if ( status <= 0 ) { 00303 m_fec[_FecCfId][_FecId]->pop_front(); 00304 --m_totFec; 00305 } 00306 else { //try to share FecData with the previous event 00307 m_target->tryPreFecData(m_fec[_FecCfId][_FecId]->pre_front(), _iRtm); 00308 } 00309 } 00310 else { 00311 m_fresh = false; 00312 return; 00313 } 00314 } 00315 else if ( !forced ) { 00316 m_fresh = false; 00317 return; 00318 } 00319 else { 00320 m_target->setNextFec(); 00321 m_target->tryPreFecData(m_fec[_FecCfId][_FecId]->pre_front(), _iRtm); 00322 } 00323 _FecId = m_target->fecNeeded(); 00324 } 00325 00326 m_target->pack(); 00327 int recordSize = m_target->recordSize(); 00328 char* recordData = new char[recordSize]; 00329 memcpy(recordData, m_target->recordData(), recordSize); 00330 m_records.push_back(new RecordBuffer(recordData, recordSize)); 00331 ++m_size; 00332 m_target->reset(); 00333 } 00334 } 00335 00336 void RpcEventBuilder::purge() 00337 { 00338 m_fresh = true; 00339 tryPack(true); 00340 m_fresh = false; 00341 }