8 Form(
"run_%d/RAW/DataR_run_%d%s.BIN", s.
run, s.
run, s.
suffix.Data());
14 Int_t cPos = s.
suffix.Index(
"_c");
16 TString chunkIdx = s.
suffix(cPos + 2, s.
suffix.Length() - cPos - 2);
19 TString seqStr = s.
suffix(1, cPos - 1);
23 Form(
"music_exp1915_%03d_00_66222_%03d_chunk%s.sol", s.
run, seq,
33 Form(
"music_exp1915_%03d_00_66222_%03d.sol", s.
run, seq);
37std::vector<TString> DiscoverSuffixesIn(
const TString &dir,
38 const TString &prefix,
40 std::vector<TString> suffixes;
41 void *dirp = gSystem->OpenDirectory(dir);
43 std::cerr <<
"DiscoverSuffixesIn: cannot open " << dir << std::endl;
47 while ((name = gSystem->GetDirEntry(dirp))) {
49 if (!fname.BeginsWith(prefix))
51 if (!fname.EndsWith(ext))
54 fname(prefix.Length(), fname.Length() - prefix.Length() - ext.Length());
56 suffixes.push_back(
"");
59 if (rest.Length() < 2 || rest[0] !=
'_')
61 TString num = rest(1, rest.Length() - 1);
64 suffixes.push_back(rest);
66 gSystem->FreeDirectory(dirp);
67 std::sort(suffixes.begin(), suffixes.end(),
68 [](
const TString &a,
const TString &b) {
73 return TString(a(1, a.Length() - 1)).Atoi() <
74 TString(b(1, b.Length() - 1)).Atoi();
79std::vector<FileSpec> BuildSpecsImpl(Bool_t processed) {
80 std::vector<FileSpec> specs;
82 for (Int_t r = 0; r < Int_t(runs.size()); r++) {
84 std::vector<TString> suffixes;
92 Int_t limit = suffixes.size();
96 if (epoch_cap > 0 && epoch_cap < limit)
98 for (Int_t k = 0; k < limit; k++) {
110Bool_t SuffixLess(
const TString &a,
const TString &b) {
115 Int_t na = 0, nb = 0;
116 if (a.Length() > 1 && a[0] ==
'_') {
117 TString numA = a(1, a.Length() - 1);
118 Int_t dash = numA.Index(
'_');
120 numA = numA(0, dash);
124 if (b.Length() > 1 && b[0] ==
'_') {
125 TString numB = b(1, b.Length() - 1);
126 Int_t dash = numB.Index(
'_');
128 numB = numB(0, dash);
140 Form(
"run_%d/RAW/", run),
141 Form(
"DataR_run_%d", run),
".BIN");
145 std::vector<TString> suffixes;
146 TString prefix = Form(
"music_exp1915_%03d_00_66222_", run);
152 ? gSystem->OpenDirectory(split_dir)
156 while ((name = gSystem->GetDirEntry(dirp))) {
158 if (!fname.BeginsWith(prefix))
160 if (!fname.EndsWith(
".sol"))
162 if (!fname.Contains(
"_chunk"))
165 Int_t chunkPos = fname.Index(
"_chunk");
169 TString seqStr = fname(prefix.Length(), chunkPos - prefix.Length());
170 if (!seqStr.IsDigit())
172 Int_t seq = seqStr.Atoi();
174 TString chunkStr = fname(chunkPos + 6, fname.Length() - chunkPos - 6 - 4);
175 if (!chunkStr.IsDigit())
179 suffixes.push_back(Form(
"_c%s", chunkStr.Data()));
181 suffixes.push_back(Form(
"_%d_c%s", seq, chunkStr.Data()));
184 gSystem->FreeDirectory(dirp);
186 if (!suffixes.empty()) {
187 std::sort(suffixes.begin(), suffixes.end(),
188 [](
const TString &a,
const TString &b) { return a < b; });
195 dirp = gSystem->OpenDirectory(sol_dir);
197 std::cerr <<
"DiscoverSolRunSuffixes: cannot open " << sol_dir << std::endl;
202 while ((name = gSystem->GetDirEntry(dirp))) {
204 if (!fname.BeginsWith(prefix))
206 if (!fname.EndsWith(
".sol"))
209 TString rest = fname(prefix.Length(), fname.Length() - prefix.Length() - 4);
213 Int_t seq = rest.Atoi();
215 suffixes.push_back(
"");
217 suffixes.push_back(Form(
"_%d", seq));
220 gSystem->FreeDirectory(dirp);
223 std::sort(suffixes.begin(), suffixes.end(),
224 [](
const TString &a,
const TString &b) {
229 return a.Atoi() < b.Atoi();
236 std::vector<TString> suffixes;
237 TString dir = IO::GetRootFilesBaseDir();
244 void *dirp = gSystem->OpenDirectory(dir);
248 while ((name = gSystem->GetDirEntry(dirp))) {
250 if (!fname.BeginsWith(prefix))
252 if (!fname.EndsWith(
".root"))
254 TString rest = fname(prefix.Length(), fname.Length() - prefix.Length() - 5);
257 if (rest.Length() > 0 && rest[0] !=
'_')
259 suffixes.push_back(rest);
261 gSystem->FreeDirectory(dirp);
262 std::sort(suffixes.begin(), suffixes.end(), SuffixLess);
267 return BuildSpecsImpl(kFALSE);
271 return BuildSpecsImpl(kTRUE);
277 for (Int_t k = 0; k < Int_t(processed.size()); k++) {
278 Bool_t already = kFALSE;
279 for (Int_t j = 0; j < Int_t(specs.size()); j++) {
280 if (specs[j].run == processed[k].run &&
281 specs[j].suffix == processed[k].suffix) {
287 specs.push_back(processed[k]);
294 if (tag.Length() > 0)
295 return Form(
"Events_%s_Run%d%s", tag.Data(), s.
run, s.
suffix.Data());
296 return Form(
"Events_Run%d%s", s.
run, s.
suffix.Data());
301 if (tag.Length() > 0)
302 return Form(
"%s_run%d%s", tag.Data(), s.
run, s.
suffix.Data());
303 return Form(
"run%d%s", s.
run, s.
suffix.Data());
311 for (Int_t i = 0; i < Int_t(all_specs.size()); i++) {
314 TString full = IO::GetRootFilesBaseDir() +
"/" + name +
".root";
315 if (gSystem->AccessPathName(full)) {
316 std::cerr <<
"Missing events file: " << full << std::endl;
321 const Int_t key = per_file ? next_key++ : s.
run;
323 g.
chain[key] =
new TChain(
"events");
324 g.
order.push_back(key);
327 g.
chain[key]->Add(full);
335 (max_points > 0 && n_total > max_points) ? max_points : n_total;
336 Long64_t stride = (n_visit > 0) ? (n_total / n_visit) : 1;
344 for (Int_t k = 0; k < Int_t(specs.size()); k++) {
352 while (i < file_label.Length() &&
353 !(file_label[i] >=
'0' && file_label[i] <=
'9'))
356 while (j < file_label.Length() &&
357 (file_label[j] >=
'0' && file_label[j] <=
'9'))
360 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::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 GateGroups GroupEventsForGating()
Build the gate groups; see GateGroups.
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 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.
Double_t ActiveSplitChunkSeconds()
Chunk length the active epoch's .sol files are split into, in seconds; non-positive means whole files...
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.
The events files grouped into the units the beam gates are fitted on.
std::map< Int_t, TChain * > chain
Chain per key. Caller owns..
std::map< TString, Int_t > key_of
Group key per EventsName().
std::map< Int_t, TString > label
Label per key, for logs and plots.
std::vector< Int_t > order
Group keys in processing order.
One input file: a run number and the subfile suffix within it.
TString suffix
Subfile suffix, empty for the first subfile.