Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Detectors/TPC/qc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ o2_add_library(TPCQC
src/Clusters.cxx
src/Tracks.cxx
src/DCSPTemperature.cxx
src/SACs.cxx
PUBLIC_LINK_LIBRARIES O2::TPCBase
O2::DataFormatsTPC
O2::GPUO2Interface)
O2::GPUO2Interface
O2::TPCCalibration)


o2_target_root_dictionary(TPCQC
Expand All @@ -28,7 +30,8 @@ o2_target_root_dictionary(TPCQC
include/TPCQC/Clusters.h
include/TPCQC/Tracks.h
include/TPCQC/CalPadWrapper.h
include/TPCQC/DCSPTemperature.h)
include/TPCQC/DCSPTemperature.h
include/TPCQC/SACs.h)

o2_add_test(PID
COMPONENT_NAME tpc
Expand All @@ -49,6 +52,12 @@ o2_add_test(Tracks
SOURCES test/test_Tracks.cxx
LABELS tpc)

o2_add_test(SACs
COMPONENT_NAME tpc
PUBLIC_LINK_LIBRARIES O2::TPCQC
SOURCES test/test_SACs.cxx
LABELS tpc)

o2_add_test_root_macro(macro/runPID.C
PUBLIC_LINK_LIBRARIES O2::TPCQC
O2::DataFormatsTPC
Expand Down
95 changes: 95 additions & 0 deletions Detectors/TPC/qc/include/TPCQC/SACs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// @file SACs.h
/// @author
///

#ifndef AliceO2_TPC_SACS_H
#define AliceO2_TPC_SACS_H

// root includes
#include "TCanvas.h"

// o2 includes
#include "TPCCalibration/IDCContainer.h"
#include "DataFormatsTPC/Defs.h"

namespace o2::tpc::qc
{

/// Keep QC information for SAC related observables
///
class SACs
{
public:
SACs() = default;

/// \return returns the stored SAC value
/// \param stack stack
/// \param interval integration interval
auto getSACValue(const unsigned int stack, const unsigned int interval) const { return mSACs[stack][interval]; }

/// \return returns the stored SAC0 value
/// \param stack stack
float getSACZeroVal(const unsigned int stack) const { return mSACZero.getValueIDCZero(getSide(stack), stack % GEMSTACKSPERSIDE); }

/// \return returns SAC1 value
/// \param Side TPC side
/// \param interval integration interval
float getSACOneVal(const Side side, unsigned int integrationInterval) const;

/// \return returns the stored DeltaSAC value
/// \param stack stack
/// \param interval integration interval
float getSACDeltaVal(const unsigned int stack, unsigned int interval) const { return mSACDelta.getValue(getSide(stack), getSACDeltaIndex(stack, interval)); }

/// \return returns index for SAC delta
/// \param stack stack
/// \param interval local integration interval
unsigned int getSACDeltaIndex(const unsigned int stack, unsigned int interval) const { return stack % GEMSTACKSPERSIDE + GEMSTACKSPERSIDE * interval; }

void setSACZero(const SACZero& sacZero) { mSACZero = sacZero; }
void setSACOne(SACOne* sacOne, const Side side = Side::A) { mSACOne[side] = sacOne; }

template <typename T>
void setSACDelta(const SACDelta<T>& sacDelta)
{
mSACDelta = sacDelta;
}

/// setting the fourier coefficients
void setFourierCoeffSAC(FourierCoeffSAC* fourier) { mFourierSAC = fourier; }

TCanvas* drawSACTypeSides(const SACType type, const unsigned int integrationInterval, const int minZ = 0, const int maxZ = -1, TCanvas* canv = nullptr);
TCanvas* drawSACOneCanvas(TCanvas* outputCanvas, int nbins1D, float xMin1D, float xMax1D, int integrationIntervals = -1) const;
TCanvas* drawFourierCoeffSAC(TCanvas* outputCanvas, Side side, int nbins1D, float xMin1D, float xMax1D) const;

void dumpToFile(std::string filename, int type = 0);

private:
std::array<std::vector<int32_t>, o2::tpc::GEMSTACKS> mSACs{};
SACZero mSACZero{};
std::array<SACOne*, SIDES> mSACOne = {nullptr, nullptr}; ///< I_1(t) = <I(r,\phi,t) / I_0(r,\phi)>_{r,\phi}
SACDelta<unsigned char> mSACDelta{};
FourierCoeffSAC* mFourierSAC = nullptr; ///< fourier coefficients of SACOne

/// \return returns side for given GEM stack
Side getSide(const unsigned int gemStack) const { return (gemStack < GEMSTACKSPERSIDE) ? Side::A : Side::C; }

/// \return returns stack for given sector and stack
unsigned int getStack(const unsigned int sector, const unsigned int stack) const { return static_cast<unsigned int>(stack + sector * GEMSTACKSPERSECTOR); }

ClassDefNV(SACs, 1)
};
} // namespace o2::tpc::qc
#endif
156 changes: 156 additions & 0 deletions Detectors/TPC/qc/src/SACs.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#include "TPCQC/SACs.h"
#include "TPCCalibration/SACDrawHelper.h"
#include "TH2Poly.h"
#include "fmt/format.h"

ClassImp(o2::tpc::qc::SACs);
using namespace o2::tpc::qc;

float SACs::getSACOneVal(const Side side, unsigned int integrationInterval) const
{
return !mSACOne[side] ? -1 : mSACOne[side]->getValue(side, integrationInterval);
}
TCanvas* SACs::drawSACTypeSides(const SACType type, const unsigned int integrationInterval, const int minZ, const int maxZ, TCanvas* canv)
{

std::string name;
std::function<float(const unsigned int, const unsigned int)> SACFunc;
if (type == o2::tpc::SACType::IDC) {
SACFunc = [this, integrationInterval](const unsigned int sector, const unsigned int stack) {
return this->getSACValue(getStack(sector, stack), integrationInterval);
};
name = "SAC";
} else if (type == o2::tpc::SACType::IDCZero) {
SACFunc = [this](const unsigned int sector, const unsigned int stack) {
return this->getSACZeroVal(getStack(sector, stack));
};
name = "SACZero";
} else if (type == o2::tpc::SACType::IDCDelta) {
SACFunc = [this, integrationInterval](const unsigned int sector, const unsigned int stack) {
return this->getSACDeltaVal(getStack(sector, stack), integrationInterval);
};
name = "SACDelta";
} else {
}

auto c = canv;
if (!c) {
std::cout << "Using the Canvas that we want\n";
c = new TCanvas(fmt::format("c_sides_{}", name).data(), fmt::format("sides_{}", name).data(), 500, 1000);
}

SACDrawHelper::SACDraw drawFun;
drawFun.mSACFunc = SACFunc;
const std::string zAxisTitle = SACDrawHelper::getZAxisTitle(type);

auto hSideA = SACDrawHelper::drawSide(drawFun, o2::tpc::Side::A, zAxisTitle);
auto hSideC = SACDrawHelper::drawSide(drawFun, o2::tpc::Side::C, zAxisTitle);

hSideA->SetTitle(fmt::format("{} ({}-Side)", name.data(), "A").data());
hSideC->SetTitle(fmt::format("{} ({}-Side)", name.data(), "C").data());

if (minZ < maxZ) {

hSideA->SetMinimum(minZ);
hSideC->SetMinimum(minZ);
hSideA->SetMaximum(maxZ);
hSideC->SetMaximum(maxZ);
}

c->Divide(1, 2);
c->cd(1);
hSideA->Draw("colz");
c->cd(2);
hSideC->Draw("colz");
return c;
}

TCanvas* SACs::drawSACOneCanvas(TCanvas* outputCanvas, int nbins1D, float xMin1D, float xMax1D, int integrationIntervals) const
{
TCanvas* canv = nullptr;

if (outputCanvas) {
canv = outputCanvas;
} else {
canv = new TCanvas("c_sides_SAC1_1D", "SAC1 1D distribution for each side", 1000, 1000);
}

auto hAside1D = new TH1F("h_SAC1_1D_ASide", "SAC1 distribution over integration intervals A-Side", nbins1D, xMin1D, xMax1D);
auto hCside1D = new TH1F("h_SAC1_1D_CSide", "SAC1 distribution over integration intervals C-Side", nbins1D, xMin1D, xMax1D);

hAside1D->GetXaxis()->SetTitle("SAC1");
hAside1D->SetTitleOffset(1.05, "XY");
hAside1D->SetTitleSize(0.05, "XY");
hCside1D->GetXaxis()->SetTitle("SAC1");
hCside1D->SetTitleOffset(1.05, "XY");
hCside1D->SetTitleSize(0.05, "XY");
if (integrationIntervals <= 0) {
integrationIntervals = std::min(mSACOne[Side::A]->mSACOne[Side::A].getNIDCs(), mSACOne[Side::C]->mSACOne[Side::C].getNIDCs());
}
for (unsigned int integrationInterval = 0; integrationInterval < integrationIntervals; ++integrationInterval) {
hAside1D->Fill(getSACOneVal(Side::A, integrationInterval));
hCside1D->Fill(getSACOneVal(Side::C, integrationInterval));
}

canv->Divide(1, 2);
canv->cd(1);
hAside1D->Draw();
canv->cd(2);
hCside1D->Draw();

hAside1D->SetBit(TObject::kCanDelete);
hCside1D->SetBit(TObject::kCanDelete);

return canv;
}

TCanvas* SACs::drawFourierCoeffSAC(TCanvas* outputCanvas, Side side, int nbins1D, float xMin1D, float xMax1D) const
{
TCanvas* canv = nullptr;

if (outputCanvas) {
canv = outputCanvas;
} else {
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);
}

std::vector<TH1F*> histos;

for (int i = 0; i < mFourierSAC->mCoeff[side].getNCoefficientsPerTF(); i++) {
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));
histos.back()->GetXaxis()->SetTitle(fmt::format("Fourier Coefficient {}", i).data());
histos.back()->SetBit(TObject::kCanDelete);
}

const auto& coeffs = mFourierSAC->mCoeff[side].getFourierCoefficients();
const auto nCoeffPerTF = mFourierSAC->mCoeff[side].getNCoefficientsPerTF();

for (int i = 0; i < mFourierSAC->mCoeff[side].getNCoefficients(); i++) {
histos.at(i % nCoeffPerTF)->Fill(coeffs.at(i));
}

canv->DivideSquare(mFourierSAC->mCoeff[side].getNCoefficientsPerTF());

size_t pad = 1;

for (const auto& hist : histos) {
canv->cd(pad);
hist->SetTitleOffset(1.05, "XY");
hist->SetTitleSize(0.05, "XY");
hist->Draw();
pad++;
}

return canv;
}
1 change: 1 addition & 0 deletions Detectors/TPC/qc/src/TPCQCLinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#pragma link C++ class o2::tpc::qc::Tracks+;
#pragma link C++ class o2::tpc::qc::CalPadWrapper+;
#pragma link C++ class o2::tpc::qc::DCSPTemperature + ;
#pragma link C++ class o2::tpc::qc::SACs + ;
#pragma link C++ function o2::tpc::qc::helpers::makeLogBinning+;
#pragma link C++ function o2::tpc::qc::helpers::setStyleHistogram1D+;
#pragma link C++ function o2::tpc::qc::helpers::setStyleHistogram2D+;
Expand Down
21 changes: 21 additions & 0 deletions Detectors/TPC/qc/test/test_SACs.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#define BOOST_TEST_MODULE Test TPC QC
#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "TPCQC/SACs.h"

BOOST_AUTO_TEST_CASE(ReadWriteROOTFile)
{
o2::tpc::qc::SACs sacs;
}