Project
Loading...
Searching...
No Matches
SACs.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <Framework/Logger.h>
13#include "TPCQC/SACs.h"
15#include "TH2Poly.h"
16#include "fmt/format.h"
17#include "TText.h"
18#include "TGraph.h"
19#include "TStyle.h"
20#include "TColor.h"
21
23using namespace o2::tpc::qc;
24
25float SACs::getSACOneVal(const Side side, unsigned int integrationInterval) const
26{
27 return !mSACOne[side] ? -1 : mSACOne[side]->getValue(side, integrationInterval);
28}
29
30TCanvas* SACs::drawSACTypeSides(const SACType type, const unsigned int integrationInterval, const int minZ, const int maxZ, TCanvas* canv)
31{
32 std::string name;
33 std::function<float(const unsigned int, const unsigned int)> SACFunc;
35 SACFunc = [this, integrationInterval](const unsigned int sector, const unsigned int stack) {
36 return this->getSACValue(getStack(sector, stack), integrationInterval);
37 };
38 name = "SAC";
39 } else if (type == o2::tpc::SACType::IDCZero) {
40 SACFunc = [this](const unsigned int sector, const unsigned int stack) {
41 return this->getSACZeroVal(getStack(sector, stack));
42 };
43 name = "SACZero";
44 } else if (type == o2::tpc::SACType::IDCDelta) {
45 SACFunc = [this, integrationInterval](const unsigned int sector, const unsigned int stack) {
46 return this->getSACDeltaVal(getStack(sector, stack), integrationInterval);
47 };
48 name = "SACDelta";
49 } else if (type == o2::tpc::SACType::IDCOutlier) {
50 SACFunc = [this](const unsigned int sector, const unsigned int stack) {
51 return this->getSACRejection(getStack(sector, stack));
52 };
53 name = "SACZero Outliers (Yellow)";
54 }
55
56 auto c = canv;
57 if (!c) {
58 c = new TCanvas(fmt::format("c_sides_{}", name).data(), fmt::format("sides_{}", name).data(), 500, 1000);
59 }
60
62 drawFun.mSACFunc = SACFunc;
63 const std::string zAxisTitle = SACDrawHelper::getZAxisTitle(type);
64
65 auto hSideA = SACDrawHelper::drawSide(drawFun, o2::tpc::Side::A, zAxisTitle);
66 auto hSideC = SACDrawHelper::drawSide(drawFun, o2::tpc::Side::C, zAxisTitle);
67
68 hSideA->SetTitle(fmt::format("{} ({}-Side)", name.data(), "A").data());
69 hSideC->SetTitle(fmt::format("{} ({}-Side)", name.data(), "C").data());
70
71 if (minZ < maxZ) {
72 hSideA->SetMinimum(minZ);
73 hSideC->SetMinimum(minZ);
74 hSideA->SetMaximum(maxZ);
75 hSideC->SetMaximum(maxZ);
76 }
77
79 Double_t levels[] = {-3., 0., 3.};
80 hSideA->SetContour(3, levels);
81 hSideC->SetContour(3, levels);
82 }
83
84 c->Divide(1, 2);
85 c->cd(1);
86 hSideA->Draw("colz PFC");
87 c->cd(2);
88 hSideC->Draw("colz PFC");
89
90 hSideA->SetBit(TObject::kCanDelete);
91 hSideC->SetBit(TObject::kCanDelete);
92
93 return c;
94}
95
96TCanvas* SACs::drawSACOneCanvas(int nbins1D, float xMin1D, float xMax1D, int integrationIntervals, TCanvas* outputCanvas) const
97{
98 auto* canv = outputCanvas;
99
100 if (!canv) {
101 canv = new TCanvas("c_sides_SAC1_1D", "SAC1 1D distribution for each side", 1000, 1000);
102 }
103
104 auto hAside1D = new TH1F("h_SAC1_1D_ASide", "SAC1 distribution over integration intervals A-Side", nbins1D, xMin1D, xMax1D);
105 auto hCside1D = new TH1F("h_SAC1_1D_CSide", "SAC1 distribution over integration intervals C-Side", nbins1D, xMin1D, xMax1D);
106
107 hAside1D->GetXaxis()->SetTitle("SAC1");
108 hAside1D->SetTitleOffset(1.05, "XY");
109 hAside1D->SetTitleSize(0.05, "XY");
110 hCside1D->GetXaxis()->SetTitle("SAC1");
111 hCside1D->SetTitleOffset(1.05, "XY");
112 hCside1D->SetTitleSize(0.05, "XY");
113 if (integrationIntervals <= 0) {
114 integrationIntervals = std::min(mSACOne[Side::A]->mSACOne[Side::A].getNIDCs(), mSACOne[Side::C]->mSACOne[Side::C].getNIDCs());
115 }
116 for (unsigned int integrationInterval = 0; integrationInterval < integrationIntervals; ++integrationInterval) {
117 hAside1D->Fill(getSACOneVal(Side::A, integrationInterval));
118 hCside1D->Fill(getSACOneVal(Side::C, integrationInterval));
119 }
120
121 canv->Divide(1, 2);
122 canv->cd(1);
123 hAside1D->Draw();
124 canv->cd(2);
125 hCside1D->Draw();
126
127 hAside1D->SetBit(TObject::kCanDelete);
128 hCside1D->SetBit(TObject::kCanDelete);
129
130 return canv;
131}
132
133TCanvas* SACs::drawFourierCoeffSAC(Side side, int nbins1D, float xMin1D, float xMax1D, TCanvas* outputCanvas) const
134{
135 auto* canv = outputCanvas;
136 if (!canv) {
137 canv = new TCanvas(fmt::format("c_FourierCoefficients_1D_{}Side", (side == Side::A) ? "A" : "C").data(), fmt::format("1D distributions of Fourier Coefficients ({}-Side)", (side == Side::A) ? "A" : "C").data(), 1000, 1000);
138 }
139
140 std::vector<TH1F*> histos;
141
142 for (int i = 0; i < mFourierSAC->mCoeff[side].getNCoefficientsPerTF(); i++) {
143 histos.emplace_back(new TH1F(fmt::format("h_FourierCoeff{}_{}Side", i, (side == Side::A) ? "A" : "C").data(), fmt::format("1D distribution of Fourier Coefficient {} ({}-Side)", i, (side == Side::A) ? "A" : "C").data(), nbins1D, xMin1D, xMax1D));
144 histos.back()->GetXaxis()->SetTitle(fmt::format("Fourier Coefficient {}", i).data());
145 }
146
147 const auto& coeffs = mFourierSAC->mCoeff[side].getFourierCoefficients();
148 const auto nCoeffPerTF = mFourierSAC->mCoeff[side].getNCoefficientsPerTF();
149
150 for (int i = 0; i < mFourierSAC->mCoeff[side].getNCoefficients(); i++) {
151 histos.at(i % nCoeffPerTF)->Fill(coeffs.at(i));
152 }
153
154 canv->DivideSquare(mFourierSAC->mCoeff[side].getNCoefficientsPerTF());
155
156 size_t pad = 1;
157
158 for (const auto& hist : histos) {
159 canv->cd(pad);
160 hist->SetTitleOffset(1.05, "XY");
161 hist->SetTitleSize(0.05, "XY");
162 hist->Draw();
163 hist->SetBit(TObject::kCanDelete);
164 pad++;
165 }
166
167 return canv;
168}
169
170TCanvas* SACs::drawSACZeroScale(TCanvas* outputCanvas) const
171{
172 TCanvas* canv = nullptr;
173
174 if (outputCanvas) {
175 canv = outputCanvas;
176 } else {
177 canv = new TCanvas("c_sides_SACZero_ScaleFactor", "SACZero", 1000, 1000);
178 }
179 canv->cd();
180
181 double xsides[] = {0, 1};
182 double yTotSAC0[] = {mScaleSACZeroAside, mScaleSACZeroCside};
183 auto gSACZeroScale = new TGraph(2, xsides, yTotSAC0);
184
185 gSACZeroScale->SetName("g_SAC0ScaleFactor");
186 gSACZeroScale->SetTitle(Form("Scaling Factor (SACZero), Rejection Factor %.2f;Sides;SACZero Total (arb. unit)", mSACZeroMaxDeviation));
187 gSACZeroScale->SetMarkerColor(kBlue);
188 gSACZeroScale->SetMarkerStyle(21);
189 gSACZeroScale->SetMarkerSize(1);
190 gSACZeroScale->GetXaxis()->SetLabelColor(0);
191 gSACZeroScale->GetXaxis()->CenterTitle();
192
193 gSACZeroScale->Draw("ap");
194 // Draw labels on the x axis
195 TText* t = new TText();
196 t->SetTextSize(0.035);
197 const char* labels[2] = {"A-Side", "C-Side"};
198 for (Int_t iSide = 0; iSide < 2; iSide++) {
199 t->DrawText((double)iSide + 0.1, yTotSAC0[iSide], labels[iSide]);
200 }
201 gSACZeroScale->GetXaxis()->SetLimits(-0.5, 1.5);
202 canv->Update();
203 canv->Modified();
204 gSACZeroScale->SetBit(TObject::kCanDelete);
205 t->SetBit(TObject::kCanDelete);
206 return canv;
207}
208
209void SACs::scaleSAC0(const float factor, const Side side)
210{
211 unsigned int sectorStart = (side == Side::A) ? 0 : o2::tpc::SECTORSPERSIDE;
212 unsigned int sectorEnd = (side == Side::A) ? o2::tpc::SECTORSPERSIDE : (sectorStart * SIDES);
213 for (unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
214 for (unsigned int stack = 0; stack < GEMSTACKSPERSECTOR; ++stack) {
215 float SACZeroValue = getSACZeroVal(getStack(sector, stack));
216 if (factor != 0.) {
217 setSACZeroVal(SACZeroValue / factor, getStack(sector, stack));
218 }
219 }
220 }
221}
222
223void SACs::setSACZeroScale(const bool rejectOutlier)
224{
225 if (mSACZero) {
226 mScaleSACZeroAside = getMeanSACZero(Side::A, rejectOutlier);
227 scaleSAC0(abs(mScaleSACZeroAside), Side::A);
228
229 mScaleSACZeroCside = getMeanSACZero(Side::C, rejectOutlier);
230 scaleSAC0(abs(mScaleSACZeroCside), Side::C);
231 } else {
232 mScaleSACZeroAside = 0;
233 mScaleSACZeroCside = 0;
234 }
235
237 if (mScaleSACZeroAside == 0.0 || mScaleSACZeroCside == 0.0) {
238 LOGP(error, "Please check the SAC0 total A side {} and C side {}, is zero, therefore no scaling applied!", mScaleSACZeroAside, mScaleSACZeroCside);
239 mScaleSACZeroAside = 1.0;
240 mScaleSACZeroCside = 1.0;
241 }
242}
243
244float SACs::getMeanSACZero(const o2::tpc::Side side, bool rejectOutliers)
245{
246 float medianSACZero[GEMSTACKSPERSECTOR] = {0.};
247
248 if (rejectOutliers) {
249 // Calculate Median for each row for rejection of outliers
250 std::vector<float> SACZeroValues[GEMSTACKSPERSECTOR];
251
252 unsigned int sectorStart = (side == Side::A) ? 0 : o2::tpc::SECTORSPERSIDE;
253 unsigned int sectorEnd = (side == Side::A) ? o2::tpc::SECTORSPERSIDE : (sectorStart * SIDES);
254 for (unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
255 for (unsigned int stack = 0; stack < GEMSTACKSPERSECTOR; ++stack) {
256 SACZeroValues[stack].push_back(getSACZeroVal(getStack(sector, stack)));
257 }
258 }
259
260 for (unsigned int stack = 0; stack < GEMSTACKSPERSECTOR; stack++) {
261 size_t n = SACZeroValues[stack].size() / 2;
262 sort(SACZeroValues[stack].begin(), SACZeroValues[stack].end());
263 if (SACZeroValues[stack].size() % 2 != 0) {
264 medianSACZero[stack] = SACZeroValues[stack].at(n);
265 } else {
266 medianSACZero[stack] = (SACZeroValues[stack].at(n) + SACZeroValues[stack].at(n - 1)) / 2.;
267 }
268 }
269 }
270
271 // Calculate Mean
272 float meanSACZero = 0;
273 float SACZeroChannelCounter = 0.;
274
275 unsigned int sectorStart = (side == Side::A) ? 0 : o2::tpc::SECTORSPERSIDE;
276 unsigned int sectorEnd = (side == Side::A) ? o2::tpc::SECTORSPERSIDE : (sectorStart * SIDES);
277 for (unsigned int sector = sectorStart; sector < sectorEnd; ++sector) {
278 for (unsigned int stack = 0; stack < GEMSTACKSPERSECTOR; ++stack) {
279
280 float SACZeroVal = getSACZeroVal(getStack(sector, stack));
281
282 if (rejectOutliers) {
283 if (abs((SACZeroVal - medianSACZero[stack]) / medianSACZero[stack]) >= mSACZeroMaxDeviation) {
284 mIsSACZeroOutlier[getStack(sector, stack)] = 1;
285 continue;
286 }
287 }
288 mIsSACZeroOutlier[getStack(sector, stack)] = -1;
289 meanSACZero += SACZeroVal;
290 SACZeroChannelCounter += 1.;
291 }
292 }
293 if (SACZeroChannelCounter > 0.) {
294 meanSACZero /= SACZeroChannelCounter;
295 }
296 return meanSACZero;
297}
int32_t i
uint32_t side
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
uint32_t stack
Definition RawData.h:1
helper class for drawing SACs per sector/side
ClassImp(o2::tpc::qc::SACs)
static std::string getZAxisTitle(const SACType type)
static void drawSide(const SACDraw &SAC, const o2::tpc::Side side, const std::string zAxisTitle, const std::string filename, const float minZ=0, const float maxZ=-1)
float getSACDeltaVal(const unsigned int stack, unsigned int interval) const
Definition SACs.h:59
void setSACZeroVal(float factor, const unsigned int stack) const
Definition SACs.h:49
TCanvas * drawSACZeroScale(TCanvas *outputCanvas=nullptr) const
Definition SACs.cxx:170
void scaleSAC0(const float factor, const Side side)
Definition SACs.cxx:209
int getSACRejection(const unsigned int stack) const
Definition SACs.h:68
void setSACZeroScale(const bool rejectOutlier)
Definition SACs.cxx:223
float getSACOneVal(const Side side, unsigned int integrationInterval) const
Definition SACs.cxx:25
TCanvas * drawSACOneCanvas(int nbins1D, float xMin1D, float xMax1D, int integrationIntervals=-1, TCanvas *outputCanvas=nullptr) const
Definition SACs.cxx:96
TCanvas * drawSACTypeSides(const SACType type, const unsigned int integrationInterval, const int minZ=0, const int maxZ=-1, TCanvas *canv=nullptr)
Definition SACs.cxx:30
TCanvas * drawFourierCoeffSAC(Side side, int nbins1D, float xMin1D, float xMax1, TCanvas *outputCanvas=nullptr) const
Definition SACs.cxx:133
auto getSACValue(const unsigned int stack, const unsigned int interval) const
Definition SACs.h:40
float getMeanSACZero(const o2::tpc::Side side, bool rejectOutliers)
Definition SACs.cxx:244
float getSACZeroVal(const unsigned int stack) const
Definition SACs.h:44
GLdouble n
Definition glcorearb.h:1982
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
GLuint const GLchar * name
Definition glcorearb.h:781
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLboolean * data
Definition glcorearb.h:298
GLint GLenum GLint const GLfloat * coeffs
Definition glcorearb.h:5520
GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat maxZ
Definition glcorearb.h:2910
GLfloat GLfloat minZ
Definition glcorearb.h:2910
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
IDCType
IDC types.
@ IDC
integrated and grouped IDCs
@ 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) )
Enum< T >::Iterator begin(Enum< T >)
Definition Defs.h:173
constexpr unsigned char SIDES
Definition Defs.h:41
Side
TPC readout sidE.
Definition Defs.h:35
@ A
Definition Defs.h:35
@ C
Definition Defs.h:36
constexpr unsigned short GEMSTACKSPERSECTOR
Definition Defs.h:57
std::array< FourierCoeff, SIDES > mCoeff
std::function< float(const unsigned int, const unsigned int)> mSACFunc
function returning the value which will be drawn for sector, stack