Project
Loading...
Searching...
No Matches
PHOSPedestalCalibDevice.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
30using namespace o2::phos;
31
33{
34
35 mStatistics = ic.options().get<int>("statistics"); // desired number of events
36 LOG(info) << "PHOS pedestal init: will collect " << mStatistics << " events";
37 LOG(info) << "mUseCCDB (try to get current object) = " << mUseCCDB;
38 LOG(info) << "mForceUpdate (update CCDB anyway) =" << mForceUpdate;
39 // Create histograms for mean and RMS
40 short n = o2::phos::Mapping::NCHANNELS - 1792;
41 mMeanHG.reset(new TH2F("MeanHighGain", "MeanHighGain", n, 1792.5, n + 1792.5, 100, 0., 100.));
42 mMeanLG.reset(new TH2F("MeanLowGain", "MeanLowGain", n, 1792.5, n + 1792.5, 100, 0., 100.));
43 mRMSHG.reset(new TH2F("RMSHighGain", "RMSHighGain", n, 1792.5, n + 1792.5, 100, 0., 10.));
44 mRMSLG.reset(new TH2F("RMSLowGain", "RMSLowGain", n, 1792.5, n + 1792.5, 100, 0., 10.));
45}
46
48{
49 // scan Cells stream, collect mean and RMS then calculate average and post
50
51 if (mRunStartTime == 0) {
52 mRunStartTime = ctx.services().get<o2::framework::TimingInfo>().creation; // approximate time in ms
53 }
54 if (!mOldPed) { // Default map and calibration was not set, use CCDB
55 LOG(info) << "Getting calib from CCDB";
56 mOldPed = ctx.inputs().get<o2::phos::Pedestals*>("oldped");
57 }
58
59 if (mStatistics <= 0) { // skip the rest of the run
60 return;
61 }
62 if (mStatistics % 100 == 0) {
63 LOG(info) << mStatistics << " left to produce calibration";
64 }
65 auto cells = ctx.inputs().get<gsl::span<o2::phos::Cell>>("cells");
66 LOG(debug) << "[PHOSPedestalCalibDevice - 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 for (int i = firstCellInEvent; i < lastCellInEvent; i++) {
72 const Cell c = cells[i];
73 if (c.getHighGain()) {
74 mMeanHG->Fill(c.getAbsId(), c.getEnergy());
75 mRMSHG->Fill(c.getAbsId(), 1.e+7 * c.getTime());
76 } else {
77 mMeanLG->Fill(c.getAbsId(), c.getEnergy());
78 mRMSLG->Fill(c.getAbsId(), 1.e+7 * c.getTime());
79 }
80 }
81 --mStatistics;
82 }
83 if (mStatistics <= 0) {
86 sendOutput(ctx.outputs());
87 }
88}
89
91{
92 if (mStatistics > 0) { // not calculated yet
93 LOG(info) << "[PHOSPedestalCalibDevice - endOfStream]";
94 // calculate stuff here
97 sendOutput(ec.outputs());
98 }
99}
100
102{
103
104 // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output
105 if (mUpdateCCDB || mForceUpdate) {
106 // prepare all info to be sent to CCDB
107 auto flName = o2::ccdb::CcdbApi::generateFileName("Pedestals");
108 std::map<std::string, std::string> md;
109 long validityTime = mRunStartTime + 7776000000; // 3 months validity time
110 o2::ccdb::CcdbObjectInfo info("PHS/Calib/Pedestals", "Pedestals", flName, md, mRunStartTime, validityTime);
111 info.setMetaData(md);
112 auto image = o2::ccdb::CcdbApi::createObjectImage(mPedestals.get(), &info);
113
114 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName()
115 << " of size " << image->size()
116 << " bytes, valid for " << info.getStartValidityTimestamp()
117 << " : " << info.getEndValidityTimestamp();
118
120 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "PHOS_Pedestal", subSpec}, *image.get());
121 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "PHOS_Pedestal", subSpec}, info);
122
123 // Now same for DCS as vector
124 std::vector<short> dcsPedestals(2 * (o2::phos::Mapping::NCHANNELS - 1792));
125 // copy HG then LG pedestals
126 for (short absId = 1793; absId <= o2::phos::Mapping::NCHANNELS; absId++) {
127 dcsPedestals.emplace_back(mPedestals->getHGPedestal(absId));
128 }
129 for (short absId = 1793; absId <= o2::phos::Mapping::NCHANNELS; absId++) {
130 dcsPedestals.emplace_back(mPedestals->getLGPedestal(absId));
131 }
132
133 auto flNameDCS = o2::ccdb::CcdbApi::generateFileName("PedestalsDCS");
134 std::map<std::string, std::string> mdDCS;
135 o2::ccdb::CcdbObjectInfo infoDCS("PHS/PedestalRun/Pedestals", "PedestalsDCS", flNameDCS, mdDCS, mRunStartTime, validityTime);
136 auto imageDCS = o2::ccdb::CcdbApi::createObjectImage(&dcsPedestals, &infoDCS);
137 // subspec 0 -> to normal CCDB
138 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "PHOS_PedestalVec", subSpec}, *imageDCS.get());
139 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "PHOS_PedestalVec", subSpec}, infoDCS);
140 // subspec 1 -> to DCS CCDB
142 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "PHOS_PedestalVec", subSpec1}, *imageDCS.get());
143 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "PHOS_PedestalVec", subSpec1}, infoDCS);
144 }
145 // Anyway send change to QC
146 LOG(info) << "[PHOSPedestalCalibDevice - run] Sending QC ";
147 output.snapshot(o2::framework::Output{"PHS", "CALIBDIFF", 0}, mPedDiff);
148}
149
151{
152 LOG(info) << "Start pedestals calculation";
153
154 mPedestals.reset(new Pedestals());
155
156 // Calculate mean of pedestal distributions
157 for (unsigned short i = mMeanHG->GetNbinsX(); i > 0; i--) {
158 TH1D* pr = mMeanHG->ProjectionY(Form("proj%d", i), i, i);
159 float a = pr->GetMean();
160 short cellId = static_cast<short>(mMeanHG->GetXaxis()->GetBinCenter(i));
161 mPedestals->setHGPedestal(cellId, std::min(255, int(a)));
162 pr->Delete();
163 pr = mMeanLG->ProjectionY(Form("projLG%d", i), i, i);
164 a = pr->GetMean();
165 mPedestals->setLGPedestal(cellId, std::min(255, int(a)));
166 pr->Delete();
167 pr = mRMSHG->ProjectionY(Form("projRMS%d", i), i, i);
168 a = pr->GetMean();
169 mPedestals->setHGRMS(cellId, a);
170 pr->Delete();
171 pr = mRMSLG->ProjectionY(Form("projRMSLG%d", i), i, i);
172 a = pr->GetMean();
173 mPedestals->setLGRMS(cellId, a);
174 pr->Delete();
175 }
176 LOG(info) << "Pedestals calculated";
177}
178
180{
181 if (!mUseCCDB) {
182 mUpdateCCDB = true;
183 return;
184 }
185
186 if (!mOldPed) { // was not read from CCDB, but expected
187 mUpdateCCDB = true;
188 return;
189 }
190
191 // Compare to current
192 int nChanged = 0;
193 for (short i = o2::phos::Mapping::NCHANNELS; i > 1792; i--) {
194 short dp = mPedestals->getHGPedestal(i) - mOldPed->getHGPedestal(i);
195 mPedDiff[i] = dp;
196 if (abs(dp) > 1) { // not a fluctuation
197 nChanged++;
198 }
199 dp = mPedestals->getLGPedestal(i) - mOldPed->getLGPedestal(i);
200 mPedDiff[i + o2::phos::Mapping::NCHANNELS] = dp;
201 if (abs(dp) > 1) { // not a fluctuation
202 nChanged++;
203 }
204 }
205 LOG(info) << nChanged << " channels changed more that 1 ADC channel";
206 if (nChanged > kMinorChange) { // serious change, do not update CCDB automatically, use "force" option to overwrite
207 LOG(error) << "too many channels changed: " << nChanged << " (threshold not more than " << kMinorChange << ")";
208 if (!mForceUpdate) {
209 LOG(error) << "you may use --forceupdate option to force updating ccdb";
210 }
211 mUpdateCCDB = false;
212 } else {
213 mUpdateCCDB = true;
214 }
215}
216
218{
219
220 std::vector<InputSpec> inputs;
221 inputs.emplace_back("cells", ConcreteDataTypeMatcher{o2::header::gDataOriginPHS, "CELLS"}, o2::framework::Lifetime::Timeframe);
222 inputs.emplace_back("cellTriggerRecords", ConcreteDataTypeMatcher{o2::header::gDataOriginPHS, "CELLTRIGREC"}, o2::framework::Lifetime::Timeframe);
223 if (useCCDB) {
224 inputs.emplace_back("oldped", o2::header::gDataOriginPHS, "PHS_Calibr", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("PHS/Calib/Pedestals"));
225 }
226
228 std::vector<OutputSpec> outputs;
229 outputs.emplace_back(o2::header::gDataOriginPHS, "CALIBDIFF", 0, o2::framework::Lifetime::Sporadic);
230 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBPayload, "PHOS_Pedestal"}, o2::framework::Lifetime::Sporadic);
231 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBWrapper, "PHOS_Pedestal"}, o2::framework::Lifetime::Sporadic);
232 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBPayload, "PHOS_PedestalVec"}, o2::framework::Lifetime::Sporadic);
233 outputs.emplace_back(ConcreteDataTypeMatcher{clbUtils::gDataOriginCDBWrapper, "PHOS_PedestalVec"}, o2::framework::Lifetime::Sporadic);
234
235 return o2::framework::DataProcessorSpec{"PedestalCalibSpec",
236 inputs,
237 outputs,
238 o2::framework::adaptFromTask<PHOSPedestalCalibDevice>(useCCDB, forceUpdate),
239 o2::framework::Options{{"statistics", o2::framework::VariantType::Int, 1000, {"max. number of events to process"}}}};
240}
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)
std::vector< ConfigParamSpec > Options
o2::framework::DataProcessorSpec getPedestalCalibSpec(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