+/**
+ * @file MakeChain.C
+ * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
+ * @date Tue Jul 12 10:20:07 2011
+ *
+ * @brief Script to generate a chain of files
+ *
+ * @ingroup pwg2_forward_scripts
+ */
+/**
+ * Check if a path points to a file
+ *
+ * @param path Path
+ *
+ * @return True if the path points to a regular file
+ *
+ * @ingroup pwg2_forward_scripts
+ */
+Bool_t
+IsFile(const char* path)
+{
+ Long_t id;
+ Long_t size;
+ Long_t flags;
+ Long_t modtime;
+ gSystem->GetPathInfo(path, &id, &size, &flags, &modtime);
+ return !((flags & 0x2) == 0x2);
+}
+
+/**
+ * Test if we can open a file
+ *
+ * @param name Name of file
+ * @param pattern Pattern to check against
+ *
+ * @return True on success
+ */
+Bool_t
+TestFile(const TString& name, const char* pattern=0)
+{
+ // If this is not a root file, ignore
+ if (!name.EndsWith(".root")) return false;
+
+ // If this file does not contain the pattern, ignore
+ if (pattern && pattern[0] != '\0' && !name.Contains(pattern)) return false;
+ if (name.Contains("friends")) return false;
+
+ Bool_t ret = true;
+ TFile* test = TFile::Open(data.Data(), "READ");
+ if (!test || test->IsZombie()) {
+ Warning("TestFile", "Failed to open file %s", data.Data());
+ ret = false;
+ }
+ else
+ test->Close();
+ return ret;
+}
+
/**
* Scan a directory (optionally recursive) for data files to add to
* the chain. Only ROOT files, and files which name contain the
continue;
}
- // If this is not a root file, ignore
- if (!name.EndsWith(".root")) continue;
-
- // If this file does not contain the pattern, ignore
- if (!name.Contains(pattern)) continue;
- if (name.Contains("friends")) continue;
-
// Get the path
TString data(Form("%s/%s", file->GetTitle(), name.Data()));
- TFile* test = TFile::Open(data.Data(), "READ");
- if (!test || test->IsZombie()) {
- Warning("ScanDirectory", "Failed to open file %s", data.Data());
- continue;
- }
- test->Close();
+ // Check the fuile
+ if (!TestFile(data, pattern)) continue;
chain->Add(data);
-
}
}
-
+/**
+ * Scan an input list of files
+ *
+ * @param chain Chain to add to
+ * @param path file with list of files to add
+ *
+ * @return true on success
+ */
+Bool_t
+ScanInputList(TChain* chain, const TString& path, const char* treeName)
+{
+ std::ifstream in(path.Data());
+ if (!in) {
+ Error("ScanInputList", "Failed to open input list %s", path.Data());
+ return false;
+ }
+ TString line;
+ while (in.good()) {
+ line.ReadLine(in); // Skip white-space
+ if (line.IsNull()) break; // Nothing -> EOF
+ if (line[0] == '#') continue; // Ignore comment lines
+ if (!TestFile(line, 0)) continue;
+ chain->Add(line);
+ }
+ in.close();
+ return true;
+}
+
+
/**
* Make a chain of specified data
*
// --- Our data chain ----------------------------------------------
TChain* chain = new TChain(treeName);
- // --- Get list of ESDs --------------------------------------------
+ // --- Get list of files --------------------------------------------
// Open source directory, and make sure we go back to were we were
TString oldDir(gSystem->WorkingDirectory());
- TSystemDirectory d(datadir, datadir);
- ScanDirectory(&d, chain, pattern, recursive);
-
+ TString path(gSystem->ExpandPathName(datadir));
+ if (!IsFile(path)) {
+ TSystemDirectory d(datadir, datadir);
+ ScanDirectory(&d, chain, pattern, recursive);
+ }
+ else if (path.EndsWith(".root")) {
+ if (TestFile(path, pattern)) chain->Add(path);
+ }
+ else {
+ // Input seems to be a list - parse it
+ ScanInputList(chain, path);
+ }
+
+ // Make sure we do not make an empty chain
+ if (chain->GetListOfFiles()->GetEntries() <= 0) {
+ Warning("MakeChain", "Chain %s is empty for input %s",
+ treeName, datadir);
+ delete chain;
+ chain = 0;
+ }
return chain;
}
//