70 , fCanDeleteRefs(kFALSE)
77 fTreeOffset =
new Long64_t[fTreeOffsetLen];
78 fFiles =
new TObjArray(fTreeOffsetLen);
79 fStatus =
new TList();
81 if (gDirectory) gDirectory->Remove(
this);
82 gROOT->GetListOfSpecials()->Add(
this);
87 ResetBit(kProofUptodate);
91 gROOT->GetListOfDataSets()->Add(
this);
94 R__LOCKGUARD(gROOTMutex);
95 gROOT->GetListOfCleanups()->Add(
this);
138 TChain::TChain(
const char* name,
const char* title)
139 :TTree(name, title, 99, nullptr)
140 , fTreeOffsetLen(100)
144 , fCanDeleteRefs(kFALSE)
154 fTreeOffset =
new Long64_t[fTreeOffsetLen];
155 fFiles =
new TObjArray(fTreeOffsetLen);
156 fStatus =
new TList();
161 ResetBit(kProofUptodate);
162 ResetBit(kProofLite);
164 R__LOCKGUARD(gROOTMutex);
167 gROOT->GetListOfSpecials()->Add(
this);
168 gROOT->GetListOfDataSets()->Add(
this);
171 gROOT->GetListOfCleanups()->Add(
this);
179 bool rootAlive = gROOT && !gROOT->TestBit(TObject::kInvalidObject);
182 R__LOCKGUARD(gROOTMutex);
183 gROOT->GetListOfCleanups()->Remove(
this);
186 SafeDelete(fProofChain);
195 auto tc = fFile ? fTree->GetReadCache(fFile) :
nullptr;
198 fFile->SetCacheRead(0, fTree);
205 delete[] fTreeOffset;
210 R__LOCKGUARD(gROOTMutex);
211 gROOT->GetListOfSpecials()->Remove(
this);
212 gROOT->GetListOfDataSets()->Remove(
this);
223 Int_t TChain::Add(TChain* chain)
225 if (!chain)
return 0;
228 if ((fNtrees + chain->GetNtrees()) >= fTreeOffsetLen) {
229 fTreeOffsetLen += 2 * chain->GetNtrees();
230 Long64_t* trees =
new Long64_t[fTreeOffsetLen];
231 for (Int_t i = 0; i <= fNtrees; i++) {
232 trees[i] = fTreeOffset[i];
234 delete[] fTreeOffset;
238 TIter next(chain->GetListOfFiles());
240 TChainElement* element = 0;
241 while ((element = (TChainElement*) next())) {
242 Long64_t nentries = element->GetEntries();
243 if (fTreeOffset[fNtrees] == TTree::kMaxEntries) {
244 fTreeOffset[fNtrees+1] = TTree::kMaxEntries;
246 fTreeOffset[fNtrees+1] = fTreeOffset[fNtrees] + nentries;
249 fEntries += nentries;
250 TChainElement* newelement =
new TChainElement(element->GetName(), element->GetTitle());
251 newelement->SetPacketSize(element->GetPacketSize());
252 newelement->SetNumberEntries(nentries);
253 fFiles->Add(newelement);
258 ResetBit(kProofUptodate);
346 Int_t TChain::Add(
const char* name, Long64_t nentries )
348 TString basename, treename, query, suffix;
349 ParseTreeFilename(name, basename, treename, query, suffix, kTRUE);
352 if (!basename.MaybeWildcard()) {
353 return AddFile(name, nentries);
359 Int_t slashpos = basename.Last(
'/');
362 directory = basename(0,slashpos);
363 basename.Remove(0,slashpos+1);
365 directory = gSystem->UnixPathName(gSystem->WorkingDirectory());
369 const char *epath = gSystem->ExpandPathName(directory.Data());
370 void *dir = gSystem->OpenDirectory(epath);
375 TRegexp re(basename,kTRUE);
376 while ((file = gSystem->GetDirEntry(dir))) {
377 if (!strcmp(file,
".") || !strcmp(file,
".."))
continue;
379 if ( (basename!=file) && s.Index(re) == kNPOS)
continue;
380 l.Add(
new TObjString(file));
382 gSystem->FreeDirectory(dir);
387 while ((obj = (TObjString*)next())) {
388 file = obj->GetName();
389 nf += AddFile(TString::Format(
"%s/%s%s",directory.Data(),file,suffix.Data()),nentries);
395 ResetBit(kProofUptodate);
458 Int_t TChain::AddFile(
const char* name, Long64_t nentries ,
const char* tname )
460 if(name==0 || name[0]==
'\0') {
461 Error(
"AddFile",
"No file name; no files connected");
465 const char *treename = GetName();
466 if (tname && strlen(tname) > 0) treename = tname;
468 TString basename, tn, query, suffix;
469 ParseTreeFilename(name, basename, tn, query, suffix, kFALSE);
472 treename = tn.Data();
475 Int_t nch = basename.Length() + query.Length();
476 char *filename =
new char[nch+1];
477 strlcpy(filename,basename.Data(),nch+1);
478 strlcat(filename,query.Data(),nch+1);
481 if (fNtrees+1 >= fTreeOffsetLen) {
483 Long64_t *trees =
new Long64_t[fTreeOffsetLen];
484 for (Int_t i=0;i<=fNtrees;i++) trees[i] = fTreeOffset[i];
485 delete [] fTreeOffset;
494 TDirectory::TContext ctxt;
495 file = TFile::Open(filename);
497 if (!file || file->IsZombie()) {
507 TObject* obj = file->Get(treename);
508 if (!obj || !obj->InheritsFrom(TTree::Class())) {
509 Error(
"AddFile",
"cannot find tree with name %s in file %s", treename, filename);
516 TTree* tree = (TTree*) obj;
517 nentries = tree->GetEntries();
518 pksize = tree->GetPacketSize();
525 if (nentries != TTree::kMaxEntries) {
526 fTreeOffset[fNtrees+1] = fTreeOffset[fNtrees] + nentries;
527 fEntries += nentries;
529 fTreeOffset[fNtrees+1] = TTree::kMaxEntries;
530 fEntries = TTree::kMaxEntries;
534 TChainElement* element =
new TChainElement(treename, filename);
535 element->SetPacketSize(pksize);
536 element->SetNumberEntries(nentries);
537 fFiles->Add(element);
539 Warning(
"AddFile",
"Adding tree with no entries from file: %s", filename);
545 ResetBit(kProofUptodate);
555 Int_t TChain::AddFileInfoList(TCollection* filelist, Long64_t nfiles )
559 TIter next(filelist);
563 while ((o = next())) {
565 TString cn = o->ClassName();
567 if (cn ==
"TFileInfo") {
568 TFileInfo *fi = (TFileInfo *)o;
569 url = (fi->GetCurrentUrl()) ? fi->GetCurrentUrl()->GetUrl() : 0;
571 Warning(
"AddFileInfoList",
"found TFileInfo with empty Url - ignoring");
574 }
else if (cn ==
"TUrl") {
575 url = ((TUrl*)o)->GetUrl();
576 }
else if (cn ==
"TObjString") {
577 url = ((TObjString*)o)->GetName();
580 Warning(
"AddFileInfoList",
"object is of type %s : expecting TFileInfo, TUrl"
581 " or TObjString - ignoring", o->ClassName());
592 ResetBit(kProofUptodate);
645 TFriendElement* TChain::AddFriend(
const char* chain,
const char* dummy )
648 fFriends =
new TList();
650 TFriendElement* fe =
new TFriendElement(
this, chain, dummy);
658 ResetBit(kProofUptodate);
662 InvalidateCurrentTree();
664 TTree* tree = fe->GetTree();
666 Warning(
"AddFriend",
"Unknown TChain %s", chain);
674 TFriendElement* TChain::AddFriend(
const char* chain, TFile* dummy)
676 if (!fFriends) fFriends =
new TList();
677 TFriendElement *fe =
new TFriendElement(
this,chain,dummy);
685 ResetBit(kProofUptodate);
689 InvalidateCurrentTree();
691 TTree *t = fe->GetTree();
693 Warning(
"AddFriend",
"Unknown TChain %s",chain);
701 TFriendElement* TChain::AddFriend(TTree* chain,
const char* alias, Bool_t )
703 if (!fFriends) fFriends =
new TList();
704 TFriendElement *fe =
new TFriendElement(
this,chain,alias);
711 ResetBit(kProofUptodate);
715 InvalidateCurrentTree();
717 TTree *t = fe->GetTree();
719 Warning(
"AddFriend",
"Unknown TChain %s",chain->GetName());
727 void TChain::Browse(TBrowser* b)
745 void TChain::CanDeleteRefs(Bool_t flag )
747 fCanDeleteRefs = flag;
753 void TChain::CreatePackets()
756 TChainElement* element = 0;
757 while ((element = (TChainElement*) next())) {
758 element->CreatePackets();
766 void TChain::DirectoryAutoAdd(TDirectory * )
781 Long64_t TChain::Draw(
const char* varexp,
const TCut& selection,
782 Option_t* option, Long64_t nentries, Long64_t firstentry)
786 if (!TestBit(kProofUptodate))
787 SetProof(kTRUE, kTRUE);
788 fProofChain->SetEventList(fEventList);
789 fProofChain->SetEntryList(fEntryList);
790 return fProofChain->Draw(varexp, selection, option, nentries, firstentry);
793 return TChain::Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
801 Long64_t TChain::Draw(
const char* varexp,
const char* selection,
802 Option_t* option,Long64_t nentries, Long64_t firstentry)
806 if (!TestBit(kProofUptodate))
807 SetProof(kTRUE, kTRUE);
808 fProofChain->SetEventList(fEventList);
809 fProofChain->SetEntryList(fEntryList);
810 return fProofChain->Draw(varexp, selection, option, nentries, firstentry);
813 if (LoadTree(firstentry) < 0)
return 0;
814 return TTree::Draw(varexp,selection,option,nentries,firstentry);
820 TBranch* TChain::FindBranch(
const char* branchname)
822 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
824 if (!TestBit(kProofUptodate))
825 SetProof(kTRUE, kTRUE);
826 return fProofChain->FindBranch(branchname);
829 return fTree->FindBranch(branchname);
833 return fTree->FindBranch(branchname);
841 TLeaf* TChain::FindLeaf(
const char* searchname)
843 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
845 if (!TestBit(kProofUptodate))
846 SetProof(kTRUE, kTRUE);
847 return fProofChain->FindLeaf(searchname);
850 return fTree->FindLeaf(searchname);
854 return fTree->FindLeaf(searchname);
862 const char* TChain::GetAlias(
const char* aliasName)
const
864 const char* alias = TTree::GetAlias(aliasName);
869 return fTree->GetAlias(aliasName);
871 const_cast<TChain*
>(
this)->LoadTree(0);
873 return fTree->GetAlias(aliasName);
881 TBranch* TChain::GetBranch(
const char* name)
883 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
885 if (!TestBit(kProofUptodate))
886 SetProof(kTRUE, kTRUE);
887 return fProofChain->GetBranch(name);
890 return fTree->GetBranch(name);
894 return fTree->GetBranch(name);
902 Bool_t TChain::GetBranchStatus(
const char* branchname)
const
904 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
906 if (!TestBit(kProofUptodate))
907 Warning(
"GetBranchStatus",
"PROOF proxy not up-to-date:"
908 " run TChain::SetProof(kTRUE, kTRUE) first");
909 return fProofChain->GetBranchStatus(branchname);
911 return TTree::GetBranchStatus(branchname);
919 TTree::TClusterIterator TChain::GetClusterIterator(Long64_t )
921 Fatal(
"GetClusterIterator",
"Not support for TChain object");
922 return TTree::GetClusterIterator(-1);
930 Long64_t TChain::GetChainEntryNumber(Long64_t entry)
const
932 return entry + fTreeOffset[fTreeNumber];
940 Long64_t TChain::GetEntries()
const
942 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
944 if (!TestBit(kProofUptodate))
945 Warning(
"GetEntries",
"PROOF proxy not up-to-date:"
946 " run TChain::SetProof(kTRUE, kTRUE) first");
947 return fProofChain->GetEntries();
949 if (fEntries == TTree::kMaxEntries) {
950 const_cast<TChain*
>(
this)->LoadTree(TTree::kMaxEntries-1);
964 Int_t TChain::GetEntry(Long64_t entry, Int_t getall)
966 Long64_t treeReadEntry = LoadTree(entry);
967 if (treeReadEntry < 0) {
973 return fTree->GetEntry(treeReadEntry, getall);
983 Long64_t TChain::GetEntryNumber(Long64_t entry)
const
988 Long64_t localentry = fEntryList->GetEntryAndTree(entry, treenum);
991 if (localentry<0)
return -1;
992 if (treenum != fTreeNumber){
993 if (fTreeOffset[treenum]==TTree::kMaxEntries){
994 for (Int_t i=0; i<=treenum; i++){
995 if (fTreeOffset[i]==TTree::kMaxEntries)
996 (
const_cast<TChain*
>(
this))->LoadTree(fTreeOffset[i-1]);
1001 Long64_t globalentry = fTreeOffset[treenum] + localentry;
1016 Int_t TChain::GetEntryWithIndex(Int_t major, Int_t minor)
1018 Long64_t serial = GetEntryNumberWithIndex(major, minor);
1019 if (serial < 0)
return -1;
1020 return GetEntry(serial);
1027 TFile* TChain::GetFile()
const
1033 const_cast<TChain*
>(
this)->LoadTree(0);
1040 TLeaf* TChain::GetLeaf(
const char* branchname,
const char *leafname)
1042 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
1044 if (!TestBit(kProofUptodate))
1045 SetProof(kTRUE, kTRUE);
1046 return fProofChain->GetLeaf(branchname, leafname);
1049 return fTree->GetLeaf(branchname, leafname);
1053 return fTree->GetLeaf(branchname, leafname);
1061 TLeaf* TChain::GetLeaf(
const char* name)
1063 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
1065 if (!TestBit(kProofUptodate))
1066 SetProof(kTRUE, kTRUE);
1067 return fProofChain->GetLeaf(name);
1070 return fTree->GetLeaf(name);
1074 return fTree->GetLeaf(name);
1087 TObjArray* TChain::GetListOfBranches()
1089 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
1091 if (!TestBit(kProofUptodate))
1092 SetProof(kTRUE, kTRUE);
1093 return fProofChain->GetListOfBranches();
1096 return fTree->GetListOfBranches();
1100 return fTree->GetListOfBranches();
1110 TObjArray* TChain::GetListOfLeaves()
1112 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
1114 if (!TestBit(kProofUptodate))
1115 SetProof(kTRUE, kTRUE);
1116 return fProofChain->GetListOfLeaves();
1119 return fTree->GetListOfLeaves();
1123 return fTree->GetListOfLeaves();
1131 Double_t TChain::GetMaximum(
const char* columname)
1133 Double_t theMax = -DBL_MAX;
1134 for (Int_t file = 0; file < fNtrees; file++) {
1135 Long64_t first = fTreeOffset[file];
1137 Double_t curmax = fTree->GetMaximum(columname);
1138 if (curmax > theMax) {
1148 Double_t TChain::GetMinimum(
const char* columname)
1150 Double_t theMin = DBL_MAX;
1151 for (Int_t file = 0; file < fNtrees; file++) {
1152 Long64_t first = fTreeOffset[file];
1154 Double_t curmin = fTree->GetMinimum(columname);
1155 if (curmin < theMin) {
1167 Int_t TChain::GetNbranches()
1170 return fTree->GetNbranches();
1174 return fTree->GetNbranches();
1182 Long64_t TChain::GetReadEntry()
const
1184 if (fProofChain && !(fProofChain->TestBit(kProofLite))) {
1186 if (!TestBit(kProofUptodate))
1187 Warning(
"GetBranchStatus",
"PROOF proxy not up-to-date:"
1188 " run TChain::SetProof(kTRUE, kTRUE) first");
1189 return fProofChain->GetReadEntry();
1191 return TTree::GetReadEntry();
1203 Double_t TChain::GetWeight()
const
1205 if (TestBit(kGlobalWeight)) {
1209 return fTree->GetWeight();
1211 const_cast<TChain*
>(
this)->LoadTree(0);
1213 return fTree->GetWeight();
1232 void TChain::InvalidateCurrentTree()
1234 if (fTree && fTree->GetListOfClones()) {
1235 for (TObjLink* lnk = fTree->GetListOfClones()->FirstLink(); lnk; lnk = lnk->Next()) {
1236 TTree* clone = (TTree*) lnk->GetObject();
1250 Int_t TChain::LoadBaskets(Long64_t )
1252 Error(
"LoadBaskets",
"Function not yet implemented for TChain.");
1277 Long64_t TChain::LoadTree(Long64_t entry)
1281 if (kLoadTree & fFriendLockStatus) {
1290 if ((entry < 0) || ((entry > 0) && (entry >= fEntries && entry!=(TTree::kMaxEntries-1) ))) {
1292 if (fTree) fTree->LoadTree(-1);
1298 Int_t treenum = fTreeNumber;
1299 if ((fTreeNumber == -1) || (entry < fTreeOffset[fTreeNumber]) || (entry >= fTreeOffset[fTreeNumber+1]) || (entry==TTree::kMaxEntries-1)) {
1305 for (treenum = 0; treenum < fNtrees; treenum++) {
1306 if (entry < fTreeOffset[treenum+1]) {
1313 Long64_t treeReadEntry = entry - fTreeOffset[treenum];
1317 if (fTree && treenum == fTreeNumber) {
1321 fTree->LoadTree(treeReadEntry);
1327 TIter next(fFriends);
1328 TFriendLock lock(
this, kLoadTree);
1329 TFriendElement* fe = 0;
1330 TFriendElement* fetree = 0;
1331 Bool_t needUpdate = kFALSE;
1332 while ((fe = (TFriendElement*) next())) {
1334 if (fTree->GetListOfFriends()) {
1335 lnk = fTree->GetListOfFriends()->FirstLink();
1339 TObject* obj = lnk->GetObject();
1340 if (obj->TestBit(TFriendElement::kFromChain) && obj->GetName() && !strcmp(fe->GetName(), obj->GetName())) {
1341 fetree = (TFriendElement*) obj;
1346 TTree* at = fe->GetTree();
1347 if (at->InheritsFrom(TChain::Class())) {
1348 Int_t oldNumber = ((TChain*) at)->GetTreeNumber();
1349 TTree* old = at->GetTree();
1350 TTree* oldintree = fetree ? fetree->GetTree() : 0;
1351 at->LoadTreeFriend(entry,
this);
1352 Int_t newNumber = ((TChain*) at)->GetTreeNumber();
1353 if ((oldNumber != newNumber) || (old != at->GetTree()) || (oldintree && (oldintree != at->GetTree()))) {
1358 fTree->RemoveFriend(oldintree);
1359 fTree->AddFriend(at->GetTree(), fe->GetName())->SetBit(TFriendElement::kFromChain);
1366 at->LoadTreeFriend(entry,
this);
1374 TChainElement *frelement;
1375 TIter fnext(fStatus);
1376 while ((frelement = (TChainElement*) fnext())) {
1377 Int_t status = frelement->GetStatus();
1378 fTree->SetBranchStatus(frelement->GetName(), status);
1383 while ((frelement = (TChainElement*) fnext())) {
1384 void* addr = frelement->GetBaddress();
1386 TBranch* br = fTree->GetBranch(frelement->GetName());
1387 TBranch** pp = frelement->GetBranchPtr();
1395 br->SetAddress(addr);
1396 if (TestBit(kAutoDelete)) {
1397 br->SetAutoDelete(kTRUE);
1403 fPlayer->UpdateFormulaLeaves();
1407 if(!fNotify->Notify())
return -6;
1411 return treeReadEntry;
1416 TTreeCache* tpf = 0;
1420 if (!fDirectory->GetList()->FindObject(
this)) {
1429 tpf = fTree->GetReadCache(fFile);
1434 fFile->SetCacheRead(0, fTree);
1446 InvalidateCurrentTree();
1449 if (fCanDeleteRefs) {
1463 if (fTree) InvalidateCurrentTree();
1467 TChainElement* element = (TChainElement*) fFiles->At(treenum);
1469 if (treeReadEntry) {
1473 element = (TChainElement*) fFiles->At(0);
1482 TDirectory::TContext ctxt;
1483 fFile = TFile::Open(element->GetTitle());
1484 if (fFile) fFile->SetBit(kMustCleanup);
1488 Int_t returnCode = 0;
1489 if (!fFile || fFile->IsZombie()) {
1499 fTree =
dynamic_cast<TTree*
>(fFile->Get(element->GetName()));
1502 Error(
"LoadTree",
"Cannot find tree with name %s in file %s", element->GetName(), element->GetTitle());
1511 fTreeNumber = treenum;
1520 tpf->UpdateBranches(fTree);
1522 fFile->SetCacheRead(tpf, fTree);
1531 if (fCacheUserSet) {
1532 this->SetCacheSize(fCacheSize);
1537 Long64_t nentries = 0;
1539 nentries = fTree->GetEntries();
1542 if (fTreeOffset[fTreeNumber+1] != (fTreeOffset[fTreeNumber] + nentries)) {
1543 fTreeOffset[fTreeNumber+1] = fTreeOffset[fTreeNumber] + nentries;
1544 fEntries = fTreeOffset[fNtrees];
1545 element->SetNumberEntries(nentries);
1547 if (entry >= fTreeOffset[fTreeNumber+1]) {
1548 if ((fTreeNumber < (fNtrees - 1)) && (entry < fTreeOffset[fTreeNumber+2])) {
1553 element->SetLoadResult(returnCode);
1560 if(!fNotify->Notify())
return -6;
1564 return LoadTree(entry);
1566 treeReadEntry = fReadEntry = -2;
1579 element->SetLoadResult(returnCode);
1587 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
1588 TTree* clone = (TTree*) lnk->GetObject();
1589 ((TChain*) fTree)->TTree::AddClone(clone);
1599 Long64_t loadResult = fTree->LoadTree(treeReadEntry);
1600 if (loadResult == treeReadEntry) {
1601 element->SetLoadResult(0);
1606 element->SetLoadResult(-5);
1614 TIter next(fFriends);
1615 TFriendLock lock(
this, kLoadTree);
1616 TFriendElement* fe = 0;
1617 while ((fe = (TFriendElement*) next())) {
1618 TTree* t = fe->GetTree();
1620 if (t->GetTreeIndex()) {
1621 t->GetTreeIndex()->UpdateFormulaLeaves(0);
1623 if (t->GetTree() && t->GetTree()->GetTreeIndex()) {
1624 t->GetTree()->GetTreeIndex()->UpdateFormulaLeaves(GetTree());
1626 t->LoadTreeFriend(entry,
this);
1627 TTree* friend_t = t->GetTree();
1629 fTree->AddFriend(friend_t, fe->GetName())->SetBit(TFriendElement::kFromChain);
1634 fTree->SetMakeClass(fMakeClass);
1635 fTree->SetMaxVirtualSize(fMaxVirtualSize);
1637 SetChainOffset(fTreeOffset[fTreeNumber]);
1640 TIter next(fStatus);
1641 while ((element = (TChainElement*) next())) {
1642 Int_t status = element->GetStatus();
1643 fTree->SetBranchStatus(element->GetName(), status);
1648 while ((element = (TChainElement*) next())) {
1649 void* addr = element->GetBaddress();
1651 TBranch* br = fTree->GetBranch(element->GetName());
1652 TBranch** pp = element->GetBranchPtr();
1660 br->SetAddress(addr);
1661 if (TestBit(kAutoDelete)) {
1662 br->SetAutoDelete(kTRUE);
1670 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
1671 TTree* clone = (TTree*) lnk->GetObject();
1672 CopyAddresses(clone);
1678 fPlayer->UpdateFormulaLeaves();
1683 if(!fNotify->Notify())
return -6;
1687 return treeReadEntry;
1695 void TChain::Lookup(Bool_t force)
1698 TChainElement* element = 0;
1699 Int_t nelements = fFiles->GetEntries();
1701 printf(
"TChain::Lookup - Looking up %d files .... \n", nelements);
1703 TFileStager *stg = 0;
1704 while ((element = (TChainElement*) next())) {
1706 if (element->HasBeenLookedUp() && !force)
continue;
1710 TUrl elemurl(element->GetTitle(), kTRUE);
1712 TString anchor = elemurl.GetAnchor();
1713 TString options = elemurl.GetOptions();
1715 elemurl.SetOptions(
"");
1716 elemurl.SetAnchor(
"");
1718 TString eurl(elemurl.GetUrl());
1719 if (!stg || !stg->Matches(eurl)) {
1722 TDirectory::TContext ctxt;
1723 stg = TFileStager::Open(eurl);
1726 Error(
"Lookup",
"TFileStager instance cannot be instantiated");
1730 Int_t n1 = (nelements > 100) ? (Int_t) nelements / 100 : 1;
1731 if (stg->Locate(eurl.Data(), eurl) == 0) {
1732 if (nlook > 0 && !(nlook % n1)) {
1733 printf(
"Lookup | %3d %% finished\r", 100 * nlook / nelements);
1737 elemurl.SetUrl(eurl);
1739 elemurl.SetOptions(options);
1740 elemurl.SetAnchor(anchor);
1742 element->SetTitle(elemurl.GetUrl());
1744 element->SetLookedUp();
1747 fFiles->Remove(element);
1748 if (gSystem->AccessPathName(eurl))
1749 Error(
"Lookup",
"file %s does not exist\n", eurl.Data());
1751 Error(
"Lookup",
"file %s cannot be read\n", eurl.Data());
1755 printf(
"Lookup | %3d %% finished\n", 100 * nlook / nelements);
1765 void TChain::Loop(Option_t* option, Long64_t nentries, Long64_t firstentry)
1767 Error(
"Loop",
"Function not yet implemented");
1769 if (option || nentries || firstentry) { }
1772 if (LoadTree(firstentry) < 0)
return;
1774 if (firstentry < 0) firstentry = 0;
1775 Long64_t lastentry = firstentry + nentries -1;
1776 if (lastentry > fEntries-1) {
1777 lastentry = fEntries -1;
1782 fSelector->Start(option);
1784 Long64_t entry = firstentry;
1786 for (tree=0;tree<fNtrees;tree++) {
1787 e0 = fTreeOffset[tree];
1788 en = fTreeOffset[tree+1] - 1;
1789 if (en > lastentry) en = lastentry;
1790 if (entry > en)
continue;
1793 fSelector->BeginFile();
1795 while (entry <= en) {
1796 fSelector->Execute(fTree, entry - e0);
1799 fSelector->EndFile();
1802 fSelector->Finish(option);
1809 void TChain::ls(Option_t* option)
const
1811 TObject::ls(option);
1813 TChainElement* file = 0;
1814 TROOT::IncreaseDirLevel();
1815 while ((file = (TChainElement*)next())) {
1818 TROOT::DecreaseDirLevel();
1842 Long64_t TChain::Merge(
const char* name, Option_t* option)
1844 TFile *file = TFile::Open(name,
"recreate",
"chain files", 1);
1845 return Merge(file, 0, option);
1851 Long64_t TChain::Merge(TCollection* , Option_t* )
1853 Error(
"Merge",
"not implemented");
1860 Long64_t TChain::Merge(TCollection* , TFileMergeInfo *)
1862 Error(
"Merge",
"not implemented");
1968 Long64_t TChain::Merge(TFile* file, Int_t basketsize, Option_t* option)
1978 Bool_t fastClone = kFALSE;
1979 TString opt = option;
1981 if (opt.Contains(
"fast")) {
1988 TObjArray* lbranches = GetListOfBranches();
2004 TTree* newTree = CloneTree(0);
2015 newTree->SetName(gSystem->BaseName(GetName()));
2018 newTree->SetAutoSave(2000000000);
2023 newTree->SetCircular(0);
2026 if (opt.Contains(
"c")) {
2027 TBranch* branch = 0;
2028 TIter nextb(newTree->GetListOfBranches());
2029 while ((branch = (TBranch*) nextb())) {
2030 branch->SetCompressionSettings(file->GetCompressionSettings());
2035 if (basketsize > 1000) {
2036 TBranch* branch = 0;
2037 TIter nextb(newTree->GetListOfBranches());
2038 while ((branch = (TBranch*) nextb())) {
2039 branch->SetBasketSize(basketsize);
2045 if ( newTree->CopyEntries(
this, -1, option ) < 0 ) {
2047 Error(
"Merge",
"TTree has not been cloned\n");
2050 newTree->CopyEntries(
this, -1, option );
2057 Int_t nfiles = newTree->GetFileNumber() + 1;
2060 if (!opt.Contains(
"keep")) {
2062 delete newTree->GetCurrentFile();
2111 void TChain::ParseTreeFilename(
const char *name, TString &filename, TString &treename, TString &query, TString &suffix,
2114 Ssiz_t pIdx = kNPOS;
2121 TUrl url(name, kTRUE);
2123 TString fn = url.GetFile();
2125 if (url.GetOptions() && (strlen(url.GetOptions()) > 0))
2126 query.Form(
"?%s", url.GetOptions());
2128 if (url.GetAnchor() && (strlen(url.GetAnchor()) > 0)) {
2131 if (!query.IsNull() || strstr(name,
"?#")) {
2132 treename = url.GetAnchor();
2135 fn = url.GetFileAndOptions();
2139 suffix = url.GetFileAndOptions();
2140 suffix.Replace(suffix.Index(fn), fn.Length(),
"");
2142 filename.Remove(filename.Index(fn) + fn.Length());
2145 static const char *dotr =
".root";
2146 static Ssiz_t dotrl = strlen(dotr);
2148 Ssiz_t js = filename.Index(dotr);
2149 while (js != kNPOS) {
2151 js = filename.Index(dotr, js + 1);
2153 if (pIdx != kNPOS) {
2154 static const char *slash =
"/";
2155 static Ssiz_t slashl = strlen(slash);
2157 Ssiz_t ppIdx = filename.Index(slash, pIdx + dotrl);
2158 if (ppIdx != kNPOS) {
2160 treename = filename(ppIdx + slashl, filename.Length());
2161 filename.Remove(ppIdx + slashl - 1);
2162 suffix.Insert(0, TString::Format(
"/%s", treename.Data()));
2171 void TChain::Print(Option_t *option)
const
2174 TChainElement *element;
2175 while ((element = (TChainElement*)next())) {
2176 Printf(
"******************************************************************************");
2177 Printf(
"*Chain :%-10s: %-54s *", GetName(), element->GetTitle());
2178 Printf(
"******************************************************************************");
2179 TFile *file = TFile::Open(element->GetTitle());
2180 if (file && !file->IsZombie()) {
2181 TTree *tree = (TTree*)file->Get(element->GetName());
2182 if (tree) tree->Print(option);
2194 Long64_t TChain::Process(
const char *filename, Option_t *option, Long64_t nentries, Long64_t firstentry)
2198 if (!TestBit(kProofUptodate))
2199 SetProof(kTRUE, kTRUE);
2200 fProofChain->SetEventList(fEventList);
2201 fProofChain->SetEntryList(fEntryList);
2202 return fProofChain->Process(filename, option, nentries, firstentry);
2205 if (LoadTree(firstentry) < 0) {
2208 return TTree::Process(filename, option, nentries, firstentry);
2216 Long64_t TChain::Process(TSelector* selector, Option_t* option, Long64_t nentries, Long64_t firstentry)
2220 if (!TestBit(kProofUptodate))
2221 SetProof(kTRUE, kTRUE);
2222 fProofChain->SetEventList(fEventList);
2223 fProofChain->SetEntryList(fEntryList);
2224 return fProofChain->Process(selector, option, nentries, firstentry);
2227 return TTree::Process(selector, option, nentries, firstentry);
2234 void TChain::RecursiveRemove(TObject *obj)
2241 if (fDirectory == obj) {
2253 void TChain::RemoveFriend(TTree* oldFriend)
2262 TTree::RemoveFriend(oldFriend);
2266 ResetBit(kProofUptodate);
2270 InvalidateCurrentTree();
2276 void TChain::Reset(Option_t*)
2287 TChainElement* element =
new TChainElement(
"*",
"");
2288 fStatus->Add(element);
2298 void TChain::ResetAfterMerge(TFileMergeInfo *info)
2307 TTree::ResetAfterMerge(info);
2315 void TChain::SavePrimitive(std::ostream &out, Option_t *option)
2317 static Int_t chCounter = 0;
2319 TString chName = gInterpreter->MapCppName(GetName());
2320 if (chName.IsNull())
2323 chName += chCounter;
2325 TString opt = option;
2328 out <<
" TChain *" << chName.Data() <<
" = new TChain(\"" << GetName() <<
"\");" << std::endl;
2330 if (opt.Contains(
"friend")) {
2331 opt.ReplaceAll(
"friend",
"");
2332 for (TObject *frel : *fFriends) {
2333 TTree *frtree = ((TFriendElement *)frel)->GetTree();
2334 if (dynamic_cast<TChain *>(frtree)) {
2335 if (strcmp(frtree->GetName(), GetName()) != 0)
2337 frtree->SavePrimitive(out, opt.Data());
2338 out <<
" " << chName.Data() <<
"->AddFriend(\"" << frtree->GetName() <<
"\");" << std::endl;
2340 TDirectory *file = frtree->GetDirectory();
2341 if (file && dynamic_cast<TFile *>(file))
2342 out <<
" " << chName.Data() <<
"->AddFriend(\"" << frtree->GetName() <<
"\", \"" << file->GetName()
2343 <<
"\");" << std::endl;
2349 for (TObject *el : *fFiles) {
2350 TChainElement *chel = (TChainElement *)el;
2352 if (chel->GetLoadResult() == 0 && chel->GetEntries() != 0) {
2353 if (chel->GetEntries() == TTree::kMaxEntries)
2354 out <<
" " << chName.Data() <<
"->AddFile(\"" << chel->GetTitle() <<
"\");" << std::endl;
2356 out <<
" " << chName.Data() <<
"->AddFile(\"" << chel->GetTitle() <<
"\"," << chel->GetEntries() <<
");"
2362 if (GetMarkerColor() != 1) {
2363 if (GetMarkerColor() > 228) {
2364 TColor::SaveColor(out, GetMarkerColor());
2365 out <<
" " << chName.Data() <<
"->SetMarkerColor(ci);" << std::endl;
2367 out <<
" " << chName.Data() <<
"->SetMarkerColor(" << GetMarkerColor() <<
");" << std::endl;
2369 if (GetMarkerStyle() != 1) {
2370 out <<
" " << chName.Data() <<
"->SetMarkerStyle(" << GetMarkerStyle() <<
");" << std::endl;
2372 if (GetMarkerSize() != 1) {
2373 out <<
" " << chName.Data() <<
"->SetMarkerSize(" << GetMarkerSize() <<
");" << std::endl;
2384 Long64_t TChain::Scan(
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
2386 if (LoadTree(firstentry) < 0) {
2389 return TTree::Scan(varexp, selection, option, nentries, firstentry);
2399 void TChain::SetAutoDelete(Bool_t autodelete)
2402 SetBit(kAutoDelete, 1);
2404 SetBit(kAutoDelete, 0);
2408 Int_t TChain::SetCacheSize(Long64_t cacheSize)
2418 fCacheUserSet = kTRUE;
2421 res = fTree->SetCacheSize(cacheSize);
2426 fCacheSize = cacheSize;
2433 void TChain::ResetBranchAddress(TBranch *branch)
2435 TChainElement* element = (TChainElement*) fStatus->FindObject(branch->GetName());
2437 element->SetBaddress(0);
2440 fTree->ResetBranchAddress(branch);
2447 void TChain::ResetBranchAddresses()
2449 TIter next(fStatus);
2450 TChainElement* element = 0;
2451 while ((element = (TChainElement*) next())) {
2452 element->SetBaddress(0);
2455 fTree->ResetBranchAddresses();
2476 Int_t TChain::SetBranchAddress(
const char *bname,
void* add, TBranch** ptr)
2478 Int_t res = kNoCheck;
2482 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2484 element =
new TChainElement(bname,
"");
2485 fStatus->Add(element);
2487 element->SetBaddress(add);
2488 element->SetBranchPtr(ptr);
2491 if (fTreeNumber >= 0) {
2492 TBranch* branch = fTree->GetBranch(bname);
2497 res = CheckBranchAddressType(branch, TClass::GetClass(element->GetBaddressClassName()), (EDataType) element->GetBaddressType(), element->GetBaddressIsPtr());
2499 void* oldAdd = branch->GetAddress();
2500 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
2501 TTree* clone = (TTree*) lnk->GetObject();
2502 TBranch* cloneBr = clone->GetBranch(bname);
2503 if (cloneBr && (cloneBr->GetAddress() == oldAdd)) {
2505 cloneBr->SetAddress(add);
2509 branch->SetAddress(add);
2511 Error(
"SetBranchAddress",
"unknown branch -> %s", bname);
2512 return kMissingBranch;
2529 Int_t TChain::SetBranchAddress(
const char* bname,
void* add, TClass* realClass, EDataType datatype, Bool_t isptr)
2531 return SetBranchAddress(bname, add, 0, realClass, datatype, isptr);
2541 Int_t TChain::SetBranchAddress(
const char* bname,
void* add, TBranch** ptr, TClass* realClass, EDataType datatype, Bool_t isptr)
2543 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2545 element =
new TChainElement(bname,
"");
2546 fStatus->Add(element);
2549 element->SetBaddressClassName(realClass->GetName());
2551 element->SetBaddressType((UInt_t) datatype);
2552 element->SetBaddressIsPtr(isptr);
2553 element->SetBranchPtr(ptr);
2554 return SetBranchAddress(bname, add, ptr);
2571 void TChain::SetBranchStatus(
const char* bname, Bool_t status, UInt_t* found)
2577 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2579 fStatus->Remove(element);
2581 element =
new TChainElement(bname,
"");
2583 fStatus->Add(element);
2584 element->SetStatus(status);
2586 if (fTreeNumber >= 0) {
2587 fTree->SetBranchStatus(bname, status, found);
2598 void TChain::SetDirectory(TDirectory* dir)
2600 if (fDirectory == dir)
return;
2601 if (fDirectory) fDirectory->Remove(
this);
2604 fDirectory->Append(
this);
2605 fFile = fDirectory->GetFile();
2620 void TChain::SetEntryList(TEntryList *elist, Option_t *opt)
2626 if (fEntryList->TestBit(kCanDelete)) {
2627 TEntryList *tmp = fEntryList;
2639 if (!elist->TestBit(kCanDelete)){
2643 if (elist->GetN() == 0){
2655 Int_t ne = fFiles->GetEntries();
2657 TString treename, filename;
2659 TEntryList *templist = 0;
2660 for (Int_t ie = 0; ie<ne; ie++){
2661 auto chainElement = (TChainElement*)fFiles->UncheckedAt(ie);
2662 treename = chainElement->GetName();
2663 filename = chainElement->GetTitle();
2664 templist = elist->GetEntryList(treename, filename, opt);
2667 templist->SetTreeNumber(ie);
2671 if (listfound == 0){
2672 Error(
"SetEntryList",
"No list found for the trees in this chain");
2677 TList *elists = elist->GetLists();
2678 Bool_t shift = kFALSE;
2683 while((templist = (TEntryList*)next())){
2684 if (templist->GetTreeNumber() < 0){
2689 fEntryList->SetShift(shift);
2715 void TChain::SetEntryListFile(
const char *filename, Option_t * )
2722 if (fEntryList->TestBit(kCanDelete)) {
2723 TEntryList *tmp = fEntryList;
2733 TString basename(filename);
2735 Int_t dotslashpos = basename.Index(
".root/");
2736 TString behind_dot_root =
"";
2737 if (dotslashpos>=0) {
2739 behind_dot_root = basename(dotslashpos+6,basename.Length()-dotslashpos+6);
2741 basename.Remove(dotslashpos+5);
2743 fEntryList =
new TEntryListFromFile(basename.Data(), behind_dot_root.Data(), fNtrees);
2744 fEntryList->SetBit(kCanDelete, kTRUE);
2745 fEntryList->SetDirectory(0);
2746 ((TEntryListFromFile*)fEntryList)->SetFileNames(fFiles);
2761 void TChain::SetEventList(TEventList *evlist)
2763 fEventList = evlist;
2765 if (fEntryList->TestBit(kCanDelete)) {
2766 TEntryList *tmp = fEntryList;
2786 if (fEntryList->TestBit(kCanDelete)){
2787 TEntryList *tmp = fEntryList;
2797 char enlistname[100];
2798 snprintf(enlistname,100,
"%s_%s", evlist->GetName(),
"entrylist");
2799 TEntryList *enlist =
new TEntryList(enlistname, evlist->GetTitle());
2800 enlist->SetDirectory(0);
2802 Int_t nsel = evlist->GetN();
2803 Long64_t globalentry, localentry;
2804 const char *treename;
2805 const char *filename;
2806 if (fTreeOffset[fNtrees-1]==TTree::kMaxEntries){
2810 printf(
"loading trees\n");
2811 (
const_cast<TChain*
>(
this))->LoadTree(evlist->GetEntry(evlist->GetN()-1));
2813 for (Int_t i=0; i<nsel; i++){
2814 globalentry = evlist->GetEntry(i);
2817 while (globalentry>=fTreeOffset[treenum])
2820 localentry = globalentry - fTreeOffset[treenum];
2822 treename = ((TNamed*)fFiles->At(treenum))->GetName();
2823 filename = ((TNamed*)fFiles->At(treenum))->GetTitle();
2825 enlist->SetTree(treename, filename);
2826 enlist->Enter(localentry);
2828 enlist->SetBit(kCanDelete, kTRUE);
2829 enlist->SetReapplyCut(evlist->GetReapplyCut());
2830 SetEntryList(enlist);
2836 void TChain::SetName(
const char* name)
2840 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
2841 gROOT->GetListOfCleanups()->Remove(
this);
2842 gROOT->GetListOfSpecials()->Remove(
this);
2843 gROOT->GetListOfDataSets()->Remove(
this);
2845 TTree::SetName(name);
2848 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
2849 gROOT->GetListOfCleanups()->Add(
this);
2850 gROOT->GetListOfSpecials()->Add(
this);
2851 gROOT->GetListOfDataSets()->Add(
this);
2859 void TChain::SetPacketSize(Int_t size)
2863 TChainElement *element;
2864 while ((element = (TChainElement*)next())) {
2865 element->SetPacketSize(size);
2880 void TChain::SetProof(Bool_t on, Bool_t refresh, Bool_t gettreeheader)
2884 SafeDelete(fProofChain);
2886 ResetBit(kProofUptodate);
2888 if (fProofChain && !refresh &&
2889 (!gettreeheader || (gettreeheader && fProofChain->GetTree()))) {
2892 SafeDelete(fProofChain);
2893 ResetBit(kProofUptodate);
2897 if ((h = gROOT->GetPluginManager()->FindHandler(
"TChain",
"proof"))) {
2898 if (h->LoadPlugin() == -1)
2900 if (!(fProofChain = reinterpret_cast<TChain *>(h->ExecPlugin(2,
this, gettreeheader))))
2901 Error(
"SetProof",
"creation of TProofChain failed");
2903 SetBit(kProofUptodate);
2927 void TChain::SetWeight(Double_t w, Option_t* option)
2930 TString opt = option;
2932 ResetBit(kGlobalWeight);
2933 if (opt.Contains(
"global")) {
2934 SetBit(kGlobalWeight);
2941 void TChain::Streamer(TBuffer& b)
2943 if (b.IsReading()) {
2946 R__LOCKGUARD(gROOTMutex);
2947 gROOT->GetListOfCleanups()->Remove(
this);
2951 Version_t R__v = b.ReadVersion(&R__s, &R__c);
2953 b.ReadClassBuffer(TChain::Class(),
this, R__v, R__s, R__c);
2957 b >> fTreeOffsetLen;
2959 fFiles->Streamer(b);
2961 fStatus->Streamer(b);
2962 fTreeOffset =
new Long64_t[fTreeOffsetLen];
2963 b.ReadFastArray(fTreeOffset,fTreeOffsetLen);
2965 b.CheckByteCount(R__s, R__c, TChain::IsA());
2970 R__LOCKGUARD(gROOTMutex);
2971 gROOT->GetListOfCleanups()->Add(
this);
2975 b.WriteClassBuffer(TChain::Class(),
this);
2983 void TChain::UseCache(Int_t , Int_t )