00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "TDSet.h"
00042
00043 #include "Riostream.h"
00044 #include "TChain.h"
00045 #include "TClass.h"
00046 #include "TClassTable.h"
00047 #include "TCut.h"
00048 #include "TDataSetManager.h"
00049 #include "TError.h"
00050 #include "TEntryList.h"
00051 #include "TEnv.h"
00052 #include "TEventList.h"
00053 #include "TFile.h"
00054 #include "TFileInfo.h"
00055 #include "TFileStager.h"
00056 #include "TFriendElement.h"
00057 #include "TKey.h"
00058 #include "THashList.h"
00059 #include "TMap.h"
00060 #include "TROOT.h"
00061 #include "TTimeStamp.h"
00062 #include "TTree.h"
00063 #include "TUrl.h"
00064 #include "TRegexp.h"
00065 #include "TVirtualPerfStats.h"
00066 #include "TProof.h"
00067 #include "TProofChain.h"
00068 #include "TProofServ.h"
00069 #include "TPluginManager.h"
00070 #include "TChain.h"
00071 #include "TChainElement.h"
00072 #include "TSystem.h"
00073 #include "THashList.h"
00074
00075 #include "TVirtualStreamerInfo.h"
00076 #include "TClassRef.h"
00077
00078 ClassImp(TDSetElement)
00079 ClassImp(TDSet)
00080
00081
00082 TDSetElement::TDSetElement() : TNamed("",""),
00083 fDirectory(), fFirst(0), fNum(0), fMsd(),
00084 fTDSetOffset(0), fEntryList(0), fValid(kFALSE),
00085 fEntries(0), fFriends(0), fDataSet(), fAssocObjList(0)
00086 {
00087
00088 ResetBit(kWriteV3);
00089 ResetBit(kHasBeenLookedUp);
00090 ResetBit(kEmpty);
00091 ResetBit(kCorrupted);
00092 ResetBit(kNewRun);
00093 ResetBit(kNewPacket);
00094 }
00095
00096
00097 TDSetElement::TDSetElement(const char *file, const char *objname, const char *dir,
00098 Long64_t first, Long64_t num,
00099 const char *msd, const char *dataset)
00100 : TNamed(file, objname)
00101 {
00102
00103
00104 if (first < 0) {
00105 Warning("TDSetElement", "first must be >= 0, %lld is not allowed - setting to 0", first);
00106 fFirst = 0;
00107 } else {
00108 fFirst = first;
00109 }
00110 if (num < -1) {
00111 Warning("TDSetElement", "num must be >= -1, %lld is not allowed - setting to -1", num);
00112 fNum = -1;
00113 } else {
00114 fNum = num;
00115 }
00116 fMsd = msd;
00117 fTDSetOffset = 0;
00118 fEntryList = 0;
00119 fFriends = 0;
00120 fValid = kFALSE;
00121 fEntries = -1;
00122 fDataSet = dataset;
00123 fAssocObjList = 0;
00124 if (dir)
00125 fDirectory = dir;
00126
00127 ResetBit(kWriteV3);
00128 ResetBit(kHasBeenLookedUp);
00129 ResetBit(kEmpty);
00130 ResetBit(kCorrupted);
00131 ResetBit(kNewRun);
00132 ResetBit(kNewPacket);
00133 }
00134
00135
00136 TDSetElement::TDSetElement(const TDSetElement& elem)
00137 : TNamed(elem.GetFileName(), elem.GetObjName())
00138 {
00139
00140 fDirectory = elem.GetDirectory();
00141 fFirst = elem.fFirst;
00142 fNum = elem.fNum;
00143 fMsd = elem.fMsd;
00144 fTDSetOffset = elem.fTDSetOffset;
00145 fEntryList = 0;
00146 fValid = elem.fValid;
00147 fEntries = elem.fEntries;
00148 fFriends = 0;
00149 fDataSet = elem.fDataSet;
00150 fAssocObjList = 0;
00151 ResetBit(kWriteV3);
00152 ResetBit(kHasBeenLookedUp);
00153 ResetBit(kEmpty);
00154 ResetBit(kCorrupted);
00155 ResetBit(kNewRun);
00156 ResetBit(kNewPacket);
00157 }
00158
00159
00160 TDSetElement::~TDSetElement()
00161 {
00162
00163 DeleteFriends();
00164 if (fAssocObjList) {
00165 fAssocObjList->SetOwner(kTRUE);
00166 SafeDelete(fAssocObjList);
00167 }
00168 }
00169
00170
00171 Int_t TDSetElement::MergeElement(TDSetElement *elem)
00172 {
00173
00174
00175
00176
00177
00178
00179
00180
00181 if (!elem) return -1;
00182
00183
00184 if (strcmp(GetName(), elem->GetName()) || strcmp(GetTitle(), elem->GetTitle()))
00185 return -1;
00186
00187 Int_t rc = -1;
00188
00189 if (fFirst == 0 && fNum == -1) {
00190
00191 rc = 1;
00192 } else if (elem->GetFirst() == 0 && elem->GetNum() == -1) {
00193
00194 fFirst = 0;
00195 fNum = -1;
00196 fEntries = elem->GetEntries();
00197 rc = 1;
00198 } else if (fFirst >= 0 && fNum > 0 && elem->GetFirst() >= 0 && elem->GetNum() > 0) {
00199 Long64_t last = fFirst + fNum - 1, lastref = 0;
00200 Long64_t lastelem = elem->GetFirst() + elem->GetNum() - 1;
00201 if (elem->GetFirst() == last + 1) {
00202 lastref = lastelem;
00203 rc = 0;
00204 } else if (fFirst == lastelem + 1) {
00205 fFirst += elem->GetFirst();
00206 lastref = last;
00207 rc = 0;
00208 } else if (elem->GetFirst() < last + 1 && elem->GetFirst() >= fFirst) {
00209 lastref = (lastelem > last) ? lastelem : last;
00210 rc = 1;
00211 } else if (fFirst < lastelem + 1 && fFirst >= elem->GetFirst()) {
00212 fFirst += elem->GetFirst();
00213 lastref = (lastelem > last) ? lastelem : last;
00214 rc = 1;
00215 }
00216 fNum = lastref - fFirst + 1;
00217 }
00218 if (rc >= 0 && fEntries < 0 && elem->GetEntries() > 0) fEntries = elem->GetEntries();
00219
00220
00221 return rc;
00222 }
00223
00224
00225 TFileInfo *TDSetElement::GetFileInfo(const char *type)
00226 {
00227
00228
00229
00230 TFileInfoMeta *meta = 0;
00231 if (!strcmp(type, "TTree")) {
00232 meta = new TFileInfoMeta(GetTitle(), "TTree", fEntries, fFirst,
00233 fFirst + fEntries - 1);
00234 } else {
00235 meta = new TFileInfoMeta(GetTitle(), fDirectory, type, fEntries, fFirst,
00236 fFirst + fEntries - 1);
00237 }
00238 return new TFileInfo(GetName(), 0, 0, 0, meta);
00239 }
00240
00241
00242 const char *TDSetElement::GetDirectory() const
00243 {
00244
00245
00246 return fDirectory;
00247 }
00248
00249
00250 void TDSetElement::Print(Option_t *opt) const
00251 {
00252
00253
00254 if (opt && opt[0] == 'a') {
00255 Printf("%s file=\"%s\" dir=\"%s\" obj=\"%s\" first=%lld num=%lld msd=\"%s\"",
00256 IsA()->GetName(), GetName(), fDirectory.Data(), GetTitle(),
00257 fFirst, fNum, fMsd.Data());
00258 } else {
00259 Printf("\tLFN: %s", GetName());
00260 }
00261 }
00262
00263
00264 void TDSetElement::Validate(Bool_t isTree)
00265 {
00266
00267
00268 Long64_t entries = GetEntries(isTree);
00269 if (entries < 0) return;
00270 if (fFirst < entries) {
00271 if (fNum == -1) {
00272 fNum = entries - fFirst;
00273 fValid = kTRUE;
00274 } else {
00275 if (fNum <= entries - fFirst) {
00276 fValid = kTRUE;
00277 } else {
00278 Error("Validate", "TDSetElement has only %lld entries starting"
00279 " with entry %lld, while %lld were requested",
00280 entries - fFirst, fFirst, fNum);
00281 }
00282 }
00283 } else {
00284 Error("Validate", "TDSetElement has only %lld entries with"
00285 " first entry requested as %lld", entries, fFirst);
00286 }
00287 }
00288
00289
00290 void TDSetElement::Validate(TDSetElement *elem)
00291 {
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 if (!elem || !elem->GetValid()) {
00306 Error("Validate", "TDSetElement to validate against is not valid");
00307 return;
00308 }
00309
00310 TString name = TUrl(GetFileName()).GetFileAndOptions();
00311 TString elemname = TUrl(elem->GetFileName()).GetFileAndOptions();
00312 if ((name == elemname) &&
00313 !strcmp(GetDirectory(), elem->GetDirectory()) &&
00314 !strcmp(GetObjName(), elem->GetObjName())) {
00315 Long64_t entries = elem->fFirst + elem->fNum;
00316 if (fFirst < entries) {
00317 if (fNum == -1) {
00318 fNum = entries - fFirst;
00319 fValid = kTRUE;
00320 } else {
00321 if (fNum <= entries - fFirst) {
00322 fValid = kTRUE;
00323 } else {
00324 Error("Validate", "TDSetElement requests %lld entries starting"
00325 " with entry %lld, while TDSetElement to validate against"
00326 " has only %lld entries", fNum, fFirst, entries);
00327 }
00328 }
00329 } else {
00330 Error("Validate", "TDSetElement to validate against has only %lld"
00331 " entries, but this TDSetElement requested %lld as its first"
00332 " entry", entries, fFirst);
00333 }
00334 } else {
00335 Error("Validate", "TDSetElements do not refer to same objects");
00336 }
00337 }
00338
00339
00340 Int_t TDSetElement::Compare(const TObject *obj) const
00341 {
00342
00343
00344 if (this == obj) return 0;
00345
00346 const TDSetElement *elem = dynamic_cast<const TDSetElement*>(obj);
00347 if (!elem) {
00348 if (obj)
00349 return (strncmp(GetName(),obj->GetName(),strlen(GetName()))) ? 1 : 0;
00350 return -1;
00351 }
00352
00353 Int_t order = strncmp(GetName(),elem->GetFileName(),strlen(GetName()));
00354 if (order == 0) {
00355 if (GetFirst() < elem->GetFirst())
00356 return -1;
00357 else if (GetFirst() > elem->GetFirst())
00358 return 1;
00359 return 0;
00360 }
00361 return order;
00362 }
00363
00364
00365 void TDSetElement::AddFriend(TDSetElement *friendElement, const char *alias)
00366 {
00367
00368
00369 if (!friendElement) {
00370 Error("AddFriend", "The friend TDSetElement is null!");
00371 return;
00372 }
00373 if (!fFriends) {
00374 fFriends = new TList();
00375 fFriends->SetOwner();
00376 }
00377
00378 if (alias && strlen(alias) > 0) {
00379 TUrl uf(friendElement->GetName());
00380 TString uo(uf.GetOptions());
00381 uo += TString::Format("friend_alias=%s|", alias);
00382 uf.SetOptions(uo);
00383 friendElement->SetName(uf.GetUrl());
00384 }
00385 fFriends->Add(new TDSetElement(*friendElement));
00386 }
00387
00388
00389 void TDSetElement::DeleteFriends()
00390 {
00391
00392 if (!fFriends)
00393 return;
00394
00395 fFriends->SetOwner(kTRUE);
00396 delete fFriends;
00397 fFriends = 0;
00398 }
00399
00400
00401 TDSetElement *TDSet::Next(Long64_t )
00402 {
00403
00404
00405 if (!fIterator) {
00406 fIterator = new TIter(fElements);
00407 }
00408
00409 fCurrent = (TDSetElement *) fIterator->Next();
00410 return fCurrent;
00411 }
00412
00413
00414 Long64_t TDSetElement::GetEntries(Bool_t isTree, Bool_t openfile)
00415 {
00416
00417
00418
00419
00420
00421 if (fEntries > -1 || !openfile)
00422 return fEntries;
00423
00424 Double_t start = 0;
00425 if (gPerfStats) start = TTimeStamp();
00426
00427
00428 TFile::EFileType typ = TFile::kDefault;
00429 TString fname = gEnv->GetValue("Path.Localroot",""), pfx(fname);
00430
00431 Int_t oldLevel = gErrorIgnoreLevel;
00432 gErrorIgnoreLevel = kError+1;
00433 if ((typ = TFile::GetType(GetName(), "", &fname)) != TFile::kLocal) fname = GetName();
00434 gErrorIgnoreLevel = oldLevel;
00435
00436 TFile *file = TFile::Open(fname);
00437
00438 if (gPerfStats)
00439 gPerfStats->FileOpenEvent(file, GetName(), start);
00440
00441 if (file == 0) {
00442 ::SysError("TDSetElement::GetEntries",
00443 "cannot open file %s (type: %d, pfx: %s)", GetName(), typ, pfx.Data());
00444 return -1;
00445 }
00446
00447
00448
00449 TUrl *eu = (TUrl *) file->GetEndpointUrl();
00450 eu->SetOptions(TUrl(fname).GetOptions());
00451 eu->SetAnchor(TUrl(fname).GetAnchor());
00452 if (strlen(eu->GetProtocol()) > 0 && strcmp(eu->GetProtocol(), "file"))
00453 fName = eu->GetUrl();
00454 else
00455 fName = eu->GetFileAndOptions();
00456 SetBit(kHasBeenLookedUp);
00457
00458 TDirectory *dirsave = gDirectory;
00459 if (!file->cd(fDirectory)) {
00460 Error("GetEntries", "cannot cd to %s", fDirectory.Data());
00461 delete file;
00462 return -1;
00463 }
00464
00465 TDirectory *dir = gDirectory;
00466 dirsave->cd();
00467
00468 if (isTree) {
00469
00470 TString on(GetTitle());
00471 TString sreg(GetTitle());
00472
00473
00474 if (sreg.Length() <= 0 || sreg == "" || sreg.Contains("*")) {
00475 if (sreg.Contains("*"))
00476 sreg.ReplaceAll("*", ".*");
00477 else
00478 sreg = ".*";
00479 TRegexp re(sreg);
00480 if (dir->GetListOfKeys()) {
00481 TIter nxk(dir->GetListOfKeys());
00482 TKey *k = 0;
00483 Bool_t notfound = kTRUE;
00484 while ((k = (TKey *) nxk())) {
00485 if (!strcmp(k->GetClassName(), "TTree")) {
00486 TString kn(k->GetName());
00487 if (kn.Index(re) != kNPOS) {
00488 if (notfound) {
00489 on = kn;
00490 notfound = kFALSE;
00491 } else if (kn != on) {
00492 Warning("GetEntries",
00493 "additional tree found in the file: %s", kn.Data());
00494 }
00495 }
00496 }
00497 }
00498 }
00499 }
00500
00501 TKey *key = dir->GetKey(on);
00502 if (key == 0) {
00503 Error("GetEntries", "cannot find tree \"%s\" in %s",
00504 GetTitle(), GetName());
00505 delete file;
00506 return -1;
00507 }
00508 TTree *tree = (TTree *) key->ReadObj();
00509 if (tree == 0) {
00510
00511 delete file;
00512 return -1;
00513 }
00514 fEntries = tree->GetEntries();
00515 delete tree;
00516
00517 } else {
00518 TList *keys = dir->GetListOfKeys();
00519 fEntries = keys->GetSize();
00520 }
00521
00522 delete file;
00523 return fEntries;
00524 }
00525
00526
00527 Int_t TDSetElement::Lookup(Bool_t force)
00528 {
00529
00530
00531 static Int_t xNetPluginOK = -1;
00532 static TFileStager *xStager = 0;
00533 Int_t retVal = 0;
00534
00535
00536 if (!force && HasBeenLookedUp())
00537 return retVal;
00538
00539 TUrl url(GetName());
00540
00541 TString anch = url.GetAnchor();
00542 TString opts = url.GetOptions();
00543
00544 TString name(url.GetUrl());
00545
00546
00547 Bool_t doit = kFALSE;
00548 TFile::EFileType type = TFile::GetType(name, "");
00549 if (type == TFile::kNet) {
00550 TPluginHandler *h = 0;
00551
00552 if (xNetPluginOK == -1) {
00553
00554 xNetPluginOK = 0;
00555 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
00556 !strcmp(h->GetClass(),"TXNetFile") && h->LoadPlugin() == 0)
00557 xNetPluginOK = 1;
00558 }
00559 doit = (xNetPluginOK == 1) ? kTRUE : kFALSE;
00560 }
00561
00562
00563 if (doit) {
00564 if (!xStager || !xStager->Matches(name)) {
00565 SafeDelete(xStager);
00566 if (!(xStager = TFileStager::Open(name))) {
00567 Error("Lookup", "TFileStager instance cannot be instantiated");
00568 retVal = -1;
00569 }
00570 }
00571 if (xStager && xStager->Locate(name.Data(), name) == 0) {
00572
00573 url.SetUrl(name);
00574
00575 url.SetOptions(opts);
00576 url.SetAnchor(anch);
00577
00578 fName = url.GetUrl();
00579 } else {
00580
00581 Error("Lookup", "couldn't lookup %s", name.Data());
00582 retVal = -1;
00583 }
00584 }
00585
00586
00587 SetBit(kHasBeenLookedUp);
00588 return retVal;
00589 }
00590
00591
00592 void TDSetElement::SetEntryList(TObject *aList, Long64_t first, Long64_t num)
00593 {
00594
00595
00596 if (!aList)
00597 return;
00598
00599
00600 TEventList *evl = 0;
00601 TEntryList *enl = dynamic_cast<TEntryList*>(aList);
00602 if (!enl)
00603 evl = dynamic_cast<TEventList*>(aList);
00604 if (!enl && !evl) {
00605 Error("SetEntryList", "type of input object must be either TEntryList "
00606 "or TEventList (found: '%s' - do nothing", aList->ClassName());
00607 return;
00608 }
00609
00610
00611 if (enl) {
00612 enl->SetEntriesToProcess(num);
00613 } else {
00614 for (; num > 0; num--, first++)
00615 evl->Enter(evl->GetEntry((Int_t)first));
00616 }
00617 fEntryList = aList;
00618
00619
00620 return;
00621 }
00622
00623
00624 void TDSetElement::AddAssocObj(TObject *assocobj)
00625 {
00626
00627 if (assocobj) {
00628 if (!fAssocObjList) fAssocObjList = new TList;
00629 if (fAssocObjList) fAssocObjList->Add(assocobj);
00630 }
00631 }
00632
00633
00634 TObject *TDSetElement::GetAssocObj(Long64_t i, Bool_t isentry)
00635 {
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 TObject *o = 0;
00646 if (!fAssocObjList || fAssocObjList->GetSize() <= 0) return o;
00647
00648 TString s;
00649 Int_t pos = -1;
00650 if (isentry) {
00651 if (i < fFirst) return o;
00652 s.Form("%lld", i - fFirst);
00653 } else {
00654 if (i < 0) return o;
00655 s.Form("%lld", i);
00656 }
00657 if (!(s.IsDigit())) return o;
00658 pos = s.Atoi();
00659 if (pos > fAssocObjList->GetSize() - 1) pos %= fAssocObjList->GetSize();
00660 return fAssocObjList->At(pos);
00661 }
00662
00663
00664 TDSet::TDSet()
00665 {
00666
00667
00668 fElements = new THashList;
00669 fElements->SetOwner();
00670 fIsTree = kFALSE;
00671 fIterator = 0;
00672 fCurrent = 0;
00673 fEntryList = 0;
00674 fProofChain = 0;
00675 fSrvMaps = 0;
00676 fSrvMapsIter = 0;
00677 ResetBit(kWriteV3);
00678 ResetBit(kEmpty);
00679 ResetBit(kValidityChecked);
00680 ResetBit(kSomeInvalid);
00681 ResetBit(kMultiDSet);
00682
00683
00684 gROOT->GetListOfDataSets()->Add(this);
00685 }
00686
00687
00688 TDSet::TDSet(const char *name,
00689 const char *objname, const char *dir, const char *type)
00690 {
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 fElements = new THashList;
00707 fElements->SetOwner();
00708 fIterator = 0;
00709 fCurrent = 0;
00710 fEntryList = 0;
00711 fProofChain = 0;
00712 fSrvMaps = 0;
00713 fSrvMapsIter = 0;
00714 ResetBit(kWriteV3);
00715 ResetBit(kEmpty);
00716 ResetBit(kValidityChecked);
00717 ResetBit(kSomeInvalid);
00718 ResetBit(kMultiDSet);
00719
00720 fType = "TTree";
00721 TClass *c = 0;
00722
00723 if (name && strlen(name) > 0) {
00724
00725 if (!type) {
00726 if (TClass::GetClass(name))
00727 fType = name;
00728 else
00729
00730 fName = name;
00731 } else {
00732
00733 fName = name;
00734
00735 if (strlen(type) > 0)
00736 if (TClass::GetClass(type))
00737 fType = type;
00738 }
00739 } else if (type && strlen(type) > 0) {
00740
00741 if (TClass::GetClass(type))
00742 fType = type;
00743 }
00744
00745 c = TClass::GetClass(fType);
00746
00747 fIsTree = (c->InheritsFrom(TTree::Class())) ? kTRUE : kFALSE;
00748
00749 if (objname)
00750 fObjName = objname;
00751
00752 if (dir)
00753 fDir = dir;
00754
00755
00756 if (fName.Length() <= 0)
00757 fName = fObjName;
00758
00759 fTitle = fType;
00760
00761
00762 gROOT->GetListOfDataSets()->Add(this);
00763 }
00764
00765
00766 TDSet::TDSet(const TChain &chain, Bool_t withfriends)
00767 {
00768
00769
00770
00771
00772
00773 fElements = new THashList;
00774 fElements->SetOwner();
00775 fIterator = 0;
00776 fCurrent = 0;
00777 fEntryList = 0;
00778 fProofChain = 0;
00779 fSrvMaps = 0;
00780 fSrvMapsIter = 0;
00781 ResetBit(kWriteV3);
00782 ResetBit(kEmpty);
00783 ResetBit(kValidityChecked);
00784 ResetBit(kSomeInvalid);
00785 ResetBit(kMultiDSet);
00786
00787 fType = "TTree";
00788 fIsTree = kTRUE;
00789 fObjName = chain.GetName();
00790
00791
00792 TIter next(chain.GetListOfFiles());
00793 TChainElement *elem = 0;
00794 TString key;
00795 while ((elem = (TChainElement *)next())) {
00796 TString file(elem->GetTitle());
00797 TString tree(elem->GetName());
00798 Int_t isl = tree.Index("/");
00799 TString dir = "/";
00800 if (isl >= 0) {
00801
00802 TString behindSlash = tree(isl + 1, tree.Length() - isl - 1);
00803
00804 tree.Remove(isl);
00805 dir = tree;
00806 tree = behindSlash;
00807 }
00808
00809 TString msd(TUrl(file).GetOptions());
00810 Int_t imsd = kNPOS;
00811 if ((imsd = msd.Index("msd=")) != kNPOS) {
00812 msd.Remove(0, imsd+4);
00813 } else {
00814
00815 msd = "";
00816 }
00817 Long64_t nent = (elem->GetEntries() > 0 &&
00818 elem->GetEntries() != TChain::kBigNumber) ? elem->GetEntries() : -1;
00819 if (Add(file, tree, dir, 0, nent, ((msd.IsNull()) ? 0 : msd.Data()))) {
00820 if (elem->HasBeenLookedUp()) {
00821
00822 TDSetElement *dse = (TDSetElement *) fElements->Last();
00823 if (dse) dse->SetLookedUp();
00824 }
00825 }
00826 }
00827 SetDirectory(0);
00828
00829
00830 if (withfriends) {
00831 TList processed;
00832 TList chainsQueue;
00833 chainsQueue.Add((TObject *)&chain);
00834 processed.Add((TObject *)&chain);
00835 while (chainsQueue.GetSize() > 0) {
00836 TChain *c = (TChain *) chainsQueue.First();
00837 chainsQueue.Remove(c);
00838 TIter friendsIter(c->GetListOfFriends());
00839 while(TFriendElement *fe = dynamic_cast<TFriendElement*> (friendsIter()) ) {
00840 if (TChain *fc = dynamic_cast<TChain*>(fe->GetTree())) {
00841 if (!processed.FindObject(fc)) {
00842 processed.AddFirst(fc);
00843 AddFriend(new TDSet((const TChain &)(*fc), kFALSE), fe->GetName());
00844 chainsQueue.Add(fc);
00845 }
00846 } else {
00847 Reset();
00848 Error("TDSet", "Only TChains supported. Found illegal tree %s",
00849 fe->GetTree()->GetName());
00850 return;
00851 }
00852 }
00853 }
00854 }
00855 }
00856
00857
00858 TDSet::~TDSet()
00859 {
00860
00861
00862 SafeDelete(fElements);
00863 SafeDelete(fIterator);
00864 SafeDelete(fProofChain);
00865 fSrvMaps = 0;
00866 fSrvMapsIter = 0;
00867
00868 gROOT->GetListOfDataSets()->Remove(this);
00869 }
00870
00871
00872 Long64_t TDSet::Process(const char *selector, Option_t *option, Long64_t nentries,
00873 Long64_t first, TObject *enl)
00874 {
00875
00876
00877
00878
00879
00880
00881 if (!IsValid() || !fElements->GetSize()) {
00882 Error("Process", "not a correctly initialized TDSet");
00883 return -1;
00884 }
00885
00886
00887 SetEntryList(enl);
00888
00889 if (gProof)
00890 return gProof->Process(this, selector, option, nentries, first);
00891
00892 Error("Process", "no active PROOF session");
00893 return -1;
00894 }
00895
00896
00897 void TDSet::AddInput(TObject *obj)
00898 {
00899
00900
00901
00902 if (gProof) {
00903 gProof->AddInput(obj);
00904 } else {
00905 Error("AddInput","No PROOF session active");
00906 }
00907 }
00908
00909
00910 void TDSet::ClearInput()
00911 {
00912
00913
00914 if (gProof)
00915 gProof->ClearInput();
00916 }
00917
00918
00919 TObject *TDSet::GetOutput(const char *name)
00920 {
00921
00922
00923
00924 if (gProof)
00925 return gProof->GetOutput(name);
00926 return 0;
00927 }
00928
00929
00930 TList *TDSet::GetOutputList()
00931 {
00932
00933
00934 if (gProof)
00935 return gProof->GetOutputList();
00936 return 0;
00937 }
00938
00939
00940 void TDSet::Print(const Option_t *opt) const
00941 {
00942
00943
00944 Printf("OBJ: %s\ttype %s\t%s\tin %s\telements %d", IsA()->GetName(), GetName(),
00945 fObjName.Data(), GetTitle(), GetListOfElements()->GetSize());
00946
00947 if (opt && opt[0] == 'a') {
00948 TIter next(GetListOfElements());
00949 TObject *obj;
00950 while ((obj = next())) {
00951 obj->Print(opt);
00952 }
00953 }
00954 }
00955
00956
00957 void TDSet::SetObjName(const char *objname)
00958 {
00959
00960
00961 if (objname)
00962 fObjName = objname;
00963 }
00964
00965
00966 void TDSet::SetDirectory(const char *dir)
00967 {
00968
00969
00970 if (dir)
00971 fDir = dir;
00972 }
00973
00974
00975 Bool_t TDSet::Add(const char *file, const char *objname, const char *dir,
00976 Long64_t first, Long64_t num, const char *msd)
00977 {
00978
00979
00980
00981
00982 if (!file || !*file) {
00983 Error("Add", "file name must be specified");
00984 return kFALSE;
00985 }
00986
00987 TString fn = file;
00988 if (gProof && gProof->IsLite()) {
00989 TUrl u(file, kTRUE);
00990 if (!strcmp(u.GetProtocol(), "file")) {
00991 fn = u.GetFile();
00992 gSystem->ExpandPathName(fn);
00993 if (!gSystem->IsAbsoluteFileName(fn))
00994 gSystem->PrependPathName(gSystem->WorkingDirectory(), fn);
00995 }
00996 }
00997
00998
00999 TDSetElement *el = (TDSetElement *) fElements->FindObject(fn);
01000 if (!el) {
01001 if (!objname)
01002 objname = GetObjName();
01003 if (!dir)
01004 dir = GetDirectory();
01005 fElements->Add(new TDSetElement(fn, objname, dir, first, num, msd));
01006 } else {
01007 TString msg;
01008 msg.Form("duplication detected: %40s is already in dataset - ignored", fn.Data());
01009 Warning("Add", "%s", msg.Data());
01010 if (gProofServ) {
01011 msg.Insert(0, "WARNING: ");
01012 gProofServ->SendAsynMessage(msg);
01013 }
01014 }
01015
01016 return kTRUE;
01017 }
01018
01019
01020 Bool_t TDSet::Add(TDSet *dset)
01021 {
01022
01023
01024 if (!dset)
01025 return kFALSE;
01026
01027 if (TestBit(TDSet::kMultiDSet)) {
01028 fElements->Add(dset);
01029 return kTRUE;
01030 }
01031
01032 if (fType != dset->GetType()) {
01033 Error("Add", "cannot add a set with a different type");
01034 return kFALSE;
01035 }
01036
01037 TDSetElement *el;
01038 TIter next(dset->fElements);
01039 TObject *last = (dset == this) ? fElements->Last() : 0;
01040 while ((el = (TDSetElement*) next())) {
01041 Add(el->GetFileName(), el->GetObjName(), el->GetDirectory(),
01042 el->GetFirst(), el->GetNum(), el->GetMsd());
01043 if (el == last) break;
01044 }
01045
01046 return kTRUE;
01047 }
01048
01049
01050 Bool_t TDSet::Add(TCollection *filelist, const char *meta, Bool_t availableOnly,
01051 TCollection *badlist)
01052 {
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 if (!filelist)
01063 return kFALSE;
01064
01065 TObject *o = 0;
01066 TIter next(filelist);
01067 while ((o = next())) {
01068 TString cn(o->ClassName());
01069 if (cn == "TFileInfo") {
01070 TFileInfo *fi = (TFileInfo *)o;
01071 if (!availableOnly ||
01072 (fi->TestBit(TFileInfo::kStaged) &&
01073 !fi->TestBit(TFileInfo::kCorrupted))) {
01074 Int_t nf = fElements->GetSize();
01075 if (!Add(fi, meta)) return kFALSE;
01076
01077 if (fElements->GetSize() <= nf) badlist->Add(fi);
01078 } else if (badlist) {
01079
01080 badlist->Add(fi);
01081 }
01082 } else if (cn == "TUrl") {
01083 Add(((TUrl *)o)->GetUrl());
01084 } else if (cn == "TObjString") {
01085 Add(((TObjString *)o)->GetName());
01086 } else {
01087 Warning("Add","found object fo unexpected type %s - ignoring", cn.Data());
01088 }
01089 }
01090
01091 return kTRUE;
01092 }
01093
01094
01095 void TDSet::SetSrvMaps(TList *srvmaps)
01096 {
01097
01098
01099
01100
01101 fSrvMaps = srvmaps;
01102 SafeDelete(fSrvMapsIter);
01103 if (fSrvMaps) fSrvMapsIter = new TIter(fSrvMaps);
01104 }
01105
01106
01107 Bool_t TDSet::Add(TFileInfo *fi, const char *meta)
01108 {
01109
01110
01111
01112
01113
01114 if (!fi) {
01115 Error("Add", "TFileInfo object name must be specified");
01116 return kFALSE;
01117 }
01118 TString msg;
01119
01120
01121 const char *file = fi->GetFirstUrl()->GetUrl();
01122 Bool_t setLookedUp = kTRUE;
01123 TString file1;
01124 if (TDataSetManager::CheckDataSetSrvMaps(fi->GetFirstUrl(), file1, fSrvMaps) &&
01125 !(file1.IsNull())) {
01126 file = file1.Data();
01127 setLookedUp = kFALSE;
01128 }
01129
01130 if (fElements->FindObject(file)) {
01131 msg.Form("duplication detected: %40s is already in dataset - ignored", file);
01132 Warning("Add", "%s", msg.Data());
01133 if (gProofServ) {
01134 msg.Insert(0, "WARNING: ");
01135 gProofServ->SendAsynMessage(msg);
01136 }
01137 return kTRUE;
01138 }
01139
01140
01141
01142
01143 TFileInfoMeta *m = 0;
01144 if (!meta || strlen(meta) <= 0 || !strcmp(meta, "/")) {
01145 TList *fil = 0;
01146 if ((fil = fi->GetMetaDataList()) && fil->GetSize() > 1) {
01147 msg.Form("\n Object name unspecified and several objects available.\n");
01148 msg += " Please choose one from the list below:\n";
01149 TIter nx(fil);
01150 while ((m = (TFileInfoMeta *) nx())) {
01151 TString nm(m->GetName());
01152 if (nm.BeginsWith("/")) nm.Remove(0,1);
01153 msg += Form(" %s -> TProof::Process(\"%s#%s\",...)\n",
01154 nm.Data(), GetName(), nm.Data());
01155 }
01156 if (gProofServ)
01157 gProofServ->SendAsynMessage(msg);
01158 else
01159 Warning("Add", "%s", msg.Data());
01160 return kFALSE;
01161 }
01162 }
01163
01164
01165 m = fi->GetMetaData(meta);
01166
01167
01168 const char *objname = 0;
01169 const char *dir = 0;
01170 Long64_t first = 0;
01171 Long64_t num = -1;
01172 if (!m) {
01173 objname = GetObjName();
01174 dir = GetDirectory();
01175 } else {
01176 objname = (m->GetObject() && strlen(m->GetObject())) ? m->GetObject() : GetObjName();
01177 dir = (m->GetDirectory() && strlen(m->GetDirectory())) ? m->GetDirectory() : GetDirectory();
01178 first = m->GetFirst();
01179 num = m->GetEntries();
01180 }
01181 const char *dataset = 0;
01182 if (strcmp(fi->GetTitle(), "TFileInfo")) dataset = fi->GetTitle();
01183 TDSetElement *el = new TDSetElement(file, objname, dir, first, -1, 0, dataset);
01184 el->SetEntries(num);
01185
01186
01187 if (fi->TestBit(TFileInfo::kStaged) && setLookedUp)
01188 el->SetBit(TDSetElement::kHasBeenLookedUp);
01189 if (fi->TestBit(TFileInfo::kCorrupted))
01190 el->SetBit(TDSetElement::kCorrupted);
01191
01192
01193 fElements->Add(el);
01194
01195 return kTRUE;
01196 }
01197
01198
01199 Int_t TDSet::ExportFileList(const char *fpath, Option_t *opt)
01200 {
01201
01202
01203
01204
01205
01206 if (!fElements)
01207 return -1;
01208 if (fElements->GetSize() <= 0)
01209 return 0;
01210
01211 Bool_t force = (opt[0] == 'F' || opt[0] == 'f');
01212
01213 if (gSystem->AccessPathName(fpath, kFileExists) == kFALSE) {
01214 if (force) {
01215
01216 if (gSystem->Unlink(fpath)) {
01217 Info("ExportFileList","error removing dataset file: %s", fpath);
01218 return -1;
01219 }
01220 }
01221 }
01222
01223
01224 TList *fileinfo = new TList;
01225 fileinfo->SetOwner();
01226
01227 TDSetElement *dse = 0;
01228 TIter next(fElements);
01229 while ((dse = (TDSetElement *) next())) {
01230 TFileInfoMeta *m = new TFileInfoMeta(dse->GetTitle(), dse->GetDirectory(), GetType(),
01231 dse->GetNum(), dse->GetFirst());
01232 TFileInfo *fi = new TFileInfo(dse->GetFileName());
01233 fi->AddMetaData(m);
01234 fileinfo->Add(fi);
01235 }
01236
01237
01238 TFile *f = TFile::Open(fpath, "RECREATE");
01239 if (f) {
01240 f->cd();
01241 fileinfo->Write("fileList", TObject::kSingleKey);
01242 f->Close();
01243 } else {
01244 Info("ExportFileList","error creating dataset file: %s", fpath);
01245 SafeDelete(fileinfo);
01246 return -1;
01247 }
01248
01249
01250 SafeDelete(f);
01251 SafeDelete(fileinfo);
01252
01253
01254 return 0;
01255 }
01256
01257
01258 void TDSet::AddFriend(TDSet *friendset, const char* alias)
01259 {
01260
01261
01262
01263
01264 if (!friendset) {
01265 Error("AddFriend", "The friend TDSet is null!");
01266 return;
01267 }
01268
01269 if (!fIsTree) {
01270 Error("AddFriend", "a friend set can only be added to a TTree TDSet");
01271 return;
01272 }
01273 TList *thisList = GetListOfElements();
01274 TList *friendsList = friendset->GetListOfElements();
01275 if (thisList->GetSize() != friendsList->GetSize() && friendsList->GetSize() != 1) {
01276 Error("AddFriend", "the friend dataset has %d elements while the main one has %d",
01277 thisList->GetSize(), friendsList->GetSize());
01278 return;
01279 }
01280 TIter next(thisList);
01281 TIter next2(friendsList);
01282 TDSetElement *friendElem = 0;
01283 if (friendsList->GetSize() == 1)
01284 friendElem = dynamic_cast<TDSetElement*> (friendsList->First());
01285 while(TDSetElement* e = dynamic_cast<TDSetElement*> (next())) {
01286 if (friendElem)
01287 e->AddFriend(friendElem, alias);
01288 else
01289 e->AddFriend(dynamic_cast<TDSetElement*> (next2()), alias);
01290 }
01291 }
01292
01293
01294 void TDSet::Reset()
01295 {
01296
01297
01298 if (!fIterator) {
01299 fIterator = new TIter(fElements);
01300 } else {
01301 fIterator->Reset();
01302 }
01303 }
01304
01305
01306 Long64_t TDSet::GetEntries(Bool_t isTree, const char *filename, const char *path,
01307 TString &objname)
01308 {
01309
01310
01311
01312 Double_t start = 0;
01313 if (gPerfStats) start = TTimeStamp();
01314
01315
01316 TFile::EFileType typ = TFile::kDefault;
01317 TString fname = gEnv->GetValue("Path.Localroot",""), pfx(fname);
01318
01319 Int_t oldLevel = gErrorIgnoreLevel;
01320 gErrorIgnoreLevel = kError+1;
01321 if ((typ = TFile::GetType(filename, "", &fname)) != TFile::kLocal) fname = filename;
01322 gErrorIgnoreLevel = oldLevel;
01323
01324 TFile *file = TFile::Open(fname);
01325
01326 if (gPerfStats)
01327 gPerfStats->FileOpenEvent(file, filename, start);
01328
01329 if (file == 0) {
01330 ::SysError("TDSet::GetEntries",
01331 "cannot open file %s (type: %d, pfx: %s)", filename, typ, pfx.Data());
01332 return -1;
01333 }
01334
01335 TDirectory *dirsave = gDirectory;
01336 if (!file->cd(path)) {
01337 ::Error("TDSet::GetEntries", "cannot cd to %s", path);
01338 delete file;
01339 return -1;
01340 }
01341
01342 TDirectory *dir = gDirectory;
01343 dirsave->cd();
01344
01345 Long64_t entries;
01346 Bool_t fillname = kFALSE;
01347 if (isTree) {
01348
01349 TString on(objname);
01350 TString sreg(objname);
01351
01352
01353 if (sreg.Length() <= 0 || sreg == "" || sreg.Contains("*")) {
01354 fillname = kTRUE;
01355 if (sreg.Contains("*"))
01356 sreg.ReplaceAll("*", ".*");
01357 else
01358 sreg = ".*";
01359 TRegexp re(sreg);
01360 if (dir->GetListOfKeys()) {
01361 TIter nxk(dir->GetListOfKeys());
01362 TKey *k = 0;
01363 Bool_t notfound = kTRUE;
01364 while ((k = (TKey *) nxk())) {
01365 if (!strcmp(k->GetClassName(), "TTree")) {
01366 TString kn(k->GetName());
01367 if (kn.Index(re) != kNPOS) {
01368 if (notfound) {
01369 on = kn;
01370 notfound = kFALSE;
01371 } else if (kn != on) {
01372 ::Warning("TDSet::GetEntries",
01373 "additional tree found in the file: %s", kn.Data());
01374 }
01375 }
01376 }
01377 }
01378 }
01379 }
01380
01381 TKey *key = dir->GetKey(on);
01382 if (key == 0) {
01383 ::Error("TDSet::GetEntries", "cannot find tree \"%s\" in %s",
01384 objname.Data(), filename);
01385 delete file;
01386 return -1;
01387 }
01388 TTree *tree = (TTree *) key->ReadObj();
01389 if (tree == 0) {
01390
01391 delete file;
01392 return -1;
01393 }
01394 entries = tree->GetEntries();
01395 delete tree;
01396
01397
01398 objname = (fillname) ? on : objname;
01399
01400 } else {
01401 TList *keys = dir->GetListOfKeys();
01402 entries = keys->GetSize();
01403 }
01404
01405 delete file;
01406 return entries;
01407 }
01408
01409
01410 Long64_t TDSet::Draw(const char *varexp, const TCut &selection, Option_t *option,
01411 Long64_t nentries, Long64_t firstentry)
01412 {
01413
01414
01415
01416
01417
01418
01419
01420 return Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
01421 }
01422
01423
01424 Long64_t TDSet::Draw(const char *varexp, const char *selection, Option_t *option,
01425 Long64_t nentries, Long64_t firstentry)
01426 {
01427
01428
01429
01430
01431 if (!IsValid() || !fElements->GetSize()) {
01432 Error("Draw", "not a correctly initialized TDSet");
01433 return -1;
01434 }
01435
01436 if (gProof)
01437 return gProof->DrawSelect(this, varexp, selection, option, nentries,
01438 firstentry);
01439
01440 Error("Draw", "no active PROOF session");
01441 return -1;
01442 }
01443
01444
01445 void TDSet::StartViewer()
01446 {
01447
01448
01449 if (gROOT->IsBatch()) {
01450 Warning("StartViewer", "viewer cannot run in batch mode");
01451 return;
01452 }
01453
01454 if (!gProof) {
01455 Error("StartViewer", "no PROOF found");
01456 return;
01457 }
01458 if (!IsTree()) {
01459 Error("StartViewer", "TDSet contents should be of type TTree (or subtype)");
01460 return;
01461 }
01462 fProofChain = new TProofChain(this, kTRUE);
01463
01464 TPluginHandler *h;
01465 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualTreeViewer"))) {
01466 if (h->LoadPlugin() == -1)
01467 return;
01468 h->ExecPlugin(1,fProofChain);
01469 }
01470 }
01471
01472
01473 TTree* TDSet::GetTreeHeader(TProof* proof)
01474 {
01475
01476
01477 return proof->GetTreeHeader(this);
01478 }
01479
01480
01481 Bool_t TDSet::ElementsValid()
01482 {
01483
01484
01485 if (TestBit(TDSet::kValidityChecked))
01486 return (TestBit(TDSet::kSomeInvalid) ? kFALSE : kTRUE);
01487
01488 SetBit(TDSet::kValidityChecked);
01489 ResetBit(TDSet::kSomeInvalid);
01490 TIter nextElem(GetListOfElements());
01491 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
01492 if (!elem->GetValid()) {
01493 SetBit(TDSet::kSomeInvalid);
01494 return kFALSE;
01495 }
01496 }
01497 return kTRUE;
01498 }
01499
01500
01501 Int_t TDSet::Remove(TDSetElement *elem, Bool_t deleteElem)
01502 {
01503
01504
01505
01506 if (!elem || !(((THashList *)(GetListOfElements()))->Remove(elem)))
01507 return -1;
01508
01509 if (deleteElem)
01510 SafeDelete(elem);
01511 return 0;
01512 }
01513
01514
01515 void TDSet::Validate()
01516 {
01517
01518
01519 TIter nextElem(GetListOfElements());
01520 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
01521 if (!elem->GetValid())
01522 elem->Validate(IsTree());
01523 }
01524 }
01525
01526
01527 void TDSet::Lookup(Bool_t removeMissing, TList **listOfMissingFiles)
01528 {
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539 SplitEntryList();
01540
01541 TString msg("Looking up for exact location of files");
01542 UInt_t n = 0;
01543 UInt_t ng = 0;
01544 UInt_t tot = GetListOfElements()->GetSize();
01545 UInt_t n2 = (tot > 50) ? (UInt_t) tot / 50 : 1;
01546 Bool_t st = kTRUE;
01547 TIter nextElem(GetListOfElements());
01548 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
01549 if (elem->GetNum() != 0) {
01550 ng++;
01551 if (!elem->GetValid())
01552 if (elem->Lookup(kFALSE))
01553 if (removeMissing) {
01554 if (Remove(elem, kFALSE))
01555 Error("Lookup", "Error removing a missing file");
01556 if (listOfMissingFiles)
01557 (*listOfMissingFiles)->Add(elem->GetFileInfo(fType));
01558 }
01559 }
01560 n++;
01561
01562 if (gProof && (n > 0 && !(n % n2)))
01563 gProof->SendDataSetStatus(msg, n, tot, st);
01564
01565 if (gProof && gProof->GetRunStatus() != TProof::kRunning)
01566 break;
01567 }
01568
01569
01570 if (ng < tot && gProofServ) {
01571 msg = Form("Files with entries to be processed: %d (out of %d)\n", ng, tot);
01572 gProofServ->SendAsynMessage(msg);
01573 } else {
01574
01575 if (gProof) gProof->SendDataSetStatus(msg, n, tot, st);
01576 }
01577
01578 return;
01579 }
01580
01581
01582 void TDSet::SetLookedUp()
01583 {
01584
01585
01586
01587 TIter nextElem(GetListOfElements());
01588 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem()))
01589 elem->SetLookedUp();
01590 }
01591
01592
01593 void TDSet::Validate(TDSet* dset)
01594 {
01595
01596
01597
01598 THashList bestElements;
01599 bestElements.SetOwner();
01600 TList namedHolder;
01601 namedHolder.SetOwner();
01602 TIter nextOtherElem(dset->GetListOfElements());
01603 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextOtherElem())) {
01604 if (!elem->GetValid()) continue;
01605 TString dir_file_obj = elem->GetDirectory();
01606 dir_file_obj += "_";
01607 dir_file_obj += TUrl(elem->GetFileName()).GetFileAndOptions();
01608 dir_file_obj += "_";
01609 dir_file_obj += elem->GetObjName();
01610 TPair *p = dynamic_cast<TPair*>(bestElements.FindObject(dir_file_obj));
01611 if (p) {
01612 TDSetElement *prevelem = dynamic_cast<TDSetElement*>(p->Value());
01613 if (prevelem) {
01614 Long64_t entries = prevelem->GetFirst()+prevelem->GetNum();
01615 if (entries<elem->GetFirst()+elem->GetNum()) {
01616 bestElements.Remove(p);
01617 bestElements.Add(new TPair(p->Key(), elem));
01618 delete p;
01619 }
01620 }
01621 } else {
01622 TNamed* named = new TNamed(dir_file_obj, dir_file_obj);
01623 namedHolder.Add(named);
01624 bestElements.Add(new TPair(named, elem));
01625 }
01626 }
01627
01628 TIter nextElem(GetListOfElements());
01629 while (TDSetElement *elem = dynamic_cast<TDSetElement*>(nextElem())) {
01630 if (!elem->GetValid()) {
01631 TString dir_file_obj = elem->GetDirectory();
01632 dir_file_obj += "_";
01633 dir_file_obj += TUrl(elem->GetFileName()).GetFileAndOptions();
01634 dir_file_obj += "_";
01635 dir_file_obj += elem->GetObjName();
01636 if (TPair *p = dynamic_cast<TPair*>(bestElements.FindObject(dir_file_obj))) {
01637 TDSetElement* validelem = dynamic_cast<TDSetElement*>(p->Value());
01638 elem->Validate(validelem);
01639 }
01640 }
01641 }
01642 }
01643
01644
01645
01646
01647
01648 void TDSetElement::Streamer(TBuffer &R__b)
01649 {
01650
01651
01652 if (R__b.IsReading()) {
01653 UInt_t R__s, R__c;
01654 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01655 ResetBit(kWriteV3);
01656 if (R__v > 4) {
01657 R__b.ReadClassBuffer(TDSetElement::Class(), this, R__v, R__s, R__c);
01658 } else {
01659
01660 SetBit(kWriteV3);
01661 if (R__v > 3) {
01662 TNamed::Streamer(R__b);
01663 } else {
01664
01665
01666 TObject::Streamer(R__b);
01667 TString name, title;
01668 R__b >> name >> title;
01669 SetNameTitle(name, title);
01670 }
01671
01672 R__b >> fDirectory;
01673 R__b >> fFirst;
01674 R__b >> fNum;
01675 R__b >> fMsd;
01676 R__b >> fTDSetOffset;
01677 TEventList *evl;
01678 R__b >> evl;
01679 R__b >> fValid;
01680 R__b >> fEntries;
01681
01682
01683 FriendsList_t *friends = new FriendsList_t;
01684 static TClassRef classFriendsList = TClass::GetClass(typeid(FriendsList_t));
01685 R__b.ReadClassBuffer( classFriendsList, friends, classFriendsList->GetClassVersion(), 0, 0);
01686 if (friends) {
01687
01688 fFriends = new TList();
01689 fFriends->SetOwner();
01690 for (FriendsList_t::iterator i = friends->begin();
01691 i != friends->end(); ++i) {
01692 TDSetElement *dse = (TDSetElement *) i->first->Clone();
01693 fFriends->Add(new TPair(dse, new TObjString(i->second.Data())));
01694 }
01695 }
01696
01697 Bool_t tmpIsTree;
01698 R__b >> tmpIsTree;
01699 R__b.CheckByteCount(R__s, R__c, TDSetElement::IsA());
01700 }
01701 } else {
01702 if (TestBit(kWriteV3)) {
01703
01704 R__b << Version_t(3);
01705 TObject::Streamer(R__b);
01706 R__b << TString(GetName());
01707 R__b << TString(GetTitle());
01708 R__b << fDirectory;
01709 R__b << fFirst;
01710 R__b << fNum;
01711 R__b << fMsd;
01712 R__b << fTDSetOffset;
01713 R__b << (TEventList *)0;
01714 R__b << fValid;
01715 R__b << fEntries;
01716
01717
01718 FriendsList_t *friends = new FriendsList_t;
01719 if (fFriends) {
01720 TIter nxf(fFriends);
01721 TPair *p = 0;
01722 while ((p = (TPair *)nxf()))
01723 friends->push_back(std::make_pair((TDSetElement *)p->Key(),
01724 TString(((TObjString *)p->Value())->GetName())));
01725 }
01726 static TClassRef classFriendsList = TClass::GetClass(typeid(FriendsList_t));
01727 R__b.WriteClassBuffer( classFriendsList, &friends );
01728
01729
01730
01731 R__b << kFALSE;
01732 } else {
01733 R__b.WriteClassBuffer(TDSetElement::Class(),this);
01734 }
01735 }
01736 }
01737
01738
01739 void TDSet::Streamer(TBuffer &R__b)
01740 {
01741
01742
01743 if (R__b.IsReading()) {
01744 UInt_t R__s, R__c;
01745 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01746 ResetBit(kWriteV3);
01747 if (R__v > 3) {
01748 R__b.ReadClassBuffer(TDSet::Class(), this, R__v, R__s, R__c);
01749 } else {
01750
01751 SetBit(kWriteV3);
01752 TNamed::Streamer(R__b);
01753 R__b >> fDir;
01754 R__b >> fType;
01755 R__b >> fObjName;
01756 TList elems;
01757 elems.Streamer(R__b);
01758 elems.SetOwner(kFALSE);
01759 if (elems.GetSize() > 0) {
01760 fElements = new THashList;
01761 fElements->SetOwner();
01762 TDSetElement *e = 0;
01763 TIter nxe(&elems);
01764 while ((e = (TDSetElement *)nxe())) {
01765 fElements->Add(e);
01766 }
01767 } else {
01768 fElements = 0;
01769 }
01770 R__b >> fIsTree;
01771 }
01772 } else {
01773 if (TestBit(kWriteV3)) {
01774
01775 R__b << Version_t(3);
01776 TNamed::Streamer(R__b);
01777 R__b << fDir;
01778 R__b << fType;
01779 R__b << fObjName;
01780 TList elems;
01781 if (fElements) {
01782 elems.SetOwner(kFALSE);
01783 if (fElements->GetSize() > 0) {
01784 TDSetElement *e = 0;
01785 TIter nxe(fElements);
01786 while ((e = (TDSetElement *)nxe()))
01787 elems.Add(e);
01788 }
01789 }
01790 elems.Streamer(R__b);
01791 R__b << fIsTree;
01792 } else {
01793 R__b.WriteClassBuffer(TDSet::Class(),this);
01794 }
01795 }
01796 }
01797
01798
01799 void TDSet::SetWriteV3(Bool_t on)
01800 {
01801
01802
01803
01804 if (on)
01805 SetBit(TDSet::kWriteV3);
01806 else
01807 ResetBit(TDSet::kWriteV3);
01808
01809 TIter nxe(GetListOfElements());
01810 TObject *o = 0;
01811 while ((o = nxe()))
01812 if (on)
01813 o->SetBit(TDSetElement::kWriteV3);
01814 else
01815 o->ResetBit(TDSetElement::kWriteV3);
01816 }
01817
01818
01819 void TDSet::SetEntryList(TObject *aList)
01820 {
01821
01822
01823 if (!aList)
01824 return;
01825
01826 if (TestBit(TDSet::kMultiDSet)) {
01827
01828
01829 TIter nxds(fElements);
01830 TDSet *ds = 0;
01831 while ((ds = (TDSet *) nxds()))
01832 ds->SetEntryList(aList);
01833
01834 } else {
01835
01836
01837 TEventList *evl = 0;
01838 TEntryList *enl = dynamic_cast<TEntryList*>(aList);
01839 if (!enl)
01840 evl = dynamic_cast<TEventList*>(aList);
01841 if (!enl && !evl) {
01842 Error("SetEntryList", "type of input object must be either TEntryList "
01843 "or TEventList (found: '%s' - do nothing", aList->ClassName());
01844 return;
01845 }
01846
01847
01848 fEntryList = (enl) ? enl : (TEntryList *)evl;
01849 }
01850
01851 return;
01852 }
01853
01854
01855 void TDSet::SplitEntryList()
01856 {
01857
01858
01859
01860 if (TestBit(TDSet::kMultiDSet)) {
01861
01862 TIter nxds(fElements);
01863 TDSet *ds = 0;
01864 while ((ds = (TDSet *) nxds()))
01865 ds->SplitEntryList();
01866
01867 return;
01868 }
01869
01870 if (!fEntryList) {
01871 if (gDebug > 0)
01872 Info("SplitEntryList", "no entry- (or event-) list to split - do nothing");
01873 return;
01874 }
01875
01876
01877 TEntryList *enl = dynamic_cast<TEntryList *>(fEntryList);
01878 if (enl) {
01879
01880 TIter next(fElements);
01881 TDSetElement *el=0;
01882 TEntryList *sublist = 0;
01883 while ((el=(TDSetElement*)next())){
01884 sublist = enl->GetEntryList(el->GetObjName(), el->GetFileName());
01885 if (sublist){
01886 el->SetEntryList(sublist);
01887 el->SetNum(sublist->GetN());
01888 } else {
01889 sublist = new TEntryList("", "");
01890 el->SetEntryList(sublist);
01891 el->SetNum(0);
01892 }
01893 }
01894 } else {
01895 TEventList *evl = dynamic_cast<TEventList *>(fEntryList);
01896 if (evl) {
01897
01898 TIter next(fElements);
01899 TDSetElement *el, *prev;
01900
01901 prev = dynamic_cast<TDSetElement*> (next());
01902 if (!prev)
01903 return;
01904 Long64_t low = prev->GetTDSetOffset();
01905 Long64_t high = low;
01906 Long64_t currPos = 0;
01907 do {
01908 el = dynamic_cast<TDSetElement*> (next());
01909
01910 high = (el == 0) ? kMaxLong64 : el->GetTDSetOffset();
01911 #ifdef DEBUG
01912 while (currPos < evl->GetN() && evl->GetEntry(currPos) < low) {
01913 Error("SplitEntryList",
01914 "TEventList: event outside of the range of any of the TDSetElements");
01915 currPos++;
01916 }
01917 #endif
01918 TEventList* nevl = new TEventList();
01919 while (currPos < evl->GetN() && evl->GetEntry((Int_t)currPos) < high) {
01920 nevl->Enter(evl->GetEntry((Int_t)currPos) - low);
01921 currPos++;
01922 }
01923 prev->SetEntryList(nevl);
01924 prev->SetNum(nevl->GetN());
01925 low = high;
01926 prev = el;
01927 } while (el);
01928 }
01929 }
01930 }
01931
01932
01933 Int_t TDSet::GetNumOfFiles()
01934 {
01935
01936
01937 Int_t nf = -1;
01938 if (fElements) {
01939 nf = 0;
01940 if (TestBit(TDSet::kMultiDSet)) {
01941 TIter nxds(fElements);
01942 TDSet *ds = 0;
01943 while ((ds = (TDSet *) nxds()))
01944 if (ds->GetListOfElements()) nf += ds->GetListOfElements()->GetSize();
01945 } else {
01946 nf = fElements->GetSize();
01947 }
01948 }
01949
01950 return nf;
01951 }