ATLAS Offline Software
Loading...
Searching...
No Matches
ToolsDiscovery.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7//
8// includes
9//
10
12
24#include <TChain.h>
25#include <TChainElement.h>
26#include <TFile.h>
27#include <TTree.h>
28#include <fstream>
29#include <memory>
30#include <stdexcept>
31
32//
33// method implementations
34//
35
36namespace SH
37{
39 const std::string& pattern,
40 const std::string& samplePattern,
41 const std::string& samplePostfix)
42 {
43 ScanDir()
44 .sampleDepth (0)
45 .minDepth (1)
46 .maxDepth (1)
47 .filePattern (pattern)
48 .samplePattern (samplePattern)
49 .samplePostfix (samplePostfix)
50 .scan (sh, list);
51 }
52
53
54
55 void scanDir (SampleHandler& sh, const std::string& dir)
56 {
57 ScanDir()
58 .sampleDepth (0)
59 .minDepth (1)
60 .maxDepth (1)
61 .scan (sh, dir);
62 }
63
64
65
66 void scanDir (SampleHandler& sh, const std::string& dir,
67 const std::string& prefix)
68 {
69 DiskListLocal list (dir, prefix);
70 ScanDir()
71 .sampleDepth (0)
72 .minDepth (1)
73 .maxDepth (1)
74 .scan (sh, list);
75 }
76
77
78
80 const std::string& pattern)
81 {
82 ScanDir()
83 .sampleDepth (-1)
84 .filePattern (pattern)
85 .samplePostfix (".*")
86 .scan (sh, list);
87 }
88
89
90
91 Sample *makeFromTChain (const std::string& name, const TChain& chain)
92 {
93 std::unique_ptr<SampleLocal> result (new SampleLocal (name));
94 result->meta()->setString (MetaFields::treeName, chain.GetName());
95
96 TIter chainIter (chain.GetListOfFiles());
97 TChainElement *chainElement = 0;
98 while ((chainElement = dynamic_cast<TChainElement*>(chainIter.Next())) != 0)
99 result->add (chainElement->GetTitle());
100 return result.release();
101 }
102
103
104
105 void scanSingleDir (SampleHandler& sh, const std::string& name,
106 DiskList& list, const std::string& pattern)
107 {
108 ScanDir()
109 .sampleDepth (0)
110 .filePattern (pattern)
111 .sampleRename ("*", name)
112 .scan (sh, list);
113 }
114
115
116
117 void scanDQ2 (SampleHandler& sh, const std::string& pattern)
118 {
119 if (pattern.find ("*") == std::string::npos)
120 {
121 addGrid (sh, pattern);
122 } else
123 {
124 std::set<std::string> types = {"DATASET", "DIDType.DATASET"};
125 if (pattern.back() == '/')
126 types = {"CONTAINER", "DIDType.CONTAINER"};
127
128 auto subresult = rucioListDids (pattern);
129 for (auto& ds : subresult)
130 {
131 if (types.find (ds.type) != types.end())
132 addGrid (sh, ds.scope + ":" + ds.name);
133 }
134 }
135 }
136
137
138
139 void scanRucio (SampleHandler& sh, const std::string& pattern,
140 bool alwaysQuery)
141 {
142 if (pattern.find ("*") == std::string::npos && !alwaysQuery)
143 {
144 addGrid (sh, pattern);
145 } else
146 {
147 auto subresult = rucioListDids (pattern);
148 bool added = false;
149 for (std::string type : {"CONTAINER", "DIDType.CONTAINER", "DATASET", "DIDType.DATASET"})
150 {
151 for (auto& ds : subresult)
152 {
153 if (ds.type == type)
154 {
155 addGrid (sh, ds.scope + ":" + ds.name);
156 added = true;
157 }
158 }
159 if (added)
160 return;
161 }
162 throw std::runtime_error ("failed to find any datasets matching pattern: " + pattern);
163 }
164 }
165
166
167
168 void addGrid (SampleHandler& sh, const std::string& ds)
169 {
170 RCU_ASSERT_SOFT (ds.find ("*") == std::string::npos);
171
172 std::string name;
173 if (ds[ds.size()-1] == '/')
174 name = ds.substr (0, ds.size()-1);
175 else
176 name = ds;
177
178 auto sample = std::make_unique<SampleGrid> (name);
179 sample->meta()->setString (MetaFields::gridName, ds);
180 sample->meta()->setString (MetaFields::gridFilter, MetaFields::gridFilter_default);
181 sh.add (std::move (sample));
182 }
183
184
185
186 void addGridCombined (SampleHandler& sh, const std::string& dsName,
187 const std::vector<std::string>& dsList)
188 {
189 std::string name;
190 for (const std::string &ds : dsList)
191 {
192 RCU_ASSERT_SOFT (ds.find ("*") == std::string::npos);
193
194 if (!name.empty())
195 name.append(",");
196
197 if (ds.at(ds.size() - 1) == '/')
198 name.append(ds.substr (0, ds.size() - 1));
199 else
200 name.append(ds);
201 }
202
203 auto sample = std::make_unique<SampleGrid> (dsName);
204 sample->meta()->setString (MetaFields::gridName, name);
205 sample->meta()->setString (MetaFields::gridFilter, MetaFields::gridFilter_default);
206 sh.add (std::move (sample));
207 }
208 void addGridCombinedFromFile (SampleHandler& sh, const std::string& dsName,
209 const std::string& dsFile)
210 {
211 std::ifstream file (dsFile.c_str());
212
213 std::string name;
214 std::string ds;
215 const std::set<char> whitespaces{'\t',' ','\n','\r'};
216 while (std::getline (file, ds))
217 {
218 while ((!ds.empty()) && whitespaces.count(ds.back())) ds.pop_back();
219 if (ds.empty() || ds.at(0) == '#')
220 continue;
221
222 RCU_ASSERT_SOFT (ds.find ("*") == std::string::npos);
223
224 if (!name.empty())
225 name.append(",");
226
227 if (ds.at(ds.size() - 1) == '/')
228 name.append(ds.substr (0, ds.size() - 1));
229 else
230 name.append(ds);
231 }
232 if (!file.eof())
233 throw std::runtime_error ("failed to read file: " + dsFile);
234
235 auto sample = std::make_unique<SampleGrid> (dsName);
236 sample->meta()->setString (MetaFields::gridName, name);
237 sample->meta()->setString (MetaFields::gridFilter, MetaFields::gridFilter_default);
238 sh.add (std::move (sample));
239 }
240
241
242 void makeGridDirect (SampleHandler& sh, const std::string& disk,
243 const std::string& from, const std::string& to,
244 bool allow_partial)
245 {
246 using namespace msgDiscovery;
247
248 SampleHandler mysh;
249
250 for (auto sample : sh.samples())
251 {
252 SampleGrid *grid = dynamic_cast<SampleGrid*>(sample.get());
253
254 if (grid == 0)
255 {
256 mysh.add (sample);
257 } else
258 {
259 const std::string ds = grid->meta()->castString (MetaFields::gridName);
260 if (ds.empty())
261 throw std::runtime_error ("no dataset configured for grid dataset " + ds);
262
264
265 std::set<std::string> knownFiles;
266 std::map<std::string,std::string> usedFiles;
267 for (auto& entry : rucioListFileReplicas (ds))
268 {
269 if (RCU::match_expr (pattern, entry.name))
270 {
271 knownFiles.insert (entry.name);
272 if (entry.disk == disk)
273 {
274 std::string url = entry.replica;
275 const auto split = url.find (from);
276 if (split != std::string::npos)
277 url.replace(split, from.size(), to);
278 usedFiles[entry.name] = url;
279 }
280 }
281 }
282
283 if (usedFiles.empty())
284 {
285 if (allow_partial)
286 ANA_MSG_WARNING ("dataset " << ds << " not at " << disk << ", skipped");
287 } else if (knownFiles.size() != usedFiles.size())
288 {
289 if (allow_partial)
290 {
291 ANA_MSG_WARNING ("only incomplete version of dataset " << ds << " at " << disk);
292 } else
293 {
294 usedFiles.clear ();
295 }
296 }
297
298 if (usedFiles.size() == 0)
299 {
300 sh.add (sample);
301 } else
302 {
303 auto mysample = std::make_unique<SampleLocal> (grid->name());
304 *mysample->meta() = *grid->meta();
305
306 for (const auto& file : usedFiles)
307 {
308 mysample->add (file.second);
309 }
310 mysh.add (std::move (mysample));
311 }
312 }
313 }
314 swap (sh, mysh);
315 }
316
317
318
319 void scanForTrees (SampleHandler& sh, std::shared_ptr<Sample>& sample,
320 const std::string& pattern)
321 {
322 auto mysample = sample->makeLocal();
323 if (mysample->numFiles() == 0)
324 {
325 sh.add (sample);
326 return;
327 }
328 std::unique_ptr<TFile> file (TFile::Open (mysample->fileName(0).c_str()));
329 if (!file.get())
330 throw std::runtime_error ("could not open file: " + mysample->fileName(0));
331 TObject *object = 0;
332 std::regex mypattern (pattern);
333 for (TIter iter (file->GetListOfKeys()); (object = iter.Next()); )
334 {
335 if (RCU::match_expr (mypattern, object->GetName()) &&
336 dynamic_cast<TTree*>(file->Get(object->GetName())))
337 {
338 std::string newName = sample->name() + "_" + object->GetName();
339 std::unique_ptr<Sample> newSample
340 (dynamic_cast<Sample*>(sample->Clone (newName.c_str())));
341 newSample->name (newName);
342 newSample->meta()->setString (MetaFields::treeName, object->GetName());
343 sh.add (std::move (newSample));
344 }
345 }
346 }
347
348
349
350 void scanForTrees (SampleHandler& sh, const std::string& pattern)
351 {
352 SH::SampleHandler sh_new;
353
354 for (auto sample : sh.samples())
355 {
356 scanForTrees (sh_new, sample, pattern);
357 }
358 swap (sh, sh_new);
359 }
360
361
362
363 void readFileList (SampleHandler& sh, const std::string& name,
364 const std::string& file)
365 {
366 std::ifstream myfile (file.c_str());
367
368 auto sample = std::make_unique<SampleLocal> (name);
369 std::string line;
370 const std::set<char> whitespaces{'\t',' ','\n','\r'};
371 while (std::getline (myfile, line))
372 {
373 while ((!line.empty()) && whitespaces.count(line.back())) line.pop_back();
374 if (!line.empty() && line.at(0) != '#')
375 {
376 sample->add (line);
377 }
378 }
379 if (!myfile.eof())
380 throw std::runtime_error ("failed to read file: " + file);
381 sh.add (std::move (sample));
382 }
383}
#define RCU_ASSERT_SOFT(x)
Definition Assert.h:155
#define ANA_MSG_WARNING(xmsg)
Macro printing warning messages.
static const std::vector< std::string > types
a DiskList implementation for local directories
an interface for listing directory contents, locally or on a file server
Definition DiskList.h:24
void swap(MetaObject &a, MetaObject &b)
standard swap
std::string castString(const std::string &name, const std::string &def_val="", CastMode mode=CAST_ERROR_THROW) const
the meta-data string with the given name
This class implements a Sample located on the grid.
Definition SampleGrid.h:36
A class that manages a list of Sample objects.
void add(const Sample &sample)
add a copy of the sample to the handler
A Sample based on a simple file list.
Definition SampleLocal.h:30
a base class that manages a set of files belonging to a particular data set and the associated meta-d...
Definition Sample.h:49
MetaObject * meta()
the meta-information for this sample
const std::string & name() const
the name of the sample we are using
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179
bool match_expr(const std::regex &expr, std::string_view str)
returns: whether we can match the entire string with the regular expression guarantee: strong failure...
std::string glob_to_regexp(std::string_view glob)
returns: a string that is the regular expression equivalent of the given glob expression guarantee: s...
This module provides a lot of global definitions, forward declarations and includes that are used by ...
Definition PrunDriver.h:15
void scanSingleDir(SampleHandler &sh, const std::string &name, DiskList &list, const std::string &pattern)
effects: scan the given directory tree and turn it into a single sample of the given name guarantee: ...
void addGrid(SampleHandler &sh, const std::string &ds)
effects: add a grid dataset for dataset ds guarantee: strong failures: out of memory II requires: ds....
void scanForTrees(SampleHandler &sh, std::shared_ptr< Sample > &sample, const std::string &pattern)
effects: scan for trees in the given sample (or sample handler), and create a separate sample for eac...
void scanDQ2(SampleHandler &sh, const std::string &pattern)
effects: make a list from DQ2 using the given pattern guarantee: basic, may add partially failures: o...
void readFileList(SampleHandler &sh, const std::string &name, const std::string &file)
effects: read a file list from a text file guarantee: strong failures: out of memory III failures: i/...
Sample * makeFromTChain(const std::string &name, const TChain &chain)
effects: create a sample with the given name from the given TChain object guarantee: strong failures:...
void scanFiles(SampleHandler &sh, DiskList &list, const std::string &pattern)
effects: scan the given directory tree and make a separate sample for each file (using the file name ...
std::vector< RucioListFileReplicasEntry > rucioListFileReplicas(const std::string &dataset)
run rucio-list-file-replicas for the given dataset
std::vector< RucioListDidsEntry > rucioListDids(const std::string &dataset)
run rucio-list-dids for the given dataset
void makeGridDirect(SampleHandler &sh, const std::string &disk, const std::string &from, const std::string &to, bool allow_partial)
effects: update all grid samples in the sample handler that are located on the given disk to be opene...
void scanDir(SampleHandler &sh, DiskList &list, const std::string &pattern, const std::string &samplePattern, const std::string &samplePostfix)
effects: scan the given directory and add all subdirectories as samples that contain root files.
void scanRucio(SampleHandler &sh, const std::string &pattern, bool alwaysQuery)
make a list of grid datasets using the given pattern
void addGridCombined(SampleHandler &sh, const std::string &dsName, const std::vector< std::string > &dsList)
effects: add a combined grid dataset with name dsName for dataset list dsList guarantee: strong failu...
void addGridCombinedFromFile(SampleHandler &sh, const std::string &dsName, const std::string &dsFile)
effects: add a combined grid dataset with name dsName for dataset list file dsFile guarantee: strong ...
static const std::string gridFilter
the field containing the file filter for the dataset on the grid
Definition MetaFields.h:30
static const std::string gridName
the field containing the name of the dataset on the grid
Definition MetaFields.h:26
static const std::string treeName
the name of the tree in the sample
Definition MetaFields.h:44
static const std::string gridFilter_default
the default value for gridFilter
Definition MetaFields.h:33
the class used for scanning local directories and file servers for samples
Definition ScanDir.h:39
ScanDir & samplePattern(const std::string &val_samplePattern)
the pattern for samples to be accepted
Definition ScanDir.cxx:130
const ScanDir & scan(SampleHandler &sh, const std::string &dir) const
scan the given directory and put the created samples into the sample handler
Definition ScanDir.cxx:168
ScanDir & sampleDepth(int val_sampleDepth)
the index of the file hierarchy at which we gather the sample name.
Definition ScanDir.cxx:47
ScanDir & maxDepth(std::size_t val_maxDepth)
the maximum depth for files to make it into the sample
Definition ScanDir.cxx:85
ScanDir & samplePostfix(const std::string &val_samplePostfix)
the pattern for the postfix to be stripped from the sampleName
Definition ScanDir.cxx:139
ScanDir & minDepth(std::size_t val_minDepth)
the minimum depth for files to make it into the sample
Definition ScanDir.cxx:76
ScanDir & sampleRename(const std::string &pattern, const std::string &name)
rename any sample matching pattern to name
Definition ScanDir.cxx:149
ScanDir & filePattern(const std::string &val_filePattern)
the pattern for files to be accepted
Definition ScanDir.cxx:94
TFile * file