Project
Loading...
Searching...
No Matches
CompareTask.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
12#include "CompareTask.h"
13#include "CompareTracks.h"
19#include "Histos.h"
20#include "MCHEvaluation/Draw.h"
23#include <TCanvas.h>
24#include <TFile.h>
25#include <TH1.h>
26#include <TString.h>
27
28using namespace o2::framework;
29
30namespace o2::mch::eval
31{
32
33CompareTask::CompareTask(std::shared_ptr<o2::base::GRPGeomRequest> req) : mCcdbRequest(req) {}
34
36{
37 if (mCcdbRequest && base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
38 if (matcher == framework::ConcreteDataMatcher("GLO", "GRPMAGFIELD", 0)) {
40 }
41 }
42}
43
44void outputToPdfClearDivide(const std::string fileName,
45 TCanvas& c,
46 int nPadsx, int nPadsy)
47{
48 c.Print(fileName.c_str());
49 c.Clear();
50 c.Divide(nPadsx, nPadsy);
51}
52
53void CompareTask::pdfOutput()
54{
55 int nPadsx, nPadsy;
56 TCanvas* c = autoCanvas("c", "c", mHistosAtVertex[0], &nPadsx, &nPadsy);
57 TCanvas* c2 = autoCanvas("c2", "c2", mHistosAtVertex[0], &nPadsx, &nPadsy);
58 c->Print(fmt::format("{}[", mOutputPdfFileName).c_str());
59
60 auto toPdf2 = [&](std::function<void(const std::array<std::vector<TH1*>, 2>&, TCanvas*)> func) {
61 func(mHistosAtVertex, c);
62 outputToPdfClearDivide(mOutputPdfFileName, *c, nPadsx, nPadsy);
63 };
64
65 auto toPdf5 = [&](std::function<void(const std::array<std::vector<TH1*>, 5>&, TCanvas*)> func) {
66 func(mComparisonsAtVertex, c);
67 outputToPdfClearDivide(mOutputPdfFileName, *c, nPadsx, nPadsy);
68 };
69
73
75
76 c->Clear();
77 drawTrackResiduals(mTrackResidualsAtFirstCluster, c);
78 c->Print(mOutputPdfFileName.c_str());
79
80 c->Clear();
81 drawClusterClusterResiduals(mClusterResiduals[4], "ClCl", c);
82 c->Print(mOutputPdfFileName.c_str());
83
84 c->Clear();
85 drawClusterTrackResiduals(mClusterResiduals[0], mClusterResiduals[1], "AllTracks", c);
86 c->Print(mOutputPdfFileName.c_str());
87
88 c->Clear();
89 c2->Clear();
90 drawClusterTrackResidualsSigma(mClusterResiduals[0], mClusterResiduals[1], "AllTracks", c, c2);
91 c->Print(mOutputPdfFileName.c_str());
92 c2->Print(mOutputPdfFileName.c_str());
93
94 c->Clear();
95 drawClusterTrackResiduals(mClusterResiduals[2], mClusterResiduals[3], "SimilarTracks", c);
96 c->Print(mOutputPdfFileName.c_str());
97
98 c->Clear();
99 c2->Clear();
100 drawClusterTrackResidualsSigma(mClusterResiduals[2], mClusterResiduals[3], "SimilarTracks", c, c2);
101 c->Print(mOutputPdfFileName.c_str());
102 c2->Print(mOutputPdfFileName.c_str());
103
104 c->Clear();
105 drawClusterTrackResidualsRatio(mClusterResiduals[0], mClusterResiduals[1], "AllTracks", c);
106 c->Print(mOutputPdfFileName.c_str());
107
108 c->Clear();
109 drawClusterTrackResidualsRatio(mClusterResiduals[2], mClusterResiduals[3], "SimilarTracks", c);
110 c->Print(mOutputPdfFileName.c_str());
111
112 c->Clear();
113
114 c->Print(fmt::format("{}]", mOutputPdfFileName).c_str());
115}
116
118{
119 auto outputFileName = ic.options().get<std::string>("outfile");
120 mOutputPdfFileName = ic.options().get<std::string>("pdf-outfile");
121 mPrintDiff = ic.options().get<bool>("print-diff");
122 mPrintAll = ic.options().get<bool>("print-all");
123 mApplyTrackSelection = ic.options().get<bool>("apply-track-selection");
124 mPrecision = ic.options().get<double>("precision");
126
127 mOutputRootFile = std::make_unique<TFile>(outputFileName.c_str(), "RECREATE");
128
129 createHistosAtVertex(mHistosAtVertex[0], "1");
130 createHistosAtVertex(mHistosAtVertex[1], "2");
131 createHistosAtVertex(mComparisonsAtVertex[0], "identical");
132 createHistosAtVertex(mComparisonsAtVertex[1], "similar1");
133 createHistosAtVertex(mComparisonsAtVertex[2], "similar2");
134 createHistosAtVertex(mComparisonsAtVertex[3], "additional");
135 createHistosAtVertex(mComparisonsAtVertex[4], "missing");
136 createHistosForClusterResiduals(mClusterResiduals[0], "AllTracks1", 2.);
137 createHistosForClusterResiduals(mClusterResiduals[1], "AllTracks2", 2.);
138 createHistosForClusterResiduals(mClusterResiduals[2], "SimilarTracks1", 2.);
139 createHistosForClusterResiduals(mClusterResiduals[3], "SimilarTracks2", 2.);
140 createHistosForClusterResiduals(mClusterResiduals[4], "ClCl", 0.2);
141 createHistosForTrackResiduals(mTrackResidualsAtFirstCluster);
142
143 mNofDifferences = 0;
144
145 auto stop = [this]() {
146 LOGP(warning, "Number of differences in ROF-by-ROF comparison: {}", mNofDifferences);
147 printStat();
148 if (!mOutputPdfFileName.empty()) {
149 pdfOutput();
150 }
151 mOutputRootFile->cd();
152 mOutputRootFile->WriteObject(&mHistosAtVertex, "histosAtVertex");
153 mOutputRootFile->WriteObject(&mComparisonsAtVertex, "comparisonsAtVertex");
154 mOutputRootFile->WriteObject(&mTrackResidualsAtFirstCluster, "trackResidualsAtFirstCluster");
155 mOutputRootFile->WriteObject(&mClusterResiduals, "clusterResiduals");
156 mOutputRootFile->Close();
157 };
158 ic.services().get<CallbackService>().set<CallbackService::Id::Stop>(stop);
159}
160
161std::list<ExtendedTrack> CompareTask::convert(gsl::span<const TrackMCH> mchTracks,
162 gsl::span<const Cluster> clusters)
163{
164 std::list<ExtendedTrack> tracks;
165 constexpr double vx{0.0};
166 constexpr double vy{0.0};
167 constexpr double vz{0.0};
168 for (const auto& mchTrack : mchTracks) {
169 tracks.emplace_back(mchTrack, clusters, vx, vy, vz);
170 }
171 return tracks;
172}
173
174void CompareTask::dump(std::string prefix,
175 const std::list<ExtendedTrack>& tracks1,
176 const std::list<ExtendedTrack>& tracks2)
177{
178 if (tracks1.size() > 0 || tracks2.size() > 0) {
179 LOGP(warning, "{} tracks1: {} tracks2: {}", prefix, tracks1.size(), tracks2.size());
180 for (const auto& t : tracks1) {
181 LOGP(warning, "Track1 {}", t.asString());
182 }
183 for (const auto& t : tracks2) {
184 LOGP(warning, "Track2 {}", t.asString());
185 }
186 }
187}
188
189std::list<ExtendedTrack> CompareTask::getExtendedTracks(const ROFRecord& rof,
190 gsl::span<const TrackMCH> tfTracks,
191 gsl::span<const Cluster> tfClusters)
192{
193 const auto mchTracks = tfTracks.subspan(rof.getFirstIdx(), rof.getNEntries());
194 return convert(mchTracks, tfClusters);
195}
196
198{
199 static int tf{0};
200 LOGP(info, "TF {}", tf);
201
202 if (mCcdbRequest) {
204 }
205
206 auto rofs1 = pc.inputs().get<gsl::span<ROFRecord>>("rofs1");
207 auto itracks1 = pc.inputs().get<gsl::span<TrackMCH>>("tracks1");
208 auto iclusters1 = pc.inputs().get<gsl::span<Cluster>>("clusters1");
209 auto rofs2 = pc.inputs().get<gsl::span<ROFRecord>>("rofs2");
210 auto itracks2 = pc.inputs().get<gsl::span<TrackMCH>>("tracks2");
211 auto iclusters2 = pc.inputs().get<gsl::span<Cluster>>("clusters2");
212
213 bool areSameRofs = std::equal(rofs1.begin(), rofs1.end(),
214 rofs2.begin(), rofs2.end(),
215 [](const ROFRecord& r1, const ROFRecord& r2) {
216 return r1.getBCData() == r2.getBCData() && r1.getBCWidth() == r2.getBCWidth();
217 }); // just compare BC id, orbit and BC width, not number of found tracks
218 if (!areSameRofs) {
219 LOGP(warning, "ROFs are different --> cannot perform ROF-by-ROF comparison");
220 }
221
222 auto nROFs = std::max(rofs1.size(), rofs2.size());
223 for (auto i = 0; i < nROFs; ++i) {
224
225 std::list<ExtendedTrack> tracks1{};
226 if (i < rofs1.size()) {
227 tracks1 = getExtendedTracks(rofs1[i], itracks1, iclusters1);
228 mNTracksAll[0] += tracks1.size();
229 if (mApplyTrackSelection) {
230 selectTracks(tracks1);
231 }
232 fillHistosAtVertex(tracks1, mHistosAtVertex[0]);
233 fillClusterTrackResiduals(tracks1, mClusterResiduals[0], false);
234 }
235
236 std::list<ExtendedTrack> tracks2{};
237 if (i < rofs2.size()) {
238 tracks2 = getExtendedTracks(rofs2[i], itracks2, iclusters2);
239 mNTracksAll[1] += tracks2.size();
240 if (mApplyTrackSelection) {
241 selectTracks(tracks2);
242 }
243 fillHistosAtVertex(tracks2, mHistosAtVertex[1]);
244 fillClusterTrackResiduals(tracks2, mClusterResiduals[1], false);
245 }
246
247 if (areSameRofs) {
248 int nDiff = compareEvents(tracks1, tracks2,
249 mPrecision,
250 mPrintDiff,
251 mPrintAll,
252 mTrackResidualsAtFirstCluster,
253 mClusterResiduals[4]);
254 fillClusterTrackResiduals(tracks1, mClusterResiduals[2], true);
255 fillClusterTrackResiduals(tracks2, mClusterResiduals[3], true);
256 if (nDiff > 0) {
257 if (mPrintDiff) {
258 LOG(warning) << "--> " << nDiff << " differences found in ROF " << rofs1[i];
259 }
260 mNofDifferences += nDiff;
261 }
262 fillComparisonsAtVertex(tracks1, tracks2, mComparisonsAtVertex);
263 }
264 }
265
266 ++tf;
267}
268
269void CompareTask::printStat()
270{
273
274 auto print = [](TString selection, int n1, int n2) {
275 if (n1 == 0) {
276 printf("%s | %8d | %8d | %7s ± %4s %%\n", selection.Data(), n1, n2, "nan", "nan");
277 } else {
278 double eff = double(n2) / n1;
279 double diff = 100. * (eff - 1.);
280 double err = 100. * std::max(1. / n1, std::sqrt(eff * std::abs(1. - eff) / n1));
281 printf("%s | %8d | %8d | %7.2f ± %4.2f %%\n", selection.Data(), n1, n2, diff, err);
282 }
283 };
284
285 printf("\n");
286 printf("-------------------------------------------------------\n");
287 printf("selection | file 1 | file 2 | diff\n");
288 printf("-------------------------------------------------------\n");
289
290 print("all ", mNTracksAll[0], mNTracksAll[1]);
291
292 print("matched ", mNTracksMatch[0], mNTracksMatch[1]);
293
294 print("selected ", mHistosAtVertex[0][0]->GetEntries(), mHistosAtVertex[1][0]->GetEntries());
295
296 double pTRange[6] = {0., 0.5, 1., 2., 4., 1000.};
297 for (int i = 0; i < 5; ++i) {
298 TString selection = (i == 0) ? TString::Format("pT < %.1f GeV/c", pTRange[1])
299 : ((i == 4) ? TString::Format("pT > %.1f ", pTRange[4])
300 : TString::Format("%.1f < pT < %.1f", pTRange[i], pTRange[i + 1]));
301 int n1 = mHistosAtVertex[0][0]->Integral(mHistosAtVertex[0][0]->GetXaxis()->FindBin(pTRange[i] + 0.01),
302 mHistosAtVertex[0][0]->GetXaxis()->FindBin(pTRange[i + 1] - 0.01));
303 int n2 = mHistosAtVertex[1][0]->Integral(mHistosAtVertex[1][0]->GetXaxis()->FindBin(pTRange[i] + 0.01),
304 mHistosAtVertex[1][0]->GetXaxis()->FindBin(pTRange[i + 1] - 0.01));
305 print(selection, n1, n2);
306 }
307
308 double pRange[6] = {0., 5., 10., 20., 40., 10000.};
309 for (int i = 0; i < 5; ++i) {
310 TString selection = (i == 0) ? TString::Format("p < %02.0f GeV/c ", pRange[1])
311 : ((i == 4) ? TString::Format("p > %02.0f ", pRange[4])
312 : TString::Format("%02.0f < p < %02.0f ", pRange[i], pRange[i + 1]));
313 int n1 = mHistosAtVertex[0][4]->Integral(mHistosAtVertex[0][4]->GetXaxis()->FindBin(pRange[i] + 0.01),
314 mHistosAtVertex[0][4]->GetXaxis()->FindBin(pRange[i + 1] - 0.01));
315 int n2 = mHistosAtVertex[1][4]->Integral(mHistosAtVertex[1][4]->GetXaxis()->FindBin(pRange[i] + 0.01),
316 mHistosAtVertex[1][4]->GetXaxis()->FindBin(pRange[i + 1] - 0.01));
317 print(selection, n1, n2);
318 }
319
320 printf("-------------------------------------------------------\n");
321 printf("\n");
322}
323} // namespace o2::mch::eval
void print() const
int32_t i
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
uint32_t c
Definition RawData.h:2
Definition of tools for track extrapolation.
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
ServiceRegistryRef services()
Definition InitContext.h:34
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
int getNEntries() const
get the number of associated objects
Definition ROFRecord.h:55
int getFirstIdx() const
get the index of the first associated object
Definition ROFRecord.h:57
static void setField()
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
std::list< ExtendedTrack > convert(gsl::span< const TrackMCH > mchTracks, gsl::span< const Cluster > clusters)
std::list< ExtendedTrack > getExtendedTracks(const ROFRecord &rof, gsl::span< const TrackMCH > tfTracks, gsl::span< const Cluster > tfClusters)
void run(o2::framework::ProcessingContext &pc)
CompareTask(std::shared_ptr< o2::base::GRPGeomRequest > req)
void dump(std::string prefix, const std::list< ExtendedTrack > &tracks1, const std::list< ExtendedTrack > &tracks2)
void init(o2::framework::InitContext &ic)
GLenum func
Definition glcorearb.h:778
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
void drawPlainHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)
Definition Draw.cxx:286
void createHistosForTrackResiduals(std::vector< TH1 * > &histos)
Definition Histos.cxx:37
void fillHistosAtVertex(const std::list< ExtendedTrack > &tracks, const std::vector< TH1 * > &histos)
Definition Histos.cxx:73
void selectTracks(std::list< ExtendedTrack > &tracks)
void drawClusterTrackResidualsSigma(const std::vector< TH1 * > &histos1, const std::vector< TH1 * > &histos2, const char *extension, TCanvas *c1=nullptr, TCanvas *c2=nullptr)
Definition Draw.cxx:211
void drawClusterClusterResiduals(const std::vector< TH1 * > &histos, const char *extension, TCanvas *c=nullptr)
Definition Draw.cxx:159
void drawClusterTrackResidualsRatio(const std::vector< TH1 * > &histos1, const std::vector< TH1 * > &histos2, const char *extension, TCanvas *c=nullptr)
Definition Draw.cxx:329
int compareEvents(std::list< ExtendedTrack > &tracks1, std::list< ExtendedTrack > &tracks2, double precision, bool printDiff, bool printAll, std::vector< TH1 * > &trackResidualsAtFirstCluster, std::vector< TH1 * > &clusterClusterResiduals)
void drawRatioHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)
Definition Draw.cxx:358
void fillClusterTrackResiduals(const std::list< ExtendedTrack > &tracks, std::vector< TH1 * > &histos, bool matched)
Definition Histos.cxx:196
void createHistosAtVertex(std::vector< TH1 * > &histos, const char *extension)
Definition Histos.cxx:55
void drawDiffHistosAtVertex(const std::array< std::vector< TH1 * >, 2 > &histos, TCanvas *c=nullptr)
Definition Draw.cxx:312
void fillComparisonsAtVertex(std::list< ExtendedTrack > &tracks1, std::list< ExtendedTrack > &tracks2, const std::array< std::vector< TH1 * >, 5 > &histos)
Definition Histos.cxx:112
void drawTrackResiduals(std::vector< TH1 * > &histos, TCanvas *c=nullptr)
Definition Draw.cxx:125
TCanvas * autoCanvas(const char *title, const char *name, const std::vector< TH1 * > &histos, int *nPadsx=nullptr, int *nPadsy=nullptr)
Definition Draw.cxx:109
void createHistosForClusterResiduals(std::vector< TH1 * > &histos, const char *extension, double range)
Definition Histos.cxx:23
void outputToPdfClearDivide(const std::string fileName, TCanvas &c, int nPadsx, int nPadsy)
void drawClusterTrackResiduals(const std::vector< TH1 * > &histos1, const std::vector< TH1 * > &histos2, const char *extension, TCanvas *c=nullptr)
Definition Draw.cxx:179
void drawComparisonsAtVertex(const std::array< std::vector< TH1 * >, 5 > histos, TCanvas *c=nullptr)
Definition Draw.cxx:385
std::unique_ptr< GPUReconstructionTimeframe > tf
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters