File indexing completed on 2025-01-18 10:10:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef ROOT_Fit_BinData
0014 #define ROOT_Fit_BinData
0015
0016 #include "Fit/FitData.h"
0017 #include "Math/Error.h"
0018 #include <cmath>
0019 #include <vector>
0020
0021 namespace ROOT {
0022
0023 namespace Fit {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 class BinData : public FitData {
0053
0054 public :
0055
0056 enum ErrorType { kNoError, kValueError, kCoordError, kAsymError };
0057
0058
0059
0060
0061
0062
0063 explicit BinData(unsigned int maxpoints = 0, unsigned int dim = 1,
0064 ErrorType err = kValueError);
0065
0066
0067
0068
0069
0070 explicit BinData (const DataOptions & opt, unsigned int maxpoints = 0,
0071 unsigned int dim = 1, ErrorType err = kValueError);
0072
0073
0074
0075
0076
0077 BinData (const DataOptions & opt, const DataRange & range,
0078 unsigned int maxpoints = 0, unsigned int dim = 1, ErrorType err = kValueError );
0079
0080
0081
0082
0083
0084
0085 BinData(unsigned int n, const double * dataX, const double * val,
0086 const double * ex , const double * eval );
0087
0088
0089
0090
0091 BinData(unsigned int n, const double * dataX, const double * dataY,
0092 const double * val, const double * ex , const double * ey,
0093 const double * eval );
0094
0095
0096
0097
0098 BinData(unsigned int n, const double * dataX, const double * dataY,
0099 const double * dataZ, const double * val, const double * ex ,
0100 const double * ey , const double * ez , const double * eval );
0101
0102
0103
0104
0105 ~BinData() override;
0106
0107
0108
0109
0110 BinData(const BinData & rhs);
0111
0112
0113 BinData & operator= ( const BinData & rhs );
0114
0115
0116
0117
0118
0119
0120
0121
0122 void Initialize( unsigned int newPoints, unsigned int dim = 1, ErrorType err = kValueError ){
0123 Append(newPoints,dim,err);
0124 }
0125
0126
0127 void Append( unsigned int newPoints, unsigned int dim = 1, ErrorType err = kValueError );
0128
0129
0130
0131
0132
0133
0134 bool HaveCoordErrors() const {
0135 assert ( fErrorType == kNoError ||
0136 fErrorType == kValueError ||
0137 fErrorType == kCoordError ||
0138 fErrorType == kAsymError );
0139
0140 return fErrorType == kCoordError;
0141 }
0142
0143
0144
0145
0146 bool HaveAsymErrors() const {
0147 assert ( fErrorType == kNoError ||
0148 fErrorType == kValueError ||
0149 fErrorType == kCoordError ||
0150 fErrorType == kAsymError );
0151
0152 return fErrorType == kAsymError;
0153 }
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 BinData & LogTransform();
0164
0165
0166
0167
0168
0169 void Add( double x, double y );
0170
0171
0172
0173
0174
0175 void Add( double x, double y, double ey );
0176
0177
0178
0179
0180
0181 void Add( double x, double y, double ex, double ey );
0182
0183
0184
0185
0186
0187 void Add( double x, double y, double ex, double eyl, double eyh );
0188
0189
0190
0191
0192 void Add( const double* x, double val );
0193
0194
0195
0196
0197 void Add( const double* x, double val, double eval );
0198
0199
0200
0201
0202 void Add( const double* x, double val, const double* ex, double eval );
0203
0204
0205
0206
0207 void Add( const double* x, double val, const double* ex, double elval, double ehval );
0208
0209
0210
0211
0212
0213
0214
0215 void AddBinUpEdge( const double* xup );
0216
0217
0218
0219
0220 double Value( unsigned int ipoint ) const
0221 {
0222 assert( ipoint < fMaxPoints );
0223 assert( fDataPtr );
0224 assert( fData.empty() || &fData.front() == fDataPtr );
0225
0226 return fDataPtr[ipoint];
0227 }
0228
0229
0230
0231
0232 const double *ValuePtr( unsigned int ipoint ) const
0233 {
0234 return &fDataPtr[ipoint];
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 const double * ErrorPtr(unsigned int ipoint) const{
0250 assert( ipoint < fMaxPoints );
0251 assert( kValueError == fErrorType || kCoordError == fErrorType ||
0252 kAsymError == fErrorType || kNoError == fErrorType );
0253
0254 if ( fErrorType == kNoError )
0255 return nullptr;
0256 return &fDataErrorPtr[ ipoint ];
0257 }
0258
0259
0260
0261
0262 double Error( unsigned int ipoint ) const
0263 {
0264 assert( ipoint < fMaxPoints );
0265 assert( kValueError == fErrorType || kCoordError == fErrorType ||
0266 kAsymError == fErrorType || kNoError == fErrorType );
0267
0268 if ( fErrorType == kNoError )
0269 {
0270 assert( !fDataErrorPtr && !fDataErrorHighPtr && !fDataErrorLowPtr );
0271 assert( fDataError.empty() && fDataErrorHigh.empty() && fDataErrorLow.empty() );
0272 return 1.0;
0273 }
0274
0275 if ( fErrorType == kValueError )
0276 {
0277 assert( fDataErrorPtr && !fDataErrorHighPtr && !fDataErrorLowPtr );
0278 assert( fDataErrorHigh.empty() && fDataErrorLow.empty() );
0279 assert( fDataError.empty() || &fDataError.front() == fDataErrorPtr );
0280
0281 double eval = fDataErrorPtr[ ipoint ];
0282
0283 if (fWrapped)
0284 return eval;
0285 else
0286 return (eval != 0.0) ? 1.0/eval : 0.0;
0287 }
0288
0289 if ( fErrorType == kAsymError )
0290 {
0291 assert( !fDataErrorPtr && fDataErrorHighPtr && fDataErrorLowPtr );
0292 assert( fDataError.empty() );
0293 assert( fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
0294 assert( fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
0295 assert( fDataErrorLow.empty() == fDataErrorHigh.empty() );
0296
0297 double eh = fDataErrorHighPtr[ ipoint ];
0298 double el = fDataErrorLowPtr[ ipoint ];
0299
0300 return (el+eh) / 2.0;
0301 }
0302
0303 assert( fErrorType == kCoordError );
0304 return fDataErrorPtr[ ipoint ];
0305 }
0306
0307 void GetAsymError( unsigned int ipoint, double& lowError, double& highError ) const
0308 {
0309 assert( fErrorType == kAsymError );
0310 assert( !fDataErrorPtr && fDataErrorHighPtr && fDataErrorLowPtr );
0311 assert( fDataError.empty() );
0312 assert( fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
0313 assert( fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
0314 assert( fDataErrorLow.empty() == fDataErrorHigh.empty() );
0315
0316 lowError = fDataErrorLowPtr[ ipoint ];
0317 highError = fDataErrorHighPtr[ ipoint ];
0318 }
0319
0320
0321
0322
0323
0324
0325 double InvError( unsigned int ipoint ) const
0326 {
0327 assert( ipoint < fMaxPoints );
0328 assert( kValueError == fErrorType || kCoordError == fErrorType ||
0329 kAsymError == fErrorType || kNoError == fErrorType );
0330
0331 if ( fErrorType == kNoError )
0332 {
0333 assert( !fDataErrorPtr && !fDataErrorHighPtr && !fDataErrorLowPtr );
0334 assert( fDataError.empty() && fDataErrorHigh.empty() && fDataErrorLow.empty() );
0335 return 1.0;
0336 }
0337
0338 if ( fErrorType == kValueError )
0339 {
0340 assert( fDataErrorPtr && !fDataErrorHighPtr && !fDataErrorLowPtr );
0341 assert( fDataErrorHigh.empty() && fDataErrorLow.empty() );
0342 assert( fDataError.empty() || &fDataError.front() == fDataErrorPtr );
0343
0344 double eval = fDataErrorPtr[ ipoint ];
0345
0346
0347
0348 if (fWrapped)
0349 return 1.0 / eval;
0350 else
0351 return (eval != 0.0) ? eval : 0.0;
0352 }
0353
0354 if ( fErrorType == kAsymError ) {
0355
0356 assert( !fDataErrorPtr && fDataErrorHighPtr && fDataErrorLowPtr );
0357 assert( fDataError.empty() );
0358 assert( fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
0359 assert( fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
0360 assert( fDataErrorLow.empty() == fDataErrorHigh.empty() );
0361
0362 double eh = fDataErrorHighPtr[ ipoint ];
0363 double el = fDataErrorLowPtr[ ipoint ];
0364
0365 return 2.0 / (el+eh);
0366 }
0367
0368 assert( fErrorType == kCoordError );
0369
0370 return 1.0 / fDataErrorPtr[ ipoint ];
0371 }
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 const double * GetPoint( unsigned int ipoint, double & value ) const
0382 {
0383 assert( ipoint < fMaxPoints );
0384 value = Value( ipoint );
0385
0386 return Coords( ipoint );
0387 }
0388
0389
0390
0391
0392
0393
0394
0395 double GetCoordErrorComponent( unsigned int ipoint, unsigned int icoord ) const
0396 {
0397 assert( ipoint < fMaxPoints );
0398 assert( icoord < fDim );
0399 assert( fCoordErrorsPtr.size() == fDim );
0400 assert( fCoordErrorsPtr[icoord] );
0401 assert( fCoordErrors.empty() || &fCoordErrors[icoord].front() == fCoordErrorsPtr[icoord] );
0402
0403 return fCoordErrorsPtr[icoord][ipoint];
0404 }
0405
0406
0407
0408
0409
0410
0411
0412 const double* CoordErrors( unsigned int ipoint ) const
0413 {
0414 assert( ipoint < fMaxPoints );
0415 assert( fpTmpCoordErrorVector );
0416 assert( fErrorType == kCoordError || fErrorType == kAsymError );
0417
0418 for ( unsigned int i=0; i < fDim; i++ )
0419 {
0420 assert( fCoordErrorsPtr[i] );
0421 assert( fCoordErrors.empty() || &fCoordErrors[i].front() == fCoordErrorsPtr[i] );
0422
0423 fpTmpCoordErrorVector[i] = fCoordErrorsPtr[i][ipoint];
0424 }
0425
0426 return fpTmpCoordErrorVector;
0427 }
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439 const double* GetPoint( unsigned int ipoint, double & value, double & invError ) const
0440 {
0441 assert( ipoint < fMaxPoints );
0442 assert( fErrorType == kNoError || fErrorType == kValueError );
0443
0444 double e = Error( ipoint );
0445
0446 if (fWrapped)
0447 invError = e;
0448 else
0449 invError = ( e != 0.0 ) ? 1.0/e : 1.0;
0450
0451 return GetPoint( ipoint, value );
0452 }
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462 const double* GetPointError(unsigned int ipoint, double & errvalue) const
0463 {
0464 assert( ipoint < fMaxPoints );
0465 assert( fErrorType == kCoordError || fErrorType == kAsymError );
0466
0467 errvalue = Error( ipoint );
0468 return CoordErrors( ipoint );
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480 const double* GetPointError(unsigned int ipoint, double & errlow, double & errhigh) const
0481 {
0482 assert( ipoint < fMaxPoints );
0483 assert( fErrorType == kAsymError );
0484 assert( !fDataErrorPtr && fDataErrorHighPtr && fDataErrorLowPtr );
0485 assert( fDataError.empty() );
0486 assert( fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
0487 assert( fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
0488 assert( fDataErrorLow.empty() == fDataErrorHigh.empty() );
0489
0490 errhigh = fDataErrorHighPtr[ ipoint ];
0491 errlow = fDataErrorLowPtr[ ipoint ];
0492
0493 return CoordErrors( ipoint );
0494 }
0495
0496
0497
0498
0499
0500
0501
0502 double GetBinUpEdgeComponent( unsigned int ipoint, unsigned int icoord ) const
0503 {
0504 assert( icoord < fDim );
0505 assert( !fBinEdge.empty() );
0506 assert( ipoint < fBinEdge.front().size() );
0507
0508 return fBinEdge[icoord][ipoint];
0509 }
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519 const double* BinUpEdge( unsigned int ipoint ) const
0520 {
0521 if ( fBinEdge.empty() || ipoint > fBinEdge.front().size() )
0522 return nullptr;
0523
0524 GetBinUpEdgeCoordinates(ipoint, fpTmpBinEdgeVector);
0525
0526 return fpTmpBinEdgeVector;
0527 }
0528
0529
0530
0531
0532 void GetBinUpEdgeCoordinates(unsigned int ipoint, double * x) const
0533 {
0534 if (fBinEdge.empty() || ipoint > fBinEdge.front().size()) return;
0535 assert(!fBinEdge.empty());
0536 assert(ipoint < fMaxPoints);
0537 for (unsigned int i = 0; i < fDim; i++) {
0538 x[i] = fBinEdge[i][ipoint];
0539 }
0540 }
0541
0542
0543
0544
0545 bool HasBinEdges() const {
0546 return fBinEdge.size() == fDim && !fBinEdge[0].empty();
0547 }
0548
0549
0550
0551
0552 double RefVolume() const { return fRefVolume; }
0553
0554
0555
0556
0557 void SetRefVolume(double value) { fRefVolume = value; }
0558
0559
0560
0561
0562 ErrorType GetErrorType( ) const
0563 {
0564 return fErrorType;
0565 }
0566
0567
0568
0569
0570
0571 double SumOfContent() const { return fSumContent; }
0572
0573
0574
0575
0576
0577 double SumOfError2() const { return fSumError2;}
0578
0579
0580
0581
0582
0583
0584 bool IsWeighted() const {
0585 return fIsWeighted;
0586 }
0587
0588 protected:
0589 void InitDataVector ();
0590
0591 void InitializeErrors();
0592
0593 void InitBinEdge();
0594
0595 void UnWrap( );
0596
0597
0598 void ComputeSums();
0599
0600 private:
0601
0602 ErrorType fErrorType;
0603 bool fIsWeighted = false;
0604 double fRefVolume;
0605 double fSumContent = 0;
0606 double fSumError2 = 0;
0607
0608
0609
0610
0611
0612 std::vector< double > fData;
0613 const double* fDataPtr;
0614
0615 std::vector< std::vector< double > > fCoordErrors;
0616 std::vector< const double* > fCoordErrorsPtr;
0617
0618
0619
0620 std::vector< double > fDataError;
0621 std::vector< double > fDataErrorHigh;
0622 std::vector< double > fDataErrorLow;
0623 const double* fDataErrorPtr;
0624 const double* fDataErrorHighPtr;
0625 const double* fDataErrorLowPtr;
0626
0627
0628
0629 double* fpTmpCoordErrorVector;
0630
0631 std::vector< std::vector< double > > fBinEdge;
0632
0633
0634 double* fpTmpBinEdgeVector;
0635 };
0636
0637
0638 }
0639
0640 }
0641
0642
0643
0644 #endif