ATLAS Offline Software
Loading...
Searching...
No Matches
SH Namespace Reference

This module provides a lot of global definitions, forward declarations and includes that are used by all modules. More...

Classes

class  DiskList
 an interface for listing directory contents, locally or on a file server More...
class  DiskListEOS
 a DiskList implementation for EOS More...
class  DiskListLocal
 a DiskList implementation for local directories More...
class  DiskListSRM
 a DiskList implementation for the SRM protocol More...
class  DiskListXRD
 a DiskList implementation for the XRD protocol More...
class  DiskOutput
 a class/interface representing an output location for files More...
class  DiskOutputLocal
 an implementation of DiskOutput for local disks More...
class  DiskOutputXRD
 an implementation of DiskOutput using the XRD protocol More...
class  DiskWriter
 an interface that manages writing a single output file More...
class  DiskWriterLocal
 an implementation of DiskWriter for local files More...
class  DiskWriterXRD
 an implementation of DiskWriter for the XRD protocol More...
class  Meta
 A base class for classes that implement arbitrary meta-data. More...
 A class implementing a templatized version of the meta-data. More...
struct  MetaDataQuery
 an object containing the result of an AMI meta-data query More...
struct  MetaDataSample
 all the meta-data fields that we may try to read from AMI. More...
struct  MetaFields
 This class contains the known meta-data names. More...
struct  MetaNames
 the names of common meta-data More...
class  MetaObject
 A class that manages meta-data to be associated with an object. More...
class  MetaVector
 This class defines a templatized version of the meta-data in vector form. More...
struct  RucioDownloadResult
 the result from rucio_download More...
struct  RucioListDidsEntry
 one entry from the rucio-list-dids command More...
struct  RucioListFileReplicasEntry
 one entry from the rucio-list-file-replicas command More...
class  Sample
 a base class that manages a set of files belonging to a particular data set and the associated meta-data. More...
class  SampleComposite
 This module defines an implementation of Sample that contains composite samples. More...
class  SampleGrid
 This class implements a Sample located on the grid. More...
class  SampleHandler
 A class that manages a list of Sample objects. More...
class  SampleHist
 A sample that represents a single histogram file. More...
class  SampleLocal
 A Sample based on a simple file list. More...
class  SampleMeta
 A Sample that consists only of Meta-Information. More...
struct  ScanDir
 the class used for scanning local directories and file servers for samples More...
class  TagList
 A class that manages a list of tags for identifying samples. More...

Functions

void fetchMetaData (MetaDataQuery &query)
 effects: fetch information on all the samples/datasets specified guarantee: basic
void fetchMetaData (SampleHandler &sh, bool override)
 effects: fetch information on all the samples in the sample handler.
const std::string & downloadStageEnvVar ()
 the name of the environment variable containing the directory for staging files from the grid
bool checkVomsProxy ()
 return whether we have a valid VOMS proxy available
void ensureVomsProxy ()
 ensure that we have a valid VOMS proxy available
std::vector< std::string > faxListFilesGlob (const std::string &name, const std::string &filter)
 list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as glob expression)
std::vector< std::string > faxListFilesRegex (const std::string &name, const std::string &filter)
 list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as regular expression)
std::vector< std::string > rucioDirectAccessGlob (const std::string &name, const std::string &filter, const std::string &selectOptions)
 list the rucio URLs for all the files in the dataset or dataset container matching the given filter (as glob expression)
std::vector< std::string > rucioDirectAccessRegex (const std::string &name, const std::string &filter, const std::string &selectOptions)
 list the rucio URLs for all the files in the dataset or dataset container matching the given filter (as regular expression)
std::vector< RucioListDidsEntryrucioListDids (const std::string &dataset)
 run rucio-list-dids for the given dataset
std::vector< RucioListFileReplicasEntryrucioListFileReplicas (const std::string &dataset)
 run rucio-list-file-replicas for the given dataset
std::map< std::string, std::unique_ptr< MetaObject > > rucioGetMetadata (const std::set< std::string > &datasets)
 run rucio-get-metadata for the given list of datasets
RucioDownloadResult rucioDownload (const std::string &location, const std::string &dataset)
 run rucio-download
std::vector< RucioDownloadResultrucioDownloadList (const std::string &location, const std::vector< std::string > &datasets)
 run rucio-download with multiple datasets
std::vector< std::string > rucioCacheDatasetGlob (const std::string &location, const std::string &dataset, const std::string &fileGlob)
 download the dataset, and return a list matching the pattern
std::string dbg (const Meta &, unsigned)
std::string dbg (const TagList &obj, unsigned)
void scanDir (SampleHandler &sh, DiskList &list, const std::string &pattern="*.root*", const std::string &samplePattern="*", const std::string &samplePostfix="")
 effects: scan the given directory and add all subdirectories as samples that contain root files.
void scanDir (SampleHandler &sh, const std::string &dir)
void scanDir (SampleHandler &sh, const std::string &dir, const std::string &prefix)
void scanFiles (SampleHandler &sh, DiskList &list, const std::string &pattern="*.root*")
 effects: scan the given directory tree and make a separate sample for each file (using the file name before any "." as the sample name).
std::unique_ptr< SamplemakeFromTChainUnique (const std::string &name, const TChain &chain)
 effects: create a sample with the given name from the given TChain object guarantee: strong failures: out of memory II
SamplemakeFromTChain (const std::string &name, const TChain &chain)
 effects: create a sample with the given name from the given TChain object guarantee: strong failures: out of memory II
void scanSingleDir (SampleHandler &sh, const std::string &name, DiskList &list, const std::string &pattern="*.root*")
 effects: scan the given directory tree and turn it into a single sample of the given name guarantee: strong failures: out of memory III
void scanDQ2 (SampleHandler &sh, const std::string &pattern)
 effects: make a list from DQ2 using the given pattern guarantee: basic, may add partially failures: out of memory III failures: dq2-ls errors
void scanRucio (SampleHandler &sh, const std::string &pattern, bool alwaysQuery=false)
 make a list of grid datasets using the given pattern
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.find ("*") == std::string::npos
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 failures: out of memory II requires: for each dataset ds: ds.find ("*") == std::string::npos
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 failures: out of memory II requires: for each dataset ds: ds.find ("*") == std::string::npos
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 opened directly.
void scanForTrees (SampleHandler &sh, const 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 each tree.
void scanForTrees (SampleHandler &sh, const std::string &pattern)
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/o errors
void printDuplicateEvents (const Sample &sample)
 effects: check the given sample for duplicate events and then print them out guarantee: basic, may print partially failures: out of memory III failures: i/o errors
void printDuplicateEventsSplit (const SampleHandler &sh)
 effects: check each sample for duplicate events and then print them out guarantee: basic, may print partially failures: out of memory III failures: i/o errors
void printDuplicateEventsJoint (const SampleHandler &sh)
 effects: check for duplicate events between all the samples and then print them out guarantee: basic, may print partially failures: out of memory III failures: i/o errors
void mergeSamples (SampleHandler &sh, const std::string &sampleName, const std::string &pattern)
 effects: remove all samples matching the name pattern, and join them into a single sample named sampleName guarantee: strong failures: out of memory II failures: i/o errors
void readSusyMeta (const SampleHandler &sh, const std::string &inputFile)
 effects: read the susy-meta-data file and add its information to the samples from the given sample handler guarantee: basic failures: i/o errors warning: there are no checks for duplicate and inconsistent sample definitions
void readSusyMetaDir (const SampleHandler &sh, const std::string &inputDir)
 effects: read an entire directory of susy-meta-data files and add their information to the samples from the given sample handle.
std::unique_ptr< TFile > openFile (const std::string &name, const MetaObject &options)
 open a file with the given options
std::unique_ptr< SampleLocalmergeFiles (const Sample &sample, const std::string &location, bool overwrite)
 merge all the files in the sample into a single file in the given location
SampleHandler mergeFiles (const SampleHandler &sh, const std::string &location, bool overwrite)
 merge all the files in the sample handles into a single file per sample in the given location
void scanNEvents (SampleHandler &sh)
 effects: scan each sample in the sample handler and store the number of entries per file in the meta-data guarantee: basic, may only scan some failures: out of memory failures: read errors failures: invalid sample type
void scanNEvents (Sample &sample)
 effects: scan the given sample and store the number of entries per file in the meta-data guarantee: strong failures: out of memory failures: read errors failures: invalid sample type
SampleHandler splitSample (Sample &sample, Long64_t nevt)
 effects: split the given sample into a set of samples, with each sample containing either exactly one file or at most nevt events side effects: if scanNEvents hasn't been run on this sample, run it.
std::string dbg (const Meta &obj, unsigned verbosity=0)
 the debugging info of this object
std::string dbg (const MetaObject &obj, unsigned verbosity=0)
 the debugging info of this object
void swap (MetaObject &a, MetaObject &b)
 standard swap
std::string dbg (const Sample &obj, unsigned verbosity=0)
 the debugging info of this object
std::string dbg (const SampleHandler &obj, unsigned verbosity=0)
 the debugging info of this object
void swap (SampleHandler &a, SampleHandler &b)
 standard swap
std::string dbg (const TagList &obj, unsigned verbosity=0)
 the debugging info of this object

Detailed Description

This module provides a lot of global definitions, forward declarations and includes that are used by all modules.

This module defines utility functions used for splitting samples.

This module defines utility functions used for joining samples.

Author
Nils Krumnack

Function Documentation

◆ addGrid()

void SH::addGrid ( SampleHandler & sh,
const std::string & ds )

effects: add a grid dataset for dataset ds guarantee: strong failures: out of memory II requires: ds.find ("*") == std::string::npos

Definition at line 175 of file ToolsDiscovery.cxx.

176 {
177 RCU_ASSERT_SOFT (ds.find ("*") == std::string::npos);
178
179 std::string name;
180 if (!ds.empty() && ds.back() == '/')
181 name = ds.substr (0, ds.size()-1);
182 else
183 name = ds;
184
185 auto sample = std::make_unique<SampleGrid> (name);
186 sample->meta()->setString (MetaFields::gridName, ds);
187 sample->meta()->setString (MetaFields::gridFilter, MetaFields::gridFilter_default);
188 sh.add (std::move (sample));
189 }
#define RCU_ASSERT_SOFT(x)
Definition Assert.h:155
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 gridFilter_default
the default value for gridFilter
Definition MetaFields.h:33

◆ addGridCombined()

void SH::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 failures: out of memory II requires: for each dataset ds: ds.find ("*") == std::string::npos

Definition at line 193 of file ToolsDiscovery.cxx.

195 {
196 std::string name;
197 for (const std::string &ds : dsList)
198 {
199 RCU_ASSERT_SOFT (ds.find ("*") == std::string::npos);
200
201 if (!name.empty())
202 name.append(",");
203
204 if (ds.at(ds.size() - 1) == '/')
205 name.append(ds.substr (0, ds.size() - 1));
206 else
207 name.append(ds);
208 }
209
210 auto sample = std::make_unique<SampleGrid> (dsName);
211 sample->meta()->setString (MetaFields::gridName, name);
212 sample->meta()->setString (MetaFields::gridFilter, MetaFields::gridFilter_default);
213 sh.add (std::move (sample));
214 }

◆ addGridCombinedFromFile()

void SH::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 failures: out of memory II requires: for each dataset ds: ds.find ("*") == std::string::npos

Definition at line 215 of file ToolsDiscovery.cxx.

217 {
218 std::ifstream file (dsFile.c_str());
219
220 std::string name;
221 std::string ds;
222 const std::set<char> whitespaces{'\t',' ','\n','\r'};
223 while (std::getline (file, ds))
224 {
225 while ((!ds.empty()) && whitespaces.count(ds.back())) ds.pop_back();
226 if (ds.empty() || ds.at(0) == '#')
227 continue;
228
229 RCU_ASSERT_SOFT (ds.find ("*") == std::string::npos);
230
231 if (!name.empty())
232 name.append(",");
233
234 if (ds.at(ds.size() - 1) == '/')
235 name.append(ds.substr (0, ds.size() - 1));
236 else
237 name.append(ds);
238 }
239 if (!file.eof())
240 throw std::runtime_error ("failed to read file: " + dsFile);
241
242 auto sample = std::make_unique<SampleGrid> (dsName);
243 sample->meta()->setString (MetaFields::gridName, name);
245 sh.add (std::move (sample));
246 }
TFile * file

◆ checkVomsProxy()

bool SH::checkVomsProxy ( )

return whether we have a valid VOMS proxy available

Guarantee
basic
Failures
grid utility failures

Definition at line 221 of file GridTools.cxx.

222 {
223 return proxyData().checkVomsProxy();
224 }

◆ dbg() [1/7]

std::string SH::dbg ( const Meta & ,
unsigned  )
related

Definition at line 21 of file Meta.cxx.

22 {
23 return "meta-object";
24 }

◆ dbg() [2/7]

std::string SH::dbg ( const TagList & obj,
unsigned  )
related

Definition at line 23 of file TagList.cxx.

24 {
25 std::string result;
26
27 for (const auto& tag : obj)
28 {
29 if (!result.empty())
30 result += ",";
31 result += tag;
32 }
33 return "(" + result + ")";
34 }

◆ downloadStageEnvVar()

const std::string & SH::downloadStageEnvVar ( )

the name of the environment variable containing the directory for staging files from the grid

Definition at line 213 of file GridTools.cxx.

214 {
215 static const std::string result = "SAMPLEHANDLER_RUCIO_DOWNLOAD";
216 return result;
217 }

◆ ensureVomsProxy()

void SH::ensureVomsProxy ( )

ensure that we have a valid VOMS proxy available

First this checks whether we have a valid PROXY, and if not it sets up a new certificate.

Guarantee
basic
Failures
grid utility failures
failure to set up new VOMS proxy

Definition at line 228 of file GridTools.cxx.

229 {
230 proxyData().ensureVomsProxy();
231 }

◆ faxListFilesGlob()

std::vector< std::string > SH::faxListFilesGlob ( const std::string & name,
const std::string & filter )

list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as glob expression)

Guarantee
strong
Failures
grid utility failures
Precondition
!name.empty()
name.find('*') == std::string::npos
!filter.empty()

Definition at line 236 of file GridTools.cxx.

237 {
238#pragma GCC diagnostic push
239#pragma GCC diagnostic ignored "-Wpragmas"
240#pragma GCC diagnostic ignored "-Wunknown-pragmas"
241#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
242 return faxListFilesRegex (name, RCU::glob_to_regexp (filter));
243#pragma GCC diagnostic pop
244 }
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...
std::vector< std::string > faxListFilesRegex(const std::string &name, const std::string &filter)
list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as...

◆ faxListFilesRegex()

std::vector< std::string > SH::faxListFilesRegex ( const std::string & name,
const std::string & filter )

list the FAX URLs for all the files in the dataset or dataset container matching the given filter (as regular expression)

Guarantee
strong
Failures
grid utility failures
Precondition
!name.empty()
name.find('*') == std::string::npos
!filter.empty()

Definition at line 249 of file GridTools.cxx.

250 {
251 RCU_REQUIRE_SOFT (!name.empty());
252 RCU_REQUIRE_SOFT (name.find('*') == std::string::npos);
253 RCU_REQUIRE_SOFT (!filter.empty());
254
256
257 static const std::string separator = "------- SampleHandler Split -------";
258 std::vector<std::string> result;
259
260 ANA_MSG_INFO ("querying FAX for dataset " << name);
261 std::string output = sh::exec_read ("source $ATLAS_LOCAL_ROOT_BASE/user/atlasLocalSetup.sh -q && lsetup --force fax && echo " + separator + " && fax-get-gLFNs " + sh::quote (name));
262 auto split = output.rfind (separator + "\n");
263 if (split == std::string::npos)
264 throw std::runtime_error ("couldn't find separator in: " + output);
265
266 std::istringstream str (output.substr (split + separator.size() + 1));
267 std::regex pattern (filter);
268 std::string line;
269 while (std::getline (str, line))
270 {
271 if (!line.empty())
272 {
273 if (!line.starts_with ("root:"))
274 throw std::runtime_error ("faxListFilesRegex: couldn't parse line: " + line);
275
276 std::string::size_type split1 = line.rfind (":");
277 std::string::size_type split2 = line.rfind ("/");
278 if (split1 < split2)
279 split1 = split2;
280 if (split1 != std::string::npos)
281 {
282 if (RCU::match_expr (pattern, line.substr (split1+1)))
283 result.push_back (line);
284 } else
285 throw std::runtime_error ("faxListFilesRegex: couldn't parse line: " + line);
286 }
287 }
288 if (result.size() == 0)
289 ANA_MSG_WARNING ("dataset " << name << " did not contain any files. this is likely not right");
290 return result;
291 }
#define RCU_REQUIRE_SOFT(x)
Definition Assert.h:141
#define ANA_MSG_INFO(xmsg,...)
Macro printing info messages.
#define ANA_MSG_WARNING(xmsg,...)
Macro printing warning messages.
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179
std::string exec_read(const std::string &cmd)
effects: execute the given command and return the output returns: the output of the command guarantee...
Definition ShellExec.cxx:35
std::string quote(const std::string &name)
effects: quote the given name to protect it from the shell returns: the quoted name guarantee: strong...
Definition ShellExec.cxx:65
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...
void ensureVomsProxy()
ensure that we have a valid VOMS proxy available

◆ fetchMetaData() [1/2]

void SH::fetchMetaData ( MetaDataQuery & query)

effects: fetch information on all the samples/datasets specified guarantee: basic

Definition at line 51 of file fetch.cxx.

52 {
53 static std::once_flag loaded;
54 auto do_load = []() {
55 // rationale: the helper module is installed via
56 // atlas_install_python_modules and is importable through
57 // PYTHONPATH, so import it by name rather than loading it from
58 // the dead RootCore $ROOTCOREBIN path.
59 if (!TPython::Exec ("import SampleHandler.SampleHandler_QueryAMI"))
60 throw std::runtime_error ("failed to import python module SampleHandler.SampleHandler_QueryAMI");
61 };
62 std::call_once (loaded, do_load);
63
64 std::ostringstream command;
65#if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,01)
66 command << "_anyresult = ";
67#endif
68 command << "SampleHandler.SampleHandler_QueryAMI.SampleHandler_QueryAmi([";
69 for (std::size_t iter = 0, end = query.samples.size(); iter != end; ++ iter)
70 {
71 if (iter != 0)
72 command << ", ";
73 command << pyQuote (query.samples[iter].name);
74 }
75 command << "])";
76#if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,01)
77 std::any result;
78 if (!TPython::Exec (command.str().c_str(), &result))
79 throw std::runtime_error ("failed to execute AMI metadata query");
80 query = std::any_cast<MetaDataQuery>(result);
81#else
82 MetaDataQuery* myquery = static_cast<MetaDataQuery*>
83 ((void*) TPython::Eval (command.str().c_str()));
84 if (myquery == nullptr)
85 throw std::runtime_error ("failed to execute AMI metadata query");
86 query = *myquery;
87#endif
88 }
query
Definition index.py:72
Definition query.py:1
an object containing the result of an AMI meta-data query

◆ fetchMetaData() [2/2]

void SH::fetchMetaData ( SampleHandler & sh,
bool override )

effects: fetch information on all the samples in the sample handler.

if override is specified it will override the existing meta-data fields, otherwise they will only be used if the given fields do not yet exist guarantee: basic

Definition at line 91 of file fetch.cxx.

92 {
93 using namespace msgFetch;
94
95 std::vector<SH::Sample*> samples;
96 // typedef std::vector<SH::Sample*> SamplesIter;
98 for (auto *sample : sh)
99 {
100 std::string name = sample->meta()->castString (SH::MetaFields::gridName, sample->name());
101 query.samples.push_back (MetaDataSample (name));
102 samples.push_back (sample);
103 }
105
106 if (!query.messages.empty())
107 ANA_MSG_INFO (query.messages);
108 for (std::size_t iter = 0, end = query.samples.size(); iter != end; ++ iter)
109 {
110 if (query.samples[iter].unknown)
111 {
112 ANA_MSG_WARNING ("failed to find sample " << query.samples[iter].name);
113 } else
114 {
115 if (iter >= samples.size())
116 throw std::runtime_error ("AMI query returned more samples than were requested");
117 SH::Sample *sample = samples[iter];
118
119 if (!override)
120 {
121 query.samples[iter].isData = sample->meta()->castDouble (SH::MetaFields::isData, query.samples[iter].isData);
122 query.samples[iter].luminosity = sample->meta()->castDouble (SH::MetaFields::lumi, query.samples[iter].luminosity);
123 query.samples[iter].crossSection = sample->meta()->castDouble (SH::MetaFields::crossSection, query.samples[iter].crossSection);
124 query.samples[iter].nevents = sample->meta()->castDouble (SH::MetaFields::numEvents, query.samples[iter].nevents);
125 query.samples[iter].kfactor = sample->meta()->castDouble (SH::MetaFields::kfactor, query.samples[iter].kfactor);
126 query.samples[iter].filterEfficiency = sample->meta()->castDouble (SH::MetaFields::filterEfficiency, query.samples[iter].filterEfficiency);
127 }
128 if (query.samples[iter].isData != -1)
129 sample->meta()->setDouble (SH::MetaFields::isData, query.samples[iter].isData);
130 if (query.samples[iter].luminosity != -1)
131 sample->meta()->setDouble (SH::MetaFields::lumi, query.samples[iter].luminosity);
132 if (query.samples[iter].crossSection != -1)
133 sample->meta()->setDouble (SH::MetaFields::crossSection, query.samples[iter].crossSection);
134 if (query.samples[iter].nevents != -1)
135 sample->meta()->setDouble (SH::MetaFields::numEvents, query.samples[iter].nevents);
136 if (query.samples[iter].kfactor != -1)
137 sample->meta()->setDouble (SH::MetaFields::kfactor, query.samples[iter].kfactor);
138 if (query.samples[iter].filterEfficiency != -1)
139 sample->meta()->setDouble (SH::MetaFields::filterEfficiency, query.samples[iter].filterEfficiency);
140 }
141 }
142 }
void fetchMetaData(MetaDataQuery &query)
effects: fetch information on all the samples/datasets specified guarantee: basic
Definition fetch.cxx:51
all the meta-data fields that we may try to read from AMI.
static const std::string kfactor
the k-factor of the sample
Definition MetaFields.h:74
static const std::string numEvents
the number of events
Definition MetaFields.h:56
static const std::string isData
whether the sample is data
Definition MetaFields.h:71
static const std::string lumi
the luminosity of the sample
Definition MetaFields.h:68
static const std::string crossSection
the cross section field
Definition MetaFields.h:50
static const std::string filterEfficiency
the filter efficiency of the sample
Definition MetaFields.h:77

◆ makeFromTChain()

Sample * SH::makeFromTChain ( const std::string & name,
const TChain & chain )

effects: create a sample with the given name from the given TChain object guarantee: strong failures: out of memory II

Definition at line 105 of file ToolsDiscovery.cxx.

106 {
107 return makeFromTChainUnique (name, chain).release();
108 }
std::unique_ptr< Sample > makeFromTChainUnique(const std::string &name, const TChain &chain)
effects: create a sample with the given name from the given TChain object guarantee: strong failures:...

◆ makeFromTChainUnique()

std::unique_ptr< Sample > SH::makeFromTChainUnique ( const std::string & name,
const TChain & chain )

effects: create a sample with the given name from the given TChain object guarantee: strong failures: out of memory II

Definition at line 91 of file ToolsDiscovery.cxx.

92 {
93 auto result = std::make_unique<SampleLocal> (name);
94 result->meta()->setString (MetaFields::treeName, chain.GetName());
95
96 TIter chainIter (chain.GetListOfFiles());
97 TChainElement *chainElement = nullptr;
98 while ((chainElement = dynamic_cast<TChainElement*>(chainIter.Next())) != nullptr)
99 result->add (chainElement->GetTitle());
100 return result;
101 }
static const std::string treeName
the name of the tree in the sample
Definition MetaFields.h:44

◆ makeGridDirect()

void SH::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 opened directly.

for that it replaces the from part of the file with the to part. if allow_partial is set, it allows for partial datasets (meaning you may lose some files that are not there). guarantee: basic, may convert only some samples failures: out of memory III failures: dq2-ls errors failures: from not part of file name

Definition at line 249 of file ToolsDiscovery.cxx.

252 {
253 using namespace msgDiscovery;
254
255 SampleHandler mysh;
256
257 for (auto sample : sh.samples())
258 {
259 SampleGrid *grid = dynamic_cast<SampleGrid*>(sample.get());
260
261 if (grid == nullptr)
262 {
263 mysh.add (sample);
264 } else
265 {
266 const std::string ds = grid->meta()->castString (MetaFields::gridName);
267 if (ds.empty())
268 throw std::runtime_error ("no dataset configured for grid sample " + grid->name());
269
271
272 std::set<std::string> knownFiles;
273 std::map<std::string,std::string> usedFiles;
274 for (auto& entry : rucioListFileReplicas (ds))
275 {
276 if (RCU::match_expr (pattern, entry.name))
277 {
278 knownFiles.insert (entry.name);
279 if (entry.disk == disk)
280 {
281 std::string url = entry.replica;
282 const auto split = url.find (from);
283 if (split == std::string::npos)
284 throw std::runtime_error ("prefix \"" + from + "\" not part of replica URL: " + url);
285 url.replace(split, from.size(), to);
286 usedFiles[entry.name] = url;
287 }
288 }
289 }
290
291 if (usedFiles.empty())
292 {
293 if (allow_partial)
294 ANA_MSG_WARNING ("dataset " << ds << " not at " << disk << ", skipped");
295 } else if (knownFiles.size() != usedFiles.size())
296 {
297 if (allow_partial)
298 {
299 ANA_MSG_WARNING ("only incomplete version of dataset " << ds << " at " << disk);
300 } else
301 {
302 usedFiles.clear ();
303 }
304 }
305
306 if (usedFiles.size() == 0)
307 {
308 mysh.add (sample);
309 } else
310 {
311 auto mysample = std::make_unique<SampleLocal> (grid->name());
312 *mysample->meta() = *grid->meta();
313
314 for (const auto& file : usedFiles)
315 {
316 mysample->add (file.second);
317 }
318 mysh.add (std::move (mysample));
319 }
320 }
321 }
322 swap (sh, mysh);
323 }
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
MetaObject * meta()
the meta-information for this sample
const std::string & name() const
the name of the sample we are using
std::vector< RucioListFileReplicasEntry > rucioListFileReplicas(const std::string &dataset)
run rucio-list-file-replicas for the given dataset

◆ mergeFiles() [1/2]

std::unique_ptr< SampleLocal > SH::mergeFiles ( const Sample & sample,
const std::string & location,
bool overwrite )

merge all the files in the sample into a single file in the given location

This is mostly meant to allow merging histogram files (particularly in EventLoop), but in some cases it can also be used to merge n-tuple fiels together.

Returns
a sample containing the merged file
Guarantee
basic
Failures
i/o errors
out of memory III

Definition at line 71 of file ToolsOther.cxx.

73 {
74 auto result = std::make_unique<SampleLocal> (sample.name());
75 result->add (location);
76 *result->meta() = *sample.meta();
77 if (overwrite || gSystem->AccessPathName (location.c_str()) != 0)
78 {
79 std::vector<std::string> files = sample.makeFileList();
80 RCU::hadd (location, files);
81 }
82 return result;
83 }
std::vector< std::string > files
file names and file pointers
Definition hcg.cxx:52
void hadd(const std::string &output_file, const std::vector< std::string > &input_files, unsigned max_files)
effects: perform the hadd functionality guarantee: basic failures: out of memory III failures: i/o er...
Definition hadd.cxx:29

◆ mergeFiles() [2/2]

SampleHandler SH::mergeFiles ( const SampleHandler & sh,
const std::string & location,
bool overwrite )

merge all the files in the sample handles into a single file per sample in the given location

This is mostly meant to allow merging histogram files (particularly in EventLoop), but in some cases it can also be used to merge n-tuple files together.

Returns
a sample handler containing the merged files
Guarantee
basic
Failures
i/o errors
out of memory III

Definition at line 88 of file ToolsOther.cxx.

90 {
91 SampleHandler result;
92 for (auto sample : sh)
93 {
94 std::string sublocation = location + sample->name() + ".root";
95 result.add (mergeFiles (*sample, sublocation, overwrite));
96 }
97 return result;
98 }
std::unique_ptr< SampleLocal > mergeFiles(const Sample &sample, const std::string &location, bool overwrite)
merge all the files in the sample into a single file in the given location

◆ mergeSamples()

void SH::mergeSamples ( SampleHandler & sh,
const std::string & sampleName,
const std::string & pattern )

effects: remove all samples matching the name pattern, and join them into a single sample named sampleName guarantee: strong failures: out of memory II failures: i/o errors

Definition at line 25 of file ToolsJoin.cxx.

27 {
28 SampleHandler mysh;
29 auto mysample = std::make_shared<SampleLocal> (sampleName);
30 bool matched = false;
31
32 std::regex mypattern (pattern);
33 for (auto& sample : sh.samples())
34 {
35 if (RCU::match_expr (mypattern, sample->name()))
36 {
37 if (!matched)
38 {
39 // rationale: inherit the metadata (tree name, cross section,
40 // ...) from the first matched sample instead of falling
41 // back to the defaults.
42 *mysample->meta() = *sample->meta();
43 matched = true;
44 }
45 for (unsigned file = 0, end = sample->numFiles();
46 file != end; ++ file)
47 {
48 mysample->add (sample->fileName (file));
49 }
50 } else
51 {
52 mysh.add (sample);
53 }
54 }
55 // rationale: only add the merged sample if at least one sample
56 // matched, so we do not create a spurious empty sample.
57 if (matched)
58 mysh.add (mysample);
59 swap (mysh, sh);
60 }

◆ openFile()

std::unique_ptr< TFile > SH::openFile ( const std::string & name,
const MetaObject & options )

open a file with the given options

for now this is to allow opening files with retries, but in the future there may be other options as well.

Guarantee
strong
Failures
i/o errors
file not found
Postcondition
result != nullptr

Definition at line 35 of file ToolsOther.cxx.

36 {
37 const unsigned retries
38 = options.castInteger (MetaNames::openRetries(),
40 const double wait
41 = options.castDouble (MetaNames::openRetriesWait(),
43 if (wait < 0)
44 throw std::runtime_error ("negative values not allowed for: " + MetaNames::openRetriesWait());
45
46 std::unique_ptr<TFile> result;
47
48 static std::atomic<unsigned> seed = 0;
49 std::default_random_engine re (++seed);
50 std::uniform_real_distribution wait_dist (wait/2, wait);
51
52 for (unsigned tries = 0; tries <= retries; ++ tries)
53 {
54 if (tries > 0)
55 {
56 unsigned mywait = 1000 * wait_dist (re);
57 std::cout << "open failed, waiting " << (mywait/1000.) << " seconds: "
58 << name << std::endl;
59 std::this_thread::sleep_for (std::chrono::milliseconds (mywait));
60 }
61 result.reset (TFile::Open (name.c_str(), "READ"));
62 if (result != nullptr)
63 return result;
64 }
65 throw std::runtime_error ("failed to open file: " + name);
66 }
const std::regex re(r_e)
static const std::string & openRetries()
the number of retries for opening a file
Definition MetaNames.cxx:23
static double openRetriesWait_default()
the default value of openRetriesWait
Definition MetaNames.cxx:49
static unsigned openRetries_default()
the default value of openRetries
Definition MetaNames.cxx:32
static const std::string & openRetriesWait()
the amount of time (in seconds) to wait when doing retries
Definition MetaNames.cxx:40

◆ printDuplicateEvents()

void SH::printDuplicateEvents ( const Sample & sample)

effects: check the given sample for duplicate events and then print them out guarantee: basic, may print partially failures: out of memory III failures: i/o errors

Definition at line 172 of file ToolsDuplicates.cxx.

173 {
174 RunEventList list;
175 std::unique_ptr<TChain> chain (sample.makeTChain ());
176 printDuplicateEvents (*chain, list);
177 }
void printDuplicateEvents(const Sample &sample)
effects: check the given sample for duplicate events and then print them out guarantee: basic,...

◆ printDuplicateEventsJoint()

void SH::printDuplicateEventsJoint ( const SampleHandler & sh)

effects: check for duplicate events between all the samples and then print them out guarantee: basic, may print partially failures: out of memory III failures: i/o errors

Definition at line 191 of file ToolsDuplicates.cxx.

192 {
193 RunEventList list;
194 for (auto *sample : sh)
195 {
196 std::unique_ptr<TChain> chain (sample->makeTChain ());
197 printDuplicateEvents (*chain, list);
198 }
199 }

◆ printDuplicateEventsSplit()

void SH::printDuplicateEventsSplit ( const SampleHandler & sh)

effects: check each sample for duplicate events and then print them out guarantee: basic, may print partially failures: out of memory III failures: i/o errors

Definition at line 181 of file ToolsDuplicates.cxx.

182 {
183 for (auto *sample : sh)
184 {
185 printDuplicateEvents (*sample);
186 }
187 }

◆ readFileList()

void SH::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/o errors

Definition at line 377 of file ToolsDiscovery.cxx.

379 {
380 std::ifstream myfile (file.c_str());
381
382 auto sample = std::make_unique<SampleLocal> (name);
383 std::string line;
384 const std::set<char> whitespaces{'\t',' ','\n','\r'};
385 while (std::getline (myfile, line))
386 {
387 while ((!line.empty()) && whitespaces.count(line.back())) line.pop_back();
388 if (!line.empty() && line.at(0) != '#')
389 {
390 sample->add (line);
391 }
392 }
393 if (!myfile.eof())
394 throw std::runtime_error ("failed to read file: " + file);
395 sh.add (std::move (sample));
396 }

◆ readSusyMeta()

void SH::readSusyMeta ( const SampleHandler & sh,
const std::string & inputFile )

effects: read the susy-meta-data file and add its information to the samples from the given sample handler guarantee: basic failures: i/o errors warning: there are no checks for duplicate and inconsistent sample definitions

Definition at line 30 of file ToolsMeta.cxx.

31 {
32 TString myfile = inputFile;
33 gSystem->ExpandPathName (myfile);
34 std::ifstream file (myfile.Data());
35 std::string line;
36
37 if (!file)
38 throw std::runtime_error ("failed to read file: " + inputFile);
39
40 while (std::getline (file, line))
41 {
42 if (line[0] >= '0' && line[0] <= '9')
43 {
44 std::istringstream str (line);
45 std::string DSID, name;
46 float crossSection = 0, kFactor = 0, filterEfficiency = 0,
47 xsUncertainty = 0;
48
49 if (!(str >> DSID >> name >> crossSection >> kFactor >> filterEfficiency
50 >> xsUncertainty))
51 throw std::runtime_error ("readSusyMeta: failed to parse line: " + line);
52
53 std::string mydsid = "." + DSID + ".";
54 for (auto *sample : sh)
55 {
56 if (sample->name().find (mydsid) != std::string::npos)
57 {
58 double oldCrossSection
59 = sample->meta()->castDouble (MetaFields::crossSection);
60 sample->meta()->setDouble (MetaFields::crossSection, oldCrossSection + crossSection);
61 sample->meta()->setDouble (MetaFields::kfactor, kFactor);
62 sample->meta()->setDouble (MetaFields::filterEfficiency, filterEfficiency);
63 sample->meta()->setDouble (MetaFields::crossSectionRelUncertainty, xsUncertainty);
64 }
65 }
66 }
67 }
68 }
static const std::string crossSectionRelUncertainty
the relative uncertainty on the cross section
Definition MetaFields.h:53

◆ readSusyMetaDir()

void SH::readSusyMetaDir ( const SampleHandler & sh,
const std::string & inputDir )

effects: read an entire directory of susy-meta-data files and add their information to the samples from the given sample handle.

for that it assumes that all files ending in ".txt" are susy-meta-data files. guarantee: basic failures: i/o errors warning: there are no checks for duplicate and inconsistent sample definitions

Definition at line 70 of file ToolsMeta.cxx.

71 {
72 TString mydir = inputDir;
73 gSystem->ExpandPathName (mydir);
74 void *dirp = 0;
75
76 try
77 {
78 dirp = gSystem->OpenDirectory (mydir.Data());
79 // rationale: OpenDirectory returns null for a missing/mistyped
80 // directory, and GetDirEntry/FreeDirectory tolerate a null
81 // handle, so this would otherwise silently read nothing; throw
82 // for consistency with readSusyMeta on a missing file.
83 if (dirp == nullptr)
84 throw std::runtime_error ("could not open directory: " + inputDir);
85 const char *file = 0;
86 while ((file = gSystem->GetDirEntry (dirp)))
87 {
88 std::string myfile = inputDir + "/" + file;
89 if (myfile.size() > 4 && myfile.substr (myfile.size()-4) == ".txt")
90 readSusyMeta (sh, myfile);
91 }
92 gSystem->FreeDirectory (dirp);
93 } catch (...)
94 {
95 gSystem->FreeDirectory (dirp);
96 throw;
97 }
98 }
void readSusyMeta(const SampleHandler &sh, const std::string &inputFile)
effects: read the susy-meta-data file and add its information to the samples from the given sample ha...
Definition ToolsMeta.cxx:30

◆ rucioCacheDatasetGlob()

std::vector< std::string > SH::rucioCacheDatasetGlob ( const std::string & location,
const std::string & dataset,
const std::string & fileGlob )

download the dataset, and return a list matching the pattern

Guarantee
basic
Failures
grid utility failures i/o errors

Definition at line 550 of file GridTools.cxx.

553 {
554 std::vector<std::string> result;
555
556 std::string path = location;
557 if (path.empty() || path.back() != '/')
558 path += "/";
559 if (dataset.find (':') != std::string::npos)
560 path += dataset.substr (dataset.find (':')+1);
561 else
562 path += dataset;
563 const std::string finished {
564 path + "-finished"};
565
566 // check if the finished file does not exist
567 // note that AccessPathName has the weirdest calling convention
568 //
569 // rationale: this check-then-download is not safe against two jobs
570 // caching the same dataset into the same directory concurrently
571 // (they can both see the marker missing and download at the same
572 // time); guarding that properly would need an exclusive lock on
573 // the directory. we do at least check that the marker file was
574 // created, so an unwritable directory fails loudly instead of
575 // silently re-downloading on every call.
576 if (gSystem->AccessPathName (finished.c_str()) != 0)
577 {
578 RucioDownloadResult status = rucioDownload (location, dataset);
579 if (status.downloadedFiles + status.alreadyLocal < status.totalFiles)
580 throw std::runtime_error ("failed to download all files of " + dataset);
581 // this just creates an empty file
582 std::ofstream finishedFile (finished.c_str());
583 if (!finishedFile)
584 throw std::runtime_error ("failed to create marker file: " + finished);
585 }
586
587 std::string output = sh::exec_read ("find " + sh::quote (path) + " -type f -name " + sh::quote (fileGlob));
588 std::istringstream str (output);
589 std::string line;
590 while (std::getline (str, line))
591 {
592 if (!line.empty())
593 result.push_back (line);
594 }
595 return result;
596 }
RucioDownloadResult rucioDownload(const std::string &location, const std::string &dataset)
run rucio-download
output
Definition merge.py:16

◆ rucioDirectAccessGlob()

std::vector< std::string > SH::rucioDirectAccessGlob ( const std::string & name,
const std::string & filter,
const std::string & selectOptions )

list the rucio URLs for all the files in the dataset or dataset container matching the given filter (as glob expression)

Guarantee
strong
Failures
grid utility failures
Precondition
!name.empty()
name.find('*') == std::string::npos
!filter.empty()

Definition at line 296 of file GridTools.cxx.

298 {
299 return rucioDirectAccessRegex (name, RCU::glob_to_regexp (filter),
300 selectOptions);
301 }
std::vector< std::string > rucioDirectAccessRegex(const std::string &name, const std::string &filter, const std::string &selectOptions)
list the rucio URLs for all the files in the dataset or dataset container matching the given filter (...

◆ rucioDirectAccessRegex()

std::vector< std::string > SH::rucioDirectAccessRegex ( const std::string & name,
const std::string & filter,
const std::string & selectOptions )

list the rucio URLs for all the files in the dataset or dataset container matching the given filter (as regular expression)

Guarantee
strong
Failures
grid utility failures
Precondition
!name.empty()
name.find('*') == std::string::npos
!filter.empty()

Definition at line 306 of file GridTools.cxx.

308 {
309 RCU_REQUIRE_SOFT (!name.empty());
310 RCU_REQUIRE_SOFT (name.find('*') == std::string::npos);
311 RCU_REQUIRE_SOFT (!filter.empty());
312
314
315 static const std::string separator = "------- SampleHandler Split -------";
316
317 ANA_MSG_INFO ("querying rucio for dataset " << name);
318 std::string output = sh::exec_read (rucioSetupCommand() + " && echo " + separator + " && rucio list-file-replicas --pfns --protocols root " + selectOptions + " " + sh::quote (name));
319 auto split = output.rfind (separator + "\n");
320 if (split == std::string::npos)
321 throw std::runtime_error ("couldn't find separator in: " + output);
322 std::istringstream str (output.substr (split + separator.size() + 1));
323
324 // this is used to avoid getting two copies of the same file. we
325 // first fill them in a map by filename, then copy them into a
326 // vector
327 std::map<std::string,std::string> resultMap;
328
329 std::regex urlPattern ("^root://.*");
330 std::regex pattern (filter);
331 std::string line;
332 while (std::getline (str, line))
333 {
334 if (line.empty())
335 {
336 // no-op
337 } else if (!RCU::match_expr (urlPattern, line))
338 {
339 ANA_MSG_INFO ("couldn't handle line: " << line);
340 } else
341 {
342 std::string::size_type split = line.rfind ("/");
343 if (split != std::string::npos)
344 {
345 std::string filename = line.substr (split+1);
346 if (RCU::match_expr (pattern, filename))
347 resultMap[filename] = line;
348 } else
349 throw std::runtime_error ("rucioDirectAccessRegex: couldn't parse line: " + line);
350 }
351 }
352
353 std::vector<std::string> result;
354 for (const auto& file : resultMap)
355 result.push_back (file.second);
356 if (result.size() == 0)
357 ANA_MSG_WARNING ("dataset " + name + " did not contain any files. this is likely not right");
358 return result;
359 }

◆ rucioDownload()

RucioDownloadResult SH::rucioDownload ( const std::string & location,
const std::string & dataset )

run rucio-download

Guarantee
basic
Failures
grid utility failures

Definition at line 511 of file GridTools.cxx.

513 {
515
516 const std::string separator = "------- SampleHandler Split -------";
517 std::string command = rucioSetupCommand() + " && echo " + separator + " && cd " + sh::quote (location) + " && rucio download " + sh::quote (dataset) + " 2>&1";
518
519 ANA_MSG_INFO ("starting rucio download " + dataset + " into " + location);
520 std::string output = sh::exec_read (command);
521 auto split = output.rfind (separator + "\n");
522 if (split == std::string::npos)
523 throw std::runtime_error ("couldn't find separator in: " + output);
524 output = output.substr (split + separator.size() + 1);
525
526 RucioDownloadResult result;
527 result.did = readLine (output, "DID ");
528 result.totalFiles = readLineUnsigned (output, "Total files (DID): ");
529 result.downloadedFiles = readLineUnsigned (output, "Downloaded files: ");
530 result.alreadyLocal = readLineUnsigned (output, "Files already found locally: ");
531 result.notDownloaded = readLineUnsigned (output, "Files that cannot be downloaded: ");
532 return result;
533 }
the result from rucio_download
Definition GridTools.h:175

◆ rucioDownloadList()

std::vector< RucioDownloadResult > SH::rucioDownloadList ( const std::string & location,
const std::vector< std::string > & datasets )

run rucio-download with multiple datasets

Guarantee
basic
Failures
grid utility failures

Definition at line 538 of file GridTools.cxx.

540 {
541 std::vector<RucioDownloadResult> result;
542 for (auto& dataset : datasets)
543 result.push_back (rucioDownload (location, dataset));
544 return result;
545 }

◆ rucioGetMetadata()

std::map< std::string, std::unique_ptr< MetaObject > > SH::rucioGetMetadata ( const std::set< std::string > & datasets)

run rucio-get-metadata for the given list of datasets

Guarantee
strong
Failures
grid utility failures
Precondition
!datasets.empty()
!dataset.empty() (for each dataset)

Definition at line 441 of file GridTools.cxx.

442 {
443 RCU_REQUIRE_SOFT (!datasets.empty());
444
446
447 static const std::string separator = "------- SampleHandler Split -------";
448 std::map<std::string,std::unique_ptr<MetaObject> > result;
449
450 std::string command = rucioSetupCommand() + " && echo " + separator + " && rucio get-metadata";
451 for (auto& dataset : datasets)
452 {
453 RCU_REQUIRE_SOFT (!dataset.empty());
454 command += " " + sh::quote (dataset);
455 }
456
457 ANA_MSG_INFO ("querying rucio for meta-data");
458 std::string output = sh::exec_read (command);
459 auto split = output.rfind (separator + "\n");
460 if (split == std::string::npos)
461 throw std::runtime_error ("couldn't find separator in: " + output);
462
463 std::istringstream str (output.substr (split + separator.size() + 1));
464 std::regex pattern ("^([^:]+): *(.+)$");
465 std::string line;
466 auto meta = std::make_unique<MetaObject>();
467
468 auto addMeta = [&] ()
469 {
470 std::string name = meta->castString ("scope") + ":" + meta->castString ("name");
471 if (result.find (name) != result.end())
472 throw std::runtime_error ("rucioGetMetadata: read " + name + " twice");
473 result[name] = std::move (meta);
474 };
475
476 while (std::getline (str, line))
477 {
478 std::smatch what;
479 if (line == "------")
480 {
481 addMeta ();
482 meta = std::make_unique<MetaObject>();
483 } else if (std::regex_match (line, what, pattern))
484 {
485 if (meta->get (what[1]))
486 throw std::runtime_error (std::string("duplicate entry: ") + what[1].str());
487 meta->setString (what[1], what[2]);
488 } else if (!line.empty())
489 {
490 ANA_MSG_WARNING ("couldn't parse line: " << line);
491 }
492 }
493 addMeta ();
494
495 for (auto& subresult : result)
496 {
497 if (datasets.find (subresult.first) == datasets.end())
498 throw std::runtime_error ("received result for dataset not requested: " + subresult.first);
499 }
500 for (auto& dataset : datasets)
501 {
502 if (result.find (dataset) == result.end())
503 throw std::runtime_error ("received no result for dataset: " + dataset);
504 }
505
506 return result;
507 }
-diff

◆ rucioListDids()

std::vector< RucioListDidsEntry > SH::rucioListDids ( const std::string & dataset)

run rucio-list-dids for the given dataset

Guarantee
strong
Failures
grid utility failures
Precondition
!dataset.empty()

Definition at line 363 of file GridTools.cxx.

364 {
365 RCU_REQUIRE_SOFT (!dataset.empty());
366
368
369 static const std::string separator = "------- SampleHandler Split -------";
370 std::vector<RucioListDidsEntry> result;
371
372 ANA_MSG_INFO ("querying rucio for dataset " << dataset);
373 std::string output = sh::exec_read (rucioSetupCommand() + " && echo " + separator + " && rucio list-dids " + sh::quote (dataset));
374 auto split = output.rfind (separator + "\n");
375 if (split == std::string::npos)
376 throw std::runtime_error ("couldn't find separator in: " + output);
377
378 std::istringstream str (output.substr (split + separator.size() + 1));
379 std::regex pattern ("^\\| ([a-zA-Z0-9_.-]+):([a-zA-Z0-9_.-]+) +\\| ([a-zA-Z0-9_.-]+) +\\| *$");
380 std::string line;
381 while (std::getline (str, line))
382 {
383 std::smatch what;
384 if (std::regex_match (line, what, pattern))
385 {
386 RucioListDidsEntry entry;
387 entry.scope = what[1];
388 entry.name = what[2];
389 entry.type = what[3];
390 result.push_back (entry);
391 }
392 }
393 return result;
394 }
one entry from the rucio-list-dids command
Definition GridTools.h:107

◆ rucioListFileReplicas()

std::vector< RucioListFileReplicasEntry > SH::rucioListFileReplicas ( const std::string & dataset)

run rucio-list-file-replicas for the given dataset

Guarantee
strong
Failures
grid utility failures
Precondition
!dataset.empty()

Definition at line 399 of file GridTools.cxx.

400 {
401 RCU_REQUIRE_SOFT (!dataset.empty());
402
404
405 static const std::string separator = "------- SampleHandler Split -------";
406 std::vector<RucioListFileReplicasEntry> result;
407
408 std::string command = rucioSetupCommand() + " && echo " + separator + " && rucio list-file-replicas --protocols root " + sh::quote (dataset);
409
410 ANA_MSG_INFO ("querying rucio for dataset " << dataset);
411 std::string output = sh::exec_read ( command );
412 auto split = output.rfind (separator + "\n");
413 if (split == std::string::npos)
414 throw std::runtime_error ("couldn't find separator in: " + output);
415
416 std::istringstream str (output.substr (split + separator.size() + 1));
417 std::regex pattern ("^\\| +([^ ]+) +\\| +([^ ]+) +\\| +([^ ]+ [^ ]+) +\\| +([^ ]+) +\\| +([^: ]+): ([^ ]+) +\\| *$");
418 std::string line;
419 while (std::getline (str, line))
420 {
421 std::smatch what;
422 if (std::regex_match (line, what, pattern) &&
423 what[1] != "SCOPE")
424 {
426 entry.scope = what[1];
427 entry.name = what[2];
428 entry.filesize = what[3];
429 entry.adler32 = what[4];
430 entry.disk = what[5];
431 entry.replica = what[6];
432 result.push_back (entry);
433 }
434 }
435 return result;
436 }
one entry from the rucio-list-file-replicas command
Definition GridTools.h:131

◆ scanDir() [1/3]

void SH::scanDir ( SampleHandler & sh,
const std::string & dir )

Definition at line 55 of file ToolsDiscovery.cxx.

56 {
57 ScanDir()
58 .sampleDepth (0)
59 .minDepth (1)
60 .maxDepth (1)
61 .scan (sh, dir);
62 }
the class used for scanning local directories and file servers for samples
Definition ScanDir.h:39
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 & minDepth(std::size_t val_minDepth)
the minimum depth for files to make it into the sample
Definition ScanDir.cxx:76

◆ scanDir() [2/3]

void SH::scanDir ( SampleHandler & sh,
const std::string & dir,
const std::string & prefix )

Definition at line 66 of file ToolsDiscovery.cxx.

68 {
69 DiskListLocal list (dir, prefix);
70 ScanDir()
71 .sampleDepth (0)
72 .minDepth (1)
73 .maxDepth (1)
74 .scan (sh, list);
75 }
a DiskList implementation for local directories

◆ scanDir() [3/3]

void SH::scanDir ( SampleHandler & sh,
DiskList & list,
const std::string & pattern = "*.root*",
const std::string & samplePattern = "*",
const std::string & samplePostfix = "" )

effects: scan the given directory and add all subdirectories as samples that contain root files.

if prefix is provided, use that instead of dir when constructing the file names. guarantee: basic, only some samples might be added failures: low level errors IV failures: directory not found failures: duplicate samples rationale: the prefix option is for the Tier 3 prototype, where you scan the local directory, but then access the files through xrootd

Definition at line 38 of file ToolsDiscovery.cxx.

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 }
ScanDir & samplePattern(const std::string &val_samplePattern)
the pattern for samples to be accepted
Definition ScanDir.cxx:130
ScanDir & samplePostfix(const std::string &val_samplePostfix)
the pattern for the postfix to be stripped from the sampleName
Definition ScanDir.cxx:139
ScanDir & filePattern(const std::string &val_filePattern)
the pattern for files to be accepted
Definition ScanDir.cxx:94

◆ scanDQ2()

void SH::scanDQ2 ( SampleHandler & sh,
const std::string & pattern )

effects: make a list from DQ2 using the given pattern guarantee: basic, may add partially failures: out of memory III failures: dq2-ls errors

Definition at line 124 of file ToolsDiscovery.cxx.

125 {
126 if (pattern.find ("*") == std::string::npos)
127 {
128 addGrid (sh, pattern);
129 } else
130 {
131 std::set<std::string> types = {"DATASET", "DIDType.DATASET"};
132 if (!pattern.empty() && pattern.back() == '/')
133 types = {"CONTAINER", "DIDType.CONTAINER"};
134
135 auto subresult = rucioListDids (pattern);
136 for (auto& ds : subresult)
137 {
138 if (types.find (ds.type) != types.end())
139 addGrid (sh, ds.scope + ":" + ds.name);
140 }
141 }
142 }
static const std::vector< std::string > types
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....
std::vector< RucioListDidsEntry > rucioListDids(const std::string &dataset)
run rucio-list-dids for the given dataset

◆ scanFiles()

void SH::scanFiles ( SampleHandler & sh,
DiskList & list,
const std::string & pattern = "*.root*" )

effects: scan the given directory tree and make a separate sample for each file (using the file name before any "." as the sample name).

guarantee: basic, only some samples might be added failures: out of memory III failures: i/o errors failures: duplicate samples

Definition at line 79 of file ToolsDiscovery.cxx.

81 {
82 ScanDir()
83 .sampleDepth (-1)
84 .filePattern (pattern)
85 .samplePostfix (".*")
86 .scan (sh, list);
87 }

◆ scanForTrees() [1/2]

void SH::scanForTrees ( SampleHandler & sh,
const 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 each tree.

if pattern is specified it is applied to the allowed tree names. guarantee: strong failures: out of memory III failures: i/o errors

Definition at line 327 of file ToolsDiscovery.cxx.

329 {
330 auto mysample = sample->makeLocal();
331 if (mysample->numFiles() == 0)
332 {
333 sh.add (sample);
334 return;
335 }
336 std::unique_ptr<TFile> file (TFile::Open (mysample->fileName(0).c_str()));
337 if (!file.get())
338 throw std::runtime_error ("could not open file: " + mysample->fileName(0));
339 TObject *object = nullptr;
340 std::regex mypattern (pattern);
341 // rationale: GetListOfKeys() contains one key per tree cycle
342 // (e.g. "physics;1", "physics;2"), all with the same name. we
343 // process each name only once, so that repeated cycles do not
344 // make sh.add throw on a duplicate sample name.
345 std::set<std::string> seenTrees;
346 for (TIter iter (file->GetListOfKeys()); (object = iter.Next()); )
347 {
348 if (RCU::match_expr (mypattern, object->GetName()) &&
349 seenTrees.insert (object->GetName()).second &&
350 dynamic_cast<TTree*>(file->Get(object->GetName())))
351 {
352 std::string newName = sample->name() + "_" + object->GetName();
353 std::unique_ptr<Sample> newSample
354 (dynamic_cast<Sample*>(sample->Clone (newName.c_str())));
355 newSample->name (newName);
356 newSample->meta()->setString (MetaFields::treeName, object->GetName());
357 sh.add (std::move (newSample));
358 }
359 }
360 }

◆ scanForTrees() [2/2]

void SH::scanForTrees ( SampleHandler & sh,
const std::string & pattern )

Definition at line 364 of file ToolsDiscovery.cxx.

365 {
366 SH::SampleHandler sh_new;
367
368 for (auto sample : sh.samples())
369 {
370 scanForTrees (sh_new, sample, pattern);
371 }
372 swap (sh, sh_new);
373 }
void scanForTrees(SampleHandler &sh, const 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...

◆ scanNEvents() [1/2]

void SH::scanNEvents ( Sample & sample)

effects: scan the given sample and store the number of entries per file in the meta-data guarantee: strong failures: out of memory failures: read errors failures: invalid sample type

Definition at line 40 of file ToolsSplit.cxx.

41 {
42 SampleLocal *const mysample = dynamic_cast<SampleLocal*>(&sample);
43 if (!mysample)
44 throw std::runtime_error ("sample not of type SampleLocal");
45
46 const std::string tree_name = sample.meta()->castString (MetaFields::treeName, MetaFields::treeName_default);
47 if (tree_name.empty())
48 throw std::runtime_error ("scanNEvents: sample doesn't contain a tree name");
49
50 Long64_t tot_entries = 0;
51 std::vector<Long64_t> entries;
52 const auto fileList = sample.makeFileList ();
53 for (const std::string& file_name : fileList)
54 {
55 std::unique_ptr<TFile> file (TFile::Open (file_name.c_str(), "READ"));
56 if (!file.get())
57 throw std::runtime_error ("failed to open file " + file_name);
58 Long64_t treeEntries = 0;
59 TTree *const tree = dynamic_cast<TTree*>(file->Get (tree_name.c_str()));
60 if (tree != 0)
61 treeEntries = tree->GetEntries ();
62 entries.push_back (treeEntries);
63 tot_entries += treeEntries;
64 }
65 RCU_ASSERT (entries.size() == fileList.size());
66 sample.meta()->addReplace (new MetaVector<Long64_t>(MetaFields::numEventsPerFile, entries));
67 sample.meta()->setDouble (MetaFields::numEvents, tot_entries);
68 }
#define RCU_ASSERT(x)
Definition Assert.h:210
A Sample based on a simple file list.
Definition SampleLocal.h:30
double entries
Definition listroot.cxx:49
static const std::string treeName_default
the default value of treeName
Definition MetaFields.h:47
static const std::string numEventsPerFile
the number of events in each file
Definition MetaFields.h:59
TChain * tree

◆ scanNEvents() [2/2]

void SH::scanNEvents ( SampleHandler & sh)

effects: scan each sample in the sample handler and store the number of entries per file in the meta-data guarantee: basic, may only scan some failures: out of memory failures: read errors failures: invalid sample type

Definition at line 32 of file ToolsSplit.cxx.

33 {
34 for (auto *sample : sh)
35 scanNEvents (*sample);
36 }
void scanNEvents(SampleHandler &sh)
effects: scan each sample in the sample handler and store the number of entries per file in the meta-...

◆ scanRucio()

void SH::scanRucio ( SampleHandler & sh,
const std::string & pattern,
bool alwaysQuery = false )

make a list of grid datasets using the given pattern

This will first look for dataset containers, and if none are found, it will instead look for datasets. If those are also not found it will produce an error.

For patterns that don't contain a wild-card (i.e. that can only match one dataset/container) it instead adds the dataset directly without querying rucio. This is a performance optimization based on the assumption that you probably checked the dataset names beforehand, and that if you made a mistake it will pop up at a later stage anyways. If you want to query rucio even in those cases set alwaysQuery to true.

Guarantee
basic, may add some datasets
Failures
no pattern match
rucio failures
out of memory III

Definition at line 146 of file ToolsDiscovery.cxx.

148 {
149 if (pattern.find ("*") == std::string::npos && !alwaysQuery)
150 {
151 addGrid (sh, pattern);
152 } else
153 {
154 auto subresult = rucioListDids (pattern);
155 bool added = false;
156 for (std::string type : {"CONTAINER", "DIDType.CONTAINER", "DATASET", "DIDType.DATASET"})
157 {
158 for (auto& ds : subresult)
159 {
160 if (ds.type == type)
161 {
162 addGrid (sh, ds.scope + ":" + ds.name);
163 added = true;
164 }
165 }
166 if (added)
167 return;
168 }
169 throw std::runtime_error ("failed to find any datasets matching pattern: " + pattern);
170 }
171 }

◆ scanSingleDir()

void SH::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: strong failures: out of memory III

Definition at line 112 of file ToolsDiscovery.cxx.

114 {
115 ScanDir()
116 .sampleDepth (0)
117 .filePattern (pattern)
118 .sampleRename ("*", name)
119 .scan (sh, list);
120 }
ScanDir & sampleRename(const std::string &pattern, const std::string &name)
rename any sample matching pattern to name
Definition ScanDir.cxx:149

◆ splitSample()

SampleHandler SH::splitSample ( Sample & sample,
Long64_t nevt )

effects: split the given sample into a set of samples, with each sample containing either exactly one file or at most nevt events side effects: if scanNEvents hasn't been run on this sample, run it.

guarantee: strong failures: out of memory failures: scanning errors

Definition at line 72 of file ToolsSplit.cxx.

73 {
74 using namespace msgSplit;
75
76 if (!dynamic_cast<SampleLocal*>(&sample))
77 throw std::runtime_error ("sample not of type SampleLocal");
78
79 TObject *meta = sample.meta()->get (MetaFields::numEventsPerFile);
80 if (!meta)
81 {
82 ANA_MSG_WARNING ("sample " << sample.name() << " lacks nc_nevtfile, running scanNEvents, please save sample");
83 scanNEvents (sample);
84 meta = sample.meta()->get (MetaFields::numEventsPerFile);
85 }
86 RCU_ASSERT (meta != 0);
87 MetaVector<Long64_t> *const nentries
88 = dynamic_cast<MetaVector<Long64_t> *>(meta);
89 if (nentries == 0)
90 throw std::runtime_error ("nc_nevtfile is of the wrong type");
91 if (nentries->value.size() != sample.numFiles())
92 throw std::runtime_error ("nc_nevtfile has the wrong number of entries");
93
94 SampleHandler result;
95 std::unique_ptr<SampleLocal> res;
96 Long64_t num = 0;
97 const std::string meta_tree = sample.meta()->castString (MetaFields::treeName, MetaFields::treeName_default);
98 const double meta_xs = sample.meta()->castDouble (MetaFields::crossSection, 0);
99 for (unsigned file = 0, end = nentries->value.size(); file != end; ++ file)
100 {
101 if (num > 0 && num + nentries->value[file] > nevt)
102 {
103 result.add (std::move (res));
104 res.reset();
105 num = 0;
106 }
107 if (res.get() == 0)
108 {
109 std::ostringstream name;
110 name << sample.name() << "_" << result.size();
111 res = std::make_unique<SampleLocal> (name.str());
112 res->tags (sample.tags());
113 res->meta()->fetch (*sample.meta());
114 if (!meta_tree.empty())
115 res->meta()->setString (MetaFields::treeName, meta_tree);
116 if (meta_xs != 0)
117 res->meta()->setDouble (MetaFields::crossSection, meta_xs);
118 }
119 res->add (sample.fileName (file));
120 num += nentries->value[file];
121 }
122 if (num > 0)
123 result.add (std::move (res));
124 return result;
125 }
std::pair< std::vector< unsigned int >, bool > res