#ifndef INCLUDE_HISTFACTORYNAVIGATION_H
#define INCLUDE_HISTFACTORYNAVIGATION_H

#include <map>

#include "TH1.h"
#include "THStack.h"

#include "RooDataSet.h"
#include "RooRealVar.h"
#include "RooProduct.h"
#include "RooStats/HistFactory/Measurement.h"
#include "RooStats/ModelConfig.h"


namespace RooStats {
  namespace HistFactory { 

    class HistFactoryNavigation {

  
    public:

      // Initialze based on an already-created HistFactory Model
      HistFactoryNavigation(ModelConfig* mc);
      HistFactoryNavigation(const std::string& File, 
			    const std::string& WorkspaceName="combined",
			    const std::string& ModelConfigName="ModelConfig");
      HistFactoryNavigation(RooAbsPdf* model, RooArgSet* observables);

      virtual ~HistFactoryNavigation() {} 

      // Should pretty print all channels and the current values

      void PrintState();
      // Should pretty print this and the current values
      void PrintState(const std::string& channel);

      // Print the current values and errors of pdf parameters
      void PrintParameters(bool IncludeConstantParams=false);

      // Print parameters that effect a particular channel
      void PrintChannelParameters(const std::string& channel, 
				  bool IncludeConstantParams=false);

      // Print parameters that effect a particular sample
      void PrintSampleParameters(const std::string& channel, const std::string& sample, 
				 bool IncludeConstantParams=false);

      // Print the different components that make up a sample
      // (NormFactors, Statistical Uncertainties, Interpolation, etc)
      void PrintSampleComponents(const std::string& channel, const std::string& sample);

      // Print a "HistFactory style" RooDataSet in a readable way
      void PrintDataSet(RooDataSet* data, const std::string& channel="");

      // Print the model and the data, comparing channel by channel
      void PrintModelAndData(RooDataSet* data);

      // The value of the ith bin for the total in that channel
      double GetBinValue(int bin, const std::string& channel);  
      // The value of the ith bin for that sample and channel

      double GetBinValue(int bin, const std::string& channel, const std::string& sample);  

      // The (current) histogram for that sample 
      // This includes all parameters and interpolation
      TH1* GetSampleHist(const std::string& channel, 
			 const std::string& sample, const std::string& name="");  

      // Get the total channel histogram for this channel
      TH1* GetChannelHist(const std::string& channel, const std::string& name="");

      // Get a histogram from the dataset for this channel
      TH1* GetDataHist(RooDataSet* data, const std::string& channel, const std::string& name="");

      // Get a stack of all samples in a channel
      THStack* GetChannelStack(const std::string& channel, const std::string& name="");

      // Draw a stack of the channel, and include data if the pointer is supplied
      void DrawChannel(const std::string& channel, RooDataSet* data=NULL);

      // Get the RooAbsReal function for a given sample in a given channel
      RooAbsReal* SampleFunction(const std::string& channel, const std::string& sample);

      // Get the set of observables for a given channel
      RooArgSet* GetObservableSet(const std::string& channel);

      // Get the constraint term for a given systematic (alpha or gamma)
      RooAbsReal* GetConstraintTerm(const std::string& parameter);

      // Get the uncertainty based on the constraint term for a given systematic
      double GetConstraintUncertainty(const std::string& parameter);

      // Find a node in the pdf and replace it with a new node
      // These nodes can be functions, pdf's, RooRealVar's, etc
      // Will do minimial checking to make sure the replacement makes sense
      void ReplaceNode(const std::string& ToReplace, RooAbsArg* ReplaceWith);

      // Set any RooRealVar's const (or not const) if they match
      // the supplied regular expression
      void SetConstant(const std::string& regExpr=".*", bool constant=true);

      void SetMaxBinToPrint(int max) { _maxBinToPrint = max; }
      int GetMaxBinToPrint() const { return _maxBinToPrint; }

      void SetMinBinToPrint(int min) { _minBinToPrint = min; }
      int GetMinBinToPrint() const { return _minBinToPrint; }

      // Get the model for this channel
      RooAbsPdf* GetModel() const { return fModel; }

      //
      RooAbsPdf* GetChannelPdf(const std::string& channel);


      std::vector< std::string > GetChannelSampleList(const std::string& channel);

      // Return the RooRealVar by the same name used in the model
      // If not found, return NULL
      RooRealVar* var(const std::string& varName) const;
      
      /*
      // Add a channel to the pdf
      // Combine the data if it is provided
      void AddChannel(const std::string& channel, RooAbsPdf* pdf, RooDataSet* data=NULL);
      */

      /*
      // Add a constraint term to the pdf
      // This method requires that the pdf NOT be simultaneous
      void AddConstraintTerm(RooAbsArg* constraintTerm);

      // Add a constraint term to the pdf of a particular channel
      // This method requires that the pdf be simultaneous 
      // OR that the channel string match the channel that the pdf represents
      void AddConstraintTerm(RooAbsArg* constraintTerm, const std::string& channel);
      */

    protected:

      // Set the title and bin widths
      void SetPrintWidths(const std::string& channel);

      // Fetch the node information for the pdf in question, and
      // save it in the varous collections in this class
      void _GetNodes(ModelConfig* mc);
      void _GetNodes(RooAbsPdf* model, const RooArgSet* observables);

      // Print a histogram's contents to the screen
      // void PrettyPrintHistogram(TH1* hist);
      void PrintMultiDimHist(TH1* hist, int bin_print_width);

      // Make a histogram from a funciton
      // Edit so it can take a RooArgSet of parameters
      TH1* MakeHistFromRooFunction( RooAbsReal* func, RooArgList vars, std::string name="Hist" );

      // Get a map of sample names to their functions for a particular channel
      std::map< std::string, RooAbsReal*> GetSampleFunctionMap(const std::string& channel);

    private:
      
      // The HistFactory Pdf Pointer
      RooAbsPdf* fModel;

      // The observables
      RooArgSet* fObservables;

      int _minBinToPrint;
      int _maxBinToPrint;

      int _label_print_width;
      int _bin_print_width;

      // The list of channels
      std::vector<std::string> fChannelNameVec;

      // Map of channel names to their full pdf's
      std::map< std::string, RooAbsPdf* > fChannelPdfMap;  

      // Map of channel names to pdf without constraint
      std::map< std::string, RooAbsPdf* > fChannelSumNodeMap;  
      
      // Map of channel names to their set of ovservables
      std::map< std::string, RooArgSet*> fChannelObservMap;

      // Map of Map of Channel, Sample names to Function Nodes
      // Used by doing: fChannelSampleFunctionMap["MyChannel"]["MySample"]
      std::map< std::string, std::map< std::string, RooAbsReal*> > fChannelSampleFunctionMap;

      // Internal method implementation of finding a daughter node
      // from a parent node (looping over all generations)
      RooAbsArg* findChild(const std::string& name, RooAbsReal* parent) const;

      // Recursively get all products of products
      RooArgSet _GetAllProducts(RooProduct* node);
      

    protected:
      ClassDef(RooStats::HistFactory::HistFactoryNavigation,2)

    };

  }
}
#endif // INCLUDE_HISTFACTORYNAVIGATION_H
 HistFactoryNavigation.h:1
 HistFactoryNavigation.h:2
 HistFactoryNavigation.h:3
 HistFactoryNavigation.h:4
 HistFactoryNavigation.h:5
 HistFactoryNavigation.h:6
 HistFactoryNavigation.h:7
 HistFactoryNavigation.h:8
 HistFactoryNavigation.h:9
 HistFactoryNavigation.h:10
 HistFactoryNavigation.h:11
 HistFactoryNavigation.h:12
 HistFactoryNavigation.h:13
 HistFactoryNavigation.h:14
 HistFactoryNavigation.h:15
 HistFactoryNavigation.h:16
 HistFactoryNavigation.h:17
 HistFactoryNavigation.h:18
 HistFactoryNavigation.h:19
 HistFactoryNavigation.h:20
 HistFactoryNavigation.h:21
 HistFactoryNavigation.h:22
 HistFactoryNavigation.h:23
 HistFactoryNavigation.h:24
 HistFactoryNavigation.h:25
 HistFactoryNavigation.h:26
 HistFactoryNavigation.h:27
 HistFactoryNavigation.h:28
 HistFactoryNavigation.h:29
 HistFactoryNavigation.h:30
 HistFactoryNavigation.h:31
 HistFactoryNavigation.h:32
 HistFactoryNavigation.h:33
 HistFactoryNavigation.h:34
 HistFactoryNavigation.h:35
 HistFactoryNavigation.h:36
 HistFactoryNavigation.h:37
 HistFactoryNavigation.h:38
 HistFactoryNavigation.h:39
 HistFactoryNavigation.h:40
 HistFactoryNavigation.h:41
 HistFactoryNavigation.h:42
 HistFactoryNavigation.h:43
 HistFactoryNavigation.h:44
 HistFactoryNavigation.h:45
 HistFactoryNavigation.h:46
 HistFactoryNavigation.h:47
 HistFactoryNavigation.h:48
 HistFactoryNavigation.h:49
 HistFactoryNavigation.h:50
 HistFactoryNavigation.h:51
 HistFactoryNavigation.h:52
 HistFactoryNavigation.h:53
 HistFactoryNavigation.h:54
 HistFactoryNavigation.h:55
 HistFactoryNavigation.h:56
 HistFactoryNavigation.h:57
 HistFactoryNavigation.h:58
 HistFactoryNavigation.h:59
 HistFactoryNavigation.h:60
 HistFactoryNavigation.h:61
 HistFactoryNavigation.h:62
 HistFactoryNavigation.h:63
 HistFactoryNavigation.h:64
 HistFactoryNavigation.h:65
 HistFactoryNavigation.h:66
 HistFactoryNavigation.h:67
 HistFactoryNavigation.h:68
 HistFactoryNavigation.h:69
 HistFactoryNavigation.h:70
 HistFactoryNavigation.h:71
 HistFactoryNavigation.h:72
 HistFactoryNavigation.h:73
 HistFactoryNavigation.h:74
 HistFactoryNavigation.h:75
 HistFactoryNavigation.h:76
 HistFactoryNavigation.h:77
 HistFactoryNavigation.h:78
 HistFactoryNavigation.h:79
 HistFactoryNavigation.h:80
 HistFactoryNavigation.h:81
 HistFactoryNavigation.h:82
 HistFactoryNavigation.h:83
 HistFactoryNavigation.h:84
 HistFactoryNavigation.h:85
 HistFactoryNavigation.h:86
 HistFactoryNavigation.h:87
 HistFactoryNavigation.h:88
 HistFactoryNavigation.h:89
 HistFactoryNavigation.h:90
 HistFactoryNavigation.h:91
 HistFactoryNavigation.h:92
 HistFactoryNavigation.h:93
 HistFactoryNavigation.h:94
 HistFactoryNavigation.h:95
 HistFactoryNavigation.h:96
 HistFactoryNavigation.h:97
 HistFactoryNavigation.h:98
 HistFactoryNavigation.h:99
 HistFactoryNavigation.h:100
 HistFactoryNavigation.h:101
 HistFactoryNavigation.h:102
 HistFactoryNavigation.h:103
 HistFactoryNavigation.h:104
 HistFactoryNavigation.h:105
 HistFactoryNavigation.h:106
 HistFactoryNavigation.h:107
 HistFactoryNavigation.h:108
 HistFactoryNavigation.h:109
 HistFactoryNavigation.h:110
 HistFactoryNavigation.h:111
 HistFactoryNavigation.h:112
 HistFactoryNavigation.h:113
 HistFactoryNavigation.h:114
 HistFactoryNavigation.h:115
 HistFactoryNavigation.h:116
 HistFactoryNavigation.h:117
 HistFactoryNavigation.h:118
 HistFactoryNavigation.h:119
 HistFactoryNavigation.h:120
 HistFactoryNavigation.h:121
 HistFactoryNavigation.h:122
 HistFactoryNavigation.h:123
 HistFactoryNavigation.h:124
 HistFactoryNavigation.h:125
 HistFactoryNavigation.h:126
 HistFactoryNavigation.h:127
 HistFactoryNavigation.h:128
 HistFactoryNavigation.h:129
 HistFactoryNavigation.h:130
 HistFactoryNavigation.h:131
 HistFactoryNavigation.h:132
 HistFactoryNavigation.h:133
 HistFactoryNavigation.h:134
 HistFactoryNavigation.h:135
 HistFactoryNavigation.h:136
 HistFactoryNavigation.h:137
 HistFactoryNavigation.h:138
 HistFactoryNavigation.h:139
 HistFactoryNavigation.h:140
 HistFactoryNavigation.h:141
 HistFactoryNavigation.h:142
 HistFactoryNavigation.h:143
 HistFactoryNavigation.h:144
 HistFactoryNavigation.h:145
 HistFactoryNavigation.h:146
 HistFactoryNavigation.h:147
 HistFactoryNavigation.h:148
 HistFactoryNavigation.h:149
 HistFactoryNavigation.h:150
 HistFactoryNavigation.h:151
 HistFactoryNavigation.h:152
 HistFactoryNavigation.h:153
 HistFactoryNavigation.h:154
 HistFactoryNavigation.h:155
 HistFactoryNavigation.h:156
 HistFactoryNavigation.h:157
 HistFactoryNavigation.h:158
 HistFactoryNavigation.h:159
 HistFactoryNavigation.h:160
 HistFactoryNavigation.h:161
 HistFactoryNavigation.h:162
 HistFactoryNavigation.h:163
 HistFactoryNavigation.h:164
 HistFactoryNavigation.h:165
 HistFactoryNavigation.h:166
 HistFactoryNavigation.h:167
 HistFactoryNavigation.h:168
 HistFactoryNavigation.h:169
 HistFactoryNavigation.h:170
 HistFactoryNavigation.h:171
 HistFactoryNavigation.h:172
 HistFactoryNavigation.h:173
 HistFactoryNavigation.h:174
 HistFactoryNavigation.h:175
 HistFactoryNavigation.h:176
 HistFactoryNavigation.h:177
 HistFactoryNavigation.h:178
 HistFactoryNavigation.h:179
 HistFactoryNavigation.h:180
 HistFactoryNavigation.h:181
 HistFactoryNavigation.h:182
 HistFactoryNavigation.h:183
 HistFactoryNavigation.h:184
 HistFactoryNavigation.h:185
 HistFactoryNavigation.h:186
 HistFactoryNavigation.h:187
 HistFactoryNavigation.h:188
 HistFactoryNavigation.h:189
 HistFactoryNavigation.h:190
 HistFactoryNavigation.h:191
 HistFactoryNavigation.h:192
 HistFactoryNavigation.h:193
 HistFactoryNavigation.h:194
 HistFactoryNavigation.h:195
 HistFactoryNavigation.h:196
 HistFactoryNavigation.h:197
 HistFactoryNavigation.h:198
 HistFactoryNavigation.h:199
 HistFactoryNavigation.h:200
 HistFactoryNavigation.h:201
 HistFactoryNavigation.h:202
 HistFactoryNavigation.h:203
 HistFactoryNavigation.h:204