/*
 * TreeOutputAction.h
 *
 *  Created on: 03/nov/2009
 *      Author: Nicola Mori
 */

/*! @file TreeOutputAction.h The TreeOutputAction class declaration file. */

#ifndef TREEOUTPUTACTION_H_
#define TREEOUTPUTACTION_H_

#include "../../CollectionAction/CollectionAction.h"

/*! @brief An abstract class which provides a template for a custom ROOT tree output action.
 *
 *  This class defines a common template for a custom output action in ROOT tree format.
 *  It takes care of opening the file, filling the tree and writing it on a file. Descendants
 *  have to implement the pure virtual members #_InitBranches() and #_ComputeBranches, which
 *  takes care, for the current event, of creating the branches and filling the structures
 *  linked to the branches. #_InitBranches() will be automatically called at the beginning of
 *  the analysis, while #_ComputeBranches will be invoked for each event.
 */

class TreeOutputAction: public CollectionAction {
public:

  /*! @brief Constructor.
   *
   * @param actionName The action's name.
   * @param outFileName The name of the output file (with extension).
   */
  TreeOutputAction(const char *actionName, TString outFileName);

  /*! @brief Destructor.
   *
   * Note that this destructor won't call delete
   */
  ~TreeOutputAction();

  /*! @brief The pre-selection tasks.
   *
   * This routine opens the ROOT output file and calls the #_InitBranches() method.
   *
   * @param events Pointer to PamLevel2 object which contains the events to analize.
   */
  void Setup(PamLevel2 *events);

  /*! @brief Routine for selected events.
   *
   *  This will call #_ComputeBranches to compute the variables and then will call
   *  Fill() for the tree.
   *
   * @param event The selected event.
   */
  void OnGood(PamLevel2 *event);


  /*! @brief The finalization routine.
   *
   * This method writes the tree on the file.
   */
  void Finalize();

protected:
  /*! @brief The tree object which will be saved in the file.
   *
   *  The derived classes will have to handle the instantiation and the creation of
   *  the branches of this tree, as well as filling its buffer variables and deleting it.
   *  TreeOutputAction takes care of filling it with the buffers' values for each event and
   *  writing it on disk.
   */
  TTree *_tree;

  /*! @brief The branch-initialization routine.
   *
   * Concrete implementations of this method will have to set the branches to save in
   * the file. The tree object which has to be branched is #_tree. If one wants to
   * branch his own structure, one possibility is to define it in the child class' header.
   *
   * @param events Pointer to PamLevel2 object which contains the events to analize.
   */
  virtual void _InitBranches(PamLevel2 *events) = 0;

  /*! @brief The branch computation routine.
   *
   * Here the buffers for the branches created in #_InitBranches() can be filled using the
   * event's data. Remember to NOT call _tree.Fill() here: this operation is automatically
   * handled by #OnGood(), so you have only to care about filling the buffers.
   * Implementation is demanded to concrete children classes.
   *
   * @param event The selected event.
   */
  virtual void _ComputeBranches(PamLevel2 *event) = 0;

private:

  TFile *_outFile;
  TString _outFileName;

};

#endif /* TREEOUTPUTACTION_H_ */
