Project
Loading...
Searching...
No Matches
PHOSRunbyrunCalibrator.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
15#include "CCDB/CcdbApi.h"
16#include "CCDB/CcdbObjectInfo.h"
19#include "TFile.h"
20#include "TF1.h"
21
22#include <fairlogger/Logger.h>
23
24using namespace o2::phos;
25
27
28PHOSRunbyrunSlot::PHOSRunbyrunSlot(bool useCCDB, std::string path) : mUseCCDB(useCCDB), mCCDBPath(path)
29{
30 const int nMass = 150.;
31 const float massMax = 0.3;
32 for (int mod = 0; mod < 4; mod++) {
33 mReMi[2 * mod] = boost::histogram::make_histogram(boost::histogram::axis::regular<>(nMass, 0., massMax, "mgg"));
34 mReMi[2 * mod + 1] = boost::histogram::make_histogram(boost::histogram::axis::regular<>(nMass, 0., massMax, "mgg"));
35 }
36 mBuffer.reset(new RingBuffer());
37}
39{
40 mUseCCDB = other.mUseCCDB;
41 mRunStartTime = other.mRunStartTime;
42 mCCDBPath = other.mCCDBPath;
43 const int nMass = 150.;
44 const float massMax = 0.3;
45 for (int mod = 0; mod < 4; mod++) {
46 mReMi[2 * mod] = boost::histogram::make_histogram(boost::histogram::axis::regular<>(nMass, 0., massMax, "mgg"));
47 mReMi[2 * mod + 1] = boost::histogram::make_histogram(boost::histogram::axis::regular<>(nMass, 0., massMax, "mgg"));
48 }
49 mBuffer.reset(new RingBuffer());
50 mBadMap = nullptr;
51}
52
54{
55 // to print number of entries in pi0 region
56 double s[4];
57 for (int mod = 0; mod < 4; mod++) {
58 s[mod] = boost::histogram::algorithm::sum(mReMi[2 * mod]);
59 }
60 LOG(info) << "Total number of entries in pi0 region: " << s[0] << "," << s[1] << "," << s[2] << "," << s[3];
61}
62
63void PHOSRunbyrunSlot::fill(const gsl::span<const Cluster>& clusters, const gsl::span<const TriggerRecord>& trs)
64{
65 if (!mBadMap) {
66 if (mUseCCDB) {
67 LOG(info) << "Retrieving BadMap from CCDB";
68 auto& ccdbManager = o2::ccdb::BasicCCDBManager::instance();
69 ccdbManager.setURL(o2::base::NameConf::getCCDBServer());
70 LOG(info) << " set-up CCDB " << o2::base::NameConf::getCCDBServer();
71 mBadMap = std::make_unique<o2::phos::BadChannelsMap>(*(ccdbManager.get<o2::phos::BadChannelsMap>("PHS/Calib/BadMap")));
72
73 if (!mBadMap) { // was not read from CCDB, but expected
74 LOG(fatal) << "Can not read BadMap from CCDB, you may use --not-use-ccdb option to create default bad map";
75 }
76 } else {
77 LOG(info) << "Do not use CCDB, create default BadMap";
78 mBadMap.reset(new BadChannelsMap());
79 }
80 }
81
82 for (auto& tr : trs) {
83
84 int firstCluInEvent = tr.getFirstEntry();
85 int lastCluInEvent = firstCluInEvent + tr.getNumberOfObjects();
86
87 // TODO!!! Get MFT0 vertex
88 TVector3 vertex = {0., 0., 0.};
89 mBuffer->startNewEvent(); // mark stored clusters to be used for Mixing
90 for (int i = firstCluInEvent; i < lastCluInEvent; i++) {
91 const Cluster& clu = clusters[i];
92
93 if (!checkCluster(clu)) {
94 continue;
95 }
96 // prepare TLorentsVector
97 float posX, posZ;
98 clu.getLocalPosition(posX, posZ);
99 TVector3 vec3;
100 Geometry::GetInstance("Run3")->local2Global(clu.module(), posX, posZ, vec3);
101 vec3 -= vertex;
102 float e = clu.getEnergy();
103 vec3 *= 1. / vec3.Mag();
104 TLorentzVector v(vec3.X() * e, vec3.Y() * e, vec3.Z() * e, e);
105 for (short ip = mBuffer->size(); ip--;) {
106 const TLorentzVector& vp = mBuffer->getEntry(ip);
107 TLorentzVector sum = v + vp;
108 if (sum.Pt() > mPtCut) {
109 if (mBuffer->isCurrentEvent(ip)) { // same (real) event
110 mReMi[2 * clu.module()](sum.M()); // put all high-pt pairs to bin 4-6 GeV
111 } else { // Mixed
112 mReMi[2 * clu.module() + 1](sum.M()); // put all high-pt pairs to bin 4-6 GeV
113 }
114 }
115 }
116 mBuffer->addEntry(v);
117 }
118 }
119}
121{
122 // Not used
123}
124bool PHOSRunbyrunSlot::checkCluster(const Cluster& clu)
125{
126 if (clu.getEnergy() > 1.e-4) {
127 return false;
128 }
129 // First check BadMap
130 float posX, posZ;
131 clu.getLocalPosition(posX, posZ);
132 short absId;
133 Geometry::relPosToAbsId(clu.module(), posX, posZ, absId);
134 if (!mBadMap->isChannelGood(absId)) {
135 return false;
136 }
137 return (clu.getEnergy() > 0.3 && clu.getMultiplicity() > 1);
138}
140{
141 for (int mod = 0; mod < 8; mod++) {
142 mReMi[mod].reset();
143 }
144}
145
146//==============================================================
147
149{
150 const int nMass = 150.;
151 const float massMax = 0.3;
152 for (int mod = 0; mod < 4; mod++) {
153 mReMi[2 * mod] = new TH1F(Form("hReInvMassMod%d", mod), "Real inv. mass per module", nMass, 0., massMax);
154 mReMi[2 * mod + 1] = new TH1F(Form("hMiInvMassMod%d", mod), "Mixed inv. mass per module", nMass, 0., massMax);
155 }
156}
158{
159 for (int mod = 0; mod < 8; mod++) {
160 if (mReMi[mod]) {
161 mReMi[mod]->Delete();
162 mReMi[mod] = nullptr;
163 }
164 }
165}
166
168{
169 // otherwize will be merged with next Slot
170 return true;
171}
176{
177
178 // Extract results for the single slot
180 LOG(info) << "Finalize slot " << slot.getTFStart() << " <= TF <= " << slot.getTFEnd();
181 // Add histos
182 for (int mod = 0; mod < 8; mod++) {
183 PHOSRunbyrunSlot::boostHisto& tmp = c->getCollectedHistos(mod);
184 int indx = 1;
185 for (auto&& x : boost::histogram::indexed(tmp)) {
186 mReMi[mod]->SetBinContent(indx, x.get() + mReMi[mod]->GetBinContent(indx));
187 indx++;
188 }
189 }
190 c->clear();
191}
192
194{
195
196 auto& cont = getSlots();
197 auto& slot = front ? cont.emplace_front(tstart, tend) : cont.emplace_back(tstart, tend);
198 slot.setContainer(std::make_unique<PHOSRunbyrunSlot>(mUseCCDB, mCCDBPath));
199 return slot;
200}
201
202bool PHOSRunbyrunCalibrator::process(TFType tf, const gsl::span<const Cluster>& clu, const gsl::span<const TriggerRecord>& tr)
203{
204
205 // process current TF
206 auto& slotTF = getSlotForTF(tf);
207 slotTF.getContainer()->setRunStartTime(tf);
208 slotTF.getContainer()->fill(clu, tr);
209
210 return true;
211}
213{
214
215 // Merge collected in different slots histograms
216 TF1 fRatio("ratio", this, &PHOSRunbyrunCalibrator::CBRatio, 0, 1, 6, "PHOSRunbyrunCalibrator", "CBRatio");
217 TF1 fBg("background", this, &PHOSRunbyrunCalibrator::bg, 0, 1, 6, "PHOSRunbyrunCalibrator", "bg");
218 TF1 fSignal("signal", this, &PHOSRunbyrunCalibrator::CBSignal, 0, 1, 6, "PHOSRunbyrunCalibrator", "CBSignal");
219 // fit inv mass distributions
220
221 for (int mod = 0; mod < 4; mod++) {
222 mReMi[2 * mod]->Sumw2();
223 mReMi[2 * mod + 1]->Sumw2();
224 TH1D* tmp = (TH1D*)mReMi[2 * mod]->Clone("Ratio");
225 tmp->Divide(mReMi[2 * mod + 1]);
226 fRatio.SetParameters(1., 0.134, 0.005, 0.01, 0., 0.);
227 tmp->Fit(&fRatio, "q", "", 0.07, 0.22);
228 fBg.SetParameters(fRatio.GetParameter(3), fRatio.GetParameter(4), fRatio.GetParameter(5));
229 mReMi[2 * mod + 1]->Multiply(&fBg);
230 // mReMi[2*mod]->Add(mReMi[2*mod+1],-1.) ;
231 fSignal.SetParameters(0.3 * mReMi[2 * mod]->Integral(65, 67, ""), 0.135, 0.005);
232 mReMi[2 * mod]->Fit(&fSignal, "q", "", 0.07, 0.22);
233 mRunByRun[2 * mod] = fSignal.GetParameter(1);
234 mRunByRun[2 * mod + 1] = fSignal.GetParError(1);
235 tmp->Write();
236 mReMi[2 * mod]->Write();
237 mReMi[2 * mod + 1]->Write();
238 delete tmp;
239 // Clear before next period?
240 mReMi[2 * mod]->Reset();
241 mReMi[2 * mod + 1]->Reset();
242 }
243
244 LOG(info) << "Wrote Run-by-run calibration histos";
245}
246double PHOSRunbyrunCalibrator::CBRatio(double* x, double* par)
247{
248 double m = par[1];
249 double s = par[2];
250 const double n = 4.1983;
251 const double a = 1.5;
252 const double A = TMath::Power((n / TMath::Abs(a)), n) * TMath::Exp(-a * a / 2);
253 const double B = n / TMath::Abs(a) - TMath::Abs(a);
254 double dx = (x[0] - m) / s;
255 if (dx > -a) {
256 return par[0] * exp(-dx * dx / 2.) +
257 par[3] + par[4] * x[0] + par[5] * x[0] * x[0];
258 } else {
259 return par[0] * A * TMath::Power((B - dx), -n) +
260 par[3] + par[4] * x[0] + par[5] * x[0] * x[0];
261 }
262}
263double PHOSRunbyrunCalibrator::CBSignal(double* x, double* par)
264{
265 double m = par[1];
266 double s = par[2];
267 const double n = 4.1983;
268 const double a = 1.5;
269 const double A = TMath::Power((n / TMath::Abs(a)), n) * TMath::Exp(-a * a / 2);
270 const double B = n / TMath::Abs(a) - TMath::Abs(a);
271 double dx = (x[0] - m) / s;
272 if (dx > -a) {
273 return par[0] * exp(-dx * dx / 2.) + par[3];
274 } else {
275 return par[0] * A * TMath::Power((B - dx), -n) + par[3];
276 }
277}
278double PHOSRunbyrunCalibrator::bg(double* x, double* par)
279{
280 return par[0] + par[1] * x[0] + par[2] * x[0] * x[0];
281}
uint64_t exp(uint64_t base, uint8_t exp) noexcept
uint64_t vertex
Definition RawEventData.h:9
int32_t i
uint32_t c
Definition RawData.h:2
Definition A.h:16
Definition B.h:16
static std::string getCCDBServer()
Definition NameConf.cxx:110
TFType getTFEnd() const
Definition TimeSlot.h:47
const Container * getContainer() const
Definition TimeSlot.h:53
TFType getTFStart() const
Definition TimeSlot.h:46
static BasicCCDBManager & instance()
CCDB container for bad (masked) channels in PHOS.
Contains PHOS cluster parameters.
Definition Cluster.h:39
float getEnergy() const
Definition Cluster.h:56
int getMultiplicity() const
Definition Cluster.h:86
char module() const
Definition Cluster.h:92
void getLocalPosition(float &posX, float &posZ) const
Definition Cluster.h:76
static void relPosToAbsId(char module, float x, float z, short &absId)
Definition Geometry.cxx:220
void local2Global(char module, float x, float z, TVector3 &globaPos) const
Definition Geometry.cxx:234
static Geometry * GetInstance()
Definition Geometry.h:63
double CBSignal(double *x, double *p)
bool process(TFType tf, const gsl::span< const Cluster > &clu, const gsl::span< const TriggerRecord > &trs)
bool hasEnoughData(const Slot &slot) const final
Slot & emplaceNewSlot(bool front, TFType tstart, TFType tend) final
void fill(const gsl::span< const Cluster > &clusters, const gsl::span< const TriggerRecord > &trs)
void merge(const PHOSRunbyrunSlot *prev)
boost::histogram::histogram< std::tuple< boost::histogram::axis::regular< double, boost::use_default, boost::use_default, boost::use_default > >, boost::histogram::unlimited_storage< std::allocator< char > > > boostHisto
PHOSRunbyrunSlot(bool useCCDB, std::string path)
float sum(float s, o2::dcs::DataPointValue v)
Definition dcs-ccdb.cxx:39
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
const GLdouble * v
Definition glcorearb.h:832
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
std::unique_ptr< GPUReconstructionTimeframe > tf
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
Cluster clu
std::vector< Cluster > clusters