// ----------------------------------------------------------------------------- // ----- ----- // ----- CbmUnpackTask ----- // ----- Created 11.02.2020 by P.-A. Loizeau ----- // ----- ----- // ----------------------------------------------------------------------------- /// CbmRoot (+externals) headers /// FairRoot headers #include <FairLogger.h> #include <FairRootManager.h> #include <FairRun.h> #include <FairRuntimeDb.h> #include <FairRunOnline.h> #include <FairParGenericSet.h> /// Fairsoft (Root, Boost, ...) headers #include <THttpServer.h> #include <TROOT.h> #include <TClonesArray.h> #include <TCanvas.h> #include <TFile.h> /// C/C++ headers #include <iostream> #include <stdint.h> #include <iomanip> #include <fstream> #include <chrono> template< class TDigi, class TAlgo, class TParam > CbmUnpackTask< TDigi, TAlgo, TParam >::CbmUnpackTask( TString sDigiBranchName, TString sDigiBranchDescr ) : TObject(), fsDigiBranchName( sDigiBranchName ), fsDigiBranchDescr( sDigiBranchDescr ) { // fvDigiIO = new std::vector< TDigi >(); // fvErrorIO = new std::vector< CbmErrorMessage >(); fUnpackerAlgo = new TAlgo(); } template< class TDigi, class TAlgo, class TParam > CbmUnpackTask< TDigi, TAlgo, TParam >::~CbmUnpackTask() { if( nullptr != fUnpackerAlgo ) delete fUnpackerAlgo; if( nullptr != fvDigiIO ) { fvDigiIO.clear(); delete fvDigiIO; }; if( nullptr != fvErrorIO ) { fvErrorIO.clear(); delete fvErrorIO; } } /** TODO: 1) proper way to access the branchname and description **/ template< class TDigi, class TAlgo, class TParam > Bool_t CbmUnpackTask< TDigi, TAlgo, TParam >::Init() { LOG(info) << "CbmUnpackTask::Init => " << "Initializing Unpacker task for the following specializations: "; FairRootManager* ioman = FairRootManager::Instance(); if( NULL == ioman ) { LOG(fatal) << "No FairRootManager instance"; } /// Check first if array not already existing due to other unpacker! fvDigiIO = static_cast< std::vector< TDigi > *>(ioman->GetObject( fsDigiBranchName )); if( nullptr == fvDigiIO ) { /// No existing array => create it! fvDigiIO = new std::vector< TDigi >(); if( nullptr == fvDigiIO ) { LOG(fatal) << "Failed creating the IO vector "; } // if( nullptr == fvDigiIO ) ioman->RegisterAny( fsDigiBranchName, // ( "" == fsDigiBranchDescr ? fsDigiBranchName : fsDigiBranchDescr), fvDigiIO, fbWriteOutput); } // if( nullptr == fvDigiIO ) else LOG(info) << "--> Found existing IO vector, re-using it."; fUnpackerAlgo->AssignOutputVector( fvDigiIO ); /// Check first if array not already existing due to other unpacker! fvErrorIO = static_cast< std::vector< TDigi > *>(ioman->GetObject( "ErrorMessage" )); if( nullptr == fvErrorIO ) { /// No existing array => create it! fvErrorIO = new std::vector< CbmErrorMessage >(); if( nullptr == fvErrorIO ) { LOG(fatal) << "Failed creating the IO vector for error messages"; } // if( nullptr == fvErrorIO ) ioman->RegisterAny( "ErrorMessage", // ( "" == fsDigiBranchDescr ? fsDigiBranchName : fsDigiBranchDescr), fvErrorIO, fbWriteOutput); } // if( nullptr == fvErrorIO ) else LOG(info) << "--> Found existing IO vector for error messages, re-using it."; fUnpackerAlgo->AssignErrorVector( fvErrorIO ); return kTRUE; } template< class TDigi, class TAlgo, class TParam > void CbmUnpackTask< TDigi, TAlgo, TParam >::SetParContainers() { LOG(info) << "Setting parameter containers for " << GetName(); TList* fParCList = fUnpackerAlgo->GetParList(); for( Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC ) { FairParGenericSet* tempObj = (FairParGenericSet*)(fParCList->At( iparC )); fParCList->Remove(tempObj); std::string sParamName{ tempObj->GetName() }; FairParGenericSet* newObj = dynamic_cast<FairParGenericSet*>( FairRun::Instance()->GetRuntimeDb()->getContainer( sParamName.data() ) ); if( nullptr == newObj ) { LOG(error) << "Failed to obtain parameter container " << sParamName << ", for parameter index " << iparC; return; } // if( nullptr == newObj ) fParCList->AddAt(newObj, iparC); // delete tempObj; } // for( Int_t iparC = 0; iparC < fParCList->GetEntries(); ++iparC ) } template< class TDigi, class TAlgo, class TParam > Bool_t CbmUnpackTask< TDigi, TAlgo, TParam >::InitContainers() { LOG(info) << "Init parameter containers for " << GetName(); Bool_t initOK = fUnpackerAlgo->InitContainers(); /// If monitor mode enabled, trigger histos creation, obtain pointer on them and add them to the HTTP server if( kTRUE == fbMonitorMode ) { /// Trigger histo creation on all associated algos initOK &= fUnpackerAlgo->CreateHistograms(); /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder) std::vector< std::pair< TNamed *, std::string > > vHistos = fUnpackerAlgo->GetHistoVector(); /// Register the histos in the HTTP server THttpServer* server = FairRunOnline::Instance()->GetHttpServer(); if( nullptr != server ) { for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto ) { server->Register( Form( "/%s", vHistos[ uHisto ].second.data() ), vHistos[ uHisto ].first ); } // for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto ) // server->RegisterCommand("/Reset_UnpSts_Hist", "bMcbm2018UnpackerTaskStsResetHistos=kTRUE"); // server->Restrict("/Reset_UnpSts_Hist", "allow=admin"); } // if( nullptr != server ) } // if( kTRUE == fbMonitorMode ) fUnpackerAlgo->SetMonitorMode( fbMonitorMode ); return initOK; } template< class TDigi, class TAlgo, class TParam > Bool_t CbmUnpackTask< TDigi, TAlgo, TParam >::ReInitContainers() { LOG(info) << "ReInit parameter containers for " << GetName(); Bool_t initOK = fUnpackerAlgo->ReInitContainers(); return initOK; } template< class TDigi, class TAlgo, class TParam > void CbmUnpackTask< TDigi, TAlgo, TParam >::AddMsComponentToList( size_t component, UShort_t usDetectorId ) { fUnpackerAlgo->AddMsComponentToList( component, usDetectorId ); } template< class TDigi, class TAlgo, class TParam > void CbmUnpackTask< TDigi, TAlgo, TParam >::Reset() { fvDigiIO->clear(); fvErrorIO->clear(); } template< class TDigi, class TAlgo, class TParam > Bool_t CbmUnpackTask< TDigi, TAlgo, TParam >::DoUnpack(const fles::Timeslice& ts, size_t /*component*/) { if( kFALSE == fUnpackerAlgo->ProcessTs( ts ) ) { LOG(error) << "Failed processing TS " << ts.index() << " in unpacker algorithm class"; return kTRUE; } // if( kFALSE == fUnpackerAlgo->ProcessTs( ts ) ) if( 0 == ts.index() % 10000 ) LOG(info) << "Processed TS with index " << std::setw( 9 ) << fulTsCounter; if( 0 == fulTsCounter % 10000 ) LOG(info) << "Processed " << std::setw( 9 ) << fulTsCounter << " TS "; fulTsCounter++; return kTRUE; } template< class TDigi, class TAlgo, class TParam > void CbmUnpackTask< TDigi, TAlgo, TParam >::Finish() { /// If monitor mode enabled, trigger histos creation, obtain pointer on them and add them to the HTTP server if( kTRUE == fbMonitorMode ) { /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder) std::vector< std::pair< TNamed *, std::string > > vHistos = fUnpackerAlgo->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( "data/HistosUnpackerSts.root" , "RECREATE"); histoFile->cd(); /// Register the histos in the HTTP server 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(); } // if( kTRUE == fbMonitorMode ) } template< class TDigi, class TAlgo, class TParam > void CbmUnpackTask< TDigi, TAlgo, TParam >::SetIgnoreOverlapMs( Bool_t bFlagIn ) { fUnpackerAlgo->SetIgnoreOverlapMs( bFlagIn ); } /* template< class TDigi, class TAlgo, class TParam > void CbmUnpackTask< TDigi, TAlgo, TParam >::SetTimeOffsetNs( Double_t dOffsetIn ) { fUnpackerAlgo->SetTimeOffsetNs( dOffsetIn ); } */