// ------------------------------------------------------------------ // ----- TMbsCalibScalTof ----- // ----- Created 08/07/2013 by P.-A. Loizeau ----- // ------------------------------------------------------------------ #include "TMbsCalibScalTof.h" // General Unpack headers #include "TMbsUnpackTofPar.h" // ToF specific headers #include "TMbsCalibTofPar.h" #include "TofVmeDef.h" #include "TofScalerDef.h" #include "TofScomDef.h" #include "TofTriglogDef.h" #include "TTofScalerBoard.h" #include "TTofTriglogBoard.h" #include "TTofCalibScaler.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 "TProfile.h" #include "TROOT.h" #include "TTimeStamp.h" TMbsCalibScalTof::TMbsCalibScalTof() : fMbsUnpackPar(NULL), fMbsCalibPar(NULL), fScalerBoardCollection(NULL), fTriglogBoardCollection(NULL), fCalibScalCollection(NULL) { // Get Base Container FairRunAna* ana = FairRunAna::Instance(); FairRuntimeDb* rtdb=ana->GetRuntimeDb(); // Unpack parameter fMbsUnpackPar = (TMbsUnpackTofPar*) (rtdb->getContainer("TMbsUnpackTofPar")); if( 0 == fMbsUnpackPar ) LOG(ERROR)<<"TMbsCalibScalTof::TMbsCalibScalTof => Could not obtain the TMbsUnpackTofPar "<getContainer("TMbsCalibTofPar")); if( 0 == fMbsCalibPar ) LOG(ERROR)<<"TMbsCalibScalTof::TMbsCalibScalTof => Could not obtain the TMbsCalibTofPar "<printParams(); } TMbsCalibScalTof::TMbsCalibScalTof(TMbsUnpackTofPar * parIn, TMbsCalibTofPar *parCalIn) : fMbsUnpackPar(parIn), fMbsCalibPar(parCalIn), fScalerBoardCollection(NULL), fTriglogBoardCollection(NULL), fCalibScalCollection(NULL) { } TMbsCalibScalTof::~TMbsCalibScalTof() { DeleteHistograms(); LOG(INFO)<<"**** TMbsCalibScalTof: Delete instance "<GetNbActiveScalersB(); // Loop over all scaler boards for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) Calibration( uScalBdIndx ); // Update the MBS time info used by all boards from the single TRIGLOG unpack event if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { if( NULL == fTriglogBoardCollection ) return kFALSE; TTofTriglogBoard * xTriglogBoard = (TTofTriglogBoard*) fTriglogBoardCollection->At(0); // Always only 1 TRIGLOG board! if( NULL == xTriglogBoard ) return kFALSE; Double_t dMbsTime = xTriglogBoard->GetMbsTimeSec() + xTriglogBoard->GetMbsTimeMilliSec()*1e-3; if( ( 0 == fdPrevMbsTime ) || ( fdPrevMbsTime + 0.05 < dMbsTime ) ) fdPrevMbsTime = dMbsTime; if( kTRUE == bFirstEvent ) fdFirstMbsTime = dMbsTime; } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) if( kTRUE == bFirstEvent ) bFirstEvent = kFALSE; return kTRUE; } Bool_t TMbsCalibScalTof::CloseScalersCalib() { if( kFALSE == CloseCalibration() ) return kFALSE; // if( kFALSE == DeleteHistograms() ) // return kFALSE; return kTRUE; } Bool_t TMbsCalibScalTof::InitParameters() { } // ------------------------------------------------------------------ Bool_t TMbsCalibScalTof::RegisterInput() { FairRootManager* rootMgr = FairRootManager::Instance(); // There should always be only 1 Trigger board active, if not => problem if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { fTriglogBoardCollection = (TClonesArray*) rootMgr->GetObject("TofTriglog"); if( NULL == fTriglogBoardCollection) { LOG(ERROR)<<"TMbsCalibScalTof::RegisterInput => Could not get the TofTriglog TClonesArray!!!"<GetNbActiveBoards( tofVme::triglog ) ) // Each scaler board has its scaler unpack object, same type for TRIGLOG, ScalOrMu, etc... if( 0 < fMbsUnpackPar->GetNbActiveScalersB() ) { fScalerBoardCollection = (TClonesArray*) rootMgr->GetObject("TofRawScalers"); if( NULL == fScalerBoardCollection) { LOG(ERROR)<<"TMbsCalibScalTof::RegisterInput => Could not get the TofRawScalers TClonesArray!!!"<GetNbActiveScalersB() ) return kTRUE; } Bool_t TMbsCalibScalTof::RegisterOutput() { FairRootManager* rootMgr = FairRootManager::Instance(); fCalibScalCollection = new TClonesArray("TTofCalibScaler"); // rootMgr->Register("TofCalibScaler","Tof",fCalibScalCollection, kTRUE); rootMgr->Register( "TofCalibScaler","Tof",fCalibScalCollection, fMbsUnpackPar->WriteDataInCbmOut()); return kTRUE; } Bool_t TMbsCalibScalTof::ClearOutput() { fCalibScalCollection->Clear("C"); return kTRUE; } // ------------------------------------------------------------------ Bool_t TMbsCalibScalTof::CreateHistogramms() { UInt_t uNbScalBd = fMbsUnpackPar->GetNbActiveScalersB(); // Resize vectors with a "board" dimension if( 0 < uNbScalBd ) { fhScalersRate.resize( uNbScalBd ); fhScalersRateEvo.resize( uNbScalBd ); if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { fhRefClkRateEvo.resize( uNbScalBd ); fhRefMbsTimeComp.resize( uNbScalBd ); fhRefClkRate.resize( uNbScalBd ); } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) } // if( 0 < fMbsUnpackPar->GetNbActiveScalersB() ) // Loop over all scalers for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) { TTofScalerBoard * xScalerBoard = (TTofScalerBoard*) fScalerBoardCollection->At(uScalBdIndx); UInt_t uType = xScalerBoard->GetScalerType(); Double_t dRefClkFreq; UInt_t uNbScalers; UInt_t uNbChan; switch( uType ) { case tofscaler::triglog : dRefClkFreq = triglog::kdRefClkFreq; uNbScalers = triglog::kuNbScalers; uNbChan = triglog::kuNbChan; break; case tofscaler::scalormu : dRefClkFreq = scalormu::kdRefClkFreq; uNbScalers = scalormu::kuNbScalers; uNbChan = scalormu::kuNbChan; break; case tofscaler::scalormubig : dRefClkFreq = scalormuBig::kdRefClkFreq; uNbScalers = scalormuBig::kuNbScalers; uNbChan = scalormuBig::kuNbChan; break; case tofscaler::undef : default: dRefClkFreq = -1.0; uNbScalers = 0; uNbChan = 0; // Here we go to next board for all undefined/invalid types continue; break; } // switch( xScalerBoard->GetScalerType() ) // Resize vectors with a "Scalers" dimension fhScalersRate[uScalBdIndx].resize( uNbScalers ); fhScalersRateEvo[uScalBdIndx].resize( uNbScalers ); for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) { // resize vectors with a "channel" dimension fhScalersRate[uScalBdIndx][uScaler].resize(uNbChan); fhScalersRateEvo[uScalBdIndx][uScaler].resize(uNbChan); for( UInt_t uCh = 0; uCh < uNbChan; uCh++) { fhScalersRate[uScalBdIndx][uScaler][uCh] = new TH1I( Form("tof_cal_%s_scal_%02d_%02d", tofscaler::ksTdcHistName[ uType ].Data(), uScaler, uCh ), Form("Rate of the channel %02d in scaler %02d; Freq. [Hz]", uCh, uScaler), (Int_t)(dRefClkFreq/2000), 0.0 , dRefClkFreq/2 ); // fhScalersRateEvo[uScalBdIndx][uScaler][uCh] = // new TH1I( Form("tof_cal_%s_scal_evo_%02d_%02d", tofscaler::ksTdcHistName[ uType ].Data(), uScaler, uCh ), // Form("Channel %02d in scaler %02d counts per second; Time [s]; Counts []", uCh, uScaler), // 3600, 0.0, 3600 ); fhScalersRateEvo[uScalBdIndx][uScaler][uCh] = new TProfile( Form("tof_cal_%s_scal_evo_%02d_%02d", tofscaler::ksTdcHistName[ uType ].Data(), uScaler, uCh ), Form("Channel %02d in scaler %02d Mean rate per second; Time [s]; Rate [1/s]", uCh, uScaler), 36000, 0.0, 3600 ); } // for( UInt_t uCh = 0; uCh < triglog::kuNbChan; uCh++) } // for( UInt_t uScaler = 0; uScaler problem if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { fhRefClkRate[uScalBdIndx] = new TH1I( Form("tof_cal_%s_refclk", tofscaler::ksTdcHistName[ uType ].Data() ), "Rate of the reference clock; Freq. [Hz]", (Int_t)(2*dRefClkFreq/1000), 0.0 , 2*dRefClkFreq ); fhRefClkRateEvo[uScalBdIndx] = new TH1I( Form("tof_cal_%s_refclk_evo", tofscaler::ksTdcHistName[ uType ].Data() ), "Reference clock counts per second; Time [s]; Counts []", 3600, 0.0, 3600 ); // fhRefClkRateEvo[uScalBdIndx] = new TProfile( Form("tof_cal_%s_refclk_evo", tofscaler::ksTdcHistName[ uType ].Data() ), // "Reference clock counts per second; Time [s]; Counts []", 36000, 0.0, 3600 ); fhRefMbsTimeComp[uScalBdIndx] = new TH2I( Form("tof_cal_%s_refmbs_comp", tofscaler::ksTdcHistName[ uType ].Data() ), "Comparison of clk VS Mbs time since first event; Mbs Time [s]; Mbs Time - Ref Clk Time [s]", 3600, 0.0, 3600, 200, -0.1, 0.1 ); } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) } // for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) return kTRUE; } Bool_t TMbsCalibScalTof::FillHistograms() { UInt_t uNbScalBd = fMbsUnpackPar->GetNbActiveScalersB(); TTofTriglogBoard * xTriglogBoard; Double_t dMbsTime = 0; if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { if( NULL == fTriglogBoardCollection ) return kFALSE; xTriglogBoard = (TTofTriglogBoard*) fTriglogBoardCollection->At(0); // Always only 1 TRIGLOG board! if( NULL == xTriglogBoard ) return kFALSE; dMbsTime = xTriglogBoard->GetMbsTimeSec() + xTriglogBoard->GetMbsTimeMilliSec()*1e-3; } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) // Loop over all scalers for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) { TTofCalibScaler * xCalibScaler = (TTofCalibScaler*) fCalibScalCollection->ConstructedAt(uScalBdIndx); UInt_t uType = xCalibScaler->GetScalerType(); Double_t dRefClkFreq; UInt_t uNbScalers; UInt_t uNbChan; switch( uType ) { case tofscaler::triglog : dRefClkFreq = triglog::kdRefClkFreq; uNbScalers = triglog::kuNbScalers; uNbChan = triglog::kuNbChan; break; case tofscaler::scalormu : dRefClkFreq = scalormu::kdRefClkFreq; uNbScalers = scalormu::kuNbScalers; uNbChan = scalormu::kuNbChan; break; case tofscaler::scalormubig : dRefClkFreq = scalormuBig::kdRefClkFreq; uNbScalers = scalormuBig::kuNbScalers; uNbChan = scalormuBig::kuNbChan; break; case tofscaler::undef : default: dRefClkFreq = -1.0; uNbScalers = 0; uNbChan = 0; // Here we go to next board for all undefined/invalid types continue; break; } // switch( xScalerBoard->GetScalerType() ) // Comparison between the time sinmce first event stored by MBS in the TRIGLOG event and the one // obtained using the reference clock counts and frequency if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) && kFALSE == bFirstEvent ) { Double_t dMbsTimeSinceFirst = dMbsTime - fdFirstMbsTime; fhRefMbsTimeComp[uScalBdIndx]->Fill( dMbsTimeSinceFirst, dMbsTimeSinceFirst - xCalibScaler->GetTimeToFirst() ); } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) && kFALSE == bFirstEvent ) // Instantaneous rate of individual channels for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) { for( UInt_t uCh = 0; uCh < uNbChan; uCh++) { if( 0 < xCalibScaler->GetTimeToLast() ) { fhScalersRate[uScalBdIndx][uScaler][uCh]->Fill( xCalibScaler->GetScalerValue( uCh, uScaler) ); fhScalersRateEvo[uScalBdIndx][uScaler][uCh]->Fill( xCalibScaler->GetTimeToFirst(), xCalibScaler->GetScalerValue( uCh, uScaler) ); } // if( 0 < xCalibScaler->GetTimeToLast() ) } // for( UInt_t uCh = 0; uCh < uNbChan; uCh++) } // for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) } // for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) return kTRUE; } Bool_t TMbsCalibScalTof::WriteHistogramms( TDirectory* inDir) { TDirectory * oldir = gDirectory; UInt_t uNbScalBd = fMbsUnpackPar->GetNbActiveScalersB(); // Loop over all scalers for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) { TTofCalibScaler * xCalibScaler = (TTofCalibScaler*) fCalibScalCollection->ConstructedAt(uScalBdIndx); UInt_t uType = xCalibScaler->GetScalerType(); UInt_t uNbScalers; UInt_t uNbChan; switch( uType ) { case tofscaler::triglog : uNbScalers = triglog::kuNbScalers; uNbChan = triglog::kuNbChan; break; case tofscaler::scalormu : uNbScalers = scalormu::kuNbScalers; uNbChan = scalormu::kuNbChan; break; case tofscaler::scalormubig : uNbScalers = scalormuBig::kuNbScalers; uNbChan = scalormuBig::kuNbChan; break; case tofscaler::undef : default: // Here we go to next board for all undefined/invalid types continue; break; } // switch( xScalerBoard->GetScalerType() ) // create a subdirectory "Cal_type" in this file TDirectory *cdCal = inDir->mkdir( Form( "Cal_%s", tofscaler::ksTdcHistName[ uType ].Data() ) ); cdCal->cd(); // make the "Cal_type" directory the current directory TDirectory *cdCalScal[ uNbScalers ]; if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { fhRefClkRate[uScalBdIndx]->Write(); fhRefClkRateEvo[uScalBdIndx]->Write(); fhRefMbsTimeComp[uScalBdIndx]->Write(); } for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) { // Create a sub folder for each scaler cdCalScal[uScaler] = cdCal->mkdir( Form( "cScal%03d", uScaler) ); cdCalScal[uScaler]->cd(); for( UInt_t uCh = 0; uCh < uNbChan; uCh++) { fhScalersRate[uScalBdIndx][uScaler][uCh]->Write(); fhScalersRateEvo[uScalBdIndx][uScaler][uCh]->Write(); } } // for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) } // for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) gDirectory->cd( oldir->GetPath() ); return kTRUE; } Bool_t TMbsCalibScalTof::DeleteHistograms() { UInt_t uNbScalBd = fMbsUnpackPar->GetNbActiveScalersB(); // Loop over all scalers for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) { TTofScalerBoard * xScalerBoard = (TTofScalerBoard*) fScalerBoardCollection->At(uScalBdIndx); UInt_t uType = xScalerBoard->GetScalerType(); UInt_t uNbScalers; switch( uType ) { case tofscaler::triglog : uNbScalers = triglog::kuNbScalers; break; case tofscaler::scalormu : uNbScalers = scalormu::kuNbScalers; break; case tofscaler::scalormubig : uNbScalers = scalormuBig::kuNbScalers; break; case tofscaler::undef : default: // Here we go to next board for all undefined/invalid types continue; break; } // switch( xScalerBoard->GetScalerType() ) for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) { fhScalersRate[uScalBdIndx][uScaler].clear(); fhScalersRateEvo[uScalBdIndx][uScaler].clear(); } // for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) fhScalersRate[uScalBdIndx].clear(); fhScalersRateEvo[uScalBdIndx].clear(); } // for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) if( 0 < uNbScalBd ) { fhScalersRate.clear(); fhScalersRateEvo.clear(); if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { fhRefClkRateEvo.clear(); fhRefMbsTimeComp.clear(); fhRefClkRate.clear(); } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) } // if( 0 < fMbsUnpackPar->GetNbActiveScalersB() ) return kTRUE; } // ------------------------------------------------------------------ Bool_t TMbsCalibScalTof::InitCalibration() { UInt_t uNbScalBd = fMbsUnpackPar->GetNbActiveScalersB(); if( 0 < uNbScalBd ) { fvuLastScalers.resize( uNbScalBd ); fvuFirstRefClk.resize( uNbScalBd ); fvuLastRefClk.resize( uNbScalBd ); fvuLastRefClkCal.resize( uNbScalBd ); fvdMeanRefClkFreq.resize( uNbScalBd ); } // Loop over all scalers for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) { TTofScalerBoard * xScalerBoard = (TTofScalerBoard*) fScalerBoardCollection->At(uScalBdIndx); TTofCalibScaler * xCalibScaler = (TTofCalibScaler*) fCalibScalCollection->ConstructedAt(uScalBdIndx); UInt_t uType = xScalerBoard->GetScalerType(); if( tofscaler::undef == xCalibScaler->GetScalerType() ) xCalibScaler->SetType( uType ); Double_t dRefClkFreq; UInt_t uNbScalers; UInt_t uNbChan; switch( uType ) { case tofscaler::triglog : dRefClkFreq = triglog::kdRefClkFreq; uNbScalers = triglog::kuNbScalers; uNbChan = triglog::kuNbChan; break; case tofscaler::scalormu : dRefClkFreq = scalormu::kdRefClkFreq; uNbScalers = scalormu::kuNbScalers; uNbChan = scalormu::kuNbChan; break; case tofscaler::scalormubig : dRefClkFreq = scalormuBig::kdRefClkFreq; uNbScalers = scalormuBig::kuNbScalers; uNbChan = scalormuBig::kuNbChan; break; case tofscaler::undef : default: dRefClkFreq = -1.0; uNbScalers = 0; uNbChan = 0; // Here we go to next board for all undefined/invalid types continue; break; } // switch( xScalerBoard->GetScalerType() ) fvuLastScalers[uScalBdIndx].resize(uNbScalers); for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) { fvuLastScalers[uScalBdIndx][uScaler].resize(uNbChan); for( UInt_t uCh = 0; uCh < uNbChan; uCh++) { fvuLastScalers[uScalBdIndx][uScaler][uCh] = 0; } // for( UInt_t uCh = 0; uCh < uNbChan; uCh++) } // for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) fvuFirstRefClk[uScalBdIndx] = 0; fvuLastRefClk[uScalBdIndx] = 0; fvuLastRefClkCal[uScalBdIndx] = 0; fvdMeanRefClkFreq[uScalBdIndx] = -1.0; } // for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) fdFirstMbsTime = 0; fdPrevMbsTime = 0; bFirstEvent = kTRUE; return kTRUE; } Bool_t TMbsCalibScalTof::Calibration( UInt_t uBoard) { if( fMbsUnpackPar->GetNbActiveScalersB() <= uBoard) return kFALSE; if( NULL == fScalerBoardCollection || NULL == fCalibScalCollection ) return kFALSE; TTofScalerBoard * xScalerBoard = (TTofScalerBoard*) fScalerBoardCollection->At(uBoard); TTofCalibScaler * xCalibScaler = (TTofCalibScaler*) fCalibScalCollection->ConstructedAt(uBoard); if( NULL == xScalerBoard || NULL == xCalibScaler ) return kFALSE; UInt_t uType = xScalerBoard->GetScalerType(); if( tofscaler::undef == xCalibScaler->GetScalerType() ) xCalibScaler->SetType( uType ); Double_t dRefClkFreq; UInt_t uNbScalers; UInt_t uNbChan; switch( uType ) { case tofscaler::triglog : dRefClkFreq = triglog::kdRefClkFreq; uNbScalers = triglog::kuNbScalers; uNbChan = triglog::kuNbChan; break; case tofscaler::scalormu : dRefClkFreq = scalormu::kdRefClkFreq; uNbScalers = scalormu::kuNbScalers; uNbChan = scalormu::kuNbChan; break; case tofscaler::scalormubig : dRefClkFreq = scalormuBig::kdRefClkFreq; uNbScalers = scalormuBig::kuNbScalers; uNbChan = scalormuBig::kuNbChan; break; case tofscaler::undef : default: dRefClkFreq = -1.0; uNbScalers = 0; uNbChan = 0; // Here we go to next board for all undefined/invalid types return kFALSE; break; } // switch( xScalerBoard->GetScalerType() ) // There should always be only 1 Trigger board active, if not => problem if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) { TTofTriglogBoard * xTriglogBoard = (TTofTriglogBoard*) fTriglogBoardCollection->At(0); // Always only 1 TRIGLOG board! Double_t dMbsTime = xTriglogBoard->GetMbsTimeSec() + xTriglogBoard->GetMbsTimeMilliSec()*1e-3; if( 0 < fdPrevMbsTime ) // MBS time is time in s since LINUX epoch (circa 1970) => never 0 except on first event! { // Update only when at least 50ms passed since last update due to ms precision of the MBS time if( fdPrevMbsTime + 0.05 < dMbsTime && kFALSE == bFirstEvent) { Double_t dTimeDiff = dMbsTime - fdPrevMbsTime; // Update only if less than 500ms passed since last update to avoid problems with spill breaks if( dTimeDiff < 0.5 ) { // Monitoring the rate of the reference clock fhRefClkRate[uBoard]->Fill( (Double_t)(xScalerBoard->GetRefClk() - fvuLastRefClkCal[uBoard] ) / dTimeDiff ); fhRefClkRateEvo[uBoard]->Fill(dMbsTime - fdFirstMbsTime, xScalerBoard->GetRefClk() - fvuLastRefClkCal[uBoard] ); // Try to update the clock frequency only if there are enough points in the monitoring histo, // the distribution spread is reasonnable and the option is ON if( 2000 < fhRefClkRate[uBoard]->GetEntries() && 10000 < fhRefClkRate[uBoard]->GetRMS() && kTRUE == fMbsCalibPar->CalibRefClocks() ) fvdMeanRefClkFreq[uBoard] = fhRefClkRate[uBoard]->GetMean(); } // if( 0 < fdPrevMbsTime ) // Save value of the reference clock in last rate update fvuLastRefClkCal[uBoard] = xScalerBoard->GetRefClk(); } // if( ( 0 == fdPrevMbsTime ) || ( fdPrevMbsTime + 0.05 < dMbsTime ) ) if( 0 < fvdMeanRefClkFreq[uBoard] ) dRefClkFreq = fvdMeanRefClkFreq[uBoard]; } // if( 0 < fdPrevMbsTime ) } // if( 1 == fMbsUnpackPar->GetNbActiveBoards( tofVme::triglog ) ) if( kFALSE == bFirstEvent ) { // If not first event, calculate the time since first and last event using the reference clock of the board Double_t dRefTime = (Double_t)( xScalerBoard->GetRefClk() - fvuFirstRefClk[uBoard] )/dRefClkFreq; Double_t dRefTimeToLast = (Double_t)( xScalerBoard->GetRefClk() - fvuLastRefClk[uBoard] )/dRefClkFreq; xCalibScaler->SetRefClk( (Double_t)( xScalerBoard->GetRefClk() )/dRefClkFreq ); xCalibScaler->SetTimeToFirst( dRefTime ); xCalibScaler->SetTimeToLast( dRefTimeToLast ); for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) { for( UInt_t uCh = 0; uCh < uNbChan; uCh++) { // for each board/scaler/channel, calculate the instantaneous rate between last event and this one // using the scaler count difference and the time since last event obtained with the reference clock UInt_t uCurrVal = xScalerBoard->GetScalerValue( uCh, uScaler); Double_t dRate = (Double_t)( uCurrVal - fvuLastScalers[uBoard][uScaler][uCh] ) / dRefTimeToLast; xCalibScaler->SetScalerValue( uCh, dRate, uScaler); // fhScalersRateEvo[uBoard][uScaler][uCh]->Fill( dRefTime, uCurrVal - fvuLastScalers[uBoard][uScaler][uCh] ); fvuLastScalers[uBoard][uScaler][uCh] = uCurrVal; } // for( UInt_t uCh = 0; uCh < uNbChan; uCh++) } // for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) } // if( kFALSE == bFirstEvent ) fvuLastRefClk[uBoard] = xScalerBoard->GetRefClk(); if( kTRUE == bFirstEvent ) { fvuFirstRefClk[uBoard] = fvuLastRefClk[uBoard]; fvuLastRefClkCal[uBoard] = fvuLastRefClk[uBoard]; for( UInt_t uScaler = 0; uScaler < uNbScalers; uScaler++) for( UInt_t uCh = 0; uCh < uNbChan; uCh++) fvuLastScalers[uBoard][uScaler][uCh] = xScalerBoard->GetScalerValue( uCh, uScaler); } // if( kTRUE == bFirstEvent ) return kTRUE; } Bool_t TMbsCalibScalTof::CloseCalibration() { // Loop over all scalers for( UInt_t uScalBdIndx = 0; uScalBdIndx < fvuLastScalers.size(); uScalBdIndx++ ) { for( UInt_t uScaler = 0; uScaler < fvuLastScalers[uScalBdIndx].size(); uScaler++) fvuLastScalers[uScalBdIndx][uScaler].clear(); fvuLastScalers[uScalBdIndx].clear(); } // for( UInt_t uScalBdIndx = 0; uScalBdIndx < uNbScalBd; uScalBdIndx++ ) if( 0 < fvuLastScalers.size() ) { fvuLastScalers.clear(); fvuFirstRefClk.clear(); fvuLastRefClk.clear(); fvdMeanRefClkFreq.clear(); } return kTRUE; } // ------------------------------------------------------------------