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