#include "TDSet.h"
#include "Riostream.h"
#include "TClass.h"
#include "TClassTable.h"
#include "TCut.h"
#include "TError.h"
#include "TFile.h"
#include "TFileInfo.h"
#include "TFriendElement.h"
#include "TKey.h"
#include "TList.h"
#include "TMap.h"
#include "TROOT.h"
#include "TTimeStamp.h"
#include "TTree.h"
#include "TUrl.h"
#include "TRegexp.h"
#include "TVirtualPerfStats.h"
#include "TProof.h"
#include "TProofChain.h"
#include "TPluginManager.h"
#include "TChain.h"
#include "TChainElement.h"
#include "TSystem.h"
#include "THashList.h"
#include <set>
#include <queue>
ClassImp(TDSetElement)
ClassImp(TDSet)
TDSetElement::TDSetElement(const char *file, const char *objname, const char *dir,
Long64_t first, Long64_t num,
const char *msd)
{
fFileName = file;
if (first < 0) {
Warning("TDSetElement", "first must be >= 0, %d is not allowed - setting to 0", first);
fFirst = 0;
} else {
fFirst = first;
}
if (num < -1) {
Warning("TDSetElement", "num must be >= -1, %d is not allowed - setting to -1", num);
fNum = -1;
} else {
fNum = num;
}
fMsd = msd;
fTDSetOffset = 0;
fEventList = 0;
fFriends = 0;
fValid = kFALSE;
fEntries = -1;
if (objname)
fObjName = objname;
if (dir)
fDirectory = dir;
}
TDSetElement::TDSetElement(const TDSetElement& elem) : TObject()
{
fFileName = elem.GetFileName();
fObjName = elem.GetObjName();
fDirectory = elem.GetDirectory();
fFirst = elem.fFirst;
fNum = elem.fNum;
fMsd = elem.fMsd;
fTDSetOffset = elem.fTDSetOffset;
fEventList = 0;
fValid = elem.fValid;
fEntries = elem.fEntries;
fIsTree = elem.fIsTree;
fFriends = 0;
}
TDSetElement::~TDSetElement()
{
DeleteFriends();
}
const char *TDSetElement::GetObjName() const
{
return fObjName;
}
const char *TDSetElement::GetDirectory() const
{
return fDirectory;
}
void TDSetElement::Print(Option_t *opt) const
{
if (opt && opt[0] == 'a') {
cout << IsA()->GetName()
<< " file=\"" << fFileName
<< "\" dir=\"" << fDirectory
<< "\" obj=\"" << fObjName
<< "\" first=" << fFirst
<< " num=" << fNum
<< " msd=\"" << fMsd
<< "\"" << endl;
} else
cout << "\tLFN: " << fFileName << endl;
}
void TDSetElement::Validate(Bool_t isTree)
{
Long64_t entries = GetEntries(isTree);
if (entries < 0) return;
if (fFirst < entries) {
if (fNum == -1) {
fNum = entries - fFirst;
fValid = kTRUE;
} else {
if (fNum <= entries - fFirst) {
fValid = kTRUE;
} else {
Error("Validate", "TDSetElement has only %d entries starting"
" with entry %d, while %d were requested",
entries - fFirst, fFirst, fNum);
}
}
} else {
Error("Validate", "TDSetElement has only %d entries with"
" first entry requested as %d", entries, fFirst);
}
}
void TDSetElement::Validate(TDSetElement *elem)
{
if (!elem || !elem->GetValid()) {
Error("Validate", "TDSetElement to validate against is not valid");
return;
}
if (!strcmp(GetFileName(), elem->GetFileName()) &&
!strcmp(GetDirectory(), elem->GetDirectory()) &&
!strcmp(GetObjName(), elem->GetObjName())) {
Long64_t entries = elem->fFirst + elem->fNum;
if (fFirst < entries) {
if (fNum == -1) {
fNum = entries - fFirst;
fValid = kTRUE;
} else {
if (fNum <= entries - fFirst) {
fValid = kTRUE;
} else {
Error("Validate", "TDSetElement requests %d entries starting"
" with entry %d, while TDSetElement to validate against"
" has only %d entries", fNum, fFirst, entries);
}
}
} else {
Error("Validate", "TDSetElement to validate against has only %d"
" entries, but this TDSetElement requested %d as its first"
" entry", entries, fFirst);
}
} else {
Error("Validate", "TDSetElements do not refer to same objects");
}
}
Int_t TDSetElement::Compare(const TObject *obj) const
{
if (this == obj) return 0;
const TDSetElement *elem = dynamic_cast<const TDSetElement*>(obj);
if (!elem) {
if (obj)
return fFileName.CompareTo(obj->GetName());
return -1;
}
Int_t order = fFileName.CompareTo(elem->GetFileName());
if (order == 0) {
if (GetFirst() < elem->GetFirst())
return -1;
else if (GetFirst() > elem->GetFirst())
return 1;
return 0;
}
return order;
}
void TDSetElement::AddFriend(TDSetElement *friendElement, const char *alias)
{
if (!friendElement) {
Error("AddFriend", "The friend TDSetElement is null!");
return;
}
if (!fFriends)
fFriends = new FriendsList_t;
fFriends->push_back(std::make_pair(new TDSetElement(*friendElement), TString(alias)));
}
void TDSetElement::DeleteFriends()
{
if (!fFriends)
return;
for (FriendsList_t::iterator i = fFriends->begin();
i != fFriends->end(); ++i) {
delete i->first;
}
delete fFriends;
fFriends = 0;
}
TDSetElement *TDSet::Next(Long64_t )
{
if (!fIterator) {
fIterator = new TIter(fElements);
}
fCurrent = (TDSetElement *) fIterator->Next();
return fCurrent;
}
Long64_t TDSetElement::GetEntries(Bool_t isTree)
{
if (fEntries > -1)
return fEntries;
Double_t start = 0;
if (gPerfStats != 0) start = TTimeStamp();
TFile *file = TFile::Open(fFileName);
if (gPerfStats != 0) {
gPerfStats->FileOpenEvent(file, fFileName, double(TTimeStamp())-start);
}
if (file == 0) {
::SysError("TDSet::GetEntries", "cannot open file %s", fFileName.Data());
return -1;
}
fFileName = ((TUrl *)file->GetEndpointUrl())->GetUrl();
SetBit(kHasBeenLookedUp);
TDirectory *dirsave = gDirectory;
if (!file->cd(fDirectory)) {
Error("GetEntries", "cannot cd to %s", fDirectory.Data());
delete file;
return -1;
}
TDirectory *dir = gDirectory;
dirsave->cd();
if (isTree) {
TString on(fObjName);
TString sreg(fObjName);
if (sreg.Length() <= 0 || sreg == "" || sreg.Contains("*")) {
if (sreg.Contains("*"))
sreg.ReplaceAll("*", ".*");
else
sreg = ".*";
TRegexp re(sreg);
if (dir->GetListOfKeys()) {
TIter nxk(dir->GetListOfKeys());
TKey *k = 0;
Bool_t notfound = kTRUE;
while ((k = (TKey *) nxk())) {
if (!strcmp(k->GetClassName(), "TTree")) {
TString kn(k->GetName());
if (kn.Index(re) != kNPOS) {
if (notfound) {
on = kn;
notfound = kFALSE;
} else if (kn != on) {
Warning("GetEntries",
"additional tree found in the file: %s", kn.Data());
}
}
}
}
}
}
TKey *key = dir->GetKey(on);
if (key == 0) {
Error("GetEntries", "cannot find tree \"%s\" in %s",
fObjName.Data(), fFileName.Data());
delete file;
return -1;
}
TTree *tree = (TTree *) key->ReadObj();
if (tree == 0) {
delete file;
return -1;
}
fEntries = tree->GetEntries();
delete tree;
} else {
TList *keys = dir->GetListOfKeys();
fEntries = keys->GetSize();
}
delete file;
return fEntries;
}
void TDSetElement::Lookup(Bool_t force)
{
static Int_t xNetPluginOK = -1;
static TString xNotRedir;
if (!force && HasBeenLookedUp())
return;
TUrl url(fFileName);
TString anch = url.GetAnchor();
TString opts = url.GetOptions();
url.SetOptions(Form("%s&filetype=rawremote=1", opts.Data()));
const char *name = url.GetUrl();
Bool_t doit = kFALSE;
TFile::EFileType type = TFile::GetType(name, "");
if (type == TFile::kNet) {
TPluginHandler *h = 0;
if (xNetPluginOK == -1) {
xNetPluginOK = 0;
if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
!strcmp(h->GetClass(),"TXNetFile") && h->LoadPlugin() == 0)
xNetPluginOK = 1;
}
doit = (xNetPluginOK == 1) ? kTRUE : kFALSE;
if (xNotRedir.Length() > 0) {
TUrl u(fFileName);
TString hp(Form("|%s:%d|", u.GetHostFQDN(), u.GetPort()));
if (xNotRedir.Contains(hp))
doit = kFALSE;
}
}
if (doit) {
TFile *f = TFile::Open(name);
if (!f || f->IsZombie()) {
Error("Lookup", "Couldn't open %s\n", name);
} else {
TUrl *u = (TUrl *) f->GetEndpointUrl();
if (!(f->TestBit(TFile::kRedirected))) {
xNotRedir += Form("|%s:%d|", u->GetHostFQDN(), u->GetPort());
} else {
TUrl eu(u->GetUrl());
eu.SetOptions(opts);
eu.SetAnchor(anch);
fFileName = eu.GetUrl();
}
delete f;
}
}
SetBit(kHasBeenLookedUp);
}
TDSet::TDSet()
{
fElements = new TList;
fElements->SetOwner();
fIsTree = kFALSE;
fIterator = 0;
fCurrent = 0;
fEventList = 0;
fProofChain = 0;
gROOT->GetListOfDataSets()->Add(this);
}
TDSet::TDSet(const char *name,
const char *objname, const char *dir, const char *type)
{
fElements = new TList;
fElements->SetOwner();
fIterator = 0;
fCurrent = 0;
fEventList = 0;
fProofChain = 0;
fType = "TTree";
TClass *c = 0;
if (name && strlen(name) > 0) {
if (!type) {
if ((c = gROOT->GetClass(name)))
fType = name;
else
fName = name;
} else {
fName = name;
if (strlen(type) > 0)
if ((c = gROOT->GetClass(type)))
fType = type;
}
} else if (type && strlen(type) > 0) {
if ((c = gROOT->GetClass(type)))
fType = type;
}
c = gROOT->GetClass(fType);
fIsTree = (c->InheritsFrom("TTree")) ? kTRUE : kFALSE;
if (objname)
fObjName = objname;
if (dir)
fDir = dir;
if (fName.Length() <= 0)
fName = fObjName;
fTitle = fType;
gROOT->GetListOfDataSets()->Add(this);
}
TDSet::TDSet(const TChain &chain, Bool_t withfriends)
{
fElements = new TList;
fElements->SetOwner();
fIterator = 0;
fCurrent = 0;
fEventList = 0;
fProofChain = 0;
fType = "TTree";
fIsTree = kTRUE;
fObjName = chain.GetName();
TIter next(chain.GetListOfFiles());
TChainElement *elem;
while ((elem = (TChainElement *)next())) {
TString file(elem->GetTitle());
TString tree(elem->GetName());
Int_t isl = tree.Index("/");
TString dir = "/";
if (isl >= 0) {
TString behindSlash = tree(isl + 1, tree.Length() - isl - 1);
tree.Remove(isl);
dir = tree;
tree = behindSlash;
}
Add(file, tree, dir);
}
SetDirectory(0);
if (withfriends) {
TList processed;
TList chainsQueue;
chainsQueue.Add((TObject *)&chain);
processed.Add((TObject *)&chain);
while (chainsQueue.GetSize() > 0) {
TChain *c = (TChain *) chainsQueue.First();
chainsQueue.Remove(c);
TIter friendsIter(c->GetListOfFriends());
while(TFriendElement *fe = dynamic_cast<TFriendElement*> (friendsIter()) ) {
if (TChain *fc = dynamic_cast<TChain*>(fe->GetTree())) {
if (!processed.FindObject(fc)) {
processed.AddFirst(fc);
AddFriend(new TDSet((const TChain &)(*fc), kFALSE), fe->GetName());
chainsQueue.Add(fc);
}
} else {
Reset();
Error("TDSet", "Only TChains supported. Found illegal tree %s",
fe->GetTree()->GetName());
return;
}
}
}
}
}
TDSet::~TDSet()
{
SafeDelete(fElements);
SafeDelete(fIterator);
SafeDelete(fProofChain);
gROOT->GetListOfDataSets()->Remove(this);
}
Long64_t TDSet::Process(const char *selector, Option_t *option, Long64_t nentries,
Long64_t first, TEventList *evl)
{
if (!IsValid() || !fElements->GetSize()) {
Error("Process", "not a correctly initialized TDSet");
return -1;
}
if (gProof)
return gProof->Process(this, selector, option, nentries, first, evl);
Error("Process", "no active PROOF session");
return -1;
}
void TDSet::AddInput(TObject *obj)
{
if (gProof) {
gProof->AddInput(obj);
} else {
Error("AddInput","No PROOF session active");
}
}
void TDSet::ClearInput()
{
if (gProof)
gProof->ClearInput();
}
TObject *TDSet::GetOutput(const char *name)
{
if (gProof)
return gProof->GetOutput(name);
return 0;
}
TList *TDSet::GetOutputList()
{
if (gProof)
return gProof->GetOutputList();
return 0;
}
void TDSet::Print(const Option_t *opt) const
{
cout <<"OBJ: " << IsA()->GetName() << "\ttype " << GetName() << "\t"
<< fObjName << "\tin " << GetTitle()
<< "\telements " << GetListOfElements()->GetSize() << endl;
if (opt && opt[0] == 'a') {
TIter next(GetListOfElements());
TObject *obj;
while ((obj = next())) {
obj->Print(opt);
}
}
}
void TDSet::SetObjName(const char *objname)
{
if (objname)
fObjName = objname;
}
void TDSet::SetDirectory(const char *dir)
{
if (dir)
fDir = dir;
}
Bool_t TDSet::Add(const char *file, const char *objname, const char *dir,
Long64_t first, Long64_t num, const char *msd)
{
if (!file || !*file) {
Error("Add", "file name must be specified");
return kFALSE;
}
TDSetElement *el;
Reset();
while ((el = Next())) {
if (!(strcmp(el->GetFileName(), file))) {
Warning("Add", "duplicate, %40s is already in dataset, ignored", file);
return kFALSE;
}
}
if (!objname)
objname = GetObjName();
if (!dir)
dir = GetDirectory();
fElements->Add(new TDSetElement(file, objname, dir, first, num, msd));
return kTRUE;
}
Bool_t TDSet::Add(TDSet *dset)
{
if (!dset)
return kFALSE;
if (fType != dset->GetType()) {
Error("Add", "cannot add a set with a different type");
return kFALSE;
}
TDSetElement *el;
TIter next(dset->fElements);
TObject *last = (dset == this) ? fElements->Last() : 0;
while ((el = (TDSetElement*) next())) {
Add(el->GetFileName(), el->GetObjName(), el->GetDirectory(),
el->GetFirst(), el->GetNum(), el->GetMsd());
if (el == last) break;
}
return kTRUE;
}
Bool_t TDSet::Add(TList *fileinfo)
{
if (!fileinfo)
return kFALSE;
TFileInfo *fi = 0;
TIter next(fileinfo);
while ((fi = (TFileInfo *) next())) {
Add(fi->GetFirstUrl()->GetUrl(kTRUE), 0, 0,
fi->GetFirst(), fi->GetEntries());
}
return kTRUE;
}
Int_t TDSet::ExportFileList(const char *fpath, Option_t *opt)
{
if (!fElements)
return -1;
if (fElements->GetSize() <= 0)
return 0;
Bool_t force = (opt[0] == 'F' || opt[0] == 'f');
if (gSystem->AccessPathName(fpath, kFileExists) == kFALSE) {
if (force) {
if (gSystem->Unlink(fpath)) {
Info("ExportFileList","error removing dataset file: %s", fpath);
return -1;
}
}
}
TList *fileinfo = new TList;
fileinfo->SetOwner();
TFileInfo *fi = 0;
TDSetElement *dse = 0;
TIter next(fElements);
while ((dse = (TDSetElement *) next())) {
Long64_t last = (dse->GetNum() > 0) ? dse->GetFirst()+dse->GetNum()-1 : -1;
fi = new TFileInfo(dse->GetFileName(), (Long64_t)(-1), 0,
0, dse->GetEntries(), dse->GetFirst(),
last);
fileinfo->Add(fi);
}
TFile *f = TFile::Open(fpath, "RECREATE");
if (f) {
f->cd();
fileinfo->Write("fileList", TObject::kSingleKey);
f->Close();
} else {
Info("ExportFileList","error creating dataset file: %s", fpath);
SafeDelete(fileinfo);
return -1;
}
SafeDelete(f);
SafeDelete(fileinfo);
return 0;
}
void TDSet::AddFriend(TDSet *friendset, const char* alias)
{
if (!friendset) {
Error("AddFriend", "The friend TDSet is null!");
return;
}
if (!fIsTree) {
Error("AddFriend", "a friend set can only be added to a TTree TDSet");
return;
}
TList* thisList = GetListOfElements();
TList* friendsList = friendset->GetListOfElements();
if (thisList->GetSize() != friendsList->GetSize() && friendsList->GetSize() != 1) {
Error("AddFriend", "The friend Set has %d elements while the main one has %d",
thisList->GetSize(), friendsList->GetSize());
return;
}
TIter next(thisList);
TIter next2(friendsList);
TDSetElement* friendElem = 0;
TString aliasString(alias);
if (friendsList->GetSize() == 1)
friendElem = dynamic_cast<TDSetElement*> (friendsList->First());
while(TDSetElement* e = dynamic_cast<TDSetElement*> (next())) {
if (friendElem)
e->AddFriend(friendElem, aliasString);
else
e->AddFriend(dynamic_cast<TDSetElement*> (next2()), aliasString);
}
}
void TDSet::Reset()
{
if (!fIterator) {
fIterator = new TIter(fElements);
} else {
fIterator->Reset();
}
}
Long64_t TDSet::GetEntries(Bool_t isTree, const char *filename, const char *path,
const char *objname)
{
Double_t start = 0;
if (gPerfStats != 0) start = TTimeStamp();
TFile *file = TFile::Open(filename);
if (gPerfStats != 0) {
gPerfStats->FileOpenEvent(file, filename, double(TTimeStamp())-start);
}
if (file == 0) {
::SysError("TDSet::GetEntries", "cannot open file %s", filename);
return -1;
}
TDirectory *dirsave = gDirectory;
if (!file->cd(path)) {
::Error("TDSet::GetEntries", "cannot cd to %s", path);
delete file;
return -1;
}
TDirectory *dir = gDirectory;
dirsave->cd();
Long64_t entries;
if (isTree) {
TString on(objname);
TString sreg(objname);
if (sreg.Length() <= 0 || sreg == "" || sreg.Contains("*")) {
if (sreg.Contains("*"))
sreg.ReplaceAll("*", ".*");
else
sreg = ".*";
TRegexp re(sreg);
if (dir->GetListOfKeys()) {
TIter nxk(dir->GetListOfKeys());
TKey *k = 0;
Bool_t notfound = kTRUE;
while ((k = (TKey *) nxk())) {
if (!strcmp(k->GetClassName(), "TTree")) {
TString kn(k->GetName());
if (kn.Index(re) != kNPOS) {
if (notfound) {
on = kn;
notfound = kFALSE;
} else if (kn != on) {
::Warning("TDSet::GetEntries",
"additional tree found in the file: %s", kn.Data());
}
}
}
}
}
}
TKey *key = dir->GetKey(on);
if (key == 0) {
::Error("TDSet::GetEntries", "cannot find tree \"%s\" in %s",
objname, filename);
delete file;
return -1;
}
TTree *tree = (TTree *) key->ReadObj();
if (tree == 0) {
delete file;
return -1;
}
entries = tree->GetEntries();
delete tree;
} else {
TList *keys = dir->GetListOfKeys();
entries = keys->GetSize();
}
delete file;
return entries;
}
Long64_t TDSet::Draw(const char *varexp, const TCut &selection, Option_t *option,
Long64_t nentries, Long64_t firstentry)
{
return Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
}
Long64_t TDSet::Draw(const char *varexp, const char *selection, Option_t *option,
Long64_t nentries, Long64_t firstentry)
{
if (!IsValid() || !fElements->GetSize()) {
Error("Draw", "not a correctly initialized TDSet");
return -1;
}
if (gProof)
return gProof->DrawSelect(this, varexp, selection, option, nentries,
firstentry);
Error("Draw", "no active PROOF session");
return -1;
}
void TDSet::StartViewer()
{
if (gROOT->IsBatch()) {
Warning("StartViewer", "viewer cannot run in batch mode");
return;
}
if (!gProof) {
Error("StartViewer", "no PROOF found");
return;
}
if (!IsTree()) {
Error("StartViewer", "TDSet contents should be of type TTree (or subtype)");
return;
}
fProofChain = new TProofChain(this, kTRUE);
TPluginHandler *h;
if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualTreeViewer"))) {
if (h->LoadPlugin() == -1)
return;
h->ExecPlugin(1,fProofChain);
}
}
TTree* TDSet::GetTreeHeader(TProof* proof)
{
return proof->GetTreeHeader(this);
}
Bool_t TDSet::ElementsValid() const
{
TIter nextElem(GetListOfElements());
while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
if (!elem->GetValid()) return kFALSE;
}
return kTRUE;
}
Int_t TDSet::Remove(TDSetElement *elem)
{
if (!elem || !(GetListOfElements()->Remove(elem)))
return -1;
SafeDelete(elem);
return 0;
}
void TDSet::Validate()
{
TIter nextElem(GetListOfElements());
while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
if (!elem->GetValid())
elem->Validate(IsTree());
}
}
void TDSet::Lookup()
{
TString msg("Looking up for exact location of files");
UInt_t n = 0;
UInt_t tot = GetListOfElements()->GetSize();
Bool_t st = kTRUE;
TIter nextElem(GetListOfElements());
while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
if (!elem->GetValid())
elem->Lookup();
n++;
if (gProof)
gProof->SendDataSetStatus(msg, n, tot, st);
}
}
void TDSet::SetLookedUp()
{
TIter nextElem(GetListOfElements());
while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem()))
elem->SetLookedUp();
}
void TDSet::Validate(TDSet* dset)
{
THashList bestElements;
bestElements.SetOwner();
TList namedHolder;
namedHolder.SetOwner();
TIter nextOtherElem(dset->GetListOfElements());
while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextOtherElem())) {
if (!elem->GetValid()) continue;
TString dir_file_obj = elem->GetDirectory();
dir_file_obj += "_";
dir_file_obj += elem->GetFileName();
dir_file_obj += "_";
dir_file_obj += elem->GetObjName();
TPair *p = dynamic_cast<TPair*>(bestElements.FindObject(dir_file_obj));
if (p) {
TDSetElement *prevelem = dynamic_cast<TDSetElement*>(p->Value());
Long64_t entries = prevelem->GetFirst()+prevelem->GetNum();
if (entries<elem->GetFirst()+elem->GetNum()) {
bestElements.Remove(p);
bestElements.Add(new TPair(p->Key(), elem));
delete p;
}
} else {
TNamed* named = new TNamed(dir_file_obj, dir_file_obj);
namedHolder.Add(named);
bestElements.Add(new TPair(named, elem));
}
}
TIter nextElem(GetListOfElements());
while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
if (!elem->GetValid()) {
TString dir_file_obj = elem->GetDirectory();
dir_file_obj += "_";
dir_file_obj += elem->GetFileName();
dir_file_obj += "_";
dir_file_obj += elem->GetObjName();
if (TPair *p = dynamic_cast<TPair*>(bestElements.FindObject(dir_file_obj))) {
TDSetElement* validelem = dynamic_cast<TDSetElement*>(p->Value());
elem->Validate(validelem);
}
}
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.