Project
Loading...
Searching...
No Matches
CPVGainCalibDevice.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"
15#include <string>
16#include <ctime>
17#include <fairlogger/Logger.h>
25#include "CCDB/CcdbObjectInfo.h"
30#include "CPVBase/Geometry.h"
31#include "TF1.h"
32
33using namespace o2::cpv;
34
36{
37 // Check if files from previous runs exist
38 // if yes, read histogram
39 mMean = std::unique_ptr<TH2F>(new TH2F("Gains", "Signals per channel", o2::cpv::Geometry::kNCHANNELS, 0.5, o2::cpv::Geometry::kNCHANNELS + 0.5, 1024, 0., 4096.));
40
41 std::string filename = mPath + "CPVGains.root";
42 TFile filein(filename.data(), "READ");
43 if (filein.IsOpen()) {
44 mMean->Add(static_cast<TH2F*>(filein.Get("Gains")));
45 filein.Close();
46 }
47}
48
50{
51
52 //
53 for (const auto& rawData : framework::InputRecordWalker(ctx.inputs())) {
54
55 o2::cpv::RawReaderMemory rawreader(o2::framework::DataRefUtils::as<const char>(rawData));
56 // loop over all the DMA pages
57 while (rawreader.hasNext()) {
58 try {
59 rawreader.next();
60 } catch (RawErrorType_t e) {
61 LOG(error) << "Raw decoding error " << (int)e;
62 // if problem in header, abandon this page
64 break;
65 }
66 // if problem in payload, try to continue
67 continue;
68 }
69 // auto& header = rawreader.getRawHeader();
70 // auto triggerBC = o2::raw::RDHUtils::getTriggerBC(header);
71 // auto triggerOrbit = o2::raw::RDHUtils::getTriggerOrbit(header);
72 // use the altro decoder to decode the raw data, and extract the RCU trailer
73 o2::cpv::RawDecoder decoder(rawreader);
74 RawErrorType_t err = decoder.decode();
75 if (err != kOK) {
76 // TODO handle severe errors
77 continue;
78 }
79 // Loop over all the channels
80 for (auto adch : decoder.getDigits()) {
81 AddressCharge ac = {adch};
82 unsigned short absId = ac.Address;
83 mMean->Fill(absId, ac.Charge);
84 }
85 } // RawReader::hasNext
86 }
87}
88
90{
91
92 LOG(info) << "[CPVGainCalibDevice - endOfStream]";
93 // calculate stuff here
95 checkGains();
96 sendOutput(ec.outputs());
97}
98
100{
101 // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output
102 // TODO in principle, this routine is generic, can be moved to Utils.h
103
104 if (mUpdateCCDB || mForceUpdate) {
105 // prepare all info to be sent to CCDB
107 auto image = o2::ccdb::CcdbApi::createObjectImage(mCalibParams.get(), &info);
108
109 auto flName = o2::ccdb::CcdbApi::generateFileName("CalibParams");
110 info.setPath("CPV/Calib/CalibParams");
111 info.setObjectType("CalibParams");
112 info.setFileName(flName);
113 // TODO: should be changed to time of the run
114 time_t now = time(nullptr);
117 std::map<std::string, std::string> md;
118 info.setMetaData(md);
119
120 LOG(info) << "Sending object CPV/Calib/CalibParams";
121
123
124 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "CPV_CalibParams", subSpec}, *image.get());
125 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "CPV_CalibParams", subSpec}, info);
126 }
127
128 // Write either final spectra (to calculate bad map) or temporary file
129 if (mUpdateCCDB) { // good statistics, final spectra
130 std::string filename = mPath + "CPVGains";
131 time_t now = time(nullptr);
132 tm* ltm = localtime(&now);
133 filename += TString::Format("_%d%d%d%d%d.root", 1 + ltm->tm_min, 1 + ltm->tm_hour, ltm->tm_mday, 1 + ltm->tm_mon, 1970 + ltm->tm_year);
134 LOG(debug) << "opening file " << filename.data();
135 TFile fout(filename.data(), "RECREATE");
136 mMean->Write();
137 fout.Close();
138 } else {
139 std::string filename = mPath + "CPVGains.root";
140 LOG(info) << "statistics not sufficient yet: " << mMean->Integral() / mMean->GetNbinsX() << ", writing file " << filename;
141 TFile fout(filename.data(), "RECREATE");
142 mMean->Write();
143 fout.Close();
144 }
145 // Anyway send change to QC
146 output.snapshot(o2::framework::Output{"CPV", "GAINDIFF", 0}, mGainRatio);
147}
148
150{
151 // Check if statistics is sufficient to fit distributions
152 // Mean statistics should be ~2 times larger than minimal
153 mUpdateCCDB = false;
154 if (mMean->Integral() > 2 * kMinimalStatistics * (o2::cpv::Geometry::kNCHANNELS)) { // average per channel
155 mCalibParams.reset(new CalibParams());
156
157 TF1* fitFunc = new TF1("fitFunc", "landau", 0., 4000.);
158 fitFunc->SetParameters(1., 200., 60.);
159 fitFunc->SetParLimits(1, 10., 2000.);
160 for (int i = 1; i <= mMean->GetNbinsX(); i++) {
161 TH1D* tmp = mMean->ProjectionY(Form("channel%d", i), i, i);
162 fitFunc->SetParameters(1., 200., 60.);
163 if (tmp->Integral(20, 2000) < kMinimalStatistics) {
164 tmp->Delete();
165 continue;
166 }
167 tmp->Fit(fitFunc, "QL0", "", 20., 2000.);
168 float a = fitFunc->GetParameter(1);
169 if (a > 0) {
170 a = 200. / a;
171 mCalibParams->setGain(i - 1, a); // absId starts from 0
172 }
173 tmp->Delete();
174 }
175 mUpdateCCDB = true;
176 // TODO: if file historam processed, remove temporary root file if it exists
177 }
178}
179
181{
182 // Estimate if newly calculated gains are reasonable: close to reviously calculated
183 // Do not update existing object automatically if difference is too strong
184 // create object with validity range if far future (?) and send warning (e-mail?) to operator
185
186 if (!mUpdateCCDB) { // gains were not calculated, do nothing
187 return;
188 }
189
190 if (mUseCCDB) { // read calibration objects from ccdb
191 // //TODO:
192 // //Get current calibration
193 // int nChanged=0;
194 // for(short i=o2::cpv::Geometry::kNCHANNELS; --i;){
195 // short dp=2.
196 // if(oldPed.getGain(i)>0) {
197 // dp = mCalibParams.getGain(i)/oldPed.getGain(i);
198 // }
199 // mGainRatio[i]=dp ;
200 // if(abs(dp-1.)>0.1){ //not a fluctuation
201 // nChanged++;
202 // }
203 // }
204 // if(nChanged>kMinorChange){ //serious change, do not update CCDB automatically, use "force" option to overwrite
205 // mUpdateCCDB=false;
206 // }
207 // else{
208 // mUpdateCCDB=true;
209 // }
210 }
211}
212
213o2::framework::DataProcessorSpec o2::cpv::getGainCalibSpec(bool useCCDB, bool forceUpdate, std::string path)
214{
215
216 std::vector<o2::framework::OutputSpec> outputs;
217 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "CPV_CalibParams"}, o2::framework::Lifetime::Sporadic);
218 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "CPV_CalibParams"}, o2::framework::Lifetime::Sporadic);
219
220 outputs.emplace_back("CPV", "GAINDIFF", 0, o2::framework::Lifetime::Sporadic);
221
222 return o2::framework::DataProcessorSpec{"GainCalibSpec",
223 o2::framework::select("A:CPV/RAWDATA"),
224 outputs,
225 o2::framework::adaptFromTask<CPVGainCalibDevice>(useCCDB, forceUpdate, path),
227}
Utils and constants for calibration and related workflows.
int16_t time
Definition RawEventData.h:4
int32_t i
A helper class to iteratate over all parts of all input routes.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
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
void setStartValidityTimestamp(long start)
void setFileName(const std::string &nm)
void setPath(const std::string &path)
void setEndValidityTimestamp(long end)
void setObjectType(const std::string &tp)
void setMetaData(const std::map< std::string, std::string > &md)
static constexpr long INFINITE_TIMESTAMP
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void sendOutput(DataAllocator &output)
void run(o2::framework::ProcessingContext &pc) final
void init(o2::framework::InitContext &ic) final
static constexpr short kNCHANNELS
Definition Geometry.h:30
Decoder of the ALTRO data in the raw page.
Definition RawDecoder.h:68
const std::vector< uint32_t > & getDigits() const
Get the reference to the digits container.
Definition RawDecoder.h:89
RawErrorType_t decode()
Decode the raw cpv payload stream.
Reader for raw data produced by the Readout application in in-memory format.
RawErrorType_t next()
Read next payload from the stream.
bool hasNext() const
check if more pages are available in the raw file
A helper class to iteratate over all parts of all input routes.
InputRecord & inputs()
The inputs associated with this processing context.
GLeglImageOES image
Definition glcorearb.h:4021
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
o2::framework::DataProcessorSpec getGainCalibSpec(bool useCCDB, bool forceUpdate, std::string path)
@ kOK
NoError.
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
std::string filename()
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"
uint32_t Charge
Bits 18 - 32 : charge.
Definition RawDecoder.h:44
uint32_t Address
Bits 0 - 17 : Address.
Definition RawDecoder.h:43