18#include "TGraphErrors.h"
19#include "TMultiGraph.h"
20#include <fmt/format.h>
23unsigned int o2::tpc::IDCDrawHelper::getPad(
const unsigned int pad,
const unsigned int region,
const unsigned int row,
const Side
side)
32 poly->SetContour(255);
33 poly->SetTitle(
nullptr);
34 poly->GetYaxis()->SetTickSize(0.002f);
35 poly->GetYaxis()->SetTitleOffset(0.7f);
36 poly->GetZaxis()->SetTitleOffset(1.3f);
38 poly->GetZaxis()->SetTitle(zAxisTitle.data());
41 poly->SetMinimum(
minZ);
42 poly->SetMaximum(
maxZ);
45 TCanvas* can =
new TCanvas(
"can",
"can", 2000, 1400);
46 can->SetRightMargin(0.14f);
47 can->SetLeftMargin(0.06f);
48 can->SetTopMargin(0.04f);
52 for (
unsigned int region = startRegion; region < endRegion; ++region) {
56 const auto coordinate =
coords[padNum];
57 const float yPos = sign *
static_cast<float>(coordinate.yVals[0] + coordinate.yVals[2]) / 2;
58 const float xPos =
static_cast<float>(coordinate.xVals[0] + coordinate.xVals[2]) / 2;
59 poly->Fill(xPos, yPos, idc.
getIDC(sector, region, irow, ipad));
68 latex.DrawLatexNDC(.07, .9, fmt::format(
"Sector {}", sector).
data());
80 poly->SetMinimum(
minZ);
81 poly->SetMaximum(
maxZ);
84 TCanvas* can = ((TVirtualPad*)gROOT->GetSelectedPad()) ? ((TCanvas*)((TVirtualPad*)gROOT->GetSelectedPad()->GetCanvas())) :
new TCanvas(
"can",
"can", 650, 600);
85 can->SetTopMargin(0.04f);
86 can->SetRightMargin(0.14f);
87 can->SetLeftMargin(0.1f);
91 std::string sideName = (
side ==
Side::A) ?
"A-Side" :
"C-Side";
93 latex.DrawLatexNDC(.13, .9, sideName.data());
106 poly->SetContour(255);
107 poly->SetTitle(
nullptr);
108 poly->GetXaxis()->SetTitleOffset(1.2f);
109 poly->GetYaxis()->SetTitleOffset(1.3f);
110 poly->GetZaxis()->SetTitleOffset(1.3f);
111 poly->GetZaxis()->SetTitle(zAxisTitle.data());
112 poly->GetZaxis()->SetMaxDigits(3);
118 for (
unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
123 const float angDeg = 10.f + sector * 20;
124 auto coordinate =
coords[padNum];
125 coordinate.rotate(angDeg);
126 const float yPos =
static_cast<float>(coordinate.yVals[0] + coordinate.yVals[1] + coordinate.yVals[2] + coordinate.yVals[3]) / 4;
127 const float xPos =
static_cast<float>(coordinate.xVals[0] + coordinate.xVals[1] + coordinate.xVals[2] + coordinate.xVals[3]) / 4;
128 const auto padTmp = getPad(ipad, region, irow,
side);
129 poly->Fill(xPos, yPos, idc.
getIDC(sector, region, irow, padTmp));
141 const int bufferSize = TH1::GetDefaultBufferSize();
143 std::string sideName = (
side ==
Side::A) ?
"A" :
"C";
144 TH1F*
h =
new TH1F(fmt::format(
"h_{}_{}side",
type.data(), sideName).data(), fmt::format(
"{} ({}-Side)",
type.data(), sideName).data(), nbins1D, xMin1D, xMax1D);
148 for (
unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
152 const auto padTmp = getPad(ipad, region, irow,
side);
153 h->Fill(idc.
getIDC(sector, region, irow, padTmp));
158 TH1::SetDefaultBufferSize(bufferSize);
168 for (
unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
172 const auto padTmp = getPad(ipad, region, irow,
side);
174 const float padX = mapper.padCentre(padNum).x();
175 hist.Fill(padX, idc.
getIDC(sector, region, irow, padTmp));
186 outputCanvas.Divide(4, 18);
189 for (
unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
190 auto hIROC =
new TH1F(fmt::format(
"h1_{}_IROC_{:02}",
type.data(), sector).data(), fmt::format(
"{} distribution IROC {:02} {}-Side",
type.data(), sector, (
side ==
Side::A) ?
"A" :
"C").
data(), nbins1D, xMin1D, xMax1D);
191 auto hOROC1 =
new TH1F(fmt::format(
"h1_{}_OROC1_{:02}",
type.data(), sector).data(), fmt::format(
"{} distribution OROC1 {:02} {}-Side",
type.data(), sector, (
side ==
Side::A) ?
"A" :
"C").
data(), nbins1D, xMin1D, xMax1D);
192 auto hOROC2 =
new TH1F(fmt::format(
"h1_{}_OROC2_{:02}",
type.data(), sector).data(), fmt::format(
"{} distribution OROC2 {:02} {}-Side",
type.data(), sector, (
side ==
Side::A) ?
"A" :
"C").
data(), nbins1D, xMin1D, xMax1D);
193 auto hOROC3 =
new TH1F(fmt::format(
"h1_{}_OROC3_{:02}",
type.data(), sector).data(), fmt::format(
"{} distribution OROC3 {:02} {}-Side",
type.data(), sector, (
side ==
Side::A) ?
"A" :
"C").
data(), nbins1D, xMin1D, xMax1D);
197 const auto padTmp = getPad(ipad, region, irow,
side);
199 hIROC->Fill(idc.
getIDC(sector, region, irow, padTmp));
200 }
else if (region < 6) {
201 hOROC1->Fill(idc.
getIDC(sector, region, irow, padTmp));
202 }
else if (region < 8) {
203 hOROC2->Fill(idc.
getIDC(sector, region, irow, padTmp));
205 hOROC3->Fill(idc.
getIDC(sector, region, irow, padTmp));
210 outputCanvas.cd(pad);
212 hIROC->GetXaxis()->SetTitle(fmt::format(
"{}",
type.data()).data());
213 hIROC->SetTitleOffset(1.05,
"XY");
214 hIROC->SetTitleSize(0.05,
"XY");
216 outputCanvas.cd(pad);
218 hOROC1->GetXaxis()->SetTitle(fmt::format(
"{}",
type.data()).data());
219 hOROC1->SetTitleOffset(1.05,
"XY");
220 hOROC1->SetTitleSize(0.05,
"XY");
222 outputCanvas.cd(pad);
224 hOROC2->GetXaxis()->SetTitle(fmt::format(
"{}",
type.data()).data());
225 hOROC2->SetTitleOffset(1.05,
"XY");
226 hOROC2->SetTitleSize(0.05,
"XY");
228 outputCanvas.cd(pad);
230 hOROC3->GetXaxis()->SetTitle(fmt::format(
"{}",
type.data()).data());
231 hOROC3->SetTitleOffset(1.05,
"XY");
232 hOROC3->SetTitleSize(0.05,
"XY");
236 hIROC->SetBit(TObject::kCanDelete);
237 hOROC1->SetBit(TObject::kCanDelete);
238 hOROC2->SetBit(TObject::kCanDelete);
239 hOROC3->SetBit(TObject::kCanDelete);
245 std::string stype =
"IDC";
249 return fmt::format(
"#it{{{}}} (ADC)", stype);
253 return fmt::format(
"#it{{{}_{{0}}}} (ADC)", stype);
257 switch (compression) {
260 return fmt::format(
"#Delta#it{{{}}}", stype);
264 return fmt::format(
"#Delta#it{{{}}}_{{medium compressed}}", stype);
268 return fmt::format(
"#Delta#it{{{}}}_{{high compressed}}", stype);
273 return fmt::format(
"#it{{{}}}_{{1}}", stype);
281 const int gifSpeed = 40;
283 TCanvas can(
"canvas",
"canvas", 3350, 2000);
284 TPad padIDCA(
"padIDCA",
"padIDCA", 0, 0.25, 0.5, 1);
285 TPad padIDCC(
"padIDCC",
"padIDCC", 0.5, 0.25, 1, 1);
286 TPad padIDCOne(
"padIDCOne",
"padIDCOne", 0, 0, 1, 0.25);
288 const float tm = 0.04f;
289 const float rm = 0.14f;
290 const float lm = 0.1f;
291 const float bm = 0.2f;
292 padIDCA.SetTopMargin(tm);
293 padIDCA.SetRightMargin(rm);
294 padIDCA.SetLeftMargin(lm);
295 padIDCC.SetTopMargin(tm);
296 padIDCC.SetRightMargin(rm);
297 padIDCC.SetLeftMargin(lm);
298 padIDCOne.SetTopMargin(tm);
299 padIDCOne.SetRightMargin(rm / 2);
300 padIDCOne.SetLeftMargin(lm / 2);
301 padIDCOne.SetBottomMargin(bm);
307 std::array<TGraphErrors, SIDES> graphIDCOne;
308 std::array<TGraphErrors, SIDES> graphIDCOneSlice;
309 TMultiGraph multiGraph;
312 const float widthLine = 0.005f;
313 const float idcWH = 0.5;
314 for (
unsigned int sideT = 0; sideT <
SIDES; ++sideT) {
316 const auto col = (sideT == 0) ? (kGreen + 2) : kBlue;
317 graphIDCOne[sideT].SetFillColorAlpha(
col, 0.3);
318 graphIDCOne[sideT].SetLineWidth(5);
319 graphIDCOneSlice[sideT] = graphIDCOne[sideT];
320 graphIDCOneSlice[sideT].Set(1);
321 graphIDCOneSlice[sideT].SetFillColorAlpha(
col, 1);
322 for (
unsigned int slice = 0; slice < slices; ++slice) {
330 graphIDCOne[sideT].AddPoint(slice + idcWH, idc);
331 graphIDCOne[sideT].SetPointError(slice, idcWH, widthLine);
333 multiGraph.Add(&graphIDCOne[sideT]);
337 const int fontsize = 50;
338 multiGraph.GetXaxis()->SetTitleFont(font);
339 multiGraph.GetXaxis()->SetLabelFont(font);
340 multiGraph.GetYaxis()->SetTitleFont(font);
341 multiGraph.GetYaxis()->SetLabelFont(font);
342 multiGraph.GetXaxis()->SetLabelSize(fontsize);
343 multiGraph.GetXaxis()->SetTitleSize(fontsize);
344 multiGraph.GetYaxis()->SetLabelSize(fontsize);
345 multiGraph.GetYaxis()->SetTitleSize(fontsize);
346 multiGraph.GetXaxis()->SetTitle(
"#it{t} (ms)");
347 multiGraph.GetXaxis()->SetTitleOffset(0.9f);
348 multiGraph.GetYaxis()->SetTitleOffset(1.5f);
350 multiGraph.SetMinimum(0.9 *
minY);
351 multiGraph.SetMaximum(1.1 *
maxY);
352 multiGraph.GetXaxis()->SetLimits(0, slices);
354 for (
unsigned int slice = 0; slice < slices; ++slice) {
355 LOGP(info,
"Drawing slice {} from {}", slice, slices - 1);
357 std::function<float(
const unsigned int,
const unsigned int,
const unsigned int,
const unsigned int)> idcFunc = [slice, idcs](
const unsigned int sector,
const unsigned int region,
const unsigned int irow,
const unsigned int pad) {
358 return idcs.
mIDCFunc(sector, region, irow, pad, slice);
362 TH2Poly* poly[
SIDES]{
nullptr,
nullptr};
363 for (
int sideT = 0; sideT <
SIDES; ++sideT) {
366 poly[sideT]->GetXaxis()->SetTitleFont(font);
367 poly[sideT]->GetXaxis()->SetLabelFont(font);
368 poly[sideT]->GetYaxis()->SetTitleFont(font);
369 poly[sideT]->GetYaxis()->SetLabelFont(font);
370 poly[sideT]->GetXaxis()->SetLabelSize(fontsize);
371 poly[sideT]->GetXaxis()->SetTitleSize(fontsize);
372 poly[sideT]->GetYaxis()->SetLabelSize(fontsize);
373 poly[sideT]->GetYaxis()->SetTitleSize(fontsize);
376 poly[sideT]->SetMinimum(
minZ);
377 poly[sideT]->SetMaximum(
maxZ);
386 poly[sideT]->Draw(
"colz");
387 const std::string sideName = (
side ==
Side::A) ?
"A-Side" :
"C-Side";
390 latex.SetTextColor(
col);
391 latex.DrawLatexNDC(0.13, 0.9, sideName.data());
393 latex.DrawLatexNDC(0.62, 0.9, fmt::format(
"Run {}", run).data());
395 graphIDCOneSlice[sideT].SetPoint(0, slice + idcWH, idcs.
mIDCOneFunc(
side, slice));
396 graphIDCOneSlice[sideT].SetPointError(0, idcWH, widthLine);
400 multiGraph.Draw(
"ZA E2");
401 graphIDCOneSlice[0].Draw(
"Z E2 SAME");
402 graphIDCOneSlice[1].Draw(
"Z E2 SAME");
404 can.Print(Form(
"%s.gif+%i",
filename.data(), gifSpeed));
405 if (slice == (slices - 1)) {
406 can.Print(Form(
"%s.gif++",
filename.data()));
helper class for drawing IDCs per region/side
Class for time synchronization of RawReader instances.
static void drawIDCZeroStackCanvas(const IDCDraw &idc, const o2::tpc::Side side, const std::string_view type, const int nbins1D, const float xMin1D, const float xMax1D, TCanvas &outputCanvas, int integrationInterval)
static void drawSideGIF(const IDCDrawGIF &idcs, const unsigned int slices, const std::string zAxisTitle, const std::string filename="IDCs", const float minZ=0, const float maxZ=-1, const int run=-1)
make a GIF of IDCs for A and C side and the 1D IDCs
static std::string getZAxisTitle(const IDCType type, const IDCDeltaCompression compression=IDCDeltaCompression::NO)
static void drawRadialProfile(const IDCDraw &idc, TH2F &hist, const o2::tpc::Side side)
static void drawSector(const IDCDraw &idc, const unsigned int startRegion, const unsigned int endRegion, const unsigned int sector, const std::string zAxisTitle, const std::string filename, const float minZ=0, const float maxZ=-1)
static void drawSide(const IDCDraw &idc, const o2::tpc::Side side, const std::string zAxisTitle, const std::string filename, const float minZ=0, const float maxZ=-1)
static GlobalPadNumber getGlobalPadNumber(const unsigned int lrow, const unsigned int pad, const unsigned int region)
static const std::vector< unsigned int > PADSPERROW[NREGIONS]
number of pads per row in region
static Mapper & instance(const std::string mappingDir="")
static constexpr unsigned int ROWSPERREGION[NREGIONS]
number of pad rows for region
static constexpr unsigned int NSECTORS
total number of sectors in the TPC
static constexpr unsigned int NREGIONS
total number of regions in one sector
static constexpr unsigned short getPadsInSector()
static constexpr int MAXSECTOR
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
GLsizei const GLubyte GLsizei GLenum const void * coords
GLint GLint GLsizei GLint GLenum GLenum type
GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat maxZ
constexpr unsigned char SECTORSPERSIDE
@ IDC
integrated and grouped IDCs
@ IDCOne
IDC1: I_1(t) = <I(r,\phi,t) / I_0(r,\phi)>_{r,\phi}.
@ IDCZero
IDC0: I_0(r,\phi) = <I(r,\phi,t)>_t.
@ IDCDelta
IDCDelta: \Delta I(r,\phi,t) = I(r,\phi,t) / ( I_0(r,\phi) * I_1(t) )
constexpr unsigned char SIDES
IDCDeltaCompression
IDC Delta IDC Compression types.
@ HIGH
high compression using char (data compression ratio ~5.5 when stored in CCDB)
@ NO
no compression using floats
@ MEDIUM
medium compression using short (data compression ratio 2 when stored in CCDB)
std::function< float(const o2::tpc::Side side, const unsigned int)> mIDCOneFunc
function returning the value which will be drawn for side, slice
std::function< float(const unsigned int, const unsigned int, const unsigned int, const unsigned int, const unsigned int)> mIDCFunc
function returning the value which will be drawn for sector, region, row, pad
std::function< float(const unsigned int, const unsigned int, const unsigned int, const unsigned int)> mIDCFunc
function returning the value which will be drawn for sector, region, row, pad
float getIDC(const unsigned int sector, const unsigned int region, const unsigned int row, const unsigned int pad) const
static TH2Poly * makeSectorHist(const std::string_view name="hSector", const std::string_view title="Sector;local #it{x} (cm);local #it{y} (cm)", const float xMin=83.65f, const float xMax=247.7f, const float yMin=-43.7f, const float yMax=43.7f, const Type type=Type::Pad)
static void drawSectorLocalPadNumberPoly(short padTextColor=kBlack, float lineScalePS=1)
static TH2Poly * makeSideHist(Side side, const Type type=Type::Pad)
static void drawSectorInformationPoly(short regionLineColor=kRed, short rowTextColor=kRed)
static void drawSectorsXY(Side side, int sectorLineColor=920, int sectorTextColor=1)
draw sector boundaris, side name and sector numbers
static std::vector< PadCoordinates > getPadCoordinatesSector()
create a vector of pad corner coordinate for one full sector