// ------------------------------------------------------------------ // ----- TTofVftxUnpacker ----- // ----- Created 14/05/2013 by P.-A. Loizeau ----- // ------------------------------------------------------------------ #include "TTofVftxUnpacker.h" // TOF headers #include "TofVmeDef.h" #include "TMbsUnpackTofPar.h" #include "TofTdcDef.h" #include "TofVftxDef.h" #include "TTofVftxData.h" #include "TTofVftxBoard.h" // FAIR headers #include "FairRootManager.h" #include "FairLogger.h" #include "TString.h" // ROOT headers #include "TClonesArray.h" #include "TH1.h" #include "TH2.h" #include "TROOT.h" #include "TDirectory.h" TTofVftxUnpacker::TTofVftxUnpacker(): fParUnpack(0), fuNbTdc(0), fVftxBoardCollection(NULL) { } TTofVftxUnpacker::TTofVftxUnpacker( TMbsUnpackTofPar * parIn ): fParUnpack( parIn ), fuNbTdc( parIn->GetNbActiveBoards( tofVme::vftx ) ), fVftxBoardCollection(NULL) { // Recover first the VFTX board objects created in general unpacker class FairRootManager* rootMgr = FairRootManager::Instance(); fVftxBoardCollection = (TClonesArray*) rootMgr->GetObject("TofVftxTdc"); if(NULL == fVftxBoardCollection) { LOG(WARNING)<<"TTofVftxUnpacker::TTofVftxUnpacker : no TOF VFTX TDC array! "<GetEntriesFast() <= iTdcIndex )) if( (iTdcIndex<0) || (fuNbTdc <= iTdcIndex) ) { LOG(ERROR)<<"Error VFTX number "<ConstructedAt(iTdcIndex); LOG(DEBUG1)<<"VFTX number "<>vftxtdc::kiHeaderKeyShift != vftxtdc::kiHeaderKeyword ) { LOG(WARNING)<<"This is not a vftx #"<< fParUnpack->GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx) <<" header, jumping this sub-event..."<>vftxtdc::kiHeaderKeyShift != vftxtdc::kiHeaderKeyword ) UInt_t uMbsNbData = (l_dat & vftxtdc::kiHeaderNbMask); if (uMbsNbData+2 != uLength && uMbsNbData+2 + 256 != uLength) { LOG(WARNING)<<"Wrong length in vftx #"<GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx) <<" header, jumping this sub-event... "< effective limitation to 256 hits then loop //return; } // if (uMbsNbData+2 != uLength && uMbsNbData+2 + 256 != uLength) UInt_t uModIndex = ((l_dat & vftxtdc::kiHeaderModMask) >> vftxtdc::kiHeaderModShift); if( uModIndex != fParUnpack->GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx) ) LOG(WARNING)<<"Wrong VFTX index in header of vftx #"<GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx) <<": "< unpack it fVftxBoard->SetTriggerType( (l_dat & vftxtdc::kiFifoHeadTrigType) >> vftxtdc::kiFifoHeadTrigTypeShift ); fVftxBoard->SetTriggerTime( (l_dat & vftxtdc::kiFifoHeadTrigTime) >> vftxtdc::kiFifoHeadTrigTimeShift ); uFifoNbData = (l_dat & vftxtdc::kiFifoHeadDataCnt) >> vftxtdc::kiFifoHeadDataCntShift; } // if( l_dat & vftxtdc::kiFifoMessageType ) else LOG(WARNING)<<"Vftx #"<GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx)<<" fifo header missing... "<GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx) <<" FIFO header compared to its MBS header, jumping this sub-event... " < 0) { UInt_t l_da0 = *pMbsData++; TTofVftxData hit; if ((l_da0 & vftxtdc::kiFifoMessageType) == vftxtdc::kiFifoMessageType) { TString sTemp = Form("Wrong data item in vftx #%d: type %d (message %08x, header %08x), jumping this sub-event...", fParUnpack->GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx), (l_da0 & vftxtdc::kiFifoMessageType) >> vftxtdc::kiFifoMessageTypeShift, l_da0, l_dat); LOG(WARNING)<> vftxtdc::kiFifoHeadTrigTypeShift, (l_da0 & vftxtdc::kiFifoHeadTrigTime) >> vftxtdc::kiFifoHeadTrigTimeShift, (l_da0 & vftxtdc::kiFifoHeadDataCnt) >> vftxtdc::kiFifoHeadDataCntShift ); LOG(WARNING)<> vftxtdc::kiFifoHeadTrigTypeShift, (l_dat & vftxtdc::kiFifoHeadTrigTime) >> vftxtdc::kiFifoHeadTrigTimeShift, (l_dat & vftxtdc::kiFifoHeadDataCnt) >> vftxtdc::kiFifoHeadDataCntShift ); LOG(WARNING)<> vftxtdc::kiChannelShift ); //4-5 bit LOG(DEBUG1)<<", ch "<< hit.GetChannel(); if ( hit.GetChannel() > vftxtdc::kuNbChan - 1) LOG(WARNING)<<"Channel number larger than "<GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx)<> vftxtdc::kiFiFoFutBitShift ); // 1 bit hit.SetCoarseTime( (l_da0 & vftxtdc::kiFifoCoarseTime) >> vftxtdc::kiFifoCtShift ); // 13-15 bits hit.SetFineTime( (l_da0 & vftxtdc::kiFifoFineTime) >> vftxtdc::kiFifoFtShift ); // 10-11 bits LOG(DEBUG1)<<", tCF: " << hit.GetCoarseTime() << "," << hit.GetFineTime(); // shift odd channels (falling edges) by three coarse time counts // nh if (hit.GetChannel() % 2) hit.SetCoarseTime( hit.GetCoarseTime() + 3 ); LOG(DEBUG1) << "," << hit.GetCoarseTime(); if( kTRUE == fParUnpack->IsDebug() ) { if( (Int_t)( hit.GetCoarseTime() ) - fiLastFpgaTdcCoarse[iTdcIndex*vftxtdc::kuNbChan + hit.GetChannel()] < 6 && -6 < ( hit.GetCoarseTime() ) - fiLastFpgaTdcCoarse[iTdcIndex*vftxtdc::kuNbChan + hit.GetChannel()] && -1 < fiLastFpgaTdcCoarse[iTdcIndex*vftxtdc::kuNbChan + hit.GetChannel()] ) { TString sTemp = Form("Too close hits in vftx #%d channel %d: old coarse %d new coarse %d diff %d ft %3x", fParUnpack->GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx), hit.GetChannel(), fiLastFpgaTdcCoarse[iTdcIndex*vftxtdc::kuNbChan + hit.GetChannel()], hit.GetCoarseTime(), (Int_t)hit.GetCoarseTime() - fiLastFpgaTdcCoarse[iTdcIndex*vftxtdc::kuNbChan + hit.GetChannel()], hit.GetFineTime()); LOG(WARNING)<IsDebug() ) fVftxBoard->AddData( hit ); } // while (uMbsNbData-- > 0) LOG(DEBUG1) << FairLogger::endl; // Attempt at sorting hits according to their times fVftxBoard->SortData(); LOG(DEBUG2)<<" VFTX TDC #"<GetActiveToAllTypeInd(iTdcIndex, tofVme::vftx)<<" finished"<cd(); // <= To prevent histos from being sucked in by the param file of the TRootManager ! TH1* hTemp = 0; // 2D vector of histograms fh1VftxChFt.resize( fuNbTdc ); //1D statistics histo Int_t Nbin=fuNbTdc*vftxtdc::kuNbChan; fh1VftxUnpChMap = new TH1I("tdc_unp_cnts","VFTX unpack channel counts",Nbin,0.,(Double_t)Nbin); // 2D correlation histo fh2VftxUnpChMap = new TH2I("tdc_unp_corr","VFTX unpack channel correlation", Nbin/2,0,Nbin/2,Nbin/2,0,Nbin/2); for( Int_t iBoardIndex = 0; iBoardIndex < fuNbTdc; iBoardIndex++) { // Board specific histograms hTemp = new TH1I( Form("tof_%s_ch_%03d", toftdc::ksTdcHistName[ toftdc::vftx ].Data(), iBoardIndex), Form("Counts per TDC channel for vftx #%03d", iBoardIndex), vftxtdc::kuNbChan, 0.0, vftxtdc::kuNbChan ); fh1VftxRawChMap.push_back( hTemp ); for( Int_t iChannelIndex = 0; iChannelIndex < vftxtdc::kuNbChan; iChannelIndex++) { // Channel specific histograms hTemp = new TH1I( Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ toftdc::vftx ].Data(), iBoardIndex, iChannelIndex), Form("Counts per Finetime bin for TDC channel %3d on vftx #%03d", iChannelIndex, iBoardIndex), vftxtdc::kiFifoFineTime + 1, -0.5, vftxtdc::kiFifoFineTime + 1 - 0.5 ); (fh1VftxChFt[iBoardIndex]).push_back( hTemp ); LOG(DEBUG)<<" TTofVftxUnpacker::CreateHistos => Create FT histo for " <GetEntries() <cd( oldir->GetPath() ); // <= To prevent histos from being sucked in by the param file of the TRootManager! } void TTofVftxUnpacker::FillHistos() { // loop over TDC boards TTofVftxBoard * fVftxBoard; for( Int_t iBoardIndex = 0; iBoardIndex < fuNbTdc; iBoardIndex++) { fVftxBoard = (TTofVftxBoard*) fVftxBoardCollection->ConstructedAt(iBoardIndex); // Loop over hits data for( Int_t iDataIndex = 0; iDataIndex < fVftxBoard->GetDataNb() ; iDataIndex++ ) { TTofVftxData data = fVftxBoard->GetData( iDataIndex); TString sTemp = Form( " TTofVftxUnpacker::FillHistos: Board #%03d Data #%04d Chan %3d CT %7d FT %7d", iBoardIndex, iDataIndex, data.GetChannel(), data.GetCoarseTime(), data.GetFineTime() ); LOG(DEBUG)<Fill(AbsCh); //nh - for quick overview fh1VftxRawChMap[iBoardIndex]->Fill( data.GetChannel() ); fh1VftxChFt[iBoardIndex][ data.GetChannel() ]->Fill( data.GetFineTime() ); fh1VftxUnpChMap->Fill(AbsCh); //nh - for quick overview if ((Int_t)AbsCh%2==0) { TTofVftxBoard * fVftxBoard2; for( Int_t iBoardIndex2 = 0; iBoardIndex2 < fuNbTdc; iBoardIndex2++) { fVftxBoard2 = (TTofVftxBoard*) fVftxBoardCollection->ConstructedAt(iBoardIndex2); // Loop over hits data for( Int_t iDataIndex2 = 0; iDataIndex2 < fVftxBoard2->GetDataNb() ; iDataIndex2++ ) { TTofVftxData data2 = fVftxBoard2->GetData( iDataIndex2); Double_t AbsCh2 = Double_t(iBoardIndex2*vftxtdc::kuNbChan)+data2.GetChannel(); if ((Int_t)AbsCh2%2==0) { fh2VftxUnpChMap->Fill(AbsCh/2,AbsCh2/2); //nh - for quick overview } } } } } // for( Int_t iDataIndex = 0; iDataIndex < fVftxBoard[iBoardIndex]->GetDataNb() ; iDataIndex++ ) } // for( Int_t iBoardIndex = 0; iBoardIndex < fuNbTdc; IBoardIndex++) } void TTofVftxUnpacker::WriteHistos( TDirectory* inDir) { TDirectory * oldir = gDirectory; TDirectory *cdVftxUnp[fuNbTdc]; fh1VftxUnpChMap->Write(); fh2VftxUnpChMap->Write(); for( Int_t iBoardIndex = 0; iBoardIndex < fuNbTdc; iBoardIndex++) { cdVftxUnp[iBoardIndex] = inDir->mkdir( Form( "Unp_%s_%03d", toftdc::ksTdcHistName[ toftdc::vftx ].Data(), iBoardIndex) ); cdVftxUnp[iBoardIndex]->cd(); // make the "Unp_triglog" directory the current directory fh1VftxRawChMap[iBoardIndex]->Write(); for( Int_t iChannelIndex = 0; iChannelIndex < vftxtdc::kuNbChan; iChannelIndex++) { fh1VftxChFt[iBoardIndex][iChannelIndex]->Write(); } // for( Int_t iChannelIndex = 0; iChannelIndex < vftxtdc::kuNbChan; iChannelIndex++) } // for( Int_t iBoardIndex = 0; iBoardIndex < fuNbTdc; iBoardIndex++) } void TTofVftxUnpacker::DeleteHistos() { fh1VftxRawChMap.clear(); for( Int_t iBoardIndex = 0; iBoardIndex < fuNbTdc; iBoardIndex++) (fh1VftxChFt[iBoardIndex]).clear(); fh1VftxChFt.clear(); }