436 constexpr Int_t kNEntriesResort = 100;
437 constexpr Float_t kNEntriesResortInv = 1.f/kNEntriesResort;
439 Int_t TTree::fgBranchStyle = 1;
440 Long64_t TTree::fgMaxTreeSize = 100000000000LL;
448 static char DataTypeToChar(EDataType datatype)
453 case kChar_t:
return 'B';
454 case kUChar_t:
return 'b';
455 case kBool_t:
return 'O';
456 case kShort_t:
return 'S';
457 case kUShort_t:
return 's';
459 case kInt_t:
return 'I';
460 case kUInt_t:
return 'i';
461 case kDouble_t:
return 'D';
462 case kDouble32_t:
return 'd';
463 case kFloat_t:
return 'F';
464 case kFloat16_t:
return 'f';
465 case kLong_t:
return 0;
466 case kULong_t:
return 0;
467 case kchar:
return 0;
468 case kLong64_t:
return 'L';
469 case kULong64_t:
return 'l';
471 case kCharStar:
return 'C';
472 case kBits:
return 0;
489 TTree::TFriendLock::TFriendLock(TTree* tree, UInt_t methodbit)
494 fMethodBit = methodbit;
496 fPrevious = fTree->fFriendLockStatus & fMethodBit;
497 fTree->fFriendLockStatus |= fMethodBit;
506 TTree::TFriendLock::TFriendLock(
const TFriendLock& tfl) :
508 fMethodBit(tfl.fMethodBit),
509 fPrevious(tfl.fPrevious)
516 TTree::TFriendLock& TTree::TFriendLock::operator=(
const TTree::TFriendLock& tfl)
520 fMethodBit=tfl.fMethodBit;
521 fPrevious=tfl.fPrevious;
529 TTree::TFriendLock::~TFriendLock()
533 fTree->fFriendLockStatus &= ~(fMethodBit & kBitMask);
546 TTree::TClusterIterator::TClusterIterator(TTree *tree, Long64_t firstEntry) : fTree(tree), fClusterRange(0), fStartEntry(0), fNextEntry(0), fEstimatedSize(-1)
548 if (fTree->fNClusterRange) {
554 fClusterRange = TMath::BinarySearch(fTree->fNClusterRange, fTree->fClusterRangeEnd, firstEntry - 1) + 1;
556 Long64_t entryInRange;
558 if (fClusterRange == 0) {
560 entryInRange = firstEntry;
562 pedestal = fTree->fClusterRangeEnd[fClusterRange-1] + 1;
563 entryInRange = firstEntry - pedestal;
566 if (fClusterRange == fTree->fNClusterRange) {
567 autoflush = fTree->fAutoFlush;
569 autoflush = fTree->fClusterSize[fClusterRange];
571 if (autoflush <= 0) {
572 autoflush = GetEstimatedClusterSize();
574 fStartEntry = pedestal + entryInRange - entryInRange%autoflush;
575 }
else if ( fTree->GetAutoFlush() <= 0 ) {
577 fStartEntry = firstEntry;
579 fStartEntry = firstEntry - firstEntry%fTree->GetAutoFlush();
581 fNextEntry = fStartEntry;
597 Long64_t TTree::TClusterIterator::GetEstimatedClusterSize()
599 auto autoFlush = fTree->GetAutoFlush();
600 if (autoFlush > 0)
return autoFlush;
601 if (fEstimatedSize > 0)
return fEstimatedSize;
603 Long64_t zipBytes = fTree->GetZipBytes();
605 fEstimatedSize = fTree->GetEntries() - 1;
607 Long64_t clusterEstimate = 1;
608 Long64_t cacheSize = fTree->GetCacheSize();
609 if (cacheSize == 0) {
611 TFile *file = fTree->GetCurrentFile();
613 TFileCacheRead *cache = fTree->GetReadCache(file);
615 cacheSize = cache->GetBufferSize();
620 if (cacheSize <= 0) {
621 cacheSize = 30000000;
623 clusterEstimate = fTree->GetEntries() * cacheSize / zipBytes;
625 fEstimatedSize = clusterEstimate ? clusterEstimate : 1;
627 return fEstimatedSize;
634 Long64_t TTree::TClusterIterator::Next()
636 fStartEntry = fNextEntry;
637 if (fTree->fNClusterRange || fTree->GetAutoFlush() > 0) {
638 if (fClusterRange == fTree->fNClusterRange) {
641 fNextEntry += GetEstimatedClusterSize();
643 if (fStartEntry > fTree->fClusterRangeEnd[fClusterRange]) {
646 if (fClusterRange == fTree->fNClusterRange) {
649 fNextEntry += GetEstimatedClusterSize();
651 Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
652 if (clusterSize == 0) {
653 clusterSize = GetEstimatedClusterSize();
655 fNextEntry += clusterSize;
656 if (fNextEntry > fTree->fClusterRangeEnd[fClusterRange]) {
660 fNextEntry = fTree->fClusterRangeEnd[fClusterRange] + 1;
666 fNextEntry = fStartEntry + GetEstimatedClusterSize();
668 if (fNextEntry > fTree->GetEntries()) {
669 fNextEntry = fTree->GetEntries();
678 Long64_t TTree::TClusterIterator::Previous()
680 fNextEntry = fStartEntry;
681 if (fTree->fNClusterRange || fTree->GetAutoFlush() > 0) {
682 if (fClusterRange == 0 || fTree->fNClusterRange == 0) {
685 fStartEntry -= GetEstimatedClusterSize();
687 if (fNextEntry <= fTree->fClusterRangeEnd[fClusterRange]) {
690 if (fClusterRange == 0) {
694 Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
695 if (clusterSize == 0) {
696 clusterSize = GetEstimatedClusterSize();
698 fStartEntry -= clusterSize;
703 fStartEntry = fNextEntry - GetEstimatedClusterSize();
705 if (fStartEntry < 0) {
735 , fDefaultEntryOffsetLen(1000)
737 , fMaxClusterRange(0)
741 , fAutoSave( -300000000)
742 , fAutoFlush(-30000000)
744 , fClusterRangeEnd(0)
773 , fFriendLockStatus(0)
774 , fTransientBuffer(0)
775 , fCacheDoAutoInit(kTRUE)
776 , fCacheDoClusterPrefetch(kFALSE)
777 , fCacheUserSet(kFALSE)
778 , fIMTEnabled(ROOT::IsImplicitMTEnabled())
779 , fNEntriesSinceSorting(0)
781 fMaxEntries = 1000000000;
784 fMaxEntryLoop = 1000000000;
785 fMaxEntryLoop *= 1000;
787 fBranches.SetOwner(kTRUE);
800 TTree::TTree(
const char* name,
const char* title, Int_t splitlevel ,
802 : TNamed(name, title)
815 , fDefaultEntryOffsetLen(1000)
817 , fMaxClusterRange(0)
821 , fAutoSave( -300000000)
822 , fAutoFlush(-30000000)
824 , fClusterRangeEnd(0)
853 , fFriendLockStatus(0)
854 , fTransientBuffer(0)
855 , fCacheDoAutoInit(kTRUE)
856 , fCacheDoClusterPrefetch(kFALSE)
857 , fCacheUserSet(kFALSE)
858 , fIMTEnabled(ROOT::IsImplicitMTEnabled())
859 , fNEntriesSinceSorting(0)
862 SetLineColor(gStyle->GetHistLineColor());
863 SetLineStyle(gStyle->GetHistLineStyle());
864 SetLineWidth(gStyle->GetHistLineWidth());
867 SetFillColor(gStyle->GetHistFillColor());
868 SetFillStyle(gStyle->GetHistFillStyle());
871 SetMarkerColor(gStyle->GetMarkerColor());
872 SetMarkerStyle(gStyle->GetMarkerStyle());
873 SetMarkerSize(gStyle->GetMarkerSize());
875 fMaxEntries = 1000000000;
878 fMaxEntryLoop = 1000000000;
879 fMaxEntryLoop *= 1000;
885 if (fDirectory) fDirectory->Append(
this);
887 fBranches.SetOwner(kTRUE);
892 if (strlen(title) > 2) {
893 if (title[0] ==
'/') {
894 Branch(title+1,32000,splitlevel);
904 if (
auto link = dynamic_cast<TNotifyLinkBase*>(fNotify)) {
907 if (fAllocationCount && (gDebug > 0)) {
908 Info(
"TTree::~TTree",
"For tree %s, allocation count is %u.", GetName(), fAllocationCount.load());
909 #ifdef R__TRACK_BASKET_ALLOC_TIME
910 Info(
"TTree::~TTree",
"For tree %s, allocation time is %lluus.", GetName(), fAllocationTime.load());
916 if (fDirectory->GetList()) {
918 fDirectory->Remove(
this);
921 TFile *file = fDirectory->GetFile();
922 MoveReadCache(file,0);
930 if (fClones && fClones->GetEntries()) {
935 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
936 TTree* clone = (TTree*) lnk->GetObject();
940 CopyAddresses(clone,kTRUE);
967 R__LOCKGUARD(gROOTMutex);
968 gROOT->GetListOfCleanups()->Remove(fClones);
975 if (fEntryList->TestBit(kCanDelete) && fEntryList->GetDirectory()==0) {
987 delete [] fClusterRangeEnd;
988 fClusterRangeEnd = 0;
989 delete [] fClusterSize;
995 if (fTransientBuffer) {
996 delete fTransientBuffer;
997 fTransientBuffer = 0;
1004 TBuffer* TTree::GetTransientBuffer(Int_t size)
1006 if (fTransientBuffer) {
1007 if (fTransientBuffer->BufferSize() < size) {
1008 fTransientBuffer->Expand(size);
1010 return fTransientBuffer;
1012 fTransientBuffer =
new TBufferFile(TBuffer::kRead, size);
1013 return fTransientBuffer;
1026 Int_t TTree::AddBranchToCache(
const char*bname, Bool_t subbranches)
1029 if (LoadTree(0)<0) {
1030 Error(
"AddBranchToCache",
"Could not load a tree");
1035 if (GetTree() !=
this) {
1036 return GetTree()->AddBranchToCache(bname, subbranches);
1039 Error(
"AddBranchToCache",
"No tree is available. Branch was not added to the cache");
1043 TFile *f = GetCurrentFile();
1045 Error(
"AddBranchToCache",
"No file is available. Branch was not added to the cache");
1048 TTreeCache *tc = GetReadCache(f,kTRUE);
1050 Error(
"AddBranchToCache",
"No cache is available, branch not added");
1053 return tc->AddBranch(bname,subbranches);
1065 Int_t TTree::AddBranchToCache(TBranch *b, Bool_t subbranches)
1068 if (LoadTree(0)<0) {
1069 Error(
"AddBranchToCache",
"Could not load a tree");
1074 if (GetTree() !=
this) {
1075 Int_t res = GetTree()->AddBranchToCache(b, subbranches);
1077 Error(
"AddBranchToCache",
"Error adding branch");
1082 Error(
"AddBranchToCache",
"No tree is available. Branch was not added to the cache");
1086 TFile *f = GetCurrentFile();
1088 Error(
"AddBranchToCache",
"No file is available. Branch was not added to the cache");
1091 TTreeCache *tc = GetReadCache(f,kTRUE);
1093 Error(
"AddBranchToCache",
"No cache is available, branch not added");
1096 return tc->AddBranch(b,subbranches);
1109 Int_t TTree::DropBranchFromCache(
const char*bname, Bool_t subbranches)
1112 if (LoadTree(0)<0) {
1113 Error(
"DropBranchFromCache",
"Could not load a tree");
1118 if (GetTree() !=
this) {
1119 return GetTree()->DropBranchFromCache(bname, subbranches);
1122 Error(
"DropBranchFromCache",
"No tree is available. Branch was not dropped from the cache");
1126 TFile *f = GetCurrentFile();
1128 Error(
"DropBranchFromCache",
"No file is available. Branch was not dropped from the cache");
1131 TTreeCache *tc = GetReadCache(f,kTRUE);
1133 Error(
"DropBranchFromCache",
"No cache is available, branch not dropped");
1136 return tc->DropBranch(bname,subbranches);
1148 Int_t TTree::DropBranchFromCache(TBranch *b, Bool_t subbranches)
1151 if (LoadTree(0)<0) {
1152 Error(
"DropBranchFromCache",
"Could not load a tree");
1157 if (GetTree() !=
this) {
1158 Int_t res = GetTree()->DropBranchFromCache(b, subbranches);
1160 Error(
"DropBranchFromCache",
"Error dropping branch");
1165 Error(
"DropBranchFromCache",
"No tree is available. Branch was not dropped from the cache");
1169 TFile *f = GetCurrentFile();
1171 Error(
"DropBranchFromCache",
"No file is available. Branch was not dropped from the cache");
1174 TTreeCache *tc = GetReadCache(f,kTRUE);
1176 Error(
"DropBranchFromCache",
"No cache is available, branch not dropped");
1179 return tc->DropBranch(b,subbranches);
1186 void TTree::AddClone(TTree* clone)
1189 fClones =
new TList();
1190 fClones->SetOwner(
false);
1194 R__LOCKGUARD(gROOTMutex);
1195 gROOT->GetListOfCleanups()->Add(fClones);
1198 if (!fClones->FindObject(clone)) {
1199 fClones->Add(clone);
1207 bool CheckReshuffling(TTree &mainTree, TTree &friendTree)
1209 const auto isMainReshuffled = mainTree.TestBit(TTree::kEntriesReshuffled);
1210 const auto isFriendReshuffled = friendTree.TestBit(TTree::kEntriesReshuffled);
1211 const auto friendHasValidIndex = [&] {
1212 auto idx = friendTree.GetTreeIndex();
1213 return idx ? idx->IsValidFor(&mainTree) : kFALSE;
1216 if ((isMainReshuffled || isFriendReshuffled) && !friendHasValidIndex) {
1217 const auto reshuffledTreeName = isMainReshuffled ? mainTree.GetName() : friendTree.GetName();
1218 const auto msg =
"Tree '%s' has the kEntriesReshuffled bit set, and cannot be used as friend nor can be added as "
1219 "a friend unless the main tree has a TTreeIndex on the friend tree '%s'. You can also unset the "
1220 "bit manually if you know what you are doing.";
1221 Error(
"AddFriend", msg, reshuffledTreeName, friendTree.GetName());
1298 TFriendElement *TTree::AddFriend(
const char *treename,
const char *filename)
1301 fFriends =
new TList();
1303 TFriendElement *fe =
new TFriendElement(
this, treename, filename);
1305 TTree *t = fe->GetTree();
1306 bool canAddFriend =
true;
1308 canAddFriend = CheckReshuffling(*
this, *t);
1309 if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1310 Warning(
"AddFriend",
"FriendElement %s in file %s has less entries %lld than its parent Tree: %lld", treename,
1311 filename, t->GetEntries(), fEntries);
1314 Error(
"AddFriend",
"Cannot find tree '%s' in file '%s', friend not added", treename, filename);
1315 canAddFriend =
false;
1332 TFriendElement *TTree::AddFriend(
const char *treename, TFile *file)
1335 fFriends =
new TList();
1337 TFriendElement *fe =
new TFriendElement(
this, treename, file);
1339 TTree *t = fe->GetTree();
1340 bool canAddFriend =
true;
1342 canAddFriend = CheckReshuffling(*
this, *t);
1343 if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1344 Warning(
"AddFriend",
"FriendElement %s in file %s has less entries %lld than its parent tree: %lld", treename,
1345 file->GetName(), t->GetEntries(), fEntries);
1348 Error(
"AddFriend",
"Cannot find tree '%s' in file '%s', friend not added", treename, file->GetName());
1349 canAddFriend =
false;
1363 TFriendElement *TTree::AddFriend(TTree *tree,
const char *alias, Bool_t warn)
1369 fFriends =
new TList();
1371 TFriendElement *fe =
new TFriendElement(
this, tree, alias);
1373 TTree *t = fe->GetTree();
1374 if (warn && (t->GetEntries() < fEntries)) {
1375 Warning(
"AddFriend",
"FriendElement '%s' in file '%s' has less entries %lld than its parent tree: %lld",
1376 tree->GetName(), fe->GetFile() ? fe->GetFile()->GetName() :
"(memory resident)", t->GetEntries(),
1379 if (CheckReshuffling(*
this, *t)) {
1465 Long64_t TTree::AutoSave(Option_t* option)
1467 if (!fDirectory || fDirectory == gROOT || !fDirectory->IsWritable())
return 0;
1469 Info(
"AutoSave",
"Tree:%s after %lld bytes written\n",GetName(),GetTotBytes());
1471 TString opt = option;
1474 if (opt.Contains(
"flushbaskets")) {
1475 if (gDebug > 0) Info(
"AutoSave",
"calling FlushBaskets \n");
1479 fSavedBytes = GetZipBytes();
1481 TKey *key = (TKey*)fDirectory->GetListOfKeys()->FindObject(GetName());
1483 if (opt.Contains(
"overwrite")) {
1484 nbytes = fDirectory->WriteTObject(
this,
"",
"overwrite");
1486 nbytes = fDirectory->WriteTObject(
this);
1487 if (nbytes && key) {
1493 TFile *file = fDirectory->GetFile();
1494 if (file) file->WriteStreamerInfo();
1496 if (opt.Contains(
"saveself")) {
1497 fDirectory->SaveSelf();
1500 if (file) file->WriteHeader();
1508 const char* writeStlWithoutProxyMsg =
"The class requested (%s) for the branch \"%s\""
1509 " is an instance of an stl collection and does not have a compiled CollectionProxy."
1510 " Please generate the dictionary for this collection (%s) to avoid to write corrupted data.";
1519 TBranch* TTree::BranchImp(
const char* branchname,
const char* classname, TClass* ptrClass,
void* addobj, Int_t bufsize, Int_t splitlevel)
1521 TClass* claim = TClass::GetClass(classname);
1523 if (claim && claim->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(claim->GetCollectionProxy())) {
1524 Error(
"Branch", writeStlWithoutProxyMsg,
1525 claim->GetName(), branchname, claim->GetName());
1528 return Branch(branchname, classname, (
void*) addobj, bufsize, splitlevel);
1530 TClass* actualClass = 0;
1531 void** addr = (
void**) addobj;
1533 actualClass = ptrClass->GetActualClass(*addr);
1535 if (ptrClass && claim) {
1536 if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1538 if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1542 Error(
"Branch",
"The class requested (%s) for \"%s\" is different from the type of the pointer passed (%s)",
1543 claim->GetName(), branchname, ptrClass->GetName());
1545 }
else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1546 if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1550 Error(
"Branch",
"The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1551 actualClass->GetName(), branchname, claim->GetName());
1555 if (claim && claim->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(claim->GetCollectionProxy())) {
1556 Error(
"Branch", writeStlWithoutProxyMsg,
1557 claim->GetName(), branchname, claim->GetName());
1560 return Branch(branchname, classname, (
void*) addobj, bufsize, splitlevel);
1567 TBranch* TTree::BranchImp(
const char* branchname, TClass* ptrClass,
void* addobj, Int_t bufsize, Int_t splitlevel)
1570 Error(
"Branch",
"The pointer specified for %s is not of a class known to ROOT", branchname);
1573 TClass* actualClass = 0;
1574 void** addr = (
void**) addobj;
1575 if (addr && *addr) {
1576 actualClass = ptrClass->GetActualClass(*addr);
1578 Warning(
"Branch",
"The actual TClass corresponding to the object provided for the definition of the branch \"%s\" is missing.\n\tThe object will be truncated down to its %s part",
1579 branchname, ptrClass->GetName());
1580 actualClass = ptrClass;
1581 }
else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1582 Error(
"Branch",
"The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s", actualClass->GetName(), branchname, ptrClass->GetName());
1586 actualClass = ptrClass;
1588 if (actualClass && actualClass->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(actualClass->GetCollectionProxy())) {
1589 Error(
"Branch", writeStlWithoutProxyMsg,
1590 actualClass->GetName(), branchname, actualClass->GetName());
1593 return Branch(branchname, actualClass->GetName(), (
void*) addobj, bufsize, splitlevel);
1600 TBranch* TTree::BranchImpRef(
const char* branchname,
const char *classname, TClass* ptrClass,
void *addobj, Int_t bufsize, Int_t splitlevel)
1602 TClass* claim = TClass::GetClass(classname);
1604 if (claim && claim->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(claim->GetCollectionProxy())) {
1605 Error(
"Branch", writeStlWithoutProxyMsg,
1606 claim->GetName(), branchname, claim->GetName());
1608 }
else if (claim == 0) {
1609 Error(
"Branch",
"The pointer specified for %s is not of a class known to ROOT and %s is not a known class", branchname, classname);
1614 TClass* actualClass = 0;
1616 Error(
"Branch",
"Reference interface requires a valid object (for branch: %s)!", branchname);
1619 actualClass = ptrClass->GetActualClass(addobj);
1620 if (ptrClass && claim) {
1621 if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1623 if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1627 Error(
"Branch",
"The class requested (%s) for \"%s\" is different from the type of the object passed (%s)",
1628 claim->GetName(), branchname, ptrClass->GetName());
1630 }
else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1631 if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1635 Error(
"Branch",
"The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1636 actualClass->GetName(), branchname, claim->GetName());
1641 Warning(
"Branch",
"The actual TClass corresponding to the object provided for the definition of the branch \"%s\" is missing.\n\tThe object will be truncated down to its %s part",
1642 branchname, ptrClass->GetName());
1643 actualClass = ptrClass;
1644 }
else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1645 Error(
"Branch",
"The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s", actualClass->GetName(), branchname, ptrClass->GetName());
1648 if (actualClass && actualClass->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(actualClass->GetCollectionProxy())) {
1649 Error(
"Branch", writeStlWithoutProxyMsg,
1650 actualClass->GetName(), branchname, actualClass->GetName());
1653 return BronchExec(branchname, actualClass->GetName(), (
void*) addobj, kFALSE, bufsize, splitlevel);
1660 TBranch* TTree::BranchImpRef(
const char* branchname, TClass* ptrClass, EDataType datatype,
void* addobj, Int_t bufsize, Int_t splitlevel)
1663 if (datatype == kOther_t || datatype == kNoType_t) {
1664 Error(
"Branch",
"The pointer specified for %s is not of a class or type known to ROOT", branchname);
1666 TString varname; varname.Form(
"%s/%c",branchname,DataTypeToChar(datatype));
1667 return Branch(branchname,addobj,varname.Data(),bufsize);
1671 TClass* actualClass = 0;
1673 Error(
"Branch",
"Reference interface requires a valid object (for branch: %s)!", branchname);
1676 actualClass = ptrClass->GetActualClass(addobj);
1678 Warning(
"Branch",
"The actual TClass corresponding to the object provided for the definition of the branch \"%s\" is missing.\n\tThe object will be truncated down to its %s part",
1679 branchname, ptrClass->GetName());
1680 actualClass = ptrClass;
1681 }
else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1682 Error(
"Branch",
"The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s", actualClass->GetName(), branchname, ptrClass->GetName());
1685 if (actualClass && actualClass->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(actualClass->GetCollectionProxy())) {
1686 Error(
"Branch", writeStlWithoutProxyMsg,
1687 actualClass->GetName(), branchname, actualClass->GetName());
1690 return BronchExec(branchname, actualClass->GetName(), (
void*) addobj, kFALSE, bufsize, splitlevel);
1696 TBranch *TTree::BranchImpArr(
const char *branchname, EDataType datatype, std::size_t N,
void *addobj, Int_t bufsize,
1699 if (datatype == kOther_t || datatype == kNoType_t) {
1701 "The inner type of the std::array passed specified for %s is not of a class or type known to ROOT",
1705 varname.Form(
"%s[%d]/%c", branchname, (
int)N, DataTypeToChar(datatype));
1706 return Branch(branchname, addobj, varname.Data(), bufsize);
1714 Int_t TTree::Branch(TList* li, Int_t bufsize , Int_t splitlevel )
1716 return Branch((TCollection*) li, bufsize, splitlevel);
1798 Int_t TTree::Branch(TCollection* li, Int_t bufsize , Int_t splitlevel ,
const char* name )
1805 Int_t nbranches = GetListOfBranches()->GetEntries();
1806 if (li->InheritsFrom(TClonesArray::Class())) {
1807 Error(
"Branch",
"Cannot call this constructor for a TClonesArray");
1810 Int_t nch = strlen(name);
1813 while ((obj = next())) {
1814 if ((splitlevel > 1) && obj->InheritsFrom(TCollection::Class()) && !obj->InheritsFrom(TClonesArray::Class())) {
1815 TCollection* col = (TCollection*) obj;
1817 branchname.Form(
"%s_%s_", name, col->GetName());
1819 branchname.Form(
"%s_", col->GetName());
1821 Branch(col, bufsize, splitlevel - 1, branchname);
1823 if (nch && (name[nch-1] ==
'_')) {
1824 branchname.Form(
"%s%s", name, obj->GetName());
1827 branchname.Form(
"%s_%s", name, obj->GetName());
1829 branchname.Form(
"%s", obj->GetName());
1832 if (splitlevel > 99) {
1835 Bronch(branchname, obj->ClassName(), li->GetObjectRef(obj), bufsize, splitlevel - 1);
1838 return GetListOfBranches()->GetEntries() - nbranches;
1845 Int_t TTree::Branch(
const char* foldername, Int_t bufsize , Int_t splitlevel )
1847 TObject* ob = gROOT->FindObjectAny(foldername);
1851 if (ob->IsA() != TFolder::Class()) {
1854 Int_t nbranches = GetListOfBranches()->GetEntries();
1855 TFolder* folder = (TFolder*) ob;
1856 TIter next(folder->GetListOfFolders());
1858 char* curname =
new char[1000];
1860 while ((obj = next())) {
1861 snprintf(curname,1000,
"%s/%s", foldername, obj->GetName());
1862 if (obj->IsA() == TFolder::Class()) {
1863 Branch(curname, bufsize, splitlevel - 1);
1865 void* add = (
void*) folder->GetListOfFolders()->GetObjectRef(obj);
1866 for (Int_t i = 0; i < 1000; ++i) {
1867 if (curname[i] == 0) {
1870 if (curname[i] ==
'/') {
1874 Int_t noccur = folder->Occurence(obj);
1876 snprintf(occur,20,
"_%d", noccur);
1877 strlcat(curname, occur,1000);
1879 TBranchElement* br = (TBranchElement*) Bronch(curname, obj->ClassName(), add, bufsize, splitlevel - 1);
1880 if (br) br->SetBranchFolder();
1884 return GetListOfBranches()->GetEntries() - nbranches;
1948 TBranch* TTree::Branch(
const char* name,
void* address,
const char* leaflist, Int_t bufsize )
1950 TBranch* branch =
new TBranch(
this, name, address, leaflist, bufsize);
1951 if (branch->IsZombie()) {
1956 fBranches.Add(branch);
1983 TBranch* TTree::Branch(
const char* name,
const char* classname,
void* addobj, Int_t bufsize , Int_t splitlevel )
1985 if (fgBranchStyle == 1) {
1986 return Bronch(name, classname, addobj, bufsize, splitlevel);
1988 if (splitlevel < 0) {
1991 return BranchOld(name, classname, addobj, bufsize, splitlevel);
2036 TBranch* TTree::BranchOld(
const char* name,
const char* classname,
void* addobj, Int_t bufsize , Int_t splitlevel )
2038 TClass* cl = TClass::GetClass(classname);
2040 Error(
"BranchOld",
"Cannot find class: '%s'", classname);
2043 if (!cl->IsTObject()) {
2044 if (fgBranchStyle == 0) {
2045 Fatal(
"BranchOld",
"The requested class ('%s') does not inherit from TObject.\n"
2046 "\tfgBranchStyle is set to zero requesting by default to use BranchOld.\n"
2047 "\tIf this is intentional use Bronch instead of Branch or BranchOld.", classname);
2049 Fatal(
"BranchOld",
"The requested class ('%s') does not inherit from TObject.\n"
2050 "\tYou can not use BranchOld to store objects of this type.",classname);
2054 TBranch* branch =
new TBranchObject(
this, name, classname, addobj, bufsize, splitlevel);
2055 fBranches.Add(branch);
2060 TObjArray* blist = branch->GetListOfBranches();
2061 const char* rdname = 0;
2062 const char* dname = 0;
2064 char** apointer = (
char**) addobj;
2065 TObject* obj = (TObject*) *apointer;
2066 Bool_t delobj = kFALSE;
2068 obj = (TObject*) cl->New();
2072 BuildStreamerInfo(cl, obj);
2074 Int_t lenName = strlen(name);
2076 if (name[lenName-1] ==
'.') {
2079 TBranch* branch1 = 0;
2082 TIter nexti(cl->GetListOfRealData());
2083 TIter next(cl->GetListOfRealData());
2087 while ((rd = (TRealData*) next())) {
2088 if (rd->TestBit(TRealData::kTransient))
continue;
2091 TDataMember* dm = rd->GetDataMember();
2092 if (!dm->IsPersistent()) {
2096 if (rd->IsObject()) {
2103 TClass* clm = TClass::GetClass(dm->GetFullTypeName());
2105 BuildStreamerInfo(clm, (
char*) obj + rd->GetThisOffset());
2109 rdname = rd->GetName();
2110 dname = dm->GetName();
2111 if (cl->CanIgnoreTObjectStreamer()) {
2115 if (!strcmp(dname,
"fBits")) {
2118 if (!strcmp(dname,
"fUniqueID")) {
2122 TDataType* dtype = dm->GetDataType();
2125 code = dm->GetDataType()->GetType();
2128 branchname = rdname;
2130 if (dm->IsaPointer()) {
2132 branchname.Form(
"%s%s", name, &rdname[1]);
2134 branchname.Form(
"%s%s", name, &rdname[0]);
2139 Int_t offset = rd->GetThisOffset();
2140 char* pointer = ((
char*) obj) + offset;
2141 if (dm->IsaPointer()) {
2144 if (!dm->IsBasic()) {
2145 clobj = TClass::GetClass(dm->GetTypeName());
2147 if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
2149 char* cpointer = (
char*) pointer;
2150 char** ppointer = (
char**) cpointer;
2151 TClonesArray* li = (TClonesArray*) *ppointer;
2152 if (splitlevel != 2) {
2154 branch1 =
new TBranchClones(branch,branchname, pointer, bufsize);
2157 branch1 =
new TBranchClones(branch,&branchname.Data()[1], pointer, bufsize);
2159 blist->Add(branch1);
2162 branch1 =
new TBranchObject(branch, branchname, li->ClassName(), pointer, bufsize);
2165 branch1 =
new TBranchObject(branch, &branchname.Data()[1], li->ClassName(), pointer, bufsize);
2167 blist->Add(branch1);
2173 if (!clobj->IsTObject()) {
2176 branch1 =
new TBranchObject(branch, dname, clobj->GetName(), pointer, bufsize, 0);
2178 branch1->SetName(branchname);
2182 branch1->SetName(&branchname.Data()[1]);
2184 blist->Add(branch1);
2189 const char* index = dm->GetArrayIndex();
2195 TString aindex (rd->GetName());
2196 Ssiz_t rdot = aindex.Last(
'.');
2198 aindex.Remove(rdot+1);
2199 aindex.Append(index);
2202 while ((rdi = (TRealData*) nexti())) {
2203 if (rdi->TestBit(TRealData::kTransient))
continue;
2205 if (!strcmp(rdi->GetName(), index)) {
2208 if (!strcmp(rdi->GetName(), aindex)) {
2209 index = rdi->GetName();
2214 char vcode = DataTypeToChar((EDataType)code);
2220 leaflist.Form(
"%s[%s]/%c", &rdname[0], index, vcode);
2222 Error(
"BranchOld",
"Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2229 leaflist.Form(
"%s/%s", dname,
"C");
2237 TString bname( branchname );
2238 bname.ReplaceAll(
"*",
"");
2239 leaflist.ReplaceAll(
"*",
"");
2242 branch1 =
new TBranch(branch, bname, *((
void**) pointer), leaflist, bufsize);
2243 TLeaf* leaf = (TLeaf*) branch1->GetListOfLeaves()->At(0);
2244 leaf->SetBit(TLeaf::kIndirectAddress);
2245 leaf->SetAddress((
void**) pointer);
2246 blist->Add(branch1);
2248 }
else if (dm->IsBasic()) {
2251 char vcode = DataTypeToChar((EDataType)code);
2253 leaflist.Form(
"%s/%c", rdname, vcode);
2255 Error(
"BranchOld",
"Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2258 branch1 =
new TBranch(branch, branchname, pointer, leaflist, bufsize);
2259 branch1->SetTitle(rdname);
2260 blist->Add(branch1);
2267 branch1->SetOffset(offset);
2269 Warning(
"BranchOld",
"Cannot process member: '%s'", rdname);
2290 TBranch* TTree::BranchRef()
2293 fBranchRef =
new TBranchRef(
this);
2366 TBranch* TTree::Bronch(
const char* name,
const char* classname,
void* addr, Int_t bufsize , Int_t splitlevel )
2368 return BronchExec(name, classname, addr, kTRUE, bufsize, splitlevel);
2374 TBranch* TTree::BronchExec(
const char* name,
const char* classname,
void* addr, Bool_t isptrptr, Int_t bufsize , Int_t splitlevel )
2376 TClass* cl = TClass::GetClass(classname);
2378 Error(
"Bronch",
"Cannot find class:%s", classname);
2389 objptr = (
char*)addr;
2391 objptr = *((
char**) addr);
2394 if (cl == TClonesArray::Class()) {
2395 TClonesArray* clones = (TClonesArray*) objptr;
2397 Error(
"Bronch",
"Pointer to TClonesArray is null");
2400 if (!clones->GetClass()) {
2401 Error(
"Bronch",
"TClonesArray with no class defined in branch: %s", name);
2404 if (!clones->GetClass()->HasDataMemberInfo()) {
2405 Error(
"Bronch",
"TClonesArray with no dictionary defined in branch: %s", name);
2408 bool hasCustomStreamer = clones->GetClass()->TestBit(TClass::kHasCustomStreamerMember);
2409 if (splitlevel > 0) {
2410 if (hasCustomStreamer)
2411 Warning(
"Bronch",
"Using split mode on a class: %s with a custom Streamer", clones->GetClass()->GetName());
2413 if (hasCustomStreamer) clones->BypassStreamer(kFALSE);
2414 TBranchObject *branch =
new TBranchObject(
this,name,classname,addr,bufsize,0, -1,isptrptr);
2415 fBranches.Add(branch);
2420 if (cl->GetCollectionProxy()) {
2421 TVirtualCollectionProxy* collProxy = cl->GetCollectionProxy();
2425 TClass* inklass = collProxy->GetValueClass();
2426 if (!inklass && (collProxy->GetType() == 0)) {
2427 Error(
"Bronch",
"%s with no class defined in branch: %s", classname, name);
2430 if ((splitlevel > 0) && inklass && (inklass->GetCollectionProxy() == 0)) {
2431 ROOT::ESTLType stl = cl->GetCollectionType();
2432 if ((stl != ROOT::kSTLmap) && (stl != ROOT::kSTLmultimap)) {
2433 if (!inklass->HasDataMemberInfo()) {
2434 Error(
"Bronch",
"Container with no dictionary defined in branch: %s", name);
2437 if (inklass->TestBit(TClass::kHasCustomStreamerMember)) {
2438 Warning(
"Bronch",
"Using split mode on a class: %s with a custom Streamer", inklass->GetName());
2448 if( splitlevel > kSplitCollectionOfPointers && collProxy->HasPointers() )
2449 branch =
new TBranchSTL(
this, name, collProxy, bufsize, splitlevel );
2451 branch =
new TBranchElement(
this, name, collProxy, bufsize, splitlevel);
2452 fBranches.Add(branch);
2454 branch->SetAddress(addr);
2456 branch->SetObject(addr);
2461 Bool_t hasCustomStreamer = kFALSE;
2462 if (!cl->HasDataMemberInfo() && !cl->GetCollectionProxy()) {
2463 Error(
"Bronch",
"Cannot find dictionary for class: %s", classname);
2467 if (!cl->GetCollectionProxy() && cl->TestBit(TClass::kHasCustomStreamerMember)) {
2469 hasCustomStreamer = kTRUE;
2472 if (splitlevel < 0 || ((splitlevel == 0) && hasCustomStreamer && cl->IsTObject())) {
2473 TBranchObject* branch =
new TBranchObject(
this, name, classname, addr, bufsize, 0, ROOT::RCompressionSetting::EAlgorithm::kInherit, isptrptr);
2474 fBranches.Add(branch);
2478 if (cl == TClonesArray::Class()) {
2484 TBranchElement* branch =
new TBranchElement(
this, name, (TClonesArray*) objptr, bufsize, splitlevel%kSplitCollectionOfPointers);
2485 fBranches.Add(branch);
2487 branch->SetAddress(addr);
2489 branch->SetObject(addr);
2500 Bool_t delobj = kFALSE;
2503 objptr = (
char*) cl->New();
2511 if ((splitlevel > 0) && !cl->CanSplit()) {
2512 if (splitlevel != 99) {
2513 Warning(
"Bronch",
"%s cannot be split, resetting splitlevel to 0", cl->GetName());
2525 TStreamerInfo* sinfo = BuildStreamerInfo(cl, objptr, splitlevel==0);
2527 Error(
"Bronch",
"Cannot build the StreamerInfo for class: %s", cl->GetName());
2536 if (splitlevel > 0) {
2539 TBranchElement* branch =
new TBranchElement(
this, name, sinfo,
id, objptr, bufsize, splitlevel);
2540 fBranches.Add(branch);
2546 if (splitlevel%kSplitCollectionOfPointers > 0) {
2547 branch->Unroll(name, cl, sinfo, objptr, bufsize, splitlevel);
2555 branch->SetAddress(addr);
2557 branch->SetObject(addr);
2561 cl->Destructor(objptr);
2571 void TTree::Browse(TBrowser* b)
2573 fBranches.Browse(b);
2575 if (strcmp(
"TList",fUserInfo->GetName())==0) {
2576 fUserInfo->SetName(
"UserInfo");
2578 fUserInfo->SetName(
"TList");
2599 Int_t TTree::BuildIndex(
const char* majorname,
const char* minorname )
2601 fTreeIndex = GetPlayer()->BuildIndex(
this, majorname, minorname);
2602 if (fTreeIndex->IsZombie()) {
2607 return fTreeIndex->GetN();
2614 TStreamerInfo* TTree::BuildStreamerInfo(TClass* cl,
void* pointer , Bool_t canOptimize )
2619 cl->BuildRealData(pointer);
2620 TStreamerInfo* sinfo = (TStreamerInfo*)cl->GetStreamerInfo(cl->GetClassVersion());
2623 TBaseClass* base = 0;
2624 TIter nextb(cl->GetListOfBases());
2625 while((base = (TBaseClass*) nextb())) {
2626 if (base->IsSTLContainer()) {
2629 TClass* clm = TClass::GetClass(base->GetName());
2630 BuildStreamerInfo(clm, pointer, canOptimize);
2632 if (sinfo && fDirectory) {
2633 sinfo->ForceWriteInfo(fDirectory->GetFile());
2689 TFile* TTree::ChangeFile(TFile* file)
2694 constexpr
auto kBufSize = 2000;
2695 char* fname =
new char[kBufSize];
2698 for (Int_t i = 0; i < 10; ++i) {
2706 strlcpy(fname, file->GetName(), kBufSize);
2708 if (fFileNumber > 1) {
2709 char* cunder = strrchr(fname,
'_');
2711 snprintf(cunder, kBufSize - Int_t(cunder - fname),
"%s%d", uscore, fFileNumber);
2712 const char* cdot = strrchr(file->GetName(),
'.');
2714 strlcat(fname, cdot, kBufSize);
2718 snprintf(fcount,21,
"%s%d", uscore, fFileNumber);
2719 strlcat(fname, fcount, kBufSize);
2722 char* cdot = strrchr(fname,
'.');
2724 snprintf(cdot, kBufSize - Int_t(fname-cdot),
"%s%d", uscore, fFileNumber);
2725 strlcat(fname, strrchr(file->GetName(),
'.'), kBufSize);
2728 snprintf(fcount,21,
"%s%d", uscore, fFileNumber);
2729 strlcat(fname, fcount, kBufSize);
2732 if (gSystem->AccessPathName(fname)) {
2736 Warning(
"ChangeFile",
"file %s already exist, trying with %d underscores", fname, nus+1);
2738 Int_t compress = file->GetCompressionSettings();
2739 TFile* newfile = TFile::Open(fname,
"recreate",
"chain files", compress);
2741 Error(
"Fill",
"Failed to open new file %s, continuing as a memory tree.",fname);
2743 Printf(
"Fill: Switching to new file: %s", fname);
2747 TBranch* branch = 0;
2749 while ((obj = file->GetList()->First())) {
2752 if (obj->InheritsFrom(
"TH1")) {
2753 gROOT->ProcessLine(TString::Format(
"((%s*)0x%lx)->SetDirectory((TDirectory*)0x%lx);", obj->ClassName(), (Long_t) obj, (Long_t) newfile));
2757 if (obj->InheritsFrom(TTree::Class())) {
2758 TTree* t = (TTree*) obj;
2762 t->fFileNumber = fFileNumber;
2764 t->SetDirectory(newfile);
2765 TIter nextb(t->GetListOfBranches());
2766 while ((branch = (TBranch*)nextb())) {
2767 branch->SetFile(newfile);
2769 if (t->GetBranchRef()) {
2770 t->GetBranchRef()->SetFile(newfile);
2775 if (newfile) newfile->Append(obj);
2803 Int_t TTree::CheckBranchAddressType(TBranch* branch, TClass* ptrClass, EDataType datatype, Bool_t isptr)
2805 if (GetMakeClass()) {
2811 TClass* expectedClass = 0;
2812 EDataType expectedType = kOther_t;
2813 if (0 != branch->GetExpectedType(expectedClass,expectedType) ) {
2815 return kInternalError;
2817 if (expectedClass && datatype == kOther_t && ptrClass == 0) {
2818 if (branch->InheritsFrom( TBranchElement::Class() )) {
2819 TBranchElement* bEl = (TBranchElement*)branch;
2820 bEl->SetTargetClass( expectedClass->GetName() );
2822 if (expectedClass && expectedClass->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(expectedClass->GetCollectionProxy())) {
2823 Error(
"SetBranchAddress",
"Unable to determine the type given for the address for \"%s\". "
2824 "The class expected (%s) refers to an stl collection and do not have a compiled CollectionProxy. "
2825 "Please generate the dictionary for this class (%s)",
2826 branch->GetName(), expectedClass->GetName(), expectedClass->GetName());
2827 return kMissingCompiledCollectionProxy;
2829 if (!expectedClass->IsLoaded()) {
2832 Error(
"SetBranchAddress",
"Unable to determine the type given for the address for \"%s\". "
2833 "The class expected (%s) does not have a dictionary and needs to be emulated for I/O purposes but is being passed a compiled object."
2834 "Please generate the dictionary for this class (%s)",
2835 branch->GetName(), expectedClass->GetName(), expectedClass->GetName());
2837 Error(
"SetBranchAddress",
"Unable to determine the type given for the address for \"%s\". "
2838 "This is probably due to a missing dictionary, the original data class for this branch is %s.", branch->GetName(), expectedClass->GetName());
2840 return kClassMismatch;
2842 if (expectedClass && ptrClass && (branch->GetMother() == branch)) {
2845 Error(
"SetBranchAddress",
"The address for \"%s\" should be the address of a pointer!", branch->GetName());
2848 if (expectedType == kFloat16_t) {
2849 expectedType = kFloat_t;
2851 if (expectedType == kDouble32_t) {
2852 expectedType = kDouble_t;
2854 if (datatype == kFloat16_t) {
2855 datatype = kFloat_t;
2857 if (datatype == kDouble32_t) {
2858 datatype = kDouble_t;
2865 if( expectedClass && ptrClass &&
2866 expectedClass != ptrClass &&
2867 branch->InheritsFrom( TBranchElement::Class() ) &&
2868 ptrClass->GetSchemaRules() &&
2869 ptrClass->GetSchemaRules()->HasRuleWithSourceClass( expectedClass->GetName() ) ) {
2870 TBranchElement* bEl = (TBranchElement*)branch;
2872 if ( ptrClass->GetCollectionProxy() && expectedClass->GetCollectionProxy() ) {
2874 Info(
"SetBranchAddress",
"Matching STL collection (at least according to the SchemaRuleSet when "
2875 "reading a %s into a %s",expectedClass->GetName(),ptrClass->GetName());
2877 bEl->SetTargetClass( ptrClass->GetName() );
2878 return kMatchConversion;
2880 }
else if ( !ptrClass->GetConversionStreamerInfo( expectedClass, bEl->GetClassVersion() ) &&
2881 !ptrClass->FindConversionStreamerInfo( expectedClass, bEl->GetCheckSum() ) ) {
2882 Error(
"SetBranchAddress",
"The pointer type given \"%s\" does not correspond to the type needed \"%s\" by the branch: %s", ptrClass->GetName(), bEl->GetClassName(), branch->GetName());
2884 bEl->SetTargetClass( expectedClass->GetName() );
2885 return kClassMismatch;
2889 bEl->SetTargetClass( ptrClass->GetName() );
2890 return kMatchConversion;
2893 }
else if (expectedClass && ptrClass && !expectedClass->InheritsFrom(ptrClass)) {
2895 if (expectedClass->GetCollectionProxy() && ptrClass->GetCollectionProxy() &&
2896 branch->InheritsFrom( TBranchElement::Class() ) &&
2897 expectedClass->GetCollectionProxy()->GetValueClass() &&
2898 ptrClass->GetCollectionProxy()->GetValueClass() )
2903 TClass *onfileValueClass = expectedClass->GetCollectionProxy()->GetValueClass();
2904 TClass *inmemValueClass = ptrClass->GetCollectionProxy()->GetValueClass();
2906 if (inmemValueClass->GetSchemaRules() &&
2907 inmemValueClass->GetSchemaRules()->HasRuleWithSourceClass(onfileValueClass->GetName() ) )
2909 TBranchElement* bEl = (TBranchElement*)branch;
2910 bEl->SetTargetClass( ptrClass->GetName() );
2911 return kMatchConversionCollection;
2915 Error(
"SetBranchAddress",
"The pointer type given (%s) does not correspond to the class needed (%s) by the branch: %s", ptrClass->GetName(), expectedClass->GetName(), branch->GetName());
2916 if (branch->InheritsFrom( TBranchElement::Class() )) {
2917 TBranchElement* bEl = (TBranchElement*)branch;
2918 bEl->SetTargetClass( expectedClass->GetName() );
2920 return kClassMismatch;
2922 }
else if ((expectedType != kOther_t) && (datatype != kOther_t) && (expectedType != kNoType_t) && (datatype != kNoType_t) && (expectedType != datatype)) {
2923 if (datatype != kChar_t) {
2925 Error(
"SetBranchAddress",
"The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" (%d) by the branch: %s",
2926 TDataType::GetTypeName(datatype), datatype, TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
2929 }
else if ((expectedClass && (datatype != kOther_t && datatype != kNoType_t && datatype != kInt_t)) ||
2930 (ptrClass && (expectedType != kOther_t && expectedType != kNoType_t && datatype != kInt_t)) ) {
2932 if (expectedClass) {
2933 Error(
"SetBranchAddress",
"The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" by the branch: %s",
2934 TDataType::GetTypeName(datatype), datatype, expectedClass->GetName(), branch->GetName());
2935 if (branch->InheritsFrom( TBranchElement::Class() )) {
2936 TBranchElement* bEl = (TBranchElement*)branch;
2937 bEl->SetTargetClass( expectedClass->GetName() );
2943 if (ptrClass->IsLoaded()) {
2944 TIter next(ptrClass->GetListOfRealData());
2946 while ((rdm = (TRealData*)next())) {
2947 if (rdm->GetThisOffset() == 0) {
2948 TDataType *dmtype = rdm->GetDataMember()->GetDataType();
2950 EDataType etype = (EDataType)dmtype->GetType();
2951 if (etype == expectedType) {
2959 TIter next(ptrClass->GetListOfDataMembers());
2961 while ((dm = (TDataMember*)next())) {
2962 if (dm->GetOffset() == 0) {
2963 TDataType *dmtype = dm->GetDataType();
2965 EDataType etype = (EDataType)dmtype->GetType();
2966 if (etype == expectedType) {
2976 TLeaf *last = (TLeaf*)branch->GetListOfLeaves()->Last();
2977 long len = last->GetOffset() + last->GetLenType() * last->GetLen();
2978 if (len <= ptrClass->Size()) {
2982 Error(
"SetBranchAddress",
"The pointer type given \"%s\" does not correspond to the type needed \"%s\" (%d) by the branch: %s",
2983 ptrClass->GetName(), TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
2987 if (expectedClass && expectedClass->GetCollectionProxy() &&
dynamic_cast<TEmulatedCollectionProxy*
>(expectedClass->GetCollectionProxy())) {
2988 Error(
"SetBranchAddress", writeStlWithoutProxyMsg,
2989 expectedClass->GetName(), branch->GetName(), expectedClass->GetName());
2990 if (branch->InheritsFrom( TBranchElement::Class() )) {
2991 TBranchElement* bEl = (TBranchElement*)branch;
2992 bEl->SetTargetClass( expectedClass->GetName() );
2994 return kMissingCompiledCollectionProxy;
2996 if (expectedClass && branch->InheritsFrom( TBranchElement::Class() )) {
2997 TBranchElement* bEl = (TBranchElement*)branch;
2998 bEl->SetTargetClass( expectedClass->GetName() );
3067 TTree* TTree::CloneTree(Long64_t nentries , Option_t* option )
3070 Bool_t fastClone = kFALSE;
3072 TString opt = option;
3074 if (opt.Contains(
"fast")) {
3079 if ((fEntries > 0) && (LoadTree(0) < 0)) {
3086 TTree* thistree = GetTree();
3089 ROOT::TIOFeatures features = this->GetIOFeatures();
3094 TTree* newtree = (TTree*) thistree->Clone();
3100 TObjArray* branches = newtree->GetListOfBranches();
3101 Int_t nb = branches->GetEntriesFast();
3102 for (Int_t i = 0; i < nb; ++i) {
3103 TBranch* br = (TBranch*) branches->UncheckedAt(i);
3104 if (br->InheritsFrom(TBranchElement::Class())) {
3105 ((TBranchElement*) br)->ResetDeleteObject();
3111 thistree->AddClone(newtree);
3112 if (thistree !=
this) {
3120 TDirectory* ndir = newtree->GetDirectory();
3123 nfile = ndir->GetFile();
3127 newcomp = nfile->GetCompressionSettings();
3135 TObjArray* leaves = newtree->GetListOfLeaves();
3136 Int_t nleaves = leaves->GetEntriesFast();
3137 for (Int_t lndx = 0; lndx < nleaves; ++lndx) {
3138 TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(lndx);
3142 TBranch* branch = leaf->GetBranch();
3143 if (branch && (newcomp > -1)) {
3144 branch->SetCompressionSettings(newcomp);
3146 if (branch) branch->SetIOFeatures(features);
3147 if (!branch || !branch->TestBit(kDoNotProcess)) {
3151 nb = branches->GetEntriesFast();
3152 for (Long64_t i = 0; i < nb; ++i) {
3153 TBranch* br = (TBranch*) branches->UncheckedAt(i);
3155 branches->RemoveAt(i);
3158 branches->Compress();
3161 TObjArray* lb = br->GetListOfBranches();
3162 Int_t nb1 = lb->GetEntriesFast();
3163 for (Int_t j = 0; j < nb1; ++j) {
3164 TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
3175 TObjArray* lb1 = b1->GetListOfBranches();
3176 Int_t nb2 = lb1->GetEntriesFast();
3177 for (Int_t k = 0; k < nb2; ++k) {
3178 TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
3196 newtree->SetMakeClass(fMakeClass);
3199 CopyAddresses(newtree);
3205 if (nentries != 0) {
3206 if (fastClone && (nentries < 0)) {
3207 if ( newtree->CopyEntries(
this, -1, option ) < 0 ) {
3209 Error(
"CloneTTree",
"TTree has not been cloned\n");
3215 newtree->CopyEntries(
this, nentries, option );
3227 void TTree::CopyAddresses(TTree* tree, Bool_t undo)
3230 TObjArray* branches = GetListOfBranches();
3231 Int_t nbranches = branches->GetEntriesFast();
3232 for (Int_t i = 0; i < nbranches; ++i) {
3233 TBranch* branch = (TBranch*) branches->UncheckedAt(i);
3234 if (branch->TestBit(kDoNotProcess)) {
3238 TBranch* br = tree->GetBranch(branch->GetName());
3239 tree->ResetBranchAddress(br);
3241 char* addr = branch->GetAddress();
3243 if (branch->IsA() == TBranch::Class()) {
3246 TLeaf *firstleaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
3247 if (!firstleaf || firstleaf->GetValuePointer()) {
3255 branch->SetAddress(0);
3256 addr = branch->GetAddress();
3260 TBranch* br = tree->GetBranch(branch->GetName());
3262 br->SetAddress(addr);
3264 if (br->InheritsFrom(TBranchElement::Class())) {
3265 ((TBranchElement*) br)->ResetDeleteObject();
3268 Warning(
"CopyAddresses",
"Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
3274 TObjArray* tleaves = tree->GetListOfLeaves();
3275 Int_t ntleaves = tleaves->GetEntriesFast();
3276 for (Int_t i = 0; i < ntleaves; ++i) {
3277 TLeaf* tleaf = (TLeaf*) tleaves->UncheckedAt(i);
3278 TBranch* tbranch = tleaf->GetBranch();
3279 TBranch* branch = GetBranch(tbranch->GetName());
3283 TLeaf* leaf = branch->GetLeaf(tleaf->GetName());
3287 if (branch->TestBit(kDoNotProcess)) {
3292 tree->ResetBranchAddress(tbranch);
3294 TBranchElement *mother =
dynamic_cast<TBranchElement*
>(leaf->GetBranch()->GetMother());
3295 if (leaf->GetLeafCount() && (leaf->TestBit(TLeaf::kNewValue) || !leaf->GetValuePointer() || (mother && mother->IsObjectOwner())) && tleaf->GetLeafCount())
3299 if (leaf->GetLeafCount()->GetMaximum() < tleaf->GetLeafCount()->GetMaximum()) {
3300 leaf->GetLeafCount()->IncludeRange( tleaf->GetLeafCount() );
3301 if (leaf->GetValuePointer()) {
3302 if (leaf->IsA() == TLeafElement::Class() && mother)
3303 mother->ResetAddress();
3305 leaf->SetAddress(
nullptr);
3309 if (!branch->GetAddress() && !leaf->GetValuePointer()) {
3317 branch->SetupAddresses();
3319 if (branch->GetAddress()) {
3320 tree->SetBranchAddress(branch->GetName(), (
void*) branch->GetAddress());
3321 TBranch* br = tree->GetBranch(branch->GetName());
3325 if (br->InheritsFrom(TBranchElement::Class())) {
3326 ((TBranchElement*) br)->ResetDeleteObject();
3329 Warning(
"CopyAddresses",
"Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
3332 tleaf->SetAddress(leaf->GetValuePointer());
3338 ( tree->IsA()->InheritsFrom(
"TNtuple") || tree->IsA()->InheritsFrom(
"TNtupleD") )
3340 tree->ResetBranchAddresses();
3346 enum EOnIndexError { kDrop, kKeep, kBuild };
3348 static Bool_t R__HandleIndex(EOnIndexError onIndexError, TTree *newtree, TTree *oldtree)
3352 Bool_t withIndex = kTRUE;
3354 if ( newtree->GetTreeIndex() ) {
3355 if ( oldtree->GetTree()->GetTreeIndex() == 0 ) {
3356 switch (onIndexError) {
3358 delete newtree->GetTreeIndex();
3359 newtree->SetTreeIndex(0);
3367 if (oldtree->GetTree()->BuildIndex(newtree->GetTreeIndex()->GetMajorName(), newtree->GetTreeIndex()->GetMinorName())) {
3368 newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3370 delete oldtree->GetTree()->GetTreeIndex();
3371 oldtree->GetTree()->SetTreeIndex(0);
3376 newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3378 }
else if ( oldtree->GetTree()->GetTreeIndex() != 0 ) {
3380 switch (onIndexError) {
3385 TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
3386 index->SetTree(newtree);
3387 newtree->SetTreeIndex(index);
3391 if (newtree->GetEntries() == 0) {
3393 TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
3394 index->SetTree(newtree);
3395 newtree->SetTreeIndex(index);
3398 if (newtree->BuildIndex(oldtree->GetTree()->GetTreeIndex()->GetMajorName(), oldtree->GetTree()->GetTreeIndex()->GetMinorName())) {
3399 newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3404 }
else if ( onIndexError == kDrop ) {
3449 Long64_t TTree::CopyEntries(TTree* tree, Long64_t nentries , Option_t* option )
3455 TString opt = option;
3457 Bool_t fastClone = opt.Contains(
"fast");
3458 Bool_t withIndex = !opt.Contains(
"noindex");
3459 EOnIndexError onIndexError;
3460 if (opt.Contains(
"asisindex")) {
3461 onIndexError = kKeep;
3462 }
else if (opt.Contains(
"buildindex")) {
3463 onIndexError = kBuild;
3464 }
else if (opt.Contains(
"dropindex")) {
3465 onIndexError = kDrop;
3467 onIndexError = kBuild;
3469 Ssiz_t cacheSizeLoc = opt.Index(
"cachesize=");
3470 Int_t cacheSize = -1;
3471 if (cacheSizeLoc != TString::kNPOS) {
3473 Ssiz_t cacheSizeEnd = opt.Index(
" ",cacheSizeLoc+10) - (cacheSizeLoc+10);
3474 TSubString cacheSizeStr( opt(cacheSizeLoc+10,cacheSizeEnd) );
3475 auto parseResult = ROOT::FromHumanReadableSize(cacheSizeStr,cacheSize);
3476 if (parseResult == ROOT::EFromHumanReadableSize::kParseFail) {
3477 Warning(
"CopyEntries",
"The cachesize option can not be parsed: %s. The default size will be used.",cacheSizeStr.String().Data());
3478 }
else if (parseResult == ROOT::EFromHumanReadableSize::kOverflow) {
3480 const char *munit =
nullptr;
3481 ROOT::ToHumanReadableSize(std::numeric_limits<decltype(cacheSize)>::max(),
false,&m,&munit);
3483 Warning(
"CopyEntries",
"The cachesize option is too large: %s (%g%s max). The default size will be used.",cacheSizeStr.String().Data(),m,munit);
3486 if (gDebug > 0 && cacheSize != -1) Info(
"CopyEntries",
"Using Cache size: %d\n",cacheSize);
3488 Long64_t nbytes = 0;
3489 Long64_t treeEntries = tree->GetEntriesFast();
3491 nentries = treeEntries;
3492 }
else if (nentries > treeEntries) {
3493 nentries = treeEntries;
3496 if (fastClone && (nentries < 0 || nentries == tree->GetEntriesFast())) {
3498 Long64_t totbytes = GetTotBytes();
3499 for (Long64_t i = 0; i < nentries; i += tree->GetTree()->GetEntries()) {
3500 if (tree->LoadTree(i) < 0) {
3504 withIndex = R__HandleIndex( onIndexError,
this, tree );
3506 if (this->GetDirectory()) {
3507 TFile* file2 = this->GetDirectory()->GetFile();
3508 if (file2 && (file2->GetEND() > TTree::GetMaxTreeSize())) {
3509 if (this->GetDirectory() == (TDirectory*) file2) {
3510 this->ChangeFile(file2);
3514 TTreeCloner cloner(tree->GetTree(),
this, option, TTreeCloner::kNoWarnings);
3515 if (cloner.IsValid()) {
3516 this->SetEntries(this->GetEntries() + tree->GetTree()->GetEntries());
3517 if (cacheSize != -1) cloner.SetCacheSize(cacheSize);
3521 Warning(
"CopyEntries",
"%s",cloner.GetWarning());
3526 if (cloner.NeedConversion()) {
3527 TTree *localtree = tree->GetTree();
3528 Long64_t tentries = localtree->GetEntries();
3529 for (Long64_t ii = 0; ii < tentries; ii++) {
3530 if (localtree->GetEntry(ii) <= 0) {
3535 if (this->GetTreeIndex()) {
3536 this->GetTreeIndex()->Append(tree->GetTree()->GetTreeIndex(), kTRUE);
3539 Warning(
"CopyEntries",
"%s",cloner.GetWarning());
3540 if (tree->GetDirectory() && tree->GetDirectory()->GetFile()) {
3541 Warning(
"CopyEntries",
"Skipped file %s\n", tree->GetDirectory()->GetFile()->GetName());
3543 Warning(
"CopyEntries",
"Skipped file number %d\n", tree->GetTreeNumber());
3550 if (this->GetTreeIndex()) {
3551 this->GetTreeIndex()->Append(0,kFALSE);
3553 nbytes = GetTotBytes() - totbytes;
3556 nentries = treeEntries;
3557 }
else if (nentries > treeEntries) {
3558 nentries = treeEntries;
3560 Int_t treenumber = -1;
3561 for (Long64_t i = 0; i < nentries; i++) {
3562 if (tree->LoadTree(i) < 0) {
3565 if (treenumber != tree->GetTreeNumber()) {
3567 withIndex = R__HandleIndex( onIndexError,
this, tree );
3569 treenumber = tree->GetTreeNumber();
3571 if (tree->GetEntry(i) <= 0) {
3574 nbytes += this->Fill();
3576 if (this->GetTreeIndex()) {
3577 this->GetTreeIndex()->Append(0,kFALSE);
3618 TTree* TTree::CopyTree(
const char* selection, Option_t* option , Long64_t nentries , Long64_t firstentry )
3622 return fPlayer->CopyTree(selection, option, nentries, firstentry);
3630 TBasket* TTree::CreateBasket(TBranch* branch)
3635 return new TBasket(branch->GetName(), GetName(), branch);
3646 void TTree::Delete(Option_t* option )
3648 TFile *file = GetCurrentFile();
3651 if (file && !strcmp(option,
"all")) {
3652 if (!file->IsWritable()) {
3653 Error(
"Delete",
"File : %s is not writable, cannot delete Tree:%s", file->GetName(),GetName());
3658 TKey *key = fDirectory->GetKey(GetName());
3661 TDirectory *dirsav = gDirectory;
3665 TIter next(GetListOfLeaves());
3670 Int_t nbytes,objlen,keylen;
3671 while ((leaf = (TLeaf*)next())) {
3672 TBranch *branch = leaf->GetBranch();
3673 Int_t nbaskets = branch->GetMaxBaskets();
3674 for (Int_t i=0;i<nbaskets;i++) {
3675 Long64_t pos = branch->GetBasketSeek(i);
3677 TFile *branchFile = branch->GetFile();
3678 if (!branchFile)
continue;
3679 branchFile->GetRecordHeader(header,pos,16,nbytes,objlen,keylen);
3680 if (nbytes <= 0)
continue;
3681 branchFile->MakeFree(pos,pos+nbytes-1);
3690 ntot += key->GetNbytes();
3693 key = fDirectory->GetKey(GetName());
3695 if (dirsav) dirsav->cd();
3696 if (gDebug) Info(
"TTree::Delete",
"Deleting Tree: %s: %d baskets deleted. Total space freed = %d bytes\n",GetName(),nbask,ntot);
3700 fDirectory->Remove(
this);
3702 MoveReadCache(file,0);
3704 ResetBit(kMustCleanup);
3708 gCling->DeleteGlobal(
this);
3718 void TTree::DirectoryAutoAdd(TDirectory* dir)
3720 if (fDirectory == dir)
return;
3722 fDirectory->Remove(
this);
3724 TFile *file = fDirectory->GetFile();
3725 MoveReadCache(file,dir);
3729 TIter next(GetListOfBranches());
3730 while((b = (TBranch*) next())) {
3734 fBranchRef->UpdateFile();
3736 if (fDirectory) fDirectory->Append(
this);
3754 Long64_t TTree::Draw(
const char* varexp,
const TCut& selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
3756 return TTree::Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
4378 Long64_t TTree::Draw(
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
4382 return fPlayer->DrawSelect(varexp,selection,option,nentries,firstentry);
4389 void TTree::DropBaskets()
4391 TBranch* branch = 0;
4392 Int_t nb = fBranches.GetEntriesFast();
4393 for (Int_t i = 0; i < nb; ++i) {
4394 branch = (TBranch*) fBranches.UncheckedAt(i);
4395 branch->DropBaskets(
"all");
4402 void TTree::DropBuffers(Int_t)
4406 Int_t nleaves = fLeaves.GetEntriesFast();
4407 for (Int_t i = 0; i < nleaves; ++i) {
4408 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
4409 TBranch* branch = (TBranch*) leaf->GetBranch();
4410 Int_t nbaskets = branch->GetListOfBaskets()->GetEntries();
4411 for (Int_t j = 0; j < nbaskets - 1; ++j) {
4412 if ((j == branch->GetReadBasket()) || (j == branch->GetWriteBasket())) {
4415 TBasket* basket = (TBasket*)branch->GetListOfBaskets()->UncheckedAt(j);
4417 ndrop += basket->DropBuffers();
4418 if (fTotalBuffers < fMaxVirtualSize) {
4475 Int_t nbranches = fBranches.GetEntriesFast();
4480 ((TBranch *)fBranches.UncheckedAt(0))->UpdateAddress();
4483 fBranchRef->Clear();
4486 const auto useIMT = ROOT::IsImplicitMTEnabled() && fIMTEnabled;
4487 ROOT::Internal::TBranchIMTHelper imtHelper;
4490 fIMTZipBytes.store(0);
4491 fIMTTotBytes.store(0);
4495 for (Int_t i = 0; i < nbranches; ++i) {
4497 TBranch *branch = (TBranch *)fBranches.UncheckedAt(i);
4499 if (branch->TestBit(kDoNotProcess))
4503 nwrite = branch->FillImpl(
nullptr);
4505 nwrite = branch->FillImpl(useIMT ? &imtHelper :
nullptr);
4509 Error(
"Fill",
"Failed filling branch:%s.%s, nbytes=%d, entry=%lld\n"
4510 " This error is symptomatic of a Tree created as a memory-resident Tree\n"
4511 " Instead of doing:\n"
4512 " TTree *T = new TTree(...)\n"
4513 " TFile *f = new TFile(...)\n"
4515 " TFile *f = new TFile(...)\n"
4516 " TTree *T = new TTree(...)\n\n",
4517 GetName(), branch->GetName(), nwrite, fEntries + 1);
4519 Error(
"Fill",
"Failed filling branch:%s.%s, nbytes=%d, entry=%lld", GetName(), branch->GetName(), nwrite,
4532 const_cast<TTree *
>(
this)->AddTotBytes(fIMTTotBytes);
4533 const_cast<TTree *
>(
this)->AddZipBytes(fIMTZipBytes);
4534 nbytes += imtHelper.GetNbytes();
4535 nerror += imtHelper.GetNerrors();
4544 if (fEntries > fMaxEntries)
4548 Info(
"TTree::Fill",
" - A: %d %lld %lld %lld %lld %lld %lld \n", nbytes, fEntries, fAutoFlush, fAutoSave,
4549 GetZipBytes(), fFlushedBytes, fSavedBytes);
4551 bool autoFlush =
false;
4552 bool autoSave =
false;
4554 if (fAutoFlush != 0 || fAutoSave != 0) {
4556 if (fFlushedBytes == 0) {
4562 Long64_t zipBytes = GetZipBytes();
4565 autoFlush = fAutoFlush < 0 ? (zipBytes > -fAutoFlush) : fEntries % fAutoFlush == 0;
4568 autoSave = fAutoSave < 0 ? (zipBytes > -fAutoSave) : fEntries % fAutoSave == 0;
4570 if (autoFlush || autoSave) {
4578 if (!TestBit(TTree::kOnlyFlushAtCluster)) {
4579 OptimizeBaskets(GetTotBytes(), 1,
"");
4581 Info(
"TTree::Fill",
"OptimizeBaskets called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",
4582 fEntries, GetZipBytes(), fFlushedBytes);
4584 fFlushedBytes = GetZipBytes();
4585 fAutoFlush = fEntries;
4588 if (fAutoSave < 0) {
4592 Long64_t totBytes = GetTotBytes();
4593 if (zipBytes != 0) {
4594 fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / zipBytes) / fEntries));
4595 }
else if (totBytes != 0) {
4596 fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / totBytes) / fEntries));
4598 TBufferFile b(TBuffer::kWrite, 10000);
4599 TTree::Class()->WriteBuffer(b, (TTree *)
this);
4600 Long64_t total = b.Length();
4601 fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / total) / fEntries));
4603 }
else if (fAutoSave > 0) {
4604 fAutoSave = fAutoFlush * (fAutoSave / fAutoFlush);
4607 if (fAutoSave != 0 && fEntries >= fAutoSave)
4611 Info(
"TTree::Fill",
"First AutoFlush. fAutoFlush = %lld, fAutoSave = %lld\n", fAutoFlush, fAutoSave);
4616 if (fNClusterRange == 0)
4617 autoFlush = fEntries > 1 && fEntries % fAutoFlush == 0;
4619 autoFlush = (fEntries - (fClusterRangeEnd[fNClusterRange - 1] + 1)) % fAutoFlush == 0;
4623 autoSave = fEntries % fAutoSave == 0;
4630 Info(
"TTree::Fill",
"FlushBaskets() called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n", fEntries,
4631 GetZipBytes(), fFlushedBytes);
4632 fFlushedBytes = GetZipBytes();
4638 Info(
"TTree::Fill",
"AutoSave called at entry %lld, fZipBytes=%lld, fSavedBytes=%lld\n", fEntries,
4639 GetZipBytes(), fSavedBytes);
4647 if (TFile *file = fDirectory->GetFile())
4648 if ((TDirectory *)file == fDirectory && (file->GetEND() > fgMaxTreeSize))
4651 return nerror == 0 ? nbytes : -1;
4658 static TBranch *R__FindBranchHelper(TObjArray *list,
const char *branchname) {
4659 if (list==0 || branchname == 0 || branchname[0] ==
'\0')
return 0;
4661 Int_t nbranches = list->GetEntries();
4663 UInt_t brlen = strlen(branchname);
4665 for(Int_t index = 0; index < nbranches; ++index) {
4666 TBranch *where = (TBranch*)list->UncheckedAt(index);
4668 const char *name = where->GetName();
4669 UInt_t len = strlen(name);
4670 if (len && name[len-1]==
']') {
4671 const char *dim = strchr(name,
'[');
4676 if (brlen == len && strncmp(branchname,name,len)==0) {
4680 if ((brlen >= len) && (branchname[len] ==
'.')
4681 && strncmp(name, branchname, len) == 0) {
4684 next = where->FindBranch(branchname);
4686 next = where->FindBranch(branchname+len+1);
4688 if (next)
return next;
4690 const char *dot = strchr((
char*)branchname,
'.');
4692 if (len==(
size_t)(dot-branchname) &&
4693 strncmp(branchname,name,dot-branchname)==0 ) {
4694 return R__FindBranchHelper(where->GetListOfBranches(),dot+1);
4706 TBranch* TTree::FindBranch(
const char* branchname)
4710 if (kFindBranch & fFriendLockStatus) {
4714 TBranch* branch = 0;
4719 if (strncmp(fName.Data(),branchname,fName.Length())==0 && branchname[fName.Length()]==
'.') {
4720 branch = R__FindBranchHelper( GetListOfBranches(), branchname + fName.Length() + 1);
4721 if (branch)
return branch;
4724 branch = R__FindBranchHelper(GetListOfBranches(), branchname);
4725 if (branch)
return branch;
4728 TIter next(GetListOfBranches());
4729 while ((branch = (TBranch*) next())) {
4730 TBranch* nestedbranch = branch->FindBranch(branchname);
4732 return nestedbranch;
4740 TFriendLock lock(
this, kFindBranch);
4741 TIter nextf(fFriends);
4742 TFriendElement* fe = 0;
4743 while ((fe = (TFriendElement*) nextf())) {
4744 TTree* t = fe->GetTree();
4749 const char *subbranch = strstr(branchname, fe->GetName());
4750 if (subbranch != branchname) {
4754 subbranch += strlen(fe->GetName());
4755 if (*subbranch !=
'.') {
4761 std::ostringstream name;
4763 name << t->GetName() <<
"." << subbranch;
4767 branch = t->FindBranch(name.str().c_str());
4778 TLeaf* TTree::FindLeaf(
const char* searchname)
4782 if (kFindLeaf & fFriendLockStatus) {
4788 char* subsearchname = (
char*) strstr(searchname, GetName());
4789 if (subsearchname != searchname) {
4792 if (subsearchname) {
4793 subsearchname += strlen(GetName());
4794 if (*subsearchname !=
'.') {
4798 if (subsearchname[0]==0) {
4809 const bool searchnameHasDot = strchr(searchname,
'.') !=
nullptr;
4812 TIter next(GetListOfLeaves());
4814 while ((leaf = (TLeaf*) next())) {
4815 leafname = leaf->GetName();
4816 Ssiz_t dim = leafname.First(
'[');
4817 if (dim >= 0) leafname.Remove(dim);
4819 if (leafname == searchname) {
4822 if (subsearchname && leafname == subsearchname) {
4827 leaftitle = leaf->GetTitle();
4828 dim = leaftitle.First(
'[');
4829 if (dim >= 0) leaftitle.Remove(dim);
4831 if (leaftitle == searchname) {
4834 if (subsearchname && leaftitle == subsearchname) {
4837 if (!searchnameHasDot)
4839 TBranch* branch = leaf->GetBranch();
4841 longname.Form(
"%s.%s",branch->GetName(),leafname.Data());
4842 dim = longname.First(
'[');
4843 if (dim>=0) longname.Remove(dim);
4844 if (longname == searchname) {
4847 if (subsearchname && longname == subsearchname) {
4850 longtitle.Form(
"%s.%s",branch->GetName(),leaftitle.Data());
4851 dim = longtitle.First(
'[');
4852 if (dim>=0) longtitle.Remove(dim);
4853 if (longtitle == searchname) {
4856 if (subsearchname && longtitle == subsearchname) {
4864 if (strstr(searchname,
".") && !strcmp(searchname, branch->GetName())) {
4867 if (subsearchname && strstr(subsearchname,
".") && !strcmp(subsearchname, branch->GetName())) {
4876 TFriendLock lock(
this, kFindLeaf);
4877 TIter nextf(fFriends);
4878 TFriendElement* fe = 0;
4879 while ((fe = (TFriendElement*) nextf())) {
4880 TTree* t = fe->GetTree();
4885 subsearchname = (
char*) strstr(searchname, fe->GetName());
4886 if (subsearchname != searchname) {
4889 if (subsearchname) {
4890 subsearchname += strlen(fe->GetName());
4891 if (*subsearchname !=
'.') {
4897 if (subsearchname) {
4898 leafname.Form(
"%s.%s",t->GetName(),subsearchname);
4900 leafname = searchname;
4902 leaf = t->FindLeaf(leafname);
4938 Int_t TTree::Fit(
const char* funcname,
const char* varexp,
const char* selection, Option_t* option, Option_t* goption, Long64_t nentries, Long64_t firstentry)
4942 return fPlayer->Fit(funcname, varexp, selection, option, goption, nentries, firstentry);
4948 struct BoolRAIIToggle {
4951 BoolRAIIToggle(Bool_t &val) : m_val(val) { m_val =
true; }
4952 ~BoolRAIIToggle() { m_val =
false; }
4988 Int_t TTree::FlushBaskets(Bool_t create_cluster)
const
4990 Int_t retval = FlushBasketsImpl();
4991 if (retval == -1)
return retval;
4993 if (create_cluster)
const_cast<TTree *
>(
this)->MarkEventCluster();
5005 Int_t TTree::FlushBasketsImpl()
const
5007 if (!fDirectory)
return 0;
5010 TObjArray *lb =
const_cast<TTree*
>(
this)->GetListOfBranches();
5011 Int_t nb = lb->GetEntriesFast();
5014 const auto useIMT = ROOT::IsImplicitMTEnabled() && fIMTEnabled;
5021 if (fSortedBranches.size() != unsigned(nb)) {
const_cast<TTree*
>(
this)->InitializeBranchLists(
false); }
5023 BoolRAIIToggle sentry(fIMTFlush);
5024 fIMTZipBytes.store(0);
5025 fIMTTotBytes.store(0);
5026 std::atomic<Int_t> nerrpar(0);
5027 std::atomic<Int_t> nbpar(0);
5028 std::atomic<Int_t> pos(0);
5030 auto mapFunction = [&]() {
5036 Int_t j = pos.fetch_add(1);
5038 auto branch = fSortedBranches[j].second;
5039 if (R__unlikely(!branch)) {
return; }
5041 if (R__unlikely(gDebug > 0)) {
5042 std::stringstream ss;
5043 ss << std::this_thread::get_id();
5044 Info(
"FlushBaskets",
"[IMT] Thread %s", ss.str().c_str());
5045 Info(
"FlushBaskets",
"[IMT] Running task for branch #%d: %s", j, branch->GetName());
5048 Int_t nbtask = branch->FlushBaskets();
5050 if (nbtask < 0) { nerrpar++; }
5051 else { nbpar += nbtask; }
5054 ROOT::TThreadExecutor pool;
5055 pool.Foreach(mapFunction, nb);
5058 const_cast<TTree*
>(
this)->AddTotBytes(fIMTTotBytes);
5059 const_cast<TTree*
>(
this)->AddZipBytes(fIMTZipBytes);
5061 return nerrpar ? -1 : nbpar.load();
5064 for (Int_t j = 0; j < nb; j++) {
5065 TBranch* branch = (TBranch*) lb->UncheckedAt(j);
5067 Int_t nwrite = branch->FlushBaskets();
5085 const char* TTree::GetAlias(
const char* aliasName)
const
5089 if (kGetAlias & fFriendLockStatus) {
5093 TObject* alias = fAliases->FindObject(aliasName);
5095 return alias->GetTitle();
5101 TFriendLock lock(const_cast<TTree*>(
this), kGetAlias);
5102 TIter nextf(fFriends);
5103 TFriendElement* fe = 0;
5104 while ((fe = (TFriendElement*) nextf())) {
5105 TTree* t = fe->GetTree();
5107 const char* alias = t->GetAlias(aliasName);
5111 const char* subAliasName = strstr(aliasName, fe->GetName());
5112 if (subAliasName && (subAliasName[strlen(fe->GetName())] ==
'.')) {
5113 alias = t->GetAlias(aliasName + strlen(fe->GetName()) + 1);
5126 TBranch* TTree::GetBranch(
const char* name)
5128 if (name == 0)
return 0;
5132 if (kGetBranch & fFriendLockStatus) {
5137 Int_t nb = fBranches.GetEntriesFast();
5138 for (Int_t i = 0; i < nb; i++) {
5139 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
5143 if (!strcmp(branch->GetName(), name)) {
5146 TObjArray* lb = branch->GetListOfBranches();
5147 Int_t nb1 = lb->GetEntriesFast();
5148 for (Int_t j = 0; j < nb1; j++) {
5149 TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
5150 if (!strcmp(b1->GetName(), name)) {
5153 TObjArray* lb1 = b1->GetListOfBranches();
5154 Int_t nb2 = lb1->GetEntriesFast();
5155 for (Int_t k = 0; k < nb2; k++) {
5156 TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
5157 if (!strcmp(b2->GetName(), name)) {
5165 TObjArray* leaves = GetListOfLeaves();
5166 Int_t nleaves = leaves->GetEntriesFast();
5167 for (Int_t i = 0; i < nleaves; i++) {
5168 TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
5169 TBranch* branch = leaf->GetBranch();
5170 if (!strcmp(branch->GetName(), name)) {
5180 TFriendLock lock(
this, kGetBranch);
5181 TIter next(fFriends);
5182 TFriendElement* fe = 0;
5183 while ((fe = (TFriendElement*) next())) {
5184 TTree* t = fe->GetTree();
5186 TBranch* branch = t->GetBranch(name);
5196 while ((fe = (TFriendElement*) next())) {
5197 TTree* t = fe->GetTree();
5201 char* subname = (
char*) strstr(name, fe->GetName());
5202 if (subname != name) {
5205 Int_t l = strlen(fe->GetName());
5207 if (*subname !=
'.') {
5211 TBranch* branch = t->GetBranch(subname);
5225 Bool_t TTree::GetBranchStatus(
const char* branchname)
const
5227 TBranch* br =
const_cast<TTree*
>(
this)->GetBranch(branchname);
5229 return br->TestBit(kDoNotProcess) == 0;
5240 Int_t TTree::GetBranchStyle()
5242 return fgBranchStyle;
5252 Long64_t TTree::GetCacheAutoSize(Bool_t withDefault )
const
5255 Double_t cacheFactor = 0.0;
5256 if (!(stcs = gSystem->Getenv(
"ROOT_TTREECACHE_SIZE")) || !*stcs) {
5257 cacheFactor = gEnv->GetValue(
"TTreeCache.Size", 1.0);
5259 cacheFactor = TString(stcs).Atof();
5262 if (cacheFactor < 0.0) {
5267 Long64_t cacheSize = 0;
5269 if (fAutoFlush < 0) cacheSize = Long64_t(-cacheFactor*fAutoFlush);
5270 else if (fAutoFlush == 0) cacheSize = 0;
5271 else cacheSize = Long64_t(cacheFactor*1.5*fAutoFlush*GetZipBytes()/(fEntries+1));
5273 if (cacheSize >= (INT_MAX / 4)) {
5274 cacheSize = INT_MAX / 4;
5277 if (cacheSize < 0) {
5281 if (cacheSize == 0 && withDefault) {
5282 if (fAutoFlush < 0) cacheSize = -fAutoFlush;
5283 else if (fAutoFlush == 0) cacheSize = 0;
5284 else cacheSize = Long64_t(1.5*fAutoFlush*GetZipBytes()/(fEntries+1));
5302 TTree::TClusterIterator TTree::GetClusterIterator(Long64_t firstentry)
5305 if (fCacheDoAutoInit)
5308 return TClusterIterator(
this,firstentry);
5314 TFile* TTree::GetCurrentFile()
const
5316 if (!fDirectory || fDirectory==gROOT) {
5319 return fDirectory->GetFile();
5334 Long64_t TTree::GetEntries(
const char *selection)
5338 return fPlayer->GetEntries(selection);
5347 Long64_t TTree::GetEntriesFriend()
const
5349 if (fEntries)
return fEntries;
5350 if (!fFriends)
return 0;
5351 TFriendElement *fr = (TFriendElement*)fFriends->At(0);
5353 TTree *t = fr->GetTree();
5355 return t->GetEntriesFriend();
5473 Int_t TTree::GetEntry(Long64_t entry, Int_t getall)
5478 if (kGetEntry & fFriendLockStatus)
return 0;
5480 if (entry < 0 || entry >= fEntries)
return 0;
5486 if (fCacheDoAutoInit)
5489 Int_t nbranches = fBranches.GetEntriesUnsafe();
5492 auto seqprocessing = [&]() {
5494 for (i=0;i<nbranches;i++) {
5495 branch = (TBranch*)fBranches.UncheckedAt(i);
5496 nb = branch->GetEntry(entry, getall);
5503 if (nbranches > 1 && ROOT::IsImplicitMTEnabled() && fIMTEnabled && !TTreeCacheUnzip::IsParallelUnzip()) {
5504 if (fSortedBranches.empty())
5505 InitializeBranchLists(
true);
5508 for (
auto branch : fSeqBranches) {
5509 nb = branch->GetEntry(entry, getall);
5513 if (nb < 0)
return nb;
5516 ROOT::Internal::TParBranchProcessingRAII pbpRAII;
5519 std::atomic<Int_t> pos(0);
5520 std::atomic<Int_t> nbpar(0);
5522 auto mapFunction = [&]() {
5528 Int_t j = pos.fetch_add(1);
5531 auto branch = fSortedBranches[j].second;
5534 std::stringstream ss;
5535 ss << std::this_thread::get_id();
5536 Info(
"GetEntry",
"[IMT] Thread %s", ss.str().c_str());
5537 Info(
"GetEntry",
"[IMT] Running task for branch #%d: %s", j, branch->GetName());
5540 std::chrono::time_point<std::chrono::system_clock> start, end;
5542 start = std::chrono::system_clock::now();
5543 nbtask = branch->GetEntry(entry, getall);
5544 end = std::chrono::system_clock::now();
5546 Long64_t tasktime = (Long64_t)std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
5547 fSortedBranches[j].first += tasktime;
5549 if (nbtask < 0) errnb = nbtask;
5550 else nbpar += nbtask;
5553 ROOT::TThreadExecutor pool;
5554 pool.Foreach(mapFunction, fSortedBranches.size());
5564 if (++fNEntriesSinceSorting == kNEntriesResort) {
5565 SortBranchesByTime();
5566 fNEntriesSinceSorting = 0;
5576 if (nb < 0)
return nb;
5579 if (!fFriends)
return nbytes;
5580 TFriendLock lock(
this,kGetEntry);
5581 TIter nextf(fFriends);
5583 while ((fe = (TFriendElement*)nextf())) {
5584 TTree *t = fe->GetTree();
5586 if (fe->TestBit(TFriendElement::kFromChain)) {
5587 nb = t->GetEntry(t->GetReadEntry(),getall);
5589 if ( t->LoadTreeFriend(entry,
this) >= 0 ) {
5590 nb = t->GetEntry(t->GetReadEntry(),getall);
5593 if (nb < 0)
return nb;
5617 void TTree::InitializeBranchLists(
bool checkLeafCount)
5619 Int_t nbranches = fBranches.GetEntriesFast();
5623 if (fBranchRef && fBranchRef != fSeqBranches[0]) {
5624 fSeqBranches.push_back(fBranchRef);
5628 if (checkLeafCount) {
5629 for (Int_t i = 0; i < nbranches; i++) {
5630 TBranch* branch = (TBranch*)fBranches.UncheckedAt(i);
5631 auto leafCount = ((TLeaf*)branch->GetListOfLeaves()->At(0))->GetLeafCount();
5633 auto countBranch = leafCount->GetBranch();
5634 if (std::find(fSeqBranches.begin(), fSeqBranches.end(), countBranch) == fSeqBranches.end()) {
5635 fSeqBranches.push_back(countBranch);
5643 if (!checkLeafCount) {
5644 fSortedBranches.clear();
5646 for (Int_t i = 0; i < nbranches; i++) {
5647 Long64_t bbytes = 0;
5648 TBranch* branch = (TBranch*)fBranches.UncheckedAt(i);
5649 if (std::find(fSeqBranches.begin(), fSeqBranches.end(), branch) == fSeqBranches.end()) {
5650 bbytes = branch->GetTotBytes(
"*");
5651 fSortedBranches.emplace_back(bbytes, branch);
5656 std::sort(fSortedBranches.begin(),
5657 fSortedBranches.end(),
5658 [](std::pair<Long64_t,TBranch*> a, std::pair<Long64_t,TBranch*> b) {
5659 return a.first > b.first;
5662 for (
size_t i = 0; i < fSortedBranches.size(); i++) {
5663 fSortedBranches[i].first = 0LL;
5670 void TTree::SortBranchesByTime()
5672 for (
size_t i = 0; i < fSortedBranches.size(); i++) {
5673 fSortedBranches[i].first *= kNEntriesResortInv;
5676 std::sort(fSortedBranches.begin(),
5677 fSortedBranches.end(),
5678 [](std::pair<Long64_t,TBranch*> a, std::pair<Long64_t,TBranch*> b) {
5679 return a.first > b.first;
5682 for (
size_t i = 0; i < fSortedBranches.size(); i++) {
5683 fSortedBranches[i].first = 0LL;
5690 TEntryList* TTree::GetEntryList()
5701 Long64_t TTree::GetEntryNumber(Long64_t entry)
const
5707 return fEntryList->GetEntry(entry);
5726 Long64_t TTree::GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor)
const
5731 return fTreeIndex->GetEntryNumberWithBestIndex(major, minor);
5746 Long64_t TTree::GetEntryNumberWithIndex(Long64_t major, Long64_t minor)
const
5751 return fTreeIndex->GetEntryNumberWithIndex(major, minor);
5763 Int_t TTree::GetEntryWithIndex(Int_t major, Int_t minor)
5767 if (kGetEntryWithIndex & fFriendLockStatus) {
5770 Long64_t serial = GetEntryNumberWithIndex(major, minor);
5775 if (fCacheDoAutoInit)
5780 fReadEntry = serial;
5782 Int_t nbranches = fBranches.GetEntriesFast();
5784 for (i = 0; i < nbranches; ++i) {
5785 branch = (TBranch*)fBranches.UncheckedAt(i);
5786 nb = branch->GetEntry(serial);
5787 if (nb < 0)
return nb;
5791 if (!fFriends)
return nbytes;
5792 TFriendLock lock(
this,kGetEntryWithIndex);
5793 TIter nextf(fFriends);
5794 TFriendElement* fe = 0;
5795 while ((fe = (TFriendElement*) nextf())) {
5796 TTree *t = fe->GetTree();
5798 serial = t->GetEntryNumberWithIndex(major,minor);
5799 if (serial <0)
return -nbytes;
5800 nb = t->GetEntry(serial);
5801 if (nb < 0)
return nb;
5811 TTree* TTree::GetFriend(
const char *friendname)
const
5816 if (kGetFriend & fFriendLockStatus) {
5822 TFriendLock lock(const_cast<TTree*>(
this), kGetFriend);
5823 TIter nextf(fFriends);
5824 TFriendElement* fe = 0;
5825 while ((fe = (TFriendElement*) nextf())) {
5826 if (strcmp(friendname,fe->GetName())==0
5827 || strcmp(friendname,fe->GetTreeName())==0) {
5828 return fe->GetTree();
5835 while ((fe = (TFriendElement*) nextf())) {
5836 TTree *res = fe->GetTree()->GetFriend(friendname);
5868 const char* TTree::GetFriendAlias(TTree* tree)
const
5870 if ((tree ==
this) || (tree == GetTree())) {
5876 if (kGetFriendAlias & fFriendLockStatus) {
5882 TFriendLock lock(const_cast<TTree*>(
this), kGetFriendAlias);
5883 TIter nextf(fFriends);
5884 TFriendElement* fe = 0;
5885 while ((fe = (TFriendElement*) nextf())) {
5886 TTree* t = fe->GetTree();
5888 return fe->GetName();
5891 if (t && t->GetTree() == tree) {
5892 return fe->GetName();
5899 while ((fe = (TFriendElement*) nextf())) {
5900 const char* res = fe->GetTree()->GetFriendAlias(tree);
5910 ROOT::TIOFeatures TTree::GetIOFeatures()
const
5918 TIterator* TTree::GetIteratorOnAllLeaves(Bool_t dir)
5920 return new TTreeFriendLeafIter(
this, dir);
5934 TLeaf* TTree::GetLeafImpl(
const char* branchname,
const char *leafname)
5938 TBranch *branch = FindBranch(branchname);
5940 leaf = branch->GetLeaf(leafname);
5946 TIter nextl(GetListOfLeaves());
5947 while ((leaf = (TLeaf*)nextl())) {
5948 if (strcmp(leaf->GetName(),leafname))
continue;
5950 UInt_t nbch = strlen(branchname);
5951 TBranch *br = leaf->GetBranch();
5952 const char* brname = br->GetName();
5953 TBranch *mother = br->GetMother();
5954 if (strncmp(brname,branchname,nbch)) {
5956 const char *mothername = mother->GetName();
5957 UInt_t motherlen = strlen(mothername);
5958 if (nbch > motherlen && strncmp(mothername,branchname,motherlen)==0 && (mothername[motherlen-1]==
'.' || branchname[motherlen]==
'.')) {
5960 if (strncmp(brname,branchname+motherlen+1,nbch-motherlen-1)) {
5976 if ((strlen(brname) > nbch) && (brname[nbch] !=
'.') && (brname[nbch] !=
'[')) {
5982 if (!fFriends)
return 0;
5983 TFriendLock lock(
this,kGetLeaf);
5984 TIter next(fFriends);
5986 while ((fe = (TFriendElement*)next())) {
5987 TTree *t = fe->GetTree();
5989 leaf = t->GetLeaf(leafname);
5990 if (leaf)
return leaf;
5996 TString strippedArg;
5998 while ((fe = (TFriendElement*)next())) {
5999 TTree *t = fe->GetTree();
6001 char *subname = (
char*)strstr(leafname,fe->GetName());
6002 if (subname != leafname)
continue;
6003 Int_t l = strlen(fe->GetName());
6005 if (*subname !=
'.')
continue;
6007 strippedArg += subname;
6008 leaf = t->GetLeaf(branchname,subname);
6009 if (leaf)
return leaf;
6024 TLeaf* TTree::GetLeaf(
const char* branchname,
const char *leafname)
6026 if (leafname == 0)
return 0;
6030 if (kGetLeaf & fFriendLockStatus) {
6034 return GetLeafImpl(branchname,leafname);
6044 TLeaf* TTree::GetLeaf(
const char *name)
6048 if (!name || (kGetLeaf & fFriendLockStatus))
6051 std::string path(name);
6052 const auto sep = path.find_last_of(
"/");
6053 if (sep != std::string::npos)
6054 return GetLeafImpl(path.substr(0, sep).c_str(), name+sep+1);
6056 return GetLeafImpl(
nullptr, name);
6064 Double_t TTree::GetMaximum(
const char* columname)
6066 TLeaf* leaf = this->GetLeaf(columname);
6072 if (fCacheDoAutoInit)
6075 TBranch* branch = leaf->GetBranch();
6076 Double_t cmax = -DBL_MAX;
6077 for (Long64_t i = 0; i < fEntries; ++i) {
6078 Long64_t entryNumber = this->GetEntryNumber(i);
6079 if (entryNumber < 0)
break;
6080 branch->GetEntry(entryNumber);
6081 for (Int_t j = 0; j < leaf->GetLen(); ++j) {
6082 Double_t val = leaf->GetValue(j);
6094 Long64_t TTree::GetMaxTreeSize()
6096 return fgMaxTreeSize;
6104 Double_t TTree::GetMinimum(
const char* columname)
6106 TLeaf* leaf = this->GetLeaf(columname);
6112 if (fCacheDoAutoInit)
6115 TBranch* branch = leaf->GetBranch();
6116 Double_t cmin = DBL_MAX;
6117 for (Long64_t i = 0; i < fEntries; ++i) {
6118 Long64_t entryNumber = this->GetEntryNumber(i);
6119 if (entryNumber < 0)
break;
6120 branch->GetEntry(entryNumber);
6121 for (Int_t j = 0;j < leaf->GetLen(); ++j) {
6122 Double_t val = leaf->GetValue(j);
6134 TVirtualTreePlayer* TTree::GetPlayer()
6139 fPlayer = TVirtualTreePlayer::TreePlayer(
this);
6147 TTreeCache *TTree::GetReadCache(TFile *file)
const
6149 TTreeCache *pe =
dynamic_cast<TTreeCache*
>(file->GetCacheRead(
this));
6150 if (pe && pe->GetTree() !=
this)
6160 TTreeCache *TTree::GetReadCache(TFile *file, Bool_t create)
6162 TTreeCache *pe = GetReadCache(file);
6163 if (create && !pe) {
6164 if (fCacheDoAutoInit)
6165 SetCacheSizeAux(kTRUE, -1);
6166 pe =
dynamic_cast<TTreeCache*
>(file->GetCacheRead(
this));
6167 if (pe && pe->GetTree() !=
this) pe = 0;
6185 TList* TTree::GetUserInfo()
6188 fUserInfo =
new TList();
6189 fUserInfo->SetName(
"UserInfo");
6201 void TTree::ImportClusterRanges(TTree *fromtree)
6203 Long64_t autoflush = fromtree->GetAutoFlush();
6204 if (fromtree->fNClusterRange == 0 && fromtree->fAutoFlush == fAutoFlush) {
6206 }
else if (fNClusterRange || fromtree->fNClusterRange) {
6207 Int_t newsize = fNClusterRange + 1 + fromtree->fNClusterRange;
6208 if (newsize > fMaxClusterRange) {
6209 if (fMaxClusterRange) {
6210 fClusterRangeEnd = (Long64_t*)TStorage::ReAlloc(fClusterRangeEnd,
6211 newsize*
sizeof(Long64_t),fMaxClusterRange*
sizeof(Long64_t));
6212 fClusterSize = (Long64_t*)TStorage::ReAlloc(fClusterSize,
6213 newsize*
sizeof(Long64_t),fMaxClusterRange*
sizeof(Long64_t));
6214 fMaxClusterRange = newsize;
6216 fMaxClusterRange = newsize;
6217 fClusterRangeEnd =
new Long64_t[fMaxClusterRange];
6218 fClusterSize =
new Long64_t[fMaxClusterRange];
6222 fClusterRangeEnd[fNClusterRange] = fEntries - 1;
6223 fClusterSize[fNClusterRange] = fAutoFlush<0 ? 0 : fAutoFlush;
6226 for (Int_t i = 0 ; i < fromtree->fNClusterRange; ++i) {
6227 fClusterRangeEnd[fNClusterRange] = fEntries + fromtree->fClusterRangeEnd[i];
6228 fClusterSize[fNClusterRange] = fromtree->fClusterSize[i];
6231 fAutoFlush = autoflush;
6233 SetAutoFlush( autoflush );
6235 Long64_t autosave = GetAutoSave();
6236 if (autoflush > 0 && autosave > 0) {
6237 SetAutoSave( autoflush*(autosave/autoflush) );
6244 void TTree::KeepCircular()
6246 Int_t nb = fBranches.GetEntriesFast();
6247 Long64_t maxEntries = fMaxEntries - (fMaxEntries / 10);
6248 for (Int_t i = 0; i < nb; ++i) {
6249 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
6250 branch->KeepCircular(maxEntries);
6252 if (fNClusterRange) {
6253 Long64_t entriesOffset = fEntries - maxEntries;
6254 Int_t oldsize = fNClusterRange;
6255 for(Int_t i = 0, j = 0; j < oldsize; ++j) {
6256 if (fClusterRangeEnd[j] > entriesOffset) {
6257 fClusterRangeEnd[i] = fClusterRangeEnd[j] - entriesOffset;
6264 fEntries = maxEntries;
6280 Int_t TTree::LoadBaskets(Long64_t maxmemory)
6282 if (maxmemory > 0) SetMaxVirtualSize(maxmemory);
6284 TIter next(GetListOfLeaves());
6286 Int_t nimported = 0;
6287 while ((leaf=(TLeaf*)next())) {
6288 nimported += leaf->GetBranch()->LoadBaskets();
6302 Long64_t TTree::LoadTree(Long64_t entry)
6306 if (kLoadTree & fFriendLockStatus) {
6313 if (fCacheDoAutoInit && entry >=0)
6317 if (fReadEntry < 0) {
6323 Bool_t friendHasEntry = kFALSE;
6329 Bool_t needUpdate = kFALSE;
6332 TIter nextf(fFriends);
6333 TFriendLock lock(
this, kLoadTree);
6334 TFriendElement* fe = 0;
6335 while ((fe = (TFriendElement*) nextf())) {
6336 if (fe->TestBit(TFriendElement::kFromChain)) {
6341 TTree* friendTree = fe->GetTree();
6342 if (friendTree == 0) {
6344 }
else if (friendTree->IsA() == TTree::Class()) {
6346 if (friendTree->LoadTreeFriend(entry,
this) >= 0) {
6347 friendHasEntry = kTRUE;
6352 Int_t oldNumber = friendTree->GetTreeNumber();
6353 if (friendTree->LoadTreeFriend(entry,
this) >= 0) {
6354 friendHasEntry = kTRUE;
6356 Int_t newNumber = friendTree->GetTreeNumber();
6357 if (oldNumber != newNumber) {
6368 fPlayer->UpdateFormulaLeaves();
6372 if(!fNotify->Notify())
return -6;
6377 if ((fReadEntry >= fEntries) && !friendHasEntry) {
6398 Long64_t TTree::LoadTreeFriend(Long64_t entry, TTree* masterTree)
6401 return LoadTree(entry);
6403 return LoadTree(fTreeIndex->GetEntryNumberFriend(masterTree));
6448 Int_t TTree::MakeClass(
const char* classname, Option_t* option)
6454 return fPlayer->MakeClass(classname, option);
6481 Int_t TTree::MakeCode(
const char* filename)
6483 Warning(
"MakeCode",
"MakeCode is obsolete. Use MakeClass or MakeSelector instead");
6486 if (!fPlayer)
return 0;
6487 return fPlayer->MakeCode(filename);
6609 Int_t TTree::MakeProxy(
const char* proxyClassname,
const char* macrofilename,
const char* cutfilename,
const char* option, Int_t maxUnrolling)
6612 if (!fPlayer)
return 0;
6613 return fPlayer->MakeProxy(proxyClassname,macrofilename,cutfilename,option,maxUnrolling);
6663 Int_t TTree::MakeSelector(
const char* selector, Option_t* option)
6665 TString opt(option);
6666 if(opt.EqualTo(
"=legacy", TString::ECaseCompare::kIgnoreCase)) {
6667 return MakeClass(selector,
"selector");
6670 if (!fPlayer)
return 0;
6671 return fPlayer->MakeReader(selector, option);
6678 Bool_t TTree::MemoryFull(Int_t nbytes)
6680 if ((fTotalBuffers + nbytes) < fMaxVirtualSize) {
6692 TTree* TTree::MergeTrees(TList* li, Option_t* options)
6699 while ((obj=next())) {
6700 if (!obj->InheritsFrom(TTree::Class()))
continue;
6701 TTree *tree = (TTree*)obj;
6702 Long64_t nentries = tree->GetEntries();
6703 if (nentries == 0)
continue;
6705 newtree = (TTree*)tree->CloneTree();
6706 if (!newtree)
continue;
6712 tree->GetListOfClones()->Remove(newtree);
6713 tree->ResetBranchAddresses();
6714 newtree->ResetBranchAddresses();
6718 newtree->CopyAddresses(tree);
6720 newtree->CopyEntries(tree,-1,options);
6722 tree->ResetBranchAddresses();
6724 if (newtree && newtree->GetTreeIndex()) {
6725 newtree->GetTreeIndex()->Append(0,kFALSE);
6735 Long64_t TTree::Merge(TCollection* li, Option_t *options)
6738 Long64_t storeAutoSave = fAutoSave;
6746 while ((tree = (TTree*)next())) {
6747 if (tree==
this)
continue;
6748 if (!tree->InheritsFrom(TTree::Class())) {
6749 Error(
"Add",
"Attempt to add object of class: %s to a %s", tree->ClassName(), ClassName());
6750 fAutoSave = storeAutoSave;
6754 Long64_t nentries = tree->GetEntries();
6755 if (nentries == 0)
continue;
6757 CopyAddresses(tree);
6759 CopyEntries(tree,-1,options);
6761 tree->ResetBranchAddresses();
6763 fAutoSave = storeAutoSave;
6764 return GetEntries();
6776 Long64_t TTree::Merge(TCollection* li, TFileMergeInfo *info)
6778 const char *options = info ? info->fOptions.Data() :
"";
6779 if (info && info->fIsFirst && info->fOutputDirectory && info->fOutputDirectory->GetFile() != GetCurrentFile()) {
6780 TDirectory::TContext ctxt(info->fOutputDirectory);
6781 TIOFeatures saved_features = fIOFeatures;
6782 if (info->fIOFeatures) {
6783 fIOFeatures = *(info->fIOFeatures);
6785 TTree *newtree = CloneTree(-1, options);
6786 fIOFeatures = saved_features;
6792 info->fOutputDirectory->GetFile()->Flush();
6793 info->fOutputDirectory->ReadTObject(
this,this->GetName());
6796 Long64_t storeAutoSave = fAutoSave;
6804 while ((tree = (TTree*)next())) {
6805 if (tree==
this)
continue;
6806 if (!tree->InheritsFrom(TTree::Class())) {
6807 Error(
"Add",
"Attempt to add object of class: %s to a %s", tree->ClassName(), ClassName());
6808 fAutoSave = storeAutoSave;
6812 tree->SetMakeClass(fMakeClass);
6815 CopyAddresses(tree);
6817 CopyEntries(tree,-1,options);
6819 tree->ResetBranchAddresses();
6821 fAutoSave = storeAutoSave;
6822 return GetEntries();
6830 void TTree::MoveReadCache(TFile *src, TDirectory *dir)
6833 TFile *dst = (dir && dir != gROOT) ? dir->GetFile() : 0;
6834 if (src == dst)
return;
6836 TTreeCache *pf = GetReadCache(src);
6838 src->SetCacheRead(0,
this);
6839 dst->SetCacheRead(pf,
this);
6842 pf->WaitFinishPrefetch();
6844 src->SetCacheRead(0,
this);
6852 Bool_t TTree::Notify()
6854 TIter next(GetListOfLeaves());
6856 while ((leaf = (TLeaf*) next())) {
6858 leaf->GetBranch()->Notify();
6876 void TTree::OptimizeBaskets(ULong64_t maxMemory, Float_t minComp, Option_t *option)
6879 if (this->GetDirectory()->IsWritable()) this->FlushBasketsImpl();
6881 TString opt( option );
6883 Bool_t pDebug = opt.Contains(
"d");
6884 TObjArray *leaves = this->GetListOfLeaves();
6885 Int_t nleaves = leaves->GetEntries();
6886 Double_t treeSize = (Double_t)this->GetTotBytes();
6888 if (nleaves == 0 || treeSize == 0) {
6892 Double_t aveSize = treeSize/nleaves;
6894 UInt_t bmax = 256000;
6895 Double_t memFactor = 1;
6896 Int_t i, oldMemsize,newMemsize,oldBaskets,newBaskets;
6897 i = oldMemsize = newMemsize = oldBaskets = newBaskets = 0;
6902 for (Int_t pass =0;pass<2;pass++) {
6907 for (i=0;i<nleaves;i++) {
6908 TLeaf *leaf = (TLeaf*)leaves->At(i);
6909 TBranch *branch = leaf->GetBranch();
6910 Double_t totBytes = (Double_t)branch->GetTotBytes();
6911 Double_t idealFactor = totBytes/aveSize;
6912 UInt_t sizeOfOneEntry;
6913 if (branch->GetEntries() == 0) {
6915 sizeOfOneEntry = aveSize;
6917 sizeOfOneEntry = 1+(UInt_t)(totBytes / (Double_t)branch->GetEntries());
6919 Int_t oldBsize = branch->GetBasketSize();
6920 oldMemsize += oldBsize;
6921 oldBaskets += 1+Int_t(totBytes/oldBsize);
6922 Int_t nb = branch->GetListOfBranches()->GetEntries();
6924 newBaskets += 1+Int_t(totBytes/oldBsize);
6927 Double_t bsize = oldBsize*idealFactor*memFactor;
6928 if (bsize < 0) bsize = bmax;
6929 if (bsize > bmax) bsize = bmax;
6930 UInt_t newBsize = UInt_t(bsize);
6936 Long64_t clusterSize = (fAutoFlush > 0) ? fAutoFlush : branch->GetEntries();
6937 if (branch->GetEntryOffsetLen()) {
6938 newBsize = newBsize + (clusterSize *
sizeof(Int_t) * 2);
6947 newBsize = newBsize - newBsize%512 + 512;
6949 if (newBsize < sizeOfOneEntry) newBsize = sizeOfOneEntry;
6950 if (newBsize < bmin) newBsize = bmin;
6951 if (newBsize > 10000000) newBsize = bmax;
6953 if (pDebug) Info(
"OptimizeBaskets",
"Changing buffer size from %6d to %6d bytes for %s\n",oldBsize,newBsize,branch->GetName());
6954 branch->SetBasketSize(newBsize);
6956 newMemsize += newBsize;
6960 newBaskets += 1+Int_t(totBytes/newBsize);
6961 if (pass == 0)
continue;
6964 if (branch->GetZipBytes() > 0) comp = totBytes/Double_t(branch->GetZipBytes());
6965 if (comp > 1 && comp < minComp) {
6966 if (pDebug) Info(
"OptimizeBaskets",
"Disabling compression for branch : %s\n",branch->GetName());
6967 branch->SetCompressionSettings(ROOT::RCompressionSetting::EAlgorithm::kUseGlobal);
6971 memFactor = Double_t(maxMemory)/Double_t(newMemsize);
6972 if (memFactor > 100) memFactor = 100;
6973 Double_t bmin_new = bmin*memFactor;
6974 Double_t bmax_new = bmax*memFactor;
6975 static const UInt_t hardmax = 1*1024*1024*1024;
6982 static const UInt_t hardmin = 8;
6983 bmin = (bmin_new > hardmax) ? hardmax : ( bmin_new < hardmin ? hardmin : (UInt_t)bmin_new );
6984 bmax = (bmax_new > hardmax) ? bmin : (UInt_t)bmax_new;
6987 Info(
"OptimizeBaskets",
"oldMemsize = %d, newMemsize = %d\n",oldMemsize, newMemsize);
6988 Info(
"OptimizeBaskets",
"oldBaskets = %d, newBaskets = %d\n",oldBaskets, newBaskets);
7019 TPrincipal* TTree::Principal(
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
7023 return fPlayer->Principal(varexp, selection, option, nentries, firstentry);
7038 void TTree::Print(Option_t* option)
const
7042 if (kPrint & fFriendLockStatus) {
7048 TKey* key = fDirectory->GetKey(GetName());
7050 skey = key->GetKeylen();
7051 s = key->GetNbytes();
7054 Long64_t total = skey;
7055 Long64_t zipBytes = GetZipBytes();
7057 total += GetTotBytes();
7059 TBufferFile b(TBuffer::kWrite, 10000);
7060 TTree::Class()->WriteBuffer(b, (TTree*)
this);
7061 total += b.Length();
7062 Long64_t file = zipBytes + s;
7065 cx = (GetTotBytes() + 0.00001) / zipBytes;
7067 Printf(
"******************************************************************************");
7068 Printf(
"*Tree :%-10s: %-54s *", GetName(), GetTitle());
7069 Printf(
"*Entries : %8lld : Total = %15lld bytes File Size = %10lld *", fEntries, total, file);
7070 Printf(
"* : : Tree compression factor = %6.2f *", cx);
7071 Printf(
"******************************************************************************");
7074 if (option ==
nullptr)
7077 if (strncmp(option,
"clusters",strlen(
"clusters"))==0) {
7078 Printf(
"%-16s %-16s %-16s %5s",
7079 "Cluster Range #",
"Entry Start",
"Last Entry",
"Size");
7081 Long64_t clusterRangeStart = 0;
7082 if (fNClusterRange) {
7083 for( ; index < fNClusterRange; ++index) {
7084 Printf(
"%-16d %-16lld %-16lld %5lld",
7085 index, clusterRangeStart, fClusterRangeEnd[index], fClusterSize[index]);
7086 clusterRangeStart = fClusterRangeEnd[index] + 1;
7089 Printf(
"%-16d %-16lld %-16lld %5lld",
7090 index, clusterRangeStart, fEntries - 1, fAutoFlush);
7094 Int_t nl =
const_cast<TTree*
>(
this)->GetListOfLeaves()->GetEntries();
7098 if (strstr(option,
"toponly")) {
7099 Long64_t *count =
new Long64_t[nl];
7101 for (l=0;l<nl;l++) {
7102 leaf = (TLeaf *)const_cast<TTree*>(
this)->GetListOfLeaves()->At(l);
7103 br = leaf->GetBranch();
7104 if (strchr(br->GetName(),
'.')) {
7106 count[keep] += br->GetZipBytes();
7109 count[keep] = br->GetZipBytes();
7112 for (l=0;l<nl;l++) {
7113 if (count[l] < 0)
continue;
7114 leaf = (TLeaf *)const_cast<TTree*>(
this)->GetListOfLeaves()->At(l);
7115 br = leaf->GetBranch();
7116 Printf(
"branch: %-20s %9lld\n",br->GetName(),count[l]);
7121 if (strlen(option) && strchr(option,
'*')) reg = option;
7122 TRegexp re(reg,kTRUE);
7123 TIter next(const_cast<TTree*>(
this)->GetListOfBranches());
7124 TBranch::ResetCount();
7125 while ((br= (TBranch*)next())) {
7126 TString st = br->GetName();
7127 st.ReplaceAll(
"/",
"_");
7128 if (st.Index(re) == kNPOS)
continue;
7134 if (fBranchRef) fBranchRef->Print(option);
7137 if (!fFriends || !strstr(option,
"all"))
return;
7138 TIter nextf(fFriends);
7139 TFriendLock lock(const_cast<TTree*>(
this),kPrint);
7141 while ((fr = (TFriendElement*)nextf())) {
7142 TTree * t = fr->GetTree();
7143 if (t) t->Print(option);
7158 void TTree::PrintCacheStats(Option_t* option)
const
7160 TFile *f = GetCurrentFile();
7162 TTreeCache *tc = GetReadCache(f);
7163 if (tc) tc->Print(option);
7238 Long64_t TTree::Process(
const char* filename, Option_t* option, Long64_t nentries, Long64_t firstentry)
7242 return fPlayer->Process(filename, option, nentries, firstentry);
7269 Long64_t TTree::Process(TSelector* selector, Option_t* option, Long64_t nentries, Long64_t firstentry)
7273 return fPlayer->Process(selector, option, nentries, firstentry);
7286 Long64_t TTree::Project(
const char* hname,
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
7289 var.Form(
"%s>>%s", varexp, hname);
7290 TString opt(
"goff");
7292 opt.Form(
"%sgoff", option);
7294 Long64_t nsel = Draw(var, selection, opt, nentries, firstentry);
7301 TSQLResult* TTree::Query(
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
7305 return fPlayer->Query(varexp, selection, option, nentries, firstentry);
7352 Long64_t TTree::ReadFile(
const char* filename,
const char* branchDescriptor,
char delimiter)
7357 Error(
"ReadFile",
"Cannot open file: %s",filename);
7360 const char* ext = strrchr(filename,
'.');
7361 if(ext != NULL && ((strcmp(ext,
".csv") == 0) || (strcmp(ext,
".CSV") == 0)) && delimiter ==
' ') {
7364 return ReadStream(in, branchDescriptor, delimiter);
7371 char TTree::GetNewlineValue(std::istream &inputStream)
7373 Long_t inPos = inputStream.tellg();
7374 char newline =
'\n';
7378 if(!inputStream.good()) {
7379 Error(
"ReadStream",
"Error reading stream: no newline found.");
7382 if(c == newline)
break;
7388 inputStream.clear();
7389 inputStream.seekg(inPos);
7398 Long64_t TTree::ReadStream(std::istream& inputStream,
const char *branchDescriptor,
char delimiter)
7401 std::stringstream ss;
7402 std::istream *inTemp;
7403 Long_t inPos = inputStream.tellg();
7404 if (!inputStream.good()) {
7405 Error(
"ReadStream",
"Error reading stream");
7409 ss << std::cin.rdbuf();
7410 newline = GetNewlineValue(ss);
7413 newline = GetNewlineValue(inputStream);
7414 inTemp = &inputStream;
7416 std::istream& in = *inTemp;
7417 Long64_t nlines = 0;
7419 TBranch *branch = 0;
7420 Int_t nbranches = fBranches.GetEntries();
7421 if (nbranches == 0) {
7422 char *bdname =
new char[4000];
7423 char *bd =
new char[100000];
7425 if (branchDescriptor) nch = strlen(branchDescriptor);
7429 in.getline(bd, 100000, newline);
7433 Error(
"ReadStream",
"Error reading stream");
7437 while( isspace(*cursor) && *cursor !=
'\n' && *cursor !=
'\0') {
7440 if (*cursor !=
'#' && *cursor !=
'\n' && *cursor !=
'\0') {
7447 strlcpy(bd,branchDescriptor,100000);
7452 void *address = &bd[90000];
7454 TString desc=
"", olddesc=
"F";
7456 if(delimiter !=
' ') {
7458 if (strchr(bdcur,bdelim)==0 && strchr(bdcur,
':') != 0) {
7464 char *colon = strchr(bdcur,bdelim);
7465 if (colon) *colon = 0;
7466 strlcpy(bdname,bdcur,4000);
7467 char *slash = strchr(bdname,
'/');
7473 desc.Form(
"%s/%s",bdname,olddesc.Data());
7475 char *bracket = strchr(bdname,
'[');
7479 branch =
new TBranch(
this,bdname,address,desc.Data(),32000);
7480 if (branch->IsZombie()) {
7482 Warning(
"ReadStream",
"Illegal branch definition: %s",bdcur);
7484 fBranches.Add(branch);
7485 branch->SetAddress(0);
7494 nbranches = fBranches.GetEntries();
7497 Info(
"ReadStream",
"Will use branches:");
7498 for (
int i = 0 ; i < nbranches; ++i) {
7499 TBranch* br = (TBranch*) fBranches.At(i);
7500 Info(
"ReadStream",
" %s: %s [%s]", br->GetName(),
7501 br->GetTitle(), br->GetListOfLeaves()->At(0)->IsA()->GetName());
7504 Info(
"ReadStream",
"Dumping read tokens, format:");
7505 Info(
"ReadStream",
"LLLLL:BBB:gfbe:GFBE:T");
7506 Info(
"ReadStream",
" L: line number");
7507 Info(
"ReadStream",
" B: branch number");
7508 Info(
"ReadStream",
" gfbe: good / fail / bad / eof of token");
7509 Info(
"ReadStream",
" GFBE: good / fail / bad / eof of file");
7510 Info(
"ReadStream",
" T: Token being read");
7515 Long64_t nGoodLines = 0;
7517 const char sDelimBuf[2] = { delimiter, 0 };
7518 const char* sDelim = sDelimBuf;
7519 if (delimiter ==
' ') {
7524 if (newline ==
'\r' && in.peek() ==
'\n') {
7528 std::getline(in, line, newline);
7531 TString sLine(line);
7532 sLine = sLine.Strip(TString::kLeading);
7533 if (sLine.IsNull()) {
7535 Info(
"ReadStream",
"Skipping empty line number %lld", nlines);
7539 if (sLine[0] ==
'#') {
7541 Info(
"ReadStream",
"Skipping comment line number %lld: '%s'",
7542 nlines, line.c_str());
7547 Info(
"ReadStream",
"Parsing line number %lld: '%s'",
7548 nlines, line.c_str());
7555 std::stringstream sToken;
7558 Bool_t goodLine = kTRUE;
7559 Int_t remainingLeafLen = 0;
7560 while (goodLine && iBranch < nbranches
7561 && sLine.Tokenize(tok, pos, sDelim)) {
7562 tok = tok.Strip(TString::kLeading);
7563 if (tok.IsNull() && delimiter ==
' ') {
7569 if (!remainingLeafLen) {
7571 branch = (TBranch*)fBranches.At(iBranch);
7573 TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
7574 if (!remainingLeafLen) {
7575 remainingLeafLen = leaf->GetLen();
7576 if (leaf->GetMaximum() > 0) {
7579 remainingLeafLen = 1;
7589 if (remainingLeafLen) {
7597 sToken.seekp(0, std::ios_base::beg);
7598 sToken.str(leafData.Data());
7599 sToken.seekg(0, std::ios_base::beg);
7600 leaf->ReadValue(sToken, 0 );
7602 Info(
"ReadStream",
"%5lld:%3d:%d%d%d%d:%d%d%d%d:%s",
7604 (
int)sToken.good(), (int)sToken.fail(),
7605 (int)sToken.bad(), (int)sToken.eof(),
7606 (int)in.good(), (int)in.fail(),
7607 (int)in.bad(), (int)in.eof(),
7608 sToken.str().c_str());
7614 Warning(
"ReadStream",
7615 "Buffer error while reading data for branch %s on line %lld",
7616 branch->GetName(), nlines);
7617 }
else if (!sToken.eof()) {
7618 if (sToken.fail()) {
7619 Warning(
"ReadStream",
7620 "Couldn't read formatted data in \"%s\" for branch %s on line %lld; ignoring line",
7621 tok.Data(), branch->GetName(), nlines);
7624 std::string remainder;
7625 std::getline(sToken, remainder, newline);
7626 if (!remainder.empty()) {
7627 Warning(
"ReadStream",
7628 "Ignoring trailing \"%s\" while reading data for branch %s on line %lld",
7629 remainder.c_str(), branch->GetName(), nlines);
7635 if (iBranch < nbranches) {
7636 Warning(
"ReadStream",
7637 "Read too few columns (%d < %d) in line %lld; ignoring line",
7638 iBranch, nbranches, nlines);
7640 }
else if (pos != kNPOS) {
7641 sLine = sLine.Strip(TString::kTrailing);
7642 if (pos < sLine.Length()) {
7643 Warning(
"ReadStream",
7644 "Ignoring trailing \"%s\" while reading line %lld",
7645 sLine.Data() + pos - 1 ,
7664 void TTree::RecursiveRemove(TObject *obj)
7666 if (obj == fEventList) {
7669 if (obj == fEntryList) {
7673 fUserInfo->RecursiveRemove(obj);
7675 if (fPlayer == obj) {
7678 if (fTreeIndex == obj) {
7682 fAliases->RecursiveRemove(obj);
7685 fFriends->RecursiveRemove(obj);
7695 void TTree::Refresh()
7697 if (!fDirectory->GetFile()) {
7700 fDirectory->ReadKeys();
7701 fDirectory->Remove(
this);
7702 TTree* tree; fDirectory->GetObject(GetName(),tree);
7709 ImportClusterRanges(tree);
7711 fAutoSave = tree->fAutoSave;
7712 fEntries = tree->fEntries;
7713 fTotBytes = tree->GetTotBytes();
7714 fZipBytes = tree->GetZipBytes();
7715 fSavedBytes = tree->fSavedBytes;
7716 fTotalBuffers = tree->fTotalBuffers.load();
7719 Int_t nleaves = fLeaves.GetEntriesFast();
7720 for (Int_t i = 0; i < nleaves; i++) {
7721 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
7722 TBranch* branch = (TBranch*) leaf->GetBranch();
7723 branch->Refresh(tree->GetBranch(branch->GetName()));
7725 fDirectory->Remove(tree);
7726 fDirectory->Append(
this);
7734 void TTree::RemoveFriend(TTree* oldFriend)
7738 if (kRemoveFriend & fFriendLockStatus) {
7744 TFriendLock lock(
this, kRemoveFriend);
7745 TIter nextf(fFriends);
7746 TFriendElement* fe = 0;
7747 while ((fe = (TFriendElement*) nextf())) {
7748 TTree* friend_t = fe->GetTree();
7749 if (friend_t == oldFriend) {
7750 fFriends->Remove(fe);
7760 void TTree::Reset(Option_t* option)
7776 Int_t nb = fBranches.GetEntriesFast();
7777 for (Int_t i = 0; i < nb; ++i) {
7778 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
7779 branch->Reset(option);
7783 fBranchRef->Reset();
7791 void TTree::ResetAfterMerge(TFileMergeInfo *info)
7806 Int_t nb = fBranches.GetEntriesFast();
7807 for (Int_t i = 0; i < nb; ++i) {
7808 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
7809 branch->ResetAfterMerge(info);
7813 fBranchRef->ResetAfterMerge(info);
7822 void TTree::ResetBranchAddress(TBranch *br)
7824 if (br && br->GetTree()) {
7832 void TTree::ResetBranchAddresses()
7834 TObjArray* branches = GetListOfBranches();
7835 Int_t nbranches = branches->GetEntriesFast();
7836 for (Int_t i = 0; i < nbranches; ++i) {
7837 TBranch* branch = (TBranch*) branches->UncheckedAt(i);
7838 branch->ResetAddress();
7851 Long64_t TTree::Scan(
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
7855 return fPlayer->Scan(varexp, selection, option, nentries, firstentry);
7893 Bool_t TTree::SetAlias(
const char* aliasName,
const char* aliasFormula)
7895 if (!aliasName || !aliasFormula) {
7898 if (!aliasName[0] || !aliasFormula[0]) {
7902 fAliases =
new TList;
7904 TNamed* oldHolder = (TNamed*) fAliases->FindObject(aliasName);
7906 oldHolder->SetTitle(aliasFormula);
7910 TNamed* holder =
new TNamed(aliasName, aliasFormula);
7911 fAliases->Add(holder);
7948 void TTree::SetAutoFlush(Long64_t autof )
7995 if( fAutoFlush != autof) {
7996 if ((fAutoFlush > 0 || autof > 0) && fFlushedBytes) {
8010 void TTree::MarkEventCluster()
8012 if (!fEntries)
return;
8014 if ( (fNClusterRange+1) > fMaxClusterRange ) {
8015 if (fMaxClusterRange) {
8017 Int_t newsize = TMath::Max(10,Int_t(2*fMaxClusterRange));
8018 fClusterRangeEnd = (Long64_t*)TStorage::ReAlloc(fClusterRangeEnd,
8019 newsize*
sizeof(Long64_t),fMaxClusterRange*
sizeof(Long64_t));
8020 fClusterSize = (Long64_t*)TStorage::ReAlloc(fClusterSize,
8021 newsize*
sizeof(Long64_t),fMaxClusterRange*
sizeof(Long64_t));
8022 fMaxClusterRange = newsize;
8025 fMaxClusterRange = 2;
8026 fClusterRangeEnd =
new Long64_t[fMaxClusterRange];
8027 fClusterSize =
new Long64_t[fMaxClusterRange];
8030 fClusterRangeEnd[fNClusterRange] = fEntries - 1;
8032 if (fAutoFlush > 0) {
8035 fClusterSize[fNClusterRange] = fAutoFlush;
8037 }
else if (fNClusterRange == 0) {
8038 fClusterSize[fNClusterRange] = fEntries;
8040 fClusterSize[fNClusterRange] = fClusterRangeEnd[fNClusterRange] - fClusterRangeEnd[fNClusterRange-1];
8057 void TTree::SetAutoSave(Long64_t autos)
8073 void TTree::SetBasketSize(
const char* bname, Int_t buffsize)
8075 Int_t nleaves = fLeaves.GetEntriesFast();
8076 TRegexp re(bname, kTRUE);
8078 for (Int_t i = 0; i < nleaves; i++) {
8079 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
8080 TBranch* branch = (TBranch*) leaf->GetBranch();
8081 TString s = branch->GetName();
8082 if (strcmp(bname, branch->GetName()) && (s.Index(re) == kNPOS)) {
8086 branch->SetBasketSize(buffsize);
8089 Error(
"SetBasketSize",
"unknown branch -> '%s'", bname);
8100 Int_t TTree::SetBranchAddress(
const char* bname,
void* addr, TBranch** ptr)
8102 TBranch* branch = GetBranch(bname);
8105 Error(
"SetBranchAddress",
"unknown branch -> %s", bname);
8106 return kMissingBranch;
8108 return SetBranchAddressImp(branch,addr,ptr);
8118 Int_t TTree::SetBranchAddress(
const char* bname,
void* addr, TClass* ptrClass, EDataType datatype, Bool_t isptr)
8120 return SetBranchAddress(bname, addr, 0, ptrClass, datatype, isptr);
8130 Int_t TTree::SetBranchAddress(
const char* bname,
void* addr, TBranch** ptr, TClass* ptrClass, EDataType datatype, Bool_t isptr)
8132 TBranch* branch = GetBranch(bname);
8135 Error(
"SetBranchAddress",
"unknown branch -> %s", bname);
8136 return kMissingBranch;
8139 Int_t res = CheckBranchAddressType(branch, ptrClass, datatype, isptr);
8143 SetBranchAddressImp(branch,addr,ptr);
8157 Int_t TTree::SetBranchAddressImp(TBranch *branch,
void* addr, TBranch** ptr)
8163 void* oldAddr = branch->GetAddress();
8164 TIter next(fClones);
8166 const char *bname = branch->GetName();
8167 while ((clone = (TTree*) next())) {
8168 TBranch* cloneBr = clone->GetBranch(bname);
8169 if (cloneBr && (cloneBr->GetAddress() == oldAddr)) {
8170 cloneBr->SetAddress(addr);
8174 branch->SetAddress(addr);
8246 void TTree::SetBranchStatus(
const char* bname, Bool_t status, UInt_t* found)
8250 if (kSetBranchStatus & fFriendLockStatus) {
8254 if (0 == strcmp(bname,
"")) {
8255 Error(
"SetBranchStatus",
"Input regexp is an empty string: no match against branch names will be attempted.");
8259 TBranch *branch, *bcount, *bson;
8260 TLeaf *leaf, *leafcount;
8263 Int_t nleaves = fLeaves.GetEntriesFast();
8264 TRegexp re(bname,kTRUE);
8269 for (i=0;i<nleaves;i++) {
8270 leaf = (TLeaf*)fLeaves.UncheckedAt(i);
8271 branch = (TBranch*)leaf->GetBranch();
8272 TString s = branch->GetName();
8273 if (strcmp(bname,
"*")) {
8275 longname.Form(
"%s.%s",GetName(),branch->GetName());
8276 if (strcmp(bname,branch->GetName())
8277 && longname != bname
8278 && s.Index(re) == kNPOS)
continue;
8281 if (status) branch->ResetBit(kDoNotProcess);
8282 else branch->SetBit(kDoNotProcess);
8283 leafcount = leaf->GetLeafCount();
8285 bcount = leafcount->GetBranch();
8286 if (status) bcount->ResetBit(kDoNotProcess);
8287 else bcount->SetBit(kDoNotProcess);
8290 if (nb==0 && strchr(bname,
'*')==0) {
8291 branch = GetBranch(bname);
8293 if (status) branch->ResetBit(kDoNotProcess);
8294 else branch->SetBit(kDoNotProcess);
8300 UInt_t foundInFriend = 0;
8302 TFriendLock lock(
this,kSetBranchStatus);
8303 TIter nextf(fFriends);
8306 while ((fe = (TFriendElement*)nextf())) {
8307 TTree *t = fe->GetTree();
8311 char *subbranch = (
char*)strstr(bname,fe->GetName());
8312 if (subbranch!=bname) subbranch = 0;
8314 subbranch += strlen(fe->GetName());
8315 if ( *subbranch !=
'.' ) subbranch = 0;
8319 name.Form(
"%s.%s",t->GetName(),subbranch);
8323 t->SetBranchStatus(name,status, &foundInFriend);
8326 if (!nb && !foundInFriend) {
8329 if (strchr(bname,
'*') != 0)
8330 Error(
"SetBranchStatus",
"No branch name is matching wildcard -> %s", bname);
8332 Error(
"SetBranchStatus",
"unknown branch -> %s", bname);
8334 if (strchr(bname,
'*') != 0)
8335 Warning(
"SetBranchStatus",
"No branch name is matching wildcard -> %s", bname);
8337 Warning(
"SetBranchStatus",
"unknown branch -> %s", bname);
8342 if (found) *found = nb + foundInFriend;
8346 for (i = 0; i < nleaves; i++) {
8347 leaf = (TLeaf*)fLeaves.UncheckedAt(i);
8348 branch = (TBranch*)leaf->GetBranch();
8349 if (!branch->TestBit(kDoNotProcess)) {
8350 leafcount = leaf->GetLeafCount();
8352 bcount = leafcount->GetBranch();
8353 bcount->ResetBit(kDoNotProcess);
8357 Int_t nbranches = branch->GetListOfBranches()->GetEntries();
8358 for (j=0;j<nbranches;j++) {
8359 bson = (TBranch*)branch->GetListOfBranches()->UncheckedAt(j);
8360 if (!bson)
continue;
8361 if (!bson->TestBit(kDoNotProcess)) {
8362 if (bson->GetNleaves() <= 0)
continue;
8363 branch->ResetBit(kDoNotProcess);
8377 void TTree::SetBranchStyle(Int_t style)
8379 fgBranchStyle = style;
8393 Int_t TTree::SetCacheSize(Long64_t cacheSize)
8396 fCacheUserSet = kTRUE;
8398 return SetCacheSizeAux(kFALSE, cacheSize);
8419 Int_t TTree::SetCacheSizeAux(Bool_t autocache , Long64_t cacheSize )
8423 fCacheDoAutoInit = kFALSE;
8428 if (cacheSize < 0) {
8429 cacheSize = GetCacheAutoSize(kTRUE);
8432 if (cacheSize == 0) {
8433 cacheSize = GetCacheAutoSize();
8434 }
else if (cacheSize < 0) {
8435 cacheSize = GetCacheAutoSize(kTRUE);
8439 TFile* file = GetCurrentFile();
8440 if (!file || GetTree() !=
this) {
8444 fCacheSize = cacheSize;
8446 if (GetTree() !=
this) {
8449 if (!autocache && cacheSize>0) {
8450 Warning(
"SetCacheSizeAux",
"A TTreeCache could not be created because the TTree has no file");
8456 TTreeCache* pf = GetReadCache(file);
8461 fCacheSize = pf->GetBufferSize();
8462 fCacheUserSet = !pf->IsAutoCreated();
8464 if (fCacheUserSet) {
8471 pf->SetAutoCreated(kFALSE);
8476 if (autocache && Long64_t(0.80*cacheSize) < fCacheSize) {
8481 if (cacheSize == fCacheSize) {
8485 if (cacheSize == 0) {
8487 pf->WaitFinishPrefetch();
8488 file->SetCacheRead(0,
this);
8493 Int_t res = pf->SetBufferSize(cacheSize);
8501 if (fCacheUserSet) {
8503 if (fCacheSize == 0)
return 0;
8507 Error(
"SetCacheSizeAux",
"Not setting up an automatically sized TTreeCache because of missing cache previously set");
8514 fCacheSize = cacheSize;
8515 if (cacheSize == 0 || pf) {
8520 if(TTreeCacheUnzip::IsParallelUnzip() && file->GetCompressionLevel() > 0)
8521 pf =
new TTreeCacheUnzip(
this, cacheSize);
8524 pf =
new TTreeCache(
this, cacheSize);
8526 pf->SetAutoCreated(autocache);
8538 Int_t TTree::SetCacheEntryRange(Long64_t first, Long64_t last)
8541 if (LoadTree(0)<0) {
8542 Error(
"SetCacheEntryRange",
"Could not load a tree");
8547 if (GetTree() !=
this) {
8548 return GetTree()->SetCacheEntryRange(first, last);
8551 Error(
"SetCacheEntryRange",
"No tree is available. Could not set cache entry range");
8555 TFile *f = GetCurrentFile();
8557 Error(
"SetCacheEntryRange",
"No file is available. Could not set cache entry range");
8560 TTreeCache *tc = GetReadCache(f,kTRUE);
8562 Error(
"SetCacheEntryRange",
"No cache is available. Could not set entry range");
8565 tc->SetEntryRange(first,last);
8572 void TTree::SetCacheLearnEntries(Int_t n)
8574 TTreeCache::SetLearnEntries(n);
8599 void TTree::SetCircular(Long64_t maxEntries)
8601 if (maxEntries <= 0) {
8603 fMaxEntries = 1000000000;
8604 fMaxEntries *= 1000;
8605 ResetBit(kCircular);
8610 TFile* bfile = fDirectory->GetFile();
8611 Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault;
8613 compress = bfile->GetCompressionSettings();
8615 Int_t nb = fBranches.GetEntriesFast();
8616 for (Int_t i = 0; i < nb; i++) {
8617 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
8618 branch->SetCompressionSettings(compress);
8623 fMaxEntries = maxEntries;
8635 void TTree::SetDebug(Int_t level, Long64_t min, Long64_t max)
8647 void TTree::SetDefaultEntryOffsetLen(Int_t newdefault, Bool_t updateExisting)
8649 if (newdefault < 10) {
8652 fDefaultEntryOffsetLen = newdefault;
8653 if (updateExisting) {
8654 TIter next( GetListOfBranches() );
8656 while ( ( b = (TBranch*)next() ) ) {
8657 b->SetEntryOffsetLen( newdefault, kTRUE );
8660 fBranchRef->SetEntryOffsetLen( newdefault, kTRUE );
8673 void TTree::SetDirectory(TDirectory* dir)
8675 if (fDirectory == dir) {
8679 fDirectory->Remove(
this);
8682 TFile *file = fDirectory->GetFile();
8683 MoveReadCache(file,dir);
8687 fDirectory->Append(
this);
8691 file = fDirectory->GetFile();
8694 fBranchRef->SetFile(file);
8697 TIter next(GetListOfBranches());
8698 while((b = (TBranch*) next())) {
8718 Long64_t TTree::SetEntries(Long64_t n)
8727 TBranch* b(
nullptr), *bMin(
nullptr), *bMax(
nullptr);
8728 Long64_t nMin = kMaxEntries;
8730 TIter next(GetListOfBranches());
8731 while((b = (TBranch*) next())){
8732 Long64_t n2 = b->GetEntries();
8733 if (!bMin || n2 < nMin) {
8737 if (!bMax || n2 > nMax) {
8742 if (bMin && nMin != nMax) {
8743 Warning(
"SetEntries",
"Tree branches have different numbers of entries, eg %s has %lld entries while %s has %lld entries.",
8744 bMin->GetName(), nMin, bMax->GetName(), nMax);
8753 void TTree::SetEntryList(TEntryList *enlist, Option_t * )
8757 if (fEntryList->TestBit(kCanDelete)){
8766 fEntryList = enlist;
8767 fEntryList->SetTree(
this);
8776 void TTree::SetEventList(TEventList *evlist)
8778 fEventList = evlist;
8780 if (fEntryList->TestBit(kCanDelete)) {
8781 TEntryList *tmp = fEntryList;
8795 fEventList = evlist;
8796 char enlistname[100];
8797 snprintf(enlistname,100,
"%s_%s", evlist->GetName(),
"entrylist");
8798 fEntryList =
new TEntryList(enlistname, evlist->GetTitle());
8799 fEntryList->SetDirectory(0);
8800 Int_t nsel = evlist->GetN();
8801 fEntryList->SetTree(
this);
8803 for (Int_t i=0; i<nsel; i++){
8804 entry = evlist->GetEntry(i);
8805 fEntryList->Enter(entry);
8807 fEntryList->SetReapplyCut(evlist->GetReapplyCut());
8808 fEntryList->SetBit(kCanDelete, kTRUE);
8817 void TTree::SetEstimate(Long64_t n )
8827 fPlayer->SetEstimate(n);
8837 ROOT::TIOFeatures TTree::SetIOFeatures(
const ROOT::TIOFeatures &features)
8841 UChar_t featuresRequested = features.GetFeatures() &
static_cast<UChar_t
>(TBasket::EIOBits::kSupported);
8843 UChar_t curFeatures = fIOFeatures.GetFeatures();
8844 UChar_t newFeatures = ~curFeatures & featuresRequested;
8845 curFeatures |= newFeatures;
8846 fIOFeatures.Set(curFeatures);
8848 ROOT::TIOFeatures newSettings(newFeatures);
8860 void TTree::SetFileNumber(Int_t number)
8862 if (fFileNumber < 0) {
8863 Warning(
"SetFileNumber",
"file number must be positive. Set to 0");
8867 fFileNumber = number;
8884 void TTree::SetMakeClass(Int_t make)
8888 Int_t nb = fBranches.GetEntriesFast();
8889 for (Int_t i = 0; i < nb; ++i) {
8890 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
8891 branch->SetMakeClass(make);
8904 void TTree::SetMaxTreeSize(Long64_t maxsize)
8906 fgMaxTreeSize = maxsize;
8912 void TTree::SetName(
const char* name)
8922 fDirectory->Remove(
this);
8923 if ((file = GetCurrentFile())) {
8924 pf = GetReadCache(file);
8925 file->SetCacheRead(0,
this,TFile::kDoNotDisconnect);
8931 fDirectory->Append(
this);
8933 file->SetCacheRead(pf,
this,TFile::kDoNotDisconnect);
8941 void TTree::SetObject(
const char* name,
const char* title)
8952 fDirectory->Remove(
this);
8953 if ((file = GetCurrentFile())) {
8954 pf = GetReadCache(file);
8955 file->SetCacheRead(0,
this,TFile::kDoNotDisconnect);
8962 fDirectory->Append(
this);
8964 file->SetCacheRead(pf,
this,TFile::kDoNotDisconnect);
8972 void TTree::SetParallelUnzip(Bool_t opt, Float_t RelSize)
8975 if (GetTree() == 0) {
8976 LoadTree(GetReadEntry());
8980 if (GetTree() !=
this) {
8981 GetTree()->SetParallelUnzip(opt, RelSize);
8984 TFile* file = GetCurrentFile();
8988 TTreeCache* pf = GetReadCache(file);
8989 if (pf && !( opt ^ (
nullptr != dynamic_cast<TTreeCacheUnzip*>(pf)))) {
8994 auto cacheSize = GetCacheAutoSize(kTRUE);
8996 auto unzip =
new TTreeCacheUnzip(
this, cacheSize);
8997 unzip->SetUnzipBufferSize( Long64_t(cacheSize * RelSize) );
8999 pf =
new TTreeCache(
this, cacheSize);
9010 void TTree::SetPerfStats(TVirtualPerfStats *perf)
9027 void TTree::SetTreeIndex(TVirtualIndex* index)
9030 fTreeIndex->SetTree(0);
9055 void TTree::SetWeight(Double_t w, Option_t*)
9066 void TTree::Show(Long64_t entry, Int_t lenmax)
9069 Int_t ret = LoadTree(entry);
9071 Error(
"Show()",
"Cannot read entry %lld (entry does not exist)", entry);
9073 }
else if (ret == -1) {
9074 Error(
"Show()",
"Cannot read entry %lld (I/O error)", entry);
9077 ret = GetEntry(entry);
9079 Error(
"Show()",
"Cannot read entry %lld (I/O error)", entry);
9081 }
else if (ret == 0) {
9082 Error(
"Show()",
"Cannot read entry %lld (no data read)", entry);
9086 printf(
"======> EVENT:%lld\n", fReadEntry);
9087 TObjArray* leaves = GetListOfLeaves();
9088 Int_t nleaves = leaves->GetEntriesFast();
9090 for (Int_t i = 0; i < nleaves; i++) {
9091 TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
9092 TBranch* branch = leaf->GetBranch();
9093 if (branch->TestBit(kDoNotProcess)) {
9096 Int_t len = leaf->GetLen();
9100 len = TMath::Min(len, lenmax);
9101 if (leaf->IsA() == TLeafElement::Class()) {
9102 leaf->PrintValue(lenmax);
9105 if (branch->GetListOfBranches()->GetEntriesFast() > 0) {
9109 if (leaf->IsA() == TLeafF::Class()) {
9112 if (leaf->IsA() == TLeafD::Class()) {
9115 if (leaf->IsA() == TLeafC::Class()) {
9119 printf(
" %-15s = ", leaf->GetName());
9120 for (Int_t l = 0; l < len; l++) {
9121 leaf->PrintValue(l);
9122 if (l == (len - 1)) {
9127 if ((l % ltype) == 0) {
9140 void TTree::StartViewer()
9144 fPlayer->StartViewer(600, 400);
9155 Int_t TTree::StopCacheLearningPhase()
9158 if (LoadTree(0)<0) {
9159 Error(
"StopCacheLearningPhase",
"Could not load a tree");
9164 if (GetTree() !=
this) {
9165 return GetTree()->StopCacheLearningPhase();
9168 Error(
"StopCacheLearningPhase",
"No tree is available. Could not stop cache learning phase");
9172 TFile *f = GetCurrentFile();
9174 Error(
"StopCacheLearningPhase",
"No file is available. Could not stop cache learning phase");
9177 TTreeCache *tc = GetReadCache(f,kTRUE);
9179 Error(
"StopCacheLearningPhase",
"No cache is available. Could not stop learning phase");
9182 tc->StopLearningPhase();
9189 static void TBranch__SetTree(TTree *tree, TObjArray &branches)
9191 Int_t nb = branches.GetEntriesFast();
9192 for (Int_t i = 0; i < nb; ++i) {
9193 TBranch* br = (TBranch*) branches.UncheckedAt(i);
9196 Int_t nBaskets = br->GetListOfBaskets()->GetEntries();
9197 Int_t writeBasket = br->GetWriteBasket();
9198 for (Int_t j=writeBasket,n=0;j>=0 && n<nBaskets;--j) {
9199 TBasket *bk = (TBasket*)br->GetListOfBaskets()->UncheckedAt(j);
9201 tree->IncrementTotalBuffers(bk->GetBufferSize());
9206 TBranch__SetTree(tree,*br->GetListOfBranches());
9213 void TFriendElement__SetTree(TTree *tree, TList *frlist)
9216 TObjLink *lnk = frlist->FirstLink();
9218 TFriendElement *elem = (TFriendElement*)lnk->GetObject();
9219 elem->fParentTree = tree;
9228 void TTree::Streamer(TBuffer& b)
9230 if (b.IsReading()) {
9233 fDirectory->Remove(
this);
9235 TFile *file = fDirectory->GetFile();
9236 MoveReadCache(file,0);
9239 fCacheDoAutoInit = kTRUE;
9240 fCacheUserSet = kFALSE;
9241 Version_t R__v = b.ReadVersion(&R__s, &R__c);
9243 b.ReadClassBuffer(TTree::Class(),
this, R__v, R__s, R__c);
9245 fBranches.SetOwner(kTRUE);
9247 if (fBranchRef) fBranchRef->SetTree(
this);
9248 TBranch__SetTree(
this,fBranches);
9249 TFriendElement__SetTree(
this,fFriends);
9252 fTreeIndex->SetTree(
this);
9255 Warning(
"Streamer",
"Old style index in this tree is deleted. Rebuild the index via TTree::BuildIndex");
9257 fIndexValues.Set(0);
9259 if (fEstimate <= 10000) {
9260 fEstimate = 1000000;
9263 if (fNClusterRange) {
9266 fMaxClusterRange = fNClusterRange;
9268 if (GetCacheAutoSize() != 0) {
9272 }
else if (fAutoFlush < 0) {
9275 fCacheSize = fAutoFlush;
9276 }
else if (fAutoFlush != 0) {
9279 Long64_t zipBytes = GetZipBytes();
9280 Long64_t totBytes = GetTotBytes();
9281 if (zipBytes != 0) {
9282 fCacheSize = fAutoFlush*(zipBytes/fEntries);
9283 }
else if (totBytes != 0) {
9284 fCacheSize = fAutoFlush*(totBytes/fEntries);
9286 fCacheSize = 30000000;
9288 if (fCacheSize >= (INT_MAX / 4)) {
9289 fCacheSize = INT_MAX / 4;
9290 }
else if (fCacheSize == 0) {
9291 fCacheSize = 30000000;
9296 ResetBit(kMustCleanup);
9302 TNamed::Streamer(b);
9303 TAttLine::Streamer(b);
9304 TAttFill::Streamer(b);
9305 TAttMarker::Streamer(b);
9307 b >> ijunk; fMaxEntryLoop = (Long64_t)ijunk;
9308 b >> ijunk; fMaxVirtualSize = (Long64_t)ijunk;
9309 b >> djunk; fEntries = (Long64_t)djunk;
9310 b >> djunk; fTotBytes = (Long64_t)djunk;
9311 b >> djunk; fZipBytes = (Long64_t)djunk;
9312 b >> ijunk; fAutoSave = (Long64_t)ijunk;
9313 b >> ijunk; fEstimate = (Long64_t)ijunk;
9314 if (fEstimate <= 10000) fEstimate = 1000000;
9315 fBranches.Streamer(b);
9316 if (fBranchRef) fBranchRef->SetTree(
this);
9317 TBranch__SetTree(
this,fBranches);
9318 fLeaves.Streamer(b);
9319 fSavedBytes = fTotBytes;
9320 if (R__v > 1) fIndexValues.Streamer(b);
9321 if (R__v > 2) fIndex.Streamer(b);
9324 OldInfoList.Streamer(b);
9325 OldInfoList.Delete();
9328 fDefaultEntryOffsetLen = 1000;
9329 ResetBit(kMustCleanup);
9330 b.CheckByteCount(R__s, R__c, TTree::IsA());
9334 fBranchRef->Clear();
9336 TRefTable *table = TRefTable::GetRefTable();
9337 if (table) TRefTable::SetRefTable(0);
9339 b.WriteClassBuffer(TTree::Class(),
this);
9341 if (table) TRefTable::SetRefTable(table);
9406 Int_t TTree::UnbinnedFit(
const char* funcname,
const char* varexp,
const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
9410 return fPlayer->UnbinnedFit(funcname, varexp, selection, option, nentries, firstentry);
9418 void TTree::UseCurrentStyle()
9420 if (gStyle->IsReading()) {
9421 SetFillColor(gStyle->GetHistFillColor());
9422 SetFillStyle(gStyle->GetHistFillStyle());
9423 SetLineColor(gStyle->GetHistLineColor());
9424 SetLineStyle(gStyle->GetHistLineStyle());
9425 SetLineWidth(gStyle->GetHistLineWidth());
9426 SetMarkerColor(gStyle->GetMarkerColor());
9427 SetMarkerStyle(gStyle->GetMarkerStyle());
9428 SetMarkerSize(gStyle->GetMarkerSize());
9430 gStyle->SetHistFillColor(GetFillColor());
9431 gStyle->SetHistFillStyle(GetFillStyle());
9432 gStyle->SetHistLineColor(GetLineColor());
9433 gStyle->SetHistLineStyle(GetLineStyle());
9434 gStyle->SetHistLineWidth(GetLineWidth());
9435 gStyle->SetMarkerColor(GetMarkerColor());
9436 gStyle->SetMarkerStyle(GetMarkerStyle());
9437 gStyle->SetMarkerSize(GetMarkerSize());
9445 Int_t TTree::Write(
const char *name, Int_t option, Int_t bufsize)
const
9448 return TObject::Write(name, option, bufsize);
9455 Int_t TTree::Write(
const char *name, Int_t option, Int_t bufsize)
9457 return ((
const TTree*)
this)->Write(name, option, bufsize);
9465 ClassImp(TTreeFriendLeafIter);
9471 TTreeFriendLeafIter::TTreeFriendLeafIter(
const TTree* tree, Bool_t dir)
9472 : fTree(const_cast<TTree*>(tree))
9482 TTreeFriendLeafIter::TTreeFriendLeafIter(
const TTreeFriendLeafIter& iter)
9487 , fDirection(iter.fDirection)
9494 TIterator& TTreeFriendLeafIter::operator=(
const TIterator& rhs)
9496 if (
this != &rhs && rhs.IsA() == TTreeFriendLeafIter::Class()) {
9497 const TTreeFriendLeafIter &rhs1 = (
const TTreeFriendLeafIter &)rhs;
9498 fDirection = rhs1.fDirection;
9506 TTreeFriendLeafIter& TTreeFriendLeafIter::operator=(
const TTreeFriendLeafIter& rhs)
9509 fDirection = rhs.fDirection;
9517 TObject* TTreeFriendLeafIter::Next()
9519 if (!fTree)
return 0;
9525 TObjArray *list = fTree->GetListOfLeaves();
9526 if (!list)
return 0;
9527 fLeafIter = list->MakeIterator(fDirection);
9528 if (!fLeafIter)
return 0;
9531 next = fLeafIter->Next();
9534 TCollection * list = fTree->GetListOfFriends();
9535 if (!list)
return next;
9536 fTreeIter = list->MakeIterator(fDirection);
9537 if (!fTreeIter)
return 0;
9539 TFriendElement * nextFriend = (TFriendElement*) fTreeIter->Next();
9542 nextTree =
const_cast<TTree*
>(nextFriend->GetTree());
9543 if (!nextTree)
return Next();
9544 SafeDelete(fLeafIter);
9545 fLeafIter = nextTree->GetListOfLeaves()->MakeIterator(fDirection);
9546 if (!fLeafIter)
return 0;
9547 next = fLeafIter->Next();
9556 Option_t* TTreeFriendLeafIter::GetOption()
const
9558 if (fLeafIter)
return fLeafIter->GetOption();