00001 #ifndef FWCore_Framework_Principal_h
00002 #define FWCore_Framework_Principal_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <map>
00021 #include <memory>
00022 #include <string>
00023 #include <vector>
00024
00025 #include "boost/shared_ptr.hpp"
00026 #include "FWCore/Framework/interface/Frameworkfwd.h"
00027 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
00028 #include "DataFormats/Provenance/interface/BranchID.h"
00029 #include "DataFormats/Provenance/interface/BranchMapper.h"
00030 #include "DataFormats/Provenance/interface/EventEntryInfo.h"
00031 #include "DataFormats/Common/interface/EDProductGetter.h"
00032 #include "DataFormats/Common/interface/OutputHandle.h"
00033 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00034 #include "DataFormats/Provenance/interface/ProductStatus.h"
00035 #include "FWCore/Framework/interface/Group.h"
00036 #include "FWCore/Framework/interface/NoDelayedReader.h"
00037
00038
00039 namespace edm {
00040 class Principal : public EDProductGetter {
00041 public:
00042 typedef std::map<BranchID, boost::shared_ptr<Group> > GroupCollection;
00043 typedef GroupCollection::const_iterator const_iterator;
00044 typedef ProcessHistory::const_iterator ProcessNameConstIterator;
00045 typedef boost::shared_ptr<const Group> SharedConstGroupPtr;
00046 typedef std::vector<BasicHandle> BasicHandleVec;
00047 typedef GroupCollection::size_type size_type;
00048
00049 typedef boost::shared_ptr<Group> SharedGroupPtr;
00050 typedef std::string ProcessName;
00051
00052 Principal(boost::shared_ptr<ProductRegistry const> reg,
00053 ProcessConfiguration const& pc,
00054 ProcessHistoryID const& hist = ProcessHistoryID(),
00055 boost::shared_ptr<BranchMapper> mapper = boost::shared_ptr<BranchMapper>(new BranchMapper),
00056 boost::shared_ptr<DelayedReader> rtrv = boost::shared_ptr<DelayedReader>(new NoDelayedReader));
00057
00058 virtual ~Principal();
00059
00060 EDProductGetter const* prodGetter() const {return this;}
00061
00062 template <typename T>
00063 OutputHandle<T> getForOutput(BranchID const& bid, bool getProd) const;
00064
00065 BasicHandle getBySelector(TypeID const& tid,
00066 SelectorBase const& s) const;
00067
00068 BasicHandle getByLabel(TypeID const& tid,
00069 std::string const& label,
00070 std::string const& productInstanceName) const;
00071
00072 BasicHandle getByLabel(TypeID const& tid,
00073 std::string const& label,
00074 std::string const& productInstanceName,
00075 std::string const& processName) const;
00076
00077 void getMany(TypeID const& tid,
00078 SelectorBase const&,
00079 BasicHandleVec& results) const;
00080
00081 BasicHandle getByType(TypeID const& tid) const;
00082
00083 void getManyByType(TypeID const& tid,
00084 BasicHandleVec& results) const;
00085
00086
00087
00088
00089
00090
00091
00092 size_t getMatchingSequence(TypeID const& typeID,
00093 SelectorBase const& selector,
00094 BasicHandleVec& results,
00095 bool stopIfProcessHasMatch) const;
00096
00097 void
00098 readImmediate() const;
00099
00100 ProcessHistory const& processHistory() const;
00101
00102 ProcessHistoryID const& processHistoryID() const {
00103 return processHistoryID_;
00104 }
00105
00106 ProcessConfiguration const& processConfiguration() const {return processConfiguration_;}
00107
00108 ProductRegistry const& productRegistry() const {return *preg_;}
00109
00110 boost::shared_ptr<DelayedReader> store() const {return store_;}
00111
00112 boost::shared_ptr<BranchMapper> branchMapperPtr() const {return branchMapperPtr_;}
00113
00114
00115
00116 void addToProcessHistory() const;
00117
00118
00119 void recombine(Principal & other, std::vector<BranchID> const& bids);
00120
00121 size_t size() const { return groups_.size(); }
00122
00123 const_iterator begin() const {return groups_.begin();}
00124 const_iterator end() const {return groups_.end();}
00125
00126 protected:
00127
00128
00129
00130 void addGroup_(std::auto_ptr<Group> g);
00131 Group* getExistingGroup(Group const& g);
00132 void replaceGroup(std::auto_ptr<Group> g);
00133
00134 SharedConstGroupPtr const getGroup(BranchID const& oid,
00135 bool resolveProd,
00136 bool resolveProv,
00137 bool fillOnDemand) const;
00138
00139 private:
00140 virtual EDProduct const* getIt(ProductID const&) const;
00141
00142 virtual void addOrReplaceGroup(std::auto_ptr<Group> g) = 0;
00143
00144 virtual void resolveProvenance(Group const& g) const = 0;
00145
00146 virtual bool unscheduledFill(std::string const& moduleLabel) const = 0;
00147
00148
00149 typedef std::map<std::string, std::vector<BranchID> > ProcessLookup;
00150 typedef std::map<std::string, ProcessLookup> TypeLookup;
00151
00152 size_t findGroups(TypeID const& typeID,
00153 TypeLookup const& typeLookup,
00154 SelectorBase const& selector,
00155 BasicHandleVec& results,
00156 bool stopIfProcessHasMatch) const;
00157
00158 void findGroupsForProcess(std::string const& processName,
00159 ProcessLookup const& processLookup,
00160 SelectorBase const& selector,
00161 BasicHandleVec& results) const;
00162
00163
00164
00165
00166
00167
00168 void resolveProduct(Group const& g, bool fillOnDemand) const;
00169
00170 mutable ProcessHistoryID processHistoryID_;
00171
00172 boost::shared_ptr<ProcessHistory> processHistoryPtr_;
00173
00174 ProcessConfiguration const& processConfiguration_;
00175
00176 mutable bool processHistoryModified_;
00177
00178
00179 GroupCollection groups_;
00180
00181
00182
00183 boost::shared_ptr<ProductRegistry const> preg_;
00184
00185
00186
00187 boost::shared_ptr<BranchMapper> branchMapperPtr_;
00188
00189
00190
00191 boost::shared_ptr<DelayedReader> store_;
00192 };
00193
00194 template <typename T>
00195 OutputHandle<T>
00196 Principal::getForOutput(BranchID const& bid, bool getProd) const {
00197 SharedConstGroupPtr const& g = getGroup(bid, getProd, true, false);
00198 if (g.get() == 0) {
00199 return OutputHandle<T>();
00200 }
00201 if (getProd && (g->product() == 0 || !g->product()->isPresent()) &&
00202 g->productDescription().present() &&
00203 g->productDescription().branchType() == InEvent &&
00204 productstatus::present(g->entryInfoPtr()->productStatus())) {
00205 throw edm::Exception(edm::errors::LogicError, "Principal::getForOutput\n")
00206 << "A product with a status of 'present' is not actually present.\n"
00207 << "The branch name is " << g->productDescription().branchName() << "\n"
00208 << "Contact a framework developer.\n";
00209 }
00210 if (!g->product() && !g->entryInfoPtr()) {
00211 return OutputHandle<T>();
00212 }
00213 return OutputHandle<T>(g->product(), &g->productDescription(), g->entryInfoPtr());
00214 }
00215
00216 }
00217 #endif