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

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

// Header file for class UnBinData

#ifndef ROOT_Fit_UnBinData
#define ROOT_Fit_UnBinData

#ifndef ROOT_Fit_DataVector
#include "Fit/DataVector.h"
#endif

#ifndef ROOT_Math_Error
#include "Math/Error.h"
#endif



namespace ROOT {

   namespace Fit {


//___________________________________________________________________________________
/**
   Class describing the unbinned data sets (just x coordinates values) of any dimensions

              There is the option to construct UnBindata copying the data in (using the DataVector class)
              or using pointer to external data (DataWrapper) class.
              In general is found to be more efficient to copy the data.
              In case of really large data sets for limiting memory consumption then the other option can be used
              Specialized constructor exists for using external data up to 3 dimensions.

              When the data are copying in the number of points can be set later (or re-set) using Initialize and
              the data are inserted one by one using the Add method.
              It is mandatory to set the size before using the Add method.

             @ingroup  FitData
*/
class UnBinData : public FitData {

public :

   /**
      constructor from dimension of point  and max number of points (to pre-allocate vector)
    */

   explicit UnBinData(unsigned int maxpoints = 0, unsigned int dim = 1, bool isWeighted = false );


   /**
      constructor from range and default option
    */
   explicit UnBinData (const DataRange & range,  unsigned int maxpoints = 0, unsigned int dim = 1, bool isWeighted = false);

   /**
      constructor from options and range
    */
   UnBinData (const DataOptions & opt, const DataRange & range,  unsigned int maxpoints = 0, unsigned int dim = 1,  bool isWeighted = false );

   /**
      constructor for 1D external data (data are not copied inside)
    */
   UnBinData(unsigned int n, const double * dataX );

   /**
      constructor for 2D external data (data are not copied inside)
      or 1D data with a weight (if isWeighted = true)
    */
   UnBinData(unsigned int n, const double * dataX, const double * dataY, bool isWeighted = false );

   /**
      constructor for 3D external data (data are not copied inside)
      or 2D data with a weight (if isWeighted = true)
    */
   UnBinData(unsigned int n, const double * dataX, const double * dataY, const double * dataZ, bool isWeighted = false );

   /**
      constructor for multi-dim external data (data are not copied inside)
      Uses as argument an iterator of a list (or vector) containing the const double * of the data
      An example could be the std::vector<const double *>::begin
      In case of weighted data, the external data must have a dim+1 lists of data
      The apssed dim refers just to the coordinate size
    */
   template<class Iterator>
   UnBinData(unsigned int n, unsigned int dim, Iterator dataItr, bool isWeighted = false ) :
      FitData( ),
      fDim(dim),
      fPointSize( (isWeighted) ? dim +1 : dim),
      fNPoints(n),
      fDataVector(0)
   {
      fDataWrapper = new DataWrapper(fPointSize, dataItr);
   }

   /**
      constructor for 1D data and a range (data are copied inside according to the given range)
    */
   UnBinData(unsigned int maxpoints, const double * dataX, const DataRange & range);

   /**
      constructor for 2D data and a range (data are copied inside according to the given range)
      or 1 1D data set + weight. If is weighted  dataY is the pointer to the list of the weights
    */
   UnBinData(unsigned int maxpoints, const double * dataX, const double * dataY, const DataRange & range, bool isWeighted = false);

   /**
      constructor for 3D data and a range (data are copied inside according to the given range)
      or a 2D data set + weights. If is weighted  dataZ is the pointer to the list of the weights
    */
   UnBinData(unsigned int maxpoints, const double * dataX, const double * dataY, const double * dataZ, const DataRange & range, bool isWeighted = false);

   /**
      constructor for multi-dim external data and a range (data are copied inside according to the range)
      Uses as argument an iterator of a list (or vector) containing the const double * of the data
      An example could be the std::vector<const double *>::begin
    */
   template<class Iterator>
   UnBinData(unsigned int maxpoints, unsigned int dim, Iterator dataItr, const DataRange & range, bool isWeighted = false ) :
      FitData( ),
      fDim(dim),
      fPointSize( (isWeighted) ? dim +1 : dim),
      fNPoints(0),
      fDataVector(0),
      fDataWrapper(0)
   {
      unsigned int n = fPointSize*maxpoints;
      if ( n > MaxSize() ) {
         MATH_ERROR_MSGVAL("UnBinData","Invalid data size n - no allocation done", n );
      }
      else if (n > 0) {
         fDataVector = new DataVector(n);

         // use data wrapper to get the data
         ROOT::Fit::DataWrapper wdata(fPointSize, dataItr);
         for (unsigned int i = 0; i < maxpoints; ++i) {
            bool isInside = true;
            for (unsigned int icoord = 0; icoord < dim; ++icoord)
               isInside &= range.IsInside( wdata.Coords(i)[icoord], icoord );
            // treat here the weight as an extra coordinate
            if ( isInside ) Add(wdata.Coords(i));
         }
         if (fNPoints < maxpoints) (fDataVector->Data()).resize(fPointSize*fNPoints);
      }
   }


private:
   /// copy constructor (private)
   UnBinData(const UnBinData &) : FitData() {}
   /// assignment operator  (private)
   UnBinData & operator= (const UnBinData &) { return *this; }

public:

#ifdef LATER
   /**
      Create from a compatible UnBinData set
    */

   UnBinData (const UnBinData & data , const DataOptions & opt, const DataRange & range) :
      DataVector(opt,range, data.DataSize() ),
      fDim(data.fDim),
      fPointSize(data.fPointSize),
      fNPoints(data.fNPoints)
   {
//       for (Iterator itr = begin; itr != end; ++itr)
//          if (itr->IsInRange(range) )
//             Add(*itr);
   }
#endif

   /**
      destructor, delete pointer to internal data or external data wrapper
    */
   virtual ~UnBinData() {
      if (fDataVector) delete fDataVector;
      if (fDataWrapper) delete fDataWrapper;
   }

   /**
      preallocate a data set given size and dimension of the coordinates
      if a vector already exists with correct dimension (point size) extend the existing one
      to a total size of maxpoints (equivalent to a Resize)
    */
   void Initialize(unsigned int maxpoints, unsigned int dim = 1, bool isWeighted = false);


   /**
      add one dim coordinate data (unweighted)
   */
   void Add(double x) {
      int index = fNPoints*PointSize();
      assert(fDataVector != 0);
      assert(PointSize() == 1);
      assert (index + PointSize() <= DataSize() );

      (fDataVector->Data())[ index ] = x;

      fNPoints++;
   }


   /**
      add 2-dim coordinate data
      can also be used to add 1-dim data with a weight
   */
   void Add(double x, double y) {
      int index = fNPoints*PointSize();
      assert(fDataVector != 0);
      assert(PointSize() == 2);
      assert (index + PointSize() <= DataSize() );

      (fDataVector->Data())[ index ] = x;
      (fDataVector->Data())[ index+1 ] = y;

      fNPoints++;
   }

   /**
      add 3-dim coordinate data
      can also be used to add 2-dim data with a weight
   */
   void Add(double x, double y, double z) {
      int index = fNPoints*PointSize();
      assert(fDataVector != 0);
      assert(PointSize() == 3);
      assert (index + PointSize() <= DataSize() );

      (fDataVector->Data())[ index ] = x;
      (fDataVector->Data())[ index+1 ] = y;
      (fDataVector->Data())[ index+2 ] = z;

      fNPoints++;
   }

   /**
      add multi-dim coordinate data
   */
   void Add(const double *x) {
      int index = fNPoints*fPointSize;

      assert(fDataVector != 0);
      assert (index + PointSize() <= DataSize() );

      double * itr = &( (fDataVector->Data()) [ index ]);

      for (unsigned int i = 0; i < fDim; ++i)
         *itr++ = x[i];

      fNPoints++;
   }

   /**
      add multi-dim coordinate data + weight
   */
   void Add(const double *x, double w) {
      int index = fNPoints*fPointSize;

      assert(fDataVector != 0);
      assert (index + PointSize() <= DataSize() );

      double * itr = &( (fDataVector->Data()) [ index ]);

      for (unsigned int i = 0; i < fDim; ++i)
         *itr++ = x[i];
      *itr = w;

      fNPoints++;
   }

   /**
      return pointer to coordinate data
    */
   const double * Coords(unsigned int ipoint) const {
      if (fDataVector)
         return &( (fDataVector->Data()) [ ipoint*fPointSize ] );
      else
         return fDataWrapper->Coords(ipoint);
   }

   bool IsWeighted() const {
      return (fPointSize == fDim+1);
   }

   double Weight(unsigned int ipoint) const {
      if (fPointSize == fDim) return 1;
      if (fDataVector )
         return  (fDataVector->Data()) [ ipoint*fPointSize + 1 ] ;
      else
         return 0; // weights are not supported for wrapper data sets
   }


   /**
      resize the vector to the given npoints
    */
   void Resize (unsigned int npoints);


   /**
      return number of contained points
    */
   unsigned int NPoints() const { return fNPoints; }

   /**
      return number of contained points
    */
   unsigned int Size() const { return fNPoints; }

   /**
      return coordinate data dimension
    */
   unsigned int NDim() const { return fDim; }

   /**
      return  point size. For unweighted data is equivalent to coordinate dimension,
      for weighted data is NDim()+1
    */
   unsigned int PointSize() const {
      return fPointSize;
   }

   /**
      return size of internal data vector (is 0 for external data)
    */
   unsigned int DataSize() const {
      return (fDataVector) ? fDataVector->Size() : 0;
   }


protected:

   void SetNPoints(unsigned int n) { fNPoints = n; }

private:

   unsigned int fDim;         // coordinate data dimension
   unsigned int fPointSize;    // poit size dimension (coordinate + weight)
   unsigned int fNPoints;     // numer of fit points

   DataVector * fDataVector;     // pointer to internal data vector (null for external data)
   DataWrapper * fDataWrapper;   // pointer to structure wrapping external data (null when data are copied in)

};


   } // end namespace Fit

} // end namespace ROOT



#endif /* ROOT_Fit_UnBinData */
 UnBinData.h:1
 UnBinData.h:2
 UnBinData.h:3
 UnBinData.h:4
 UnBinData.h:5
 UnBinData.h:6
 UnBinData.h:7
 UnBinData.h:8
 UnBinData.h:9
 UnBinData.h:10
 UnBinData.h:11
 UnBinData.h:12
 UnBinData.h:13
 UnBinData.h:14
 UnBinData.h:15
 UnBinData.h:16
 UnBinData.h:17
 UnBinData.h:18
 UnBinData.h:19
 UnBinData.h:20
 UnBinData.h:21
 UnBinData.h:22
 UnBinData.h:23
 UnBinData.h:24
 UnBinData.h:25
 UnBinData.h:26
 UnBinData.h:27
 UnBinData.h:28
 UnBinData.h:29
 UnBinData.h:30
 UnBinData.h:31
 UnBinData.h:32
 UnBinData.h:33
 UnBinData.h:34
 UnBinData.h:35
 UnBinData.h:36
 UnBinData.h:37
 UnBinData.h:38
 UnBinData.h:39
 UnBinData.h:40
 UnBinData.h:41
 UnBinData.h:42
 UnBinData.h:43
 UnBinData.h:44
 UnBinData.h:45
 UnBinData.h:46
 UnBinData.h:47
 UnBinData.h:48
 UnBinData.h:49
 UnBinData.h:50
 UnBinData.h:51
 UnBinData.h:52
 UnBinData.h:53
 UnBinData.h:54
 UnBinData.h:55
 UnBinData.h:56
 UnBinData.h:57
 UnBinData.h:58
 UnBinData.h:59
 UnBinData.h:60
 UnBinData.h:61
 UnBinData.h:62
 UnBinData.h:63
 UnBinData.h:64
 UnBinData.h:65
 UnBinData.h:66
 UnBinData.h:67
 UnBinData.h:68
 UnBinData.h:69
 UnBinData.h:70
 UnBinData.h:71
 UnBinData.h:72
 UnBinData.h:73
 UnBinData.h:74
 UnBinData.h:75
 UnBinData.h:76
 UnBinData.h:77
 UnBinData.h:78
 UnBinData.h:79
 UnBinData.h:80
 UnBinData.h:81
 UnBinData.h:82
 UnBinData.h:83
 UnBinData.h:84
 UnBinData.h:85
 UnBinData.h:86
 UnBinData.h:87
 UnBinData.h:88
 UnBinData.h:89
 UnBinData.h:90
 UnBinData.h:91
 UnBinData.h:92
 UnBinData.h:93
 UnBinData.h:94
 UnBinData.h:95
 UnBinData.h:96
 UnBinData.h:97
 UnBinData.h:98
 UnBinData.h:99
 UnBinData.h:100
 UnBinData.h:101
 UnBinData.h:102
 UnBinData.h:103
 UnBinData.h:104
 UnBinData.h:105
 UnBinData.h:106
 UnBinData.h:107
 UnBinData.h:108
 UnBinData.h:109
 UnBinData.h:110
 UnBinData.h:111
 UnBinData.h:112
 UnBinData.h:113
 UnBinData.h:114
 UnBinData.h:115
 UnBinData.h:116
 UnBinData.h:117
 UnBinData.h:118
 UnBinData.h:119
 UnBinData.h:120
 UnBinData.h:121
 UnBinData.h:122
 UnBinData.h:123
 UnBinData.h:124
 UnBinData.h:125
 UnBinData.h:126
 UnBinData.h:127
 UnBinData.h:128
 UnBinData.h:129
 UnBinData.h:130
 UnBinData.h:131
 UnBinData.h:132
 UnBinData.h:133
 UnBinData.h:134
 UnBinData.h:135
 UnBinData.h:136
 UnBinData.h:137
 UnBinData.h:138
 UnBinData.h:139
 UnBinData.h:140
 UnBinData.h:141
 UnBinData.h:142
 UnBinData.h:143
 UnBinData.h:144
 UnBinData.h:145
 UnBinData.h:146
 UnBinData.h:147
 UnBinData.h:148
 UnBinData.h:149
 UnBinData.h:150
 UnBinData.h:151
 UnBinData.h:152
 UnBinData.h:153
 UnBinData.h:154
 UnBinData.h:155
 UnBinData.h:156
 UnBinData.h:157
 UnBinData.h:158
 UnBinData.h:159
 UnBinData.h:160
 UnBinData.h:161
 UnBinData.h:162
 UnBinData.h:163
 UnBinData.h:164
 UnBinData.h:165
 UnBinData.h:166
 UnBinData.h:167
 UnBinData.h:168
 UnBinData.h:169
 UnBinData.h:170
 UnBinData.h:171
 UnBinData.h:172
 UnBinData.h:173
 UnBinData.h:174
 UnBinData.h:175
 UnBinData.h:176
 UnBinData.h:177
 UnBinData.h:178
 UnBinData.h:179
 UnBinData.h:180
 UnBinData.h:181
 UnBinData.h:182
 UnBinData.h:183
 UnBinData.h:184
 UnBinData.h:185
 UnBinData.h:186
 UnBinData.h:187
 UnBinData.h:188
 UnBinData.h:189
 UnBinData.h:190
 UnBinData.h:191
 UnBinData.h:192
 UnBinData.h:193
 UnBinData.h:194
 UnBinData.h:195
 UnBinData.h:196
 UnBinData.h:197
 UnBinData.h:198
 UnBinData.h:199
 UnBinData.h:200
 UnBinData.h:201
 UnBinData.h:202
 UnBinData.h:203
 UnBinData.h:204
 UnBinData.h:205
 UnBinData.h:206
 UnBinData.h:207
 UnBinData.h:208
 UnBinData.h:209
 UnBinData.h:210
 UnBinData.h:211
 UnBinData.h:212
 UnBinData.h:213
 UnBinData.h:214
 UnBinData.h:215
 UnBinData.h:216
 UnBinData.h:217
 UnBinData.h:218
 UnBinData.h:219
 UnBinData.h:220
 UnBinData.h:221
 UnBinData.h:222
 UnBinData.h:223
 UnBinData.h:224
 UnBinData.h:225
 UnBinData.h:226
 UnBinData.h:227
 UnBinData.h:228
 UnBinData.h:229
 UnBinData.h:230
 UnBinData.h:231
 UnBinData.h:232
 UnBinData.h:233
 UnBinData.h:234
 UnBinData.h:235
 UnBinData.h:236
 UnBinData.h:237
 UnBinData.h:238
 UnBinData.h:239
 UnBinData.h:240
 UnBinData.h:241
 UnBinData.h:242
 UnBinData.h:243
 UnBinData.h:244
 UnBinData.h:245
 UnBinData.h:246
 UnBinData.h:247
 UnBinData.h:248
 UnBinData.h:249
 UnBinData.h:250
 UnBinData.h:251
 UnBinData.h:252
 UnBinData.h:253
 UnBinData.h:254
 UnBinData.h:255
 UnBinData.h:256
 UnBinData.h:257
 UnBinData.h:258
 UnBinData.h:259
 UnBinData.h:260
 UnBinData.h:261
 UnBinData.h:262
 UnBinData.h:263
 UnBinData.h:264
 UnBinData.h:265
 UnBinData.h:266
 UnBinData.h:267
 UnBinData.h:268
 UnBinData.h:269
 UnBinData.h:270
 UnBinData.h:271
 UnBinData.h:272
 UnBinData.h:273
 UnBinData.h:274
 UnBinData.h:275
 UnBinData.h:276
 UnBinData.h:277
 UnBinData.h:278
 UnBinData.h:279
 UnBinData.h:280
 UnBinData.h:281
 UnBinData.h:282
 UnBinData.h:283
 UnBinData.h:284
 UnBinData.h:285
 UnBinData.h:286
 UnBinData.h:287
 UnBinData.h:288
 UnBinData.h:289
 UnBinData.h:290
 UnBinData.h:291
 UnBinData.h:292
 UnBinData.h:293
 UnBinData.h:294
 UnBinData.h:295
 UnBinData.h:296
 UnBinData.h:297
 UnBinData.h:298
 UnBinData.h:299
 UnBinData.h:300
 UnBinData.h:301
 UnBinData.h:302
 UnBinData.h:303
 UnBinData.h:304
 UnBinData.h:305
 UnBinData.h:306
 UnBinData.h:307
 UnBinData.h:308
 UnBinData.h:309
 UnBinData.h:310
 UnBinData.h:311
 UnBinData.h:312
 UnBinData.h:313
 UnBinData.h:314
 UnBinData.h:315
 UnBinData.h:316
 UnBinData.h:317
 UnBinData.h:318
 UnBinData.h:319
 UnBinData.h:320
 UnBinData.h:321
 UnBinData.h:322
 UnBinData.h:323
 UnBinData.h:324
 UnBinData.h:325
 UnBinData.h:326
 UnBinData.h:327
 UnBinData.h:328
 UnBinData.h:329
 UnBinData.h:330
 UnBinData.h:331
 UnBinData.h:332
 UnBinData.h:333
 UnBinData.h:334
 UnBinData.h:335
 UnBinData.h:336
 UnBinData.h:337
 UnBinData.h:338
 UnBinData.h:339
 UnBinData.h:340
 UnBinData.h:341
 UnBinData.h:342
 UnBinData.h:343
 UnBinData.h:344
 UnBinData.h:345
 UnBinData.h:346
 UnBinData.h:347
 UnBinData.h:348
 UnBinData.h:349
 UnBinData.h:350
 UnBinData.h:351
 UnBinData.h:352
 UnBinData.h:353
 UnBinData.h:354
 UnBinData.h:355
 UnBinData.h:356
 UnBinData.h:357
 UnBinData.h:358
 UnBinData.h:359
 UnBinData.h:360
 UnBinData.h:361