diff --git a/fles/mcbm2018/CMakeLists.txt b/fles/mcbm2018/CMakeLists.txt index dd306e6d230d303f655a555b4b6efd4458b74e7b..dff4b9109ce51418ac69edc628dc4756ab95294b 100644 --- a/fles/mcbm2018/CMakeLists.txt +++ b/fles/mcbm2018/CMakeLists.txt @@ -126,6 +126,9 @@ Set(SRCS tasks/CbmMcbm2019CheckTimingPairs.cxx tasks/CbmMcbm2019TimeWinEventBuilderAlgo.cxx tasks/CbmMcbm2019TimeWinEventBuilderTask.cxx + + tasks/CbmMcbmCheckTimingAlgo.cxx + tasks/CbmMcbmCheckTimingTask.cxx ) If(_UINT8_T_EXIST) diff --git a/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h b/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h index f346414b765fa0f65b3582c8f1aabf0f56fced30..4090bac6908c43ca728b93662f8d57a2781bf299 100644 --- a/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h +++ b/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h @@ -73,4 +73,7 @@ #pragma link C++ class CbmMcbm2019TimeWinEventBuilderAlgo + ; #pragma link C++ class CbmMcbm2019TimeWinEventBuilderTask + ; +#pragma link C++ class CbmMcbmCheckTimingAlgo+; +#pragma link C++ class CbmMcbmCheckTimingTask+; + #endif diff --git a/fles/mcbm2018/tasks/CbmMcbmCheckTimingAlgo.cxx b/fles/mcbm2018/tasks/CbmMcbmCheckTimingAlgo.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b55fd46e24fe37f76febb123ede2172929c3072f --- /dev/null +++ b/fles/mcbm2018/tasks/CbmMcbmCheckTimingAlgo.cxx @@ -0,0 +1,527 @@ +/******************************************************************************** + * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ +#include "CbmMcbmCheckTimingAlgo.h" + +#include "CbmDigiManager.h" +#include "CbmStsDigi.h" +#include "CbmMuchBeamTimeDigi.h" +#include "CbmRichDigi.h" +#include "CbmTrdDigi.h" +#include "CbmTofDigi.h" +#include "CbmPsdDigi.h" +#include "CbmFlesHistosTools.h" + +#include "FairLogger.h" +#include "FairRootManager.h" +#include "FairRunOnline.h" + +#include "TH1.h" +#include "TH2.h" +#include "THttpServer.h" +#include <TFile.h> + +#include <iomanip> +#include <iostream> +using std::fixed; +using std::setprecision; + +// ---- Default constructor ------------------------------------------- +CbmMcbmCheckTimingAlgo::CbmMcbmCheckTimingAlgo() +{ +} + +// ---- Destructor ---------------------------------------------------- +CbmMcbmCheckTimingAlgo::~CbmMcbmCheckTimingAlgo() +{ +} + +// ---- Initialisation ---------------------------------------------- +void CbmMcbmCheckTimingAlgo::SetParContainers() +{ + // Load all necessary parameter containers from the runtime data base + /* + FairRunAna* ana = FairRunAna::Instance(); + FairRuntimeDb* rtdb=ana->GetRuntimeDb(); + + <CbmMcbmCheckTimingAlgoDataMember> = (<ClassPointer>*) + (rtdb->getContainer("<ContainerName>")); + */ +} + +// ---- Init ---------------------------------------------------------- +Bool_t CbmMcbmCheckTimingAlgo::Init() +{ + /// Check if all required data input storage are present + /// Reference detector + CheckDataPresence( fRefDet ); + /// Checked detectors + for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + { + CheckDataPresence( *det ); + } // for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + + CreateHistos(); + + return kTRUE; +} + +void CbmMcbmCheckTimingAlgo::CheckDataPresence( CheckTimingDetector detToCheck ) +{ + // Get a handle from the IO manager + FairRootManager* ioman = FairRootManager::Instance(); + fDigiMan = CbmDigiManager::Instance(); + fDigiMan->UseMuchBeamTimeDigi(); + fDigiMan->Init(); + + /// Handle special case for T0 as not yet supported in DigiManager + if( ECbmModuleId::kT0 == detToCheck.detId ) + { + // Get a pointer to the previous already existing data level + fpT0DigiVec = ioman->InitObjectAs< std::vector< CbmTofDigi > const * >( "T0Digi" ); + if ( ! fpT0DigiVec ) + { + LOG( fatal ) << "No storage with T0 digis found while it should be used. Stopping there!"; + } // if ( ! fpT0DigiVec ) + } // if( ECbmModuleId::kT0 == detToCheck.detId ) + else if ( ! fDigiMan->IsPresent( detToCheck.detId ) ) + { + LOG( fatal ) << "No " << detToCheck.sName << " digis found while it should be used. Stopping there!"; + } // else if ( ! fDigiMan->IsPresent( detToCheck.detId ) ) of if( ECbmModuleId::kT0 == detToCheck.detId ) +} + +void CbmMcbmCheckTimingAlgo::CreateHistos() +{ + /// Logarithmic bining for self time comparison + uint32_t iNbBinsLog = 0; + /// Parameters are NbDecadesLog, NbStepsDecade, NbSubStepsInStep + std::vector<double> dBinsLogVector = GenerateLogBinArray( 9, 9, 1, iNbBinsLog ); + double* dBinsLog = dBinsLogVector.data(); + + for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + { + fvhDetSelfDiff.push_back( new TH1D( Form( "h%sSelfDiff", (*det).sName.data() ), + Form( "time difference between consecutivs %s Digis;time diff [ns];Counts", + (*det).sName.data() ), + iNbBinsLog, dBinsLog ) + ); + + fvhDetToRefDiff.push_back( new TH1D( Form( "h%s%sDiff", (*det).sName.data(), fRefDet.sName.data() ), + Form( "%s - %s time difference;time diff [ns];Counts", + (*det).sName.data(), fRefDet.sName.data() ), + (*det).uRangeNbBins, (*det).dTimeRangeBeg, (*det).dTimeRangeEnd ) + ); + + fvhDetToRefDiffRefCharge.push_back( new TH2F( Form( "h%s%sDiffRefCharge", (*det).sName.data(), fRefDet.sName.data() ), + Form( "%s - %s;time diff [ns]; %s Charge [a.u]; Counts", + (*det).sName.data(), fRefDet.sName.data(), fRefDet.sName.data() ), + (*det).uRangeNbBins, (*det).dTimeRangeBeg, (*det).dTimeRangeEnd, + 256, 0, 256 ) + ); + fvhDetToRefDiffDetCharge.push_back( new TH2F( Form( "h%s%sDiffDetCharge", (*det).sName.data(), fRefDet.sName.data() ), + Form( "%s - %s;time diff [ns]; %s Charge [a.u]; Counts", + (*det).sName.data(), fRefDet.sName.data(), (*det).sName.data() ), + (*det).uRangeNbBins, (*det).dTimeRangeBeg, (*det).dTimeRangeEnd, + 256, 0, 256 ) + ); + fvhDetToRefDiffEvo.push_back( new TH2F( Form( "h%s%sDiffEvo", (*det).sName.data(), fRefDet.sName.data() ), + Form( "%s - %s;TS; time diff [ns];Counts", + (*det).sName.data(), fRefDet.sName.data() ), + 1000, 0, 10000, + (*det).uRangeNbBins, (*det).dTimeRangeBeg, (*det).dTimeRangeEnd ) + ); + fvhDetToRefDiffEvoLong.push_back( new TH2F( Form( "h%s%sDiffEvoLong", (*det).sName.data(), fRefDet.sName.data() ), + Form( "%s - %s;TS; time diff [ns];Counts", + (*det).sName.data(), fRefDet.sName.data() ), + 1800, 0, 18000, + (*det).uRangeNbBins, (*det).dTimeRangeBeg, (*det).dTimeRangeEnd ) + ); + } // for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + + /// Add reference detector digi to digi time difference histo at end of vector + fvhDetSelfDiff.push_back( new TH1D( Form( "h%sSelfDiff", fRefDet.sName.data() ), + Form( "time difference between consecutivs %s Digis;time diff [ns];Counts", + fRefDet.sName.data() ), + iNbBinsLog, dBinsLog ) + ); + + /// Register the histos in the HTTP server + FairRunOnline* run = FairRunOnline::Instance(); + if( run ) + { + THttpServer* server = run->GetHttpServer(); + if( nullptr != server ) + { + /// Register histos for all checked detectors + for( UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx ) + { + server->Register("/CheckTiming/SelfDiff", fvhDetSelfDiff[ uDetIdx ] ); + server->Register("/CheckTiming/RefDiff", fvhDetToRefDiff[ uDetIdx ] ); + server->Register("/CheckTiming/DiffCharge", fvhDetToRefDiffRefCharge[ uDetIdx ] ); + server->Register("/CheckTiming/DiffCharge", fvhDetToRefDiffDetCharge[ uDetIdx ] ); + server->Register("/CheckTiming/DiffEvo", fvhDetToRefDiffEvo[ uDetIdx ] ); + server->Register("/CheckTiming/DiffEvo", fvhDetToRefDiffEvoLong[ uDetIdx ] ); + } // for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + + /// Register the histo for reference detector digi to digi time difference + server->Register("/CheckTiming/SelfDiff", fvhDetSelfDiff[ fvDets.size() ] ); + } // if( nullptr != server ) + } // if( run ) +} +// ---- ReInit ------------------------------------------------------- +Bool_t CbmMcbmCheckTimingAlgo::ReInit() +{ + return kTRUE; +} + +// ---- Exec ---------------------------------------------------------- +void CbmMcbmCheckTimingAlgo::ProcessTs() +{ + LOG(debug) << "executing TS " << fuNbTs; + + switch( fRefDet.detId ) + { + case ECbmModuleId::kSts: + { + CheckInterSystemOffset< CbmStsDigi >(); + break; + } // case ECbmModuleId::kSts: + case ECbmModuleId::kMuch: + { + CheckInterSystemOffset< CbmMuchBeamTimeDigi >(); + break; + } // case ECbmModuleId::kMuch: + case ECbmModuleId::kTrd: + { + CheckInterSystemOffset< CbmTrdDigi >(); + break; + } // case ECbmModuleId::kTrd: + case ECbmModuleId::kTof: + { + CheckInterSystemOffset< CbmTofDigi >(); + break; + } // case ECbmModuleId::kTof: + case ECbmModuleId::kRich: + { + CheckInterSystemOffset< CbmRichDigi >(); + break; + } // case ECbmModuleId::kRich: + case ECbmModuleId::kPsd: + { + CheckInterSystemOffset< CbmPsdDigi >(); + break; + } // case ECbmModuleId::kPsd: + case ECbmModuleId::kT0: + { + CheckInterSystemOffset< CbmTofDigi >(); + break; + } // case ECbmModuleId::kT0: + default: + { + LOG( fatal ) << "CbmMcbm2019TimeWinEventBuilderAlgo::LoopOnSeeds => " + << "Trying to search matches with unsupported det: " + << fRefDet.sName; + break; + } // default: + } // switch( fRefDet ) + + fuNbTs++; +} + +template <class DigiRef > +void CbmMcbmCheckTimingAlgo::CheckInterSystemOffset() +{ + UInt_t uNbRefDigis = 0; + switch( fRefDet.detId ) + { + case ECbmModuleId::kNotExist: + { + LOG( fatal ) << "CbmMcbmCheckTimingAlgo::Exec => Unknow reference detector enum! " + << fRefDet.sName; + break; + } // Digi containers controlled by DigiManager + case ECbmModuleId::kT0: + { + uNbRefDigis = fpT0DigiVec->size(); + break; + } // case ECbmModuleId::kT0 + default: + { + uNbRefDigis = fDigiMan->GetNofDigis( fRefDet.detId ); + break; + } // default: + } // switch( fRefDet.detId ) + + /// Re-initialize array references + for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + { + (*det).iPrevRefFirstDigi = 0; + } // for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + + for( UInt_t uDigi = 0; uDigi < uNbRefDigis; ++uDigi ) + { + LOG( debug ) << Form( "Checking seed %6u / %6u", uDigi, uNbRefDigis ); + + Double_t dRefTime = 0; + Double_t dRefCharge = 0; + if( ECbmModuleId::kT0 == fRefDet.detId ) + { + dRefTime = fpT0DigiVec->at( uDigi ).GetTime(); + dRefCharge = fpT0DigiVec->at( uDigi ).GetCharge(); + } // if( ECbmModuleId::kT0 == fRefDet.detId ) + else + { + dRefTime = fDigiMan->Get< DigiRef >( uDigi )->GetTime() ; + dRefCharge = fDigiMan->Get< DigiRef >( uDigi )->GetCharge(); + } // else of if( ECbmModuleId::kT0 == fRefDet.detId ) + + /// Fill self time difference histo + fvhDetSelfDiff[ fvDets.size() ]->Fill( dRefTime - fRefDet.dPrevTime ); + fRefDet.dPrevTime = dRefTime; + + /// Charge cut if defined! + if( fRefDet.uChargeCutMin != fRefDet.uChargeCutMax ) + { + if( fRefDet.uChargeCutMin < fRefDet.uChargeCutMax ) + { + /// Cut charges between Min and Max to reject pulser + if( fRefDet.uChargeCutMin < dRefCharge && dRefCharge < fRefDet.uChargeCutMax ) + { + continue; + } // if( fRefDet.uChargeCutMin < dRefCharge && dRefCharge < fRefDet.uChargeCutMax ) + } // if( fRefDet.uChargeCutMin < fRefDet.uChargeCutMax ) + else + { + /// Select charges between Max and Min to select pulser (Min and Max swapped!!) + if( fRefDet.uChargeCutMin < dRefCharge || dRefCharge < fRefDet.uChargeCutMax ) + { + continue; + } // if( fRefDet.uChargeCutMin < dRefCharge || dRefCharge < fRefDet.uChargeCutMax ) + } // else of if( fRefDet.uChargeCutMin < fRefDet.uChargeCutMax ) + } // if( fRefDet.uChargeCutMin =! fRefDet.uChargeCutMax ) + + /// Fill time difference for each check detector defined in list + for( UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx ) + { + switch( fvDets[ uDetIdx ].detId ) + { + case ECbmModuleId::kSts: + { + FillTimeOffsetHistos< CbmStsDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kSts: + case ECbmModuleId::kMuch: + { + FillTimeOffsetHistos< CbmMuchBeamTimeDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kMuch: + case ECbmModuleId::kTrd: + { + FillTimeOffsetHistos< CbmTrdDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kTrd: + case ECbmModuleId::kTof: + { + FillTimeOffsetHistos< CbmTofDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kTof: + case ECbmModuleId::kRich: + { + FillTimeOffsetHistos< CbmRichDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kRich: + case ECbmModuleId::kPsd: + { + FillTimeOffsetHistos< CbmPsdDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kPsd: + case ECbmModuleId::kT0: + { + FillTimeOffsetHistos< CbmTofDigi >( dRefTime, dRefCharge, uDetIdx ); + break; + } // case ECbmModuleId::kT0: + default: + { + LOG( fatal ) << "CbmMcbmCheckTimingAlgo::CheckInterSystemOffset => " + << "Trying to search matches with unsupported det: " + << fvDets[ uDetIdx ].sName; + break; + } // default: + } // switch( fvDets[ uDetIdx ].detId ) + } // for( UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx ) + } // for( UInt_t uDigi = 0; uDigi < uNbRefDigis; ++uDigi ) +} + +template <class Digi> +void CbmMcbmCheckTimingAlgo::FillTimeOffsetHistos( const Double_t dRefTime, + const Double_t dRefCharge, + UInt_t uDetIdx ) +{ + UInt_t uNbDigis = fDigiMan->GetNofDigis( fvDets[ uDetIdx ].detId ); + UInt_t uFirstDigiInWin = fvDets[ uDetIdx ].iPrevRefFirstDigi; + + for( UInt_t uDigiIdx = fvDets[ uDetIdx ].iPrevRefFirstDigi; uDigiIdx < uNbDigis; ++uDigiIdx ) + { + Double_t dTime = 0; + Double_t dCharge = 0; + if( ECbmModuleId::kT0 == fvDets[ uDetIdx ].detId ) + { + dTime = fpT0DigiVec->at( uDigiIdx ).GetTime(); + dCharge = fpT0DigiVec->at( uDigiIdx ).GetCharge(); + } // if( ECbmModuleId::kT0 == fRefDet.detId ) + else + { + dTime = fDigiMan->Get< Digi >( uDigiIdx )->GetTime() ; + dCharge = fDigiMan->Get< Digi >( uDigiIdx )->GetCharge(); + } // else of if( ECbmModuleId::kT0 == fRefDet.detId ) + + /// Fill self correlation histo while avoiding double counting due to + /// the "smart looping" + if( fvDets[ uDetIdx ].dPrevTime <= dTime ) + { + fvhDetSelfDiff[ uDetIdx ]->Fill( dTime - fvDets[ uDetIdx ].dPrevTime ); + fvDets[ uDetIdx ].dPrevTime = dTime; + } // if( fvDets[ uDetIdx ].dPrevTime < dTime ) + + Double_t dDiffTime = dTime - dRefTime; + + if( dDiffTime < fvDets[ uDetIdx ].dTimeRangeBeg ) + { + ++ uFirstDigiInWin; // Update Index of first digi in Win to next digi + continue; // not yet in interesting range + } // if (diffTime > offsetRange) + if( fvDets[ uDetIdx ].dTimeRangeEnd < dDiffTime ) + { + /// already past interesting range + break; + } // if( fvDets[ uDetIdx ].dTimeRangeEnd < dDiffTime ) + + /// Charge cut if defined! + if( fvDets[ uDetIdx ].uChargeCutMin != fvDets[ uDetIdx ].uChargeCutMax ) + { + if( fvDets[ uDetIdx ].uChargeCutMin < fvDets[ uDetIdx ].uChargeCutMax ) + { + /// Cut charges between Min and Max to reject pulser + if( fvDets[ uDetIdx ].uChargeCutMin < dCharge && dCharge < fvDets[ uDetIdx ].uChargeCutMax ) + { + continue; + } // if( fvDets[ uDetIdx ].uChargeCutMin < dCharge && dCharge < fvDets[ uDetIdx ].uChargeCutMax ) + } // if( fvDets[ uDetIdx ].uChargeCutMin < fvDets[ uDetIdx ].uChargeCutMax ) + else + { + /// Select charges between Max and Min to select pulser (Min and Max swapped!!) + if( fvDets[ uDetIdx ].uChargeCutMin < dCharge || dCharge < fvDets[ uDetIdx ].uChargeCutMax ) + { + continue; + } // if( fvDets[ uDetIdx ].uChargeCutMin < dCharge || dCharge < fvDets[ uDetIdx ].uChargeCutMax ) + } // else of if( fvDets[ uDetIdx ].uChargeCutMin < fvDets[ uDetIdx ].uChargeCutMax ) + } // if( fvDets[ uDetIdx ].uChargeCutMin != fvDets[ uDetIdx ].uChargeCutMax ) + + /// Fill histos + fvhDetToRefDiff[ uDetIdx ]->Fill( dDiffTime ); + fvhDetToRefDiffRefCharge[ uDetIdx ]->Fill( dRefCharge, dDiffTime ); + fvhDetToRefDiffDetCharge[ uDetIdx ]->Fill( dCharge, dDiffTime ); + fvhDetToRefDiffEvo[ uDetIdx ]->Fill( fuNbTs, dDiffTime ); + fvhDetToRefDiffEvoLong[ uDetIdx ]->Fill( fuNbTs, dDiffTime ); + } // for( UInt_t uDigiIdx = fvDets[ uDetIdx ].iPrevRefFirstDigi; uDigiIdx < uNbDigis; ++uDigiIdx ) + + /// Store earliest possible starting index for next reference digi (time sorted!) + fvDets[ uDetIdx ].iPrevRefFirstDigi = uFirstDigiInWin; +} + +// ---- Finish -------------------------------------------------------- +void CbmMcbmCheckTimingAlgo::Finish() +{ + LOG(info) << Form( "Checked %6d Timeslices", fuNbTs); +} + +void CbmMcbmCheckTimingAlgo::WriteHistos() +{ + TFile* old = gFile; + TFile* outfile = TFile::Open(fOutFileName,"RECREATE"); + + for( UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx ) + { + fvhDetSelfDiff[ uDetIdx ]->Write(); + fvhDetToRefDiff[ uDetIdx ]->Write(); + fvhDetToRefDiffRefCharge[ uDetIdx ]->Write(); + fvhDetToRefDiffDetCharge[ uDetIdx ]->Write(); + fvhDetToRefDiffEvo[ uDetIdx ]->Write(); + fvhDetToRefDiffEvoLong[ uDetIdx ]->Write(); + } // for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + + /// Register the histo for reference detector digi to digi time difference + fvhDetSelfDiff[ fvDets.size() ]->Write(); + + outfile->Close(); + delete outfile; + + gFile = old; +} + +// ---- Finish -------------------------------------------------------- +void CbmMcbmCheckTimingAlgo::SetReferenceDetector( ECbmModuleId refDetIn, std::string sNameIn, + Double_t dTimeRangeBegIn, Double_t dTimeRangeEndIn, + UInt_t uRangeNbBinsIn, + UInt_t uChargeCutMinIn, UInt_t uChargeCutMaxIn ) +{ + fRefDet.detId = refDetIn; + fRefDet.sName = sNameIn; + fRefDet.dTimeRangeBeg = dTimeRangeBegIn; + fRefDet.dTimeRangeEnd = dTimeRangeEndIn; + fRefDet.uRangeNbBins = uRangeNbBinsIn; + fRefDet.uChargeCutMin = uChargeCutMinIn; + fRefDet.uChargeCutMax = uChargeCutMaxIn; +} +void CbmMcbmCheckTimingAlgo::AddCheckDetector( ECbmModuleId detIn, std::string sNameIn, + Double_t dTimeRangeBegIn, Double_t dTimeRangeEndIn, + UInt_t uRangeNbBinsIn, + UInt_t uChargeCutMinIn, UInt_t uChargeCutMaxIn ) +{ + std::vector< CheckTimingDetector >::iterator det; + for( det = fvDets.begin(); det != fvDets.end(); ++det ) + { + if( (*det).detId == detIn ) + { + LOG( warning ) << "CbmMcbmCheckTimingAlgo::AddCheckDetector => Detector already in list, this call will only update the parameters!"; + + (*det).dTimeRangeBeg = dTimeRangeBegIn; + (*det).dTimeRangeEnd = dTimeRangeEndIn; + (*det).uRangeNbBins = uRangeNbBinsIn; + (*det).uChargeCutMin = uChargeCutMinIn; + (*det).uChargeCutMax = uChargeCutMaxIn; + + break; + } // if( (*det).detId == detIn ) + } // for( det = fvDets.begin(); det != fvDets.end(); ++det ) + + if( fvDets.end() == det ) + { + fvDets.push_back( CheckTimingDetector( detIn, sNameIn ) ); + det = fvDets.end(); + det--; + (*det).dTimeRangeBeg = dTimeRangeBegIn; + (*det).dTimeRangeEnd = dTimeRangeEndIn; + (*det).uRangeNbBins = uRangeNbBinsIn; + (*det).uChargeCutMin = uChargeCutMinIn; + (*det).uChargeCutMax = uChargeCutMaxIn; + } // if( fvDets.end() == det ) +} + +void CbmMcbmCheckTimingAlgo::RemoveCheckDetector( ECbmModuleId detIn ) +{ + for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) + { + if( (*det).detId == detIn ) + { + fvDets.erase( det ); + break; + } // if( (*det).detId == detIn ) + } // for( std::vector< CheckTimingDetector >::iterator det = fvDets.begin(); det != fvDets.end(); ++det ) +} + +ClassImp(CbmMcbmCheckTimingAlgo) diff --git a/fles/mcbm2018/tasks/CbmMcbmCheckTimingAlgo.h b/fles/mcbm2018/tasks/CbmMcbmCheckTimingAlgo.h new file mode 100644 index 0000000000000000000000000000000000000000..3b970766b5965ff229edafe5ea188f6c6a890366 --- /dev/null +++ b/fles/mcbm2018/tasks/CbmMcbmCheckTimingAlgo.h @@ -0,0 +1,127 @@ +/******************************************************************************** + * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ +#ifndef CBMMCBMCHECKTIMINGALGO_H +#define CBMMCBMCHECKTIMINGALGO_H + +#include "TString.h" +#include "CbmModuleList.h" +#include <vector> +#include "CbmTofDigi.h" + +class TH1; +class TH2; +class CbmDigiManager; + +class CheckTimingDetector +{ + public: + CheckTimingDetector() {;} + CheckTimingDetector( ECbmModuleId detIdIn, std::string sNameIn ) { detId = detIdIn; sName = sNameIn; } + + /// Settings + ECbmModuleId detId = ECbmModuleId::kNotExist; + std::string sName = "Invalid"; + Double_t dTimeRangeBeg = -1000.0; + Double_t dTimeRangeEnd = 1000.0; + UInt_t uRangeNbBins = 320; + UInt_t uChargeCutMin = 0; /// Charge cut used for example to reject/select pulser, no effect if equal, select if min < max, reject if max < min + UInt_t uChargeCutMax = 0; /// Charge cut used for example to reject/select pulser, no effect if equal, select if min < max, reject if max < min + + /// Book-keeping variables + Double_t dPrevTime = 0.; + Int_t iPrevRefFirstDigi = 0; +}; + +class CbmMcbmCheckTimingAlgo +{ + public: + + CbmMcbmCheckTimingAlgo(); + + CbmMcbmCheckTimingAlgo(const CbmMcbmCheckTimingAlgo&) = delete; + CbmMcbmCheckTimingAlgo operator=(const CbmMcbmCheckTimingAlgo&) = delete; + + /** Constructor with parameters (Optional) **/ + // CbmMcbmCheckTimingAlgo(Int_t verbose); + + + /** Destructor **/ + ~CbmMcbmCheckTimingAlgo(); + + + /** Initiliazation of task at the beginning of a run **/ + Bool_t Init(); + + /** ReInitiliazation of task when the runID changes **/ + Bool_t ReInit(); + + + /** Executed for each event. **/ + void ProcessTs(); + + /** Load the parameter container from the runtime database **/ + void SetParContainers(); + + /** Finish task called at the end of the run **/ + void Finish(); + + inline void SetOutFilename( TString sNameIn ) { fOutFileName = sNameIn; } + void WriteHistos(); + + void SetReferenceDetector( ECbmModuleId refDetIn, std::string sNameIn, + Double_t dTimeRangeBegIn = -1000.0, Double_t dTimeRangeEndIn = 1000.0, + UInt_t uRangeNbBinsIn = 320, + UInt_t uChargeCutMinIn = 0, UInt_t uChargeCutMaxIn = 0 ); + void AddCheckDetector( ECbmModuleId detIn, std::string sNameIn, + Double_t dTimeRangeBegIn = -1000.0, Double_t dTimeRangeEndIn = 1000.0, + UInt_t uRangeNbBinsIn = 320, + UInt_t uChargeCutMinIn = 0, UInt_t uChargeCutMaxIn = 0 ); + void RemoveCheckDetector( ECbmModuleId detIn ); + + private: + void CheckDataPresence( CheckTimingDetector detToCheck ); + void CreateHistos(); + + template <class DigiRef> void CheckInterSystemOffset(); + template <class Digi> void FillTimeOffsetHistos( const Double_t dRefTime, + const Double_t dRefCharge, + UInt_t uDetIdx ); + + + /** Input array from previous already existing data level **/ + CbmDigiManager* fDigiMan = nullptr; //! + + /** T0 is not included in CbmDigiManager, so add it explicitly here **/ + const std::vector< CbmTofDigi > * fpT0DigiVec = nullptr; //! + + // + UInt_t fuNbTs = 0; + + CheckTimingDetector fRefDet{ CheckTimingDetector( ECbmModuleId::kT0, "T0" ) }; + std::vector< CheckTimingDetector > fvDets{ CheckTimingDetector( ECbmModuleId::kSts, "Sts" ), + CheckTimingDetector( ECbmModuleId::kMuch, "Much" ), + CheckTimingDetector( ECbmModuleId::kTrd, "Trd" ), + CheckTimingDetector( ECbmModuleId::kTof, "Tof" ), + CheckTimingDetector( ECbmModuleId::kRich, "Rich" ), + CheckTimingDetector( ECbmModuleId::kPsd, "Psd" ) }; + + /// vectors storing histograms for each detector under investigation + std::vector< TH1 * > fvhDetSelfDiff = {}; + std::vector< TH1 * > fvhDetToRefDiff = {}; + std::vector< TH2 * > fvhDetToRefDiffRefCharge = {}; + std::vector< TH2 * > fvhDetToRefDiffDetCharge = {}; + std::vector< TH2 * > fvhDetToRefDiffEvo = {}; + std::vector< TH2 * > fvhDetToRefDiffEvoLong = {}; + + /** Name of the histogram output file **/ + TString fOutFileName = "data/HistosCheckTiming.root"; + + ClassDef(CbmMcbmCheckTimingAlgo,1); +}; + +#endif diff --git a/fles/mcbm2018/tasks/CbmMcbmCheckTimingTask.cxx b/fles/mcbm2018/tasks/CbmMcbmCheckTimingTask.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f3f4b12caa7f263250fa6993504a0326e636f818 --- /dev/null +++ b/fles/mcbm2018/tasks/CbmMcbmCheckTimingTask.cxx @@ -0,0 +1,148 @@ +/******************************************************************************** + * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ +#include "CbmMcbmCheckTimingTask.h" + +/// CBM headers + +/// FAIRROOT headers +#include "FairLogger.h" + +/// FAIRSOFT headers (geant, boost, ...) +#include "TH2.h" +#include "TH1.h" +#include "THttpServer.h" +#include <TFile.h> + +/// C/C++ headers + +// ---- Default constructor ------------------------------------------- +CbmMcbmCheckTimingTask::CbmMcbmCheckTimingTask() + : FairTask("CbmMcbmCheckTimingTask") +{ + /// Create Algo. To be made generic/switchable when more event building algo are available! + fpAlgo = new CbmMcbmCheckTimingAlgo(); +} + +// ---- Destructor ---------------------------------------------------- +CbmMcbmCheckTimingTask::~CbmMcbmCheckTimingTask() +{ + +} + +// ---- Initialisation ---------------------------------------------- +void CbmMcbmCheckTimingTask::SetParContainers() +{ + /// Nothing to do +} + +// ---- Init ---------------------------------------------------------- +InitStatus CbmMcbmCheckTimingTask::Init() +{ + /// Call Algo Init method + if( kTRUE == fpAlgo->Init() ) + return kSUCCESS; + else return kFATAL; +} + +// ---- ReInit ------------------------------------------------------- +InitStatus CbmMcbmCheckTimingTask::ReInit() +{ + return kSUCCESS; +} + +// ---- Exec ---------------------------------------------------------- +void CbmMcbmCheckTimingTask::Exec(Option_t* /*option*/) +{ + LOG(debug2) << "CbmMcbmCheckTimingTask::Exec => Starting sequence"; + /// Call Algo ProcessTs method + fpAlgo->ProcessTs(); + + LOG(debug2) << "CbmMcbmCheckTimingTask::Exec => Done"; +} + + +// ---- Finish -------------------------------------------------------- +void CbmMcbmCheckTimingTask::Finish() +{ +// SaveHistos(); + + /// Call Algo finish method + fpAlgo->Finish(); +} +//---------------------------------------------------------------------- +void CbmMcbmCheckTimingTask::SaveHistos() +{ + fpAlgo->WriteHistos(); +/* + /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder) + std::vector< std::pair< TNamed *, std::string > > vHistos = fpAlgo->GetHistoVector(); + + /// (Re-)Create ROOT file to store the histos + TDirectory * oldDir = NULL; + TFile * histoFile = NULL; + /// Store current directory position to allow restore later + oldDir = gDirectory; + /// open separate histo file in recreate mode + histoFile = new TFile( fsOutFileName , "RECREATE"); + histoFile->cd(); + + /// Save all plots and create folders if needed + for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto ) + { + /// Make sure we end up in chosen folder + TString sFolder = vHistos[ uHisto ].second.data(); + if( nullptr == gDirectory->Get( sFolder ) ) + gDirectory->mkdir( sFolder ); + gDirectory->cd( sFolder ); + + /// Write plot + vHistos[ uHisto ].first->Write(); + + histoFile->cd(); + } // for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto ) + + /// Restore original directory position + oldDir->cd(); + histoFile->Close(); +*/ +} +//---------------------------------------------------------------------- +void CbmMcbmCheckTimingTask::SetOutFilename( TString sNameIn ) +{ + fsOutFileName = sNameIn; + fpAlgo->SetOutFilename( fsOutFileName ); +} +//---------------------------------------------------------------------- +void CbmMcbmCheckTimingTask::SetReferenceDetector( ECbmModuleId refDetIn, std::string sNameIn, + Double_t dTimeRangeBegIn, Double_t dTimeRangeEndIn, + UInt_t uRangeNbBinsIn, + UInt_t uChargeCutMinIn, UInt_t uChargeCutMaxIn ) +{ + fpAlgo->SetReferenceDetector( refDetIn, sNameIn, + dTimeRangeBegIn, dTimeRangeEndIn, + uRangeNbBinsIn, + uChargeCutMinIn, uChargeCutMaxIn ); +} +void CbmMcbmCheckTimingTask::AddCheckDetector( ECbmModuleId detIn, std::string sNameIn, + Double_t dTimeRangeBegIn, Double_t dTimeRangeEndIn, + UInt_t uRangeNbBinsIn, + UInt_t uChargeCutMinIn, UInt_t uChargeCutMaxIn ) +{ + fpAlgo->AddCheckDetector( detIn, sNameIn, + dTimeRangeBegIn, dTimeRangeEndIn, + uRangeNbBinsIn, + uChargeCutMinIn, uChargeCutMaxIn ); +} + +void CbmMcbmCheckTimingTask::RemoveCheckDetector( ECbmModuleId detIn ) +{ + fpAlgo->RemoveCheckDetector( detIn ); +} + +//---------------------------------------------------------------------- +ClassImp(CbmMcbmCheckTimingTask) diff --git a/fles/mcbm2018/tasks/CbmMcbmCheckTimingTask.h b/fles/mcbm2018/tasks/CbmMcbmCheckTimingTask.h new file mode 100644 index 0000000000000000000000000000000000000000..e94523e68d2e6f643c08702f9adaf6ada5fb095f --- /dev/null +++ b/fles/mcbm2018/tasks/CbmMcbmCheckTimingTask.h @@ -0,0 +1,80 @@ +/******************************************************************************** + * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ +#ifndef CBMMCBMCHECKTIMINGTASK_H +#define CBMMCBMCHECKTIMINGTASK_H + +/// CBM headers +#include "CbmMcbmCheckTimingAlgo.h" + +/// FAIRROOT headers +#include "FairTask.h" + +/// FAIRSOFT headers (geant, boost, ...) + +/// C/C++ headers + +class TClonesArray; + +class CbmMcbmCheckTimingTask : public FairTask +{ + public: + + /** Default constructor **/ + CbmMcbmCheckTimingTask(); + + CbmMcbmCheckTimingTask(const CbmMcbmCheckTimingTask&) = delete; + CbmMcbmCheckTimingTask operator=(const CbmMcbmCheckTimingTask&) = delete; + + /** Constructor with parameters (Optional) **/ + // CbmMcbmCheckTimingTask(Int_t verbose); + + + /** Destructor **/ + ~CbmMcbmCheckTimingTask(); + + + /** Initiliazation of task at the beginning of a run **/ + virtual InitStatus Init(); + + /** ReInitiliazation of task when the runID changes **/ + virtual InitStatus ReInit(); + + + /** Executed for each event. **/ + virtual void Exec(Option_t*); + + /** Load the parameter container from the runtime database **/ + virtual void SetParContainers(); + + /** Finish task called at the end of the run **/ + virtual void Finish(); + + void SetOutFilename( TString sNameIn ); + + void SetReferenceDetector( ECbmModuleId refDetIn, std::string sNameIn, + Double_t dTimeRangeBegIn = -1000.0, Double_t dTimeRangeEndIn = 1000.0, + UInt_t uRangeNbBinsIn = 320, + UInt_t uChargeCutMinIn = 0, UInt_t uChargeCutMaxIn = 0 ); + void AddCheckDetector( ECbmModuleId detIn, std::string sNameIn, + Double_t dTimeRangeBegIn = -1000.0, Double_t dTimeRangeEndIn = 1000.0, + UInt_t uRangeNbBinsIn = 320, + UInt_t uChargeCutMinIn = 0, UInt_t uChargeCutMaxIn = 0 ); + void RemoveCheckDetector( ECbmModuleId detIn ); + + private: + void SaveHistos(); + + CbmMcbmCheckTimingAlgo * fpAlgo = nullptr; + + /** Name of the histogram output file **/ + TString fsOutFileName = "data/HistosCheckTiming.root"; + + ClassDef(CbmMcbmCheckTimingTask,1); +}; + +#endif // CBMMCBM2019TIMEWINEVENTBUILDERTASK_H