MUSIC unknown
Analysis for the MUSIC active-target ionization chamber
Loading...
Searching...
No Matches
FileSet.cpp
Go to the documentation of this file.
1#include "FileSet.hpp"
2
3std::mutex g_plot_mutex;
4std::mutex g_log_mutex;
5
7 return Constants::cfg.COMPASS_BASE_DIR +
8 Form("run_%d/RAW/DataR_run_%d%s.BIN", s.run, s.run, s.suffix.Data());
9}
10
11TString FileSet::SolBinPath(const FileSpec &s) {
12 // SOLARIS naming: music_exp1915_<RUN3DIGITS>_00_66222_<SEQ3DIGITS>.sol
13 // suffix is empty for _000, or "_1" -> _001, etc.
14 // Chunk suffix "_cNNN" (seq 0) or "_<seq>_cNNN" resolves to _chunkNNN.sol
15 // in split dir.
16 Int_t cPos = s.suffix.Index("_c");
17 if (cPos >= 0) {
18 TString chunkIdx = s.suffix(cPos + 2, s.suffix.Length() - cPos - 2);
19 Int_t seq = 0;
20 if (cPos > 1) {
21 TString seqStr = s.suffix(1, cPos - 1);
22 seq = seqStr.Atoi();
23 }
24 return Constants::cfg.SOL_SPLIT_DIR +
25 Form("music_exp1915_%03d_00_66222_%03d_chunk%s.sol", s.run, seq,
26 chunkIdx.Data());
27 }
28
29 Int_t seq = 0;
30 if (s.suffix != "" && s.suffix[0] == '_') {
31 TString seq_str = s.suffix(1, s.suffix.Length() - 1);
32 seq = seq_str.Atoi();
33 }
34 return Constants::cfg.SOL_BASE_DIR +
35 Form("music_exp1915_%03d_00_66222_%03d.sol", s.run, seq);
36}
37
38namespace {
39std::vector<TString> DiscoverSuffixesIn(const TString &dir,
40 const TString &prefix,
41 const TString &ext) {
42 std::vector<TString> suffixes;
43 void *dirp = gSystem->OpenDirectory(dir);
44 if (!dirp) {
45 std::cerr << "DiscoverSuffixesIn: cannot open " << dir << std::endl;
46 return suffixes;
47 }
48 const Char_t *name;
49 while ((name = gSystem->GetDirEntry(dirp))) {
50 TString fname(name);
51 if (!fname.BeginsWith(prefix))
52 continue;
53 if (!fname.EndsWith(ext))
54 continue;
55 TString rest =
56 fname(prefix.Length(), fname.Length() - prefix.Length() - ext.Length());
57 if (rest == "") {
58 suffixes.push_back("");
59 continue;
60 }
61 if (rest.Length() < 2 || rest[0] != '_')
62 continue;
63 TString num = rest(1, rest.Length() - 1);
64 if (!num.IsDigit())
65 continue;
66 suffixes.push_back(rest);
67 }
68 gSystem->FreeDirectory(dirp);
69 std::sort(suffixes.begin(), suffixes.end(),
70 [](const TString &a, const TString &b) {
71 if (a == "")
72 return true;
73 if (b == "")
74 return false;
75 return TString(a(1, a.Length() - 1)).Atoi() <
76 TString(b(1, b.Length() - 1)).Atoi();
77 });
78 return suffixes;
79}
80
81std::vector<FileSpec> BuildSpecsImpl(Bool_t processed) {
82 std::vector<FileSpec> specs;
83 const std::vector<Int_t> &runs = Constants::ActiveRunNumbers();
84 for (Int_t r = 0; r < Int_t(runs.size()); r++) {
85 Int_t run = runs[r];
86 std::vector<TString> suffixes;
87 if (processed) {
90 suffixes = FileSet::DiscoverSolRunSuffixes(run);
91 } else {
92 suffixes = FileSet::DiscoverRunSuffixes(run);
93 }
94 Int_t limit = suffixes.size();
95 if (Constants::cfg.N_CHUNKS > 0 && Constants::cfg.N_CHUNKS < limit)
96 limit = Constants::cfg.N_CHUNKS;
97 Int_t epoch_cap = Constants::ActiveMaxFiles();
98 if (epoch_cap > 0 && epoch_cap < limit)
99 limit = epoch_cap;
100 for (Int_t k = 0; k < limit; k++) {
101 FileSpec s;
102 s.run = run;
103 s.suffix = suffixes[k];
104 specs.push_back(s);
105 }
106 }
107 return specs;
108}
109} // namespace
110
111std::vector<TString> FileSet::DiscoverRunSuffixes(Int_t run) {
112 return DiscoverSuffixesIn(Constants::cfg.COMPASS_BASE_DIR +
113 Form("run_%d/RAW/", run),
114 Form("DataR_run_%d", run), ".BIN");
115}
116
117std::vector<TString> FileSet::DiscoverSolRunSuffixes(Int_t run) {
118 std::vector<TString> suffixes;
119 TString prefix = Form("music_exp1915_%03d_00_66222_", run);
120
121 // Check for split chunks first
122 TString split_dir = Constants::cfg.SOL_SPLIT_DIR;
123 void *dirp = gSystem->OpenDirectory(split_dir);
124 if (dirp) {
125 const Char_t *name;
126 while ((name = gSystem->GetDirEntry(dirp))) {
127 TString fname(name);
128 if (!fname.BeginsWith(prefix))
129 continue;
130 if (!fname.EndsWith(".sol"))
131 continue;
132 if (!fname.Contains("_chunk"))
133 continue;
134
135 Int_t chunkPos = fname.Index("_chunk");
136 if (chunkPos < 0)
137 continue;
138
139 TString seqStr = fname(prefix.Length(), chunkPos - prefix.Length());
140 if (!seqStr.IsDigit())
141 continue;
142 Int_t seq = seqStr.Atoi();
143
144 TString chunkStr = fname(chunkPos + 6, fname.Length() - chunkPos - 6 - 4);
145 if (!chunkStr.IsDigit())
146 continue;
147
148 if (seq == 0) {
149 suffixes.push_back(Form("_c%s", chunkStr.Data()));
150 } else {
151 suffixes.push_back(Form("_%d_c%s", seq, chunkStr.Data()));
152 }
153 }
154 gSystem->FreeDirectory(dirp);
155
156 if (!suffixes.empty()) {
157 std::sort(suffixes.begin(), suffixes.end(),
158 [](const TString &a, const TString &b) { return a < b; });
159 return suffixes;
160 }
161 }
162
163 // Fall back to original files
164 TString sol_dir = Constants::cfg.SOL_BASE_DIR;
165 dirp = gSystem->OpenDirectory(sol_dir);
166 if (!dirp) {
167 std::cerr << "DiscoverSolRunSuffixes: cannot open " << sol_dir << std::endl;
168 return suffixes;
169 }
170
171 const Char_t *name;
172 while ((name = gSystem->GetDirEntry(dirp))) {
173 TString fname(name);
174 if (!fname.BeginsWith(prefix))
175 continue;
176 if (!fname.EndsWith(".sol"))
177 continue;
178
179 TString rest = fname(prefix.Length(), fname.Length() - prefix.Length() - 4);
180 if (!rest.IsDigit())
181 continue;
182
183 Int_t seq = rest.Atoi();
184 if (seq == 0) {
185 suffixes.push_back("");
186 } else {
187 suffixes.push_back(Form("_%d", seq));
188 }
189 }
190 gSystem->FreeDirectory(dirp);
191
192 // Sort by sequence number
193 std::sort(suffixes.begin(), suffixes.end(),
194 [](const TString &a, const TString &b) {
195 if (a == "")
196 return true;
197 if (b == "")
198 return false;
199 return a.Atoi() < b.Atoi();
200 });
201
202 return suffixes;
203}
204
205std::vector<TString> FileSet::DiscoverProcessedRunSuffixes(Int_t run) {
206 std::vector<TString> suffixes;
207 TString dir = IO::GetRootFilesBaseDir();
208 TString prefix = Form("Events_Run%d", run);
209 void *dirp = gSystem->OpenDirectory(dir);
210 if (!dirp)
211 return suffixes;
212 const Char_t *name;
213 while ((name = gSystem->GetDirEntry(dirp))) {
214 TString fname(name);
215 if (!fname.BeginsWith(prefix))
216 continue;
217 if (!fname.EndsWith(".root"))
218 continue;
219 TString rest = fname(prefix.Length(), fname.Length() - prefix.Length() - 5);
220 suffixes.push_back(rest);
221 }
222 gSystem->FreeDirectory(dirp);
223 std::sort(suffixes.begin(), suffixes.end(),
224 [](const TString &a, const TString &b) {
225 if (a == "")
226 return true;
227 if (b == "")
228 return false;
229 // Extract leading numeric part for sorting: _1_c000 -> 1, _c000
230 // -> 0
231 Int_t na = 0, nb = 0;
232 if (a.Length() > 1 && a[0] == '_') {
233 TString numA = a(1, a.Length() - 1);
234 Int_t dash = numA.Index('_');
235 if (dash > 0)
236 numA = numA(0, dash);
237 if (numA.IsDigit())
238 na = numA.Atoi();
239 }
240 if (b.Length() > 1 && b[0] == '_') {
241 TString numB = b(1, b.Length() - 1);
242 Int_t dash = numB.Index('_');
243 if (dash > 0)
244 numB = numB(0, dash);
245 if (numB.IsDigit())
246 nb = numB.Atoi();
247 }
248 if (na != nb)
249 return na < nb;
250 return a < b;
251 });
252 return suffixes;
253}
254
255std::vector<FileSpec> FileSet::BuildFileSpecs() {
256 return BuildSpecsImpl(kFALSE);
257}
258
259std::vector<FileSpec> FileSet::BuildProcessedFileSpecs() {
260 return BuildSpecsImpl(kTRUE);
261}
262
264 std::vector<FileSpec> specs = BuildFileSpecs();
265 std::vector<FileSpec> processed = BuildProcessedFileSpecs();
266 for (Int_t k = 0; k < Int_t(processed.size()); k++) {
267 Bool_t already = kFALSE;
268 for (Int_t j = 0; j < Int_t(specs.size()); j++) {
269 if (specs[j].run == processed[k].run &&
270 specs[j].suffix == processed[k].suffix) {
271 already = kTRUE;
272 break;
273 }
274 }
275 if (!already)
276 specs.push_back(processed[k]);
277 }
278 return specs;
279}
280
282 return Form("DataR_run_%d%s.root", s.run, s.suffix.Data());
283}
284
286 return Form("DataR_run_%d%s.shift.root", s.run, s.suffix.Data());
287}
288
289TString FileSet::EventsName(const FileSpec &s) {
290 const TString &tag = Constants::ActiveFileTag();
291 if (tag.Length() > 0)
292 return Form("Events_%s_Run%d%s", tag.Data(), s.run, s.suffix.Data());
293 return Form("Events_Run%d%s", s.run, s.suffix.Data());
294}
295
296TString FileSet::FileLabel(const FileSpec &s) {
297 const TString &tag = Constants::ActiveFileTag();
298 if (tag.Length() > 0)
299 return Form("%s_run%d%s", tag.Data(), s.run, s.suffix.Data());
300 return Form("run%d%s", s.run, s.suffix.Data());
301}
302
303std::map<Int_t, TChain *>
304FileSet::GroupEventsByRun(std::vector<Int_t> &run_order) {
305 std::map<Int_t, TChain *> chain_by_run;
306 std::vector<FileSpec> all_specs = BuildProcessedFileSpecs();
307 for (Int_t i = 0; i < Int_t(all_specs.size()); i++) {
308 const FileSpec &s = all_specs[i];
309 TString full = IO::GetRootFilesBaseDir() + "/" + EventsName(s) + ".root";
310 if (gSystem->AccessPathName(full)) {
311 std::cerr << "Missing events file: " << full << std::endl;
312 continue;
313 }
314 if (chain_by_run.find(s.run) == chain_by_run.end()) {
315 chain_by_run[s.run] = new TChain("events");
316 run_order.push_back(s.run);
317 }
318 chain_by_run[s.run]->Add(full);
319 }
320 return chain_by_run;
321}
322
323Long64_t FileSet::SampleStride(Long64_t n_total, Long64_t max_points) {
324 Long64_t n_visit =
325 (max_points > 0 && n_total > max_points) ? max_points : n_total;
326 Long64_t stride = (n_visit > 0) ? (n_total / n_visit) : 1;
327 if (stride < 1)
328 stride = 1;
329 return stride;
330}
331
332FileSpec FileSet::ResolveFileSpec(const TString &file_label) {
333 std::vector<FileSpec> specs = BuildFileSpecs();
334 for (Int_t k = 0; k < Int_t(specs.size()); k++) {
335 if (FileLabel(specs[k]) == file_label)
336 return specs[k];
337 }
338 FileSpec s;
339 s.run = -1;
340 s.suffix = "";
341 Int_t i = 0;
342 while (i < file_label.Length() &&
343 !(file_label[i] >= '0' && file_label[i] <= '9'))
344 i++;
345 Int_t j = i;
346 while (j < file_label.Length() &&
347 (file_label[j] >= '0' && file_label[j] <= '9'))
348 j++;
349 if (j > i)
350 s.run = TString(file_label(i, j - i)).Atoi();
351 return s;
352}
std::mutex g_plot_mutex
Serialises all plotting and canvas work.
Definition FileSet.cpp:3
std::mutex g_log_mutex
Serialises multi-line progress logging from worker threads.
Definition FileSet.cpp:4
static TString EventsName(const FileSpec &s)
Filename of the built-events ROOT file for a subfile.
Definition FileSet.cpp:289
static std::map< Int_t, TChain * > GroupEventsByRun(std::vector< Int_t > &run_order)
Chain every run's events files, grouped by run.
Definition FileSet.cpp:304
static std::vector< FileSpec > BuildFileSpecs()
Every raw input subfile for the configured runs.
Definition FileSet.cpp:255
static std::vector< TString > DiscoverSolRunSuffixes(Int_t run)
Subfile suffixes present on disk for a SOLARIS run.
Definition FileSet.cpp:117
static TString FileLabel(const FileSpec &s)
Human-readable label identifying a subfile.
Definition FileSet.cpp:296
static TString CompassBinPath(const FileSpec &s)
Path to a CoMPASS binary subfile.
Definition FileSet.cpp:6
static std::vector< FileSpec > BuildRawOrProcessedFileSpecs()
The union of raw and processed subfiles, without duplicates.
Definition FileSet.cpp:263
static FileSpec ResolveFileSpec(const TString &file_label)
Recover the FileSpec behind a label from FileLabel().
Definition FileSet.cpp:332
static TString SolBinPath(const FileSpec &s)
Path to a SOLARIS .sol subfile.
Definition FileSet.cpp:11
static std::vector< FileSpec > BuildProcessedFileSpecs()
Every subfile that already has processed output.
Definition FileSet.cpp:259
static std::vector< TString > DiscoverRunSuffixes(Int_t run)
Subfile suffixes present on disk for a CoMPASS run.
Definition FileSet.cpp:111
static TString RawRootName(const FileSpec &s)
Filename of the raw converted ROOT file for a subfile.
Definition FileSet.cpp:281
static TString ShiftFriendName(const FileSpec &s)
Filename of the timing-shift friend tree for a subfile.
Definition FileSet.cpp:285
static Long64_t SampleStride(Long64_t n_total, Long64_t max_points)
Stride that visits at most max_points of n_total entries.
Definition FileSet.cpp:323
static std::vector< TString > DiscoverProcessedRunSuffixes(Int_t run)
Subfile suffixes for which processed output already exists.
Definition FileSet.cpp:205
Int_t ActiveMaxFiles()
Cap on subfiles processed per run for the active epoch.
const std::vector< Int_t > & ActiveRunNumbers()
Runs of the active epoch, or the flat RUN_NUMBERS when none is set.
const TString & ActiveFileTag()
Output-name prefix of the active epoch.
const DatasetConfig & cfg
The active dataset's configuration, flat block.
Bool_t ActiveUseSolarisData()
Whether this era's data is SOLARIS rather than CoMPASS.
One input file: a run number and the subfile suffix within it.
Definition FileSet.hpp:40
TString suffix
Subfile suffix, empty for the first subfile.
Definition FileSet.hpp:42
Int_t run
Run number.
Definition FileSet.hpp:41