BmnRoot
Loading...
Searching...
No Matches
BmnHistHgnd.cxx
Go to the documentation of this file.
1#include "BmnHistHgnd.h"
2
3#include "BmnHgndDigi.h"
4#include "TGaxis.h"
5
6BmnHistHgnd::BmnHistHgnd(TString title, TString path, Int_t PeriodID, BmnSetup stp)
7 : BmnHist(PeriodID, stp)
8{
9 fTitle = title;
10 fName = title + "_cl";
11 SetGeometry(Form("Hgnd_geo_period%d.root", PeriodID));
12 TGaxis::SetMaxDigits(2);
13 InitializeAddresses();
15}
16
18{
19 if (fDir) {
20 LOG(info) << "BmnHistHgnd::~BmnHistHgnd: fDir return";
21 return;
22 }
23 for (auto& canvasInfo : m_canvases) {
24 if (canvasInfo) {
25 for (auto*& pad : canvasInfo->pads) {
26 if (pad) {
27 delete pad;
28 pad = nullptr;
29 }
30 }
31 canvasInfo->pads.clear();
32 }
33 delete canvasInfo->canvas;
34 }
35}
36
37void BmnHistHgnd::SetGeometry(const std::string& path)
38{
39 LOG(debug) << "BmnHistHgnd::SetGeometry " << path;
40 fGeoHandler = std::make_unique<BmnNdetGeo>();
41 fGeoHandler->ReadGeometryFromFile(path);
42}
43
44void BmnHistHgnd::InitializeAddresses()
45{
46 fAddresses.clear();
47
48 // Detectors (1 and 2 for Hgnd)
49 std::vector<int> detectors = {1, 2};
50
51 for (int det : detectors) {
52 for (uint32_t lay = 1; lay <= kLAYRS; ++lay) {
53 for (uint32_t row = 1; row <= kROWS; ++row) {
54 for (uint32_t col = 1; col <= kCOLS; ++col) {
55 uint32_t address = BmnNdetAddress::GetAddress(det, row, col, lay);
56 fAddresses.insert(address);
57 }
58 }
59 }
60 }
61
62 LOG(info) << "BmnHistHgnd: initialized " << fAddresses.size() << " addresses";
63}
64
65void BmnHistHgnd::setupAxis(TH1* hist, const std::string& xTitle, const std::string& yTitle)
66{
67 if (!xTitle.empty()) {
68 hist->GetXaxis()->SetTitle(xTitle.c_str());
69 hist->GetXaxis()->SetTitleColor(kOrange + 10);
70 }
71 if (!yTitle.empty()) {
72 hist->GetYaxis()->SetTitle(yTitle.c_str());
73 hist->GetYaxis()->SetTitleColor(kOrange + 10);
74 }
75}
76
78{
79 // Helper lambdas
80 auto createH1 = [this](const std::string& name, const std::string& title, int nbins, double xmin, double xmax,
81 const std::string& xTitle = "", const std::string& yTitle = "") -> TH1F* {
82 TString fullName = fTitle + "_" + name;
83 auto* hist = new TH1F(fullName, title.c_str(), nbins, xmin, xmax);
84 setupAxis(hist, xTitle, yTitle);
85 m_allHistograms.push_back(hist);
86 return hist;
87 };
88
89 auto createH2 = [this](const std::string& name, const std::string& title, int nbinsx, double xmin, double xmax,
90 int nbinsy, double ymin, double ymax, const std::string& xTitle = "",
91 const std::string& yTitle = "") -> TH2F* {
92 TString fullName = fTitle + "_" + name;
93 auto* hist = new TH2F(fullName, title.c_str(), nbinsx, xmin, xmax, nbinsy, ymin, ymax);
94 setupAxis(hist, xTitle, yTitle);
95 hist->GetZaxis()->SetNoExponent(kFALSE);
96 hist->SetOption("colz");
97 hist->SetStats(0);
98 m_allHistograms.push_back(hist);
99 return hist;
100 };
101
102 auto addCanvas = [this](const std::string& name, int w, int h, int rows = 1, int cols = 1) -> CanvasInfo* {
103 TString fullName = fTitle + name;
104 auto* canvas = new TCanvas(fullName, fullName, w, h);
105 if (rows > 1 || cols > 1)
106 canvas->Divide(rows, cols);
107
108 auto info = std::make_unique<CanvasInfo>(canvas);
109 CanvasInfo* ptr = info.get();
110 m_canvases.push_back(std::move(info));
111 return ptr;
112 };
113
114 auto addPad = [](CanvasInfo* cinfo, TH1* hist, const std::string& opt, const std::string& name = "") {
115 auto* pad = new PadInfo(hist);
116 pad->opt = opt;
117 if (!name.empty()) {
118 pad->name = name;
119 } else {
120 pad->name = hist->GetName();
121 }
122 cinfo->pads.push_back(pad);
123 };
124
125 // 1D histograms
126 h1_ECells =
127 createH1("h1_ECells", "Hgnd signal in cells", kROWS * kCOLS, 0, kROWS * kCOLS, "Cell id", "Average Signal");
128 h1_ProfileSlice =
129 createH1("h1_ProfileSlice", "Energy in detector slice", kLAYRS, 1, kLAYRS + 1, "Layer id", "Events");
130
131 // 2D histograms
132 h2_grid =
133 createH2("h2_grid", "Hgnd_Grid", kROWS + 2, 0, kROWS + 2, kCOLS + 2, 0, kCOLS + 2, "X position", "Y position");
134 h2_Layer_Cell = createH2("h2_Layer_Cell", "h2_Layer_Cell", kLAYRS + 2, 0, kLAYRS + 2, kROWS * kCOLS + 2, 0,
135 kROWS * kCOLS + 2, "Layer number", "Cell number");
136
137 for (uint32_t layer = 1; layer <= kLAYRS; ++layer) {
138 TString ampName = fTitle + TString::Format("_hLayer%d_Amp", layer);
139 hLayerAmps[layer] =
140 new TH2F(ampName, TString::Format("Layer %d Amplitudes", layer), kROWS, 0, kROWS, kCOLS, 0, kCOLS);
141 setupAxis(hLayerAmps[layer], "Column", "Row");
142 m_allHistograms.push_back(hLayerAmps[layer]);
143 }
144
145 // Address-indexed histograms
146 for (uint32_t address : fAddresses) {
147 int arm = BmnNdetAddress::GetArmId(address);
148 int lay = BmnNdetAddress::GetLayerId(address);
149 int row = BmnNdetAddress::GetRowId(address);
150 int col = BmnNdetAddress::GetColumnId(address);
151
152 // Profile histogram (signal vs lay for this cell)
153 if (lay == 1) {
154 TString profName = fTitle + TString::Format("_hProfCell_%08X", address);
155 hProfCell[address] =
156 new TH1F(profName, TString::Format("D%d R%d C%d Profile", arm, row, col), kLAYRS, 1, kLAYRS + 1);
157 setupAxis(hProfCell[address], "Layer id", "Average Signal");
158 m_allHistograms.push_back(hProfCell[address]);
159 }
160
161 // Amplitude histogram
162 TString ampTimeName = fTitle + TString::Format("_hCellAmpTime_%08X", address);
163 hCellAmpTime[address] = new TH2F(ampTimeName, TString::Format("D%d L%d R%d C%d Amplitude", arm, lay, row, col),
164 100, 0, 100, 100, -300, 300);
165 setupAxis(hCellAmpTime[address], "Signal", "");
166 m_allHistograms.push_back(hCellAmpTime[address]);
167 }
168
169 // Canvases
170 auto* canAmpsInfo = addCanvas("CanvasAmplitudes", PAD_WIDTH, PAD_HEIGHT, 2, 1);
171 addPad(canAmpsInfo, h2_grid, "colz", "h2_grid");
172 addPad(canAmpsInfo, h1_ECells, "hist", "h1_ECells");
173
174 auto* canvSliceInfo = addCanvas("CanvasSlice", PAD_WIDTH, PAD_HEIGHT, 2, 1);
175 addPad(canvSliceInfo, h2_Layer_Cell, "colz", "h2_Layer_Cell");
176 addPad(canvSliceInfo, h1_ProfileSlice, "hist", "h1_ProfileSlice");
177
178 // Profile canvas - show first lay only (original behavior)
179 auto* canvProfInfo = addCanvas("CanvasProfiles", PAD_WIDTH, PAD_HEIGHT, kROWS, kCOLS);
180 for (uint32_t address : fAddresses) {
181 int lay = BmnNdetAddress::GetLayerId(address);
182 if (lay == 1) {
183 int row = BmnNdetAddress::GetRowId(address);
184 int col = BmnNdetAddress::GetColumnId(address);
185 addPad(canvProfInfo, hProfCell[address], "hist", TString::Format("R%dC%d", row, col).Data());
186 }
187 }
188
189 // Cell amplitude canvas - show all addresses
190 auto* canvCellAmpInfo = addCanvas("CanvasCellAmp", PAD_WIDTH, PAD_HEIGHT, kROWS, kCOLS);
191 for (uint32_t address : fAddresses) {
192 int lay = BmnNdetAddress::GetLayerId(address);
193 int row = BmnNdetAddress::GetRowId(address);
194 int col = BmnNdetAddress::GetColumnId(address);
195 addPad(canvCellAmpInfo, hCellAmpTime[address], "hist", TString::Format("L%d_R%dC%d", lay, row, col).Data());
196 }
197}
198
199void BmnHistHgnd::Register(THttpServer* serv)
200{
201 fServer = serv;
202 fServer->Register("/", this);
203 TString path = "/" + fTitle + "/";
204
205 for (auto& cinfo_ptr : m_canvases) {
206 fServer->Register(path, cinfo_ptr->canvas);
207 }
208
209 TString cmd = "/" + fName + "/->Reset()";
210 fServer->SetItemField(path.Data(), "_monitoring", "2000");
211 fServer->SetItemField(path.Data(), "_layout", "grid11x11");
212 TString cmdTitle = path + "Reset";
213 fServer->RegisterCommand(cmdTitle.Data(), cmd.Data(), "button;");
214 fServer->Restrict(cmdTitle, "visible=shift");
215 fServer->Restrict(cmdTitle, "allow=shift");
216 cmd = "/" + fName + "/->SetRefRun(%arg1%)";
217 cmdTitle = path + "SetRefRun";
218 fServer->RegisterCommand(cmdTitle.Data(), cmd.Data(), "button;");
219 cmdTitle = path + "ChangeSelection";
220 fServer->RegisterCommand(cmdTitle, TString("/") + fName.Data() + "/->SetSelection(%arg1%)", "button;");
221 fServer->Restrict(cmdTitle, "visible=shift");
222 fServer->Restrict(cmdTitle, "allow=shift");
223 fServer->Restrict(cmdTitle.Data(), "deny=guest");
224}
225
226void BmnHistHgnd::SetDir(TFile* outFile, TTree* recoTree)
227{
228 frecoTree = recoTree;
229 fDir = nullptr;
230 if (outFile) {
231 fDir = outFile->mkdir(fTitle + "_hists");
232 }
233
234 for (auto* hist : m_allHistograms) {
235 hist->SetDirectory(fDir);
236 }
237}
238
239void BmnHistHgnd::SetSelection(Int_t Trigger)
240{
241 fSelection = true;
242 fSelectedTrigger = Trigger;
243 Reset();
244}
245
247{
248 for (auto& cinfo_ptr : m_canvases) {
249 BmnHist::DrawRef(cinfo_ptr->canvas, &cinfo_ptr->pads);
250 }
251}
252
254{
255 BmnEventHeader* head = fDigiArrays->header;
256 TClonesArray* digits = fDigiArrays->hgnd;
257 if (!digits)
258 return;
259
260 if (fSelection && ((head->GetInputSignalsAR() >> fSelectedTrigger) & 1)) {
261 // Scale by event counter
262 double scale = 1.0 / fEventCounter;
263 h1_ECells->Scale(scale);
264 h1_ProfileSlice->Scale(scale);
265 h2_grid->Scale(scale);
266 h2_Layer_Cell->Scale(scale);
267
268 // Scale address-indexed histograms
269 for (auto& [address, hist] : hProfCell) {
270 if (hist)
271 hist->Scale(scale);
272 }
273
274 for (Int_t iDig = 0; iDig < digits->GetEntriesFast(); iDig++) {
275 auto* digi = static_cast<BmnHgndDigi*>(digits->At(iDig));
276
277 uint32_t address = digi->GetAddress();
278 double signal = digi->GetSignal();
279 double time = digi->GetTime();
280 auto arm = digi->GetArmId();
281 auto row = digi->GetRowId();
282 auto col = digi->GetColumnId();
283 auto cell = (row - 1) * kCOLS + col;
284 auto lay = digi->GetLayerId();
285
286 // Verify address is known
287 if (fAddresses.find(address) == fAddresses.end()) {
288 LOG(debug) << "Unknown Hgnd address: " << address;
289 continue;
290 }
291
292 // Fill histograms
293 h1_ECells->Fill(cell, signal);
294 h1_ProfileSlice->Fill(lay, signal);
295 h2_grid->Fill(col, row, signal);
296 h2_Layer_Cell->Fill(lay, cell, signal);
297
298 // Fill per-cell histograms
299 if (hCellAmpTime.find(address) != hCellAmpTime.end()) {
300 hCellAmpTime[address]->Fill(signal, time);
301 }
302 if (hProfCell.find(BmnNdetAddress::GetAddress(arm, row, col, 1)) != hProfCell.end()) {
303 hProfCell[BmnNdetAddress::GetAddress(arm, row, col, 1)]->Fill(lay, signal);
304 }
305 if (hLayerAmps.find(lay) != hLayerAmps.end()) {
306 hLayerAmps[lay]->Fill(row, col, signal);
307 }
308 }
309
310 fEventCounter++;
311 }
312}
313
315{
316 TString FileName = Form("bmn_run%04d_hist.root", id);
317 printf("SetRefRun: %s\n", FileName.Data());
318 if (refRunName != FileName) {
319 refRunName = FileName;
320 refID = id;
321
322 for (auto& cinfo_ptr : m_canvases) {
323 BmnHist::LoadRefRun(refID, refPath + FileName, fTitle, cinfo_ptr->pads);
324 }
325
326 DrawBoth();
327 }
328 return kBMNSUCCESS;
329}
330
332{
333 for (auto& cinfo_ptr : m_canvases) {
334 for (auto* pad : cinfo_ptr->pads) {
335 if (pad->ref) {
336 delete pad->ref;
337 pad->ref = nullptr;
338 }
339 }
340 }
341 refID = 0;
342}
343
345{
346 printf("BmnHistHgnd : Reset histos\n");
347 fEventCounter = 1;
348
349 for (auto* hist : m_allHistograms) {
350 hist->Reset();
351 }
352}
#define PAD_WIDTH
Definition BmnAdcQA.cxx:3
#define PAD_HEIGHT
Definition BmnAdcQA.cxx:4
BmnStatus
Definition BmnEnums.h:24
@ kBMNSUCCESS
Definition BmnEnums.h:25
BmnSetup
Definition BmnEnums.h:89
uint32_t GetAddress() const
UInt_t GetInputSignalsAR()
Data structure for a single HGND digit.
Definition BmnHgndDigi.h:20
virtual ~BmnHistHgnd()
void FillFromDigi(DigiArrays *fDigiArrays) override
void SetDir(TFile *outFile, TTree *recoTree) override
void SetSelection(Int_t Trigger)
void CreateHistos()
void ClearRefRun() override
BmnHistHgnd(TString title, TString path, Int_t PeriodID, BmnSetup stp)
void Register(THttpServer *serv) override
BmnStatus SetRefRun(Int_t id)
void DrawBoth() override
void Reset() override
TTree * frecoTree
Definition BmnHist.h:88
Int_t refID
Definition BmnHist.h:92
TString refPath
Definition BmnHist.h:90
TDirectory * fDir
Definition BmnHist.h:89
static void DrawRef(unique_ptr< TCanvas > &canGemStrip, vector< PadInfo * > *canGemStripPads)
Definition BmnHist.cxx:15
TString refRunName
Definition BmnHist.h:91
static BmnStatus LoadRefRun(Int_t refID, TString FullName, TString fTitle, vector< PadInfo * > canPads, vector< TString > Names)
Definition BmnHist.cxx:100
THttpServer * fServer
Definition BmnHist.h:87
static uint32_t GetRowId(uint32_t address)
Return Row id from address.
static uint32_t GetAddress(uint32_t ArmId, uint32_t RowId, uint32_t ColumnId, uint32_t LayerId)
Return address.
static uint32_t GetColumnId(uint32_t address)
Return Column id from address.
static uint32_t GetArmId(uint32_t address)
Return Arm id from address.
static uint32_t GetLayerId(uint32_t address)
Return Layer id from address.
TClonesArray * hgnd
Definition DigiArrays.h:137
BmnEventHeader * header
Definition DigiArrays.h:146
Storage for pad content and it's options.
Definition PadInfo.h:20
std::vector< PadInfo * > pads
Definition BmnHistHgnd.h:26