Project
Loading...
Searching...
No Matches
PHOSHGLGRatioCalibDevice.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
13#include "CCDB/CcdbApi.h"
14#include "CCDB/CcdbObjectInfo.h"
17#include <string>
18#include <fairlogger/Logger.h>
27#include "PHOSBase/Mapping.h"
28#include <TFile.h>
29#include <TF1.h>
30
31using namespace o2::phos;
32
34{
35
36 mStatistics = ic.options().get<int>("statistics"); // desired number of events
37
38 // Create histograms for mean and RMS
39 short n = o2::phos::Mapping::NCHANNELS - 1792;
40 mhRatio.reset(new TH2F("HGLGRatio", "HGLGRatio", n, 1792.5, n + 1792.5, 100, 10., 20.));
41 mCalibParams.reset(new CalibParams());
42}
43
45{
46
47 // scan Cells stream, collect HG/LG pairs
48 if (mRunStartTime == 0) {
49 mRunStartTime = ctx.services().get<o2::framework::TimingInfo>().creation; // approximate time in ms
50 }
51
52 if (mStatistics <= 0) { // skip the rest of the run
53 return;
54 }
55
56 if (!mOldCalibParams) { // Default map and calibration was not set, use CCDB
57 if (mUseCCDB) {
58 LOG(info) << "Getting calib from CCDB";
59 mOldCalibParams = ctx.inputs().get<o2::phos::CalibParams*>("oldclb");
60 } else { // For test only
61 mOldCalibParams = std::make_unique<o2::phos::CalibParams>(1);
62 }
63 }
64
65 auto cells = ctx.inputs().get<gsl::span<o2::phos::Cell>>("cells");
66 LOG(debug) << "[PHOSHGLGRatioCalibDevice - run] Received " << cells.size() << " cells, running calibration ...";
67 auto cellsTR = ctx.inputs().get<gsl::span<o2::phos::TriggerRecord>>("cellTriggerRecords");
68 for (const auto& tr : cellsTR) {
69 int firstCellInEvent = tr.getFirstEntry();
70 int lastCellInEvent = firstCellInEvent + tr.getNumberOfObjects();
71 mMapPairs.clear();
72
73 for (int i = firstCellInEvent; i < lastCellInEvent; i++) {
74 const Cell c = cells[i];
75
76 auto search = mMapPairs.find(c.getAbsId());
77 if (search != mMapPairs.end()) { // exist
78 if (c.getHighGain()) {
79 search->second.mHGAmp = c.getEnergy();
80 }
81 if (c.getLowGain()) {
82 search->second.mLGAmp = c.getEnergy();
83 }
84 } else {
85 PairAmp pa = {0};
86 if (c.getHighGain()) {
87 pa.mHGAmp = c.getEnergy();
88 }
89 if (c.getLowGain()) {
90 pa.mLGAmp = c.getEnergy();
91 }
92 mMapPairs.insert({c.getAbsId(), pa});
93 }
94 }
95 fillRatios();
96 --mStatistics;
97 }
98 if (mStatistics <= 0) {
99 LOG(info) << "[PHOSHGLGRatioCalibDevice - finalyzing calibration]";
100 // calculate stuff here
102 checkRatios();
103 sendOutput(ctx.outputs());
104 }
105}
106
108{
109
110 if (mStatistics > 0) { // not calculated yet
111 LOG(info) << "[PHOSHGLGRatioCalibDevice - endOfStream]";
112 // calculate stuff here
114 checkRatios();
115 sendOutput(ec.outputs());
116 }
117}
118
120{
121 // scan collected map and fill ratio histogram if both channels are filled
122 for (auto& it : mMapPairs) {
123 if (it.second.mHGAmp > 0 && it.second.mLGAmp > mMinLG) {
124 mhRatio->Fill(it.first, float(it.second.mHGAmp / it.second.mLGAmp));
125 }
126 }
127 mMapPairs.clear(); // to avoid double counting
128}
129
131{
132 // Calculate mean of the ratio
133 short n = o2::phos::Mapping::NCHANNELS - 1792;
134 if (mhRatio->Integral() > 2 * minimalStatistics * n) { // average per channel
135
136 TF1* fitFunc = new TF1("fitFunc", "gaus", 0., 4000.);
137 fitFunc->SetParameters(1., 200., 60.);
138 fitFunc->SetParLimits(1, 10., 2000.);
139 for (short i = n; i > 0; i--) {
140 TH1D* tmp = mhRatio->ProjectionY(Form("channel%d", i), i, i);
141 fitFunc->SetParameters(tmp->Integral(), tmp->GetMean(), tmp->GetRMS());
142 if (tmp->Integral() < minimalStatistics) {
143 tmp->Delete();
144 continue;
145 }
146 tmp->Fit(fitFunc, "QL0", "", 0., 20.);
147 float a = fitFunc->GetParameter(1);
148 mCalibParams->setHGLGRatio(i + 1792, a); // absId starts from 0
149 tmp->Delete();
150 }
151 }
152}
153
155{
156 // Compare ratios to current ones stored in CCDB
157 if (!mUseCCDB) {
158 mUpdateCCDB = true;
159 // Set default values for gain and time
160 for (short i = o2::phos::Mapping::NCHANNELS; i > 1792; i--) {
161 mCalibParams->setGain(i, 0.005);
162 mCalibParams->setHGTimeCalib(i, 0.);
163 mCalibParams->setLGTimeCalib(i, 0.);
164 }
165 return;
166 }
167 LOG(info) << "Retrieving current HG/LG ratio from CCDB";
168
169 if (!mOldCalibParams) { // was not read from CCDB, but expected
170 mUpdateCCDB = true;
171 LOG(error) << "Can not read current CalibParams from ccdb";
172 return;
173 }
174
175 LOG(info) << "Got current calibration from CCDB";
176 // Compare to current
177 int nChanged = 0;
178 for (short i = o2::phos::Mapping::NCHANNELS; i > 1792; i--) {
179 short dp = 2;
180 if (mOldCalibParams->getHGLGRatio(i) > 0) {
181 dp = mCalibParams->getHGLGRatio(i) / mOldCalibParams->getHGLGRatio(i);
182 } else {
183 if (mCalibParams->getHGLGRatio(i) == 0 && mOldCalibParams->getHGLGRatio(i) == 0) {
184 dp = 1.;
185 }
186 }
187 mRatioDiff[i] = dp;
188 if (abs(dp - 1.) > 0.1) { // not a fluctuation
189 nChanged++;
190 }
191 // Copy other stuff from the current CalibParams to new one
192 mCalibParams->setGain(i, mOldCalibParams->getGain(i));
193 mCalibParams->setHGTimeCalib(i, mOldCalibParams->getHGTimeCalib(i));
194 mCalibParams->setLGTimeCalib(i, mOldCalibParams->getLGTimeCalib(i));
195 }
196 LOG(info) << nChanged << "channels changed more than 10 %";
197 if (nChanged > kMinorChange) { // serious change, do not update CCDB automatically, use "force" option to overwrite
198 LOG(error) << "too many channels changed: " << nChanged << " (threshold " << kMinorChange << ")";
199 if (!mForceUpdate) {
200 LOG(error) << "you may use --forceupdate option to force updating ccdb";
201 }
202 mUpdateCCDB = false;
203 } else {
204 mUpdateCCDB = true;
205 }
206}
207
209{
210
211 // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output
212 if (mUpdateCCDB || mForceUpdate) {
213 // prepare all info to be sent to CCDB
214 auto flName = o2::ccdb::CcdbApi::generateFileName("CalibParams");
215 std::map<std::string, std::string> md;
216 long validityTime = mRunStartTime + 31622400000; // one year validity range
217 o2::ccdb::CcdbObjectInfo info("PHS/Calib/CalibParams", "CalibParams", flName, md, mRunStartTime, validityTime);
218 info.setMetaData(md);
219 auto image = o2::ccdb::CcdbApi::createObjectImage(mCalibParams.get(), &info);
220
221 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName()
222 << " of size " << image->size()
223 << " bytes, valid for " << info.getStartValidityTimestamp()
224 << " : " << info.getEndValidityTimestamp();
225
227 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "PHOS_HGLGratio", subSpec}, *image.get());
228 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "PHOS_HGLGratio", subSpec}, info);
229 }
230 // Anyway send change to QC
231 LOG(info) << "[PHOSHGLGRatioCalibDevice - sendOutput] Sending QC ";
232 output.snapshot(o2::framework::Output{"PHS", "CALIBDIFF", 0}, mRatioDiff);
233}
234
236{
237
238 std::vector<InputSpec> inputs;
239 inputs.emplace_back("cells", ConcreteDataTypeMatcher{o2::header::gDataOriginPHS, "CELLS"}, o2::framework::Lifetime::Timeframe);
240 inputs.emplace_back("cellTriggerRecords", ConcreteDataTypeMatcher{o2::header::gDataOriginPHS, "CELLTRIGREC"}, o2::framework::Lifetime::Timeframe);
241 if (useCCDB) {
242 inputs.emplace_back("oldclb", o2::header::gDataOriginPHS, "PHS_Calibr", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("PHS/Calib/CalibParams"));
243 }
244
246 std::vector<OutputSpec> outputs;
247 outputs.emplace_back(o2::header::gDataOriginPHS, "CALIBDIFF", 0, Lifetime::Sporadic);
248 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBPayload, "PHOS_HGLGratio"}, Lifetime::Sporadic);
249 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBWrapper, "PHOS_HGLGratio"}, Lifetime::Sporadic);
250 return o2::framework::DataProcessorSpec{"HGLGRatioCalibSpec",
251 inputs,
252 outputs,
253 o2::framework::adaptFromTask<PHOSHGLGRatioCalibDevice>(useCCDB, forceUpdate),
254 o2::framework::Options{{"statistics", o2::framework::VariantType::Int, 100000, {"max. number of events to process"}}}};
255}
Utils and constants for calibration and related workflows.
int32_t i
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Definition of the Names Generator class.
uint32_t c
Definition RawData.h:2
std::ostringstream debug
static std::string generateFileName(const std::string &inp)
Definition CcdbApi.cxx:798
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
long getEndValidityTimestamp() const
const std::string & getPath() const
void setMetaData(const std::map< std::string, std::string > &md)
long getStartValidityTimestamp() const
const std::string & getFileName() const
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static constexpr short NCHANNELS
Number of channels starting from 1.
Definition Mapping.h:42
void run(o2::framework::ProcessingContext &pc) final
void init(o2::framework::InitContext &ic) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
GLdouble n
Definition glcorearb.h:1982
GLeglImageOES image
Definition glcorearb.h:4021
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr o2::header::DataOrigin gDataOriginPHS
Definition DataHeader.h:574
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
bool search(DeviceExecution const &execution, std::string const &option, std::string const &argument)
std::vector< ConfigParamSpec > Options
DataProcessorSpec getHGLGRatioCalibSpec(bool useCCDB, bool forceUpdate)
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
uint32_t SubSpecificationType
Definition DataHeader.h:620
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cell > cells