/** @file
 * $Source: /home/cvsmanager/yoda/event/PamelaRun.h,v $
 * $Id: PamelaRun.h,v 3.0 2005/03/04 15:54:11 kusanagi Exp $
 * $Author: kusanagi $
 * 
 * Header file for the PamelaRun class.
 */
/*! \mainpage Yoda
 * <H1> Yet anOther Data Analysis package</H1>
 * YODA is the proposed data processing and analysis package for 
 * <A HREF="http://wizard.roma2.infn.it/pamela/fram_des.htm">Pamela</A>.
 * Aditionally to the automatically generated information, there is a short
 * tutorial available:
 * <H2> <A HREF="yoda1.html">Installation</A></H2>
 * <H2> <A HREF="yoda2.html">General terminology</A></H2>
 * <H2> <A HREF="yoda3.html">Directory and file structure</A></H2>
 * <H2> <A HREF="yoda4.html">Code organization</A></H2>
 * <H2> <A HREF="yoda5.html">Interactive analysis</A></H2>
 * <H2> <A HREF="yoda6.html">Existing subpackets</A></H2>
 * <H2> <A HREF="yoda7.html">Writing new subpackets</A></H2>
 * <H2> <A HREF="yoda8.html">Writing Algorithms</A></H2>
 *
 */
#ifndef PAMELA_RUN_H
#define PAMELA_RUN_H

//#include <string>
//#include <map>
//#include <list>

//#include <root/TFile.h>
//#include <root/TTree.h>
//#include <root/TChain.h>
#include <TFile.h> //Substituted by Maurizio 05 Feb 2004
#include <TTree.h> //Substituted by Maurizio 05 Feb 2004
#include <TChain.h> //Substituted by Maurizio 05 Feb 2004


#include "PacketType.h"
#include "SubPacket.h"
#include "Algorithm.h"
#include "EventHeader.h"
#include "RunInfo.h"
#include <sstream>


/**
 * pamela is the base namespace of this package.
 */
namespace pamela {
  class Algorithm;
  /**
   * Base class for a "Run", that is used for reading and writing
   * data to the ROOT files in pamela.
   */
  class PamelaRun {
  private:
    std::stringstream oss;
    /**
     * The path to the bases of the ROOT repository.
     */
    std::string Path;
    /**
     * The run name; 
     */
    std::string Run;
    /**
     * The run number.
     */
    int RunNumber;
    /**
     * The information about the run to be stored in the ROOT files
     */
    pamela::RunInfo info;
    void RunExists(std::string) throw (std::exception);
    std::string GetDirName(const pamela::PacketType*) const;
    std::string GetFileName(const pamela::SubPacket*, std::string) ;
    std::string GetFileName(const pamela::SubPacket*) ;
    TChain* ReadHeaderTree(const pamela::PacketType*) throw (std::exception);
    TTree* CreateTTree(pamela::Algorithm*, const pamela::SubPacket*, std::string name) 
      throw (std::exception);
   
  protected:
    /**
     * A map used to store ROOT trees distinguished by the packet type.
     */
    typedef std::map<const pamela::PacketType*, TTree*> RootTreeMap;
    /**
     * A map of all opened header ROOT trees, sorted by the
     * PacketType. The trees will have mounted all other trees of the
     * same package type as friends.
     */
    RootTreeMap TTreeMap; //!
    /**
     * A list of ROOT TFiles.
     */
    typedef std::list<TFile *> TFileList;
    /**
     * A list of ROOT TTrees.
     */
    typedef std::list<TTree *> TTreeList;
    /**
     * A map of Root Tree lists, with their packet type as key.
     */
    typedef std::map<const pamela::PacketType*, TTreeList> TTreeListMap;
    /**
     * The map of lists of all ROOT TTrees, sorted by the packet type.
     */
    TTreeListMap WritingRootTrees; //!
    /**
     * A map that contains subpacket objects sorted by their names.
     */
    typedef std::map<std::string, pamela::SubPacket*> SubPacketMap;
    /**
     * The map of all subpackets that are currently read from the trees.
     */
    SubPacketMap SubPacketAddresses;
    
    

  public:
    PamelaRun(std::string, std::string);
    static std::string GetRunName(int run); 
    //static int RunExists(int = 1) throw (std::exception);
    
    /**
     * Get the run number.
     */ 
    int GetRunNumber(void) const { return RunNumber; }
    TTree* ReadTTree(pamela::PacketType const *);
    void ReadSubPacket(void *);
    void ReadSubPacket(void *, std::string);
    void ReadSubPacket(const pamela::Algorithm*, void*);
    void ReadSubPacket(const pamela::Algorithm*, void*, std::string);
    void WriteSubPacket(pamela::Algorithm*, void*, const TClass*);
    void WriteSubPacket(pamela::Algorithm*, void*, const TClass*, std::string);
    void WriteHeaders(pamela::Algorithm*, pamela::EventHeader **);
    void WriteHeader(pamela::Algorithm*, pamela::EventHeader**, const pamela::PacketType*); // 23/11/2002 maurizio mede it from private to public
    void WriteFiles(void);
    void FillTrees(const pamela::PacketType*);
    std::string GetRun(){ return Run; }
    ClassDef(PamelaRun, 1)
  };
}

#endif /* PAMELA_RUN_H */
