// @(#)root/mathcore:$Id$
// Author: L. Moneta Wed Aug 30 11:05:02 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Header file for class DataRange

#ifndef ROOT_Fit_DataRange
#define ROOT_Fit_DataRange

#include <vector>

namespace ROOT {

   namespace Fit {


//___________________________________________________________________________________
/**
   class describing the range in the coordinates
   it supports  multiple range in a coordinate.
   The rnage dimension is the dimension of the coordinate, its size is
   the number of interval for each coordinate.
   Default range is -inf, inf
   Range can be modified with the add range method

   @ingroup FitData
*/
class DataRange {

public:

   typedef std::vector<std::pair<double,double> > RangeSet;
   typedef std::vector< RangeSet >   RangeIntervals;

   /**
      Default constructor (infinite range)
   */
   explicit DataRange (unsigned int dim = 1) :
      fRanges ( std::vector<RangeSet> (dim) )
   {}

   /**
      construct a range for [xmin, xmax]
    */
   DataRange(double xmin, double xmax);

   /**
      construct a range for [xmin, xmax] , [ymin, ymax]
    */
   DataRange(double xmin, double xmax, double ymin, double ymax);
   /**
      construct a range for [xmin, xmax] , [ymin, ymax] , [zmin, zmax]
    */
   DataRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax);
   /**
      get range dimension
    */
   unsigned int NDim() const { return fRanges.size(); }

   /**
      return range size for coordinate icoord (starts from zero)
      Size == 0 indicates no range is present [-inf, + inf]
   */
   unsigned int Size(unsigned int icoord = 0) const {
      return icoord <  fRanges.size() ? fRanges[icoord].size() : 0;
   }

   /**
      return true if a range has been set in any of  the coordinates
      i.e. when  it is not [-inf,+inf] for all coordinates
      Avoid in case of multi-dim to loop on all the coordinated and ask the size
    */
   bool IsSet() const {
      for (unsigned int icoord = 0; icoord < fRanges.size(); ++icoord)
         if (fRanges[icoord].size() > 0) return true;
      return false;
   }

   /**
       return the vector of ranges for the coordinate icoord
   */
   const RangeSet & Ranges(unsigned int icoord = 0) const {
      // return icoord <  fRanges.size() ? fRanges[icoord] : RangeSet();
      return fRanges.at(icoord);
   }

   /**
       return the i-th range for the coordinate icoord.
       Useful method when only one range is present for the given coordinate
   */
   std::pair<double, double> operator() (unsigned int icoord = 0,unsigned int irange = 0) const;

   /**
      get the first range for given coordinate. If range does not exist
      return -inf, +inf
    */
   void GetRange(unsigned int icoord, double & xmin, double & xmax) const {
      if (Size(icoord) == 0) GetInfRange(xmin,xmax);
      else {
         xmin = fRanges[icoord].front().first;
         xmax = fRanges[icoord].front().second;
      }
   }
   /**
      get first range for the x - coordinate
    */
   void GetRange(double & xmin, double & xmax) const {  GetRange(0,xmin,xmax); }
   /**
      get first range for the x and y coordinates
    */
   void GetRange(double & xmin, double & xmax, double & ymin, double & ymax) const {
      GetRange(0,xmin,xmax); GetRange(1,ymin,ymax);
   }
   /**
      get first range for the x and y and z coordinates
    */
   void GetRange(double & xmin, double & xmax, double & ymin, double & ymax, double & zmin, double & zmax) const {
      GetRange(0,xmin,xmax); GetRange(1,ymin,ymax); GetRange(2,zmin,zmax);
   }
   /**
      get first range for coordinates and fill the vector
    */
   void GetRange(double * xmin, double * xmax)   const {
      for (unsigned int i = 0; i < fRanges.size(); ++i)
         GetRange(i,xmin[i],xmax[i]);
   }

   /**
      Destructor (no operations)
   */
   ~DataRange ()  {}



   /**
      add a range [xmin,xmax] for the new coordinate icoord
      Adding a range does not delete existing one, but takes the OR with
      existing ranges.
      if want to replace range use method SetRange, which replace range with existing one
    */
   void AddRange(unsigned  int  icoord , double xmin, double xmax );

   /**
      add a range [xmin,xmax] for the first coordinate icoord
    */
   void AddRange(double xmin, double xmax ) { AddRange(0,xmin,xmax); }
   /**
      add a range [xmin,xmax] for the first and [ymin,ymax] for the second coordinate
    */
   void AddRange(double xmin, double xmax, double ymin, double ymax ) { AddRange(0,xmin,xmax); AddRange(1,ymin,ymax); }
   /**
      add a range [xmin,xmax] for the first and [ymin,ymax] for the second coordinate and
      [zmin,zmax] for the third coordinate
    */
   void AddRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax ) {
      AddRange(0,xmin,xmax); AddRange(1,ymin,ymax); AddRange(2,zmin,zmax); }

   /**
      set a range [xmin,xmax] for the new coordinate icoord
      If more range exists for other coordinates, delete the existing one and use it the new one
      Use Add range if want to keep the union of the existing ranges
    */
   void SetRange(unsigned  int  icoord , double xmin, double xmax );

   /**
      set a range [xmin,xmax] for the first coordinate icoord
    */
   void SetRange(double xmin, double xmax ) { SetRange(0,xmin,xmax); }
   /**
      set a range [xmin,xmax] for the first and [ymin,ymax] for the second coordinate
    */
   void SetRange(double xmin, double xmax, double ymin, double ymax ) { SetRange(0,xmin,xmax); SetRange(1,ymin,ymax); }
   /**
      set a range [xmin,xmax] for the first and [ymin,ymax] for the second coordinate and
      [zmin,zmax] for the third coordinate
    */
   void SetRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax ) {
      SetRange(0,xmin,xmax); SetRange(1,ymin,ymax); SetRange(2,zmin,zmax); }

   /**
      clear all ranges in one coordinate (is now -inf, +inf)
    */
   void Clear (unsigned  int  icoord = 0 );

   /**
      check if a point is inside the range for the given coordinate
    */
   bool IsInside(double x, unsigned int icoord = 0) const;

protected:
   /**
       internal function to remove all the existing ranges between xmin and xmax
       called when a new range is inserted
   */
   void CleanRangeSet(unsigned int icoord, double xmin, double xmax);

   // get the full range (-inf, +inf)
   static void GetInfRange(double &x1, double &x2);

private:

   RangeIntervals fRanges;  // list of all ranges


};

   } // end namespace Fit

} // end namespace ROOT


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