00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Fit/BinData.h"
00014 #include "Math/Error.h"
00015
00016 #include <cassert>
00017 #include <cmath>
00018
00019 namespace ROOT {
00020
00021 namespace Fit {
00022
00023
00024
00025
00026 BinData::BinData(unsigned int maxpoints , unsigned int dim , ErrorType err ) :
00027
00028
00029 FitData(),
00030 fDim(dim),
00031 fPointSize(GetPointSize(err,dim) ),
00032 fNPoints(0),
00033 fRefVolume(1.0),
00034 fDataVector(0),
00035 fDataWrapper(0)
00036 {
00037 unsigned int n = fPointSize*maxpoints;
00038 if ( n > MaxSize() )
00039 MATH_ERROR_MSGVAL("BinData","Invalid data size n - no allocation done", n )
00040 else if (n > 0)
00041 fDataVector = new DataVector(n);
00042 }
00043
00044 BinData::BinData (const DataOptions & opt, unsigned int maxpoints, unsigned int dim, ErrorType err ) :
00045
00046
00047 FitData(opt),
00048 fDim(dim),
00049 fPointSize(GetPointSize(err,dim) ),
00050 fNPoints(0),
00051 fRefVolume(1.0),
00052 fDataVector(0),
00053 fDataWrapper(0)
00054 {
00055 unsigned int n = fPointSize*maxpoints;
00056 if ( n > MaxSize() )
00057 MATH_ERROR_MSGVAL("BinData","Invalid data size n - no allocation done", n )
00058 else if (n > 0)
00059 fDataVector = new DataVector(n);
00060 }
00061
00062
00063
00064 BinData::BinData (const DataOptions & opt, const DataRange & range, unsigned int maxpoints , unsigned int dim , ErrorType err ) :
00065
00066
00067
00068
00069 FitData(opt,range),
00070 fDim(dim),
00071 fPointSize(GetPointSize(err,dim) ),
00072 fNPoints(0),
00073 fRefVolume(1.0),
00074 fDataVector(0),
00075 fDataWrapper(0)
00076 {
00077 unsigned int n = fPointSize*maxpoints;
00078 if ( n > MaxSize() )
00079 MATH_ERROR_MSGVAL("BinData","Invalid data size n - no allocation done", n )
00080 else if (n > 0)
00081 fDataVector = new DataVector(n);
00082 }
00083
00084
00085
00086
00087
00088 BinData::BinData(unsigned int n, const double * dataX, const double * val, const double * ex , const double * eval ) :
00089
00090 fDim(1),
00091 fPointSize(2),
00092 fNPoints(n),
00093 fRefVolume(1.0),
00094 fDataVector(0)
00095 {
00096 if (eval != 0) {
00097 fPointSize++;
00098 if (ex != 0) fPointSize++;
00099 }
00100 fDataWrapper = new DataWrapper(dataX, val, eval, ex);
00101 }
00102
00103
00104
00105
00106
00107 BinData::BinData(unsigned int n, const double * dataX, const double * dataY, const double * val, const double * ex , const double * ey, const double * eval ) :
00108
00109 fDim(2),
00110 fPointSize(3),
00111 fNPoints(n),
00112 fRefVolume(1.0),
00113 fDataVector(0)
00114 {
00115 if (eval != 0) {
00116 fPointSize++;
00117 if (ex != 0 && ey != 0 ) fPointSize += 2;
00118 }
00119 fDataWrapper = new DataWrapper(dataX, dataY, val, eval, ex, ey);
00120 }
00121
00122
00123
00124 BinData::BinData(unsigned int n, const double * dataX, const double * dataY, const double * dataZ, const double * val, const double * ex , const double * ey , const double * ez , const double * eval ) :
00125
00126 fDim(3),
00127 fPointSize(4),
00128 fNPoints(n),
00129 fRefVolume(1.0),
00130 fDataVector(0)
00131 {
00132 if (eval != 0) {
00133 fPointSize++;
00134 if (ex != 0 && ey != 0 && ez != 0) fPointSize += 3;
00135 }
00136 fDataWrapper = new DataWrapper(dataX, dataY, dataZ, val, eval, ex, ey, ez);
00137 }
00138
00139
00140
00141 BinData::BinData(const BinData & rhs) :
00142 FitData(),
00143 fDim(rhs.fDim),
00144 fPointSize(rhs.fPointSize),
00145 fNPoints(rhs.fNPoints),
00146 fRefVolume(1.0),
00147 fDataVector(0),
00148 fDataWrapper(0),
00149 fBinEdge(rhs.fBinEdge)
00150 {
00151
00152 if (rhs.fDataVector != 0) fDataVector = new DataVector(*rhs.fDataVector);
00153 else if (rhs.fDataWrapper != 0) fDataWrapper = new DataWrapper(*rhs.fDataWrapper);
00154 }
00155
00156
00157 BinData & BinData::operator= (const BinData & rhs) {
00158
00159 if (&rhs == this) return *this;
00160 fDim = rhs.fDim;
00161 fPointSize = rhs.fPointSize;
00162 fNPoints = rhs.fNPoints;
00163 fBinEdge = rhs.fBinEdge;
00164 fRefVolume = rhs.fRefVolume;
00165
00166 if (fDataVector) delete fDataVector;
00167 if (fDataWrapper) delete fDataWrapper;
00168 if (rhs.fDataVector != 0)
00169 fDataVector = new DataVector(*rhs.fDataVector);
00170 else
00171 fDataVector = 0;
00172 if (rhs.fDataWrapper != 0)
00173 fDataWrapper = new DataWrapper(*rhs.fDataWrapper);
00174 else
00175 fDataWrapper = 0;
00176
00177 return *this;
00178 }
00179
00180
00181
00182 BinData::~BinData() {
00183
00184 if (fDataVector) delete fDataVector;
00185 if (fDataWrapper) delete fDataWrapper;
00186 }
00187
00188 void BinData::Initialize(unsigned int maxpoints, unsigned int dim , ErrorType err ) {
00189
00190
00191 if (fDataWrapper) delete fDataWrapper;
00192 fDataWrapper = 0;
00193 unsigned int pointSize = GetPointSize(err,dim);
00194 if ( pointSize != fPointSize && fDataVector) {
00195
00196
00197 delete fDataVector;
00198 fDataVector = 0;
00199 }
00200 fPointSize = pointSize;
00201 fDim = dim;
00202 unsigned int n = fPointSize*maxpoints;
00203 if ( n > MaxSize() ) {
00204 MATH_ERROR_MSGVAL("BinData::Initialize"," Invalid data size ", n );
00205 return;
00206 }
00207 if (fDataVector) {
00208
00209 (fDataVector->Data()).resize( fDataVector->Size() + n);
00210 }
00211 else {
00212 fDataVector = new DataVector(n);
00213 }
00214
00215 if (Opt().fIntegral) fBinEdge.reserve( maxpoints * fDim);
00216 }
00217
00218 void BinData::Resize(unsigned int npoints) {
00219
00220 if (fPointSize == 0) return;
00221 if ( npoints > MaxSize() ) {
00222 MATH_ERROR_MSGVAL("BinData::Resize"," Invalid data size ", npoints );
00223 return;
00224 }
00225 int nextraPoints = npoints - DataSize()/ fPointSize;
00226 if (nextraPoints == 0) return;
00227 else if (nextraPoints < 0) {
00228
00229 if (!fDataVector) return;
00230 (fDataVector->Data()).resize( npoints * fPointSize);
00231 }
00232 else
00233 Initialize(nextraPoints, fDim, GetErrorType() );
00234 }
00235
00236
00237 void BinData::Add(double x, double y ) {
00238
00239 int index = fNPoints*PointSize();
00240 assert (fDataVector != 0);
00241 assert (PointSize() == 2 );
00242 assert (index + PointSize() <= DataSize() );
00243
00244 double * itr = &((fDataVector->Data())[ index ]);
00245 *itr++ = x;
00246 *itr++ = y;
00247
00248 fNPoints++;
00249 }
00250
00251
00252
00253 void BinData::Add(double x, double y, double ey) {
00254
00255
00256 int index = fNPoints*PointSize();
00257
00258 assert( fDim == 1);
00259 assert (fDataVector != 0);
00260 assert (PointSize() == 3 );
00261 assert (index + PointSize() <= DataSize() );
00262
00263 double * itr = &((fDataVector->Data())[ index ]);
00264 *itr++ = x;
00265 *itr++ = y;
00266 *itr++ = (ey!= 0) ? 1.0/ey : 0;
00267
00268 fNPoints++;
00269 }
00270
00271
00272
00273 void BinData::Add(double x, double y, double ex, double ey) {
00274
00275
00276 int index = fNPoints*PointSize();
00277 assert (fDataVector != 0);
00278 assert( fDim == 1);
00279 assert (PointSize() == 4 );
00280 assert (index + PointSize() <= DataSize() );
00281
00282 double * itr = &((fDataVector->Data())[ index ]);
00283 *itr++ = x;
00284 *itr++ = y;
00285 *itr++ = ex;
00286 *itr++ = ey;
00287
00288 fNPoints++;
00289 }
00290
00291
00292
00293 void BinData::Add(double x, double y, double ex, double eyl , double eyh) {
00294
00295
00296 int index = fNPoints*PointSize();
00297 assert (fDataVector != 0);
00298 assert( fDim == 1);
00299 assert (PointSize() == 5 );
00300 assert (index + PointSize() <= DataSize() );
00301
00302 double * itr = &((fDataVector->Data())[ index ]);
00303 *itr++ = x;
00304 *itr++ = y;
00305 *itr++ = ex;
00306 *itr++ = eyl;
00307 *itr++ = eyh;
00308
00309 fNPoints++;
00310 }
00311
00312
00313
00314
00315 void BinData::Add(const double *x, double val) {
00316
00317 int index = fNPoints*PointSize();
00318 assert (fDataVector != 0);
00319 assert (PointSize() == fDim + 1 );
00320
00321 if (index + PointSize() > DataSize())
00322 MATH_ERROR_MSGVAL("BinData::Add","add a point beyond the data size", DataSize() );
00323
00324 assert (index + PointSize() <= DataSize() );
00325
00326 double * itr = &((fDataVector->Data())[ index ]);
00327
00328 for (unsigned int i = 0; i < fDim; ++i)
00329 *itr++ = x[i];
00330 *itr++ = val;
00331
00332 fNPoints++;
00333 }
00334
00335
00336
00337 void BinData::Add(const double *x, double val, double eval) {
00338
00339 int index = fNPoints*PointSize();
00340 assert (fDataVector != 0);
00341 assert (PointSize() == fDim + 2 );
00342
00343 if (index + PointSize() > DataSize())
00344 MATH_ERROR_MSGVAL("BinData::Add","add a point beyond the data size", DataSize() );
00345
00346 assert (index + PointSize() <= DataSize() );
00347
00348 double * itr = &((fDataVector->Data())[ index ]);
00349
00350 for (unsigned int i = 0; i < fDim; ++i)
00351 *itr++ = x[i];
00352 *itr++ = val;
00353 *itr++ = (eval!= 0) ? 1.0/eval : 0;
00354
00355 fNPoints++;
00356 }
00357
00358
00359
00360
00361 void BinData::Add(const double *x, double val, const double * ex, double eval) {
00362
00363 int index = fNPoints*PointSize();
00364 assert (fDataVector != 0);
00365 assert (PointSize() == 2*fDim + 2 );
00366
00367 if (index + PointSize() > DataSize())
00368 MATH_ERROR_MSGVAL("BinData::Add","add a point beyond the data size", DataSize() );
00369
00370 assert (index + PointSize() <= DataSize() );
00371
00372 double * itr = &((fDataVector->Data())[ index ]);
00373
00374 for (unsigned int i = 0; i < fDim; ++i)
00375 *itr++ = x[i];
00376 *itr++ = val;
00377 for (unsigned int i = 0; i < fDim; ++i)
00378 *itr++ = ex[i];
00379 *itr++ = eval;
00380
00381 fNPoints++;
00382 }
00383
00384
00385
00386 void BinData::Add(const double *x, double val, const double * ex, double elval, double ehval) {
00387
00388 int index = fNPoints*PointSize();
00389 assert (fDataVector != 0);
00390 assert (PointSize() == 2*fDim + 3 );
00391
00392 if (index + PointSize() > DataSize())
00393 MATH_ERROR_MSGVAL("BinData::Add","add a point beyond the data size", DataSize() );
00394
00395 assert (index + PointSize() <= DataSize() );
00396
00397 double * itr = &((fDataVector->Data())[ index ]);
00398
00399 for (unsigned int i = 0; i < fDim; ++i)
00400 *itr++ = x[i];
00401 *itr++ = val;
00402 for (unsigned int i = 0; i < fDim; ++i)
00403 *itr++ = ex[i];
00404 *itr++ = elval;
00405 *itr++ = ehval;
00406
00407 fNPoints++;
00408 }
00409
00410 void BinData::AddBinUpEdge(const double *xup ) {
00411
00412
00413 fBinEdge.insert( fBinEdge.end(), xup, xup + fDim);
00414
00415
00416 assert( fNPoints * fDim == fBinEdge.size() );
00417
00418
00419 const double * xlow = Coords(fNPoints-1);
00420
00421 double binVolume = 1;
00422 for (unsigned int j = 0; j < fDim; ++j) {
00423 binVolume *= (xup[j]-xlow[j]);
00424 }
00425
00426
00427 if (fNPoints == 1) {
00428 fRefVolume = binVolume;
00429 return;
00430 }
00431
00432 if (binVolume < fRefVolume)
00433 fRefVolume = binVolume;
00434
00435 }
00436
00437
00438 BinData & BinData::LogTransform() {
00439
00440
00441 if (fNPoints == 0) return *this;
00442
00443 if (fDataVector) {
00444
00445 ErrorType type = GetErrorType();
00446
00447 std::vector<double> & data = fDataVector->Data();
00448
00449 typedef std::vector<double>::iterator DataItr;
00450 unsigned int ip = 0;
00451 DataItr itr = data.begin();
00452
00453 if (type == kNoError ) {
00454 fPointSize = fDim + 2;
00455 }
00456
00457 while (ip < fNPoints ) {
00458 assert( itr != data.end() );
00459 DataItr valitr = itr + fDim;
00460 double val = *(itr+fDim);
00461 if (val <= 0) {
00462 MATH_ERROR_MSG("BinData::TransformLog","Some points have negative values - cannot apply a log transformation");
00463
00464 Resize(0);
00465 return *this;
00466 }
00467 *(itr+fDim) = std::log(val);
00468
00469 if (type == kNoError ) {
00470
00471 DataItr errpos = data.insert(itr+fDim+1,val);
00472
00473 itr = errpos - fDim -1;
00474
00475 }
00476 else if (type == kValueError) {
00477
00478 *(itr+fDim+1) *= val;
00479 }
00480 else {
00481
00482 for (unsigned int j = fDim + 1; j < fPointSize; ++j)
00483 *(itr+j) /= val;
00484 }
00485 itr += fPointSize;
00486 ip++;
00487 }
00488
00489 return *this;
00490 }
00491
00492 if (fDataWrapper == 0) return *this;
00493
00494
00495 ErrorType type = kValueError;
00496 std::vector<double> errx;
00497 if (fDataWrapper->CoordErrors(0) != 0 ) {
00498 type = kCoordError;
00499 errx.resize(fDim);
00500 }
00501
00502 BinData tmpData(fNPoints, fDim, type);
00503 for (unsigned int i = 0; i < fNPoints; ++i ) {
00504 double val = fDataWrapper->Value(i);
00505 if (val <= 0) {
00506 MATH_ERROR_MSG("BinData::TransformLog","Some points have negative values - cannot apply a log transformation");
00507
00508 Resize(0);
00509 return *this;
00510 }
00511 double err = fDataWrapper->Error(i);
00512 if (err <= 0) err = 1;
00513 if (type == kValueError )
00514 tmpData.Add(fDataWrapper->Coords(i), std::log(val), err/val);
00515 else if (type == kCoordError) {
00516 const double * exold = fDataWrapper->CoordErrors(i);
00517 assert(exold != 0);
00518 for (unsigned int j = 0; j < fDim; ++j) {
00519 std::cout << " j " << j << " val " << val << " " << errx.size() << std::endl;
00520 errx[j] = exold[j]/val;
00521 }
00522 tmpData.Add(fDataWrapper->Coords(i), std::log(val), &errx.front(), err/val);
00523 }
00524 }
00525 delete fDataWrapper;
00526 fDataWrapper = 0;
00527 *this = tmpData;
00528 return *this;
00529 }
00530
00531 }
00532
00533 }
00534