<commit_before><br> 
<hr> 
<a name="tree"></a> 
<h3>Tree</h3>
<ul>
<li>Changed the MaxTreeSize default from 1.9 GBytes to 100 GBytes.</li>

<li>Add new special functions in TTreeFormula (and hence TTree::Draw and TTree::Scan) to calculate the minimun and maximum with an entry:
    <ul>
    <li><pre lang="cxx">Min$(formula),Max$(formula):</pre>return the minimun/maximum (within one TTree entry) of the value of the
                       elements of the formula given as a parameter.</li>
    <li><pre lang="cxx">MinIf$(formula,condition),MaxIf$(formula,condition):</pre>return the minimum (maximum) (within one TTree entry)
                       of the value of the elements of the formula given as a parameter
                      if they match the condition. If not element match the condition, the result is zero.  To avoid the
                       the result is zero.  To avoid the consequent peak a zero, use the 
                       pattern: 
       <pre lang="cxx">tree->Draw("MinIf$(formula,condition)","condition");</pre>
                       which will avoid calculation MinIf$ for the entries that have no match 
                       for the condition.</li>
    </ul>
</li>
<li>Add support in TTreeFormula (and hence TTree::Draw and TTree::Scan) for the ternary condition operator ( cond ? if_expr : else_expr ).</li>
<li>Significantly (by 2 order of magnitude) improved the performance of TTree::Draw calling C++ functions.</li>
<li>Replace the function <tt>TSelectorDraw::MakeIndex</tt> and <tt>TSelectorDraw::GetNameByIndex</tt> 
     with the function <tt>TSelectorDraw::SplitNames.</tt>  </li>
<li>Add a return value to SetBranchAddress, a return value greater or equal to zero indicate success, a negative
value indicates failure (in both case, the address is still updated).  Example:
<pre lang="cxx">if (tree->SetBranchAddress(mybranch,&myvar) < 0) {
   cerr << "Something went wrong\n";
   return;
}</pre>
The possible return values are:<ul>
<li>kMissingBranch (-5) : Missing branch</li>
<li>kInternalError (-4) : Internal error (could not find the type corresponding to a data type number.</li>
<li>kMissingCompiledCollectionProxy (-3) : Missing compiled collection proxy for a compiled collection.</li>
<li>kMismatch (-2) : Non-Class Pointer type given does not match the type expected by the branch.</li>
<li>kClassMismatch (-1) : Class Pointer type given does not match the type expected by the branch.</li>
<li>kMatch (0) : perfect match.</li>
<li>kMatchConversion (1) : match with (I/O) conversion.</li>
<li>kMatchConversionCollection (2) : match with (I/O) conversion of the content of a collection.</li>
<li>kMakeClass (3) : MakeClass mode so we can not check.</li>
<li>kVoidPtr (4) : void* passed so no check was made.</li>
<li>kNoCheck (5) : Underlying TBranch not yet available so no check was made.</li>
</ul>
<li>Insure that the TTreeCloner (fast merging) is able to also copy 'uninitialized' TStreamerInfo describing abstract classes.</li>
<li>Repair several use case of splitting collection of pointers (especially when their split level is 1).</li>
<li>Several run-time performance improvements.</li>
<li>In TTree::Fill use fZipBytes instead of fTotBytes for deciding when to flush or autosave.</li>
<li>Properly handle TTree aliases containing array indices.</li>
<li>Fix the default sorting order of baskets when the TTree is an older in-memory TTree.
Enhance the sort order to use the 'entry number' when the seek position are equal.
Consequently the default sort order for an older in-memory TTree is now
essentially kSortBasketsByEntry rather than kSortBasketsByBranch (old 'correct' sort 
order) or 'random' (the 'broken' sort order prior to this release).</li>
</ul>
<h4>IMPORTANT enhancement in TTree::Fill:</h4>

The baskets are flushed and the Tree header saved at regular intervals (See AutoFlush and OptimizeBaskets)<p>

When the amount of data written so far (fTotBytes) is greater than fAutoFlush (see SetAutoFlush) all the baskets are flushed to disk.
This makes future reading faster as it guarantees that baskets belonging to nearby entries will be on the same disk region.<p>
When the first call to flush the baskets happens, we also take this opportunity to optimize the baskets buffers. 
We also check if the number of bytes written is greater than fAutoSave (see SetAutoSave).
In this case we also write the Tree header. This makes the Tree recoverable up to this point in case the program writing the Tree crashes.<p>
Note that the user can also decide to call FlushBaskets and AutoSave in her event loop on the base of the number of events written instead of the number of bytes written.

<h4>New function TTree::OptimizeBaskets</h4>
void TTree::OptimizeBaskets(Int_t maxMemory, Float_t minComp, Option_t *option) 
<p>
This function may be called after having filled some entries in a Tree
using the information in the existing branch buffers, it will reassign
new branch buffer sizes to optimize time and memory.

The function computes the best values for branch buffer sizes such that
the total buffer sizes is less than maxMemory and nearby entries written 
at the same time.
In case the branch compression factor for the data written so far is less 
than compMin, the compression is disabled.
 
if option ="d" an analysis report is printed.

<p>
This function may also be called on an existing Tree to figure out the best values
given the information in the Tree header
<pre>
   TFile f("myfile.root");
   TTree *T = (TTree*)f.Get("mytreename");
   T->Print();  //show the branch buffer sizes before optimization
   T->OptimizeBaskets(10000000,1,"d");
   T->Print();  //show the branch buffer sizes after optimization
</pre>

<h4>New interface functions to customize the TreeCache</h4>
<pre lang="cxx">   virtual void  AddBranchToCache(const char *bname, Bool_t subbranches = kFALSE);
   virtual void  AddBranchToCache(TBranch *branch,   Bool_t subbranches = kFALSE);
   virtual void  PrintCacheStats(Option_t* option = "") const;
   virtual void  SetParallelUnzip(Bool_t opt=kTRUE);
   virtual void  SetCacheEntryRange(Long64_t first, Long64_t last);
   virtual void  SetCacheLearnEntries(Int_t n=10);
   virtual void  StopCacheLearningPhase();</pre>

<h4>New functionality AutoFlush (and changes to AutoSave)</h4>

Implement a new member fAutoFlush in TTree with its getter and setter:

<pre lang="cxx">void TTree::SetAutoFlush(Long64_t autof)</pre>

The logic of the AutoFlush mechanism is optimized such that the TreeCache
will read always up to the point where FlushBaskets has been called.
This minimizes the number of cases where one has to seek backward when reading.
<br>
This function may be called at the start of a program to change
the default value for fAutoFlush.

<ul><li>CASE 1 : autof &gt; 0<br>

 autof is the number of consecutive entries after which TTree::Fill will
 flush all branch buffers to disk.

</li><li>     CASE 2 : autof &lt; 0<br>

 When filling the Tree the branch buffers will be flushed to disk when
 more than autof bytes have been written to the file. At the first FlushBaskets
 TTree::Fill will replace fAutoFlush by the current value of fEntries.

 Calling this function with autof &lt; 0 is interesting when it is hard to estimate
 the size of one entry. This value is also independent of the Tree.

 When calling SetAutoFlush with no arguments, the
 default value is -30000000, ie that the first AutoFlush will be done when
 30 MBytes of data are written to the file.

</li><li>      CASE 3 : autof = 0<br>
 The AutoFlush mechanism is disabled.

</li></ul>
 Flushing the buffers at regular intervals optimize the location of
 consecutive entries on the disk.

<br>
Changed the default value of AutoSave from 10 to 30 MBytes.
<br>



<h4>New class TTreePerfStats</h4>
This new class is an important tool to measure the I/O performance of a Tree.
It shows the locations in the file when reading a Tree. In particular it is easy
to see the performance of the Tree Cache. The results can be:
<ul>
<li>drawn in a canvas.</li>
<li>printed on standard output.</li>
<li>saved to a file for processing later.</li>
</ul>
<pre>
       Example of use                                                 
 {
   TFile *f = TFile::Open("RelValMinBias-GEN-SIM-RECO.root");
   T = (TTree*)f->Get("Events");
   Long64_t nentries = T->GetEntries();
   T->SetCacheSize(10000000);
   T->AddBranchToCache("*");

   TTreePerfStats *ps= new TTreePerfStats("ioperf",T);

   for (Int_t i=0;i<nentries;i++) {
      T->GetEntry(i);
   }
   ps->SaveAs("atlas_perf.root");
 }
</pre>
<p>
 then, in a root interactive session, one can do:
<pre>
    root > TFile f("atlas_perf.root");
    root > ioperf->Draw();
    root > ioperf->Print();
</pre>

<p> The Draw or Print functions print the following information:
<pre.
   TreeCache = TTree cache size in MBytes
   N leaves  = Number of leaves in the TTree
   ReadTotal = Total number of zipped bytes read<commit_msg>Fix a typo<commit_after><br> 
<hr> 
<a name="tree"></a> 
<h3>Tree</h3>
<ul>
<li>Changed the MaxTreeSize default from 1.9 GBytes to 100 GBytes.</li>

<li>Add new special functions in TTreeFormula (and hence TTree::Draw and TTree::Scan) to calculate the minimun and maximum with an entry:
    <ul>
    <li><pre lang="cxx">Min$(formula),Max$(formula):</pre>return the minimun/maximum (within one TTree entry) of the value of the
                       elements of the formula given as a parameter.</li>
    <li><pre lang="cxx">MinIf$(formula,condition),MaxIf$(formula,condition):</pre>return the minimum (maximum) (within one TTree entry)
                       of the value of the elements of the formula given as a parameter
                      if they match the condition. If not element match the condition, the result is zero.  To avoid the
                       the result is zero.  To avoid the consequent peak a zero, use the 
                       pattern: 
       <pre lang="cxx">tree->Draw("MinIf$(formula,condition)","condition");</pre>
                       which will avoid calculation MinIf$ for the entries that have no match 
                       for the condition.</li>
    </ul>
</li>
<li>Add support in TTreeFormula (and hence TTree::Draw and TTree::Scan) for the ternary condition operator ( cond ? if_expr : else_expr ).</li>
<li>Significantly (by 2 order of magnitude) improved the performance of TTree::Draw calling C++ functions.</li>
<li>Replace the function <tt>TSelectorDraw::MakeIndex</tt> and <tt>TSelectorDraw::GetNameByIndex</tt> 
     with the function <tt>TSelectorDraw::SplitNames.</tt>  </li>
<li>Add a return value to SetBranchAddress, a return value greater or equal to zero indicate success, a negative
value indicates failure (in both case, the address is still updated).  Example:
<pre lang="cxx">if (tree->SetBranchAddress(mybranch,&myvar) < 0) {
   cerr << "Something went wrong\n";
   return;
}</pre>
The possible return values are:<ul>
<li>kMissingBranch (-5) : Missing branch</li>
<li>kInternalError (-4) : Internal error (could not find the type corresponding to a data type number.</li>
<li>kMissingCompiledCollectionProxy (-3) : Missing compiled collection proxy for a compiled collection.</li>
<li>kMismatch (-2) : Non-Class Pointer type given does not match the type expected by the branch.</li>
<li>kClassMismatch (-1) : Class Pointer type given does not match the type expected by the branch.</li>
<li>kMatch (0) : perfect match.</li>
<li>kMatchConversion (1) : match with (I/O) conversion.</li>
<li>kMatchConversionCollection (2) : match with (I/O) conversion of the content of a collection.</li>
<li>kMakeClass (3) : MakeClass mode so we can not check.</li>
<li>kVoidPtr (4) : void* passed so no check was made.</li>
<li>kNoCheck (5) : Underlying TBranch not yet available so no check was made.</li>
</ul>
<li>Insure that the TTreeCloner (fast merging) is able to also copy 'uninitialized' TStreamerInfo describing abstract classes.</li>
<li>Repair several use case of splitting collection of pointers (especially when their split level is 1).</li>
<li>Several run-time performance improvements.</li>
<li>In TTree::Fill use fZipBytes instead of fTotBytes for deciding when to flush or autosave.</li>
<li>Properly handle TTree aliases containing array indices.</li>
<li>Fix the default sorting order of baskets when the TTree is an older in-memory TTree.
Enhance the sort order to use the 'entry number' when the seek position are equal.
Consequently the default sort order for an older in-memory TTree is now
essentially kSortBasketsByEntry rather than kSortBasketsByBranch (old 'correct' sort 
order) or 'random' (the 'broken' sort order prior to this release).</li>
</ul>
<h4>IMPORTANT enhancement in TTree::Fill:</h4>

The baskets are flushed and the Tree header saved at regular intervals (See AutoFlush and OptimizeBaskets)<p>

When the amount of data written so far (fTotBytes) is greater than fAutoFlush (see SetAutoFlush) all the baskets are flushed to disk.
This makes future reading faster as it guarantees that baskets belonging to nearby entries will be on the same disk region.<p>
When the first call to flush the baskets happens, we also take this opportunity to optimize the baskets buffers. 
We also check if the number of bytes written is greater than fAutoSave (see SetAutoSave).
In this case we also write the Tree header. This makes the Tree recoverable up to this point in case the program writing the Tree crashes.<p>
Note that the user can also decide to call FlushBaskets and AutoSave in her event loop on the base of the number of events written instead of the number of bytes written.

<h4>New function TTree::OptimizeBaskets</h4>
void TTree::OptimizeBaskets(Int_t maxMemory, Float_t minComp, Option_t *option) 
<p>
This function may be called after having filled some entries in a Tree
using the information in the existing branch buffers, it will reassign
new branch buffer sizes to optimize time and memory.

The function computes the best values for branch buffer sizes such that
the total buffer sizes is less than maxMemory and nearby entries written 
at the same time.
In case the branch compression factor for the data written so far is less 
than compMin, the compression is disabled.
 
if option ="d" an analysis report is printed.

<p>
This function may also be called on an existing Tree to figure out the best values
given the information in the Tree header
<pre>
   TFile f("myfile.root");
   TTree *T = (TTree*)f.Get("mytreename");
   T->Print();  //show the branch buffer sizes before optimization
   T->OptimizeBaskets(10000000,1,"d");
   T->Print();  //show the branch buffer sizes after optimization
</pre>

<h4>New interface functions to customize the TreeCache</h4>
<pre lang="cxx">   virtual void  AddBranchToCache(const char *bname, Bool_t subbranches = kFALSE);
   virtual void  AddBranchToCache(TBranch *branch,   Bool_t subbranches = kFALSE);
   virtual void  PrintCacheStats(Option_t* option = "") const;
   virtual void  SetParallelUnzip(Bool_t opt=kTRUE);
   virtual void  SetCacheEntryRange(Long64_t first, Long64_t last);
   virtual void  SetCacheLearnEntries(Int_t n=10);
   virtual void  StopCacheLearningPhase();</pre>

<h4>New functionality AutoFlush (and changes to AutoSave)</h4>

Implement a new member fAutoFlush in TTree with its getter and setter:

<pre lang="cxx">void TTree::SetAutoFlush(Long64_t autof)</pre>

The logic of the AutoFlush mechanism is optimized such that the TreeCache
will read always up to the point where FlushBaskets has been called.
This minimizes the number of cases where one has to seek backward when reading.
<br>
This function may be called at the start of a program to change
the default value for fAutoFlush.

<ul><li>CASE 1 : autof &gt; 0<br>

 autof is the number of consecutive entries after which TTree::Fill will
 flush all branch buffers to disk.

</li><li>     CASE 2 : autof &lt; 0<br>

 When filling the Tree the branch buffers will be flushed to disk when
 more than autof bytes have been written to the file. At the first FlushBaskets
 TTree::Fill will replace fAutoFlush by the current value of fEntries.

 Calling this function with autof &lt; 0 is interesting when it is hard to estimate
 the size of one entry. This value is also independent of the Tree.

 When calling SetAutoFlush with no arguments, the
 default value is -30000000, ie that the first AutoFlush will be done when
 30 MBytes of data are written to the file.

</li><li>      CASE 3 : autof = 0<br>
 The AutoFlush mechanism is disabled.

</li></ul>
 Flushing the buffers at regular intervals optimize the location of
 consecutive entries on the disk.

<br>
Changed the default value of AutoSave from 10 to 30 MBytes.
<br>



<h4>New class TTreePerfStats</h4>
This new class is an important tool to measure the I/O performance of a Tree.
It shows the locations in the file when reading a Tree. In particular it is easy
to see the performance of the Tree Cache. The results can be:
<ul>
<li>drawn in a canvas.</li>
<li>printed on standard output.</li>
<li>saved to a file for processing later.</li>
</ul>
<pre>
       Example of use                                                 
 {
   TFile *f = TFile::Open("RelValMinBias-GEN-SIM-RECO.root");
   T = (TTree*)f->Get("Events");
   Long64_t nentries = T->GetEntries();
   T->SetCacheSize(10000000);
   T->AddBranchToCache("*");

   TTreePerfStats *ps= new TTreePerfStats("ioperf",T);

   for (Int_t i=0;i<nentries;i++) {
      T->GetEntry(i);
   }
   ps->SaveAs("atlas_perf.root");
 }
</pre>
<p>
 then, in a root interactive session, one can do:
<pre>
    root > TFile f("atlas_perf.root");
    root > ioperf->Draw();
    root > ioperf->Print();
</pre>

<p> The Draw or Print functions print the following information:
<pre>
   TreeCache = TTree cache size in MBytes
   N leaves  = Number of leaves in the TTree
   ReadTotal = Total number of zipped bytes read
{'fraction_non_alphanumeric': 0.08729670820991449, 'fraction_numerical': 0.00894204437489521, 'mean_word_length': 3.9983240223463685, 'pattern_counts': {'":': 0, '<': 261, '<?xml version=': 0, '>': 284, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1518942', 'n_tokens_mistral': 5334, 'n_tokens_neox': 5117, 'n_words': 2357}