diff --git a/reco/detectors/psd/CbmPsdHitProducer.cxx b/reco/detectors/psd/CbmPsdHitProducer.cxx index f646df175355e7817b80bd0b965bec36dd3f52c0..46e174427be0a255fded646b0ab41a1c861a098e 100644 --- a/reco/detectors/psd/CbmPsdHitProducer.cxx +++ b/reco/detectors/psd/CbmPsdHitProducer.cxx @@ -5,40 +5,40 @@ #include "CbmPsdHitProducer.h" #include "CbmDigiManager.h" +#include "CbmEvent.h" #include "CbmPsdDigi.h" #include "CbmPsdHit.h" -#include "FairRootManager.h" +#include <FairRootManager.h> #include <Logger.h> -#include "TClonesArray.h" -#include "TMath.h" +#include <TClonesArray.h> #include <TFile.h> +#include <TMath.h> +#include <TStopwatch.h> #include <fstream> +#include <iomanip> #include <iostream> #include <map> using std::cout; using std::endl; +using std::fixed; +using std::left; +using std::pair; +using std::setprecision; +using std::setw; // ----- Default constructor ------------------------------------------- -CbmPsdHitProducer::CbmPsdHitProducer() - : FairTask("Ideal Psd Hit Producer", 1) - , fNHits(0) - , fHitArray(NULL) - , fDigiMan(nullptr) - , fXi() - , fYi() - , fhModXNewEn(NULL) { - // Reset(); -} +CbmPsdHitProducer::CbmPsdHitProducer() : FairTask("Ideal Psd Hit Producer", 1), fXi(), fYi() {} // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- -CbmPsdHitProducer::~CbmPsdHitProducer() { +CbmPsdHitProducer::~CbmPsdHitProducer() +{ if (fHitArray) { fHitArray->Delete(); delete fHitArray; @@ -48,139 +48,201 @@ CbmPsdHitProducer::~CbmPsdHitProducer() { // ----- Public method Init -------------------------------------------- -InitStatus CbmPsdHitProducer::Init() { - - //ifstream fxypos("psd_geo_xy.txt"); - //for (Int_t ii=1; ii<50; ii++) { //SELIM: 49 modules, including central & corner modules (rejected in analysis/flow/eventPlane.cxx) - // fxypos>>fXi[ii]>>fYi[ii]; - // cout<<ii<<" "<<fXi[ii]<<" "<<fYi[ii]<<endl; - //} - //fxypos.close(); +InitStatus CbmPsdHitProducer::Init() +{ fhModXNewEn = new TH1F("hModXNewEn", "X distr, En", 300, -150., 150.); fhModXNewEn->Print(); - // Get RootManager + std::cout << std::endl << std::endl; + LOG(info) << "======= " << GetName() << ": Init ====================="; + + // --- Get RootManager FairRootManager* ioman = FairRootManager::Instance(); if (!ioman) { - LOG(fatal) - << "-W- CbmPsdHitProducer::Init: RootManager not instantised!"; //FLORIAN & SELIM + LOG(fatal) << "-W- CbmPsdHitProducer::Init: RootManager not instantised!"; //FLORIAN & SELIM return kFATAL; } + // --- Get event array, if present + fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("Event")); + if (fEvents) LOG(info) << GetName() << ": found Event branch, run event-by-event"; + else { + fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent")); + if (fEvents) LOG(info) << GetName() << ": found CbmEvent branch, run event-by-event"; + } + if (!fEvents) { + LOG(info) << GetName() << ": no event branch found; run in time-based mode"; + LOG(warn) << "*** Note that the current PSD hit producer is not suited for time-based reconstruction!"; + LOG(warn) << "*** Unless you have run the simulation event-by-event, it will not produce sensible results."; + } + // --- Initialise digi manager CbmDigiManager* digiMan = CbmDigiManager::Instance(); digiMan->Init(); + // --- Check input branch (PsdDigi). If not present, set task inactive. if (!digiMan->IsPresent(ECbmModuleId::kPsd)) { LOG(error) << GetName() << ": No PsdDigi input array present; " << "task will be inactive."; return kERROR; } + LOG(info) << GetName() << ": found PsdDigi branch"; - - // Create and register output array + // --- Create and register output array fHitArray = new TClonesArray("CbmPsdHit", 1000); - ioman->Register( - "PsdHit", "PSD", fHitArray, IsOutputBranchPersistent("PsdHit")); - + ioman->Register("PsdHit", "PSD", fHitArray, IsOutputBranchPersistent("PsdHit")); fHitArray->Dump(); - cout << "-I- CbmPsdHitProducer: Intialisation successfull " << kSUCCESS - << endl; + LOG(info) << GetName() << ": registered branch PsdHit"; + + LOG(info) << GetName() << ": intialisation successfull"; + LOG(info) << "======================================================\n"; return kSUCCESS; } - - // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- -void CbmPsdHitProducer::Exec(Option_t* /*opt*/) { +void CbmPsdHitProducer::Exec(Option_t* /*opt*/) +{ - cout << " CbmPsdHitProducer::Exec(Option_t* /*opt*/) " << endl; - fhModXNewEn->Print(); + // --- Timer + TStopwatch timer; + timer.Start(); - // Reset output array + // --- Reset output array Reset(); - // Declare some variables - const CbmPsdDigi* dig = NULL; + // --- Local variables + pair<Int_t, Int_t> result; + Int_t nEvents = 0; + Int_t nDigis = 0; + Int_t nHits = 0; + Int_t nDigisAll = fDigiMan->GetNofDigis(ECbmModuleId::kPsd); + CbmEvent* event = nullptr; + + // --- Time-slice mode: process entire digi array + if (!fEvents) { + result = ProcessData(nullptr); + nDigis = result.first; + nHits = result.second; + } + + // --- Event mode: loop over events and process digis within + else { + assert(fEvents); + nEvents = fEvents->GetEntriesFast(); + for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) { + event = dynamic_cast<CbmEvent*>(fEvents->At(iEvent)); + assert(event); + result = ProcessData(event); + LOG(debug) << GetName() << ": Event " << iEvent << " / " << nEvents << ", digis " << result.first << ", hits " + << result.second; + nDigis += result.first; + nHits += result.second; + } //# events + } //? event mode + + // --- Timeslice log and statistics + timer.Stop(); + if (fEvents) + LOG(info) << std::setw(20) << std::left << GetName() << fixed << setprecision(2) << " [" << timer.RealTime() * 1000. + << " ms] TS " << fNofTs << ", events " << nEvents << ", digis " << nDigis << " / " << nDigisAll + << ", hits " << fNofHits; + else + LOG(info) << std::setw(20) << std::left << GetName() << fixed << setprecision(2) << " [" << timer.RealTime() * 1000. + << " ms] TS " << fNofTs << ", digis " << nDigis << " / " << nDigisAll << ", hits " << fNofHits; + fNofTs++; + fNofEvents += nEvents; + fNofDigis += nDigis; + fNofHits += nHits; + fTimeTot += timer.RealTime(); +} +// ------------------------------------------------------------------------- + + +// ----- End-of-timeslice action --------------------------------------- +void CbmPsdHitProducer::Finish() +{ + + std::cout << std::endl; + LOG(info) << "====================================="; + LOG(info) << GetName() << ": Run summary"; + LOG(info) << "Time slices : " << fNofTs; + LOG(info) << "Digis / TS : " << fixed << setprecision(2) << Double_t(fNofDigis) / Double_t(fNofTs); + LOG(info) << "Hits / TS : " << fixed << setprecision(2) << Double_t(fNofHits) / Double_t(fNofTs); + LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTimeTot / Double_t(fNofTs) << " ms"; + if (fEvents) { + LOG(info) << "Events : " << fNofEvents; + LOG(info) << "Events / TS : " << fixed << setprecision(2) << Double_t(fNofEvents) / Double_t(fNofTs); + LOG(info) << "Digis / event : " << fixed << setprecision(2) << Double_t(fNofDigis) / Double_t(fNofEvents); + LOG(info) << "Hits / event : " << fixed << setprecision(2) << Double_t(fNofHits) / Double_t(fNofEvents); + } + + // --- Write energy deposition histogram + TFile* oldFile = gFile; + TDirectory* oldDir = gDirectory; + TFile* outfile = new TFile("EdepHistos.root", "RECREATE"); + outfile->cd(); + fhModXNewEn->Write(); + outfile->Close(); + gFile = oldFile; + gDirectory = oldDir; + LOG(info) << "Histograms written to EdepHistos.root"; + LOG(info) << "=====================================\n"; +} +// ------------------------------------------------------------------------- + - /* - Double_t edep[NPsdMod];//marina - for (Int_t imod=0; imod<NPsdMod; imod++) { edep[imod]=0.; }//marina -*/ +// ----- Data processing ----------------------------------------------- +pair<Int_t, Int_t> CbmPsdHitProducer::ProcessData(CbmEvent* event) +{ - std::map<int, Double_t> edepmap; + // --- Local variables + std::map<int, Double_t> edepmap; // energy deposition per module, key is module ID + Int_t nHits = 0; + const CbmPsdDigi* digi = nullptr; + Int_t nDigis = (event ? event->GetNofData(ECbmDataType::kPsdDigi) : fDigiMan->GetNofDigis(ECbmModuleId::kPsd)); - // Loop over PsdDigits - Int_t nDigi = fDigiMan->GetNofDigis(ECbmModuleId::kPsd); - cout << " nDigits " << nDigi << endl; + // --- Loop over PsdDigis. Distribute energy deposition into the modules. + Int_t digiIndex = -1; + for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) { - for (Int_t idig = 0; idig < nDigi; idig++) { - dig = fDigiMan->Get<CbmPsdDigi>(idig); - if (!dig) continue; - Int_t mod = dig->GetModuleID(); - // Int_t sec = dig->GetSectionID(); - Double_t eDep = (Double_t) dig->GetEdep(); - //edep[mod-1] += (Double_t) dig->GetEdep(); //DEBUG: SELIM + digiIndex = (event ? event->GetIndex(ECbmDataType::kPsdDigi, iDigi) : iDigi); + digi = fDigiMan->Get<const CbmPsdDigi>(digiIndex); + assert(digi); + Int_t mod = digi->GetModuleID(); + Double_t eDep = (Double_t) digi->GetEdep(); auto insert_result = edepmap.insert(std::make_pair(mod, eDep)); if (!insert_result.second) { // entry was here before (*insert_result.first).second += eDep; } - } // Loop over MCPoints + } // # digis - fNHits = 0; + // --- Create hits, one per activated module + UInt_t hitIndex = -1; for (auto edep_entry : edepmap) { int modID = edep_entry.first; Double_t eDep = edep_entry.second; - new ((*fHitArray)[fNHits]) CbmPsdHit(modID, eDep); - fNHits++; - } - - /* - for (Int_t imod=0; imod<NPsdMod; imod++) //marina - { - if (edep[imod]>0.) - { - new ((*fHitArray)[fNHits]) CbmPsdHit(imod+1, edep[imod]); - fNHits++; - //cout<<"MARINA CbmPsdHitProducer " <<fNHits <<" " <<imod+1 <<" " <<edep[imod] <<endl; - //fhModXNewEn->Fill(fXi[imod],TMath::Sqrt(edep[imod]) ); - //cout<<"CbmPsdHitProducer "<<fNHits<<" "<<imod<<" "<<edep[imod]<<endl; - } + hitIndex = fHitArray->GetEntriesFast(); + new ((*fHitArray)[hitIndex]) CbmPsdHit(modID, eDep); + if (event) event->AddData(ECbmDataType::kPsdHit, hitIndex); + nHits++; } - */ - // Event summary - cout << "-I- CbmPsdHitProducer: " << fNHits << " CbmPsdHits created." << endl; + return std::make_pair(nDigis, nHits); } // ------------------------------------------------------------------------- -void CbmPsdHitProducer::Finish() { - cout << " CbmPsdHitProducer::Finish() " << endl; - /// Save old global file and folder pointer to avoid messing with FairRoot - TFile* oldFile = gFile; - TDirectory* oldDir = gDirectory; - - TFile* outfile = new TFile("EdepHistos.root", "RECREATE"); - outfile->cd(); - fhModXNewEn->Write(); - /// Restore old global file and folder pointer to avoid messing with FairRoot - gFile = oldFile; - gDirectory = oldDir; - - //outfile->Close(); //SELIM -} - -// ----- Private method Reset ------------------------------------------ -void CbmPsdHitProducer::Reset() { - fNHits = 0; +// ----- Reset: clear output array ------------------------------------- +void CbmPsdHitProducer::Reset() +{ if (fHitArray) fHitArray->Delete(); } +// ------------------------------------------------------------------------- ClassImp(CbmPsdHitProducer) diff --git a/reco/detectors/psd/CbmPsdHitProducer.h b/reco/detectors/psd/CbmPsdHitProducer.h index 05fd5a5ae292cb9ba9e06a9f7e2f3581c5539ffe..03b4707d7a6bd6ceb149820c7109c4d7ec12b438 100644 --- a/reco/detectors/psd/CbmPsdHitProducer.h +++ b/reco/detectors/psd/CbmPsdHitProducer.h @@ -17,10 +17,13 @@ #include "CbmDigiManager.h" -#include "FairTask.h" -#include "TH1F.h" + +#include <FairTask.h> + +#include <TH1F.h> class TClonesArray; +class CbmEvent; const Int_t NPsdMod = 44; //with 4 central mods @@ -45,13 +48,28 @@ public: private: - Int_t fNHits; + Int_t fNHits = 0; /** Output array of CbmPsdHit **/ - TClonesArray* fHitArray; + TClonesArray* fHitArray = nullptr; /** Digi Manager for input **/ - CbmDigiManager* fDigiMan; //! + CbmDigiManager* fDigiMan = nullptr; //! + + /** Event array **/ + TClonesArray* fEvents = nullptr; //! + + + /** @brief Processing of digis **/ + std::pair<Int_t, Int_t> ProcessData(CbmEvent* event); + + /** Counters **/ + ULong64_t fNofTs = 0; + ULong64_t fNofEvents = 0; + ULong64_t fNofDigis = 0; + ULong64_t fNofHits = 0; + Double_t fTimeTot = 0.; + CbmPsdHitProducer(const CbmPsdHitProducer&); CbmPsdHitProducer operator=(const CbmPsdHitProducer&); @@ -61,7 +79,7 @@ private: Float_t fXi[NPsdMod]; //X coordinate of center of module Float_t fYi[NPsdMod]; //X coordinate of center of module - TH1F* fhModXNewEn; //edep in each module for Marina + TH1F* fhModXNewEn = nullptr; //edep in each module for Marina ClassDef(CbmPsdHitProducer, 2);