CbmRoot
Loading...
Searching...
No Matches
CbmPsdHitProducer.cxx
Go to the documentation of this file.
1/* Copyright (C) 2012-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Alla Maevskaya, Selim Seddiki, Volker Friese [committer], Evgeny Kashirin */
4
5// -------------------------------------------------------------------------
6// ----- CbmPsdHitProducer source file -----
7// ----- Created 15/05/12 by Alla & SELIM -----
8// -------------------------------------------------------------------------
9#include "CbmPsdHitProducer.h"
10
11#include "CbmDigiManager.h"
12#include "CbmEvent.h"
13#include "CbmPsdDigi.h"
14#include "CbmPsdHit.h"
15
16#include <FairRootManager.h>
17#include <Logger.h>
18
19#include <TClonesArray.h>
20#include <TFile.h>
21#include <TMath.h>
22#include <TStopwatch.h>
23
24#include <fstream>
25#include <iomanip>
26#include <iostream>
27#include <map>
28
29using std::cout;
30using std::endl;
31using std::fixed;
32using std::left;
33using std::pair;
34using std::right;
35using std::setprecision;
36using std::setw;
37using std::stringstream;
38
39
40// ----- Default constructor -------------------------------------------
41CbmPsdHitProducer::CbmPsdHitProducer() : FairTask("PsdHitProducer", 1), fXi(), fYi() {}
42// -------------------------------------------------------------------------
43
44
45// ----- Destructor ----------------------------------------------------
47{
48 if (fHitArray) {
49 fHitArray->Delete();
50 delete fHitArray;
51 }
52}
53// -------------------------------------------------------------------------
54
55
56// ----- Public method Init --------------------------------------------
58{
59
60 fhModXNewEn = new TH1F("hModXNewEn", "X distr, En", 300, -150., 150.);
61 fhModXNewEn->Print();
62
63 std::cout << std::endl << std::endl;
64 LOG(info) << "======= " << GetName() << ": Init =====================";
65
66 // --- Get RootManager
67 FairRootManager* ioman = FairRootManager::Instance();
68 if (!ioman) {
69 LOG(fatal) << "-W- CbmPsdHitProducer::Init: RootManager not instantised!"; //FLORIAN & SELIM
70 return kFATAL;
71 }
72
73 // --- Get event array, if present
74 fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("Event"));
75 if (fEvents)
76 LOG(info) << GetName() << ": found Event branch, run event-by-event";
77 else {
78 fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
79 if (fEvents) LOG(info) << GetName() << ": found CbmEvent branch, run event-by-event";
80 }
81 if (!fEvents) {
82 LOG(info) << GetName() << ": no event branch found; run in time-based mode";
83 LOG(warn) << "*** Note that the current PSD hit producer is not suited for time-based reconstruction!";
84 LOG(warn) << "*** Unless you have run the simulation event-by-event, it will not produce sensible results.";
85 }
86
87 // --- Initialise digi manager
89 digiMan->Init();
90
91 // --- Check input branch (PsdDigi). If not present, set task inactive.
92 if (!digiMan->IsPresent(ECbmModuleId::kPsd)) {
93 LOG(error) << GetName() << ": No PsdDigi input array present; "
94 << "task will be inactive.";
95 return kERROR;
96 }
97 LOG(info) << GetName() << ": found PsdDigi branch";
98
99 // --- Create and register output array
100 fHitArray = new TClonesArray("CbmPsdHit", 1000);
101 ioman->Register("PsdHit", "PSD", fHitArray, IsOutputBranchPersistent("PsdHit"));
102 fHitArray->Dump();
103 LOG(info) << GetName() << ": registered branch PsdHit";
104
105 LOG(info) << GetName() << ": intialisation successfull";
106 LOG(info) << "======================================================\n";
107 return kSUCCESS;
108}
109// -------------------------------------------------------------------------
110
111
112// ----- Public method Exec --------------------------------------------
113void CbmPsdHitProducer::Exec(Option_t* /*opt*/)
114{
115
116 // --- Timer
117 TStopwatch timer;
118 timer.Start();
119
120 // --- Reset output array
121 Reset();
122
123 // --- Local variables
124 pair<Int_t, Int_t> result;
125 Int_t nEvents = 0;
126 Int_t nDigis = 0;
127 Int_t nHits = 0;
128 Int_t nDigisAll = fDigiMan->GetNofDigis(ECbmModuleId::kPsd);
129 CbmEvent* event = nullptr;
130
131 // --- Time-slice mode: process entire digi array
132 if (!fEvents) {
133 result = ProcessData(nullptr);
134 nDigis = result.first;
135 nHits = result.second;
136 }
137
138 // --- Event mode: loop over events and process digis within
139 else {
140 assert(fEvents);
141 nEvents = fEvents->GetEntriesFast();
142 for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
143 event = dynamic_cast<CbmEvent*>(fEvents->At(iEvent));
144 assert(event);
145 result = ProcessData(event);
146 LOG(debug) << GetName() << ": Event " << iEvent << " / " << nEvents << ", digis " << result.first << ", hits "
147 << result.second;
148 nDigis += result.first;
149 nHits += result.second;
150 } //# events
151 } //? event mode
152
153 // --- Timeslice log and statistics
154 timer.Stop();
155 stringstream logOut;
156 logOut << setw(20) << left << GetName() << " [";
157 logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] ";
158 logOut << "TS " << fNofTs;
159 if (fEvents) logOut << ", events " << nEvents;
160 logOut << ", digis " << nDigis << " / " << nDigisAll;
161 logOut << ", hits " << nHits;
162 LOG(info) << logOut.str();
163 fNofTs++;
164 fNofEvents += nEvents;
165 fNofDigis += nDigis;
166 fNofHits += nHits;
167 fTimeTot += timer.RealTime();
168}
169// -------------------------------------------------------------------------
170
171
172// ----- End-of-timeslice action ---------------------------------------
174{
175
176 std::cout << std::endl;
177 LOG(info) << "=====================================";
178 LOG(info) << GetName() << ": Run summary";
179 LOG(info) << "Time slices : " << fNofTs;
180 LOG(info) << "Digis / TS : " << fixed << setprecision(2) << Double_t(fNofDigis) / Double_t(fNofTs);
181 LOG(info) << "Hits / TS : " << fixed << setprecision(2) << Double_t(fNofHits) / Double_t(fNofTs);
182 LOG(info) << "Time / TS : " << fixed << setprecision(2) << 1000. * fTimeTot / Double_t(fNofTs) << " ms";
183 if (fEvents) {
184 LOG(info) << "Events : " << fNofEvents;
185 LOG(info) << "Events / TS : " << fixed << setprecision(2) << Double_t(fNofEvents) / Double_t(fNofTs);
186 LOG(info) << "Digis / event : " << fixed << setprecision(2) << Double_t(fNofDigis) / Double_t(fNofEvents);
187 LOG(info) << "Hits / event : " << fixed << setprecision(2) << Double_t(fNofHits) / Double_t(fNofEvents);
188 }
189
190 // --- Write energy deposition histogram
191 TFile* oldFile = gFile;
192 TDirectory* oldDir = gDirectory;
193 TFile* outfile = new TFile("EdepHistos.root", "RECREATE");
194 outfile->cd();
195 fhModXNewEn->Write();
196 outfile->Close();
197 gFile = oldFile;
198 gDirectory = oldDir;
199 LOG(info) << "Histograms written to EdepHistos.root";
200 LOG(info) << "=====================================\n";
201}
202// -------------------------------------------------------------------------
203
204
205// ----- Data processing -----------------------------------------------
206pair<Int_t, Int_t> CbmPsdHitProducer::ProcessData(CbmEvent* event)
207{
208
209 // --- Local variables
210 std::map<int, Double_t> edepmap; // energy deposition per module, key is module ID
211 Int_t nHits = 0;
212 const CbmPsdDigi* digi = nullptr;
213 Int_t nDigis = (event ? event->GetNofData(ECbmDataType::kPsdDigi) : fDigiMan->GetNofDigis(ECbmModuleId::kPsd));
214
215 // --- Loop over PsdDigis. Distribute energy deposition into the modules.
216 Int_t digiIndex = -1;
217 for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
218
219 digiIndex = (event ? event->GetIndex(ECbmDataType::kPsdDigi, iDigi) : iDigi);
220 digi = fDigiMan->Get<const CbmPsdDigi>(digiIndex);
221 assert(digi);
222
223 Int_t mod = digi->GetModuleID();
224 Double_t eDep = (Double_t) digi->GetEdep();
225 auto insert_result = edepmap.insert(std::make_pair(mod, eDep));
226 if (!insert_result.second) { // entry was here before
227 (*insert_result.first).second += eDep;
228 }
229
230 } // # digis
231
232 // --- Create hits, one per activated module
233 UInt_t hitIndex = -1;
234 for (auto edep_entry : edepmap) {
235 int modID = edep_entry.first;
236 Double_t eDep = edep_entry.second;
237 hitIndex = fHitArray->GetEntriesFast();
238 new ((*fHitArray)[hitIndex]) CbmPsdHit(modID, eDep);
239 if (event) event->AddData(ECbmDataType::kPsdHit, hitIndex);
240 nHits++;
241 }
242
243 return std::make_pair(nDigis, nHits);
244}
245// -------------------------------------------------------------------------
246
247
248// ----- Reset: clear output array -------------------------------------
250{
251 if (fHitArray) fHitArray->Delete();
252}
253// -------------------------------------------------------------------------
254
255
ClassImp(CbmConverterManager)
@ kPsd
Projectile spectator detector.
CbmDigiManager.
static Int_t GetNofDigis(ECbmModuleId systemId)
static Bool_t IsPresent(ECbmModuleId systemId)
Presence of a digi branch.
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
Data class for PSD digital information.
Definition CbmPsdDigi.h:36
double GetEdep() const
Energy deposit.
Definition CbmPsdDigi.h:119
double GetModuleID() const
Module Identifier.
Definition CbmPsdDigi.h:125
std::pair< Int_t, Int_t > ProcessData(CbmEvent *event)
Processing of digis.
virtual InitStatus Init()
virtual void Exec(Option_t *opt)
TClonesArray * fEvents
TClonesArray * fHitArray
CbmDigiManager * fDigiMan