CbmRoot
Loading...
Searching...
No Matches
CbmMcbm2020TrdTshiftPar.cxx
Go to the documentation of this file.
1/* Copyright (C) 2020-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pascal Raisig, Florian Uhlig [committer] */
4
6
7// FairRoot
8#include "FairParamList.h"
9#include "Logger.h"
10
11// ROOT
12#include "THnSparse.h"
13
14// C/C++
15#include <iomanip>
16#include <iostream>
17
18// #define CTAVM CbmTrdAnalysisVarManager // See comments in GetNevents() et al.
19// #define CTAH CbmTrdAnalysisHisto // See comments in GetNevents() et al.
20
21CbmMcbm2020TrdTshiftPar::CbmMcbm2020TrdTshiftPar(const char* name, const char* title, const char* context)
22 : FairParGenericSet(name, title, context)
23 , fNtimeslices(1)
24{
25 detName = "TRD";
26}
27
29
30// ----- Public method clear ----
32
33{
34 status = kFALSE;
35 resetInputVersions();
36}
37
38// ----- Public method printparams ----
40
41{
42 std::cout << "CbmMcbm2020TrdTshiftPar::printparams() " << &fTimeshifts << std::endl;
43 size_t ntimeshifts = (fTimeshifts.GetSize() / (fgNchannels + 1));
44 std::cout << "ParSet has " << ntimeshifts << " timeshift changes stored" << std::endl;
45
46 for (size_t ishiftblock = 0; ishiftblock < ntimeshifts; ishiftblock++) {
47 std::cout << "Shiftblock of event " << fTimeshifts[ishiftblock * (fgNchannels + 1)] << std::endl;
48 for (size_t ichannel = 0; ichannel < fgNchannels; ichannel++) {
49 if (ichannel % 6 == 0) std::cout << std::endl;
50 std::cout << " Ch " << ichannel << " shift " << fTimeshifts[(ishiftblock * (fgNchannels + 1)) + ichannel];
51 }
52 }
53}
54
55// ---- putParams ----
57{
58 if (!l) return;
59 l->add(pararraynames[0].data(), fNtimeslices);
60 l->add(pararraynames[1].data(), fTimeshifts);
61}
62
63// ---- getParams ----
64Bool_t CbmMcbm2020TrdTshiftPar::getParams(FairParamList* l)
65{
66 if (!l) return kFALSE;
67
68 if (!l->fill(pararraynames[0].data(), &fNtimeslices)) return kFALSE;
69 if (!l->fill(pararraynames[1].data(), &fTimeshifts)) return kFALSE;
70
71 // Create a map from the list imported from the par file
72 size_t nthShift = 0;
73
74 size_t nentries = fTimeshifts.GetSize();
75 size_t ichannel = 0;
76 size_t itimeslice = 0;
77 for (size_t ientry = 0; ientry < nentries; ientry++) {
78 // We have a chain of one eventId value + fgNchannels shift values
79 nthShift = ientry / (fgNchannels + 1);
80
81 // Look for the first value in the chain, which is the eventId
82 if ((ientry - nthShift * (fgNchannels + 1)) == 0) {
83 // Before starting the extraction of the next chain, emplace the previous chain to the map
84 if (ientry != 0) {
85 auto tspair = std::pair<size_t, std::vector<Int_t>>(itimeslice, fvecCurrentTimeshifts);
86 fmapTimeshifts.emplace(tspair);
87 }
88 itimeslice = fTimeshifts[ientry];
91 }
92 else {
93 ichannel = ientry - 1 - nthShift * (fgNchannels + 1);
94 fvecCurrentTimeshifts[ichannel] = fTimeshifts[ientry];
95 }
96 }
97 // Now we have to fill the blank spots in the map, since, we do not now if the timeslices are accessed in a completely ordered manor
98 for (itimeslice = 0; itimeslice < static_cast<size_t>(std::abs(fNtimeslices[0])); itimeslice++) {
99 auto itspair = fmapTimeshifts.find(itimeslice);
100
101 if (itspair != fmapTimeshifts.end()) { continue; }
102 else {
103 // Get previous timeshift vector to add it also to the current pair
104 itspair--;
105
106 auto newtspair = std::pair<size_t, std::vector<Int_t>>(itimeslice, itspair->second);
107 fmapTimeshifts.emplace(newtspair);
108 }
109 }
110 return kTRUE;
111}
112
113// ---- GetTimeshifts ----
114bool CbmMcbm2020TrdTshiftPar::GetTimeshifts(std::shared_ptr<TH2> timeshiftHisto)
115{
116
118
119 fNtimeslices[0] = timeshiftHisto->GetNbinsX();
120 size_t nshifts = 1;
121 fvecCurrentTimeshifts.clear();
122 fvecCurrentTimeshifts.resize(0, 0);
124 Int_t tshift = 0;
125 size_t tsidx = 0;
126 size_t ientry = 0;
127 size_t eventId = 0;
128
129 // We write at least one shift value to fTimeshifts. Thus, we resize it to one valueset
130 size_t nentries = nshifts * (fgNchannels + 1);
131 fTimeshifts.Set(nentries);
132
133 bool didChange = true;
134 for (size_t ievent = 1; ievent < static_cast<size_t>(std::abs(fNtimeslices[0])); ievent++) {
135 tsidx = timeshiftHisto->GetXaxis()->GetBinLowEdge(ievent);
136 for (size_t ichannel = 0; ichannel < fgNchannels; ichannel++) {
137 tshift = (Int_t) timeshiftHisto->GetBinContent(ievent, ichannel);
138 if (tshift != fvecCurrentTimeshifts[ichannel]) {
139 didChange = true;
140 fvecCurrentTimeshifts[ichannel] = tshift;
141 }
142 }
143 if (didChange) {
144 // First resize the fTimeshifts array
145 nshifts++;
146 nentries = nshifts * (fgNchannels + 1);
147 fTimeshifts.Set(nentries);
148
149 // Then write the eventId correlated to the tsIdx to the array
150 // For mCbm2020 a timeslice contains 10 µslices, the tsidx jumps accordingly by 10, e.g. tsidx0 = 7 -> tsidx = 17
151 eventId = tsidx / 10;
152 fTimeshifts[ientry] = eventId;
153 ientry++;
154 // Followed by the channelwise shift values
155 for (size_t ichannel = 0; ichannel < fgNchannels; ichannel++) {
156 tshift = fvecCurrentTimeshifts[ichannel];
157 // The above represents the timeshift in multiples of a µSlice length (for mCbm 2020 1280 ns) since here we have time to do the calculation of the actual timeshift, we do it here and not in the unpacker algo.
158 tshift *= fgMicroSliceLength;
159 fTimeshifts.AddAt(tshift, ientry);
160 ientry++;
161 }
162 }
163 // reset didChange value
164 didChange = false;
165 }
166 return fTimeshifts.GetSize() > 0;
167}
168
169// ---- GetTimeshiftsVec ----
170std::vector<Int_t> CbmMcbm2020TrdTshiftPar::GetTimeshiftsVec(size_t tsidx)
171{
172 auto pair = fmapTimeshifts.find(tsidx);
173 return pair->second;
174}
175
176// ---- GetNEvents ----
177double CbmMcbm2020TrdTshiftPar::GetNEvents(std::shared_ptr<TFile> mcbmanafile)
178{
180
181 TH1* histo = nullptr;
182
183 // We have to do some hardcoding here, since the TrdAnalysisFramework is not yet in the common master. The handling with TAF in place will be given commented out
184
185 //First get the required histogram from the mcbmana file
186 // std::vector<CTAVM::eVars> varvec = {CTAVM::eVars::kRunId, CTAVM::eVars::kEnd, CTAVM::eVars::kEnd};
187 // auto weight = CTAVM::eVars::kNEvents;
188 // auto fillstation = CTAH::eFillStation::kRunInfo;
189 // auto htype = (int) CTAH::eHistoType::kGlobal;
190 // histo = CTAH::GetHistoFromFile(varvec, fillstation, htype, mcbmanafile, weight);
191
192 std::string hpath = "FillStation-RunInfo/FullTrd/RunId_wNEvents-RunInfo";
193 histo = mcbmanafile->Get<TH1>(hpath.data());
194 LOG_IF(fatal, !histo) << " CbmMcbm2020TrdTshiftPar::GetNEvents " << hpath.data() << " not found in the file"
195 << std::endl;
196 double nevents = histo->GetBinContent(histo->GetMaximumBin());
197 return nevents;
198}
199
200// ---- GetCalibHisto ----
201std::shared_ptr<TH3> CbmMcbm2020TrdTshiftPar::GetCalibHisto(std::shared_ptr<TFile> mcbmanafile)
202{
204 THnSparse* hsparse = nullptr;
205
206 // std::vector<CTAVM::eVars> varvec = {CTAVM::eVars::kTsSourceTsIndex, CTAVM::eVars::kDigiTrdChannel, CTAVM::eVars::kDigiDtCorrSlice};
207 // auto fillstation = CTAH::eFillStation::kTrdBmonDigi;
208 // auto htype = (int) CTAH::eHistoType::kGlobal;
209 // histo =
210 // (THnSparseD*) CTAH::GetHistoFromFile(varvec, fillstation, htype, mcbmanafile);
211
212 std::string hpath = "FillStation-TrdBmonDigi/FullTrd/"
213 "TsSourceTsIndex_DigiTrdChannel_DigiDtCorrSlice-TrdBmonDigi";
214 hsparse = mcbmanafile->Get<THnSparse>(hpath.data());
215
216 LOG_IF(fatal, !hsparse) << " CbmMcbm2020TrdTshiftPar::GetCalibHisto " << hpath.data() << " not found in the file"
217 << std::endl;
218
219 auto nevents = GetNEvents(mcbmanafile);
220
221 // auto tsaxis = CTAH::GetVarAxis(hsparse, CTAVM::eVars::kTsSourceTsIndex);
222 auto tsaxis = hsparse->GetAxis(0); // For now we know that the TsIndex is on the X-Axis
223 tsaxis->SetRangeUser(0.0, (double) nevents);
224 auto temphisto = hsparse->Projection(0, 1, 2);
225 auto histo = std::make_shared<TH3D>(*temphisto);
226 delete temphisto;
227 histo->SetName("calibbasehisto");
228 histo->SetTitle("calibbasehisto");
229 // We need the uniqueIDs for the correct handling within TAF
230 histo->GetXaxis()->SetUniqueID(hsparse->GetAxis(0)->GetUniqueID());
231 histo->GetYaxis()->SetUniqueID(hsparse->GetAxis(1)->GetUniqueID());
232 histo->GetZaxis()->SetUniqueID(hsparse->GetAxis(2)->GetUniqueID());
233
234 return histo;
235}
236
237// ---- GetCalibHisto ----
238std::shared_ptr<TH2> CbmMcbm2020TrdTshiftPar::GetCalibHisto(std::shared_ptr<TH3> calibbasehisto)
239{
241
242 // Get the x-axis definitions
243 size_t nevents = calibbasehisto->GetNbinsX();
244 size_t firstTsIdx = calibbasehisto->GetXaxis()->GetBinLowEdge(calibbasehisto->GetXaxis()->GetFirst());
245 size_t lastTsIdx = calibbasehisto->GetXaxis()->GetBinUpEdge(calibbasehisto->GetXaxis()->GetLast());
246
247 // Get the y-axis definitions
248 size_t nchannels = calibbasehisto->GetNbinsY();
249 size_t firstChannel = calibbasehisto->GetYaxis()->GetBinLowEdge(calibbasehisto->GetYaxis()->GetFirst());
250 size_t lastChannel = calibbasehisto->GetYaxis()->GetBinUpEdge(calibbasehisto->GetYaxis()->GetLast());
251
252 std::shared_ptr<TH2I> calibhisto = std::make_shared<TH2I>("calibhisto", "calibhisto", nevents, firstTsIdx, lastTsIdx,
253 nchannels, firstChannel, lastChannel);
254
255
256 for (size_t itsidx = 1; itsidx < nevents; itsidx++) {
257 for (size_t ichannel = 1; ichannel < nchannels; ichannel++) {
258 auto dominantshift = GetDominantShift(calibbasehisto, itsidx, ichannel) < 255
259 ? GetDominantShift(calibbasehisto, itsidx, ichannel)
260 : calibhisto->GetBinContent(itsidx - 1, ichannel);
261 if (itsidx - 1 == 0) dominantshift = 0;
262 calibhisto->SetBinContent(itsidx, ichannel, dominantshift);
263 }
264 }
265 return calibhisto;
266}
267
268// ---- GetDominantShift ----
269Int_t CbmMcbm2020TrdTshiftPar::GetDominantShift(std::shared_ptr<TH3> calibbasehisto, size_t itsidx, size_t ichannel)
270{
271 auto hdomshift = calibbasehisto->ProjectionZ("domshift", itsidx, itsidx, ichannel, ichannel);
272
273 // Scale histo to one
274 hdomshift->Scale(1. / hdomshift->Integral());
275
276 auto domshift = hdomshift->GetBinCenter(hdomshift->GetMaximumBin());
277 auto dominance = hdomshift->GetMaximum();
278
279 delete hdomshift;
280
281 // Only add dominant slices with at least 50% of the entries in the dominant slice
282
283 if (dominance > 0.5)
284 // if (dominance > 0.25)
285 return domshift;
286 else
287 return 255;
288}
289
290// ---- FillTimeshiftArray ----
291bool CbmMcbm2020TrdTshiftPar::FillTimeshiftArray(std::shared_ptr<TFile> mcbmanafile)
292{
294
295 auto calibbasehisto = GetCalibHisto(mcbmanafile);
296 auto calibhisto = GetCalibHisto(calibbasehisto);
297 return GetTimeshifts(calibhisto);
298}
299
ClassImp(CbmConverterManager)
std::map< size_t, std::vector< Int_t > > fmapTimeshifts
std::vector< Int_t > GetTimeshiftsVec(size_t tsidx)
Return the timeshift vector for a given Timeslice Index. Works only if getParams() was run before.
bool FillTimeshiftArray(std::shared_ptr< TFile > mcbmanafile)
Extract the timeshift values from a TAF output file that contains the required histograms and write t...
const std::vector< std::string > pararraynames
Names of the parameter arrays.
std::vector< Int_t > fvecCurrentTimeshifts
< Keys of the map are the tsIdx when a shift value for any channel changes, the vector contains the s...
std::shared_ptr< TH3 > GetCalibHisto(std::shared_ptr< TFile > mcbmanafile)
Extract the required base histogram from a mcbmana task output file.
TArrayI fTimeshifts
Array contains the timeshifts. Everytime a timeshift appears the tsIdx from the TS MetaData is follow...
Int_t GetDominantShift(std::shared_ptr< TH3 > calibbasehisto, size_t itsidx, size_t ichannel)
Extract the dominant shift value from the calibbase histogram. For a give tsIdx and channel.
double GetNEvents(std::shared_ptr< TFile > mcbmanafile)
Extract the number of events from a mcbmana task output file, which has to contain the required histo...
Bool_t getParams(FairParamList *)
const size_t fgNchannels
Number of channels on the single Trd module used during mCbm2020.
bool GetTimeshifts(std::shared_ptr< TH2 > timeshiftHisto)
Extract the timeshift values from a histo containing the information and write them to fTimeshifts.
TArrayI fNtimeslices
Number of timeslices in the given run. This is required to fill a complete fmapTimeshifts,...
const UInt_t fgMicroSliceLength
Length of a single microslice during mCbm 2020 data taking.
CbmMcbm2020TrdTshiftPar(const char *name="CbmMcbm2020TrdTshiftPar", const char *title="TRD timeshift unpacker parameters mCbm 2020", const char *context="Default")