Belle II Software development
ARICHMergerHist.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * *
4 * This file is licensed under LGPL-3.0, see LICENSE.md. *
5 **************************************************************************/
6
7#include <arich/utility/ARICHMergerHist.h>
8#include <framework/logging/Logger.h>
9
10#include <TLine.h>
11#include <TColor.h>
12#include <TGraph.h>
13#include <TAxis.h>
14#include <TLatex.h>
15#include <map>
16
17#include <cmath>
18
19#ifndef M_PI
20#define M_PI 3.14159265358979323846
21#endif
22
23using namespace Belle2;
24
25// Map: MergerID -> internal index (1..72)
26static const std::map<int, int> MERGER_TO_INTERNAL = {
27 {53, 1}, {24, 2}, {22, 3}, {11, 4}, {2, 5}, {12, 6}, {76, 7}, {34, 8}, {32, 9}, {72, 10},
28 {7, 11}, {66, 12}, {97, 13}, {63, 14}, {19, 15}, {57, 16}, {5, 17}, {79, 18}, {6, 19}, {80, 20},
29 {10, 21}, {37, 22}, {60, 23}, {35, 24}, {30, 25}, {41, 26}, {69, 27}, {20, 28}, {55, 29}, {47, 30},
30 {71, 31}, {15, 32}, {14, 33}, {74, 34}, {77, 35}, {64, 36}, {62, 37}, {67, 38}, {82, 39}, {56, 40},
31 {68, 41}, {78, 42}, {46, 43}, {81, 44}, {27, 45}, {39, 46}, {18, 47}, {44, 48}, {17, 49}, {25, 50},
32 {16, 51}, {51, 52}, {1, 53}, {61, 54}, {54, 55}, {48, 56}, {8, 57}, {29, 58}, {3, 59}, {73, 60},
33 {93, 61}, {38, 62}, {58, 63}, {59, 64}, {50, 65}, {26, 66}, {31, 67}, {33, 68}, {49, 69}, {65, 70},
34 {52, 71}, {75, 72}
35};
36
37// --------------------------------------------------
38// Geometry
39// --------------------------------------------------
40static const double SECTOR_CENTER_DEG[7] =
41{0.0, 30.0, 90.0, 150.0, 210.0, 270.0, 330.0};
42
43// Global drawing scale (conversion to ROOT coordinates)
44static const double GEOM_SCALE = 11.0;
45
46// Block size
47static const double BLOCK_W = 1.3 * GEOM_SCALE;
48static const double BLOCK_H = 0.8 * GEOM_SCALE;
49
50// Ring radii
51static const double R1 = 6.1 * GEOM_SCALE;
52static const double R2 = 7.7 * GEOM_SCALE;
53static const double R3 = 9.5 * GEOM_SCALE;
54static const double R4 = 11.25 * GEOM_SCALE;
55
56static const double ROW1_OFFSETS[3] = {+21.5, 0.0, -21.5};
57static const double ROW2_OFFSETS[4] = {+22.5, +9.5, -9.5, -22.5};
58static const double ROW3_OFFSETS[4] = {+19.0, +8.0, -8.0, -19.0};
59static const double ROW4_OFFSETS[1] = {+1.0};
60// --------------------------------------------------
61
62void ARICHMergerHist::pol2xy(double r, double angDeg, double& x, double& y)
63{
64 const double th = angDeg * M_PI / 180.0;
65 x = r * std::cos(th);
66 y = r * std::sin(th);
67}
68
70 const char* title,
71 double globalRotationDeg,
72 bool rightToLeftNumbering)
73 : TH2Poly()
74{
75 m_globalRotationDeg = globalRotationDeg;
76 m_rightToLeft = rightToLeftNumbering;
77 m_merger2bin.assign(72, 0);
78
79 SetName(name);
80 SetTitle(title);
81
82 int polyBin = 1;
83 int mergerNumber = 1;
84
85 auto add_block = [&](double r, double angDeg) {
86
87 double cx, cy;
88 pol2xy(r, angDeg, cx, cy);
89
90 const double rot = (angDeg + 90.0) * M_PI / 180.0;
91 const double c = std::cos(rot);
92 const double s = std::sin(rot);
93
94 const double hx = BLOCK_W / 2.0;
95 const double hy = BLOCK_H / 2.0;
96
97 const double lx[5] = {-hx, +hx, +hx, -hx, -hx};
98 const double ly[5] = {-hy, -hy, +hy, +hy, -hy};
99
100 double gx[5], gy[5];
101 for (int i = 0; i < 5; ++i) {
102 const double rx = lx[i] * c - ly[i] * s;
103 const double ry = lx[i] * s + ly[i] * c;
104 gx[i] = rx + cx;
105 gy[i] = ry + cy;
106 }
107
108 auto* g = new TGraph(5, gx, gy);
109 AddBin(g);
110
111 if (mergerNumber >= 1 && mergerNumber <= 72)
112 m_merger2bin[mergerNumber - 1] = polyBin;
113
114 ++polyBin;
115 ++mergerNumber;
116 };
117
118 auto add_ring = [&](double r, const double * offsets, int nOffsets, double centerDeg) {
119 if (m_rightToLeft) {
120 for (int i = nOffsets - 1; i >= 0; --i)
121 add_block(r, centerDeg + offsets[i]);
122 } else {
123 for (int i = 0; i < nOffsets; ++i)
124 add_block(r, centerDeg + offsets[i]);
125 }
126 };
127
128 for (int X = 1; X <= 6; ++X) {
129 const double cdeg = SECTOR_CENTER_DEG[X] + m_globalRotationDeg;
130
131 add_ring(R1, ROW1_OFFSETS, 3, cdeg);
132 add_ring(R2, ROW2_OFFSETS, 4, cdeg);
133 add_ring(R3, ROW3_OFFSETS, 4, cdeg);
134 add_block(R4, cdeg + ROW4_OFFSETS[0]);
135 }
136
137 if (mergerNumber != 73)
138 B2ERROR("ARICHMergerHist internal error: expected 72 bins, got "
139 << mergerNumber - 1);
140
141 SetOption("colz");
142 SetStats(0);
143 GetXaxis()->SetLimits(-140., 140.);
144 GetYaxis()->SetLimits(-140., 140.);
145}
146
147// --------------------------------------------------
148// Using 1..72 Merger position (1_1,...,1_12,...,6_12)
149// --------------------------------------------------
151{
152 if (!hist) return;
153
154 if (hist->GetNbinsX() != 72) {
155 B2ERROR("ARICHMergerHist::fillFromTH1: histogram must have 72 bins (got "
156 << hist->GetNbinsX() << ")");
157 return;
158 }
159
160 for (int i = 1; i <= 72; ++i) {
161 const int b = m_merger2bin[i - 1];
162 SetBinContent(b, hist->GetBinContent(i));
163 }
164}
165
166// --------------------------------------------------
167// Using MergerID numbering
168// --------------------------------------------------
169void ARICHMergerHist::SetBinContentFromSN(unsigned mergerID, double value)
170{
171 if (mergerID < 1 || mergerID > 100) return;
172
173 int internal = MERGER_TO_INTERNAL.at(mergerID);
174 int polybin = m_merger2bin[internal - 1];
175
176 SetBinContent(polybin, value);
177}
178
179void ARICHMergerHist::Draw(Option_t* option)
180{
181 TH2Poly::Draw(option);
182
183 // -------------------------------------------------
184 // Sector lines
185 // -------------------------------------------------
186 const double rInner = 50.0;
187 const double rOuter = 130.0;
188
189 for (int k = 0; k < 6; ++k) {
190 const double aDeg = k * 60.0 + m_globalRotationDeg;
191
192 double x1, y1, x2, y2;
193 pol2xy(rInner, aDeg, x1, y1);
194 pol2xy(rOuter, aDeg, x2, y2);
195
196 m_lines[k] = TLine(x1, y1, x2, y2);
197 m_lines[k].SetLineWidth(2);
198 m_lines[k].SetLineColor(kGray + 2);
199 m_lines[k].Draw();
200 }
201
202 // -------------------------------------------------
203 // Sector labels S-1 ... S-6
204 // -------------------------------------------------
205 const double rLabel = 45.0;
206
207 for (int s = 0; s < 6; ++s) {
208 const double centerDeg = SECTOR_CENTER_DEG[s + 1] + m_globalRotationDeg;
209
210 double x, y;
211 pol2xy(rLabel, centerDeg, x, y);
212
213 auto* txt = new TLatex(x, y, Form("S-%d", s + 1));
214 txt->SetBit(kCanDelete);
215 txt->SetTextAlign(22);
216 txt->SetTextFont(62);
217 txt->SetTextSize(0.030);
218 txt->Draw();
219 }
220}
void fillFromTH1(TH1 *hist)
Fill from TH1.
void Draw(Option_t *option="") override
Draw with sector lines and labels.
static void pol2xy(double r, double angDeg, double &x, double &y)
Convert polar coordinates to cartesian.
bool m_rightToLeft
If true, numbering in each ring is right-to-left.
ARICHMergerHist()=default
Default constructor.
double m_globalRotationDeg
Global rotation applied to the geometry (degrees).
TLine m_lines[6]
Sector boundary lines drawn on top of the histogram.
std::vector< int > m_merger2bin
Merger number (1..72) → TH2Poly bin index.
void SetBinContentFromSN(unsigned mergerID, double value)
Set content using the real ARICH hardware MergerID.
Abstract base class for different kinds of events.