Next Previous Contents

10. Extending TMBAnalzye

You can extend TMBAnalyze_x without any modifications to the original packages. This is useful if you want to add new branches or your own private information while generating the TMBTree. This section assumes that you have basic knowledge about ROOT's persistency system.

As a first step, you should create your own CVS and framework package where you will put your code. In the following we assume that your framework class is called TMBExtendPkg. This class only has to inherit from fwk::Package base class:


#include "framework/Package.hpp"
#include "tmb_tree_maker/TMBMaker.hpp"

namespace MyExtension {

   class TMBExtendPkg : public fwk::package {
   public:
       TMBExtendPkg(fwk::Context *ctx);
       std::string packageName() const;
       static const std::string package_name();
       static const std::string version();
   private:
       TMBMaker *_maker;
   };
}

Extending TMBAnalyze is very easy if your own data is either:

In both cases you should create a subclass of the TMBMaker class. We assume you have defined your own root class, e.g.

  class MyClass : public TObject {
  public:
      MyClass();
  private:
     Int_t data;
  public:
     ClassDef(MyClass, 1);
  };

10.1 Storing TClonesArrays

We handle the case of a TClonesArray first.

Your maker class should look like this:

   class MyArrayMaker : public TMBMaker {
   public:
      MyArrayMaker(const char *name, const char *title);
      ~MyArrayMaker();
      Int_t Make(edm::Event& event);
   };

In the constructor, you specify your branch name and pass an instance of a properly initialized TClonesArray to the base class:

MyArrayMaker::MyArrayMaker(const char *name, const char *title)
    : TMBMaker(name, title)
{
   _Fruits     = new TClonesArray("MyClass", 2, kFALSE);
   _BranchName = "MyArray";
   Save();
}

Then, in the Make() method, you actually fill the array with any data you like. The assumption is that you either get it from the edm::Event or generate it yourself.

Int_t MyArrayMaker::Make(const edm::Event& event)
{
   TClonesArray& array = *(TClonesArray *)_Fruits;

   for(int i = 0; i < numObjects; i++) {   
      // create your object
      new (array[i]) MyClass();
   }
   return 0;
}

That's it. Now all we have to do is make the MyArrayMaker class known to TMBAnalyze. We do this by simply creating an instance of the class in our framework package:

    TMBExtendPkg::TMBExtendPkg(fwk::Context *ctx)
         : fwk::Package(ctx),
           _maker(0)
    {
       bool doMyClassArray = packageRCP().getBool("doMyClassArray");
       if(doMyClassArray) _maker = new MyArrayMaker("MyClassArray", "Maker for MyClass");
    }

    TMBExtendPkg::~TMBExtendPkg() { delete _maker; }

Now you can add your RegTMBExtendPkg to tmb_analyze/bin/OBJECTS and relink the executable. Alternatively, you can create your own executable by copying over tmb_analyze/bin/OBJECTS into your own package bin directory and just add any local modifications.

10.2 Storing Single Objects

The modifications for storing a single object instead of a TClonesArray are rather simple.

10.3 Storing other Persistent Information

The scheme above assumes that you have one Maker class for each object or array of objects which is stored in turn in a single branch.

You don't have to follow this scheme, but you will have to do more of the work yourself in this case. If you assign a null pointer to _Fruits the normal procedure will not apply. However, in this case, you have to create the branch yourself. To do this, override the MakeBranch method and do anything you have to do for your custom branch(es).

You can get access to the common tree like this:

     TTree *tree = gTMBTree->Tree();
     tree->Branch("branch1", ...);
     tree->Branch("branch2", ...);
     ...

For instance, you could store plain old ntuples here.


Next Previous Contents