8 Form(
"run_%d/RAW/DataR_run_%d%s.BIN", s.
run, s.
run, s.
suffix.Data());
16 Int_t cPos = s.
suffix.Index(
"_c");
18 TString chunkIdx = s.
suffix(cPos + 2, s.
suffix.Length() - cPos - 2);
21 TString seqStr = s.
suffix(1, cPos - 1);
25 Form(
"music_exp1915_%03d_00_66222_%03d_chunk%s.sol", s.
run, seq,
35 Form(
"music_exp1915_%03d_00_66222_%03d.sol", s.
run, seq);
39std::vector<TString> DiscoverSuffixesIn(
const TString &dir,
40 const TString &prefix,
42 std::vector<TString> suffixes;
43 void *dirp = gSystem->OpenDirectory(dir);
45 std::cerr <<
"DiscoverSuffixesIn: cannot open " << dir << std::endl;
49 while ((name = gSystem->GetDirEntry(dirp))) {
51 if (!fname.BeginsWith(prefix))
53 if (!fname.EndsWith(ext))
56 fname(prefix.Length(), fname.Length() - prefix.Length() - ext.Length());
58 suffixes.push_back(
"");
61 if (rest.Length() < 2 || rest[0] !=
'_')
63 TString num = rest(1, rest.Length() - 1);
66 suffixes.push_back(rest);
68 gSystem->FreeDirectory(dirp);
69 std::sort(suffixes.begin(), suffixes.end(),
70 [](
const TString &a,
const TString &b) {
75 return TString(a(1, a.Length() - 1)).Atoi() <
76 TString(b(1, b.Length() - 1)).Atoi();
81std::vector<FileSpec> BuildSpecsImpl(Bool_t processed) {
82 std::vector<FileSpec> specs;
84 for (Int_t r = 0; r < Int_t(runs.size()); r++) {
86 std::vector<TString> suffixes;
94 Int_t limit = suffixes.size();
98 if (epoch_cap > 0 && epoch_cap < limit)
100 for (Int_t k = 0; k < limit; k++) {
113 Form(
"run_%d/RAW/", run),
114 Form(
"DataR_run_%d", run),
".BIN");
118 std::vector<TString> suffixes;
119 TString prefix = Form(
"music_exp1915_%03d_00_66222_", run);
123 void *dirp = gSystem->OpenDirectory(split_dir);
126 while ((name = gSystem->GetDirEntry(dirp))) {
128 if (!fname.BeginsWith(prefix))
130 if (!fname.EndsWith(
".sol"))
132 if (!fname.Contains(
"_chunk"))
135 Int_t chunkPos = fname.Index(
"_chunk");
139 TString seqStr = fname(prefix.Length(), chunkPos - prefix.Length());
140 if (!seqStr.IsDigit())
142 Int_t seq = seqStr.Atoi();
144 TString chunkStr = fname(chunkPos + 6, fname.Length() - chunkPos - 6 - 4);
145 if (!chunkStr.IsDigit())
149 suffixes.push_back(Form(
"_c%s", chunkStr.Data()));
151 suffixes.push_back(Form(
"_%d_c%s", seq, chunkStr.Data()));
154 gSystem->FreeDirectory(dirp);
156 if (!suffixes.empty()) {
157 std::sort(suffixes.begin(), suffixes.end(),
158 [](
const TString &a,
const TString &b) { return a < b; });
165 dirp = gSystem->OpenDirectory(sol_dir);
167 std::cerr <<
"DiscoverSolRunSuffixes: cannot open " << sol_dir << std::endl;
172 while ((name = gSystem->GetDirEntry(dirp))) {
174 if (!fname.BeginsWith(prefix))
176 if (!fname.EndsWith(
".sol"))
179 TString rest = fname(prefix.Length(), fname.Length() - prefix.Length() - 4);
183 Int_t seq = rest.Atoi();
185 suffixes.push_back(
"");
187 suffixes.push_back(Form(
"_%d", seq));
190 gSystem->FreeDirectory(dirp);
193 std::sort(suffixes.begin(), suffixes.end(),
194 [](
const TString &a,
const TString &b) {
199 return a.Atoi() < b.Atoi();
206 std::vector<TString> suffixes;
207 TString dir = IO::GetRootFilesBaseDir();
208 TString prefix = Form(
"Events_Run%d", run);
209 void *dirp = gSystem->OpenDirectory(dir);
213 while ((name = gSystem->GetDirEntry(dirp))) {
215 if (!fname.BeginsWith(prefix))
217 if (!fname.EndsWith(
".root"))
219 TString rest = fname(prefix.Length(), fname.Length() - prefix.Length() - 5);
220 suffixes.push_back(rest);
222 gSystem->FreeDirectory(dirp);
223 std::sort(suffixes.begin(), suffixes.end(),
224 [](
const TString &a,
const TString &b) {
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(
'_');
236 numA = numA(0, dash);
240 if (b.Length() > 1 && b[0] ==
'_') {
241 TString numB = b(1, b.Length() - 1);
242 Int_t dash = numB.Index(
'_');
244 numB = numB(0, dash);
256 return BuildSpecsImpl(kFALSE);
260 return BuildSpecsImpl(kTRUE);
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) {
276 specs.push_back(processed[k]);
282 return Form(
"DataR_run_%d%s.root", s.
run, s.
suffix.Data());
286 return Form(
"DataR_run_%d%s.shift.root", s.
run, s.
suffix.Data());
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());
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());
303std::map<Int_t, TChain *>
305 std::map<Int_t, TChain *> chain_by_run;
307 for (Int_t i = 0; i < Int_t(all_specs.size()); i++) {
309 TString full = IO::GetRootFilesBaseDir() +
"/" +
EventsName(s) +
".root";
310 if (gSystem->AccessPathName(full)) {
311 std::cerr <<
"Missing events file: " << full << std::endl;
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);
318 chain_by_run[s.
run]->Add(full);
325 (max_points > 0 && n_total > max_points) ? max_points : n_total;
326 Long64_t stride = (n_visit > 0) ? (n_total / n_visit) : 1;
334 for (Int_t k = 0; k < Int_t(specs.size()); k++) {
342 while (i < file_label.Length() &&
343 !(file_label[i] >=
'0' && file_label[i] <=
'9'))
346 while (j < file_label.Length() &&
347 (file_label[j] >=
'0' && file_label[j] <=
'9'))
350 s.
run = TString(file_label(i, j - i)).Atoi();
std::mutex g_plot_mutex
Serialises all plotting and canvas work.
std::mutex g_log_mutex
Serialises multi-line progress logging from worker threads.
static TString EventsName(const FileSpec &s)
Filename of the built-events ROOT file for a subfile.
static std::map< Int_t, TChain * > GroupEventsByRun(std::vector< Int_t > &run_order)
Chain every run's events files, grouped by run.
static std::vector< FileSpec > BuildFileSpecs()
Every raw input subfile for the configured runs.
static std::vector< TString > DiscoverSolRunSuffixes(Int_t run)
Subfile suffixes present on disk for a SOLARIS run.
static TString FileLabel(const FileSpec &s)
Human-readable label identifying a subfile.
static TString CompassBinPath(const FileSpec &s)
Path to a CoMPASS binary subfile.
static std::vector< FileSpec > BuildRawOrProcessedFileSpecs()
The union of raw and processed subfiles, without duplicates.
static FileSpec ResolveFileSpec(const TString &file_label)
Recover the FileSpec behind a label from FileLabel().
static TString SolBinPath(const FileSpec &s)
Path to a SOLARIS .sol subfile.
static std::vector< FileSpec > BuildProcessedFileSpecs()
Every subfile that already has processed output.
static std::vector< TString > DiscoverRunSuffixes(Int_t run)
Subfile suffixes present on disk for a CoMPASS run.
static TString RawRootName(const FileSpec &s)
Filename of the raw converted ROOT file for a subfile.
static TString ShiftFriendName(const FileSpec &s)
Filename of the timing-shift friend tree for a subfile.
static Long64_t SampleStride(Long64_t n_total, Long64_t max_points)
Stride that visits at most max_points of n_total entries.
static std::vector< TString > DiscoverProcessedRunSuffixes(Int_t run)
Subfile suffixes for which processed output already exists.
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.
TString suffix
Subfile suffix, empty for the first subfile.