BmnRoot 26.10.0-210-gc52d34b0
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
tracks3d.C
Go to the documentation of this file.
1/*
2 BM@N alignment routine
3 BM@N experiment at NICA complex, JINR, 2026
4
5 Department: Math & Soft Group of HEP lab
6 Author: Claude (Opus 5)
7 Supervisor: Igor Polev, polev@jinr.int
8
9 Track sample view: a random set of tracks drawn as 3D polylines through
10 their hits, as in the tracks pad of BmnAlignReport::Draw()
11*/
12
13// headers below are for IDE syntax to work and they will be
14// turned off during execution in ROOT macro mode
15#ifndef __CLING__
16#include "BmnAlignModels.h" // IWYU pragma: keep
17#include "BmnDataFilters.h"
18#include "BmnRootIterator.h"
20#include "TAxis3D.h"
21#include "TCanvas.h"
22#include "TMath.h"
23#include "TPolyLine3D.h"
24#include "TRandom3.h"
25#include "TView.h"
26
27#include <algorithm>
28#include <array>
29#include <vector>
30#endif
31
32#include "fairlogger/Logger.h"
33
34/**
35 * @brief Draw a uniformly random sample of tracks as 3D polylines through their hits.
36 *
37 * Tracks and hits are read through BmnRootIterator with the aligner's default
38 * filters, so the sample comes from exactly the tracks the aligner would use.
39 * Reservoir sampling makes it exact in size and uniform over all accepted
40 * tracks, at the cost of one full pass over the data. As in
41 * BmnAlignReport::Draw(), x and z are swapped: the beam runs along the
42 * horizontal axis of the view.
43 *
44 * @param fileListPath text file listing the .root files, '#' lines are ignored
45 * @param tracksToDraw size of the sample
46 * @param maxTracks sample among the first maxTracks accepted tracks only, 0 for all
47 *
48 * @return 0 on success, -1 if nothing could be read
49 */
50int tracks3d(const char* fileListPath = "/home/igor/data.cache/Run9compare/rc_aln.run_Top_9555_ev0_p0.lst",
51 Int_t tracksToDraw = 100,
52 Int_t maxTracks = 0)
53{
54 fair::Logger::SetConsoleColor(true);
55 fair::Logger::SetConsoleSeverity("info");
56
57 BmnRun9DM detectorModel;
58 // the target geometry places the vertex hit the iterator prepends to each track
59 if (!detectorModel.Init("/home/igor/bmnroot/geometry/target_Sn.geo") || tracksToDraw <= 0)
60 return -1;
61
62 BmnSimpleProgressBar progressBar;
63 BmnRootIterator iterator{
64 fileListPath, detectorModel, BmnDefaultTrackFilter(kTRUE), BmnDefaultHitFilter(detectorModel), &progressBar,
65 kFALSE, maxTracks};
66 if (!iterator.Initialized())
67 return -1;
68
69 using Point_t = std::array<Double_t, 3>; // z, y, x - the order the view shows them in
70 std::vector<std::vector<Point_t>> sample;
71 sample.reserve(tracksToDraw);
72 TRandom3 rnd{0};
73 Long64_t seen{0};
74 progressBar.Init();
75 for (iterator.ResetAll(); !iterator.EndOfTracks(); iterator.NextTrack(), seen++) {
76 // reservoir sampling: once the reservoir is full, track number k (from 0)
77 // takes a random slot with probability tracksToDraw / (k + 1)
78 const Long64_t slot{seen < tracksToDraw ? seen : rnd.Integer(static_cast<UInt_t>(seen + 1))};
79 if (slot >= tracksToDraw)
80 continue;
81
82 std::vector<Point_t> points;
83 points.reserve(iterator.HitsInTrack());
84 for (; !iterator.EndOfHits(); iterator.NextHit())
85 points.push_back({iterator.HitZ(), iterator.HitY(), iterator.HitX()});
86 std::sort(points.begin(), points.end()); // z first, so a polyline never zigzags back
87
88 if (seen < tracksToDraw)
89 sample.push_back(std::move(points));
90 else
91 sample[slot] = std::move(points);
92 }
93 progressBar.Clear();
94 LOG(info) << " " << sample.size() << " of " << seen << " accepted tracks drawn";
95 if (sample.empty())
96 return -1;
97
98 Point_t lo, hi;
99 lo.fill(TMath::Infinity());
100 hi.fill(-TMath::Infinity());
101 for (const std::vector<Point_t>& track : sample)
102 for (const Point_t& p : track)
103 for (Int_t i{0}; i < 3; i++) {
104 lo[i] = std::min(lo[i], p[i]);
105 hi[i] = std::max(hi[i], p[i]);
106 }
107
108 TCanvas* pCnv{new TCanvas( // RAM not released - acceptable in macro mode
109 "tracks3d", Form("%zu random tracks from %s", sample.size(), fileListPath), 1200, 800)};
110 pCnv->cd();
111 TView* view{TView::CreateView(1)};
112 view->SetRange(lo[0], lo[1], lo[2], hi[0], hi[1], hi[2]);
113
114 for (const std::vector<Point_t>& track : sample) {
115 TPolyLine3D* line{new TPolyLine3D()};
116 for (std::size_t i{0}; i < track.size(); i++)
117 line->SetPoint(i, track[i][0], track[i][1], track[i][2]);
118 line->SetLineColor(kBlue);
119 line->Draw();
120 }
121
123 axis->GetXaxis()->SetTitle("z, cm");
124 axis->GetYaxis()->SetTitle("y, cm");
125 axis->GetZaxis()->SetTitle("x, cm");
126 return 0;
127}
TrackFilter_t BmnDefaultTrackFilter(Bool_t wholeTrackOnly=kTRUE)
HitFilter_t BmnDefaultHitFilter(const BmnDetectorModel &model)
int i
Definition P4_F32vec4.h:22
int Int_t
unsigned int UInt_t
constexpr Bool_t kFALSE
long long Long64_t
constexpr Bool_t kTRUE
kBlue
char * Form(const char *fmt,...)
Bool_t Init(const char *targetGeoFile=nullptr)
virtual void SetLineColor(Color_t lcolor)
static TAxis3D * ToggleRulers(TVirtualPad *pad=nullptr)
virtual TAxis * GetZaxis()
virtual TAxis * GetXaxis()
virtual TAxis * GetYaxis()
TVirtualPad * cd(Int_t subpadnumber=0) override
virtual void SetTitle(const char *title="")
virtual void SetPoint(Int_t point, Double_t x, Double_t y, Double_t z)
void Draw(Option_t *option="") override
virtual UInt_t Integer(UInt_t imax)
static TView * CreateView(Int_t system=1, const Double_t *rmin=nullptr, const Double_t *rmax=nullptr)
virtual void SetRange(const Double_t *min, const Double_t *max)=0
Double_t Infinity()
int tracks3d(const char *fileListPath="/home/igor/data.cache/Run9compare/rc_aln.run_Top_9555_ev0_p0.lst", Int_t tracksToDraw=100, Int_t maxTracks=0)
Draw a uniformly random sample of tracks as 3D polylines through their hits.
Definition tracks3d.C:50