]>
Commit | Line | Data |
---|---|---|
56236b95 | 1 | /** |
2 | * @file MakeChain.C | |
3 | * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk> | |
4 | * @date Tue Jul 12 10:20:07 2011 | |
5 | * | |
6 | * @brief Script to generate a chain of files | |
7 | * | |
bd6f5206 | 8 | * @ingroup pwglf_forward_scripts |
56236b95 | 9 | */ |
10 | /** | |
11 | * Check if a path points to a file | |
12 | * | |
13 | * @param path Path | |
14 | * | |
15 | * @return True if the path points to a regular file | |
16 | * | |
bd6f5206 | 17 | * @ingroup pwglf_forward_scripts |
56236b95 | 18 | */ |
19 | Bool_t | |
20 | IsFile(const char* path) | |
21 | { | |
22 | Long_t id; | |
23 | Long_t size; | |
24 | Long_t flags; | |
25 | Long_t modtime; | |
26 | gSystem->GetPathInfo(path, &id, &size, &flags, &modtime); | |
27 | return !((flags & 0x2) == 0x2); | |
28 | } | |
29 | ||
30 | /** | |
31 | * Test if we can open a file | |
32 | * | |
33 | * @param name Name of file | |
34 | * @param pattern Pattern to check against | |
35 | * | |
36 | * @return True on success | |
37 | */ | |
38 | Bool_t | |
39 | TestFile(const TString& name, const char* pattern=0) | |
40 | { | |
41 | // If this is not a root file, ignore | |
42 | if (!name.EndsWith(".root")) return false; | |
43 | ||
44 | // If this file does not contain the pattern, ignore | |
45 | if (pattern && pattern[0] != '\0' && !name.Contains(pattern)) return false; | |
46 | if (name.Contains("friends")) return false; | |
47 | ||
48 | Bool_t ret = true; | |
e2213ed5 | 49 | TFile* test = TFile::Open(name.Data(), "READ"); |
56236b95 | 50 | if (!test || test->IsZombie()) { |
e2213ed5 | 51 | Warning("TestFile", "Failed to open file %s", name.Data()); |
56236b95 | 52 | ret = false; |
53 | } | |
54 | else | |
55 | test->Close(); | |
56 | return ret; | |
57 | } | |
58 | ||
b2e7f2d6 | 59 | /** |
60 | * Scan a directory (optionally recursive) for data files to add to | |
61 | * the chain. Only ROOT files, and files which name contain the | |
62 | * passed pattern are considered. | |
63 | * | |
64 | * @param dir Directory to scan | |
65 | * @param chain Chain to add data to | |
66 | * @param pattern Pattern that the file name must contain | |
67 | * @param recursive Whether to scan recursively | |
56199f2b | 68 | * |
bd6f5206 | 69 | * @ingroup pwglf_forward_scripts |
b2e7f2d6 | 70 | */ |
71 | void | |
72 | ScanDirectory(TSystemDirectory* dir, TChain* chain, | |
73 | const char* pattern, bool recursive) | |
74 | { | |
75 | // Get list of files, and go back to old working directory | |
76 | TString oldDir(gSystem->WorkingDirectory()); | |
77 | TList* files = dir->GetListOfFiles(); | |
78 | gSystem->ChangeDirectory(oldDir); | |
79 | ||
80 | // Sort list of files and check if we should add it | |
81 | files->Sort(); | |
82 | TIter next(files); | |
83 | TSystemFile* file = 0; | |
84 | while ((file = static_cast<TSystemFile*>(next()))) { | |
85 | TString name(file->GetName()); | |
86 | ||
87 | // Ignore special links | |
88 | if (name == "." || name == "..") continue; | |
89 | ||
90 | // Check if this is a directory | |
91 | if (file->IsDirectory()) { | |
92 | if (recursive) | |
b5c9a732 | 93 | ScanDirectory(static_cast<TSystemDirectory*>(file),chain, |
94 | pattern,recursive); | |
b2e7f2d6 | 95 | continue; |
96 | } | |
97 | ||
b2e7f2d6 | 98 | // Get the path |
99 | TString data(Form("%s/%s", file->GetTitle(), name.Data())); | |
100 | ||
56236b95 | 101 | // Check the fuile |
102 | if (!TestFile(data, pattern)) continue; | |
b2e7f2d6 | 103 | chain->Add(data); |
b2e7f2d6 | 104 | } |
105 | } | |
56236b95 | 106 | /** |
107 | * Scan an input list of files | |
108 | * | |
95c09e1c | 109 | * @param chain Chain to add to |
110 | * @param path File with list of files to add | |
111 | * @param treeName Name of tree in files | |
56236b95 | 112 | * |
113 | * @return true on success | |
114 | */ | |
115 | Bool_t | |
e2213ed5 | 116 | ScanInputList(TChain* chain, const TString& path, const char* treeName=0) |
56236b95 | 117 | { |
118 | std::ifstream in(path.Data()); | |
119 | if (!in) { | |
120 | Error("ScanInputList", "Failed to open input list %s", path.Data()); | |
121 | return false; | |
122 | } | |
123 | TString line; | |
124 | while (in.good()) { | |
125 | line.ReadLine(in); // Skip white-space | |
126 | if (line.IsNull()) break; // Nothing -> EOF | |
127 | if (line[0] == '#') continue; // Ignore comment lines | |
128 | if (!TestFile(line, 0)) continue; | |
129 | chain->Add(line); | |
130 | } | |
131 | in.close(); | |
132 | return true; | |
133 | } | |
134 | ||
135 | ||
b2e7f2d6 | 136 | /** |
137 | * Make a chain of specified data | |
138 | * | |
139 | * @param what What data to chain. Possible values are | |
140 | * - ESD Event summary data (AliESD) | |
141 | * - AOD Analysis object data (AliAOD) | |
142 | * - MC Simulation data (galice) | |
143 | * @param datadir Data directory to scan | |
144 | * @param recursive Whether to recurse into sub-directories | |
145 | * | |
146 | * @return Pointer to newly create chain, or null | |
56199f2b | 147 | * |
bd6f5206 | 148 | * @ingroup pwglf_forward_scripts |
b2e7f2d6 | 149 | */ |
150 | TChain* | |
151 | MakeChain(const char* what, const char* datadir, bool recursive=false) | |
152 | { | |
153 | TString w(what); | |
154 | w.ToUpper(); | |
155 | const char* treeName = 0; | |
156 | const char* pattern = 0; | |
157 | if (w.Contains("ESD")) { treeName = "esdTree"; pattern = "AliESD"; } | |
158 | else if (w.Contains("AOD")) { treeName = "aodTree"; pattern = "AliAOD"; } | |
159 | else if (w.Contains("MC")) { treeName = "TE"; pattern = "galice"; } | |
160 | else { | |
161 | Error("MakeChain", "Unknown mode '%s' (not one of ESD,AOD, or MC)", what); | |
162 | return 0; | |
163 | } | |
164 | ||
165 | // --- Our data chain ---------------------------------------------- | |
166 | TChain* chain = new TChain(treeName); | |
167 | ||
56236b95 | 168 | // --- Get list of files -------------------------------------------- |
b2e7f2d6 | 169 | // Open source directory, and make sure we go back to were we were |
170 | TString oldDir(gSystem->WorkingDirectory()); | |
56236b95 | 171 | TString path(gSystem->ExpandPathName(datadir)); |
172 | if (!IsFile(path)) { | |
173 | TSystemDirectory d(datadir, datadir); | |
174 | ScanDirectory(&d, chain, pattern, recursive); | |
175 | } | |
176 | else if (path.EndsWith(".root")) { | |
177 | if (TestFile(path, pattern)) chain->Add(path); | |
178 | } | |
179 | else { | |
180 | // Input seems to be a list - parse it | |
181 | ScanInputList(chain, path); | |
182 | } | |
183 | ||
184 | // Make sure we do not make an empty chain | |
185 | if (chain->GetListOfFiles()->GetEntries() <= 0) { | |
186 | Warning("MakeChain", "Chain %s is empty for input %s", | |
187 | treeName, datadir); | |
188 | delete chain; | |
189 | chain = 0; | |
190 | } | |
b2e7f2d6 | 191 | return chain; |
192 | } | |
56199f2b | 193 | // |
194 | // EOF | |
195 | // |