Skip to content
Merged
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
4 changes: 3 additions & 1 deletion Modules/FIT/FT0/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ target_sources(O2QcFT0 PRIVATE src/AgingLaserTask.cxx
src/OutOfBunchCollCheck.cxx
src/MergedTreeCheck.cxx
src/RecPointsQcTask.cxx
src/ChannelGeometry.cxx)
src/ChannelGeometry.cxx
src/AmpTimeDistribution.cxx)

target_include_directories(
O2QcFT0
Expand Down Expand Up @@ -43,6 +44,7 @@ add_root_dictionary(O2QcFT0
include/FT0/MergedTreeCheck.h
include/FT0/RecPointsQcTask.h
include/FT0/ChannelGeometry.h
include/FT0/AmpTimeDistribution.h
LINKDEF include/FT0/LinkDef.h)

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/FT0
Expand Down
47 changes: 47 additions & 0 deletions Modules/FIT/FT0/include/FT0/AmpTimeDistribution.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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.

#ifndef O2_FITAMPTIMEDISTRIBUTION_H
#define O2_FITAMPTIMEDISTRIBUTION_H

#include "TH2F.h"

#include <string>
#include <memory>
#include <utility>
#include <vector>

#include <span>

namespace o2::fit
{

struct AmpTimeDistribution {
AmpTimeDistribution() = default;
AmpTimeDistribution(const std::string& name, const std::string& title, int nBins, double minRange, double maxRange, int binsInStep = 50, int binMax = 4095, int axis = 0);
AmpTimeDistribution(const AmpTimeDistribution&);
AmpTimeDistribution(AmpTimeDistribution&&) noexcept;
AmpTimeDistribution& operator=(const AmpTimeDistribution&);
AmpTimeDistribution& operator=(AmpTimeDistribution&&) noexcept;
typedef float Content_t; // to template?
typedef TH2F Hist2F_t;
std::unique_ptr<Hist2F_t> mHist = nullptr;

void initHists(const std::string& name, const std::string& title, int nBins, double minRange, double maxRange, int binsInStep = 50, int binMax = 4095, int axis = 0);
static std::vector<double> makeVaribleBins(const std::vector<std::pair<int, int>>& vecParams, int binMax = 4095);
static std::vector<double> makeVaribleBins(int binsInStep = 50, int binMax = 4095);
};

template <std::size_t NCHANNELS, std::size_t NADC>
using AmpTimeDistributionDetector = std::array<std::array<AmpTimeDistribution, NCHANNELS>, NADC>;

} // namespace o2::fit
#endif
6 changes: 4 additions & 2 deletions Modules/FIT/FT0/include/FT0/RecPointsQcTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#define QC_MODULE_FT0_FT0RECOQCTASK_H

#include <Framework/InputRecord.h>

#include <FT0/AmpTimeDistribution.h>
#include "QualityControl/QcInfoLogger.h"
#include <FT0Base/Geometry.h>
#include <DataFormatsFT0/RecPoints.h>
Expand All @@ -46,7 +46,7 @@ namespace o2::quality_control_modules::ft0

class RecPointsQcTask final : public TaskInterface
{
static constexpr int NCHANNELS = o2::ft0::Geometry::Nchannels;
static constexpr int sNCHANNELS = o2::ft0::Geometry::Nchannels;

public:
/// \brief Constructor
Expand All @@ -62,8 +62,10 @@ class RecPointsQcTask final : public TaskInterface
void endOfActivity(const Activity& activity) override;
void reset() override;
using Detector_t = o2::quality_control_modules::fit::detectorFIT::DetectorFT0;
void initHists();

private:
std::array<o2::fit::AmpTimeDistribution, sNCHANNELS> mArrAmpTimeDistribution;
TList* mListHistGarbage;
std::set<unsigned int> mSetAllowedChIDs;
unsigned int mTrgPos_minBias;
Expand Down
99 changes: 99 additions & 0 deletions Modules/FIT/FT0/src/AmpTimeDistribution.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// 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 <FT0/AmpTimeDistribution.h>
#include <cstring>

using namespace o2::fit;

AmpTimeDistribution::AmpTimeDistribution(const std::string& name, const std::string& title, int nBins, double minRange, double maxRange, int binsInStep, int binMax, int axis)
{
initHists(name, title, nBins, minRange, maxRange, binsInStep, binMax, axis);
}

AmpTimeDistribution::AmpTimeDistribution(const AmpTimeDistribution& other)
{
if (other.mHist) {
const std::string newName = std::string(other.mHist->GetName()) + "_Cloned";
mHist = std::unique_ptr<AmpTimeDistribution::Hist2F_t>(dynamic_cast<AmpTimeDistribution::Hist2F_t*>(other.mHist->Clone(newName.c_str())));
}
}

AmpTimeDistribution::AmpTimeDistribution(AmpTimeDistribution&& other) noexcept : mHist(std::move(other.mHist))
{
}

AmpTimeDistribution& AmpTimeDistribution::operator=(const AmpTimeDistribution& other)
{
if (this != &other) {
if (other.mHist) {
const std::string newName = std::string(other.mHist->GetName()) + "_Cloned";
mHist = std::unique_ptr<AmpTimeDistribution::Hist2F_t>(dynamic_cast<AmpTimeDistribution::Hist2F_t*>(other.mHist->Clone(newName.c_str())));
} else {
mHist.reset();
}
}
return *this;
}
AmpTimeDistribution& AmpTimeDistribution::operator=(AmpTimeDistribution&& other) noexcept
{
if (this != &other) {
mHist = std::move(other.mHist);
}
return *this;
}

void AmpTimeDistribution::initHists(const std::string& name, const std::string& title, int nBins, double minRange, double maxRange, int binsInStep, int binMax, int axis)
{
const auto& varBins = makeVaribleBins(binsInStep, binMax);
const int varNbins = varBins.size() - 1;
if (axis == 0) {
mHist = std::make_unique<AmpTimeDistribution::Hist2F_t>(name.c_str(), title.c_str(), varNbins, varBins.data(), nBins, minRange, maxRange);
} else if (axis == 1) {
mHist = std::make_unique<AmpTimeDistribution::Hist2F_t>(name.c_str(), title.c_str(), nBins, minRange, maxRange, varNbins, varBins.data());
}
}

std::vector<double> AmpTimeDistribution::makeVaribleBins(const std::vector<std::pair<int, int>>& vecParams, int binMax)
{
std::vector<double> vecLowEdgeBins{};
int startBin{ 0 };
auto makeBinRange = [&vec = vecLowEdgeBins, binMax](int startBin, int binWidth, int nBins) {
const int endBin = startBin + binWidth * nBins;
for (int iBin = startBin; iBin < endBin; iBin += binWidth) {
vec.emplace_back(static_cast<double>(iBin));
if (iBin > binMax) {
break;
}
}
return endBin;
};
for (const auto& entry : vecParams) {
startBin = makeBinRange(startBin, entry.first, entry.second);
}
return vecLowEdgeBins;
}

std::vector<double> AmpTimeDistribution::makeVaribleBins(int binsInStep, int binMax)
{
auto generateParams = [](int binsInStep, int binMax) {
std::vector<std::pair<int, int>> vecParams{};
int endBin{ 0 };
int binWidth = 1;
while (endBin < binMax) {
vecParams.push_back({ binWidth, binsInStep });
endBin += (binWidth * binsInStep);
binWidth *= 2;
}
return vecParams;
};
return makeVaribleBins(generateParams(binsInStep, binMax), binMax);
}
54 changes: 33 additions & 21 deletions Modules/FIT/FT0/src/RecPointsQcTask.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
#include <DataFormatsFT0/ChannelData.h>
#include <Framework/InputRecord.h>
#include <vector>

#include "DataFormatsParameters/GRPLHCIFData.h"
#include "FITCommon/HelperHist.h"
#include "FITCommon/HelperCommon.h"

#include "DetectorsBase/GRPGeomHelper.h"
#include "CommonDataFormat/BunchFilling.h"
namespace o2::quality_control_modules::ft0
{

Expand All @@ -38,14 +39,23 @@ RecPointsQcTask::~RecPointsQcTask()
{
delete mListHistGarbage;
}
void RecPointsQcTask::initHists()
{
for (int iCh = 0; iCh < sNCHANNELS; iCh++) {
const std::string name = fmt::format("hAmpVsTime_ch{}", iCh);
const std::string title = fmt::format("Amp Vs Time channelID {}; Amp [ADC]; Time [ps]", iCh);
mArrAmpTimeDistribution[iCh] = o2::fit::AmpTimeDistribution(name, title, 200, -2000., 2000., 50, 4095, 0); // in total 315 bins along x-axis
getObjectsManager()->startPublishing(mArrAmpTimeDistribution[iCh].mHist.get());
}
}

void RecPointsQcTask::initialize(o2::framework::InitContext& /*ctx*/)
{
ILOG(Info, Support) << "@@@@initialize RecoQcTask" << ENDM; // QcInfoLogger is used. FairMQ logs will go to there as well.

mHistTime2Ch = std::make_unique<TH2F>("TimePerChannel", "Time vs Channel;Channel;Time [ps]", NCHANNELS, 0, NCHANNELS, 500, -2050, 2050);
mHistTime2Ch = std::make_unique<TH2F>("TimePerChannel", "Time vs Channel;Channel;Time [ps]", sNCHANNELS, 0, sNCHANNELS, 500, -2050, 2050);
mHistTime2Ch->SetOption("colz");
mHistAmp2Ch = std::make_unique<TH2F>("AmpPerChannel", "Amplitude vs Channel;Channel;Amp [#ADC channels]", NCHANNELS, 0, NCHANNELS, 200, 0, 1000);
mHistAmp2Ch = std::make_unique<TH2F>("AmpPerChannel", "Amplitude vs Channel;Channel;Amp [#ADC channels]", sNCHANNELS, 0, sNCHANNELS, 200, 0, 1000);
mHistAmp2Ch->SetOption("colz");
mHistCollTimeAC = std::make_unique<TH1F>("CollTimeAC", "(T0A+T0C)/2;ps", 100, -1000, 1000);
mHistCollTimeA = std::make_unique<TH1F>("CollTimeA", "T0A;ps", 100, -1000, 1000);
Expand Down Expand Up @@ -87,15 +97,16 @@ void RecPointsQcTask::initialize(o2::framework::InitContext& /*ctx*/)
mHistTimeA_perTrg = helper::registerHist<TH2F>(getObjectsManager(), PublicationPolicy::Forever, "COLZ", "TimeA_perTrg", "T0A per Trigger;Time [ps]; Trigger", binsTime, mMapTrgBits);
mHistTimeC_perTrg = helper::registerHist<TH2F>(getObjectsManager(), PublicationPolicy::Forever, "COLZ", "TimeC_perTrg", "T0C per Trigger;Time [ps]; Trigger", binsTime, mMapTrgBits);
mHistBC_perTriggers = helper::registerHist<TH2F>(getObjectsManager(), PublicationPolicy::Forever, "COLZ", "BC_perTriggers", "BC per Triggers;BC; Trigger", binsBC, mMapTrgBits);

for (const auto& chID : mSetAllowedChIDs) {
auto pairHistAmpVsTime = mMapHistAmpVsTime.insert({ chID, new TH2F(Form("Amp_vs_time_channel%i", chID), Form("Amplitude vs time, channel %i;Amp;Time", chID), 1000, 0, 4000, 100, -1000, 1000) });
if (pairHistAmpVsTime.second) {
mListHistGarbage->Add(pairHistAmpVsTime.first->second);
getObjectsManager()->startPublishing(pairHistAmpVsTime.first->second);
/*
for (const auto& chID : mSetAllowedChIDs) {
auto pairHistAmpVsTime = mMapHistAmpVsTime.insert({ chID, new TH2F(Form("Amp_vs_time_channel%i", chID), Form("Amplitude vs time, channel %i;Amp;Time", chID), 1000, 0, 4000, 100, -1000, 1000) });
if (pairHistAmpVsTime.second) {
mListHistGarbage->Add(pairHistAmpVsTime.first->second);
getObjectsManager()->startPublishing(pairHistAmpVsTime.first->second);
}
}
}

*/
initHists();
ILOG(Info, Support) << "@@@ histos created" << ENDM;
}

Expand All @@ -114,9 +125,8 @@ void RecPointsQcTask::startOfActivity(const Activity& activity)
mHistTimeA_perTrg->Reset();
mHistTimeC_perTrg->Reset();
mHistBC_perTriggers->Reset();

for (auto& entry : mMapHistAmpVsTime) {
entry.second->Reset();
for (int iCh = 0; iCh < sNCHANNELS; iCh++) {
mArrAmpTimeDistribution[iCh].mHist->Reset();
}
}

Expand All @@ -128,7 +138,9 @@ void RecPointsQcTask::monitorData(o2::framework::ProcessingContext& ctx)
{
auto chan = ctx.inputs().get<gsl::span<o2::ft0::ChannelDataFloat>>("channels");
auto recpoints = ctx.inputs().get<gsl::span<o2::ft0::RecPoints>>("recpoints");

const auto& grplhcif = o2::base::GRPGeomHelper::instance().getGRPLHCIF();
const auto& bcSchema = grplhcif ? grplhcif->getBunchFilling().getBCPattern() : o2::BunchFilling::Pattern{};
const bool isPbPb = grplhcif ? grplhcif->getAtomicNumberB1() == 82 && grplhcif->getAtomicNumberB2() == 82 : false;
for (const auto& recpoint : recpoints) {
const auto bc = recpoint.getInteractionRecord().bc;
int time[o2::ft0::Constants::sNCHANNELS_PM] = { 0 };
Expand Down Expand Up @@ -158,13 +170,14 @@ void RecPointsQcTask::monitorData(o2::framework::ProcessingContext& ctx)
}
}
}
const bool isMinBiasEvent = (isPbPb && minBias) || (!isPbPb && triggersignals.getVertex()); // for pp only vertex, for PbPb vrt && (CENT || SCENT)
for (const auto& chData : channels) {
time[chData.ChId] = chData.CFDTime;
amp[chData.ChId] = chData.QTCAmpl;
mHistTime2Ch->Fill(static_cast<Double_t>(chData.ChId), static_cast<Double_t>(chData.CFDTime));
mHistAmp2Ch->Fill(static_cast<Double_t>(chData.ChId), static_cast<Double_t>(chData.QTCAmpl));
if (mSetAllowedChIDs.find(static_cast<unsigned int>(chData.ChId)) != mSetAllowedChIDs.end() && minBias) { // ampt-time dependency is needed only for PbPb runs
mMapHistAmpVsTime[chData.ChId]->Fill(chData.QTCAmpl, chData.CFDTime);
if (bcSchema.test(bc) && isMinBiasEvent) { // ampt-time dependency
mArrAmpTimeDistribution[chData.ChId].mHist->Fill(chData.QTCAmpl, chData.CFDTime);
}
}
if (vertexTrigger) {
Expand Down Expand Up @@ -239,9 +252,8 @@ void RecPointsQcTask::reset()
mHistTimeA_perTrg->Reset();
mHistTimeC_perTrg->Reset();
mHistBC_perTriggers->Reset();

for (auto& entry : mMapHistAmpVsTime) {
entry.second->Reset();
for (int iCh = 0; iCh < sNCHANNELS; iCh++) {
mArrAmpTimeDistribution[iCh].mHist->Reset();
}
}

Expand Down