Project
Loading...
Searching...
No Matches
FastMultEst.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
14#include "Framework/Logger.h"
15#include <ctime>
16#include <cstring>
17#include <TRandom.h>
18
19using namespace o2::its;
20
21bool FastMultEst::sSeedSet = false;
22
25{
26 if (!sSeedSet && FastMultEstConfig::Instance().cutRandomFraction > 0.f) {
27 sSeedSet = true;
28 if (FastMultEstConfig::Instance().randomSeed > 0) {
29 gRandom->SetSeed(FastMultEstConfig::Instance().randomSeed);
30 } else if (FastMultEstConfig::Instance().randomSeed < 0) {
31 gRandom->SetSeed(std::time(nullptr) % 0xffff);
32 }
33 }
34}
35
38void FastMultEst::fillNClPerLayer(const gsl::span<const o2::itsmft::CompClusterExt>& clusters)
39{
41 std::memset(&nClPerLayer[0], 0, sizeof(int) * FastMultEst::NLayers);
42 for (int i = clusters.size(); i--;) { // profit from clusters being ordered in chip increasing order
43 while (clusters[i].getSensorID() < nchAcc) {
44 assert(lr >= 0);
46 }
47 nClPerLayer[lr]++;
48 }
49}
50
53float FastMultEst::processNoiseFree(const std::array<int, NLayers> ncl)
54{
55 // we assume that on the used layers the observed number of clusters is defined by the
56 // the noise ~ nu * Nchips and contribution from the signal tracks Ntr*mAccCorr
57 const auto& conf = FastMultEstConfig::Instance();
58
59 float mat[3] = {0}, b[2] = {0};
60 nLayersUsed = 0;
61 for (int il = conf.firstLayer; il <= conf.lastLayer; il++) {
62 if (ncl[il] > 0) {
64 float err2i = 1. / ncl[il];
65 float m2n = nch * err2i;
66 mat[0] += err2i * conf.accCorr[il] * conf.accCorr[il];
67 mat[2] += nch * m2n;
68 mat[1] += conf.accCorr[il] * m2n; // non-diagonal element
69 b[0] += conf.accCorr[il];
70 b[1] += nch;
72 }
73 }
74 mult = noisePerChip = chi2 = -1;
75 float det = mat[0] * mat[2] - mat[1] * mat[1];
76 if (nLayersUsed < 2 || std::abs(det) < 1e-15) {
77 return -1;
78 }
79 float detI = 1. / det;
80 mult = detI * (b[0] * mat[2] - b[1] * mat[1]);
81 noisePerChip = detI * (b[1] * mat[0] - b[0] * mat[1]);
82 cov[0] = mat[2] * detI;
83 cov[2] = mat[0] * detI;
84 cov[1] = -mat[1] * detI;
85 chi2 = 0.;
86 for (int il = conf.firstLayer; il <= conf.lastLayer; il++) {
87 if (ncl[il] > 0) {
89 float diff = mult * conf.accCorr[il] + nch * noisePerChip - ncl[il];
90 chi2 += diff * diff / ncl[il];
91 }
92 }
93 chi2 = nLayersUsed > 2 ? chi2 / (nLayersUsed - 2) : 0.;
94 return mult > 0 ? mult : 0;
95}
96
99float FastMultEst::processNoiseImposed(const std::array<int, NLayers> ncl)
100{
101 // we assume that on the used layers the observed number of clusters is defined by the
102 // the noise ~ nu * Nchips and contribution from the signal tracks Ntr*conf.accCorr
103 //
104 // minimize the form sum_lr (noise_i - mu nchips_i)^2 / (mu nchips_i) + lambda_i * (noise_i + mult*acc_i - ncl_i)
105 // whith noise_i being estimate of the noise clusters in nchips_i of layer i, mu is the mean noise per chip,
106 // mult is the number of signal clusters on the ref. (1st) layer and the acc_i is the acceptance of layer i wrt 1st.
107 // The lambda_i is hust a Lagrange multiplier.
108
109 const auto& conf = FastMultEstConfig::Instance();
110 float w2sum = 0., wnsum = 0., wsum = 0.;
111 nLayersUsed = 0;
112 for (int il = conf.firstLayer; il <= conf.lastLayer; il++) {
113 if (ncl[il] > 0) {
114 float nchInv = 1. / o2::itsmft::ChipMappingITS::getNChipsPerLr(il);
115 w2sum += conf.accCorr[il] * conf.accCorr[il] * nchInv;
116 wnsum += ncl[il] * nchInv * conf.accCorr[il];
117 wsum += conf.accCorr[il];
118 nLayersUsed++;
119 }
120 }
121 mult = 0;
122 chi2 = -1;
123 noisePerChip = conf.imposeNoisePerChip;
124 if (nLayersUsed < 1) {
125 return -1;
126 }
127 auto w2sumI = 1. / w2sum;
128 mult = (wnsum - noisePerChip * wsum) * w2sumI;
129 cov[0] = wnsum * w2sumI;
130 cov[2] = 0.;
131 cov[1] = 0.;
132
133 chi2 = 0.;
134 for (int il = conf.firstLayer; il <= conf.lastLayer; il++) {
135 if (ncl[il] > 0) {
136 float noise = ncl[il] - mult * conf.accCorr[il], estNoise = o2::itsmft::ChipMappingITS::getNChipsPerLr(il) * noisePerChip;
137 float diff = noise - estNoise;
138 chi2 += diff * diff / estNoise;
139 }
140 }
141 chi2 = nLayersUsed > 2 ? chi2 / (nLayersUsed - 2) : 0.;
142 return mult > 0 ? mult : 0;
143}
144
145int FastMultEst::selectROFs(const gsl::span<const o2::itsmft::ROFRecord> rofs, const gsl::span<const o2::itsmft::CompClusterExt> clus,
146 const gsl::span<const o2::itsmft::PhysTrigger> trig, std::vector<bool>& sel)
147{
148 int nrof = rofs.size(), nsel = 0;
149 const auto& multEstConf = FastMultEstConfig::Instance(); // parameters for mult estimation and cuts
150 sel.clear();
151 sel.resize(nrof, true); // by default select all
152 lastRandomSeed = gRandom->GetSeed();
153 if (multEstConf.isMultCutRequested()) {
154 for (uint32_t irof = 0; irof < nrof; irof++) {
155 nsel += sel[irof] = multEstConf.isPassingMultCut(process(rofs[irof].getROFData(clus)));
156 }
157 } else {
158 nsel = nrof;
159 }
160 using IdNT = std::pair<int, int>;
161 if (multEstConf.cutRandomFraction > 0.) {
162 int ntrig = trig.size(), currTrig = 0;
163 if (multEstConf.preferTriggered) {
165 std::vector<IdNT> nTrigROF;
166 nTrigROF.reserve(nrof);
167 for (uint32_t irof = 0; irof < nrof; irof++) {
168 if (sel[irof]) {
169 if (nsel && gRandom->Rndm() < multEstConf.cutRandomFraction) {
170 nsel--;
171 }
172 auto irROF = rofs[irof].getBCData();
173 while (currTrig < ntrig && trig[currTrig].ir < irROF) { // triggers are sorted, jump to 1st one not less than current ROF
174 currTrig++;
175 }
176 auto& trof = nTrigROF.emplace_back(irof, 0);
177 irROF += alpParams.roFrameLengthInBC;
178 while (currTrig < ntrig && trig[currTrig].ir < irROF) {
179 trof.second++;
180 currTrig++;
181 }
182 }
183 }
184 if (nsel > 0) {
185 sort(nTrigROF.begin(), nTrigROF.end(), [](const IdNT& a, const IdNT& b) { return a.second > b.second; }); // order in number of triggers
186 auto last = nTrigROF.begin() + nsel;
187 sort(nTrigROF.begin(), last, [](const IdNT& a, const IdNT& b) { return a.first < b.first; }); // order in ROF ID first nsel ROFs
188 }
189 for (int i = nsel; i < int(nTrigROF.size()); i++) { // reject ROFs in the tail
190 sel[nTrigROF[i].first] = false;
191 }
192 } else { // dummy random rejection
193 for (int irof = 0; irof < nrof; irof++) {
194 if (sel[irof]) {
195 float sr = gRandom->Rndm();
196 if (gRandom->Rndm() < multEstConf.cutRandomFraction) {
197 sel[irof] = false;
198 nsel--;
199 }
200 }
201 }
202 }
203 }
204 LOGP(debug, "NSel = {} of {} rofs Seeds: before {} after {}", nsel, nrof, lastRandomSeed, gRandom->GetSeed());
205
206 return nsel;
207}
int32_t i
std::ostringstream debug
static constexpr int getNChipsPerLr(int l)
compose FEEid for given stave (ru) relative to layer and link, see documentation in the constructor
static constexpr int getNChips()
number of chips per barrel
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
std::array< int, NLayers > nClPerLayer
state of the gRandom before
Definition FastMultEst.h:43
float processNoiseFree(const std::array< int, NLayers > ncl)
void fillNClPerLayer(const gsl::span< const o2::itsmft::CompClusterExt > &clusters)
float processNoiseImposed(const std::array< int, NLayers > ncl)
uint32_t lastRandomSeed
number of layers actually used
Definition FastMultEst.h:41
int selectROFs(const gsl::span< const o2::itsmft::ROFRecord > rofs, const gsl::span< const o2::itsmft::CompClusterExt > clus, const gsl::span< const o2::itsmft::PhysTrigger > trig, std::vector< uint8_t > &sel)
float cov[3]
estimated or imposed noise per chip
Definition FastMultEst.h:38
float noisePerChip
estimated signal clusters multipliciy at reference (1st?) layer
Definition FastMultEst.h:37
float chi2
covariance matrix of estimation
Definition FastMultEst.h:39
static bool sSeedSet
Definition FastMultEst.h:62
static constexpr int NLayers
Definition FastMultEst.h:34
o2::InteractionRecord ir(0, 0)
std::vector< Cluster > clusters