00001 #ifndef COLLECTIONBUILDER_H_ 00002 #define COLLECTIONBUILDER_H_ 00003 00004 #include <initializer_list> 00005 #include <vector> 00006 00007 #include <boost/iterator/iterator_facade.hpp> 00008 #include <TLorentzVector.h> 00009 #include <TTreeReader.h> 00010 00011 #include <EventCache.h> 00012 00013 00036 class CollectionBuilderBase { 00037 public: 00038 using Momentum = TLorentzVector; 00039 00041 class MomentumIt : public boost::iterator_facade< 00042 MomentumIt, Momentum const, boost::random_access_traversal_tag, 00043 Momentum const &, int> { 00044 public: 00045 MomentumIt() = default; 00046 MomentumIt(CollectionBuilderBase const &builder, size_t index); 00047 00048 private: 00049 friend class boost::iterator_core_access; 00050 00051 void advance(difference_type n); 00052 void decrement(); 00053 reference dereference() const; 00054 difference_type distance_to(MomentumIt const &other) const; 00055 bool equal(MomentumIt const &other) const; 00056 void increment(); 00057 00058 CollectionBuilderBase const &builder_; 00059 size_t index_; 00060 }; 00061 00070 class MomentaWrapper { 00071 public: 00072 MomentaWrapper(CollectionBuilderBase const &builder); 00073 00074 Momentum const &at(size_t index) const; 00075 MomentumIt begin() const; 00076 MomentumIt end() const; 00077 Momentum const &operator[](size_t index) const; 00078 size_t size() const; 00079 00081 bool HasOverlap(Momentum const &p4, double maxDR) const; 00082 00083 private: 00084 CollectionBuilderBase const &builder_; 00085 }; 00086 00093 CollectionBuilderBase(TTreeReader &reader); 00094 00104 void EnableCleaning( 00105 std::initializer_list<CollectionBuilderBase const *> builders); 00106 00108 MomentaWrapper GetMomenta() const; 00109 00115 Momentum const &GetSumMomentumShift() const; 00116 00123 bool IsDuplicate(Momentum const &p4, double maxDR) const; 00124 00125 protected: 00138 void AddMomentumShift(Momentum const &uncorrP4, Momentum const &corrP4) const; 00139 00149 void Update() const; 00150 00151 private: 00158 virtual void Build() const = 0; 00159 00161 virtual Momentum const &GetMomentum(size_t i) const = 0; 00162 00164 virtual size_t GetNumMomenta() const = 0; 00165 00167 EventCache cache_; 00168 00173 std::vector<CollectionBuilderBase const *> prioritizedBuilders_; 00174 00179 mutable Momentum sumP4Shift_; 00180 }; 00181 00182 00183 inline CollectionBuilderBase::MomentumIt::MomentumIt( 00184 CollectionBuilderBase const &builder, size_t index) 00185 : builder_{builder}, index_{index} {} 00186 00187 00188 inline void CollectionBuilderBase::MomentumIt::advance(difference_type n) { 00189 index_ += n; 00190 } 00191 00192 00193 inline void CollectionBuilderBase::MomentumIt::decrement() { 00194 --index_; 00195 } 00196 00197 00198 inline CollectionBuilderBase::MomentumIt::reference 00199 CollectionBuilderBase::MomentumIt::dereference() const { 00200 return builder_.GetMomentum(index_); 00201 } 00202 00203 00204 inline CollectionBuilderBase::MomentumIt::difference_type 00205 CollectionBuilderBase::MomentumIt::distance_to(MomentumIt const &other) const { 00206 return int(other.index_) - int(index_); 00207 } 00208 00209 00210 inline bool CollectionBuilderBase::MomentumIt::equal( 00211 MomentumIt const &other) const { 00212 return &builder_ == &other.builder_ and index_ == other.index_; 00213 } 00214 00215 00216 inline void CollectionBuilderBase::MomentumIt::increment() { 00217 ++index_; 00218 } 00219 00220 00221 inline CollectionBuilderBase::MomentaWrapper::MomentaWrapper( 00222 CollectionBuilderBase const &builder) 00223 : builder_{builder} {} 00224 00225 00226 inline CollectionBuilderBase::Momentum const & 00227 CollectionBuilderBase::MomentaWrapper::at(size_t index) const { 00228 return builder_.GetMomentum(index); 00229 } 00230 00231 00232 inline CollectionBuilderBase::MomentumIt 00233 CollectionBuilderBase::MomentaWrapper::begin() const { 00234 return {builder_, 0}; 00235 } 00236 00237 00238 inline CollectionBuilderBase::MomentumIt 00239 CollectionBuilderBase::MomentaWrapper::end() const { 00240 return {builder_, builder_.GetNumMomenta()}; 00241 } 00242 00243 00244 inline CollectionBuilderBase::Momentum const & 00245 CollectionBuilderBase::MomentaWrapper::operator[](size_t index) const { 00246 return builder_.GetMomentum(index); 00247 } 00248 00249 00250 inline size_t CollectionBuilderBase::MomentaWrapper::size() const { 00251 return builder_.GetNumMomenta(); 00252 } 00253 00254 00255 inline CollectionBuilderBase::CollectionBuilderBase(TTreeReader &reader) 00256 : cache_{reader} {} 00257 00258 00259 inline CollectionBuilderBase::MomentaWrapper 00260 CollectionBuilderBase::GetMomenta() const { 00261 return {*this}; 00262 } 00263 00264 00265 inline CollectionBuilderBase::Momentum const & 00266 CollectionBuilderBase::GetSumMomentumShift() const { 00267 Update(); 00268 return sumP4Shift_; 00269 } 00270 00271 00272 inline void CollectionBuilderBase::AddMomentumShift( 00273 Momentum const &uncorrP4, Momentum const &corrP4) const { 00274 sumP4Shift_ += (corrP4 - uncorrP4); 00275 } 00276 00277 00278 inline void CollectionBuilderBase::Update() const { 00279 if (cache_.IsUpdated()) { 00280 sumP4Shift_ = Momentum{}; 00281 Build(); 00282 } 00283 } 00284 00285 00295 template <typename T> 00296 class CollectionBuilder : public CollectionBuilderBase { 00297 public: 00303 CollectionBuilder(TTreeReader &reader); 00304 00306 virtual std::vector<T> const &Get() const = 0; 00307 00308 private: 00310 CollectionBuilderBase::Momentum const &GetMomentum( 00311 size_t index) const final; 00312 00314 size_t GetNumMomenta() const final; 00315 }; 00316 00317 00318 template <typename T> 00319 CollectionBuilder<T>::CollectionBuilder(TTreeReader &reader) 00320 : CollectionBuilderBase{reader} {} 00321 00322 00323 template <typename T> 00324 CollectionBuilderBase::Momentum const & 00325 CollectionBuilder<T>::GetMomentum(size_t index) const { 00326 return Get().at(index).p4; 00327 } 00328 00329 00330 template <typename T> 00331 size_t CollectionBuilder<T>::GetNumMomenta() const { 00332 return Get().size(); 00333 } 00334 00335 #endif // COLLECTIONBUILDER_H_ 00336