56 #include "StChain/StChainOpt.h"
60 #include "StETofCollection.h"
61 #include "StETofHeader.h"
62 #include "StETofDigi.h"
64 #include "StMuDSTMaker/COMMON/StMuDst.h"
65 #include "StMuDSTMaker/COMMON/StMuETofDigi.h"
66 #include "StMuDSTMaker/COMMON/StMuETofHeader.h"
68 #include "StETofCalibMaker.h"
69 #include "StETofUtil/StETofHardwareMap.h"
70 #include "StETofUtil/StETofConstants.h"
72 #include "tables/St_etofCalibParam_Table.h"
73 #include "tables/St_etofElectronicsMap_Table.h"
74 #include "tables/St_etofStatusMap_Table.h"
75 #include "tables/St_etofTimingWindow_Table.h"
76 #include "tables/St_etofSignalVelocity_Table.h"
77 #include "tables/St_etofDigiTotCorr_Table.h"
78 #include "tables/St_etofDigiTimeCorr_Table.h"
79 #include "tables/St_etofDigiSlewCorr_Table.h"
80 #include "tables/St_etofResetTimeCorr_Table.h"
81 #include "tables/St_etofPulserTotPeak_Table.h"
82 #include "tables/St_etofPulserTimeDiffGbtx_Table.h"
83 #include "tables/St_etofGet4State_Table.h"
85 namespace etofSlewing {
86 const unsigned int nTotBins = 30;
89 const float conversionFactor = 1. / 100.;
99 mFileNameCalibParam(
"" ),
100 mFileNameElectronicsMap(
"" ),
101 mFileNameStatusMap(
"" ),
102 mFileNameTimingWindow(
"" ),
103 mFileNameSignalVelocity(
"" ),
104 mFileNameCalibHistograms(
"" ),
105 mFileNameResetTimeCorr(
"" ),
106 mFileNamePulserTotPeak(
"" ),
107 mFileNamePulserTimeDiffGbtx(
"" ),
109 mGet4TotBinWidthNs( 1. ),
110 mMinDigisPerSlewBin( 25 ),
111 mResetTimeCorr( 0. ),
115 mPulserPeakTime( 0. ),
116 mReferencePulserIndex( 0 ),
117 mStrictPulserHandling( 0 ),
118 mUsePulserGbtxDiff( true ),
122 mFileNameGet4State(
""),
134 LOG_DEBUG <<
"StETofCalibMaker::ctor" << endm;
137 mTimingWindow.clear();
138 mPulserWindow.clear();
139 mSignalVelocity.clear();
140 mDigiTotCorr.clear();
141 mDigiSlewCorr.clear();
143 mPulserPeakTot.clear();
144 mPulserTimeDiff.clear();
145 mPulserTimeDiffGbtx.clear();
146 mNPulsersCounter.clear();
147 mNStatusBitsCounter.clear();
148 mPulserPresent.clear();
150 mJumpingPulsers.clear();
152 mUnlockPulserState.clear();
154 mStuckFwDigi.clear();
161 StETofCalibMaker::~StETofCalibMaker()
169 StETofCalibMaker::Init()
171 LOG_INFO <<
"StETofCalibMaker::Init()" << endm;
181 StETofCalibMaker::InitRun( Int_t runnumber )
183 mRunYear = ( runnumber + 727000 ) / 1000000 + 1999;
184 LOG_INFO <<
"runnumber: " << runnumber <<
" --> year: " << mRunYear << endm;
187 std::ifstream paramFile;
205 readGet4State(mGlobalCounter , 0);
208 if( mFileNameElectronicsMap.empty() ) {
209 LOG_INFO <<
"etofElectronicsMap: no filename provided --> load database table" << endm;
211 dbDataSet = GetDataBase(
"Geometry/etof/etofElectronicsMap" );
213 St_etofElectronicsMap* etofElectronicsMap =
static_cast< St_etofElectronicsMap*
> ( dbDataSet->
Find(
"etofElectronicsMap" ) );
214 if( !etofElectronicsMap ) {
215 LOG_ERROR <<
"unable to get the electronics map from the database" << endm;
222 LOG_INFO <<
"etofElectronicsMap: filename provided --> use parameter file: " << mFileNameElectronicsMap.c_str() << endm;
232 if( mFileNameStatusMap.empty() ) {
233 LOG_INFO <<
"etofStatusMap: no filename provided --> load database table" << endm;
235 dbDataSet = GetDataBase(
"Calibrations/etof/etofStatusMap" );
237 St_etofStatusMap* etofStatusMap =
static_cast< St_etofStatusMap*
> ( dbDataSet->
Find(
"etofStatusMap" ) );
238 if( !etofStatusMap ) {
239 LOG_ERROR <<
"unable to get the status map from the database" << endm;
243 etofStatusMap_st* statusMapTable = etofStatusMap->GetTable();
245 for(
size_t i=0; i<eTofConst::nChannelsInSystem; i++ ) {
246 mStatus[ channelToKey( i ) ] = (int) statusMapTable->status[ i ];
250 LOG_INFO <<
"etofStatusMap: filename provided --> use parameter file: " << mFileNameStatusMap.c_str() << endm;
252 paramFile.open( mFileNameStatusMap.c_str() );
254 if( !paramFile.is_open() ) {
255 LOG_ERROR <<
"unable to get the 'etofStatusMap' parameters from file --> file does not exist" << endm;
259 std::vector< int > status;
261 while( paramFile >> temp ) {
262 status.push_back( temp );
267 if( status.size() != eTofConst::nChannelsInSystem ) {
268 LOG_ERROR <<
"parameter file for 'etofStatusMap' has not the right amount of entries: ";
269 LOG_ERROR << status.size() <<
" instead of " << eTofConst::nChannelsInSystem <<
" !!!!" << endm;
273 for(
size_t i=0; i<eTofConst::nChannelsInSystem; i++ ) {
274 mStatus[ channelToKey( i ) ] = status[ i ];
278 for(
const auto& kv : mStatus ) {
279 LOG_DEBUG <<
"channel key: " << kv.first <<
" --> status = " << kv.second << endm;
285 mTimingWindow.clear();
286 mPulserWindow.clear();
288 if( mFileNameTimingWindow.empty() ) {
289 LOG_INFO <<
"etofTimingWindow: no filename provided --> load database table" << endm;
291 dbDataSet = GetDataBase(
"Calibrations/etof/etofTimingWindow" );
293 St_etofTimingWindow* etofTimingWindow =
static_cast< St_etofTimingWindow*
> ( dbDataSet->
Find(
"etofTimingWindow" ) );
294 if( !etofTimingWindow ) {
295 LOG_ERROR <<
"unable to get the timing window from the database" << endm;
299 etofTimingWindow_st* timingWindowTable = etofTimingWindow->GetTable();
301 for(
size_t i=0; i<12 ; i++ ) {
302 int key = timingWindowTable->afckAddress[ i ];
304 mTimingWindow[ key ] = std::make_pair( timingWindowTable->timingMin[ i ], timingWindowTable->timingMax[ i ] );
305 mPulserWindow[ key ] = std::make_pair( timingWindowTable->pulserMin[ i ], timingWindowTable->pulserMax[ i ] );
307 mPulserPeakTime = timingWindowTable->pulserPeak[ i ];
312 LOG_INFO <<
"etofTimingWindow: filename provided --> use parameter file: " << mFileNameTimingWindow.c_str() << endm;
314 paramFile.open( mFileNameTimingWindow.c_str() );
316 if( !paramFile.is_open() ) {
317 LOG_ERROR <<
"unable to get the 'etofTimingWindow' parameters from file --> file does not exist" << endm;
322 std::vector< float > times;
326 while( std::getline( paramFile, temp ) ) {
327 std::istringstream istring( temp );
330 istring >>std::hex >> address >> std::dec;
332 while( istring >> time ) {
333 times.push_back( time );
336 if( times.size() != 6 ) {
337 LOG_ERROR <<
"parameter file for 'etofTimingWindow' has not the right amount of entries: ";
338 LOG_ERROR <<
"times for address (0x" << std::hex << address << std::dec <<
") has " << times.size() <<
" instead of " << 6 <<
" !!!!" << endm;
343 mTimingWindow[ address ] = std::make_pair( times.at( 0 ), times.at( 1 ) );
344 mPulserWindow[ address ] = std::make_pair( times.at( 3 ), times.at( 4 ) );
346 mPulserPeakTime = times.at( 5 );
351 if( mTimingWindow.size() > 12 ) {
352 LOG_ERROR <<
" too many entries in mTimingWindow map ...." << endm;
355 if( mPulserWindow.size() > 12 ) {
356 LOG_ERROR <<
" too many entries in mPulserWindow map ...." << endm;
361 for(
const auto& kv : mTimingWindow ) {
362 LOG_DEBUG <<
"AFCK address: 0x" << std::hex << kv.first << std::dec <<
" --> timing window from " << kv.second.first <<
" to " << kv.second.second <<
" ns" << endm;
364 for(
const auto& kv : mPulserWindow ) {
365 LOG_DEBUG <<
"AFCK address: 0x" << std::hex << kv.first << std::dec <<
" --> pulser window from " << kv.second.first <<
" to " << kv.second.second <<
" ns" << endm;
367 LOG_DEBUG <<
"pulser time peak at " << mPulserPeakTime <<
" ns" << endm;
371 if( mFileNameCalibParam.empty() ) {
372 LOG_INFO <<
"etofCalibParam: no filename provided --> load database table" << endm;
374 dbDataSet = GetDataBase(
"Calibrations/etof/etofCalibParam" );
376 St_etofCalibParam* etofCalibParam =
static_cast< St_etofCalibParam*
> ( dbDataSet->
Find(
"etofCalibParam" ) );
377 if( !etofCalibParam ) {
378 LOG_ERROR <<
"unable to get the calibration params from the database" << endm;
382 etofCalibParam_st* calibParamTable = etofCalibParam->GetTable();
384 mGet4TotBinWidthNs = calibParamTable->get4TotBinWidthNs;
385 mMinDigisPerSlewBin = calibParamTable->minDigisInSlewBin;
388 if( mReferencePulserIndex == 0 ) {
389 mReferencePulserIndex = calibParamTable->referencePulserIndex;
392 LOG_INFO <<
"--- reference pulser index is set manually ---" << endm;
396 LOG_INFO <<
"etofCalibParam: filename provided --> use parameter file: " << mFileNameCalibParam.c_str() << endm;
398 paramFile.open( mFileNameCalibParam.c_str() );
400 if( !paramFile.is_open() ) {
401 LOG_ERROR <<
"unable to get the 'etofCalibParam' parameters from file --> file does not exist" << endm;
405 std::vector< float > param;
407 while( paramFile >> temp ) {
408 param.push_back( temp );
413 if( param.size() != 3 ) {
414 LOG_ERROR <<
"parameter file for 'etofCalibParam' has not the right amount of entries: ";
415 LOG_ERROR << param.size() <<
" instead of 3 !!!!" << endm;
419 if( param.at( 0 ) > 0. ) {
420 mGet4TotBinWidthNs = param.at( 0 );
422 if( param.at( 1 ) > 0 ) {
423 mMinDigisPerSlewBin = param.at( 1 );
427 if( param.at( 2 ) > 0 && mReferencePulserIndex == 0 ) {
428 mReferencePulserIndex = param.at( 2 );
431 LOG_INFO <<
"--- reference pulser index is set manually ---" << endm;
435 LOG_INFO <<
" Get4 TOT bin width to ns conversion factor: " << mGet4TotBinWidthNs << endm;
436 LOG_INFO <<
" minimal number of digis required in slewing bin: " << mMinDigisPerSlewBin << endm;
437 LOG_INFO <<
" reference pulser index: " << mReferencePulserIndex << endm;
443 mSignalVelocity.clear();
445 if( mFileNameSignalVelocity.empty() ) {
446 LOG_INFO <<
"etofSignalVelocity: no filename provided --> load database table" << endm;
448 dbDataSet = GetDataBase(
"Calibrations/etof/etofSignalVelocity" );
450 St_etofSignalVelocity* etofSignalVelocity =
static_cast< St_etofSignalVelocity*
> ( dbDataSet->
Find(
"etofSignalVelocity" ) );
451 if( !etofSignalVelocity ) {
452 LOG_ERROR <<
"unable to get the signal velocity from the database" << endm;
456 etofSignalVelocity_st* velocityTable = etofSignalVelocity->GetTable();
458 for(
size_t i=0; i<eTofConst::nCountersInSystem; i++ ) {
459 if( velocityTable->signalVelocity[ i ] > 0 ) {
460 mSignalVelocity[ detectorToKey( i ) ] = velocityTable->signalVelocity[ i ];
465 LOG_INFO <<
"etofSignalVelocity: filename provided --> use parameter file: " << mFileNameSignalVelocity.c_str() << endm;
467 paramFile.open( mFileNameSignalVelocity.c_str() );
469 if( !paramFile.is_open() ) {
470 LOG_ERROR <<
"unable to get the 'etofSignalVelocity' parameters from file --> file does not exist" << endm;
474 std::vector< float > velocity;
476 while( paramFile >> temp ) {
477 velocity.push_back( temp );
482 if( velocity.size() != eTofConst::nCountersInSystem ) {
483 LOG_ERROR <<
"parameter file for 'etofSignalVelocity' has not the right amount of entries: ";
484 LOG_ERROR << velocity.size() <<
" instead of " << eTofConst::nCountersInSystem <<
" !!!!" << endm;
488 for(
size_t i=0; i<eTofConst::nCountersInSystem; i++ ) {
489 if( velocity.at( i ) > 0 ) {
490 mSignalVelocity[ detectorToKey( i ) ] = velocity.at( i );
495 for(
const auto& kv : mSignalVelocity ) {
496 LOG_DEBUG <<
"counter key: " << kv.first <<
" --> signal velocity = " << kv.second <<
" cm / ns" << endm;
502 mDigiTotCorr.clear();
503 mDigiTimeCorr.clear();
504 mDigiSlewCorr.clear();
506 if( mFileNameCalibHistograms.empty() ) {
510 LOG_INFO <<
"etofDigiTotCorr: no filename provided --> load database table" << endm;
512 dbDataSet = GetDataBase(
"Calibrations/etof/etofDigiTotCorr" );
514 St_etofDigiTotCorr* etofDigiTotCorr =
static_cast< St_etofDigiTotCorr*
> ( dbDataSet->
Find(
"etofDigiTotCorr" ) );
515 if( !etofDigiTotCorr ) {
516 LOG_ERROR <<
"unable to get the digi tot correction from the database" << endm;
520 etofDigiTotCorr_st* digiTotCorrTable = etofDigiTotCorr->GetTable();
522 for(
size_t i=0; i<eTofConst::nChannelsInSystem; i++ ) {
523 unsigned int key = channelToKey( i );
524 unsigned int detector = key / 1000;
526 if( mDigiTotCorr.count( detector ) == 0 ) {
527 TString name = Form(
"digiTotCorr_%d", detector );
528 mDigiTotCorr[ detector ] =
new TH1F( name, name, 2 * eTofConst::nStrips, 0, 2 * eTofConst::nStrips );
531 unsigned int strip = ( key % 1000 ) / 10;
532 unsigned int side = key % 10;
535 LOG_DEBUG << i <<
" " << detector <<
" " << strip <<
" " << side <<
" " << digiTotCorrTable->totCorr[ i ] << endm;
538 mDigiTotCorr.at( detector )->SetBinContent( strip + eTofConst::nStrips * ( side - 1 ) , digiTotCorrTable->totCorr[ i ] );
541 for(
auto& kv : mDigiTotCorr ) {
542 kv.second->SetDirectory( 0 );
549 LOG_INFO <<
"etofDigiTimeCorr: no filename provided --> load database table" << endm;
552 dbDataSet = GetDataBase(
"Calibrations/etof/etofDigiTimeCorr" );
554 St_etofDigiTimeCorr* etofDigiTimeCorr =
static_cast< St_etofDigiTimeCorr*
> ( dbDataSet->
Find(
"etofDigiTimeCorr" ) );
555 if( !etofDigiTimeCorr ) {
556 LOG_ERROR <<
"unable to get the digi time correction from the database" << endm;
560 etofDigiTimeCorr_st* digiTimeCorrTable = etofDigiTimeCorr->GetTable();
562 for(
size_t i=0; i<eTofConst::nChannelsInSystem; i++ ) {
563 unsigned int key = channelToKey( i );
564 unsigned int detector = key / 1000;
566 if( mDigiTimeCorr.count( detector ) == 0 ) {
567 TString name = Form(
"digiTimeCorr_%d", detector );
568 mDigiTimeCorr[ detector ] =
new TH1F( name, name, 2 * eTofConst::nStrips, 0, 2 * eTofConst::nStrips );
571 unsigned int strip = ( key % 1000 ) / 10;
572 unsigned int side = key % 10;
575 LOG_DEBUG << i <<
" " << detector <<
" " << strip <<
" " << side <<
" " << digiTimeCorrTable->timeCorr[ i ] << endm;
578 mDigiTimeCorr.at( detector )->SetBinContent( strip + eTofConst::nStrips * ( side - 1 ) , digiTimeCorrTable->timeCorr[ i ] );
581 for(
auto& kv : mDigiTimeCorr ) {
582 kv.second->SetDirectory( 0 );
589 LOG_INFO <<
"etofDigiSlewCorr: no filename provided --> load database table" << endm;
591 dbDataSet = GetDataBase(
"Calibrations/etof/etofDigiSlewCorr" );
593 St_etofDigiSlewCorr* etofDigiSlewCorr =
static_cast< St_etofDigiSlewCorr*
> ( dbDataSet->
Find(
"etofDigiSlewCorr" ) );
594 if( !etofDigiSlewCorr ) {
595 LOG_ERROR <<
"unable to get the digi slewing correction from the database" << endm;
599 etofDigiSlewCorr_st* digiSlewCorrTable = etofDigiSlewCorr->GetTable();
601 for(
size_t i=0; i<eTofConst::nChannelsInSystem; i++ ) {
602 unsigned int key = channelToKey( i );
605 std::vector< float > binEdges;
606 std::vector< float > corr;
608 binEdges.push_back( 0. );
609 for(
size_t j=0; j<etofSlewing::nTotBins; j++ ) {
610 int tableIndex = i * etofSlewing::nTotBins + j;
612 if( i != digiSlewCorrTable->channelId[ tableIndex ] ) {
613 LOG_ERROR <<
"something went wrong in reading the database table for eTOF slewing corrections" << endm;
617 binEdges.push_back( digiSlewCorrTable->upperTotEdge[ tableIndex ] * etofSlewing::conversionFactor );
618 corr.push_back( digiSlewCorrTable->corr[ tableIndex ] * etofSlewing::conversionFactor );
622 if( mDigiSlewCorr.count( key ) == 0 ) {
623 TString name = Form(
"digiSlewCorr_%d", key );
624 mDigiSlewCorr[ key ] =
new TProfile( name, name, etofSlewing::nTotBins, binEdges.data() );
628 for(
size_t j=0; j<etofSlewing::nTotBins; j++ ) {
629 float totCenter = mDigiSlewCorr.at( key )->GetBinCenter( j+1 );
630 mDigiSlewCorr.at( key )->Fill( totCenter, corr.at( j ), mMinDigisPerSlewBin + 1 );
634 for(
auto& kv : mDigiSlewCorr ) {
635 kv.second->SetDirectory( 0 );
639 LOG_INFO <<
"etof calibration histograms: filename provided --> use parameter file: " << mFileNameCalibHistograms.c_str() << endm;
641 if( !isFileExisting( mFileNameCalibHistograms ) ) {
642 LOG_ERROR <<
"unable to get the 'etofDigiTotCorr', 'etofDigiTimeCorr', 'etofDigiSlewCorr' parameters from file --> file does not exist" << endm;
645 TFile* histFile =
new TFile( mFileNameCalibHistograms.c_str(),
"READ" );
648 LOG_ERROR <<
"No calibration file found: " << mFileNameCalibHistograms.c_str() << endm;
649 LOG_INFO <<
"setting all parameters to default" << endm;
650 }
else if( histFile->IsZombie() ){
651 LOG_ERROR <<
"Zombie calibration file: " << mFileNameCalibHistograms.c_str() << endm;
652 LOG_INFO <<
"stopping execution" << endm;
656 TFile* histOffsetFile =
new TFile( mFileNameOffsetHistograms.c_str(),
"READ" );
658 if( !histOffsetFile ) {
659 LOG_INFO <<
"No offset file found: " << mFileNameOffsetHistograms.c_str() << endm;
660 LOG_INFO <<
"setting all parameters to default" << endm;
661 }
else if( histOffsetFile->IsZombie() ) {
662 LOG_ERROR <<
"Zombie offset file: " << mFileNameOffsetHistograms.c_str() << endm;
663 LOG_INFO <<
"stopping execution" << endm;
666 LOG_INFO <<
"Successfully opened RunOffset file "<< mFileNameOffsetHistograms.c_str() << endm;
671 TString hPosOffsetName = Form(
"calib_Run%d_PosOffsets_pfx", runnumber );
672 TString hT0OffsetName = Form(
"calib_Run%d_T0Offsets_pfx", runnumber );
673 TProfile* hPosOffsetProfile =
nullptr;
674 TProfile* hT0OffsetProfile =
nullptr;
676 if( histOffsetFile && !(histOffsetFile->IsZombie()) ){
677 LOG_INFO <<
"Getting run offset histograms Pos: "<< hPosOffsetName <<
" T0: "<< hT0OffsetName << endm;
678 hPosOffsetProfile = ( TProfile* ) histOffsetFile->Get( hPosOffsetName );
679 hT0OffsetProfile = ( TProfile* ) histOffsetFile->Get( hT0OffsetName );
682 for(
unsigned int sector = eTofConst::sectorStart; sector <= eTofConst::sectorStop; sector++ ) {
684 if( mRunYear == 2018 && sector != 18 )
continue;
686 for(
unsigned int zPlane = eTofConst::zPlaneStart; zPlane <= eTofConst::zPlaneStop; zPlane++ ) {
687 for(
unsigned int counter = eTofConst::counterStart; counter <= eTofConst::counterStop; counter++ ) {
689 unsigned int key = sector * 100 + zPlane * 10 + counter;
691 LOG_DEBUG <<
"detectorId key: " << sector <<
" " << zPlane <<
" " << counter << endm;
700 if( mDigiTotCorr.count( key ) == 0 ) {
701 TString name = Form(
"digiTotCorr_%d", key );
702 mDigiTotCorr[ key ] =
new TH1F( name, name, 2 * eTofConst::nStrips, 0, 2 * eTofConst::nStrips );
705 hname = Form(
"calib_Sector%02d_ZPlane%d_Det%d_TotDigi_pfx", sector, zPlane, counter );
706 hProfile = ( TProfile* ) histFile->Get( hname );
709 for(
size_t i=1; i<=2 * eTofConst::nStrips; i++ ) {
710 if( hProfile->GetBinContent( i ) != 0 ) {
711 mDigiTotCorr.at( key )->SetBinContent( i , hProfile->GetBinContent( i ) );
714 mDigiTotCorr.at( key )->SetBinContent( i , 1. );
718 if( mDigiTotCorr.at( key )->GetBinContent( i ) < 0.05 || mDigiTotCorr.at( key )->GetBinContent( i ) > 10 ) {
719 mDigiTotCorr.at( key )->SetBinContent( i , 1. );
724 if( isFileExisting( mFileNameCalibHistograms ) ) {
725 LOG_WARN <<
"unable to find histogram: " << hname << endm;
728 for(
size_t i=1; i<=2 * eTofConst::nStrips; i++ ) {
729 mDigiTotCorr.at( key )->SetBinContent( i , 1. );
733 LOG_DEBUG <<
"histogram " << mDigiTotCorr.at( key )->GetName() <<
" filled" << endm;
739 if( mDigiTimeCorr.count( key ) == 0 ) {
740 TString name = Form(
"digiTimeCorr_%d", key );
741 mDigiTimeCorr[ key ] =
new TH1F( name, name, 2 * eTofConst::nStrips, 0, 2 * eTofConst::nStrips );
745 hname = Form(
"calib_Sector%02d_ZPlane%d_Det%d_Pos_pfx", sector, zPlane, counter );
746 hProfile = ( TProfile* ) histFile->Get( hname );
748 double dRunOffset = 0;
749 if (hPosOffsetProfile) {
750 int mCounterBin = hPosOffsetProfile->FindBin( 9*(sector -13) + 3 * (zPlane - 1) + counter );
751 dRunOffset = hPosOffsetProfile->GetBinContent( mCounterBin );
752 LOG_DEBUG <<
"setting run position offset to "<< dRunOffset<<
" for counter "<< ( 9*(sector -13) + 3 * (zPlane - 1) + counter ) << endm;
754 LOG_INFO <<
"position offset histogram "<<hPosOffsetName <<
" not found" << endm;
758 for(
size_t i=1; i<= eTofConst::nStrips; i++ ) {
759 mDigiTimeCorr.at( key )->AddBinContent( i , -1. * ( hProfile->GetBinContent( i ) + dRunOffset ) / mSignalVelocity.at( key ) );
760 mDigiTimeCorr.at( key )->AddBinContent( eTofConst::nStrips + i , ( hProfile->GetBinContent( i ) + dRunOffset ) / mSignalVelocity.at( key ) );
764 if( isFileExisting( mFileNameCalibHistograms ) ) {
765 LOG_WARN <<
"unable to find histogram: " << hname << endm;
770 hname = Form(
"calib_Sector%02d_ZPlane%d_Det%d_T0corr", sector, zPlane, counter );
771 hProfile = ( TProfile* ) histFile->Get( hname );
774 if (hT0OffsetProfile) {
775 int mCounterBin = hT0OffsetProfile->FindBin( 9*(sector -13) + 3 * (zPlane - 1) + counter );
776 dRunOffset = hT0OffsetProfile->GetBinContent( mCounterBin );
778 LOG_DEBUG <<
"setting run time offset to "<< dRunOffset<<
" for counter "<< ( 9*(sector -13) + 3 * (zPlane - 1) + counter ) << endm;
780 if( hProfile && hProfile->GetNbinsX() == 1 ) {
781 LOG_DEBUG <<
"T0 histogram with 1 bin: " << key << endm;
782 for(
size_t i=1; i<=2 * eTofConst::nStrips; i++ ) {
783 mDigiTimeCorr.at( key )->AddBinContent( i , hProfile->GetBinContent( 1 ) + dRunOffset );
786 else if( hProfile && hProfile->GetNbinsX() == eTofConst::nStrips ) {
787 LOG_DEBUG <<
"T0 histogram with 32 bins: " << key << endm;
788 for(
size_t i=1; i<= eTofConst::nStrips; i++ ) {
789 mDigiTimeCorr.at( key )->AddBinContent( i , hProfile->GetBinContent( i ) + dRunOffset );
790 mDigiTimeCorr.at( key )->AddBinContent( i + eTofConst::nStrips , hProfile->GetBinContent( i ) + dRunOffset );
794 if( isFileExisting( mFileNameCalibHistograms ) ) {
795 LOG_WARN <<
"unable to find histogram: " << hname << endm;
799 LOG_DEBUG <<
"histogram " << mDigiTimeCorr.at( key )->GetName() <<
" filled" << endm;
805 for(
unsigned int chan = 0; chan < eTofConst::nChannelsPerCounter; chan++ ) {
806 unsigned int strip = ( chan % 32 ) + 1;
807 unsigned int side = ( chan / 32 ) + 1;
808 unsigned int key = sector * 100000 + zPlane * 10000 + counter * 1000 + strip * 10 + side;
810 LOG_DEBUG <<
"channelId key: " << sector <<
" " << zPlane <<
" " << counter <<
" " << strip <<
" " << side << endm;
812 hname = Form(
"calib_Sector%02d_ZPlane%d_Det%d_Chan%d_Walk_pfx", sector, zPlane, counter, chan );
813 hProfile = ( TProfile* ) histFile->Get( hname );
817 LOG_DEBUG <<
"unable to find histogram: " << hname <<
"--> check detector-wise" << endm;
818 hname = Form(
"calib_Sector%02d_ZPlane%d_Det%d_AvWalk_pfx", sector, zPlane, counter );
819 hProfile = ( TProfile* ) histFile->Get( hname );
823 unsigned int nbins = hProfile->GetNbinsX();
825 if( mDigiSlewCorr.count( key ) == 0 ) {
827 std::vector< float > bins( nbins + 1 );
829 for(
size_t i=0; i<nbins; i++ ) {
830 bins.at( i ) = hProfile->GetXaxis()->GetBinLowEdge( i+1 );
832 bins.at( nbins ) = hProfile->GetXaxis()->GetBinUpEdge( nbins );
834 TString name = Form(
"digiSlewCorr_%d", key );
835 mDigiSlewCorr[ key ] =
new TProfile( name, name, nbins, bins.data() );
838 for(
size_t iTotBin=1; iTotBin<=nbins; iTotBin++ ) {
839 mDigiSlewCorr.at( key )->Fill( hProfile->GetBinCenter( iTotBin ), hProfile->GetBinContent( iTotBin ), hProfile->GetBinEntries( iTotBin ) );
843 LOG_DEBUG <<
"unable to find histogram: " << hname << endm;
851 for(
auto& kv : mDigiTotCorr ) {
852 kv.second->SetDirectory( 0 );
854 for(
auto& kv : mDigiTimeCorr ) {
855 kv.second->SetDirectory( 0 );
857 for(
auto& kv : mDigiSlewCorr ) {
858 kv.second->SetDirectory( 0 );
871 if( mFileNameResetTimeCorr.empty() ) {
872 LOG_INFO <<
"etofResetTimeCorr: no filename provided --> load database table" << endm;
874 dbDataSet = GetDataBase(
"Calibrations/etof/etofResetTimeCorr" );
876 St_etofResetTimeCorr* etofResetTimeCorr =
static_cast< St_etofResetTimeCorr*
> ( dbDataSet->
Find(
"etofResetTimeCorr" ) );
877 if( !etofResetTimeCorr ) {
878 LOG_ERROR <<
"unable to get the reset time correction from the database" << endm;
882 etofResetTimeCorr_st* resetTimeCorrTable = etofResetTimeCorr->GetTable();
884 mResetTimeCorr = resetTimeCorrTable->resetTimeOffset;
887 LOG_INFO <<
"etofResetTimeCorr: filename provided --> use parameter file: " << mFileNameResetTimeCorr.c_str() << endm;
889 paramFile.open( mFileNameResetTimeCorr.c_str() );
891 if( !paramFile.is_open() ) {
892 LOG_ERROR <<
"unable to get the 'etofResetTimeCorr' parameters from file --> file does not exist" << endm;
896 std::map< unsigned int, float > param;
899 while( paramFile >> temp ) {
901 param[ (
unsigned int ) temp ] = temp2;
906 for(
const auto& kv : param ) {
907 LOG_DEBUG <<
"run: " << kv.first <<
" --> reset time corr = " << kv.second <<
" ns" << endm;
910 if( param.count( runnumber ) ) {
911 mResetTimeCorr = param.at( runnumber );
915 LOG_INFO <<
"additional reset time offset correction: " << mResetTimeCorr <<
" ns" << endm;
920 mPulserPeakTot.clear();
922 if( mFileNamePulserTotPeak.empty() ) {
923 LOG_INFO <<
"etofPulserPeakTot: no filename provided --> load database table" << endm;
925 dbDataSet = GetDataBase(
"Calibrations/etof/etofPulserTotPeak" );
927 St_etofPulserTotPeak* etofPulserTotPeak =
static_cast< St_etofPulserTotPeak*
> ( dbDataSet->
Find(
"etofPulserTotPeak" ) );
928 if( !etofPulserTotPeak ) {
929 LOG_ERROR <<
"unable to get the pulser tot peak parameters from the database" << endm;
933 etofPulserTotPeak_st* pulserTotTable = etofPulserTotPeak->GetTable();
935 for(
size_t i=0; i<eTofConst::nCountersInSystem * 2; i++ ) {
936 if( pulserTotTable->pulserTot[ i ] > 0 ) {
937 mPulserPeakTot[ sideToKey( i ) ] = ( int ) pulserTotTable->pulserTot[ i ];
942 LOG_INFO <<
"etofPulserPeakTot: filename provided --> use parameter file: " << mFileNamePulserTotPeak.c_str() << endm;
944 paramFile.open( mFileNamePulserTotPeak.c_str() );
946 if( !paramFile.is_open() ) {
947 LOG_ERROR <<
"unable to get the 'etofPulserTotPeak' parameters from file --> file does not exist" << endm;
951 std::vector< float > param;
953 while( paramFile >> temp ) {
954 param.push_back( temp );
959 if( param.size() != eTofConst::nCountersInSystem * 2 ) {
960 LOG_ERROR <<
"parameter file for 'etofPulserTotPeak' has not the right amount of entries: ";
961 LOG_ERROR << param.size() <<
" instead of " << eTofConst::nCountersInSystem * 2 <<
" !!!!" << endm;
965 for(
size_t i=0; i<eTofConst::nCountersInSystem * 2; i++ ) {
966 if( param.at( i ) > 0 ) {
967 mPulserPeakTot[ sideToKey( i ) ] = param.at( i );
972 for(
const auto& kv : mPulserPeakTot ) {
973 LOG_DEBUG <<
"side key: " << kv.first <<
" --> pulser peak tot = " << kv.second <<
" (bin)" << endm;
979 mPulserTimeDiffGbtx.clear();
981 if( mFileNamePulserTimeDiffGbtx.empty() ) {
982 LOG_INFO <<
"etofPulserTimeDiffGbtx: no filename provided --> load database table" << endm;
984 dbDataSet = GetDataBase(
"Calibrations/etof/etofPulserTimeDiffGbtx" );
986 St_etofPulserTimeDiffGbtx* etofPulserTimeDiffGbtx =
static_cast< St_etofPulserTimeDiffGbtx*
> ( dbDataSet->
Find(
"etofPulserTimeDiffGbtx" ) );
987 if( !etofPulserTimeDiffGbtx ) {
988 LOG_ERROR <<
"unable to get the pulser time difference parameters from the database" << endm;
992 etofPulserTimeDiffGbtx_st* pulserTimeTable = etofPulserTimeDiffGbtx->GetTable();
994 for(
size_t i=0; i<eTofConst::nModules * eTofConst::nSides; i++ ) {
995 unsigned int sector = eTofConst::sectorStart + i / ( eTofConst::nPlanes * eTofConst::nSides );
996 unsigned int zPlane = eTofConst::zPlaneStart + ( i % ( eTofConst::nPlanes * eTofConst::nSides ) ) / eTofConst::nSides;
997 unsigned int side = eTofConst::counterStart + i % eTofConst::nSides;
999 mPulserTimeDiffGbtx[ sector * 1000 + zPlane * 100 + 1 * 10 + side ] = 0.;
1000 mPulserTimeDiffGbtx[ sector * 1000 + zPlane * 100 + 2 * 10 + side ] = pulserTimeTable->pulserTimeDiffGbtx[ i * 2 + 0 ];
1001 mPulserTimeDiffGbtx[ sector * 1000 + zPlane * 100 + 3 * 10 + side ] = pulserTimeTable->pulserTimeDiffGbtx[ i * 2 + 1 ];
1005 LOG_INFO <<
"etofPulserTimeDiff: filename provided --> use parameter file: " << mFileNamePulserTimeDiffGbtx.c_str() << endm;
1007 paramFile.open( mFileNamePulserTimeDiffGbtx.c_str() );
1009 if( !paramFile.is_open() ) {
1010 LOG_ERROR <<
"unable to get the 'etotPulserTimeDiffGbtc' parameters from file --> file does not exist" << endm;
1014 std::vector< float > param;
1016 while( paramFile >> temp ) {
1017 param.push_back( temp );
1022 if( param.size() != eTofConst::nModules * eTofConst::nSides * 2 ) {
1023 LOG_ERROR <<
"parameter file for 'etofPulserTimeDiffGbtx' has not the right amount of entries: ";
1024 LOG_ERROR << param.size() <<
" instead of " << eTofConst::nModules * eTofConst::nSides <<
" !!!!" << endm;
1028 for(
size_t i=0; i<eTofConst::nModules * eTofConst::nSides; i++ ) {
1029 unsigned int sector = eTofConst::sectorStart + i / ( eTofConst::nPlanes * eTofConst::nSides );
1030 unsigned int zPlane = eTofConst::zPlaneStart + ( i % ( eTofConst::nPlanes * eTofConst::nSides ) ) / eTofConst::nSides;
1031 unsigned int side = eTofConst::counterStart + i % eTofConst::nSides;
1033 mPulserTimeDiffGbtx[ sector * 1000 + zPlane * 100 + 1 * 10 + side ] = 0.;
1034 mPulserTimeDiffGbtx[ sector * 1000 + zPlane * 100 + 2 * 10 + side ] = param.at( i * 2 + 0 );
1035 mPulserTimeDiffGbtx[ sector * 1000 + zPlane * 100 + 3 * 10 + side ] = param.at( i * 2 + 1 );
1041 bool allZero =
true;
1043 for(
const auto& kv : mPulserTimeDiffGbtx ) {
1044 if( fabs( kv.second ) > 1e-4 ) allZero =
false;
1047 LOG_INFO <<
"side key: " << kv.first <<
" --> pulser time diff inside Gbtx ( to counter 1 ) = " << kv.second << endm;
1052 mUsePulserGbtxDiff =
false;
1053 LOG_INFO <<
"the use of pulser relations inside a Gbtx is turned off" << endm;
1057 mHistograms.at(
"pulserDigiTimeDiff_GbtxCorrProfMod" )->Reset();
1068 StETofCalibMaker::FinishRun( Int_t runnumber )
1076 for(
auto kv = mDigiTotCorr.begin(); kv != mDigiTotCorr.end(); kv++ ) {
1078 kv->second =
nullptr;
1080 mDigiTotCorr.clear();
1082 for(
auto kv = mDigiTimeCorr.begin(); kv != mDigiTimeCorr.end(); kv++ ) {
1084 kv->second =
nullptr;
1086 mDigiTimeCorr.clear();
1088 for(
auto kv = mDigiSlewCorr.begin(); kv != mDigiSlewCorr.end(); kv++ ) {
1090 kv->second =
nullptr;
1092 mDigiSlewCorr.clear();
1094 mPulserPeakTot.clear();
1095 mPulserTimeDiff.clear();
1097 mJumpingPulsers.clear();
1099 mGet4StateMap.clear();
1100 mGet4ZeroStateMap.clear();
1101 mMasterStartVec.clear();
1113 LOG_INFO <<
"Finish() - writing *.etofCalib.root ..." << endm;
1125 LOG_DEBUG <<
"StETofCalibMaker::Make(): starting ..." << endm;
1127 mEvent = (
StEvent* ) GetInputDS(
"StEvent" );
1132 unsigned long int evtNr = GetEventNumber();
1133 if(mFileNameGet4State.empty()){
1136 if( evtNr > mDbEntryStop || evtNr < mDbEntryStart) readGet4State(mGlobalCounter , 99);
1141 while( evtNr > mDbEntryStop || evtNr < mDbEntryStart){
1145 LOG_ERROR <<
" Get4 State File for event Nr:" << GetEventNumber() <<
"not found" << endm;
1150 if(evtNr < mDbEntryStart) forward = -1;
1151 readGet4State(mGlobalCounter , forward);
1156 checkGet4State( evtNr );
1160 LOG_DEBUG <<
"Make(): running on StEvent" << endm;
1164 if( !etofCollection ) {
1165 LOG_WARN <<
"Make() - Found StEvent data structure, but no eTOF collection. Try MuDst processing instead" << endm;
1166 mMuDst = (
StMuDst* ) GetInputDS(
"MuDst" );
1169 LOG_DEBUG <<
"Make() - running on MuDsts" << endm;
1182 LOG_DEBUG <<
"Make(): no StEvent found" << endm;
1184 mMuDst = (
StMuDst* ) GetInputDS(
"MuDst" );
1187 LOG_DEBUG <<
"Make(): running on MuDsts" << endm;
1194 LOG_WARN <<
"Make() - no StMuDst or StEvent" << endm;
1208 if( !etofCollection ) {
1209 LOG_WARN <<
"processStEvent() - no etof collection" << endm;
1213 if( !etofCollection->digisPresent() ) {
1214 LOG_WARN <<
"processStEvent() - no digis present" << endm;
1218 if( !etofCollection->etofHeader() ) {
1219 LOG_WARN <<
"processStEvent() - no header" << endm;
1225 StETofHeader* etofHeader = etofCollection->etofHeader();
1226 StSPtrVecETofDigi& etofDigis = etofCollection->etofDigis();
1243 size_t nDigis = etofDigis.size();
1245 LOG_INFO <<
"processStEvent() - # fired eTOF digis : " << nDigis << endm;
1248 mTriggerTime = triggerTime( etofHeader );
1249 mResetTime = fmod( resetTime( etofHeader ), eTofConst::bTofClockCycle );
1251 std::map< unsigned int, std::vector< unsigned int > > pulserCandMap;
1254 for(
size_t i=0; i<nDigis; i++ ) {
1259 LOG_WARN <<
"No digi found" << endm;
1264 resetToRaw( aDigi );
1269 applyMapping( aDigi );
1272 if( mRunYear != 2018 ) {
1273 flagPulserDigis( aDigi, i, pulserCandMap );
1279 LOG_INFO <<
"size of pulserCandMap: " << pulserCandMap.size() << endm;
1281 calculatePulserOffsets( pulserCandMap );
1284 TClass* headerClass = etofHeader->IsA();
1285 if( headerClass->GetClassVersion() > 2 ){
1287 std::vector<bool> goodEventFlagVec;
1288 std::vector<bool> hasPulsersVec;
1291 for(
unsigned int iCounter = 0; iCounter < 108; iCounter++){
1292 hasPulsersVec.push_back((mNPulsersCounter.count(iCounter) > 0) && (mNPulsersCounter[iCounter] == 2));
1294 if (hasPulsersVec.size() == 108){
1299 for(
unsigned int iGet4 = 0; iGet4 < 1728; iGet4++){
1303 if (goodEventFlagVec.size() == 1728){
1304 etofHeader->setGoodEventFlagVec(goodEventFlagVec);
1312 int nDuplicates = 0;
1314 for(
size_t i=0; i<nDigis; i++ ) {
1318 LOG_WARN <<
"No digi found" << endm;
1323 current.tot = aDigi->
rawTot();
1324 current.time = aDigi->
rawTime();
1327 auto it = std::find( mStuckFwDigi.begin(), mStuckFwDigi.end(), current );
1328 if( it != mStuckFwDigi.end() ) {
1330 LOG_INFO <<
"digi from stuck firmware (s" << aDigi->
sector() <<
" m" << aDigi->
zPlane() <<
" c" << aDigi->
counter() <<
") --> ignore" << endm;
1336 else if( current == prev ) {
1337 mStuckFwDigi.push_back( current );
1338 resetToRaw( mMuDst->
etofDigi( i-1 ) );
1350 applyCalibration( aDigi, etofHeader );
1353 if( mDoQA && nDuplicates > 0 ) {
1354 LOG_INFO <<
"*** # duplicate digis from stuck firmware: " << nDuplicates << endm;
1355 for(
const auto& v : mStuckFwDigi ) {
1356 LOG_INFO <<
"stuck channel with geomId: " << v.geomId <<
" " << v.tot <<
" " << v.time << endm;
1359 mStuckFwDigi.clear();
1367 LOG_DEBUG <<
"processMuDst(): starting ..." << endm;
1370 if( !mMuDst->
etofArray( muETofDigi ) ) {
1371 LOG_WARN <<
"processMuDst() - no digi array" << endm;
1375 if( !mMuDst->numberOfETofDigi() ) {
1376 LOG_WARN <<
"processMuDst() - no digis present" << endm;
1380 if( !mMuDst->
etofArray( muETofHeader ) ) {
1381 LOG_WARN <<
"processMuDst() - no digi array" << endm;
1386 mNPulsersCounter.clear();
1405 size_t nDigis = mMuDst->numberOfETofDigi();
1408 mTriggerTime = triggerTime( (
StETofHeader* ) etofHeader );
1409 mResetTime = fmod( resetTime( (
StETofHeader* ) etofHeader ), eTofConst::bTofClockCycle );
1410 std::map< unsigned int, std::vector< unsigned int >> pulserCandMap;
1414 for(
size_t i=0; i<nDigis; i++ ) {
1419 LOG_WARN <<
"No digi found" << endm;
1424 resetToRaw( aDigi );
1430 applyMapping( aDigi );
1436 if( mRunYear != 2018 ) {
1437 flagPulserDigis( aDigi, i, pulserCandMap );
1444 calculatePulserOffsets( pulserCandMap );
1448 TClass* headerClass = etofHeader->IsA();
1449 if( headerClass->GetClassVersion() > 2 ){
1451 std::vector<bool> goodEventFlagVec;
1452 std::vector<bool> hasPulsersVec;
1455 for(
unsigned int iCounter = 0; iCounter < 108; iCounter++){
1456 hasPulsersVec.push_back((mNPulsersCounter.count(iCounter) > 0) && (mNPulsersCounter[iCounter] == 2));
1459 if (hasPulsersVec.size() == 108){
1460 etofHeader->setHasPulsersVec(hasPulsersVec);
1464 for(
unsigned int iGet4 = 0; iGet4 < 1728; iGet4++){
1468 if(mGet4StateMap[iGet4] == 3){
1469 goodEventFlagVec.at(iGet4) =
false;
1473 if (goodEventFlagVec.size() == 1728){
1474 etofHeader->setGoodEventFlagVec(goodEventFlagVec);
1481 int nDuplicates = 0;
1483 for(
size_t i=0; i<nDigis; i++ ) {
1487 LOG_WARN <<
"No digi found" << endm;
1492 current.tot = aDigi->
rawTot();
1493 current.time = aDigi->
rawTime();
1496 auto it = std::find( mStuckFwDigi.begin(), mStuckFwDigi.end(), current );
1497 if( it != mStuckFwDigi.end() ) {
1499 LOG_INFO <<
"digi from stuck firmware (s" << aDigi->
sector() <<
" m" << aDigi->
zPlane() <<
" c" << aDigi->
counter() <<
") --> ignore" << endm;
1505 else if( current == prev ) {
1506 mStuckFwDigi.push_back( current );
1507 resetToRaw( mMuDst->
etofDigi( i-1 ) );
1518 applyCalibration( aDigi, etofHeader );
1521 if( mDoQA && nDuplicates > 0 ) {
1522 LOG_INFO <<
"*** # duplicate digis from stuck firmware: " << nDuplicates << endm;
1523 for(
const auto& v : mStuckFwDigi ) {
1524 LOG_INFO <<
"stuck channel with geomId: " << v.geomId <<
" " << v.tot <<
" " << v.time << endm;
1527 mStuckFwDigi.clear();
1534 StETofCalibMaker::isFileExisting(
const std::string fileName )
1536 std::ifstream infile( fileName );
1537 return infile.good();
1546 StETofCalibMaker::resetToRaw(
StETofDigi* aDigi )
1548 if( !aDigi )
return;
1551 aDigi->setCalibTime( 0. );
1552 aDigi->setCalibTot( -1. );
1554 aDigi->setAssociatedHit(
nullptr );
1563 StETofCalibMaker::applyMapping(
StETofDigi* aDigi )
1565 std::vector< unsigned int > geomVec;
1567 unsigned int rocId = aDigi->
rocId();
1568 unsigned int get4Id = aDigi->
get4Id();
1569 unsigned int elChan = aDigi->
elChan();
1571 mHwMap->mapToGeom( rocId, get4Id, elChan, geomVec );
1573 if( geomVec.size() < 5 ) {
1575 LOG_ERROR <<
"geometry vector has wrong size !!! --> skip digi" << endm;
1580 unsigned int sector = geomVec.at( 0 );
1581 unsigned int zplane = geomVec.at( 1 );
1582 unsigned int counter = geomVec.at( 2 );
1583 unsigned int strip = geomVec.at( 3 );
1584 unsigned int side = geomVec.at( 4 );
1586 if( mDebug && ( sector == 0 || zplane == 0 || counter == 0 || strip == 0 || side == 0 ) ) {
1587 LOG_ERROR <<
"geometry vector has entries equal to zero !!! --> skip digi" << endm;
1590 aDigi->
setGeoAddress( sector, zplane, counter, strip, side );
1594 LOG_DEBUG <<
"sector, zplane, counter, strip, side: " << aDigi->
sector() <<
", ";
1595 LOG_DEBUG << aDigi->
zPlane() <<
", " << aDigi->
counter() <<
", ";
1596 LOG_DEBUG << aDigi->
strip() <<
", " << aDigi->
side() << endm;
1598 LOG_DEBUG <<
"continuous module number: " << mHwMap->module( aDigi->
sector(), aDigi->
zPlane() ) << endm;
1608 StETofCalibMaker::flagPulserDigis(
StETofDigi* aDigi,
unsigned int index, std::map<
unsigned int, std::vector< unsigned int > >& pulserDigiMap )
1610 bool isPulserCand =
false;
1616 if( ( aDigi->
strip() == 1 && aDigi->
side() == 1 ) || ( aDigi->
strip() == 32 && aDigi->
side() == 2 ) ) {
1617 float timeToTrigger = aDigi->
rawTime() - mTriggerTime;
1620 float totToPeak = aDigi->
rawTot() - mPulserPeakTot.at( key );
1621 float totToHalfPeak = aDigi->
rawTot() - mPulserPeakTot.at( key ) * 0.5;
1623 isPulserCand = ( timeToTrigger > mPulserWindow.at( aDigi->
rocId() ).first &&
1624 timeToTrigger < mPulserWindow.at( aDigi->
rocId() ).second &&
1625 ( fabs( totToPeak ) < 25 || fabs( totToHalfPeak ) < 10 ) );
1629 if( isPulserCand ) {
1630 pulserDigiMap[ key ].push_back( index );
1643 StETofCalibMaker::calculatePulserOffsets( std::map<
unsigned int, std::vector< unsigned int > >& pulserDigiMap )
1646 for(
auto it=pulserDigiMap.begin(); it!=pulserDigiMap.end(); it++ ) {
1647 LOG_DEBUG <<
"channel: " << it->first <<
" nCandidates: " << it->second.size() << endm;
1651 if( mReferencePulserIndex == 0 ) {
1653 LOG_INFO <<
"reference pulser index is 0 --> pulser correction is turned off" << endm;
1659 LOG_INFO <<
"reference pulser index: " << mReferencePulserIndex << endm;
1662 std::map< int, double > pulserTimes;
1663 mNPulsersCounter.clear();
1664 mPulserPresent.clear();
1667 for(
auto it=pulserDigiMap.begin(); it!=pulserDigiMap.end(); it++ ) {
1668 if( it->second.size() == 0 ) {
1671 int sideIndex = it->first;
1673 double bestDiff = 100000;
1676 for(
size_t j=0; j<it->second.size(); j++ ) {
1677 double pulserTime = 0.;
1678 double pulserTot = 0.;
1680 pulserTime = mMuDst->
etofDigi( it->second.at( j ) )->rawTime();
1681 pulserTot = mMuDst->
etofDigi( it->second.at( j ) )->rawTot();
1682 }
else if( mEvent ) {
1683 pulserTime = ( mEvent->etofCollection()->etofDigis() )[ it->second.at( j ) ]->
rawTime();
1684 pulserTot = ( mEvent->etofCollection()->etofDigis() )[ it->second.at( j ) ]->rawTot();
1686 double timeToTrigger = pulserTime - mTriggerTime;
1687 double totToPeak = pulserTot - mPulserPeakTot.at( sideIndex );
1689 if( mDebug && it->second.size() > 1 ) {
1690 LOG_INFO << it->second.size() <<
" pulsers @ " << sideIndex <<
" : timeToTrigger: " << timeToTrigger <<
" tot: " << pulserTot << endm;
1694 double currentDiff = fabs( timeToTrigger - mPulserPeakTime ) * 0.1 + fabs( totToPeak );
1695 if( currentDiff < bestDiff ) {
1696 bestDiff = currentDiff;
1701 if( mDebug && it->second.size() > 1 ) {
1702 LOG_INFO <<
" --> selected CAND-INDEX: " << candIndex << endm;
1705 double pulserTime = 0.;
1708 pulserTime = mMuDst->
etofDigi( it->second.at( candIndex ) )->rawTime();
1711 mMuDst->
etofDigi( it->second.at( candIndex ) )->setCalibTot( -999. );
1712 }
else if( mEvent ) {
1713 pulserTime = ( mEvent->etofCollection()->etofDigis() )[ it->second.at( candIndex ) ]->
rawTime();
1716 mEvent->etofCollection()->etofDigis() [ it->second.at( candIndex ) ]->setCalibTot( -999. );
1719 pulserTimes[ sideIndex ] = pulserTime;
1721 int sector = sideIndex / 1000;
1722 int plane = ( sideIndex % 1000) / 100;
1723 int counter = ( sideIndex % 100) / 10;
1724 int key = 9 * ( sector - 13 ) + 3 * ( plane - 1 ) + ( counter - 1 );
1725 if( mNPulsersCounter.count( key ) ){
1726 mNPulsersCounter[key]++;
1728 mNPulsersCounter[key] = 1;
1731 mPulserPresent[ sideIndex ] =
true;
1734 double referenceTime = 0.;
1737 if( pulserTimes.count( mReferencePulserIndex ) ) {
1738 referenceTime = pulserTimes.at( mReferencePulserIndex );
1741 LOG_INFO <<
"preliminary reference time:" << referenceTime << endm;
1748 if( mUsePulserGbtxDiff ) {
1749 for(
int gbtxId = 0; gbtxId < eTofConst::nModules * eTofConst::nSides; gbtxId++ ) {
1750 int sector = eTofConst::sectorStart + gbtxId / ( eTofConst::nPlanes * eTofConst::nSides );
1751 int zPlane = eTofConst::zPlaneStart + ( gbtxId % ( eTofConst::nPlanes * eTofConst::nSides ) ) / eTofConst::nSides;
1752 int side = eTofConst::sideStart + gbtxId % eTofConst::nSides;
1754 int partialKey = sector * 1000 + zPlane * 100 + side;
1756 vector< double > times( eTofConst::nCounters );
1758 double average = 0.;
1761 for(
int counter = 1; counter <= eTofConst::nCounters; counter++ ) {
1762 int key = partialKey + 10 * counter;
1764 if( pulserTimes.count( key ) ) {
1766 if( pulserTimes.count( partialKey + 10 ) ) {
1767 mHistograms.at(
"pulserDigiTimeToCounter1" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, pulserTimes.at( partialKey + 10 ) - pulserTimes.at( key ) );
1769 if( pulserTimes.count( partialKey + 20 ) ) {
1770 mHistograms.at(
"pulserDigiTimeToCounter2" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, pulserTimes.at( partialKey + 20 ) - pulserTimes.at( key ) );
1772 if( pulserTimes.count( partialKey + 30 ) ) {
1773 mHistograms.at(
"pulserDigiTimeToCounter3" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, pulserTimes.at( partialKey + 30 ) - pulserTimes.at( key ) );
1777 times.at( counter - 1 ) = pulserTimes.at( key ) + mPulserTimeDiffGbtx.at( key );
1779 bool isNonSmearedPulser =
false;
1780 if( referenceTime != 0 ) {
1781 double dist = times.at( counter - 1 ) - referenceTime;
1782 double redDist = mHistograms.at(
"pulserDigiTimeDiff_GbtxCorrProfMod" )->GetBinContent( gbtxId * eTofConst::nCounters + counter );
1784 double modDist = fmod( dist - redDist, eTofConst::coarseClockCycle );
1785 modDist = modDist - eTofConst::coarseClockCycle * round( modDist / eTofConst::coarseClockCycle );
1788 if( redDist == 0 || fabs( modDist ) > 0.5 ) {
1789 if( redDist != 0 ) LOG_INFO <<
"too far away --> smeared pulser: " << key <<
"(" << gbtxId <<
"-" << counter <<
")" << endm;
1794 isNonSmearedPulser =
true;
1797 mHistograms.at(
"pulserDigiTimeDiff_GbtxCorrProf" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, dist );
1798 mHistograms.at(
"pulserDigiTimeDiff_GbtxCorrProfMod" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, redDist );
1801 mHistograms.at(
"pulserDigiTimeDiff_GbtxCorr" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, dist );
1802 mHistograms.at(
"pulserDigiTimeDiff" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, pulserTimes.at( key ) - referenceTime );
1807 if( isNonSmearedPulser ) {
1808 average += times.at( counter - 1 );
1812 times.at( counter - 1 ) = 0.;
1819 if( nAv == eTofConst::nCounters ) {
1820 double diff12 = fabs( times.at( 0 ) - times.at( 1 ) );
1821 double diff13 = fabs( times.at( 0 ) - times.at( 2 ) );
1822 double diff23 = fabs( times.at( 1 ) - times.at( 2 ) );
1824 if( diff12 > 0.2 && diff13 > 0.2 && diff23 < 0.2 ) {
1825 average -= times.at( 0 );
1828 if( fabs( times.at( 0 ) - ( average / nAv ) + eTofConst::coarseClockCycle ) < 0.2 ) {
1829 mJumpingPulsers[ partialKey + 10 ] = 1;
1831 times.at( 0 ) += eTofConst::coarseClockCycle;
1832 average += times.at( 0 );
1835 else if( fabs( times.at( 0 ) - ( average / nAv ) - eTofConst::coarseClockCycle ) < 0.2 ) {
1836 mJumpingPulsers[ partialKey + 10 ] = -1;
1838 times.at( 0 ) -= eTofConst::coarseClockCycle;
1839 average += times.at( 0 );
1844 mHistograms.at(
"1_off" )->Fill( gbtxId * eTofConst::nCounters + 1.5, times.at( 0 ) - ( average / nAv ) );
1847 else if( diff12 > 0.2 && diff13 < 0.2 && diff23 > 0.2 ) {
1848 average -= times.at( 1 );
1851 if( fabs( times.at( 1 ) - ( average / nAv ) + eTofConst::coarseClockCycle ) < 0.2 ) {
1852 mJumpingPulsers[ partialKey + 20 ] = 1;
1854 times.at( 1 ) += eTofConst::coarseClockCycle;
1855 average += times.at( 1 );
1858 else if( fabs( times.at( 1 ) - ( average / nAv ) - eTofConst::coarseClockCycle ) < 0.2 ) {
1859 mJumpingPulsers[ partialKey + 20 ] = -1;
1861 times.at( 1 ) -= eTofConst::coarseClockCycle;
1862 average += times.at( 1 );
1867 mHistograms.at(
"2_off" )->Fill( gbtxId * eTofConst::nCounters + 1.5, times.at( 1 ) - ( average / nAv ) );
1870 else if( diff12 < 0.2 && diff13 > 0.2 && diff23 > 0.2 ) {
1871 average -= times.at( 2 );
1874 if( fabs( times.at( 2 ) - ( average / nAv ) + eTofConst::coarseClockCycle ) < 0.2 ) {
1875 mJumpingPulsers[ partialKey + 30 ] = 1;
1877 times.at( 2 ) += eTofConst::coarseClockCycle;
1878 average += times.at( 2 );
1881 else if( fabs( times.at( 2 ) - ( average / nAv ) - eTofConst::coarseClockCycle ) < 0.2 ) {
1882 mJumpingPulsers[ partialKey + 30 ] = -1;
1884 times.at( 2 ) -= eTofConst::coarseClockCycle;
1885 average += times.at( 2 );
1890 mHistograms.at(
"3_off" )->Fill( gbtxId * eTofConst::nCounters + 1.5, times.at( 2 ) - ( average / nAv ) );
1895 if( nAv == eTofConst::nCounters - 1 ) {
1897 if( times.at( 0 ) > 0 && times.at( 1 ) > 0 && fabs( fabs( times.at( 0 ) - times.at( 1 ) ) - eTofConst::coarseClockCycle ) < 0.2 ) {
1898 if( mJumpingPulsers.count( partialKey + 10 ) ) {
1900 times.at( 0 ) += mJumpingPulsers.at( partialKey + 10 ) * eTofConst::coarseClockCycle;
1901 average += mJumpingPulsers.at( partialKey + 10 ) * eTofConst::coarseClockCycle;
1903 else if( mJumpingPulsers.count( partialKey + 20 ) ) {
1905 times.at( 1 ) += mJumpingPulsers.at( partialKey + 20 ) * eTofConst::coarseClockCycle;
1906 average += mJumpingPulsers.at( partialKey + 20 ) * eTofConst::coarseClockCycle;
1910 if( times.at( 0 ) < times.at( 1 ) ) {
1911 times.at( 0 ) += eTofConst::coarseClockCycle;
1912 average += eTofConst::coarseClockCycle;
1915 times.at( 1 ) += eTofConst::coarseClockCycle;
1916 average += eTofConst::coarseClockCycle;
1920 else if( times.at( 0 ) && times.at( 2 ) > 0 && fabs( fabs( times.at( 0 ) - times.at( 2 ) ) - eTofConst::coarseClockCycle ) < 0.2 ) {
1921 if( mJumpingPulsers.count( partialKey + 10 ) ) {
1923 times.at( 0 ) += mJumpingPulsers.at( partialKey + 10 ) * eTofConst::coarseClockCycle;
1924 average += mJumpingPulsers.at( partialKey + 10 ) * eTofConst::coarseClockCycle;
1926 else if( mJumpingPulsers.count( partialKey + 30 ) ) {
1928 times.at( 2 ) += mJumpingPulsers.at( partialKey + 30 ) * eTofConst::coarseClockCycle;
1929 average += mJumpingPulsers.at( partialKey + 30 ) * eTofConst::coarseClockCycle;
1933 if( times.at( 0 ) < times.at( 2 ) ) {
1934 times.at( 0 ) += eTofConst::coarseClockCycle;
1935 average += eTofConst::coarseClockCycle;
1938 times.at( 2 ) += eTofConst::coarseClockCycle;
1939 average += eTofConst::coarseClockCycle;
1943 else if( times.at( 1 ) > 0 && times.at( 2 ) > 0 && fabs( fabs( times.at( 1 ) - times.at( 2 ) ) - eTofConst::coarseClockCycle ) < 0.2 ) {
1944 if( mJumpingPulsers.count( partialKey + 20 ) ) {
1946 times.at( 1 ) += mJumpingPulsers.at( partialKey + 20 ) * eTofConst::coarseClockCycle;
1947 average += mJumpingPulsers.at( partialKey + 20 ) * eTofConst::coarseClockCycle;
1949 else if( mJumpingPulsers.count( partialKey + 30 ) ) {
1951 times.at( 2 ) += mJumpingPulsers.at( partialKey + 30 ) * eTofConst::coarseClockCycle;
1952 average += mJumpingPulsers.at( partialKey + 30 ) * eTofConst::coarseClockCycle;
1956 if( times.at( 1 ) < times.at( 2 ) ) {
1957 times.at( 1 ) += eTofConst::coarseClockCycle;
1958 average += eTofConst::coarseClockCycle;
1961 times.at( 2 ) += eTofConst::coarseClockCycle;
1962 average += eTofConst::coarseClockCycle;
1973 if( mDoQA && referenceTime != 0 ) {
1974 mHistograms.at(
"pulserDigiTimeDiff_perGbtx" )->Fill( gbtxId * eTofConst::nCounters + 1.5, average - referenceTime );
1977 for(
int counter = eTofConst::counterStart; counter <= eTofConst::counterStop; counter++ ) {
1978 double diffToAv = 0.;
1980 if( times.at( counter - eTofConst::counterStart ) != 0. ) {
1981 diffToAv = times.at( counter - eTofConst::counterStart ) - average;
1983 if( fabs( diffToAv ) > 0.2 ) diffToAv = 0.;
1986 mHistograms.at(
"pulserDigiTimeDiff_toAverage" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, diffToAv );
1990 if( average != 0. ) {
1992 pulserTimes[ partialKey + 10 * counter ] = average + diffToAv - mPulserTimeDiffGbtx.at( partialKey + 10 * counter );
1996 if( pulserTimes.count( partialKey + 10 * counter ) ) {
1997 pulserTimes.erase( partialKey + 10 * counter );
2007 if( pulserTimes.count( mReferencePulserIndex ) ) {
2008 if( mPulserTimeDiff.count( mReferencePulserIndex ) ){
2009 referenceTime = pulserTimes.at( mReferencePulserIndex ) - mPulserTimeDiff[ mReferencePulserIndex ];
2012 referenceTime = pulserTimes.at( mReferencePulserIndex );
2019 if( referenceTime != 0 ) {
2020 int iLockThreshold = 0;
2021 mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->Reset(
"ICESM");
2023 for(
auto& kv : pulserTimes ) {
2025 if( mPulserTimeDiff.count( kv.first ) ) {
2029 double modDist = mPulserTimeDiff.at( kv.first ) - ( kv.second - referenceTime );
2033 if( fabs( modDist ) > 0.2 ) {
2034 mUnlockPulserState[ kv.first ]++;
2040 if( mUnlockPulserState.at( kv.first ) < iLockThreshold ) {
2049 mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->Fill( kv.second - referenceTime );
2053 if( mUnlockPulserState.count( kv.first ) ) {
2054 LOG_INFO <<
" --> new event doesn't have offset for pulser " << kv.first <<
" --> remove the entry" << endm;
2055 mUnlockPulserState.erase( kv.first );
2063 int sector = kv.first / 1000;
2064 int zPlane = ( kv.first % 1000 ) / 100;
2065 int counter = ( kv.first % 100 ) / 10;
2066 int side = kv.first % 10;
2068 int gbtxId = ( sector - eTofConst::sectorStart ) * ( eTofConst::nPlanes * eTofConst::nSides )
2069 + ( zPlane - eTofConst::zPlaneStart ) * eTofConst::nSides
2070 + ( side - eTofConst::sideStart );
2072 if( mPulserTimeDiff.count( kv.first ) ) {
2073 mHistograms.at(
"pulserDigiTimeDiff_fullCorr" )->Fill( gbtxId * eTofConst::nCounters + counter - 0.5, mPulserTimeDiff.at( kv.first ) );
2076 mHistograms[
"pulserDigiPresence" ]->Fill(gbtxId * eTofConst::nCounters + counter - 0.5);
2082 mHistograms[
"pulserDigiPresence" ]->Fill( -1 );
2083 mHistograms[
"pulserDigiTimeDiff_CorrAgreement" ]->Fill( mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->GetMaximum() );
2084 mHistograms[
"pulserDigiTimeDiff_CorrCommonJump" ]->Fill( mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->GetEntries() );
2086 if( ( mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->GetEntries() > 150 ) && ( mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->GetMaximum() > 15 ) ){
2089 int iMaximumBin = mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->GetMaximumBin();
2090 double dRefCorrAverage = 0;
2091 int iNRefCorrAgree = 0;
2093 for(
auto& kv : pulserTimes ) {
2094 if ( mHistograms[
"pulserDigiTimeDiff_RefCorr" ]->FindBin(kv.second - referenceTime) == iMaximumBin ){
2095 dRefCorrAverage += kv.second - referenceTime;
2099 dRefCorrAverage /= iNRefCorrAgree;
2100 referenceTime -= dRefCorrAverage;
2102 mPulserTimeDiff[ mReferencePulserIndex ] -= dRefCorrAverage;
2106 for(
auto& kv : pulserTimes ) {
2107 if ( ! mPulserTimeDiff[ kv.first ] ) {
2108 mPulserTimeDiff[ kv.first ] = kv.second - referenceTime;
2111 if( mUnlockPulserState.count( kv.first ) ){
2112 if( mUnlockPulserState.at( kv.first ) > iLockThreshold ){
2113 mPulserTimeDiff[ kv.first ] = kv.second - referenceTime;
2130 if( !mStatus.count( key) || mStatus.at( key ) != 1 ) {
2132 LOG_DEBUG <<
"status of channel with key " << key <<
" was not ok ---> skip calibrating this digi" << endm;
2138 if( fabs( aDigi->
calibTot() + 999. ) < 1.e-5 ) {
2140 LOG_DEBUG <<
"digi flaged as pulser --> skip" << endm;
2145 float timeToTrigger = aDigi->
rawTime() - mTriggerTime;
2148 if( timeToTrigger > mTimingWindow.at( aDigi->
rocId() ).first &&
2149 timeToTrigger < mTimingWindow.at( aDigi->
rocId() ).second )
2152 if( mStrictPulserHandling ){
2154 if( !mPulserPresent.count( PulserKey ) ) {
2156 LOG_DEBUG <<
"no pulser in the same event for this counter --> digi skipped due to strict pulser handling" << endm;
2162 double calibTot = aDigi->
rawTot() * mGet4TotBinWidthNs * calibTotFactor( aDigi );
2164 aDigi->setCalibTot( calibTot );
2166 int get4Id = 144 * ( aDigi->
sector() - 13 ) + 48 * ( aDigi->
zPlane() -1 ) + 16 * ( aDigi->
counter() - 1 ) + 8 * ( aDigi->
side() - 1 ) + ( ( aDigi->
strip() - 1 ) / 4 );
2168 double stateCorr =0;
2169 if(mGet4StateMap[get4Id] == 1) stateCorr = 6.25;
2170 else if(mGet4StateMap[get4Id] == 2) stateCorr = -6.25;
2173 double calibTime = aDigi->
rawTime() - mResetTime
2175 - calibTimeOffset( aDigi )
2176 - slewingTimeOffset( aDigi )
2177 - applyPulserOffset( aDigi )
2181 if(mGet4StateMap[get4Id] == 3){
2186 aDigi->setCalibTime( calibTime );
2190 LOG_DEBUG <<
"raw Time, ToT: " << aDigi->
rawTime() <<
", " << aDigi->
rawTot() << endm;
2191 LOG_DEBUG <<
"calibrated Time, ToT: " << aDigi->
calibTime() <<
", " << aDigi->
calibTot() << endm;
2197 LOG_DEBUG <<
"digi is outside the timing window (time to trigger = " << timeToTrigger <<
") --> skip" << endm;
2208 if( !aDigi )
return;
2211 aDigi->setCalibTime( 0. );
2212 aDigi->setCalibTot( -1. );
2214 aDigi->setAssociatedHitId( -1 );
2228 StETofCalibMaker::flagPulserDigis(
StMuETofDigi* aDigi,
unsigned int index, std::map<
unsigned int, std::vector< unsigned int > >& pulserDigiMap )
2230 flagPulserDigis( (
StETofDigi* ) aDigi, index, pulserDigiMap );
2248 StETofCalibMaker::calibTotFactor(
StETofDigi* aDigi )
2251 unsigned int bin = aDigi->
strip() + 32 * ( aDigi->
side() - 1 );
2253 if( mDigiTotCorr.count( key ) ) {
2254 float binContent = mDigiTotCorr.at( key )->GetBinContent( bin );
2256 if( fabs( binContent ) > 1e-5 ) {
2258 LOG_DEBUG <<
"calibTotFactor: histogram with key " << key <<
" at bin " << bin <<
" -> return bin content: " << binContent << endm;
2260 return (1.0/binContent);
2264 LOG_WARN <<
"calibTotFactor: histogram with key " << key <<
" at bin " << bin <<
" has content of 0 -> return 1" << endm;
2271 LOG_WARN <<
"calibTotFactor: required histogram with key " << key <<
" doesn't exist -> return 1" << endm;
2283 StETofCalibMaker::calibTimeOffset(
StETofDigi* aDigi )
2286 unsigned int bin = aDigi->
strip() + 32 * ( aDigi->
side() - 1 );
2288 if( mDigiTimeCorr.count( key ) ) {
2289 float binContent = mDigiTimeCorr.at( key )->GetBinContent( bin );
2291 LOG_DEBUG <<
"calibTimeOffset: histogram with key " << key <<
" at bin " << bin <<
" -> return bin content: " << binContent << endm;
2297 LOG_WARN <<
"calibTimeOffset: required histogram with key " << key <<
" doesn't exist -> return 0" << endm;
2309 StETofCalibMaker::slewingTimeOffset(
StETofDigi* aDigi )
2313 if( mDigiSlewCorr.count( key ) ) {
2315 unsigned int totBin = mDigiSlewCorr.at( key )->FindBin( aDigi->
rawTot() );
2317 if( mDigiSlewCorr.at( key )->GetBinEntries( totBin ) <= mMinDigisPerSlewBin && totBin < etofSlewing::nTotBins ) {
2319 LOG_DEBUG <<
"slewingTimeOffset: insufficient statistics for slewing calibration in channel " << key <<
" at tot bin " << totBin <<
" --> return 0" << endm;
2324 float val = mDigiSlewCorr.at( key )->Interpolate( aDigi->
rawTot() );
2326 LOG_DEBUG <<
"slewingTimeOffset: histogram with key " << key <<
" with calib TOT of " << aDigi->
calibTot() <<
" --> interpolated correction: " << val << endm;
2332 LOG_DEBUG <<
"slewingTimeOffset: required histogram with key " << key <<
" doesn't exist -> return 0" << endm;
2344 StETofCalibMaker::applyPulserOffset(
StETofDigi* aDigi )
2348 if( !mPulserTimeDiff.count( key )) {
2352 return mPulserTimeDiff.at( key );
2364 double triggerTime = header->trgGdpbFullTime();
2367 std::map< uint64_t, short > countsGdpbTs;
2368 for(
const auto& kv : header->rocGdpbTs() ) {
2370 LOG_DEBUG <<
"triggerTime (" << std::hex <<
"Ox" << kv.first << std::dec <<
") " << kv.second * eTofConst::coarseClockCycle * 1.e-9 << endm;
2372 ++countsGdpbTs[ kv.second ];
2379 uint64_t mostProbableTriggerTs = 0;
2381 for(
auto it = countsGdpbTs.begin(); it != countsGdpbTs.end(); it++ ) {
2382 auto next = std::next( it, 1 );
2383 auto prev = std::prev( it, 1 );
2385 short countTs = it->second;
2387 if( next != countsGdpbTs.end() && ( next->first - it->first ) == 1 ) {
2388 countTs += next->second;
2390 if( accCount > 0 && ( it->first - prev->first ) == 1 ) {
2391 countTs += prev->second;
2394 if( countTs >= accCount ) {
2397 if( it->second > maxCount ) {
2398 maxCount = it->second;
2399 mostProbableTriggerTs = it->first;
2404 if( mostProbableTriggerTs > 0 ) {
2405 triggerTime = mostProbableTriggerTs * eTofConst::coarseClockCycle;
2409 LOG_DEBUG <<
"trigger TS: " << mostProbableTriggerTs <<
" --> trigger time (ns): " << triggerTime << endm;
2424 std::map< uint64_t, short > countsStarTsRaw;
2425 for(
const auto& kv : header->rocStarTs() ) {
2427 LOG_DEBUG <<
"resetTime (" << std::hex <<
"Ox" << kv.first << std::dec <<
") " << kv.second * eTofConst::coarseClockCycle * 1.e-9 << endm;
2431 if( mRunYear == 2018 && kv.first != 0x18e6 )
continue;
2433 if( kv.second != 0 ) {
2434 ++countsStarTsRaw[ kv.second ];
2440 std::map< uint64_t, short > countsStarTs;
2441 for(
auto it = countsStarTsRaw.begin(); it != countsStarTsRaw.end(); it++ ) {
2442 auto next = std::next( it, 1 );
2444 short countTs = it->second;
2446 if( next != countsStarTsRaw.end() && ( next->first - it->first ) == 1 ) {
2447 countTs += next->second;
2450 countsStarTs[ it->first ] = countTs;
2457 if( countsStarTs.size() == 0 ) {
2458 LOG_INFO <<
"all AFCKs report a reset time value 0" << endm;
2461 for(
const auto& kv : countsStarTs ) {
2462 LOG_DEBUG <<
"resetTime cand:" << kv.first <<
" (" << kv.second <<
" times)" << endm;
2463 mHistograms.at(
"resetTimeCand_times" )->Fill( kv.second );
2466 for(
const auto& kv : header->rocStarTs() ) {
2467 unsigned int sector;
2468 mHwMap->mapToSector( kv.first, sector );
2470 LOG_DEBUG <<
"resetTime(" << sector <<
"): " << kv.second << endm;
2472 std::string histName =
"resetTimeDifferenceToSector" + to_string( sector );
2473 for(
const auto& jv : header->rocStarTs() ) {
2475 mHwMap->mapToSector( jv.first, sec );
2477 mHistograms.at( histName )->Fill( sec, ( int64_t ) jv.second - ( int64_t ) kv.second );
2483 while( countsStarTs.size() > 0 ) {
2484 auto it = std::max_element( countsStarTs.begin(), countsStarTs.end(),
2485 [](
const pair< uint64_t, short >& p1,
const pair< uint64_t, short >& p2 ) {
2486 return p1.second < p2.second; } );
2488 double resetTime = it->first * eTofConst::coarseClockCycle;
2492 if( abs( mResetTs - ( int64_t ) it->first ) < 2 ) {
2493 resetTime = mResetTs * eTofConst::coarseClockCycle;
2496 LOG_INFO <<
"change in reset TS: " << mResetTs <<
" --> " << it->first << endm;
2497 mResetTs = it->first;
2503 if( mTriggerTime - resetTime < 7.2e12 ) {
2505 LOG_DEBUG <<
"reset time (ns): " << resetTime <<
" --> difference to trigger time in seconds: " << ( mTriggerTime - resetTime ) * 1.e-9 << endm;
2507 LOG_DEBUG <<
"--> picked reset TS:" << mResetTs << endm;
2510 mHistograms.at(
"resetTimeCand_picked" )->Fill( it->second );
2512 auto rawIt = std::max_element( countsStarTsRaw.begin(), countsStarTsRaw.end(),
2513 [](
const pair< uint64_t, short >& p1,
const pair< uint64_t, short >& p2 ) {
2514 return p1.second < p2.second; } );
2516 mHistograms.at(
"resetTimeCand_compare" )->Fill( ( int64_t ) mResetTs - ( int64_t ) rawIt->first );
2517 mHistograms.at(
"resetTimeCand_value" )->Fill( mResetTs % (
int ) eTofConst::bTofClockCycle );
2523 countsStarTs.erase( it );
2533 StETofCalibMaker::channelToKey(
const unsigned int channelId ) {
2534 unsigned int sector = ( channelId / eTofConst::nChannelsPerSector ) + eTofConst::sectorStart;
2535 unsigned int zPlane = ( ( channelId % eTofConst::nChannelsPerSector ) / eTofConst::nChannelsPerModule ) + eTofConst::zPlaneStart;
2536 unsigned int counter = ( ( channelId % eTofConst::nChannelsPerModule ) / eTofConst::nChannelsPerCounter ) + eTofConst::counterStart;
2537 unsigned int strip = ( ( channelId % eTofConst::nChannelsPerCounter ) / eTofConst::nSides ) + eTofConst::stripStart;
2538 unsigned int side = ( channelId % eTofConst::nSides ) + eTofConst::sideStart;
2540 return sector * 100000 + zPlane * 10000 + counter * 1000 + strip * 10 + side;
2546 StETofCalibMaker::detectorToKey(
const unsigned int detectorId ) {
2547 unsigned int sector = ( detectorId / eTofConst::nCountersPerSector ) + eTofConst::sectorStart;
2548 unsigned int zPlane = ( ( detectorId % eTofConst::nCountersPerSector ) / eTofConst::nCounters ) + eTofConst::zPlaneStart;
2549 unsigned int counter = ( detectorId % eTofConst::nCounters ) + eTofConst::counterStart;
2551 return sector * 100 + zPlane * 10 + counter;
2557 StETofCalibMaker::sideToKey(
const unsigned int sideId ) {
2558 unsigned int sector = ( sideId / ( eTofConst::nCountersPerSector * eTofConst::nSides ) ) + eTofConst::sectorStart;
2559 unsigned int zPlane = ( ( sideId % ( eTofConst::nCountersPerSector * eTofConst::nSides ) ) / ( eTofConst::nCounters * eTofConst::nSides ) ) + eTofConst::zPlaneStart;
2560 unsigned int counter = ( ( sideId % ( eTofConst::nCounters * eTofConst::nSides ) ) / eTofConst::nSides ) + eTofConst::counterStart;
2561 unsigned int side = ( sideId % eTofConst::nSides ) + eTofConst::sideStart;
2563 return sector * 1000 + zPlane * 100 + counter * 10 + side;
2572 StETofCalibMaker::setHistFileName()
2574 string extension =
".etofCalib.root";
2576 if( GetChainOpt()->GetFileOut() !=
nullptr ) {
2577 TString outFile = GetChainOpt()->GetFileOut();
2579 mHistFileName = ( string ) outFile;
2582 size_t lastindex = mHistFileName.find_last_of(
"." );
2583 mHistFileName = mHistFileName.substr( 0, lastindex );
2586 lastindex = mHistFileName.find_last_of(
"." );
2587 mHistFileName = mHistFileName.substr( 0, lastindex );
2590 lastindex = mHistFileName.find_last_of(
"/" );
2591 mHistFileName = mHistFileName.substr( lastindex + 1, mHistFileName.length() );
2593 mHistFileName = mHistFileName + extension;
2595 LOG_ERROR <<
"Cannot set the output filename for histograms" << endm;
2601 StETofCalibMaker::bookHistograms()
2603 LOG_INFO <<
"bookHistograms() ... " << endm;
2605 mHistograms[
"pulserDigiTimeDiff_GbtxCorrProf" ] =
new TProfile(
"pulserDigiTimeDiff_GbtxCorrProf",
"time difference of pulsers to reference;pulser channel;#Delta T (ns)", 216, 0, 216,
"s" );
2606 mHistograms[
"pulserDigiTimeDiff_GbtxCorrProfMod" ] =
new TProfile(
"pulserDigiTimeDiff_GbtxCorrProfMod",
"time difference of pulsers to reference;pulser channel;#Delta T (ns)", 216, 0, 216,
"s" );
2607 mHistograms[
"pulserDigiTimeDiff_fullCorr" ] =
new TH2F(
"pulserDigiTimeDiff_fullCorr",
"time difference of pulsers to reference;pulser channel;#Delta T (ns)", 216, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2608 mHistograms[
"pulserDigiTimeDiff_RefCorr" ] =
new TH1F(
"pulserDigiTimeDiff_RefCorr",
"time difference of pulsers to reference; #Delta T (ns)", 45, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ));
2611 mHistograms[
"pulserDigiTimeDiff" ] =
new TH2F(
"pulserDigiTimeDiff",
"time difference of pulsers to reference;pulser channel;#Delta T (ns)", 216, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2612 mHistograms[
"pulserDigiTimeToCounter1" ] =
new TH2F(
"pulserDigiTimeToCounter1",
"time difference of pulsers to counter 1;pulser channel;#Delta T (ns)", 216, 0, 216, 2*360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2613 mHistograms[
"pulserDigiTimeToCounter2" ] =
new TH2F(
"pulserDigiTimeToCounter2",
"time difference of pulsers to counter 2;pulser channel;#Delta T (ns)", 216, 0, 216, 2*360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2614 mHistograms[
"pulserDigiTimeToCounter3" ] =
new TH2F(
"pulserDigiTimeToCounter3",
"time difference of pulsers to counter 3;pulser channel;#Delta T (ns)", 216, 0, 216, 2*360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2616 mHistograms[
"pulserDigiTimeDiff_GbtxCorr" ] =
new TH2F(
"pulserDigiTimeDiff_GbtxCorr",
"time difference of pulsers to reference;pulser channel;#Delta T (ns)", 216, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2617 mHistograms[
"pulserDigiTimeDiff_perGbtx" ] =
new TH2F(
"pulserDigiTimeDiff_perGbtx",
"average time difference of pulsers in one Gbtx to reference;pulser channel;#Delta T (ns)", 216/3, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2618 mHistograms[
"pulserDigiTimeDiff_toAverage" ] =
new TH2F(
"pulserDigiTimeDiff_toAverage",
"time difference of pulsers to reference;pulser channel;#Delta T (ns)", 216, 0, 216, 4*360, -359.5 * ( 6.25 / 112 ), 360.5 * ( 6.25 / 112 ) );
2620 mHistograms[
"1_off" ] =
new TH2F(
"1_off",
"average time difference of pulsers in one Gbtx to reference;pulser channel;#Delta T (ns)", 216/3, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2621 mHistograms[
"2_off" ] =
new TH2F(
"2_off",
"average time difference of pulsers in one Gbtx to reference;pulser channel;#Delta T (ns)", 216/3, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2622 mHistograms[
"3_off" ] =
new TH2F(
"3_off",
"average time difference of pulsers in one Gbtx to reference;pulser channel;#Delta T (ns)", 216/3, 0, 216, 360, -179.5 * ( 6.25 / 112 ), 180.5 * ( 6.25 / 112 ) );
2624 mHistograms[
"pulserDigiTimeDiff_CorrAgreement" ] =
new TH1F(
"pulserDigiTimeDiff_CorrAgreement",
"Number of pulsers agreeing on a common shift between events; #pulsers", 218, -0.5, 217.5);
2625 mHistograms[
"pulserDigiTimeDiff_CorrCommonJump" ] =
new TH1F(
"pulserDigiTimeDiff_CorrCommonJump",
"Number of pulsers jumping at the same time between events; #pulsers", 218, -0.5, 217.5);
2626 mHistograms[
"pulserDigiPresence" ] =
new TH1F(
"pulserDigiPresence",
"pulser presence (number of events at ( -1 );pulser channel", 218, -1.5, 216.5);
2628 for(
int i=0; i<12; i++ ) {
2629 std::string histName =
"resetTimeDifferenceToSector" + to_string( i + 13 );
2630 mHistograms[ histName ] =
new TH2F( Form(
"resetTimeDifferenceToSector%d", i + 13 ), Form(
"reset time difference to sector %d;sector;#DeltaT (clock ticks)", i + 13 ), 12, 12.5, 24.4, 5, -2.5, 2.5 );
2632 mHistograms[
"ETOF_QA_daqMissmatches_get4" ] =
new TProfile(
"ETOF_QA_daqMissmatches_get4",
"missmatch percentage for each get4; get4 []; missmatch percentage", 1728, 0.5, 1728.5 );
2633 mHistograms[
"ETOF_QA_daqMissmatches_counter" ] =
new TProfile(
"ETOF_QA_daqMissmatches_counter",
"missmatch percentage for each counter; counter []; missmatch percentage", 108, 0.5, 108.5 );
2634 mHistograms[
"resetTimeCand_times" ] =
new TH1F(
"resetTimeCand_times",
"sectors agreeing on reset time candidates;# sectors with common candidate;# events", 12, 0.5, 12.5 );
2635 mHistograms[
"resetTimeCand_picked" ] =
new TH1F(
"resetTimeCand_picked",
"sectors agreeing on picked reset time;# sectors with picked reset time;# events", 12, 0.5, 12.5 );
2636 mHistograms[
"resetTimeCand_compare" ] =
new TH1F(
"resetTimeCand_compare",
"difference between old and new way;#DeltaT (clock ticks);# events", 5, -2.5, 2.5 );
2637 mHistograms[
"resetTimeCand_value" ] =
new TH1F(
"resetTimeCand_value",
"picked reset time value;clock ticks;# events", (
int ) eTofConst::bTofClockCycle, 0.5, 0.5 + eTofConst::bTofClockCycle );
2640 for (
auto& kv : mHistograms ) {
2641 kv.second->SetDirectory( 0 );
2647 StETofCalibMaker::writeHistograms()
2649 if( mHistFileName !=
"" ) {
2650 LOG_INFO <<
"writing histograms to: " << mHistFileName.c_str() << endm;
2652 TFile histFile( mHistFileName.c_str(),
"RECREATE",
"etofCalib" );
2655 for(
int i=0; i<12; i++ ) {
2656 std::string histName =
"resetTimeDifferenceToSector" + to_string( i + 13 );
2657 mHistograms.at( histName )->Scale( 12. / mHistograms.at( histName )->GetEntries() );
2660 for (
const auto& kv : mHistograms ) {
2661 if( kv.second->GetEntries() > 0 ) kv.second->Write();
2667 LOG_INFO <<
"histogram file name is empty string --> cannot write histograms" << endm;
2673 void StETofCalibMaker::readGet4State(
int fileNr,
short forward){
2675 bool fileZero =
false;
2678 for(
int i =0; i< eTofConst::nGet4sInSystem; i++){
2679 mStateVec[i].clear();
2680 mStartVec[i].clear();
2681 mGet4StateMap[i] = 0;
2686 mMasterStartVec.clear();
2687 mMasterStartVec.resize(0);
2689 std::vector< unsigned long int > intVec;
2692 if(forward == 0) mGlobalCounter = 1;
2694 else if(forward > 0) mGlobalCounter++;
2696 else mGlobalCounter--;
2698 if(mGlobalCounter == 0){
2703 if(mFileNameGet4State.empty()){
2705 TDataSet* dbDataSet = GetDataBase(
"Calibrations/etof/etofGet4State" );
2707 LOG_ERROR <<
"unable to get the get4 state map database" << endm;
2710 const int intsPerEntry = 1000000;
2712 St_etofGet4State* etofStateMap =
static_cast< St_etofGet4State*
> ( dbDataSet->
Find(
"etofGet4State" ) );
2713 if( !etofStateMap ) {
2714 LOG_ERROR <<
"unable to get the get4 state map from the database" << endm;
2718 etofGet4State_st* stateMapTable = etofStateMap->GetTable();
2720 for(
size_t i=0; i< intsPerEntry; i++ ) {
2721 if(stateMapTable->etofGet4State[ i ] <= 0)
break;
2722 intVec.push_back( stateMapTable->etofGet4State[ i ]);
2727 std::ifstream paramFile;
2729 paramFile.open( mFileNameGet4State.c_str() );
2731 if( !paramFile.is_open() ) {
2732 LOG_ERROR <<
"unable to get the 'Get4State' parameters from file --> file does not exist" << endm;
2736 unsigned long int temp;
2737 while( paramFile >> temp ) {
2738 intVec.push_back( temp );
2742 std::vector<unsigned long int> startVec;
2743 std::map<unsigned long int,vector<int>> stateVec;
2744 std::map<unsigned long int ,vector<int>> get4IdVec;
2746 decodeInt(intVec , mGet4StateMap , mGet4ZeroStateMap , startVec , mMasterStartVec , stateVec , get4IdVec);
2749 for(
int i = 0; i< eTofConst::nGet4sInSystem;i++){
2751 for(
unsigned int j=0; j< startVec.size(); j++){
2753 unsigned long int key = startVec.at(j);
2755 for(
unsigned int n =0; n < get4IdVec.at(key).size(); n++){
2758 if(i == get4IdVec.at(key).at(n)){
2759 mStateVec[i].push_back(stateVec.at(key).at(n));
2760 mStartVec[i].push_back(startVec.at(j));
2767 mStateMapStart = 0 ;
2768 mStateMapStop = startVec.at(0);
2769 mDbEntryStart = startVec.at(0);
2770 mDbEntryStop = startVec.at((startVec.size()-1));
2777 sort( mMasterStartVec.begin(), mMasterStartVec.end() );
2778 mMasterStartVec.erase( unique( mMasterStartVec.begin(), mMasterStartVec.end() ), mMasterStartVec.end() );
2784 void StETofCalibMaker::checkGet4State(
unsigned long int eventNr){
2786 if(eventNr >= mStateMapStart && eventNr < mStateMapStop) {
2790 unsigned long int closestStop = 99999999;
2791 unsigned long int closestStart = 0;
2795 for(
unsigned int i =0; i< eTofConst::nGet4sInSystem; i++){
2797 std::vector<unsigned long int> tmpStart = mStartVec[i];
2798 std::vector<short> tmpState = mStateVec[i];
2801 unsigned int indexStart = 0;
2804 if (tmpStart.empty())
continue;
2806 auto lower = std::lower_bound(tmpStart.begin(), tmpStart.end(), eventNr);
2807 indexStart = std::distance(tmpStart.begin(), lower);
2808 if(indexStart > 0) indexStart--;
2811 if(eventNr > tmpStart.at((tmpStart.size() -1))){
2812 indexStart = (tmpStart.size() -1);
2816 if((indexStart < (tmpStart.size() -1 )) && eventNr == tmpStart.at(indexStart + 1)){
2821 newState = tmpState.at(indexStart);
2823 if(tmpStart.at(indexStart) > eventNr ) newState = mGet4ZeroStateMap[i];
2825 mGet4StateMap[i] = newState;
2830 for(
unsigned int z=0; z< mMasterStartVec.size();z++){
2834 closestStop = mMasterStartVec.at(z);
2836 }
else if(z == (mMasterStartVec.size()-1)){
2837 closestStart = mMasterStartVec.at(z);
2838 closestStop = 99999999;
2841 }
else if(eventNr == mMasterStartVec.at(z) ||
2842 (eventNr < mMasterStartVec.at(z+1) && eventNr > mMasterStartVec.at(z))){
2843 closestStart = mMasterStartVec.at(z);
2844 closestStop = mMasterStartVec.at(z+1);
2851 mStateMapStart = closestStart;
2852 mStateMapStop = closestStop;
2854 if(mStateMapStart == mDbEntryStop) {
2856 mStateMapStop = 99999999;
2861 void StETofCalibMaker::decodeInt( std::vector<unsigned long int> intVec ,std::map<int , short>& mGet4StateMap ,std::map<int , short>& mGet4ZeroStateMap ,std::vector<unsigned long int>& startVec ,std::vector<unsigned long int>& mMasterStartVec ,std::map<
unsigned long int,vector<int>>& stateVec ,std::map<
unsigned long int,vector<int>>& get4IdVec){
2863 unsigned long int lastEvtId =0;
2865 for(
unsigned int i = 0; i < intVec.size(); i++){
2870 unsigned long int EvtId;
2877 switch (intVec.at(i) / 100000000) {
2880 tmp = intVec.at(i) % 4200000000;
2881 stateInt1 = tmp / 10000;
2882 stateInt2 = tmp % 10000;
2889 if(stateInt1 < 6912){
2890 Get4Id1 = stateInt1 % eTofConst::nGet4sInSystem;
2891 get4state1 = stateInt1 / eTofConst::nGet4sInSystem;
2893 if(stateInt2 < 6912){
2894 Get4Id2 = stateInt2 % eTofConst::nGet4sInSystem;
2895 get4state2 = stateInt2 / eTofConst::nGet4sInSystem;
2899 mGet4StateMap[Get4Id1] = get4state1;
2900 mGet4StateMap[Get4Id2] = get4state2;
2901 mGet4ZeroStateMap[Get4Id1] = get4state1;
2902 mGet4ZeroStateMap[Get4Id2] = get4state2;
2904 stateVec[lastEvtId].push_back(get4state1);
2905 get4IdVec[lastEvtId].push_back(Get4Id1);
2906 stateVec[lastEvtId].push_back(get4state2);
2907 get4IdVec[lastEvtId].push_back(Get4Id2);
2914 EvtId = intVec.at(i) % 4000000000;
2916 startVec.push_back(EvtId);
2917 mMasterStartVec.push_back(EvtId);
2926 tmp = intVec.at(i) % 4100000000;
2927 stateInt1 = tmp / 10000;
2931 if(stateInt1 < 6912) {
2932 Get4Id1 = stateInt1 % eTofConst::nGet4sInSystem;
2933 get4state1 = stateInt1 / eTofConst::nGet4sInSystem;
2936 stateVec[lastEvtId].push_back(get4state1);
2937 get4IdVec[lastEvtId].push_back(Get4Id1);
2942 LOG_ERROR <<
"Get4 state not well defined -> Check db / state file !" << endm;
unsigned int sector() const
Sector.
double calibTime() const
calibrated time
unsigned int zPlane() const
ZPlane.
static StMuETofHeader * etofHeader()
returns pointer to the StMuETofHeader
unsigned int side() const
Side.
unsigned int strip() const
Strip.
double rawTot() const
Getter for uncalibrated Tot.
unsigned int sector() const
Sector.
unsigned int zPlane() const
ZPlane.
unsigned int strip() const
Strip.
double rawTime() const
Raw Time.
double rawTot() const
Getter for uncalibrated Tot.
static TClonesArray * etofArray(int type)
returns pointer to the n-th TClonesArray from the etof arrays // FS
static StMuETofDigi * etofDigi(int i)
returns pointer to the i-th StMuEtofDigi
unsigned int elChan() const
electronic Channel.
unsigned int get4Id() const
get4Id.
unsigned int counter() const
Counter.
void setGeoAddress(const unsigned int iSector, const unsigned int iZPlane, const unsigned int iCounter, const unsigned int iChannel, const unsigned int iSide)
double calibTot() const
Getter for calibrated Tot.
unsigned int rocId() const
RocId.
unsigned int side() const
Side.
StETofCalibMaker(const char *name="etofCalib")
default constructor
unsigned int counter() const
Counter.
void setGeoAddress(const unsigned int iSector, const unsigned int iZPlane, const unsigned int iCounter, const unsigned int iChannel, const unsigned int iSide)
virtual TDataSet * Find(const char *path) const
double rawTime() const
Raw Time.