CMS 3D CMS Logo

Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Private Attributes

fwlite::DataGetterHelper Class Reference

#include <DataGetterHelper.h>

List of all members.

Public Member Functions

 DataGetterHelper (TTree *tree, boost::shared_ptr< HistoryGetterBase > historyGetter, boost::shared_ptr< BranchMapReader > branchMap=boost::shared_ptr< BranchMapReader >(), boost::shared_ptr< edm::EDProductGetter > getter=boost::shared_ptr< edm::EDProductGetter >(), bool useCache=false)
virtual const std::string getBranchNameFor (const std::type_info &, const char *, const char *, const char *) const
virtual bool getByLabel (const std::type_info &, const char *, const char *, const char *, void *, Long_t) const
edm::EDProduct const * getByProductID (edm::ProductID const &, Long_t) const
edm::EDProductGettergetter ()
void setGetter (boost::shared_ptr< edm::EDProductGetter > getter)
virtual ~DataGetterHelper ()

Static Public Member Functions

static void throwProductNotFoundException (const std::type_info &, const char *, const char *, const char *)

Private Types

typedef std::map
< internal::DataKey,
boost::shared_ptr
< internal::Data > > 
KeyToDataMap

Private Member Functions

 DataGetterHelper (const DataGetterHelper &)
void getBranchData (edm::EDProductGetter *, Long64_t, internal::Data &) const
internal::DatagetBranchDataFor (const std::type_info &, const char *, const char *, const char *) const
const edm::ProcessHistoryhistory () const
const DataGetterHelperoperator= (const DataGetterHelper &)

Private Attributes

boost::shared_ptr
< BranchMapReader
branchMap_
KeyToDataMap data_
boost::shared_ptr
< edm::EDProductGetter
getter_
boost::shared_ptr
< fwlite::HistoryGetterBase
historyGetter_
std::map< edm::ProductID,
boost::shared_ptr
< internal::Data > > 
idToData_
std::vector< const char * > labels_
std::auto_ptr< TTreeCache > tcache_
bool tcTrained_
TTree * tree_

Detailed Description

Definition at line 42 of file DataGetterHelper.h.


Member Typedef Documentation

typedef std::map<internal::DataKey, boost::shared_ptr<internal::Data> > fwlite::DataGetterHelper::KeyToDataMap [private]

Definition at line 87 of file DataGetterHelper.h.


Constructor & Destructor Documentation

DataGetterHelper::DataGetterHelper ( TTree *  tree,
boost::shared_ptr< HistoryGetterBase historyGetter,
boost::shared_ptr< BranchMapReader branchMap = boost::shared_ptr<BranchMapReader>(),
boost::shared_ptr< edm::EDProductGetter getter = boost::shared_ptr<edm::EDProductGetter>(),
bool  useCache = false 
)

Definition at line 61 of file DataGetterHelper.cc.

References branchMap_, Exception, tcache_, diffTreeTool::tree, tree_, and TTCACHE_SIZE.

                                                     :
        branchMap_(branchMap),
        historyGetter_(historyGetter),
        getter_(getter),
        tcache_(0),
        tcTrained_(false)
    {
        if(0==tree) {
            throw cms::Exception("NoTree")<<"The TTree pointer passed to the constructor was null";
        }
        tree_ = tree;
        if (useCache) {
            tree_->SetCacheSize(TTCACHE_SIZE);
            TFile* iFile(branchMap_->getFile());
            tcache_.reset(dynamic_cast<TTreeCache*>(iFile->GetCacheRead()));
            iFile->SetCacheRead(0);
            //std::cout << "In const " << iFile << " " << tcache_ << " " << iFile->GetCacheRead() << std::endl;
        }
    }
DataGetterHelper::~DataGetterHelper ( ) [virtual]

Definition at line 90 of file DataGetterHelper.cc.

{    }
fwlite::DataGetterHelper::DataGetterHelper ( const DataGetterHelper ) [private]

Member Function Documentation

void DataGetterHelper::getBranchData ( edm::EDProductGetter iGetter,
Long64_t  index,
internal::Data iData 
) const [private]

Definition at line 129 of file DataGetterHelper.cc.

References fwlite::internal::Data::branch_, branchMap_, getHLTprescales::index, fwlite::internal::Data::lastProduct_, VarParsing::obj, fwlite::internal::Data::obj_, L1TEmulatorMonitor_cff::p, fwlite::internal::Data::pObj_, fwlite::internal::Data::pProd_, tcache_, tcTrained_, and tree_.

Referenced by getByLabel(), and getByProductID().

    {
        GetterOperate op(iGetter);

        //WORK AROUND FOR ROOT!!
        //Create a new instance so that we can clear any cache the object uses
        //this slows the code down
        Reflex::Object obj = iData.obj_;
        iData.obj_ = iData.obj_.TypeOf().Construct();
        iData.pObj_ = iData.obj_.Address();
        iData.branch_->SetAddress(&(iData.pObj_));
        //If a REF to this was requested in the past, we might as well do the work now
        if(0!=iData.pProd_) {
            //The type is the same so the offset will be the same
            void* p = iData.pProd_;
            iData.pProd_ = reinterpret_cast<edm::EDProduct*>(static_cast<char*>(iData.obj_.Address())+(static_cast<char*>(p)-static_cast<char*>(obj.Address())));
        }
        obj.Destruct();
        //END OF WORK AROUND

        if (0 == tcache_.get()) {
            iData.branch_->GetEntry(index);
        } else {
            if (!tcTrained_) {
                tcache_->SetLearnEntries(100);
                tcache_->SetEntryRange(0, tree_->GetEntries());
                tcTrained_ = true;
            }
            withTCache tcguard(branchMap_->getFile(), tcache_.get());
            tree_->LoadTree(index);
            iData.branch_->GetEntry(index);
       }
       iData.lastProduct_=index;
    }
internal::Data & DataGetterHelper::getBranchDataFor ( const std::type_info &  iInfo,
const char *  iModuleLabel,
const char *  iProductInstanceLabel,
const char *  iProcessLabel 
) const [private]

Definition at line 168 of file DataGetterHelper.cc.

References fwlite::branchNotFound, data_, Exception, fwlite::findBranch(), edm::TypeID::friendlyClassName(), h, history(), fwlite::internal::DataKey::kEmpty(), combine::key, labels_, fwlite::internal::DataKey::module(), mergeVDriftHistosByStation::name, VarParsing::obj, fwlite::internal::DataKey::process(), fwlite::internal::DataKey::product(), edm::ProcessHistory::rbegin(), edm::ProcessHistory::rend(), and tree_.

Referenced by getBranchNameFor(), and getByLabel().

    {
        edm::TypeID type(iInfo);
        internal::DataKey key(type, iModuleLabel, iProductInstanceLabel, iProcessLabel);

        boost::shared_ptr<internal::Data> theData;
        DataMap::iterator itFind = data_.find(key);
        if(itFind == data_.end() ) {
            //see if such a branch actually exists
            const std::string sep("_");
            //CHANGE: If this fails, need to lookup the the friendly name which was used to write the file
            std::string name(type.friendlyClassName());
            name +=sep+std::string(key.module());
            name +=sep+std::string(key.product())+sep;

            //if we have to lookup the process label, remember it and register the product again
            std::string foundProcessLabel;
            TBranch* branch = 0;

            if (0==iProcessLabel || iProcessLabel==key.kEmpty() ||
                strlen(iProcessLabel)==0) {
                const std::string* lastLabel=0;
                //have to search in reverse order since newest are on the bottom
                const edm::ProcessHistory& h = DataGetterHelper::history();
                for (edm::ProcessHistory::const_reverse_iterator iproc = h.rbegin(), eproc = h.rend();
                    iproc != eproc;
                    ++iproc) {

                    lastLabel = &(iproc->processName());
                    branch=findBranch(tree_,name,iproc->processName());
                    if(0!=branch) {
                    break;
                    }
                }
                if(0==branch) {
                    return branchNotFound;
                }
                //do we already have this one?
                if(0!=lastLabel) {
                    internal::DataKey fullKey(type,iModuleLabel,iProductInstanceLabel,lastLabel->c_str());
                    itFind = data_.find(fullKey);
                    if(itFind != data_.end()) {
                        //remember the data we've found
                        theData = itFind->second;
                    } else {
                        //only set this if we don't already have it since it this string is not empty we re-register
                        foundProcessLabel = *lastLabel;
                    }
                }
            } else {
                //we have all the pieces
                branch = findBranch(tree_,name,key.process());
                if(0==branch){
                    return branchNotFound;
                }
            }

            //cache the info
            char* newModule = new char[strlen(iModuleLabel)+1];
            std::strcpy(newModule,iModuleLabel);
            labels_.push_back(newModule);

            char* newProduct = const_cast<char*>(key.product());
            if(newProduct[0] != 0) {
                newProduct = new char[strlen(newProduct)+1];
                std::strcpy(newProduct,key.product());
                labels_.push_back(newProduct);
            }
            char* newProcess = const_cast<char*>(key.process());
            if(newProcess[0]!=0) {
                newProcess = new char[strlen(newProcess)+1];
                std::strcpy(newProcess,key.process());
                labels_.push_back(newProcess);
            }
            internal::DataKey newKey(edm::TypeID(iInfo),newModule,newProduct,newProcess);

            if(0 == theData.get() ) {
                //We do not already have this data as another key

                //Use Reflex to create an instance of the object to be used as a buffer
                Reflex::Type rType = Reflex::Type::ByTypeInfo(iInfo);
                if(rType == Reflex::Type()) {
                    throw cms::Exception("UnknownType")<<"No Reflex dictionary exists for type "<<iInfo.name();
                }
                Reflex::Object obj = rType.Construct();

                if(obj.Address() == 0) {
                    throw cms::Exception("ConstructionFailed")<<"failed to construct an instance of "<<rType.Name();
                }
                boost::shared_ptr<internal::Data> newData(new internal::Data() );
                newData->branch_ = branch;
                newData->obj_ = obj;
                newData->lastProduct_=-1;
                newData->pObj_ = obj.Address();
                newData->pProd_ = 0;
                branch->SetAddress(&(newData->pObj_));
                theData = newData;
            }
            itFind = data_.insert(std::make_pair(newKey, theData)).first;

            if(foundProcessLabel.size()) {
                //also remember it with the process label
                newProcess = new char[foundProcessLabel.size()+1];
                std::strcpy(newProcess,foundProcessLabel.c_str());
                labels_.push_back(newProcess);
                internal::DataKey newKey(edm::TypeID(iInfo),newModule,newProduct,newProcess);

                data_.insert(std::make_pair(newKey,theData));
            }
        }
        return *(itFind->second);
    }
const std::string DataGetterHelper::getBranchNameFor ( const std::type_info &  iInfo,
const char *  iModuleLabel,
const char *  iProductInstanceLabel,
const char *  iProcessLabel 
) const [virtual]

Definition at line 285 of file DataGetterHelper.cc.

References fwlite::internal::Data::branch_, and getBranchDataFor().

Referenced by fwlite::LuminosityBlock::getBranchNameFor(), fwlite::Run::getBranchNameFor(), and fwlite::Event::getBranchNameFor().

    {
        internal::Data& theData =
            DataGetterHelper::getBranchDataFor(iInfo, iModuleLabel, iProductInstanceLabel, iProcessLabel);

        if (0 != theData.branch_) {
            return std::string(theData.branch_->GetName());
        }
        return std::string("");
    }
bool DataGetterHelper::getByLabel ( const std::type_info &  iInfo,
const char *  iModuleLabel,
const char *  iProductInstanceLabel,
const char *  iProcessLabel,
void *  oData,
Long_t  index 
) const [virtual]

Definition at line 300 of file DataGetterHelper.cc.

References fwlite::internal::Data::branch_, getBranchData(), getBranchDataFor(), getter_, getHLTprescales::index, fwlite::internal::Data::lastProduct_, and fwlite::internal::Data::obj_.

Referenced by fwlite::Run::getByLabel(), fwlite::Event::getByLabel(), fwlite::LuminosityBlock::getByLabel(), and getByProductID().

    {
        // Maintain atEnd() check in parent classes
        void** pOData = reinterpret_cast<void**>(oData);
        *pOData = 0;

        internal::Data& theData =
            DataGetterHelper::getBranchDataFor(iInfo, iModuleLabel, iProductInstanceLabel, iProcessLabel);

        if (0 != theData.branch_) {
            if(index != theData.lastProduct_) {
                //haven't gotten the data for this event
                getBranchData(getter_.get(), index, theData);
            }
            *pOData = theData.obj_.Address();
        }

        if ( 0 == *pOData ) return false;
        else return true;
    }
edm::EDProduct const * DataGetterHelper::getByProductID ( edm::ProductID const &  iID,
Long_t  index 
) const

Definition at line 327 of file DataGetterHelper.cc.

References edm::BranchDescription::branchID(), branchMap_, data_, Exception, edm::BranchDescription::fullClassName(), getBranchData(), getByLabel(), getter_, idToData_, getHLTprescales::index, gen::k, edm::BranchDescription::moduleLabel(), edm::BranchDescription::processName(), edm::BranchDescription::productInstanceName(), and edm::wrappedClassName().

Referenced by fwlite::Event::getByProductID(), fwlite::Run::getByProductID(), and fwlite::LuminosityBlock::getByProductID().

    {
        std::map<edm::ProductID,boost::shared_ptr<internal::Data> >::const_iterator itFound = idToData_.find(iID);
        if(itFound == idToData_.end() ) {
            edm::BranchDescription bDesc = branchMap_->productToBranch(iID);

            if (!bDesc.branchID().isValid()) {
                return 0;
            }

            //Calculate the key from the branch description
            Reflex::Type type( Reflex::Type::ByName(edm::wrappedClassName(bDesc.fullClassName())));
            assert( Reflex::Type() != type) ;

            //Only the product instance label may be empty
            const char* pIL = bDesc.productInstanceName().c_str();
            if(pIL[0] == 0) {
                pIL = 0;
            }
            internal::DataKey k(edm::TypeID(type.TypeInfo()),
                                bDesc.moduleLabel().c_str(),
                                pIL,
                                bDesc.processName().c_str());

            //has this already been gotten?
            KeyToDataMap::iterator itData = data_.find(k);
            if(data_.end() == itData) {
                //ask for the data
                void* dummy = 0;
                getByLabel(type.TypeInfo(),
                            k.module(),
                            k.product(),
                            k.process(),
                            &dummy, index);
                if (0 == dummy) {
                    return 0;
                }
                itData = data_.find(k);
                assert(itData != data_.end());
                //assert(0!=dummy);
                assert(dummy == itData->second->obj_.Address());
            }
            itFound = idToData_.insert(std::make_pair(iID,itData->second)).first;
        }
        if(index != itFound->second->lastProduct_) {
            //haven't gotten the data for this event
            getBranchData(getter_.get(), index, *(itFound->second));
        }
        if(0==itFound->second->pProd_) {
            //need to convert pointer to proper type
            static Reflex::Type sEDProd( Reflex::Type::ByTypeInfo(typeid(edm::EDProduct)));
            //assert( sEDProd != Reflex::Type() );
            Reflex::Object edProdObj = itFound->second->obj_.CastObject( sEDProd );

            itFound->second->pProd_ = reinterpret_cast<edm::EDProduct*>(edProdObj.Address());

            if(0==itFound->second->pProd_) {
                cms::Exception("FailedConversion")
                    <<"failed to convert a '"<<itFound->second->obj_.TypeOf().Name()<<"' to a edm::EDProduct";
            }
        }
        return itFound->second->pProd_;
    }
edm::EDProductGetter* fwlite::DataGetterHelper::getter ( ) [inline]

Definition at line 73 of file DataGetterHelper.h.

References getter_.

Referenced by fwlite::Event::draw(), fwlite::Event::scan(), and setGetter().

                                         {
               return getter_.get();
            }
const edm::ProcessHistory & DataGetterHelper::history ( ) const [private]

Definition at line 392 of file DataGetterHelper.cc.

References historyGetter_.

Referenced by getBranchDataFor().

                                                             {
        return historyGetter_->history();
    }
const DataGetterHelper& fwlite::DataGetterHelper::operator= ( const DataGetterHelper ) [private]
void fwlite::DataGetterHelper::setGetter ( boost::shared_ptr< edm::EDProductGetter getter) [inline]

Definition at line 69 of file DataGetterHelper.h.

References getter(), and getter_.

Referenced by fwlite::Event::setGetter().

                                                                         {
                getter_ = getter;
            }
void DataGetterHelper::throwProductNotFoundException ( const std::type_info &  iType,
const char *  iModule,
const char *  iProduct,
const char *  iProcess 
) [static]

Definition at line 401 of file DataGetterHelper.cc.

References edm::TypeID::className(), Exception, and edm::errors::ProductNotFound.

    {
        edm::TypeID type(iType);
        throw edm::Exception(edm::errors::ProductNotFound)<<"A branch was found for \n  type ='"<<type.className()<<"'\n  module='"<<iModule
            <<"'\n  productInstance='"<<((0!=iProduct)?iProduct:"")<<"'\n  process='"<<((0!=iProcess)?iProcess:"")<<"'\n"
            "but no data is available for this Lumi";
    }

Member Data Documentation

boost::shared_ptr<BranchMapReader> fwlite::DataGetterHelper::branchMap_ [mutable, private]

Definition at line 86 of file DataGetterHelper.h.

Referenced by DataGetterHelper(), getBranchData(), and getByProductID().

Definition at line 88 of file DataGetterHelper.h.

Referenced by getBranchDataFor(), and getByProductID().

Definition at line 94 of file DataGetterHelper.h.

Referenced by getByLabel(), getByProductID(), getter(), and setGetter().

Definition at line 93 of file DataGetterHelper.h.

Referenced by history().

std::map<edm::ProductID,boost::shared_ptr<internal::Data> > fwlite::DataGetterHelper::idToData_ [mutable, private]

Definition at line 92 of file DataGetterHelper.h.

Referenced by getByProductID().

std::vector<const char*> fwlite::DataGetterHelper::labels_ [mutable, private]

Definition at line 89 of file DataGetterHelper.h.

Referenced by getBranchDataFor().

std::auto_ptr<TTreeCache> fwlite::DataGetterHelper::tcache_ [mutable, private]

Definition at line 95 of file DataGetterHelper.h.

Referenced by DataGetterHelper(), and getBranchData().

bool fwlite::DataGetterHelper::tcTrained_ [mutable, private]

Definition at line 96 of file DataGetterHelper.h.

Referenced by getBranchData().

Definition at line 85 of file DataGetterHelper.h.

Referenced by DataGetterHelper(), getBranchData(), and getBranchDataFor().