Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-14 09:22:55

0001 // @(#)root/tree:$Id$
0002 // Author: Brian Bockelman, 2017-06-13
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TTreeReaderValueFast
0013 #define ROOT_TTreeReaderValueFast
0014 
0015 
0016 ////////////////////////////////////////////////////////////////////////////
0017 //                                                                        //
0018 // TTreeReaderValueFast                                                   //
0019 //                                                                        //
0020 // A simple interface for reading data from trees or chains.              //
0021 //                                                                        //
0022 //                                                                        //
0023 ////////////////////////////////////////////////////////////////////////////
0024 
0025 #include "ROOT/TTreeReaderFast.hxx"
0026 
0027 #include "TBranch.h"
0028 #include "TBufferFile.h"
0029 
0030 #include <type_traits>
0031 
0032 class TBranch;
0033 
0034 namespace ROOT {
0035 namespace Experimental {
0036 namespace Internal {
0037 
0038 /* All the common code shared by the fast reader templates.
0039  */
0040 class TTreeReaderValueFastBase {
0041    public:
0042       TTreeReaderValueFastBase(const TTreeReaderValueFastBase&) = delete;
0043 
0044       ROOT::Internal::TTreeReaderValueBase::ESetupStatus GetSetupStatus() const { return fSetupStatus; }
0045       virtual ROOT::Internal::TTreeReaderValueBase::EReadStatus GetReadStatus() const { return fReadStatus; }
0046 
0047       //////////////////////////////////////////////////////////////////////////////
0048       /// Construct a tree value reader and register it with the reader object.
0049       TTreeReaderValueFastBase(TTreeReaderFast* reader, const std::string &branchName) :
0050          fBranchName(branchName),
0051          fLeafName(branchName), // TODO: only support single-leaf branches for now.
0052          fTreeReader(reader),
0053          fBuffer(TBuffer::kWrite, 32*1024),
0054          fEvtIndex(reader->GetIndexRef())
0055       {
0056          if (fTreeReader) fTreeReader->RegisterValueReader(this);
0057       }
0058 
0059       Int_t GetEvents(Long64_t eventNum) {
0060           //printf("Getting events starting at %lld.  Current remaining is %d events with base %lld.\n", eventNum, fRemaining, fEventBase);
0061           if (fEventBase >= 0 && (fRemaining + fEventBase > eventNum)) {
0062              Int_t adjust = (eventNum - fEventBase);
0063              if (R__unlikely(Adjust(adjust) < 0)) {
0064                 //printf("Failed to adjust offset to mid-buffer.\n");
0065                 return -1;
0066              }
0067              fRemaining -= adjust;
0068           } else {
0069              if (!fBranch) {
0070                 fReadStatus = ROOT::Internal::TTreeReaderValueBase::kReadError;
0071                 // printf("Failed to retrieve branch.\n");
0072                 return -1;
0073              }
0074              fRemaining = fBranch->GetBulkRead().GetEntriesSerialized(eventNum, fBuffer);
0075              if (R__unlikely(fRemaining < 0)) {
0076                 fReadStatus = ROOT::Internal::TTreeReaderValueBase::kReadError;
0077                 //printf("Failed to retrieve entries from the branch.\n");
0078                 return -1;
0079              }
0080           }
0081           fEventBase = eventNum;
0082           //printf("After getting events, the base is %lld with %d remaining.\n", fEventBase, fRemaining);
0083           fReadStatus = ROOT::Internal::TTreeReaderValueBase::kReadSuccess;
0084           return fRemaining;
0085       }
0086 
0087       virtual const char *GetTypeName() {return "{UNDETERMINED}";}
0088 
0089 
0090    protected:
0091 
0092       // Adjust the current buffer offset forward N events.
0093       virtual Int_t Adjust(Int_t eventCount) {
0094          Int_t bufOffset = fBuffer.Length();
0095          fBuffer.SetBufferOffset(bufOffset + eventCount*GetSize());
0096          return 0;
0097       }
0098       virtual UInt_t GetSize() = 0;
0099 
0100       void MarkTreeReaderUnavailable() {
0101          fTreeReader = nullptr;
0102       }
0103 
0104       // Create the linkage between the TTreeReader's current tree and this ReaderValue
0105       // object.  After CreateProxy() is invoked, if fSetupStatus doesn't indicate an
0106       // error, then we are pointing toward a valid TLeaf in the current tree
0107       void CreateProxy();
0108 
0109       virtual ~TTreeReaderValueFastBase();
0110 
0111       // Returns the name of the branch type; will be used when the TBranch version to
0112       // detect between the compile-time and runtime type names.
0113       virtual const char *BranchTypeName() = 0;
0114 
0115       std::string  fBranchName;          // Name of the branch we should read from.
0116       std::string  fLeafName;            // The branch's leaf we should read from.  NOTE: currently only support single-leaf branches.
0117       TTreeReaderFast *fTreeReader{nullptr}; // Reader we belong to
0118       TBranch *    fBranch{nullptr};     // Actual branch object we are reading.
0119       TLeaf *      fLeaf{nullptr};       // Actual leaf we are reading.
0120       TBufferFile  fBuffer;              // Buffer object holding the current events.
0121       Int_t        fRemaining{0};        // Number of events remaining in the buffer.
0122       Int_t       &fEvtIndex;            // Current event index.
0123       Long64_t     fLastChainOffset{-1}; // Current chain in the TTree we are pointed at.
0124       Long64_t     fEventBase{-1};       // Event number of the current buffer position.
0125 
0126       ROOT::Internal::TTreeReaderValueBase::ESetupStatus fSetupStatus{ROOT::Internal::TTreeReaderValueBase::kSetupNotSetup}; // setup status of this data access
0127       ROOT::Internal::TTreeReaderValueBase::EReadStatus  fReadStatus{ROOT::Internal::TTreeReaderValueBase::kReadNothingYet}; // read status of this data access
0128 
0129       friend class ROOT::Experimental::TTreeReaderFast;
0130 };
0131 
0132 }  // Internal
0133 
0134 template <typename T>
0135 class TTreeReaderValueFast final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
0136 
0137    public:
0138        TTreeReaderValueFast(TTreeReaderFast* reader, const std::string &branchname) : ROOT::Experimental::Internal::TTreeReaderValueFastBase(reader, branchname) {}
0139 
0140       T* Get() {
0141          return Deserialize(reinterpret_cast<char *>(reinterpret_cast<T*>(fBuffer.GetCurrent()) + fEvtIndex));
0142       }
0143       T* operator->() { return Get(); }
0144       T& operator*() { return *Get(); }
0145 
0146    protected:
0147       T* Deserialize(char *) {return nullptr;}
0148 
0149       const char *GetTypeName() override {return "{INCOMPLETE}";}
0150       UInt_t GetSize() override {return sizeof(T);}
0151 };
0152 
0153 template<>
0154 class TTreeReaderValueFast<float> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
0155 
0156    public:
0157 
0158       TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
0159             TTreeReaderValueFastBase(&tr, branchname) {}
0160 
0161       float* Get() {
0162          return Deserialize(reinterpret_cast<char *>(reinterpret_cast<float*>(fBuffer.GetCurrent()) + fEvtIndex));
0163       }
0164       float* operator->() { return Get(); }
0165       float& operator*() { return *Get(); }
0166 
0167    protected:
0168       const char *GetTypeName() override {return "float";}
0169       const char *BranchTypeName() override {return "float";}
0170       UInt_t GetSize() override {return sizeof(float);}
0171       float * Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
0172 
0173       float fTmp;
0174 };
0175 
0176 template <>
0177 class TTreeReaderValueFast<double> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
0178 
0179    public:
0180 
0181       TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
0182             TTreeReaderValueFastBase(&tr, branchname) {}
0183 
0184       // TODO: why isn't template specialization working here?
0185       double* Get() {
0186          //printf("Double: Attempting to deserialize buffer %p from index %d.\n", fBuffer.GetCurrent(), fEvtIndex);
0187          return Deserialize(reinterpret_cast<char *>(reinterpret_cast<double*>(fBuffer.GetCurrent()) + fEvtIndex));
0188       }
0189       double* operator->() { return Get(); }
0190       double& operator*() { return *Get(); }
0191 
0192    protected:
0193       const char *GetTypeName() override {return "double";}
0194       const char *BranchTypeName() override {return "double";}
0195       UInt_t GetSize() override {return sizeof(double);}
0196       double* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
0197 
0198       double fTmp;
0199 };
0200 
0201 template <>
0202 class TTreeReaderValueFast<Int_t> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
0203 
0204    public:
0205 
0206       TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
0207             TTreeReaderValueFastBase(&tr, branchname) {}
0208 
0209       Int_t* Get() {
0210          return Deserialize(reinterpret_cast<char *>(reinterpret_cast<Int_t*>(fBuffer.GetCurrent()) + fEvtIndex));
0211       }
0212       Int_t* operator->() { return Get(); }
0213       Int_t& operator*() { return *Get(); }
0214 
0215    protected:
0216       const char *GetTypeName() override {return "integer";}
0217       const char *BranchTypeName() override {return "integer";}
0218       UInt_t GetSize() override {return sizeof(Int_t);}
0219       Int_t* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
0220 
0221       Int_t fTmp;
0222 };
0223 
0224 template <>
0225 class TTreeReaderValueFast<UInt_t> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
0226 
0227    public:
0228 
0229       TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
0230             TTreeReaderValueFastBase(&tr, branchname) {}
0231 
0232       UInt_t* Get() {
0233          return Deserialize(reinterpret_cast<char *>(reinterpret_cast<UInt_t*>(fBuffer.GetCurrent()) + fEvtIndex));
0234       }
0235       UInt_t* operator->() { return Get(); }
0236       UInt_t& operator*() { return *Get(); }
0237 
0238    protected:
0239       const char *GetTypeName() override {return "unsigned integer";}
0240       const char *BranchTypeName() override {return "unsigned integer";}
0241       UInt_t GetSize() override {return sizeof(UInt_t);}
0242       UInt_t* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
0243 
0244       UInt_t fTmp;
0245 };
0246 
0247 template <>
0248 class TTreeReaderValueFast<bool> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
0249 
0250    public:
0251 
0252       TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
0253             TTreeReaderValueFastBase(&tr, branchname) {}
0254 
0255       bool* Get() {
0256          return Deserialize(reinterpret_cast<char *>(reinterpret_cast<bool*>(fBuffer.GetCurrent()) + fEvtIndex));
0257       }
0258       bool* operator->() { return Get(); }
0259       bool& operator*() { return *Get(); }
0260 
0261    protected:
0262       const char *GetTypeName() override {return "unsigned integer";}
0263       const char *BranchTypeName() override {return "unsigned integer";}
0264       UInt_t GetSize() override {return sizeof(bool);}
0265       bool* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
0266 
0267       bool fTmp;
0268 };
0269 
0270 }  // Experimental
0271 }  // ROOT
0272 
0273 #endif // ROOT_TTreeReaderValueFast