// ------------------------------------------------------------------ // ----- TMbsCalibTdcTof ----- // ----- Created 20/06/2013 by P.-A. Loizeau ----- // ------------------------------------------------------------------ #include "TMbsCalibTdcTof.h" // General Unpack headers #include "TMbsUnpackTofPar.h" // ToF specific headers #include "TMbsCalibTofPar.h" #include "TofTdcDef.h" #include "TofCaenDef.h" #include "TofVftxDef.h" #include "TofTrb3Def.h" #include "TofGet4Def.h" #include "TTofTdcBoard.h" #include "TTofTdcData.h" #include "TTofCalibData.h" // FAIR headers #include "FairLogger.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" #include "FairRootManager.h" // ROOT headers #include "TClonesArray.h" #include "TH2.h" #include "TH1.h" #include "TROOT.h" #include "TTimeStamp.h" TMbsCalibTdcTof::TMbsCalibTdcTof() : fMbsUnpackPar(NULL), fMbsCalibPar(NULL), fCaenBoardCollection(NULL), fVftxBoardCollection(NULL), fTrb3BoardCollection(NULL), fGet4BoardCollection(NULL), fCalibDataCollection(NULL) { // Get Base Container FairRunAna* ana = FairRunAna::Instance(); FairRuntimeDb* rtdb=ana->GetRuntimeDb(); // Unpack parameter fMbsUnpackPar = (TMbsUnpackTofPar*) (rtdb->getContainer("TMbsUnpackTofPar")); if( 0 == fMbsUnpackPar ) LOG(ERROR)<<"TMbsCalibTdcTof::TMbsCalibTdcTof => Could not obtain the TMbsUnpackTofPar "<getContainer("TMbsCalibTofPar")); if( 0 == fMbsCalibPar ) LOG(ERROR)<<"TMbsCalibTdcTof::TMbsCalibTdcTof => Could not obtain the TMbsCalibTofPar "<printParams(); } TMbsCalibTdcTof::TMbsCalibTdcTof(TMbsUnpackTofPar * parIn, TMbsCalibTofPar *parCalIn) : fMbsUnpackPar(parIn), fMbsCalibPar(parCalIn), fCaenBoardCollection(NULL), fVftxBoardCollection(NULL), fTrb3BoardCollection(NULL), fGet4BoardCollection(NULL), fCalibDataCollection(NULL) { } TMbsCalibTdcTof::~TMbsCalibTdcTof() { DeleteHistograms(); DeleteTotVariables(); LOG(INFO)<<"**** TMbsCalibTdcTof: Delete instance "<GetNbActiveBoards( uType ); iTdc ++) Calibration( uType, iTdc); // TOT mode 1 and 4 are already done. // TOT mode 2 time orders and builds TOT for each TDC inside the Calibration function if( 3 == fMbsCalibPar->GetTotMode( uType ) ) // In the case where 1 input channel correspond to a TDC channel in 2 consecutive boards, // we can time order the hits now that we have all boards calibrated // and then we will be able to associate the hits in full calibrated TDC data! BuildTotSplitBoards( uType ); } return kTRUE; } Bool_t TMbsCalibTdcTof::CloseTdcCalib() { if( kTRUE == fMbsCalibPar->EnaCalibOutput() ) WriteCalibrationFile(); if( kTRUE == fMbsCalibPar->EnaSingleCalibOutput() ) WriteSingleCalibrations(); return kTRUE; } Bool_t TMbsCalibTdcTof::InitParameters() { } // ------------------------------------------------------------------ Bool_t TMbsCalibTdcTof::RegisterInput() { FairRootManager* rootMgr = FairRootManager::Instance(); if( 0 < fMbsUnpackPar->GetNbActiveBoards( toftdc::caenV1290 ) ) { fCaenBoardCollection = (TClonesArray*) rootMgr->GetObject("TofCaenTdc"); if( NULL == fCaenBoardCollection) { LOG(ERROR)<<"TMbsCalibTdcTof::RegisterInput => Could not get the TofCaenTdc TClonesArray!!!"<GetNbActiveBoards( uType ) ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( toftdc::vftx ) ) { fVftxBoardCollection = (TClonesArray*) rootMgr->GetObject("TofVftxTdc"); if( NULL == fVftxBoardCollection) { LOG(ERROR)<<"TMbsCalibTdcTof::RegisterInput => Could not get the TofVftxTdc TClonesArray!!!"<GetNbActiveBoards( uType ) ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( toftdc::trb3 ) ) { fTrb3BoardCollection = (TClonesArray*) rootMgr->GetObject("TofTrb3Tdc"); if( NULL == fTrb3BoardCollection) { LOG(ERROR)<<"TMbsCalibTdcTof::RegisterInput => Could not get the TofTrb3Tdc TClonesArray!!!"<GetNbActiveBoards( uType ) ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( toftdc::get4 ) ) { fGet4BoardCollection = (TClonesArray*) rootMgr->GetObject("TofGet4Tdc"); if( NULL == fGet4BoardCollection) { LOG(ERROR)<<"TMbsCalibTdcTof::RegisterInput => Could not get the TofGet4Tdc TClonesArray!!!"<GetNbActiveBoards( uType ) ) return kTRUE; } Bool_t TMbsCalibTdcTof::RegisterOutput() { FairRootManager* rootMgr = FairRootManager::Instance(); fCalibDataCollection = new TClonesArray("TTofCalibData"); // rootMgr->Register("TofCalibData","Tof",fCalibDataCollection, kTRUE); rootMgr->Register( "TofCalibData","Tof",fCalibDataCollection, fMbsUnpackPar->WriteDataInCbmOut()); /* fCalibTdcTrigCollection = new TClonesArray("Double_t"); rootMgr->Register("TofCalibTdcTrigg","Tof",fCalibTdcTrigCollection, kTRUE); */ return kTRUE; } Bool_t TMbsCalibTdcTof::ClearOutput() { fCalibDataCollection->Clear("C"); return kTRUE; } // ------------------------------------------------------------------ Bool_t TMbsCalibTdcTof::CreateHistogramms() { // Loop over all TDC types for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) { if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; Double_t dClockCycle = 0.0; UInt_t uFtBinNb = 0; UInt_t uMaxMul = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; dClockCycle = caentdc::kdClockCycleSize; uFtBinNb = caentdc::kiFineTime + 1; uMaxMul = toftdc::kuDefNbMulti; // TODO: add proper value for this type break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; dClockCycle = vftxtdc::kdClockCycleSize; uFtBinNb = vftxtdc::kiFifoFineTime + 1; uMaxMul = vftxtdc::kuNbMulti; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; dClockCycle = trb3tdc::kdClockCycleSize; uFtBinNb = trb3tdc::kiFineTime + 1; uMaxMul = toftdc::kuDefNbMulti; // TODO: add proper value for this type break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; dClockCycle = get4tdc::kdClockCycleSize; uFtBinNb = get4tdc::kiFineTime + 1; uMaxMul = toftdc::kuDefNbMulti; // TODO: add proper value for this type break; default: break; } // switch( uType ) // Calibration variable initialization Int_t NHBins=fMbsUnpackPar->GetNbActiveBoards(uType) * uNbChan / 2; fhCalHits[uType]=new TH1D(Form("hCalHits%01d",uType),"Calibrated TDC hits",NHBins,0.,(Double_t)NHBins); fhDnlChan[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan, NULL ); fhDnlSum[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan, NULL ); fhBinSizeChan[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan, NULL ); for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbChan + iChanInd; // Current Dnl correction per bin fhDnlChan[uType][iHistoIndex] = new TH1D( Form("tof_%s_dnlch_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Current Dnl factor for channel %3d in %s TDC #%03d", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), uFtBinNb, -0.5, uFtBinNb-0.5 ); // Current Dnl Sum per bin fhDnlSum[uType][iHistoIndex] = new TH1D( Form("tof_%s_dnlsum_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Current Dnl Sum for channel %3d in %s TDC #%03d; Bin[]; ", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), uFtBinNb, -0.5, uFtBinNb-0.5 ); // Current Bin sizes from Dnl correction fhBinSizeChan[uType][iHistoIndex] = new TH1D( Form("tof_%s_binszch_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Current Bin size from Dnl factor for channel %3d in %s TDC #%03d; Bin size [ps]; Bins []", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), (Int_t)(20*dClockCycle/uFtBinNb), -0.5, 20*dClockCycle/uFtBinNb -0.5 ); } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) // Monitoring histograms UInt_t uNbDataChan = uNbChan; // If we are using the 1 input chan = 2 tdc chan tot mode, the number of channels in // calibrated data is halved! if( 2 == fMbsCalibPar->GetTotMode(uType) ) uNbDataChan /= 2; if( kTRUE == fMbsCalibPar->IsTimeHistEna() ) fhTimeToTrigg[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbDataChan, NULL ); if( kTRUE == fMbsCalibPar->IsSingleTimeHistEna() ) fhTimeToTriggSingles[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbDataChan, NULL ); if( kTRUE == fMbsCalibPar->IsTotHistEna() && 0 < fMbsCalibPar->GetTotMode(uType) ) fhToT[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbDataChan, NULL ); if( kTRUE == fMbsCalibPar->IsMultiDistHistEna() ) fhMultiDist[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbDataChan, NULL ); fhMultiplicity[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ), NULL ); for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) { for( Int_t iChanInd = 0; iChanInd< uNbDataChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbDataChan + iChanInd; // Time to board trigger in ps if( kTRUE == fMbsCalibPar->IsTimeHistEna() ) fhTimeToTrigg[uType][iHistoIndex] = new TH1I( Form("tof_%s_t2trig_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Time to board trigger for channel %3d in %s TDC #%03d; Trigger time - Calibrated Time [ps]", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), 8000, -700000.0, 100000.0 ); // Time to board trigger in ps for events with a single hit in the channel if( kTRUE == fMbsCalibPar->IsSingleTimeHistEna() ) fhTimeToTriggSingles[uType][iHistoIndex] = new TH1I( Form("tof_%s_t2trig_sing_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Time to board trigger for events with a single hit for channel %3d in %s TDC #%03d; Trigger time - Calibrated Time [ps]", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), 8000, -700000.0, 100000.0 ); // Tot in ps if( kTRUE == fMbsCalibPar->IsTotHistEna() && 0 < fMbsCalibPar->GetTotMode(uType) ) fhToT[uType][iHistoIndex] = new TH1I( Form("tof_%s_tot_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Time over threshold for channel %3d in %s TDC #%03d; ToT [ps]", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), 30000, -150000, 150000 ); // Distance between consecutive multiple hits on same channel in ps if( kTRUE == fMbsCalibPar->IsMultiDistHistEna() ) fhMultiDist[uType][iHistoIndex] = new TH2I( Form("tof_%s_muldist_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd), Form("Time to previous hit for multiple hits for channel %3d in %s TDC #%03d; T(n) - T(n-1) [ps]; n (Multiple hits index) []", iChanInd, toftdc::ksTdcHistName[ uType ].Data(), iTdc), 7500, -50000, 100000, vftxtdc::kuNbMulti, 1, vftxtdc::kuNbMulti + 1 ); } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) //Multiplicity fhMultiplicity[uType][iTdc] = new TH2I( Form("tof_%s_mul_b%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc), Form("Data multiplicty per channel in %s TDC #%03d; Channel []; Multiplicity []", toftdc::ksTdcHistName[ uType ].Data(), iTdc), uNbDataChan, 0.0, uNbDataChan, uMaxMul + 1, 0, uMaxMul + 1 ); } // for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) } // for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) return kTRUE; } Bool_t TMbsCalibTdcTof::FillHistograms() { TTofCalibData * fCalibData; LOG(DEBUG)<<"TMbsCalibTdcTof::FillHistograms => "<GetEntriesFast() <<" data unpacked & calibrated successfully in this event!"< uMul[ toftdc::NbTdcTypes ]; std::vector< Double_t > dLastTime[ toftdc::NbTdcTypes ]; // If we are using the 1 input chan = 2 tdc chan tot mode, the number of channels in // calibrated data is halved! for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) { if( 2 == fMbsCalibPar->GetTotMode(uType) ) uNbChan[ uType ] /= 2; uMul[ uType ].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan[uType] ); dLastTime[ uType ].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan[uType] ); } // loop over Calibrated Data for( Int_t iDataIndex = 0; iDataIndex < fCalibDataCollection->GetEntriesFast() ; iDataIndex++ ) { fCalibData = (TTofCalibData *)fCalibDataCollection->At( iDataIndex ); // Monitoring histograms UInt_t uType = fCalibData->GetType(); UInt_t uTdc = fCalibData->GetBoard(); UInt_t uChan = fCalibData->GetChannel(); Double_t dTime = fCalibData->GetTime(); Double_t dTot = fCalibData->GetTot(); Int_t iHistoIndex = uTdc*uNbChan[uType] + uChan; fhCalHits[uType]->Fill((Double_t) iHistoIndex ); // Time to board trigger in ps if( kTRUE == fMbsCalibPar->IsTimeHistEna() ) fhTimeToTrigg[uType][iHistoIndex]->Fill( dTime - fdBoardTriggerTime[uType][uTdc] ); // Tot in ps if( kTRUE == fMbsCalibPar->IsTotHistEna() ) fhToT[uType][iHistoIndex]->Fill( dTot ); // Distance between consecutive multiple hits on same channel in ps if( kTRUE == fMbsCalibPar->IsMultiDistHistEna() && 0 < uMul[ uType ][ iHistoIndex ] ) fhMultiDist[uType][iHistoIndex]->Fill( uMul[ uType ][ iHistoIndex ], dTime - dLastTime[ uType ][ iHistoIndex ] ); // Multi hits data uMul[ uType ][ iHistoIndex ]++; dLastTime[ uType ][ iHistoIndex ] = dTime; TString sTemp = Form( "TMbsCalibTdcTof::FillHistos: Data #%04d Type %s Board #%03d Chan %3d Time %7.0f Tot %7.0f Edge %1d", iDataIndex, // toftdc::ksTdcHistName[ fCalibData->GetType() ].Data(), "Missing", fCalibData->GetBoard(), fCalibData->GetChannel(), fCalibData->GetTime(), fCalibData->GetTot(), fCalibData->GetEdge() ); LOG(DEBUG)<GetDataNb() ; iDataIndex++ ) // Time to board trigger in ps for events with a single hit in the channel for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) { TString sTemp = Form( "TMbsCalibTdcTof::FillHistos: %s Board #%03d Trigger Time %7.0f ", toftdc::ksTdcHistName[ uType ].Data(), iTdc, fdBoardTriggerTime[uType][iTdc] ); LOG(DEBUG)<Fill(iChanInd, uMul[uType][ iTdc*uNbChan[uType] + iChanInd ] ); if( 1 == uMul[uType][ iTdc*uNbChan[uType] + iChanInd ] && kTRUE == fMbsCalibPar->IsSingleTimeHistEna() ) { Int_t iHistoIndex = iTdc*uNbChan[uType] + iChanInd; fhTimeToTriggSingles[uType][iHistoIndex]->Fill( dLastTime[uType][iHistoIndex] - fdBoardTriggerTime[uType][iTdc] ); } // if( 1 == uMul[uType][ iTdc*uNbChan[uType] + iChanInd ] ) } // for( Int_t iChanInd = 0; iChanInd< uNbChan[uType]; iChanInd++) } // for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) return kTRUE; } Bool_t TMbsCalibTdcTof::WriteHistogramms( TDirectory* inDir) { TDirectory * oldir = gDirectory; for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; break; default: break; } // switch( uType ) LOG(DEBUG) <<"TMbsCalibTdcTof::WriteHistogramms for type " << uType << FairLogger::endl; // save overview histos fhCalHits[uType]->Write(); // create a subdirectory "Cal_type" in this file TDirectory *cdCal = inDir->mkdir( Form( "Cal_%s", toftdc::ksTdcHistName[ uType ].Data() ) ); cdCal->cd(); // make the "Cal_type" directory the current directory TDirectory *cdCalTdc[ fMbsUnpackPar->GetNbActiveBoards( uType ) ]; TDirectory *cdCalTdcHist[ fMbsUnpackPar->GetNbActiveBoards( uType ) ][3]; // loop over active TDCs for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) { // Create a sub folder for each TDC cdCalTdc[iTdc] = cdCal->mkdir( Form( "cTdc%03d", iTdc) ); cdCalTdc[iTdc]->cd(); // Create a sub folder for each histogram type cdCalTdcHist[iTdc][0] = cdCalTdc[iTdc]->mkdir( Form( "dnl%03d", iTdc) ); cdCalTdcHist[iTdc][1] = cdCalTdc[iTdc]->mkdir( Form( "dnlSum%03d", iTdc) ); cdCalTdcHist[iTdc][2] = cdCalTdc[iTdc]->mkdir( Form( "binSz%03d", iTdc) ); // Loop over all TDC channels for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbChan + iChanInd; // Current Dnl correction per bin cdCalTdcHist[iTdc][0]->cd(); fhDnlChan[uType][iHistoIndex]->Write(); // Current Dnl Sum per bin cdCalTdcHist[iTdc][1]->cd(); fhDnlSum[uType][iHistoIndex]->Write(); // Current Bin sizes from Dnl correction cdCalTdcHist[iTdc][2]->cd(); fhBinSizeChan[uType][iHistoIndex]->Write(); } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) } // for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) // Monitoring histograms UInt_t uNbDataChan = uNbChan; // If we are using the 1 input chan = 2 tdc chan tot mode, the number of channels in // calibrated data is halved! if( 2 == fMbsCalibPar->GetTotMode(uType) ) uNbDataChan /= 2; // create a subdirectory "Mon_Type" in this file TDirectory *cdMon = inDir->mkdir( Form( "Mon_%s", toftdc::ksTdcHistName[ uType ].Data() ) ); cdMon->cd(); // make the "Mon_type" directory the current directory TDirectory *cdMonTdc[ fMbsUnpackPar->GetNbActiveBoards( uType ) ]; TDirectory *cdMonTdcHist[ fMbsUnpackPar->GetNbActiveBoards( uType ) ][4]; // loop over active TDCs for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) { // Create a sub folder for each TDC cdMonTdc[iTdc] = cdMon->mkdir( Form( "mTdc%03d", iTdc) ); cdMonTdc[iTdc]->cd(); fhMultiplicity[uType][iTdc]->Write(); // Create a sub folder for each histogram type if( kTRUE == fMbsCalibPar->IsTimeHistEna() ) cdMonTdcHist[iTdc][0] = cdMonTdc[iTdc]->mkdir( Form( "t2trig%03d", iTdc) ); if( kTRUE == fMbsCalibPar->IsSingleTimeHistEna() ) cdMonTdcHist[iTdc][1] = cdMonTdc[iTdc]->mkdir( Form( "t2trig_sing%03d", iTdc) ); if( kTRUE == fMbsCalibPar->IsTotHistEna() ) cdMonTdcHist[iTdc][2] = cdMonTdc[iTdc]->mkdir( Form( "tot%03d", iTdc) ); if( kTRUE == fMbsCalibPar->IsMultiDistHistEna() ) cdMonTdcHist[iTdc][3] = cdMonTdc[iTdc]->mkdir( Form( "mulDist%03d", iTdc) ); // Loop over all input channels for( Int_t iChanInd = 0; iChanInd< uNbDataChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbDataChan + iChanInd; if( kTRUE == fMbsCalibPar->IsTimeHistEna() ) { cdMonTdcHist[iTdc][0]->cd(); fhTimeToTrigg[uType][iHistoIndex]->Write(); } // if( kTRUE == fMbsCalibPar->IsTimeHistEna() ) if( kTRUE == fMbsCalibPar->IsSingleTimeHistEna() ) { cdMonTdcHist[iTdc][1]->cd(); fhTimeToTriggSingles[uType][iHistoIndex]->Write(); } // if( kTRUE == fMbsCalibPar->IsSingleTimeHistEna() ) if( kTRUE == fMbsCalibPar->IsTotHistEna() ) { cdMonTdcHist[iTdc][2]->cd(); fhToT[uType][iHistoIndex]->Write(); } // if( kTRUE == fMbsCalibPar->IsTotHistEna() ) if( kTRUE == fMbsCalibPar->IsMultiDistHistEna() ) { cdMonTdcHist[iTdc][3]->cd(); fhMultiDist[uType][iHistoIndex]->Write(); } // if( kTRUE == fMbsCalibPar->IsMultiDistHistEna() ) } // for( Int_t iChanInd = 0; iChanInd< uNbDataChan[uType]; iChanInd++) } // for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) gDirectory->cd( oldir->GetPath() ); return kTRUE; } Bool_t TMbsCalibTdcTof::DeleteHistograms() { return kTRUE; } // ------------------------------------------------------------------ Bool_t TMbsCalibTdcTof::InitCalibration() { // Loop over all TDC types for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) { if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; UInt_t uFtBinNb = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; uFtBinNb = caentdc::kiFineTime + 1; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; uFtBinNb = vftxtdc::kiFifoFineTime + 1; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; uFtBinNb = trb3tdc::kiFineTime + 1; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; uFtBinNb = get4tdc::kiFineTime + 1; break; default: break; } // switch( uType ) // Calibration variable initialization fiNbHitsForCalib[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan, 0 ); fdCorr[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan ); fdBoardTriggerTime[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ), 0.0 ); // loop over all active TDC & all channels for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbChan + iChanInd; fdCorr[uType][iHistoIndex].resize(uFtBinNb, 0.0); } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) } // for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( kTRUE == fMbsCalibPar->EnaSingleCalib() ) LoadSingleCalibrations(); else LoadCalibrationFile(); return kTRUE; } Bool_t TMbsCalibTdcTof::GetHistosFromUnpack() { TDirectory * oldir = gDirectory; // <= To prevent histos from being sucked in by the param file of the TRootManager! gROOT->cd(); // <= To prevent histos from being sucked in by the param file of the TRootManager ! // Loop over all TDC types for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) { if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; break; default: break; } // switch( uType ) fhFineTime[uType].resize( fMbsUnpackPar->GetNbActiveBoards( uType ) * uNbChan ); TString sInfoLoading = "Got FineTime histograms from unpack step for following "+ toftdc::ksTdcHistName[ uType ] + " TDC channels:"; LOG(INFO)<GetNbActiveBoards( uType ); iTdc ++) { sInfoLoading = Form("tdc #%3d: ",iTdc ); for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbChan + iChanInd; // gDirectory->GetObject( Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), // iTdc, iChanInd), // fhFineTime[uType][iHistoIndex]); fhFineTime[uType][iHistoIndex] = (TH1*) gDirectory->FindObject( Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd)); if( NULL == fhFineTime[uType][iHistoIndex] ) { LOG(ERROR)<<" TMbsCalibTdcTof::GetHistosFromUnpack => Could not get FT histo for " <cd( oldir->GetPath() ); // <= To prevent histos from being sucked in by the param file of the TRootManager! return kFALSE; } // if( NULL == fhFineTime[uType][iHistoIndex] ) else LOG(DEBUG)<<" TMbsCalibTdcTof::GetHistosFromUnpack =>Got FT histo for " <GetEntries() <GetNbActiveBoards( uType ); iTdc ++) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) else LOG(INFO)<<" TMbsCalibTdcTof::GetHistosFromUnpack => no boards for "<cd( oldir->GetPath() ); // <= To prevent histos from being sucked in by the param file of the TRootManager! return kTRUE; } Bool_t TMbsCalibTdcTof::LoadCalibrationFile() { // First check if the inital calibration file name is properly defined if( kTRUE != fMbsCalibPar->GetInitCalFilename().EqualTo("") && kTRUE != fMbsCalibPar->GetInitCalFilename().EqualTo("-") ) { // Save online ROOT directory as the File opening auto change current Dir oldDir = gDirectory; TString sInitialCalibHistoName = ""; fileCalibrationIn = new TFile( fMbsCalibPar->GetInitCalFilename(), "READ"); if( kTRUE == fileCalibrationIn->IsOpen() ) { // Loop over all TDC types for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) { if( 0 == fMbsCalibPar->GetNbCalibBoards( uType ) || 0 == fMbsUnpackPar->GetNbActiveBoards( uType ) ) continue; UInt_t uNbChan = 0; UInt_t uFtBinNb = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; uFtBinNb = caentdc::kiFineTime + 1; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; uFtBinNb = vftxtdc::kiFifoFineTime + 1; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; uFtBinNb = trb3tdc::kiFineTime + 1; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; uFtBinNb = get4tdc::kiFineTime + 1; break; default: break; } // switch( uType ) if( 0 == uNbChan || 1 == uFtBinNb ) { LOG(INFO)<<"TMbsCalibTdcTof::LoadCalibrationFile Undefined tdc parameters for type "; LOG(INFO)< No initial calib loading!"<GetNbCalibBoards( uType ) * uNbChan, NULL ); Bool_t bincontrol[uFtBinNb]; Int_t iSum[fMbsCalibPar->GetNbCalibBoards( uType )][uNbChan]; // Temp variable to store pointer on calib histo in File TH1* fInitialCalibHistoFromFile = 0; for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) { if( -1 < fMbsCalibPar->GetInitialCalInd( uType, iTdc ) ) { sInfoLoading = Form("tdc #%3d: ",iTdc ); for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Int_t iHistoIndex = iTdc*uNbChan + iChanInd; // Initialize pointer to NULL fInitialCalibHistoFromFile = NULL; // Find histogram in file and store its pointer in a temp variable sInitialCalibHistoName = Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), fMbsCalibPar->GetInitialCalInd( uType, iTdc ), iChanInd ); fileCalibrationIn->GetObject( sInitialCalibHistoName, fInitialCalibHistoFromFile); if( NULL == fInitialCalibHistoFromFile ) sInfoLoading += " 0 "; else { sInfoLoading += " 1 "; // Clone the found histo and move it to online ROOT directory instead of File fhInitialCalibHisto[ uType ][ iHistoIndex ] = (TH1*)fInitialCalibHistoFromFile->Clone( Form("%s_CalibFile", sInitialCalibHistoName.Data() ) ); fhInitialCalibHisto[ uType ][ iHistoIndex ]->SetDirectory( oldDir ); } // else of if( 0 == fInitialCalibHistoFromFile ) // Extract calibration factors from initialization histo CalibFactorsInit( uType, iTdc, iChanInd ); } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) LOG(INFO)<GetInitialCalInd( uType, iTdc ) ) } // for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) } // for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) // File closing and going back to online ROOT folder fileCalibrationIn->Close(); gDirectory->Cd(oldDir->GetPath()); } // if( kTRUE == fileCalibrationIn->IsOpen() ) else { LOG(INFO)<<"Could not open "<GetInitCalFilename(); LOG(INFO)<<" to load initial TDC calibration, please check setting in Calibration option file"<GetNbCalibBoards( uType ) || 0 == fMbsUnpackPar->GetNbActiveBoards( uType ) ) continue; else { UInt_t uNbChan = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; break; default: break; } // switch( uType ) if( 0 == uNbChan ) { LOG(INFO)<<"TMbsCalibTdcTof::LoadCalibrationFile Undefined tdc parameters for type "; LOG(INFO)< No initial calib loading!"<GetNbCalibBoards( uType ) * uNbChan, NULL ); } return kFALSE; } // else of if( kTRUE == fileCalibrationIn->IsOpen() ) } // if( sInitialCalibrationFilename OK and 1 == fMbsCalibPar->uEnableCalib) return kTRUE; } Bool_t TMbsCalibTdcTof::LoadSingleCalibrations() { for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) { if( 0 == fMbsCalibPar->GetNbCalibBoards( uType ) || 0 == fMbsUnpackPar->GetNbActiveBoards( uType ) ) continue; UInt_t uNbChan = 0; UInt_t uFtBinNb = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; uFtBinNb = caentdc::kiFineTime + 1; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; uFtBinNb = vftxtdc::kiFifoFineTime + 1; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; uFtBinNb = trb3tdc::kiFineTime + 1; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; uFtBinNb = get4tdc::kiFineTime + 1; break; default: break; } // switch( uType ) if( 0 == uNbChan || 1 == uFtBinNb ) { LOG(INFO)<<"TMbsCalibTdcTof::LoadSingleCalibrations Undefined tdc parameters for type "; LOG(INFO)< No initial calib loading!"<GetNbCalibBoards( uType ) * uNbChan, NULL ); Bool_t bincontrol[uFtBinNb]; Int_t iSum[fMbsCalibPar->GetNbCalibBoards( uType )][uNbChan]; // Save online ROOT directory as the File opening auto change current Dir oldDir = gDirectory; for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) if( -1 < fMbsCalibPar->GetInitialCalInd( uType, iTdc ) ) { sInfoLoading = Form("tdc #%3d: ",iTdc ); for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { TString sInitialCalibFileName = Form("./calib/%s_Tdc%03dChan%03d.root ", toftdc::ksTdcHistName[ uType ].Data(), fMbsCalibPar->GetInitialCalInd( uType, iTdc ), iChanInd); TString sInitialCalibHistoName = ""; fileCalibrationIn = new TFile( sInitialCalibFileName, "READ"); if( kTRUE == fileCalibrationIn->IsOpen() ) { // Initialize pointer to NULL TH1* fInitialCalibHistoFromFile = NULL; sInitialCalibHistoName = Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), fMbsCalibPar->GetInitialCalInd( uType, iTdc ), iChanInd ); fileCalibrationIn->GetObject( sInitialCalibHistoName, fInitialCalibHistoFromFile); Int_t iHistoIndex = iTdc*uNbChan + iChanInd; if( NULL == fInitialCalibHistoFromFile ) sInfoLoading += " 0 "; else { sInfoLoading += " 1 "; fhInitialCalibHisto[ uType ][ iHistoIndex ] = (TH1*)fInitialCalibHistoFromFile->Clone( Form("%s_CalibFile", sInitialCalibHistoName.Data() ) ); fhInitialCalibHisto[ uType ][ iHistoIndex ]->SetDirectory( oldDir ); // Extract calibration factors from initialization histo CalibFactorsInit( uType, iTdc, iChanInd ); } // else of if( NULL == fInitialCalibHistoFromFile ) fileCalibrationIn->Close(); } // if( kTRUE == fileCalibrationIn->IsOpen() ) else sInfoLoading += " 0 "; } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) LOG(INFO)<GetInitialCalInd( uType, iTdc ) ) } // for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) return kTRUE; } Bool_t TMbsCalibTdcTof::CalibFactorsInit( UInt_t uType, UInt_t uBoard, UInt_t uChan ) { UInt_t uNbChan = 0; Double_t dClockCycle = 0.0; UInt_t uFtBinNb = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; dClockCycle = caentdc::kdClockCycleSize; uFtBinNb = caentdc::kiFineTime + 1; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; dClockCycle = vftxtdc::kdClockCycleSize; uFtBinNb = vftxtdc::kiFifoFineTime + 1; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; dClockCycle = trb3tdc::kdClockCycleSize; uFtBinNb = trb3tdc::kiFineTime + 1; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; dClockCycle = get4tdc::kdClockCycleSize; uFtBinNb = get4tdc::kiFineTime + 1; break; default: break; } // switch( uType ) Int_t iHistoIndex = uBoard*uNbChan + uChan; if( NULL != fhInitialCalibHisto[ uType ][ iHistoIndex ]) { // Reset Histos with DNL ploting fhDnlChan[uType][iHistoIndex]->Reset(); fhDnlSum[uType][iHistoIndex]->Reset(); fhBinSizeChan[uType][iHistoIndex]->Reset(); //set the sum to zero before summing over all bins in one channel Bool_t bincontrol[uFtBinNb]; Int_t iSum = 0; Double_t dTotalEntriesInHisto = (Double_t)(fhInitialCalibHisto[ uType ][ iHistoIndex ]->GetEntries() ); for(Int_t iBin = 0; iBin < (Int_t)uFtBinNb; iBin++) { Int_t iBinContent = (Int_t)(fhInitialCalibHisto[ uType ][ iHistoIndex ]->GetBinContent(iBin+1)); //Looking for the used bins if( iBinContent <= 0) bincontrol[iBin] = kFALSE; else if( iBinContent > 0) bincontrol[iBin] = kTRUE; // build the sum of all bin content if(bincontrol[iBin]) { iSum = iSum + iBinContent; fdCorr[uType][iHistoIndex][iBin] = (Double_t)iSum / dTotalEntriesInHisto; fhDnlChan[uType][iHistoIndex]->Fill(iBin, (Double_t)iBinContent/dTotalEntriesInHisto ); fhBinSizeChan[uType][iHistoIndex]->Fill( dClockCycle*(Double_t)iBinContent/dTotalEntriesInHisto ); } // if(bincontrol[iBin]) else { if( 0 < iBin) fdCorr[uType][iHistoIndex][iBin] = fdCorr[uType][iHistoIndex][iBin-1]; else fdCorr[uType][iHistoIndex][iBin] = 0.0; } // else of if(bincontrol[iBin]) fhDnlSum[uType][iHistoIndex]->Fill(iBin, fdCorr[uType][iHistoIndex][iBin] ); } // for(Int_t iBin=0; iBin < (Int_t)uFtBinNb; iBin++) } // if( NULL != fInitialCalibHisto[iTdc][iChanInd]) else return kFALSE; return kTRUE; } Bool_t TMbsCalibTdcTof::Calibration( UInt_t uType, UInt_t uBoard) { LOG(DEBUG)<<"TMbsCalibTdcTof::Calibration => Type "<GetNbActiveBoards( uType ) <<" Board "<GetNbActiveBoards( uType ) ) { // TDC type specific values UInt_t uNbChan = 0; TClonesArray * xUnpDataArray = NULL; Double_t dClockCycle = 0.0; Bool_t bInvertFt = kFALSE; Double_t dTotBinToPs = 0.0; Int_t iCoarseSize = 0; Int_t iCoarseOfLim = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; xUnpDataArray = fCaenBoardCollection; dClockCycle = caentdc::kdClockCycleSize; bInvertFt = caentdc::kbInvertFt; iCoarseSize = caentdc::kiCoarseCounterSize; iCoarseOfLim = caentdc::kiCoarseOverflowTest; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; xUnpDataArray = fVftxBoardCollection; dClockCycle = vftxtdc::kdClockCycleSize; bInvertFt = vftxtdc::kbInvertFt; iCoarseSize = vftxtdc::kiCoarseCounterSize; iCoarseOfLim = vftxtdc::kiCoarseOverflowTest; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; xUnpDataArray = fTrb3BoardCollection; dClockCycle = trb3tdc::kdClockCycleSize; bInvertFt = trb3tdc::kbInvertFt; iCoarseSize = trb3tdc::kiCoarseCounterSize; iCoarseOfLim = trb3tdc::kiCoarseOverflowTest; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; xUnpDataArray = fGet4BoardCollection; dClockCycle = get4tdc::kdClockCycleSize; bInvertFt = get4tdc::kbInvertFt; dTotBinToPs = get4tdc::kdTotBinSize; iCoarseSize = get4tdc::kiCoarseCounterSize; iCoarseOfLim = get4tdc::kiCoarseOverflowTest; break; default: break; } // switch( uType ) if( NULL == xUnpDataArray || NULL == fCalibDataCollection ) { LOG(ERROR)<<"TMbsCalibTdcTof::Calibration => Data pt failed Type "<GetNbActiveBoards( uType ) <<" Board "<At(uBoard); if( NULL == xBoardUnpData ) { fdBoardTriggerTime[uType][uBoard] = 0.0; LOG(ERROR)<<"TMbsCalibTdcTof::Calibration => Bd pt failed Type "<GetNbActiveBoards( uType ) <<" Board "<GetTotMode( uType ) ) xTempCalibData[uType]->Clear("C"); // Trigger time Int_t iTriggerCoarseTime = xBoardUnpData->GetTriggerTime(); fdBoardTriggerTime[uType][uBoard] = iTriggerCoarseTime * dClockCycle; // TODO: board time corrections => board to board offset, Offsets between different tdc types, etc... // Data calibration Int_t iNbUnpData = xBoardUnpData->GetDataNb(); TTofTdcData * xUnpDataPtr; TTofCalibData * xCalData; LOG(DEBUG)<<"TMbsCalibTdcTof::Calibration Type "<GetDataPtr(iUnpDataInd); Int_t iHistoIndex = uBoard*uNbChan + xUnpDataPtr->GetChannel(); Int_t iCoarseTime = xUnpDataPtr->GetCoarseTime(); Double_t dCalibTime = dClockCycle * iCoarseTime; if( kTRUE == bInvertFt ) dCalibTime += dClockCycle *( 1 - fdCorr[uType][iHistoIndex][xUnpDataPtr->GetFineTime()] ); else dCalibTime += dClockCycle * fdCorr[uType][iHistoIndex][xUnpDataPtr->GetFineTime()]; if( kTRUE == fMbsCalibPar->UseCoarse() ) { // Test Coarse counter Overflow if( iCoarseOfLim < iCoarseTime - iTriggerCoarseTime ) // trigger -- OverflowLimit --> hit //=> if right order probably: hit ... Overflow ... trigger dCalibTime -= dClockCycle * iCoarseSize; else if( iCoarseOfLim < iTriggerCoarseTime - iCoarseTime ) // hit -- OverflowLimit --> trigger //=> if right order probably: trigger ... Overflow ... hit dCalibTime += dClockCycle * iCoarseSize; } // if( kTRUE == fMbsCalibPar->UseCoarse() // ToT calculation // TODO: multiple consecutive Rising edges // TODO: Time difference with coarse counter overflow check/safety for Tot LOG(DEBUG1)<<"TMbsCalibTdcTof: ch " << xUnpDataPtr->GetChannel() <<", HI " << iHistoIndex << " CF: "<< iCoarseTime <<","<GetFineTime()] <<", TotMode:"<< fMbsCalibPar->GetTotMode( uType ) << FairLogger::endl; Double_t dTot = 0.0; UInt_t uEdge = 0; switch( fMbsCalibPar->GetTotMode( uType ) ) { case 1: { Int_t iDataIndex = uBoard*uNbChan + xUnpDataPtr->GetChannel(); UInt_t uChan = xUnpDataPtr->GetChannel(); if( fMbsCalibPar->GetTotInvFlag( uType, uBoard, uChan ) == xUnpDataPtr->GetEdge() ) { if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) ((TTofCalibData*)(xTofTdcDataPrevArray[uType]->At( iDataIndex )))->Clear(); // rising edge new((*xTofTdcDataPrevArray[uType])[ iDataIndex ]) TTofCalibData( uType, uBoard, uChan, dCalibTime , dTot, uEdge ); } // if( 0 == xUnpDataPtr->GetEdge() ) else if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) { TTofCalibData* dataRisingEdge = (TTofCalibData*)(xTofTdcDataPrevArray[uType]->At( iDataIndex ) ); if( kTRUE == dataRisingEdge->IsFilled() ) { Double_t dDataTime = dataRisingEdge->GetTime(); // falling edge & rising edge present & filled dTot = dataRisingEdge->GetTimeDifference( dCalibTime ); // Time offset if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dDataTime -= fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, uChan ); // Tot offset // Tot offset signe inverted if rising and falling inverted if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dTot -= fMbsCalibPar->GetTotOffsetVal( uType, uBoard, uChan ) * ( 1 == fMbsCalibPar->GetTotInvFlag( uType, uBoard, uChan ) ? -1 : 1 ); // Use time from rising edge and newly calculated tot to create the hit new((*fCalibDataCollection)[ fCalibDataCollection->GetEntriesFast() ]) TTofCalibData( uType, uBoard, uChan, dDataTime, dTot, 2 ); } // if( kTRUE == (xTofTdcDataPrevArray[uType]->At( iDataIndex ) )->IsFilled() ) } // else if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) break; } // encapsulation needed because of iDataIndex presence/initialization in multiple cases case 2: { UInt_t uInputChan = ( xUnpDataPtr->GetChannel() - xUnpDataPtr->GetChannel()%2 ) / 2; // Save data for later time ordering Int_t iDataIndex = xTempCalibData[uType]->GetEntriesFast(); uEdge = ( xUnpDataPtr->GetChannel()%2 + 1 + fMbsCalibPar->GetTotInvFlag( uType, uBoard, uInputChan ) )%2; // Apply time offsets to ensure proper time sorting before TOT matching // Time offset applies to input channel, not TDC channel! if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dCalibTime -= fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, uInputChan ); // Tot offset applies to input channel, not TDC channel! // Tot offset sign inverted if rising and falling inverted if( kTRUE == fMbsCalibPar->EnaTimeOffset() && 1 == uEdge ) dCalibTime -= fMbsCalibPar->GetTotOffsetVal( uType, uBoard, uInputChan ) * ( 1 == fMbsCalibPar->GetTotInvFlag( uType, uBoard, uInputChan ) ? -1 : 1 ); new((*xTempCalibData[uType])[ iDataIndex ]) TTofCalibData( uType, uBoard, uInputChan, dCalibTime , 0.0, uEdge ); LOG(DEBUG1)<<"TMbsCalibTdcTof::Calibration: add " << iDataIndex << " for Type " << uType <<", B " << uBoard << ", Ch " << uInputChan << ", E " << uEdge <<", Offs " << fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, uInputChan ) <<", " << fMbsCalibPar->GetTotOffsetVal( uType, uBoard, uInputChan ) <<", Fl " << fMbsCalibPar->GetTotInvFlag( uType, uBoard, uInputChan ) << FairLogger::endl; break; } // encapsulation needed because of iDataIndex presence/initialization in multiple cases case 3: { // TODO: make it independent of board order! // (time ordering is done in unpacker only inside a board => fail with inverted board order) // TODO: board to board offset UInt_t uChan = xUnpDataPtr->GetChannel(); // Save data for later time ordering Int_t iDataIndex = xTempCalibData[uType]->GetEntriesFast(); uEdge = ( uBoard%2 + fMbsCalibPar->GetTotInvFlag( uType, uBoard, uChan ) )%2; new((*xTempCalibData[uType])[ iDataIndex ]) TTofCalibData( uType, uBoard%2, uChan, dCalibTime , 0.0, uEdge ); break; } // encapsulation needed because of iDataIndex presence/initialization in multiple cases case 4: dTot = xUnpDataPtr->GetTot() * dTotBinToPs; // Offset of input channel time if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dCalibTime -= fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, xUnpDataPtr->GetChannel() ); // Offset between rising and falling edge => Tot offset if( kTRUE == fMbsCalibPar->EnaTotOffset() ) dTot -= fMbsCalibPar->GetTotOffsetVal( uType, uBoard, xUnpDataPtr->GetChannel() ); new((*fCalibDataCollection)[ fCalibDataCollection->GetEntriesFast() ]) TTofCalibData( uType, uBoard, xUnpDataPtr->GetChannel(), dCalibTime , dTot, 2 ); break; case 0: default : { uEdge = xUnpDataPtr->GetEdge(); if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) { // Time offset applies to input channel, not TDC channel! UInt_t uInputChan; switch( uType ) { case toftdc::vftx: // 2 TDC channel per input channel uInputChan = ( xUnpDataPtr->GetChannel() - xUnpDataPtr->GetChannel()%2 ) / 2; break; case toftdc::caenV1290: case toftdc::trb3: case toftdc::get4: default: // 1 TDC channel per input channel uInputChan = xUnpDataPtr->GetChannel(); break; } // switch( uType ) dCalibTime -= fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, uInputChan ); } // if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) // Not Tot => no Tot offset!! // For now always save new((*fCalibDataCollection)[ fCalibDataCollection->GetEntriesFast() ]) TTofCalibData( uType, uBoard, xUnpDataPtr->GetChannel(), dCalibTime , dTot, uEdge ); break; } // encapsulation needed because of uInputChan presence/initialization in multiple cases } // switch( fMbsCalibPar->GetTotMode() ) } // for( Int_t iUnpDataInd = 0; iUnpDataInd < iNbUnpData; iUnpDataInd++ ) LOG(DEBUG1)<<" TMbsCalibTdcTof: Caldata " << fCalibDataCollection->GetEntriesFast() << FairLogger::endl; // TOT mode 1 and 4 are already done. // TOT mode 3 needs all boards to have been processed before time ordering of calibrated data and // Tot building. if( 2 == fMbsCalibPar->GetTotMode( uType ) ) { // In the case where 1 input channel correspond to 2 TDC channels, // we can time order the hits now that we have all of them calibrated // and then we will be able to associate them in full calibrated TDC data! BuildTotSplitChannels( uType, uBoard ); } // if( 2 == fMbsCalibPar->GetTotMode( uType ) ) // Recalibration if necessary/possible // Check if initial histos array was created Bool_t bBoardInitialThere = kFALSE; if( fhInitialCalibHisto[ uType ].size() == fMbsUnpackPar->GetNbActiveBoards( uType )*uNbChan ) bBoardInitialThere = kTRUE; // loop over channels for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Int_t iHistoIndex = uBoard*uNbChan + iChanInd; if( 0 < fMbsCalibPar->GetMinHitCalib() ) { Int_t iNbHitsThisCh = fhFineTime[uType][iHistoIndex]->GetEntries(); // Check if initial calibration histograms are available Bool_t bInitialThere = kFALSE; if( kTRUE == bBoardInitialThere ) if( NULL != fhInitialCalibHisto[ uType ][ iHistoIndex ] ) bInitialThere = kTRUE; // Check whether we should use the initial calibration on top of the new data Bool_t bUseInitial = bInitialThere; if( 0 < fMbsCalibPar->GetMinHitCalibNewOnly() && fMbsCalibPar->GetMinHitCalibNewOnly() <= iNbHitsThisCh ) bUseInitial = kFALSE; if( 0 < iNbHitsThisCh && 0 == iNbHitsThisCh % fMbsCalibPar->GetMinHitCalib() ) CalibFactorsCalc( uType, uBoard, iChanInd, bUseInitial); } // if( 0 < fMbsCalibPar->GetMinHitCalib() ) } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) else return kFALSE; return kTRUE; } Bool_t TMbsCalibTdcTof::CalibFactorsCalc( UInt_t uType, UInt_t uBoard, UInt_t uChan, Bool_t bWithInitial ) { UInt_t uNbChan = 0; Double_t dClockCycle = 0.0; UInt_t uFtBinNb = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; dClockCycle = caentdc::kdClockCycleSize; uFtBinNb = caentdc::kiFineTime + 1; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; dClockCycle = vftxtdc::kdClockCycleSize; uFtBinNb = vftxtdc::kiFifoFineTime + 1; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; dClockCycle = trb3tdc::kdClockCycleSize; uFtBinNb = trb3tdc::kiFineTime + 1; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; dClockCycle = get4tdc::kdClockCycleSize; uFtBinNb = get4tdc::kiFineTime + 1; break; default: break; } // switch( uType ) Int_t iHistoIndex = uBoard*uNbChan + uChan; // define correction variables // & set the sum to zero before summing over all bins in one channel Bool_t bincontrol[uFtBinNb]; Int_t iSum = 0; if( kTRUE == bWithInitial ) { // Use both initial calibration histograms and new data // To extract the correction factors if( NULL != fhInitialCalibHisto[ uType ][ iHistoIndex ]) { // Reset Histos with DNL ploting fhDnlChan[uType][iHistoIndex]->Reset(); fhDnlSum[uType][iHistoIndex]->Reset(); fhBinSizeChan[uType][iHistoIndex]->Reset(); Double_t dTotalEntriesInHisto = (Double_t)(fhFineTime[ uType ][ iHistoIndex ]->GetEntries() ) + (Double_t)(fhInitialCalibHisto[ uType ][ iHistoIndex ]->GetEntries() ); for(Int_t iBin = 0; iBin < (Int_t)uFtBinNb; iBin++) { Int_t iBinContent = (Int_t)(fhFineTime[ uType ][ iHistoIndex ]->GetBinContent(iBin+1)) + (Int_t)(fhInitialCalibHisto[ uType ][ iHistoIndex ]->GetBinContent(iBin+1)); //Looking for the used bins if( iBinContent <= 0) bincontrol[iBin] = kFALSE; else if( iBinContent > 0) bincontrol[iBin] = kTRUE; // build the sum of all bin content if(bincontrol[iBin]) { iSum = iSum + iBinContent; fdCorr[uType][iHistoIndex][iBin] = (Double_t)iSum / dTotalEntriesInHisto; fhDnlChan[uType][iHistoIndex]->Fill(iBin, (Double_t)iBinContent/dTotalEntriesInHisto ); fhBinSizeChan[uType][iHistoIndex]->Fill( dClockCycle*(Double_t)iBinContent/dTotalEntriesInHisto ); } // if(bincontrol[iBin]) else { if( 0 < iBin) fdCorr[uType][iHistoIndex][iBin] = fdCorr[uType][iHistoIndex][iBin-1]; else fdCorr[uType][iHistoIndex][iBin] = 0.0; } // else of if(bincontrol[iBin]) fhDnlSum[uType][iHistoIndex]->Fill(iBin, fdCorr[uType][iHistoIndex][iBin] ); } // for(Int_t iBin=0; iBin < (Int_t)uFtBinNb; iBin++) return kTRUE; } // if( NULL != fhInitialCalibHisto[ uType ][ iHistoIndex ]) } // if( kTRUE == bWithInitial ) // If either choice to use only new data or initial histo missing // => Use only new data to extract the correction factors // Reset Histos with DNL ploting fhDnlChan[uType][iHistoIndex]->Reset(); fhDnlSum[uType][iHistoIndex]->Reset(); Double_t dTotalEntriesInHisto = (Double_t)(fhFineTime[ uType ][ iHistoIndex ]->GetEntries() ); for(Int_t iBin = 0; iBin < (Int_t)uFtBinNb; iBin++) { Int_t iBinContent = (Int_t)(fhFineTime[ uType ][ iHistoIndex ]->GetBinContent(iBin+1)); //Looking for the used bins if( iBinContent <= 0) bincontrol[iBin] = kFALSE; else if( iBinContent > 0) bincontrol[iBin] = kTRUE; // build the sum of all bin content if(bincontrol[iBin]) { iSum = iSum + iBinContent; fdCorr[uType][iHistoIndex][iBin] = (Double_t)iSum / dTotalEntriesInHisto; fhDnlChan[uType][iHistoIndex]->Fill(iBin, (Double_t)iBinContent/dTotalEntriesInHisto ); } // if(bincontrol[iBin]) else { if( 0 < iBin) fdCorr[uType][iHistoIndex][iBin] = fdCorr[uType][iHistoIndex][iBin-1]; else fdCorr[uType][iHistoIndex][iBin] = 0.0; } // else of if(bincontrol[iBin]) fhDnlSum[uType][iHistoIndex]->Fill(iBin, fdCorr[uType][iHistoIndex][iBin] ); } // for(Int_t iBin=0; iBin < (Int_t)uFtBinNb; iBin++) return kTRUE; } Bool_t TMbsCalibTdcTof::WriteCalibrationFile() { TTimeStamp timeCurrent; oldDir = gDirectory; TString sCalibOutFilename = Form("./TofTdcCalibHistos_%u_%u.root", timeCurrent.GetDate( kFALSE), timeCurrent.GetTime( kFALSE) ); TFile* fileCalibrationOut = new TFile( sCalibOutFilename, "RECREATE", Form("Calibration Data for ToF TDCs, saved from analysis on %s", timeCurrent.AsString("lc") ), 9); if( kTRUE == fileCalibrationOut->IsOpen() ) { sCalibOutFilename += ":/"; gDirectory->Cd(sCalibOutFilename); for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; break; default: break; } // switch( uType ) if( 0 == uNbChan ) { LOG(INFO)<<"TMbsCalibTdcTof::WriteSingleCalibrations Undefined tdc parameters for type "; LOG(INFO)< No calib histo saving!"<GetNbActiveBoards( uType ); iTdc ++) { sInfoSaving = Form("tdc #%3d: ",iTdc ); for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { TString sCalibHistoOutputName = Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd ); Int_t iHistoIndex = iTdc*uNbChan + iChanInd; // New Calibration histo using only new data if( 0 < (fhFineTime[ uType ][ iHistoIndex ]->GetEntries() ) ) { fhFineTime[ uType ][ iHistoIndex ]->Write( sCalibHistoOutputName, TObject::kOverwrite); sInfoSaving += " 1 "; } // if( 0 < (fhFineTime[ uType ][ iHistoIndex ]->GetEntries() ) ) else sInfoSaving += " 0 "; } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) LOG(INFO)<GetNbCalibBoards( uType ); iTdc ++) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) //fileCalibrationOut->Write("",TObject::kOverwrite); fileCalibrationOut->Close(); LOG(INFO)<<"Calibration data saved in "<IsOpen() ) else LOG(WARNING)<<"TMbsCalibTdcTof::WriteCalibrationFile => Unable to open root file " <Cd(oldDir->GetPath()); return kTRUE; } Bool_t TMbsCalibTdcTof::WriteSingleCalibrations() { for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; break; default: break; } // switch( uType ) if( 0 == uNbChan ) { LOG(INFO)<<"TMbsCalibTdcTof::WriteSingleCalibrations Undefined tdc parameters for type "; LOG(INFO)< No calib histo saving!"<GetNbActiveBoards( uType )*uNbChan ) bBoardInitialThere = kTRUE; for( Int_t iTdc = 0; iTdc < fMbsUnpackPar->GetNbActiveBoards( uType ); iTdc ++) { sInfoSaving = Form("tdc #%3d: ",iTdc ); for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) { Bool_t bDataToSave = kFALSE; Bool_t bInitialThere = kFALSE; Int_t iHistoIndex = iTdc*uNbChan + iChanInd; if( kTRUE == bBoardInitialThere ) if( NULL != fhInitialCalibHisto[ uType ][ iHistoIndex ] ) bInitialThere = kTRUE; if( 0 < (fhFineTime[ uType ][ iHistoIndex ]->GetEntries() ) ) bDataToSave = kTRUE; if( 1 == fMbsCalibPar->GetSingleCalOutMode() || kFALSE == bInitialThere ) { if( kTRUE == bDataToSave ) { TString sCalibOutFilename = Form("./calib/%s_Tdc%03dChan%03d.root", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd); TFile* fileCalibrationOut = new TFile( sCalibOutFilename, "RECREATE", Form("Calibration Data for %s TDC %02d channel %02d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd ), 9); if( kTRUE == fileCalibrationOut->IsOpen() ) { sCalibOutFilename += ":/"; gDirectory->Cd(sCalibOutFilename); TString sCalibHistoOutputName = Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd ); fhFineTime[ uType ][ iHistoIndex ]->Write( sCalibHistoOutputName, TObject::kOverwrite); sInfoSaving += " 1 "; //fileCalibrationOut->Write("",TObject::kOverwrite); fileCalibrationOut->Close(); gDirectory->Cd(oldDir->GetPath()); } // if( kTRUE == fileCalibrationOut->IsOpen() ) else sInfoSaving += " 0 "; } // if( kTRUE == bDataToSave ) else sInfoSaving += " 0 "; } // if( 1 == fMbsCalibPar->GetSingleCalOutMode() || kFALSE == bInitialThere ) else if( kTRUE == bDataToSave ) { // Update old calibration histo with new data TString sCalibOutFilename = Form("./calib/%s_Tdc%03dChan%03d.root ", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd); TFile* fileCalibrationOut = new TFile( sCalibOutFilename, "RECREATE", Form("Calibration Data for %s TDC %02d channel %02d", toftdc::ksTdcHistName[ uType ].Data(), iTdc, iChanInd ), 9); if( kTRUE == fileCalibrationOut->IsOpen() ) { sCalibOutFilename += ":/"; gDirectory->Cd(sCalibOutFilename); TString sCalibHistoOutputName = Form("tof_%s_ft_b%03d_ch%03d", toftdc::ksTdcHistName[ uType ].Data(), fMbsCalibPar->GetInitialCalInd( uType, iTdc ), iChanInd ); // Try to update old calibration histo with new data fhInitialCalibHisto[ uType ][ iHistoIndex ]->Add( fhFineTime[ uType ][ iHistoIndex ] ); fhInitialCalibHisto[ uType ][ iHistoIndex ]->Write( sCalibHistoOutputName, TObject::kOverwrite); sInfoSaving += " 1 "; //fileCalibrationOut->Write("",TObject::kOverwrite); fileCalibrationOut->Close(); gDirectory->Cd(oldDir->GetPath()); } // if( kTRUE == fileCalibrationOut->IsOpen() ) else sInfoSaving += " 0 "; } // else of if( 1 == fMbsCalibPar->uSingleChannelCalibFilesOutput ) // No new Data => no need to update calibration!!! else sInfoSaving += " 0 "; } // for( Int_t iChanInd = 0; iChanInd< uNbChan; iChanInd++) LOG(INFO)<GetNbCalibBoards( uType ); iTdc ++) // Go back to original directory gDirectory->Cd(oldDir->GetPath()); } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) return kTRUE; } // ------------------------------------------------------------------ Bool_t TMbsCalibTdcTof::CreateTotVariables() { for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { UInt_t uNbChan = 0; UInt_t uMaxMult = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; uMaxMult = toftdc::kuDefNbMulti; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; uMaxMult = vftxtdc::kuNbMulti; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; uMaxMult = toftdc::kuDefNbMulti; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; uMaxMult = toftdc::kuDefNbMulti; break; default: break; } // switch( uType ) // TODO: test for flag for TOT inside a single data switch( fMbsCalibPar->GetTotMode( uType ) ) { case 1: xTofTdcDataPrevArray[uType] = new TClonesArray("TTofCalibData", uNbChan * fMbsUnpackPar->GetNbActiveBoards( uType )); // no need of a temporary vector to hold not associated edges and time order them // as the hits are either already ordered break; case 2: xTofTdcDataPrevArray[uType] = new TClonesArray("TTofCalibData", uNbChan/2 * fMbsUnpackPar->GetNbActiveBoards( uType )); // Use a temporary vector to hold not associated edges and time order them // 1 input channel -> 2 TDC channels => all boards used xTempCalibData[uType] = new TClonesArray("TTofCalibData", uMaxMult * uNbChan/2 * fMbsUnpackPar->GetNbActiveBoards( uType )); break; case 3: if( 1 == fMbsUnpackPar->GetNbActiveBoards( uType )%2 ) return kFALSE; xTofTdcDataPrevArray[uType] = new TClonesArray("TTofCalibData", uNbChan * fMbsUnpackPar->GetNbActiveBoards( uType )); // Use a temporary vector to hold not associated edges and time order them // 1 FEE channel -> 2 input channels in each board => 1/2 boards used xTempCalibData[uType] = new TClonesArray("TTofCalibData", uMaxMult * uNbChan * fMbsUnpackPar->GetNbActiveBoards( uType ) /2); break; case 0: case 4: // no need of a temporary vector to hold not associated edges and time order them // as the hits are either already associated default : xTofTdcDataPrevArray[uType] = NULL; break; } // switch( fMbsCalibPar->GetTotMode() ) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) else xTofTdcDataPrevArray[uType] = NULL; return kTRUE; } Bool_t TMbsCalibTdcTof::ClearTotVariables() { for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { // TODO: test for flag for TOT inside a single data switch( fMbsCalibPar->GetTotMode( uType ) ) { case 1: xTofTdcDataPrevArray[uType]->Clear("C"); // no need of a temporary vector to hold not associated edges and time order them // as the hits are either already ordered break; case 2: xTofTdcDataPrevArray[uType]->Clear("C"); // Use a temporary vector to hold not associated edges and time order them // 1 input channel -> 2 TDC channels => all boards used xTempCalibData[uType]->Clear("C"); break; case 3: if( 1 == fMbsUnpackPar->GetNbActiveBoards( uType )%2 ) return kFALSE; xTofTdcDataPrevArray[uType]->Clear("C"); // Use a temporary vector to hold not associated edges and time order them // 1 FEE channel -> 2 input channels in each board => 1/2 boards used xTempCalibData[uType]->Clear("C"); break; case 0: case 4: // no need of a temporary vector to hold not associated edges and time order them // as the hits are either already associated default : break; } // switch( fMbsCalibPar->GetTotMode() ) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) return kTRUE; } Bool_t TMbsCalibTdcTof::DeleteTotVariables() { for( UInt_t uType = toftdc::caenV1290; uType < toftdc::NbTdcTypes; uType++ ) if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) { // TODO: test for flag for TOT inside a single data switch( fMbsCalibPar->GetTotMode( uType ) ) { case 1: delete xTofTdcDataPrevArray[uType]; // no need of a temporary vector to hold not associated edges and time order them // as the hits are either already ordered break; case 2: delete xTofTdcDataPrevArray[uType]; // Use a temporary vector to hold not associated edges and time order them // 1 input channel -> 2 TDC channels => all boards used delete xTempCalibData[uType]; break; case 3: if( 1 == fMbsUnpackPar->GetNbActiveBoards( uType )%2 ) return kFALSE; delete xTofTdcDataPrevArray[uType]; // Use a temporary vector to hold not associated edges and time order them // 1 FEE channel -> 2 input channels in each board => 1/2 boards used delete xTempCalibData[uType]; break; case 0: case 4: // no need of a temporary vector to hold not associated edges and time order them // as the hits are either already associated default : break; } // switch( fMbsCalibPar->GetTotMode() ) } // if( 0 < fMbsUnpackPar->GetNbActiveBoards( uType ) ) return kTRUE; } Bool_t TMbsCalibTdcTof::BuildTotSplitChannels( UInt_t uType, UInt_t uBoard ) { UInt_t uNbChan = 0; switch( uType ) { case toftdc::caenV1290: uNbChan = caentdc::kuNbChan; break; case toftdc::vftx: uNbChan = vftxtdc::kuNbChan; break; case toftdc::trb3: uNbChan = trb3tdc::kuNbChan; break; case toftdc::get4: uNbChan = get4tdc::kuNbChan; break; default: break; } // switch( uType ) // In the case where 1 input channel correspond to 2 TDC channels, // we can time order the hits now that we have all of them calibrated // and then we will be able to associate them in full calibrated TDC data! xTempCalibData[uType]->Sort(); // now build TOT Int_t iNbCalData = xTempCalibData[uType]->GetEntriesFast(); LOG(DEBUG)<<"TMbsCalibTdcTof::BuildTotSplitChannels Type "<At(iCalDataInd); UInt_t uInputChan = xCalibData->GetChannel(); Int_t iDataIndex = uBoard*uNbChan/2 + uInputChan; UInt_t uEdge = xCalibData->GetEdge(); Double_t dCalibTime = xCalibData->GetTime(); LOG(DEBUG1)<<"TMbsCalibTdcTof::BuildTotSplitChannels Type "<At( iDataIndex ) ) ((TTofCalibData*)(xTofTdcDataPrevArray[uType]->At( iDataIndex )))->Clear(); // rising edge channel LOG(DEBUG1)<<"TMbsCalibTdcTof::BuildTotSplitChannels store rising edge " << iDataIndex <GetChannel()%2 ) else if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) { TTofCalibData* dataRisingEdge = (TTofCalibData*)(xTofTdcDataPrevArray[uType]->At( iDataIndex ) ); LOG(DEBUG1)<<"TMbsCalibTdcTof::BuildTotSplitChannels rising edge: " <IsFilled()<<","<GetTime()<IsFilled() ) { Double_t dDataTime = dataRisingEdge->GetTime(); // falling edge & rising edge present & filled Double_t dTot = dataRisingEdge->GetTimeDifference( dCalibTime ); /* * Commented as time offset should be applied BEFORE time sorting (negative TOT -> positive TOT) // Time offset applies to input channel, not TDC channel! if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dDataTime -= fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, uInputChan ); // Tot offset applies to input channel, not TDC channel! // Tot offset signe inverted if rising and falling inverted if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dTot -= fMbsCalibPar->GetTotOffsetVal( uType, uBoard, uInputChan ) * ( 1 == fMbsCalibPar->GetTotInvFlag( uType, uBoard, uInputChan ) ? -1 : 1 ); */ // Use time from rising edge and newly calculated tot to create the hit new((*fCalibDataCollection)[ fCalibDataCollection->GetEntriesFast() ]) TTofCalibData( uType, uBoard, uInputChan, dDataTime, dTot, 2 ); } // if( kTRUE == (xTofTdcDataPrevArray[uType]->At( iDataIndex ) )->IsFilled() ) } // else if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) } // for( Int_t iUnpDataInd = 0; iUnpDataInd < iNbUnpData; iUnpDataInd++ ) LOG(DEBUG1)<<"TMbsCalibTdcTof::BuildTotSplitChannels Type "<GetEntriesFast()<Sort(); // now build TOT Int_t iNbCalData = xTempCalibData[uType]->GetEntriesFast(); for( Int_t iCalDataInd = 0; iCalDataInd < iNbCalData; iCalDataInd++ ) { TTofCalibData * xCalibData = (TTofCalibData*) xTempCalibData[uType]->At(iCalDataInd); UInt_t uBoard = xCalibData->GetBoard(); UInt_t uInputChan = xCalibData->GetChannel(); Int_t iDataIndex = uBoard*uNbChan + uInputChan; UInt_t uEdge = xCalibData->GetEdge(); Double_t dCalibTime = xCalibData->GetTime(); if( 0 == uEdge ) { if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) ((TTofCalibData*)(xTofTdcDataPrevArray[uType]->At( iDataIndex )))->Clear(); // rising edge channel new((*xTofTdcDataPrevArray[uType])[ iDataIndex ]) TTofCalibData( *xCalibData ); } // if( 1 == xUnpDataPtr->GetChannel()%2 ) else if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) { TTofCalibData* dataRisingEdge = (TTofCalibData*)(xTofTdcDataPrevArray[uType]->At( iDataIndex ) ); if( kTRUE == dataRisingEdge->IsFilled() ) { Double_t dDataTime = dataRisingEdge->GetTime(); // falling edge & rising edge present & filled Double_t dTot = dataRisingEdge->GetTimeDifference( dCalibTime ); // Time offset applies to input channel, not TDC channel! if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dDataTime -= fMbsCalibPar->GetTimeOffsetVal( uType, uBoard, uInputChan ); // Tot offset applies to input channel, not TDC channel! // Tot offset signe inverted if rising and falling inverted if( kTRUE == fMbsCalibPar->EnaTimeOffset() ) dTot -= fMbsCalibPar->GetTotOffsetVal( uType, uBoard, uInputChan ) * ( 1 == fMbsCalibPar->GetTotInvFlag( uType, uBoard, uInputChan ) ? -1 : 1 ); // Use time from rising edge and newly calculated tot to create the hit new((*fCalibDataCollection)[ fCalibDataCollection->GetEntriesFast() ]) TTofCalibData( uType, uBoard, uInputChan, dDataTime, dTot, 2 ); } // if( kTRUE == (xTofTdcDataPrevArray[uType]->At( iDataIndex ) )->IsFilled() ) } // else if( 0 < xTofTdcDataPrevArray[uType]->At( iDataIndex ) ) } // for( Int_t iUnpDataInd = 0; iUnpDataInd < iNbUnpData; iUnpDataInd++ ) return kTRUE; }