CMS 3D CMS Logo

TFWLiteSelectorBasic.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 //
4 // Package: TFWLiteSelector
5 // Class : TFWLiteSelectorBasic
6 //
7 // Implementation:
8 // <Notes on implementation>
9 //
10 // Original Author: Chris Jones
11 // Created: Tue Jun 27 17:58:10 EDT 2006
12 //
13 
14 // user include files
16 
26 #include "DataFormats/Provenance/interface/EventEntryDescription.h" // kludge to allow compilation
50 
51 // system include files
52 #include "TBranch.h"
53 #include "TChain.h"
54 #include "TFile.h"
55 #include "TTree.h"
56 
57 #include <iostream>
58 #include <memory>
59 #include <string>
60 #include <vector>
61 #include <unordered_map>
62 
63 namespace edm {
64  namespace root {
66  public:
68  void setEntry(Long64_t iEntry) { entry_ = iEntry; }
69  void setTree(TTree* iTree) { eventTree_ = iTree; }
70  void set(std::shared_ptr<std::unordered_map<unsigned int, BranchDescription const*>> iMap) {
71  bidToDesc_ = std::move(iMap);
72  }
73 
74  private:
75  std::unique_ptr<WrapperBase> getTheProduct(BranchID const& k) const;
76  std::unique_ptr<WrapperBase> getProduct_(BranchID const& k, EDProductGetter const* ep) override;
77  virtual std::unique_ptr<EventEntryDescription> getProvenance_(BranchKey const&) const {
78  return std::unique_ptr<EventEntryDescription>();
79  }
80  void mergeReaders_(DelayedReader*) override {}
81  void reset_() override {}
82 
84  const override {
85  return nullptr;
86  }
88  const override {
89  return nullptr;
90  };
91 
92  Long64_t entry_;
93  TTree* eventTree_;
94  std::shared_ptr<std::unordered_map<unsigned int, BranchDescription const*>> bidToDesc_;
95  };
96 
97  std::unique_ptr<WrapperBase> FWLiteDelayedReader::getProduct_(BranchID const& k, EDProductGetter const* /*ep*/) {
98  return getTheProduct(k);
99  }
100 
101  std::unique_ptr<WrapperBase> FWLiteDelayedReader::getTheProduct(BranchID const& k) const {
102  auto itFind = bidToDesc_->find(k.id());
103  if (itFind == bidToDesc_->end()) {
104  throw Exception(errors::ProductNotFound) << "could not find entry for product " << k;
105  }
106  BranchDescription const& bDesc = *(itFind->second);
107 
108  TBranch* branch = eventTree_->GetBranch(bDesc.branchName().c_str());
109  if (nullptr == branch) {
110  throw cms::Exception("MissingBranch") << "could not find branch named '" << bDesc.branchName() << "'"
111  << "\n Perhaps the data being requested was not saved in this file?";
112  }
113  //find the class type
114  std::string const fullName = wrappedClassName(bDesc.className());
115  TypeWithDict classType = TypeWithDict::byName(fullName);
116  if (!bool(classType)) {
117  throw cms::Exception("MissingDictionary") << "could not find dictionary for type '" << fullName << "'"
118  << "\n Please make sure all the necessary libraries are available.";
119  }
120 
121  //create an instance of it
122  ObjectWithDict wrapperObj = classType.construct();
123  if (nullptr == wrapperObj.address()) {
124  throw cms::Exception("FailedToCreate") << "could not create an instance of '" << fullName << "'";
125  }
126  void* address = wrapperObj.address();
127  branch->SetAddress(&address);
128  ObjectWithDict edProdObj = wrapperObj.castObject(TypeWithDict::byName("edm::WrapperBase"));
129 
130  WrapperBase* prod = reinterpret_cast<WrapperBase*>(edProdObj.address());
131 
132  if (nullptr == prod) {
133  throw cms::Exception("FailedConversion") << "failed to convert a '" << fullName << "' to a edm::WrapperBase."
134  << "Please contact developers since something is very wrong.";
135  }
136  branch->GetEntry(entry_);
137  return std::unique_ptr<WrapperBase>(prod);
138  }
139 
142  : tree_(nullptr),
143  reg_(new ProductRegistry()),
144  bidToDesc_(std::make_shared<std::unordered_map<unsigned int, BranchDescription const*>>()),
145  phreg_(new ProcessHistoryRegistry()),
146  branchIDListHelper_(new BranchIDListHelper()),
147  // Note that thinned collections are not supported yet, the next
148  // line just makes it compile but when the Ref or Ptr tries to
149  // find the thinned collection it will report them not found.
150  // More work needed here if this is needed (we think no one
151  // is using TFWLiteSelector anymore and intend to implement
152  // this properly if it turns out we are wrong)
153  thinnedAssociationsHelper_(new ThinnedAssociationsHelper()),
154  processNames_(),
155  reader_(new FWLiteDelayedReader),
156  prov_(),
157  pointerToBranchBuffer_(),
158  provRetriever_(new edm::ProductProvenanceRetriever(0)) {
159  reader_->set(get_underlying_safe(bidToDesc_));
160  }
161  void setTree(TTree* iTree) {
162  tree_ = iTree;
163  reader_->setTree(iTree);
164  }
165 
166  TTree const* tree() const { return get_underlying_safe(tree_); }
167  TTree*& tree() { return get_underlying_safe(tree_); }
168  std::shared_ptr<ProductRegistry const> reg() const { return get_underlying_safe(reg_); }
169  std::shared_ptr<ProductRegistry>& reg() { return get_underlying_safe(reg_); }
170  std::shared_ptr<BranchIDListHelper const> branchIDListHelper() const {
171  return get_underlying_safe(branchIDListHelper_);
172  }
173  std::shared_ptr<BranchIDListHelper>& branchIDListHelper() { return get_underlying_safe(branchIDListHelper_); }
174  std::shared_ptr<ThinnedAssociationsHelper const> thinnedAssociationsHelper() const {
175  return get_underlying_safe(thinnedAssociationsHelper_);
176  }
177  std::shared_ptr<ThinnedAssociationsHelper>& thinnedAssociationsHelper() {
178  return get_underlying_safe(thinnedAssociationsHelper_);
179  }
180 
189  std::vector<EventEntryDescription> prov_;
190  std::vector<EventEntryDescription const*> pointerToBranchBuffer_;
192 
197  };
198  } // namespace root
199 } // namespace edm
200 
201 //
202 // constants, enums and typedefs
203 //
204 
205 //
206 // static data member definitions
207 //
208 
209 //
210 // constructors and destructor
211 //
212 TFWLiteSelectorBasic::TFWLiteSelectorBasic() : m_(new edm::root::TFWLiteSelectorMembers), everythingOK_(false) {}
213 
214 // TFWLiteSelectorBasic::TFWLiteSelectorBasic(TFWLiteSelectorBasic const& rhs)
215 // {
216 // // do actual copying here;
217 // }
218 
220 
221 //
222 // assignment operators
223 //
224 // TFWLiteSelectorBasic const& TFWLiteSelectorBasic::operator=(TFWLiteSelectorBasic const& rhs)
225 // {
226 // //An exception safe implementation is
227 // TFWLiteSelectorBasic temp(rhs);
228 // swap(rhs);
229 //
230 // return *this;
231 // }
232 
233 //
234 // member functions
235 //
236 void TFWLiteSelectorBasic::Begin(TTree* iTree) {
237  Init(iTree);
238  begin(fInput);
239 }
240 
242  Init(iTree);
243  preProcessing(fInput, *fOutput);
244 }
245 
246 void TFWLiteSelectorBasic::Init(TTree* iTree) {
247  if (iTree == nullptr)
248  return;
249  m_->setTree(iTree);
250 }
251 
253  //std::cout << "Notify start" << std::endl;
254  //we have switched to a new file
255  //get new file from Tree
256  if (nullptr == m_->tree_) {
257  std::cout << "No tree" << std::endl;
258  return kFALSE;
259  }
260  TFile* file = m_->tree_->GetCurrentFile();
261  if (nullptr == file) {
262  //When in Rome, do as the Romans
263  TChain* chain = dynamic_cast<TChain*>(m_->tree());
264  if (nullptr == chain) {
265  std::cout << "No file" << std::endl;
266  return kFALSE;
267  }
268  file = chain->GetFile();
269  if (nullptr == file) {
270  std::cout << "No file" << std::endl;
271  return kFALSE;
272  }
273  }
274  setupNewFile(*file);
275  return everythingOK_ ? kTRUE : kFALSE;
276 }
277 
278 namespace {
279  struct Operate {
280  Operate(edm::EDProductGetter const* iGetter) : old_(setRefCoreStreamer(iGetter)) {}
281 
282  ~Operate() { setRefCoreStreamer(old_); }
283 
284  private:
285  edm::EDProductGetter const* old_;
286  };
287 } // namespace
288 
289 Bool_t TFWLiteSelectorBasic::Process(Long64_t iEntry) {
290  //std::cout << "Process start" << std::endl;
291  if (everythingOK_) {
292  std::unique_ptr<edm::EventAuxiliary> eaux = std::make_unique<edm::EventAuxiliary>();
293  edm::EventAuxiliary& aux = *eaux;
294  edm::EventAuxiliary* pAux = eaux.get();
295  TBranch* branch = m_->tree_->GetBranch(edm::BranchTypeToAuxiliaryBranchName(edm::InEvent).c_str());
296 
297  branch->SetAddress(&pAux);
298  branch->GetEntry(iEntry);
299 
300  //NEW m_->processNames_ = aux.processHistory();
301 
302  // std::cout << "ProcessNames\n";
303  // for(auto const& name : m_->processNames_) {
304  // std::cout << " " << name << std::endl;
305  // }
306 
307  edm::EventSelectionIDVector eventSelectionIDs;
308  edm::EventSelectionIDVector* pEventSelectionIDVector = &eventSelectionIDs;
309  TBranch* eventSelectionsBranch = m_->tree_->GetBranch(edm::poolNames::eventSelectionsBranchName().c_str());
310  if (!eventSelectionsBranch) {
311  throw edm::Exception(edm::errors::FatalRootError) << "Failed to find event Selections branch in event tree";
312  }
313  eventSelectionsBranch->SetAddress(&pEventSelectionIDVector);
314  eventSelectionsBranch->GetEntry(iEntry);
315 
316  edm::BranchListIndexes branchListIndexes;
317  edm::BranchListIndexes* pBranchListIndexes = &branchListIndexes;
318  TBranch* branchListIndexBranch = m_->tree_->GetBranch(edm::poolNames::branchListIndexesBranchName().c_str());
319  if (!branchListIndexBranch) {
320  throw edm::Exception(edm::errors::FatalRootError) << "Failed to find branch list index branch in event tree";
321  }
322  branchListIndexBranch->SetAddress(&pBranchListIndexes);
323  branchListIndexBranch->GetEntry(iEntry);
324  m_->branchIDListHelper_->fixBranchListIndexes(branchListIndexes);
325 
326  try {
327  m_->reader_->setEntry(iEntry);
328  auto runAux = std::make_shared<edm::RunAuxiliary>(aux.run(), aux.time(), aux.time());
329  auto rp = std::make_shared<edm::RunPrincipal>(runAux, m_->reg(), m_->pc_, nullptr, 0);
330  auto lbp = std::make_shared<edm::LuminosityBlockPrincipal>(m_->reg(), m_->pc_, nullptr, 0);
331  lbp->setAux(edm::LuminosityBlockAuxiliary(rp->run(), 1, aux.time(), aux.time()));
332  m_->ep_->fillEventPrincipal(*eaux,
333  *m_->phreg_,
334  std::move(eventSelectionIDs),
335  std::move(branchListIndexes),
336  *(m_->provRetriever_),
337  m_->reader_.get());
338  lbp->setRunPrincipal(rp);
339  m_->ep_->setLuminosityBlockPrincipal(lbp.get());
340  m_->processNames_ = m_->ep_->processHistory();
341 
342  edm::Event event(*m_->ep_, m_->md_, nullptr);
343 
344  //Make the event principal accessible to edm::Ref's
345  Operate sentry(m_->ep_->prodGetter());
346  process(event);
347  } catch (std::exception const& iEx) {
348  std::cout << "While processing entry " << iEntry << " the following exception was caught \n"
349  << iEx.what() << std::endl;
350  } catch (...) {
351  std::cout << "While processing entry " << iEntry << " an unknown exception was caught" << std::endl;
352  }
353  }
354  return everythingOK_ ? kTRUE : kFALSE;
355 }
356 
358 
360 
362  //look up meta-data
363  //get product registry
364 
365  //std::vector<edm::EventProcessHistoryID> eventProcessHistoryIDs_;
366  TTree* metaDataTree = dynamic_cast<TTree*>(iFile.Get(edm::poolNames::metaDataTreeName().c_str()));
367  if (!metaDataTree) {
368  std::cout << "could not find TTree " << edm::poolNames::metaDataTreeName() << std::endl;
369  everythingOK_ = false;
370  return;
371  }
372  edm::FileFormatVersion* fftPtr = &(m_->fileFormatVersion_);
373  if (metaDataTree->FindBranch(edm::poolNames::fileFormatVersionBranchName().c_str()) != nullptr) {
374  metaDataTree->SetBranchAddress(edm::poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
375  }
376 
377  edm::ProductRegistry* pReg = &(*m_->reg_);
378  metaDataTree->SetBranchAddress(edm::poolNames::productDescriptionBranchName().c_str(), &(pReg));
379 
380  typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> PsetMap;
381  PsetMap psetMap;
382  PsetMap* psetMapPtr = &psetMap;
383  if (metaDataTree->FindBranch(edm::poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
384  metaDataTree->SetBranchAddress(edm::poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
385  } else {
386  TTree* psetTree = dynamic_cast<TTree*>(iFile.Get(edm::poolNames::parameterSetsTreeName().c_str()));
387  if (nullptr == psetTree) {
389  << "Could not find tree " << edm::poolNames::parameterSetsTreeName() << " in the input file.\n";
390  }
391  typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
392  IdToBlobs idToBlob;
393  IdToBlobs* pIdToBlob = &idToBlob;
394  psetTree->SetBranchAddress(edm::poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
395  for (long long i = 0; i != psetTree->GetEntries(); ++i) {
396  psetTree->GetEntry(i);
397  psetMap.insert(idToBlob);
398  }
399  }
400 
402  edm::ProcessHistoryRegistry::vector_type* pHistVectorPtr = &pHistVector;
403  if (metaDataTree->FindBranch(edm::poolNames::processHistoryBranchName().c_str()) != nullptr) {
404  metaDataTree->SetBranchAddress(edm::poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
405  }
406 
407  edm::ProcessConfigurationVector procConfigVector;
408  edm::ProcessConfigurationVector* procConfigVectorPtr = &procConfigVector;
409  if (metaDataTree->FindBranch(edm::poolNames::processConfigurationBranchName().c_str()) != nullptr) {
410  metaDataTree->SetBranchAddress(edm::poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
411  }
412 
413  auto branchIDListsHelper = std::make_shared<edm::BranchIDListHelper>();
414  edm::BranchIDLists const* branchIDListsPtr = &branchIDListsHelper->branchIDLists();
415  if (metaDataTree->FindBranch(edm::poolNames::branchIDListBranchName().c_str()) != nullptr) {
416  metaDataTree->SetBranchAddress(edm::poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
417  }
418 
419  metaDataTree->GetEntry(0);
420 
421  for (auto& prod : m_->reg_->productListUpdator()) {
422  prod.second.init();
423  setIsMergeable(prod.second);
424  }
425 
426  // Merge into the registries. For now, we do NOT merge the product registry.
428  for (auto const& entry : psetMap) {
429  edm::ParameterSet pset(entry.second.pset());
430  pset.setID(entry.first);
431  psetRegistry.insertMapped(pset);
432  }
433 
434  for (auto const& ph : pHistVector) {
435  m_->phreg_->registerProcessHistory(ph);
436  }
437 
438  m_->pointerToBranchBuffer_.erase(m_->pointerToBranchBuffer_.begin(), m_->pointerToBranchBuffer_.end());
439 
440  std::unique_ptr<edm::ProductRegistry> newReg = std::make_unique<edm::ProductRegistry>();
441 
442  edm::ProductRegistry::ProductList& prodList = m_->reg_->productListUpdator();
443  {
444  for (auto& item : prodList) {
445  edm::BranchDescription& prod = item.second;
446  //std::cout << "productname = " << item.second << " end " << std::endl;
447  std::string newFriendlyName = edm::friendlyname::friendlyName(prod.className());
448  if (newFriendlyName == prod.friendlyClassName()) {
449  newReg->copyProduct(prod);
450  } else {
451  if (m_->fileFormatVersion_.splitProductIDs()) {
453  << "Cannot change friendly class name algorithm without more development work\n"
454  << "to update BranchIDLists. Contact the framework group.\n";
455  }
456  edm::BranchDescription newBD(prod);
457  newBD.updateFriendlyClassName();
458  newReg->copyProduct(newBD);
459  }
460  prod.init();
461  }
462 
463  m_->reg().reset(newReg.release());
464  }
465 
466  edm::ProductRegistry::ProductList& prodList2 = m_->reg_->productListUpdator();
467  std::vector<edm::EventEntryDescription> temp(prodList2.size(), edm::EventEntryDescription());
468  m_->prov_.swap(temp);
469  m_->pointerToBranchBuffer_.reserve(prodList2.size());
470 
471  for (auto& item : prodList2) {
472  edm::BranchDescription& prod = item.second;
473  if (prod.branchType() == edm::InEvent) {
474  prod.init();
475  //NEED to do this and check to see if branch exists
476  if (m_->tree_->GetBranch(prod.branchName().c_str()) == nullptr) {
477  prod.setDropped(true);
478  }
479 
480  //std::cout << "id " << it->first << " branch " << it->second << std::endl;
481  //m_->pointerToBranchBuffer_.push_back(&(*itB));
482  //void* tmp = &(m_->pointerToBranchBuffer_.back());
483  //edm::EventEntryDescription* tmp = &(*itB);
484  //CDJ need to fix provenance and be backwards compatible, for now just don't read the branch
485  //m_->metaTree_->SetBranchAddress(prod.branchName().c_str(), tmp);
486  }
487  }
488  m_->branchIDListHelper_->updateFromInput(*branchIDListsPtr);
489  m_->reg_->setFrozen();
490  m_->bidToDesc_->clear();
491  for (auto const& p : m_->reg_->productList()) {
492  m_->bidToDesc_->emplace(p.second.branchID().id(), &p.second);
493  }
494  m_->ep_ = std::make_shared<edm::EventPrincipal>(
495  m_->reg(), m_->branchIDListHelper(), m_->thinnedAssociationsHelper(), m_->pc_, nullptr);
496  everythingOK_ = true;
497 }
498 
499 //
500 // const member functions
501 //
502 
503 //
504 // static member functions
505 //
signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const * preEventReadFromSourceSignal() const override
std::vector< EventEntryDescription const * > pointerToBranchBuffer_
std::string const & idToParameterSetBlobsBranchName()
Definition: BranchType.cc:261
virtual void terminate(TList &out)=0
std::vector< ProcessConfiguration > ProcessConfigurationVector
std::string const & branchName() const
std::shared_ptr< ThinnedAssociationsHelper const > thinnedAssociationsHelper() const
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:116
std::shared_ptr< std::unordered_map< unsigned int, BranchDescription const * > > bidToDesc_
BranchType const & branchType() const
std::vector< BranchIDList > BranchIDLists
Definition: BranchIDList.h:19
std::shared_ptr< BranchIDListHelper const > branchIDListHelper() const
Definition: chain.py:1
virtual std::unique_ptr< EventEntryDescription > getProvenance_(BranchKey const &) const
void * address() const
virtual void preProcessing(const TList *in, TList &out)=0
std::vector< EventEntryDescription > prov_
edm::propagate_const< TTree * > tree_
edm::propagate_const< std::shared_ptr< edm::root::TFWLiteSelectorMembers > > m_
ObjectWithDict castObject(TypeWithDict const &) const
std::map< BranchKey, BranchDescription > ProductList
#define nullptr
edm::propagate_const< std::shared_ptr< ThinnedAssociationsHelper > > thinnedAssociationsHelper_
void mergeReaders_(DelayedReader *) override
void setRefCoreStreamer(bool resetAll=false)
std::string const & fileFormatVersionBranchName()
Definition: BranchType.cc:219
virtual void postProcessing(TList &out)=0
std::string const & eventSelectionsBranchName()
Definition: BranchType.cc:249
edm::propagate_const< std::shared_ptr< edm::ProductProvenanceRetriever > > provRetriever_
std::shared_ptr< BranchIDListHelper > & branchIDListHelper()
virtual void process(const edm::Event &event)=0
unsigned int id() const
Definition: BranchID.h:23
signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const * postEventReadFromSourceSignal() const override
std::vector< EventSelectionID > EventSelectionIDVector
std::string const & parameterSetsTreeName()
Definition: BranchType.cc:257
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:74
std::vector< BranchListIndex > BranchListIndexes
std::string const & className() const
std::string friendlyName(std::string const &iFullName)
edm::propagate_const< std::shared_ptr< ProductRegistry > > reg_
edm::propagate_const< std::shared_ptr< FWLiteDelayedReader > > reader_
edm::propagate_const< std::shared_ptr< BranchIDListHelper > > branchIDListHelper_
std::string const & friendlyClassName() const
void setDropped(bool isDropped)
bool insertMapped(value_type const &v, bool forceUpdate=false)
Definition: Registry.cc:32
std::string const & metaDataTreeName()
Definition: BranchType.cc:169
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
std::shared_ptr< ProductRegistry > & reg()
std::string const & parameterSetMapBranchName()
Definition: BranchType.cc:184
element_type const * get() const
std::string const & processHistoryBranchName()
Definition: BranchType.cc:199
int k[5][pyjets_maxn]
edm::propagate_const< std::shared_ptr< edm::EventPrincipal > > ep_
void SlaveTerminate() override
void SlaveBegin(TTree *) override
std::string wrappedClassName(std::string const &iFullName)
void Begin(TTree *) override
std::unique_ptr< WrapperBase > getProduct_(BranchID const &k, EDProductGetter const *ep) override
std::string const & productDescriptionBranchName()
Definition: BranchType.cc:174
std::string const & processConfigurationBranchName()
Definition: BranchType.cc:204
std::shared_ptr< ThinnedAssociationsHelper > & thinnedAssociationsHelper()
Bool_t Process(Long64_t) override
std::unique_ptr< WrapperBase > getTheProduct(BranchID const &k) const
edm::propagate_const< std::shared_ptr< std::unordered_map< unsigned int, BranchDescription const * > > > bidToDesc_
edm::propagate_const< std::shared_ptr< ProcessHistoryRegistry > > phreg_
std::shared_ptr< ProductRegistry const > reg() const
HLT enums.
std::string const & branchIDListBranchName()
Definition: BranchType.cc:209
std::string const & branchListIndexesBranchName()
Definition: BranchType.cc:253
void setIsMergeable(BranchDescription &)
def move(src, dest)
Definition: eostools.py:511
static Registry * instance()
Definition: Registry.cc:12
void Init(TTree *) override
virtual void begin(TList *&in)=0