]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/scripts/MakeChain.C
Fixed up some documentation
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / scripts / MakeChain.C
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  * 
8  * @ingroup pwglf_forward_scripts
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  *
17  * @ingroup pwglf_forward_scripts
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;
49   TFile* test = TFile::Open(name.Data(), "READ");
50   if (!test || test->IsZombie()) { 
51     Warning("TestFile", "Failed to open file %s", name.Data());
52     ret = false;
53   }
54   else 
55     test->Close();
56   return ret;
57 }
58
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 
68  *
69  * @ingroup pwglf_forward_scripts
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) 
93         ScanDirectory(static_cast<TSystemDirectory*>(file),chain,
94                       pattern,recursive);
95       continue;
96     }
97     
98     // Get the path 
99     TString data(Form("%s/%s", file->GetTitle(), name.Data()));
100
101     // Check the fuile 
102     if (!TestFile(data, pattern)) continue;
103     chain->Add(data);
104   }
105 }
106 /** 
107  * Scan an input list of files 
108  * 
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 
112  * 
113  * @return true on success 
114  */
115 Bool_t 
116 ScanInputList(TChain* chain, const TString& path, const char* treeName=0)
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   
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
147  *
148  * @ingroup pwglf_forward_scripts
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
168   // --- Get list of files --------------------------------------------
169   // Open source directory, and make sure we go back to were we were 
170   TString oldDir(gSystem->WorkingDirectory());
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   }
191   return chain;
192 }
193 //
194 // EOF
195 //