00001 #include "DataLoaderAlg.h"
00002
00003 #include "RawData/RawRecord.h"
00004 #include "RawData/RawData.h"
00005 #include "RawData/RawDataReader.h"
00006 #include "RawData/RawRecordFormat.h"
00007 #include "RawData/RawDataFormat.h"
00008 #include "Event/ReadoutPmtCrate.h"
00009 #include "Event/ReadoutRpcCrate.h"
00010
00011
00012 #include <sstream>
00013
00014 DataLoaderAlg::DataLoaderAlg(const std::string& name, ISvcLocator* pSvcLocator)
00015 : DybAlgorithm<DayaBay::ReadoutHeader>(name,pSvcLocator)
00016 , m_inputFiles()
00017 , m_usePacked(true)
00018 , m_useUnpacked(true)
00019 , m_reader(0)
00020 , m_fileIndex(0)
00021 , m_fileYear(0)
00022 , m_fileMonth(0)
00023 , m_fileDay(0)
00024 , m_utcDay(0)
00025 {
00026 declareProperty("InputFiles",m_inputFiles,
00027 "List of input data files");
00028 declareProperty("UsePacked",m_usePacked=true,"Load Packed Data");
00029 declareProperty("UseUnpacked",m_useUnpacked=true,"Load Unpacked Data");
00030 }
00031
00032 DataLoaderAlg::~DataLoaderAlg()
00033 {
00034 }
00035
00036 StatusCode DataLoaderAlg::initialize()
00037 {
00038
00039 m_fileIndex = 0;
00040 return StatusCode::SUCCESS;
00041 }
00042
00043 StatusCode DataLoaderAlg::execute()
00044 {
00045
00046
00047
00048 DayaBay::RawEvent* event = 0;
00049 StatusCode sc = this->readNextEvent(event);
00050 if( !sc.isSuccess() ) return sc;
00051
00052
00053 DayaBay::ReadoutHeader* readoutHeader = MakeHeaderObject();
00054
00055
00056 sc = this->loadEventData(event, readoutHeader);
00057
00058 delete event;
00059 return sc;
00060 }
00061
00062 StatusCode DataLoaderAlg::finalize()
00063 {
00064
00065
00066 if(m_reader){
00067 delete m_reader;
00068 m_reader=0;
00069 }
00070 m_fileIndex=0;
00071 return StatusCode::SUCCESS;
00072 }
00073
00075
00076 StatusCode DataLoaderAlg::openNextFile()
00077 {
00078
00079
00080
00081 if(m_reader){
00082 delete m_reader;
00083 m_reader=0;
00084 }
00085
00086
00087 if(m_fileIndex >= m_inputFiles.size()){
00088 warning() << "No more files to read" << endreq;
00089 return StatusCode::FAILURE;
00090 }
00091
00092
00093 m_reader = new DayaBay::RawDataReader;
00094 if(!m_reader){
00095 error() << "Failed to create new file reader" << endreq;
00096 return StatusCode::FAILURE;
00097 }
00098
00099
00100 if(!m_reader->open( m_inputFiles[m_fileIndex].c_str() )){
00101 error() << "Failed to open input file: " << m_inputFiles[m_fileIndex]
00102 << endreq;
00103 delete m_reader;
00104 m_reader=0;
00105 return StatusCode::FAILURE;
00106 }
00107
00108 return StatusCode::SUCCESS;
00109 }
00110
00111 StatusCode DataLoaderAlg::readNextEvent(DayaBay::RawEvent*& nextEvent)
00112 {
00113
00114
00115 DayaBay::RawEvent* event = 0;
00116 while( !event ){
00117
00118
00119 if(!m_reader){
00120 StatusCode sc = this->openNextFile();
00121 if(! sc.isSuccess() ){
00122 return sc;
00123 }
00124 }
00125
00126
00127 DayaBay::RawRecord* record = m_reader->nextRecord();
00128 if(!record){
00129 error() << "Failed to read next record from file: "
00130 << m_inputFiles[m_fileIndex] << endreq;
00131 return StatusCode::FAILURE;
00132 }
00133
00134
00135 if( !record->isDataSeparator() ){
00136
00137 std::stringstream message;
00138 record->dump( message );
00139 info() << message.str() << endreq;
00140 if( record->isFileStart() ){
00141 DayaBay::RawFileStart* fileStart = dynamic_cast<DayaBay::RawFileStart*>(record);
00142 if(fileStart){
00143 this->m_fileYear = fileStart->date() % 10000;
00144 this->m_fileMonth = (fileStart->date() / 10000) % 100;
00145 this->m_fileDay = (fileStart->date() / 1000000) % 100;
00146 this->m_utcDay = 0;
00147 }
00148 }
00149 if( record->isFileEnd() ){
00150
00151 delete m_reader;
00152 m_reader = 0;
00153 m_fileIndex++;
00154 }
00155 delete record;
00156 continue;
00157 }
00158
00159
00160 DayaBay::RawDataSeparator* dataSeparator =
00161 dynamic_cast<DayaBay::RawDataSeparator*>(record);
00162 if( !dataSeparator ){
00163 error() << "Failed to process data separator" << endreq;
00164 std::stringstream message;
00165 record->dump( message );
00166 error() << message.str() << endreq;
00167 delete record;
00168 return StatusCode::FAILURE;
00169 }
00170
00171 DayaBay::RawData* data = dataSeparator->data();
00172 if( !data ){
00173 error() << "Failed to load payload data" << endreq;
00174 std::stringstream message;
00175 record->dump( message );
00176 error() << message.str() << endreq;
00177 delete record;
00178 return StatusCode::FAILURE;
00179 }
00180
00181 if( !data->isEventType() ){
00182
00183 std::stringstream message;
00184 data->dump( message );
00185 info() << message.str() << endreq;
00186 delete data;
00187 delete record;
00188 continue;
00189 }
00190
00191
00192 event = dynamic_cast<DayaBay::RawEvent*>(data);
00193 if( !event ){
00194 error() << "Failed to read event" << endreq;
00195 std::stringstream message;
00196 data->dump( message );
00197 error() << message.str() << endreq;
00198 delete data;
00199 delete record;
00200 return StatusCode::FAILURE;
00201 }
00202 }
00203
00204 nextEvent = event;
00205 return StatusCode::SUCCESS;
00206 }
00207
00208
00209 StatusCode DataLoaderAlg::loadEventData(DayaBay::RawEvent* event,
00210 DayaBay::ReadoutHeader* readoutHeader)
00211 {
00212
00213
00214
00215 TimeStamp triggerTime;
00216 StatusCode sc = this->findTriggerTime(event,triggerTime);
00217 if(!sc.isSuccess()){
00218 warning() << "Failed to find trigger time for event: " << event->eventId()
00219 << endreq;
00220 }
00221
00222
00223 Site::Site_t site = this->convertSite( event->siteId() );
00224 Context context(site,
00225 SimFlag::kData,
00226 triggerTime,
00227 (DetectorId::DetectorId_t)(event->detectorId()));
00228
00229 readoutHeader->setContext(context);
00230 readoutHeader->setEarliest(triggerTime);
00231 readoutHeader->setLatest(triggerTime);
00232
00233
00234 DayaBay::Detector detector(this->convertSite(event->siteId()),
00235 this->convertDetector(event->detectorId()));
00236
00237 DayaBay::Readout* readout = 0;
00238 if( detector.isAD() || detector.isWaterShield() ){
00239 readout = new DayaBay::ReadoutPmtCrate();
00240 }else if( detector.detectorId() == DetectorId::kRPC){
00241 readout = new DayaBay::ReadoutRpcCrate();
00242 }else{
00243 error() << "Unknown detector: \"" << detector.detName() << "\","
00244 << " cannot make readout." << endreq;
00245 return StatusCode::FAILURE;
00246 }
00247
00248
00249 readout->setDetector(detector);
00250
00251
00252 if(m_usePacked){
00253
00254 readout->setRawEvent( event->clone() );
00255 }
00256
00257 if(m_useUnpacked){
00258
00259 sc = this->unpackEvent(event, readout);
00260 if( !sc.isSuccess() ){
00261 delete readout;
00262 return sc;
00263 }
00264 }
00265
00266 readoutHeader->setReadout( readout );
00267 readout->setHeader( readoutHeader );
00268
00269 return StatusCode::SUCCESS;
00270 }
00271
00272
00273 StatusCode DataLoaderAlg::findTriggerTime(DayaBay::RawEvent* event,
00274 TimeStamp& triggerTime)
00275 {
00276
00277 if(!event){
00278 error() << "Cannot find time of invalid event" << endreq;
00279 return StatusCode::FAILURE;
00280 }
00281
00282 bool foundTriggerTime = false;
00283 while( DayaBay::RawModule* module = event->nextModule() ){
00284 if( module->isLocalTriggerModule() ){
00285 while( DayaBay::DataFragment* fragment = module->nextDataFragment() ){
00286 if( fragment->isLocalTriggerData() ){
00287 DayaBay::LocalTriggerData* ltbData =
00288 dynamic_cast<DayaBay::LocalTriggerData*>(fragment);
00289 if(!ltbData){
00290 error() << "Failed to access local trigger data fragment" << endreq;
00291 return StatusCode::FAILURE;
00292 }
00293 triggerTime = this->convertTriggerTime(ltbData);
00294 foundTriggerTime = true;
00295 break;
00296 }
00297 delete fragment;
00298 }
00299 if( foundTriggerTime ) break;
00300 }
00301 delete module;
00302 }
00303 event->resetModule();
00304 if(!foundTriggerTime) return StatusCode::FAILURE;
00305 return StatusCode::SUCCESS;
00306 }
00307
00308
00309 TimeStamp DataLoaderAlg::convertTriggerTime(DayaBay::LocalTriggerData* ltbData)
00310 {
00311
00312 TimeStamp triggerTime;
00313 if(ltbData->isUnixTime()){
00314 triggerTime = TimeStamp(ltbData->unixtime(),
00315 ltbData->nanosecond()+ltbData->accumulation());
00316 }else if(ltbData->isUtcTime()){
00317
00318
00319 if( ltbData->days() < this->m_utcDay ){
00320
00321 this->m_fileYear++;
00322 }
00323 triggerTime = TimeStamp(this->m_fileYear,
00324 1 ,
00325 ltbData->days()+1 ,
00326 ltbData->hour(),
00327 ltbData->minute(),
00328 ltbData->second(),
00329 ltbData->nanosecond()+ltbData->accumulation(),
00330 true );
00331 this->m_utcDay = ltbData->days();
00332 }else{
00333
00334
00335
00336
00337 unsigned int seconds = ltbData->hour()*61*61
00338 + ltbData->minute()*61
00339 + ltbData->second();
00340 unsigned int hour = seconds / 3600;
00341 unsigned int minute = (seconds - hour*3600) / 60;
00342 unsigned int second = (seconds - (hour*3600 + minute*60));
00343 int timezoneOffset = -8*60*60;
00344 triggerTime = TimeStamp(this->m_fileYear,
00345 this->m_fileMonth,
00346 this->m_fileDay,
00347 hour,
00348 minute,
00349 second,
00350 (int)(ltbData->clock()*12.5) ,
00351 true ,
00352 timezoneOffset);
00353 }
00354 return triggerTime;
00355 }
00356
00357 Site::Site_t DataLoaderAlg::convertSite(unsigned int daqSiteId)
00358 {
00359
00360 switch(daqSiteId){
00361 case 1:
00362 return Site::kDayaBay;
00363 case 2:
00364 return Site::kLingAo;
00365 case 3:
00366 return Site::kFar;
00367 case 4:
00368 return Site::kMid;
00369 case 6:
00370 return Site::kSAB;
00371 default:
00372 break;
00373 }
00374 return Site::kUnknown;
00375 }
00376
00377 DetectorId::DetectorId_t DataLoaderAlg::convertDetector(
00378 unsigned int daqDetectorId)
00379 {
00380
00381 switch(daqDetectorId){
00382 case 1:
00383 return DetectorId::kAD1;
00384 case 2:
00385 return DetectorId::kAD2;
00386 case 3:
00387 return DetectorId::kAD3;
00388 case 4:
00389 return DetectorId::kAD4;
00390 case 5:
00391 return DetectorId::kIWS;
00392 case 6:
00393 return DetectorId::kOWS;
00394 case 7:
00395 return DetectorId::kRPC;
00396 default:
00397 break;
00398 }
00399 return DetectorId::kUnknown;
00400 }
00401
00402 int DataLoaderAlg::convertBoard(unsigned int daqSlotId)
00403 {
00404 return daqSlotId;
00405 }
00406
00407 int DataLoaderAlg::convertConnector(unsigned int daqChannelId)
00408 {
00409 return daqChannelId+1;
00410 }
00411
00412 DayaBay::Trigger::TriggerType_t DataLoaderAlg::convertTriggerType(
00413 DayaBay::LocalTriggerData* ltbData,
00414 const DayaBay::Detector* detector)
00415 {
00416
00417 unsigned int triggerType = DayaBay::Trigger::kUnknown;
00418 if(ltbData->isManualTrigger())
00419 triggerType |= DayaBay::Trigger::kManual;
00420 if(ltbData->isCrossTrigger())
00421 triggerType |= DayaBay::Trigger::kCross;
00422 if(ltbData->isPeriodicTrigger())
00423 triggerType |= DayaBay::Trigger::kPeriodic;
00424 if(ltbData->isMultiplicityTrigger())
00425 triggerType |= DayaBay::Trigger::kMult;
00426
00427 if(ltbData->isEsumAdcTrigger())
00428 triggerType |= DayaBay::Trigger::kESum;
00429 if(ltbData->isEsumCompHighTrigger())
00430 triggerType |= DayaBay::Trigger::kESum;
00431 if(ltbData->isEsumCompLowTrigger())
00432 triggerType |= DayaBay::Trigger::kESum;
00433 if(ltbData->isEsumCompAllTrigger())
00434 triggerType |= DayaBay::Trigger::kESum;
00435
00436 switch(detector->detectorId()){
00437 case DetectorId::kAD1:
00438 triggerType |= DayaBay::Trigger::kAD1;
00439 break;
00440 case DetectorId::kAD2:
00441 triggerType |= DayaBay::Trigger::kAD2;
00442 break;
00443 case DetectorId::kAD3:
00444 triggerType |= DayaBay::Trigger::kAD3;
00445 break;
00446 case DetectorId::kAD4:
00447 triggerType |= DayaBay::Trigger::kAD4;
00448 break;
00449 case DetectorId::kIWS:
00450 triggerType |= DayaBay::Trigger::kIWS;
00451 break;
00452 case DetectorId::kOWS:
00453 triggerType |= DayaBay::Trigger::kOWS;
00454 break;
00455 default:
00456 break;
00457 }
00458
00459 return static_cast<DayaBay::Trigger::TriggerType_t>(triggerType);
00460 }
00461
00462 DayaBay::FeeGain::FeeGain_t DataLoaderAlg::convertAdcRange(
00463 unsigned int daqAdcRange)
00464 {
00465
00466 switch(daqAdcRange){
00467 case 0:
00468 return DayaBay::FeeGain::kHigh;
00469 case 1:
00470 return DayaBay::FeeGain::kLow;
00471 default:
00472 break;
00473 }
00474 return DayaBay::FeeGain::kUnknown;
00475 }
00476
00477
00478 StatusCode DataLoaderAlg::unpackEvent(DayaBay::RawEvent* event,
00479 DayaBay::Readout* readout)
00480 {
00481
00482
00483
00484 while( DayaBay::RawModule* module = event->nextModule() ){
00485 StatusCode sc;
00486 if( module->isLocalTriggerModule() ){
00487 sc = this->unpackLtbModule(module, readout);
00488 }else if( module->isPmtFeeModule() ){
00489 sc = this->unpackFeeModule(module,
00490 dynamic_cast<DayaBay::ReadoutPmtCrate*>(readout));
00491 }else if( module->isFlashAdcModule() ){
00492
00493 }else if( module->isRpcRomModule() ){
00494
00495 }else if( module->isRpcRtmModule() ){
00496
00497 }else{
00498 warning() << "Cannot unpack unknown module type: "
00499 << module->moduleType()<< endreq;
00500 sc = StatusCode::FAILURE;
00501 }
00502 if( !sc.isSuccess() ){
00503
00504 continue;
00505 }
00506 delete module;
00507 }
00508
00509 return StatusCode::SUCCESS;
00510 }
00511
00512 StatusCode DataLoaderAlg::unpackLtbModule(DayaBay::RawModule* module,
00513 DayaBay::Readout* readout)
00514 {
00515
00516 bool firstTriggerFragment = true;
00517 TimeStamp triggerTime;
00518
00519 while( DayaBay::DataFragment* fragment = module->nextDataFragment() ){
00520 if( fragment->isLocalTriggerData() ){
00521
00522 DayaBay::LocalTriggerData* ltbData =
00523 dynamic_cast<DayaBay::LocalTriggerData*>(fragment);
00524 if(!ltbData){
00525 warning() << "Bad Local Trigger Data fragment" << endreq;
00526 continue;
00527 }
00528 triggerTime = this->convertTriggerTime(ltbData);
00529 if(firstTriggerFragment){
00530
00531 readout->setTriggerTime( triggerTime );
00532 readout->setTriggerType(this->convertTriggerType(ltbData,
00533 &(readout->detector())));
00534
00535 DayaBay::HeadFragment* headFragment = module->headFragment();
00536 if( headFragment ){
00537 readout->setTriggerNumber( headFragment->triggerNumber() );
00538 delete headFragment;
00539 }else{
00540 warning() << "Missing head fragment!" << endreq;
00541 }
00542 firstTriggerFragment = false;
00543 }else{
00544 if(triggerTime != readout->triggerTime()){
00545 TimeStamp dtTrigger( triggerTime );
00546 dtTrigger.Subtract( readout->triggerTime() );
00547 debug() << "Additional trigger at dT = " << dtTrigger.GetSeconds()
00548 << " [s]" << endreq;
00549 }
00550 }
00551 }else{
00552 warning() << "Unknown LTB data fragment type: " << fragment->dataType()
00553 << endreq;
00554 }
00555 delete fragment;
00556 }
00557 return StatusCode::SUCCESS;
00558 }
00559
00560 StatusCode DataLoaderAlg::unpackFeeModule(DayaBay::RawModule* module,
00561 DayaBay::ReadoutPmtCrate* readout)
00562 {
00563
00564 if(!readout){
00565 warning() << "Trying to add FEE data to a non-PMT readout"
00566 << endreq;
00567 return StatusCode::FAILURE;
00568 }
00569
00570 while( DayaBay::DataFragment* fragment = module->nextDataFragment() ){
00571 if( fragment->isFeePeakData() ){
00572
00573 DayaBay::FeePeakData* feePeakData =
00574 dynamic_cast<DayaBay::FeePeakData*>(fragment);
00575 if(!feePeakData){
00576 warning() << "Bad FEE Peak-finding Data fragment" << endreq;
00577 continue;
00578 }
00579
00580 DayaBay::FeeChannelId channelId(
00581 this->convertBoard(module->slot()),
00582 this->convertConnector(feePeakData->channel()),
00583 readout->detector().site(),
00584 readout->detector().detectorId());
00585
00586 DayaBay::ReadoutPmtChannel& feeChannel = readout->channel(channelId);
00587 if(feeChannel.channelId() != channelId){
00588
00589 feeChannel.setChannelId(channelId);
00590 feeChannel.setMode(0x1);
00591 feeChannel.setReadout(readout);
00592 }
00593
00594 feeChannel.tdc().push_back( feePeakData->tdc() );
00595 feeChannel.tdcHitCount().push_back( feePeakData->tdcHitCount() );
00596 feeChannel.adc().push_back( feePeakData->adc() );
00597 feeChannel.adcRange().push_back(
00598 this->convertAdcRange(feePeakData->adcRange()) );
00599 feeChannel.adcCycle().push_back( feePeakData->peakCycle() );
00600 if( feePeakData->hasAdcPedestal() )
00601 feeChannel.pedestal().push_back( feePeakData->adcPedestal() );
00602 }else{
00603 warning() << "Unknown FEE data fragment type: " << fragment->dataType()
00604 << endreq;
00605 }
00606 delete fragment;
00607 }
00608 return StatusCode::SUCCESS;
00609 }
00610
00611
00612
00613
00614
00615