// Author: I. Froehlich
// Written: 1.02.2008
// Revised: 

#ifndef _PADAPTIVEMESHN_H_
#define _PADAPTIVEMESHN_H_

#define MAX_SUBMESH_N 20
#define MAX_DIMENSIONS 4

#include "TObject.h"
#include "PChannelModel.h"

class PAdaptiveMeshN : public TObject {

 private:

    Double_t y_max;        //upper value in each hyper-cube
    Double_t area_size;    //volume of the hyper-cube(es)
    Double_t x_max[MAX_DIMENSIONS], x_min[MAX_DIMENSIONS]; //width of the hypercubes
    Int_t sub_size[MAX_DIMENSIONS];       //sub-size in each dimension of the parent hypercube
    Int_t total_sub_size;  //total number of sub-meshs
    Int_t is_divided;
    Int_t layer;           //layer of the hypercube. The innermost has 0

    PAdaptiveMeshN *sub_tree;  //for each dimension pointer to the subtree
    Double_t *sub_area;        //for each dimension volume size

    Int_t num_dimensions;   //number of dimensions of the hyper-cube
    Int_t variable_dimensions;  //number of dimensions to be sampled
    PChannelModel *model;   //Model to be sampled
    Double_t array[MAX_DIMENSIONS]; //storage array for GetWeight()

    void ReCalc(void);      //re-calculate all volumes
    void FixArray(void);    //set the fixed array contributions
    
    UInt_t pattern;
    Int_t mcpoints;
    Double_t threshold_diff;
    Double_t threshold_abs;

    PAdaptiveMeshN *GetRandomBin(Double_t f_random);

 public:

    //constructor
    //pattern sets the variables to be sampled in the GetWeight method in PChannelModel
    PAdaptiveMeshN(UInt_t my_pattern, Int_t my_max_dimensions, 
		   PChannelModel *my_model, Double_t my_y_max);
    PAdaptiveMeshN();
    void SetDefaults(UInt_t my_pattern, Int_t my_max_dimensions, 
		     PChannelModel *my_model, Double_t my_y_max);
    void ReCalcYMax(void);
    ~PAdaptiveMeshN();

    void SetRange (Int_t dimension, Double_t my_x_min,  Double_t my_x_max) {
	x_min[dimension] = my_x_min;
	x_max[dimension] = my_x_max;
    };

    Bool_t GetRandom();

    Double_t GetArea() {return area_size;};
    
    Double_t GetArrayValue(Int_t dimension)  {
	if (dimension > num_dimensions) {
	    Warning("GetArrayValue", "dimension>num_dimensions");
	    return 0;
	}
	return array[dimension];
    };

    Double_t GetXMax(Int_t dimension)  {
	// method should be fast. I do not make any test here!
	return x_max[dimension];
    };

    Double_t GetXMin(Int_t dimension) {
	// method should be fast. I do not make any test here!
	return x_min[dimension];
    };

    Double_t GetYMax() {
	return y_max;
    };

    void SetYMax(Double_t  d) {y_max = d;};

    void SetMCPoints(Int_t n) {mcpoints = n;};
    
    void SetThreshold(Double_t diff, Double_t abs) {
	threshold_diff = diff;
	threshold_abs  = abs;
    };

    void Divide(Int_t num, Int_t my_layer);

    //void Draw(const Option_t *delme=NULL);

    void PrintMesh(void);

    ClassDef(PAdaptiveMeshN, 0)  // Envelope with adaptable size of the bins (N dimensions)
};

#endif
 PAdaptiveMeshN.h:1
 PAdaptiveMeshN.h:2
 PAdaptiveMeshN.h:3
 PAdaptiveMeshN.h:4
 PAdaptiveMeshN.h:5
 PAdaptiveMeshN.h:6
 PAdaptiveMeshN.h:7
 PAdaptiveMeshN.h:8
 PAdaptiveMeshN.h:9
 PAdaptiveMeshN.h:10
 PAdaptiveMeshN.h:11
 PAdaptiveMeshN.h:12
 PAdaptiveMeshN.h:13
 PAdaptiveMeshN.h:14
 PAdaptiveMeshN.h:15
 PAdaptiveMeshN.h:16
 PAdaptiveMeshN.h:17
 PAdaptiveMeshN.h:18
 PAdaptiveMeshN.h:19
 PAdaptiveMeshN.h:20
 PAdaptiveMeshN.h:21
 PAdaptiveMeshN.h:22
 PAdaptiveMeshN.h:23
 PAdaptiveMeshN.h:24
 PAdaptiveMeshN.h:25
 PAdaptiveMeshN.h:26
 PAdaptiveMeshN.h:27
 PAdaptiveMeshN.h:28
 PAdaptiveMeshN.h:29
 PAdaptiveMeshN.h:30
 PAdaptiveMeshN.h:31
 PAdaptiveMeshN.h:32
 PAdaptiveMeshN.h:33
 PAdaptiveMeshN.h:34
 PAdaptiveMeshN.h:35
 PAdaptiveMeshN.h:36
 PAdaptiveMeshN.h:37
 PAdaptiveMeshN.h:38
 PAdaptiveMeshN.h:39
 PAdaptiveMeshN.h:40
 PAdaptiveMeshN.h:41
 PAdaptiveMeshN.h:42
 PAdaptiveMeshN.h:43
 PAdaptiveMeshN.h:44
 PAdaptiveMeshN.h:45
 PAdaptiveMeshN.h:46
 PAdaptiveMeshN.h:47
 PAdaptiveMeshN.h:48
 PAdaptiveMeshN.h:49
 PAdaptiveMeshN.h:50
 PAdaptiveMeshN.h:51
 PAdaptiveMeshN.h:52
 PAdaptiveMeshN.h:53
 PAdaptiveMeshN.h:54
 PAdaptiveMeshN.h:55
 PAdaptiveMeshN.h:56
 PAdaptiveMeshN.h:57
 PAdaptiveMeshN.h:58
 PAdaptiveMeshN.h:59
 PAdaptiveMeshN.h:60
 PAdaptiveMeshN.h:61
 PAdaptiveMeshN.h:62
 PAdaptiveMeshN.h:63
 PAdaptiveMeshN.h:64
 PAdaptiveMeshN.h:65
 PAdaptiveMeshN.h:66
 PAdaptiveMeshN.h:67
 PAdaptiveMeshN.h:68
 PAdaptiveMeshN.h:69
 PAdaptiveMeshN.h:70
 PAdaptiveMeshN.h:71
 PAdaptiveMeshN.h:72
 PAdaptiveMeshN.h:73
 PAdaptiveMeshN.h:74
 PAdaptiveMeshN.h:75
 PAdaptiveMeshN.h:76
 PAdaptiveMeshN.h:77
 PAdaptiveMeshN.h:78
 PAdaptiveMeshN.h:79
 PAdaptiveMeshN.h:80
 PAdaptiveMeshN.h:81
 PAdaptiveMeshN.h:82
 PAdaptiveMeshN.h:83
 PAdaptiveMeshN.h:84
 PAdaptiveMeshN.h:85
 PAdaptiveMeshN.h:86
 PAdaptiveMeshN.h:87
 PAdaptiveMeshN.h:88
 PAdaptiveMeshN.h:89
 PAdaptiveMeshN.h:90
 PAdaptiveMeshN.h:91
 PAdaptiveMeshN.h:92
 PAdaptiveMeshN.h:93
 PAdaptiveMeshN.h:94
 PAdaptiveMeshN.h:95
 PAdaptiveMeshN.h:96
 PAdaptiveMeshN.h:97
 PAdaptiveMeshN.h:98
 PAdaptiveMeshN.h:99
 PAdaptiveMeshN.h:100
 PAdaptiveMeshN.h:101
 PAdaptiveMeshN.h:102
 PAdaptiveMeshN.h:103
 PAdaptiveMeshN.h:104
 PAdaptiveMeshN.h:105