Logo ROOT   master
Reference Guide
BinData.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: M. Borinsky
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class BinData
12 
13 #include "Fit/BinData.h"
14 #include "Math/Error.h"
15 
16 #include <cassert>
17 #include <cmath>
18 
19 using namespace std;
20 
21 namespace ROOT {
22 
23  namespace Fit
24  {
25 
26  BinData::BinData(unsigned int maxpoints, unsigned int dim,
27  ErrorType err ) :
28  FitData( maxpoints, dim ),
29  fErrorType( err ),
30  fDataPtr( nullptr ),
31  fDataErrorPtr( nullptr ), fDataErrorHighPtr( nullptr ), fDataErrorLowPtr( nullptr ),
32  fpTmpCoordErrorVector( nullptr ), fpTmpBinEdgeVector( nullptr )
33  {
35  InitDataVector( );
36  }
37 
38 
39  /**
40  constructor from option and default range
41  */
42  BinData::BinData (const DataOptions & opt, unsigned int maxpoints,
43  unsigned int dim, ErrorType err ) :
44  FitData( opt, maxpoints, dim ),
45  fErrorType( err ),
46  fDataPtr( nullptr ),
47  fDataErrorPtr( nullptr ), fDataErrorHighPtr( nullptr ), fDataErrorLowPtr( nullptr ),
48  fpTmpCoordErrorVector( nullptr ), fpTmpBinEdgeVector( nullptr )
49  {
51  InitDataVector( );
52  }
53 
54  /**
55  constructor from options and range
56  efault is 1D and value errors
57  */
58  BinData::BinData (const DataOptions & opt, const DataRange & range,
59  unsigned int maxpoints, unsigned int dim, ErrorType err ) :
60  FitData( opt, range, maxpoints, dim ),
61  fErrorType( err ),
62  fDataPtr( nullptr ),
63  fDataErrorPtr( nullptr ), fDataErrorHighPtr( nullptr ), fDataErrorLowPtr( nullptr ),
64  fpTmpCoordErrorVector( nullptr ), fpTmpBinEdgeVector( nullptr )
65  {
67  InitDataVector( );
68  }
69 
70  /** constructurs using external data */
71 
72  /**
73  constructor from external data for 1D with errors on coordinate and value
74  */
75  BinData::BinData (unsigned int n, const double * dataX, const double * val,
76  const double * ex , const double * eval ) :
77  FitData( n, dataX ),
78  fDataPtr( nullptr ),
79  fDataErrorPtr( nullptr ), fDataErrorHighPtr( nullptr ), fDataErrorLowPtr( nullptr ),
80  fpTmpCoordErrorVector( nullptr ), fpTmpBinEdgeVector( nullptr )
81  {
82  assert( val );
83  fDataPtr = val;
84 
85  if ( nullptr != eval )
86  {
87  fDataErrorPtr = eval;
88 
90 
91  if ( nullptr != ex )
92  {
93  fCoordErrorsPtr.resize( 1 );
94 
95  fCoordErrorsPtr[0] = ex;
96 
98  }
99  }
100  else
101  {
103  }
104 
105  fpTmpCoordErrorVector = new double [ fDim ];
106 
107  ComputeSums();
108  }
109 
110  /**
111  constructor from external data for 2D with errors on coordinate and value
112  */
113  BinData::BinData(unsigned int n, const double * dataX, const double * dataY,
114  const double * val, const double * ex , const double * ey,
115  const double * eval ) :
116  FitData( n, dataX, dataY ),
117  fDataErrorPtr( nullptr ), fDataErrorHighPtr( nullptr ), fDataErrorLowPtr( nullptr ),
118  fpTmpCoordErrorVector( nullptr ), fpTmpBinEdgeVector( nullptr )
119  {
120  assert( val );
121  fDataPtr = val;
122 
123  if ( nullptr != eval )
124  {
125  fDataErrorPtr = eval;
126 
128 
129  if ( nullptr != ex || nullptr != ey )
130  {
131  fCoordErrorsPtr.resize( 2 );
132 
133  fCoordErrorsPtr[0] = ex;
134  fCoordErrorsPtr[1] = ey;
135 
137  }
138  }
139  else
140  {
142  }
143 
144  fpTmpCoordErrorVector = new double [ fDim ];
145  ComputeSums();
146  }
147 
148  /**
149  constructor from external data for 3D with errors on coordinate and value
150  */
151  BinData::BinData(unsigned int n, const double * dataX, const double * dataY,
152  const double * dataZ, const double * val, const double * ex ,
153  const double * ey , const double * ez , const double * eval ) :
154  FitData( n, dataX, dataY, dataZ ),
155  fDataErrorPtr( nullptr ), fDataErrorHighPtr( nullptr ), fDataErrorLowPtr( nullptr ),
156  fpTmpCoordErrorVector( nullptr ), fpTmpBinEdgeVector( nullptr )
157  {
158  assert( val );
159  fDataPtr = val;
160 
161  if ( nullptr != eval )
162  {
163  fDataErrorPtr = eval;
164 
166 
167  if ( nullptr != ex || nullptr != ey || nullptr != ez )
168  {
169  fCoordErrorsPtr.resize( 3 );
170 
171  fCoordErrorsPtr[0] = ex;
172  fCoordErrorsPtr[1] = ey;
173  fCoordErrorsPtr[2] = ez;
174 
176  }
177  }
178  else
179  {
181  }
182 
183  fpTmpCoordErrorVector = new double [ fDim ];
184  ComputeSums();
185  }
186 
187  /**
188  destructor
189  */
191  {
192  assert( fMaxPoints == 0 || fWrapped == fData.empty() );
193 
194  assert( kValueError == fErrorType || kCoordError == fErrorType ||
196  assert( fMaxPoints == 0 || fDataError.empty() || &fDataError.front() == fDataErrorPtr );
197  assert( fMaxPoints == 0 || fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
198  assert( fMaxPoints == 0 || fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
199  assert( fMaxPoints == 0 || fDataErrorLow.empty() == fDataErrorHigh.empty() );
200  assert( fMaxPoints == 0 || fData.empty() || &fData.front() == fDataPtr );
201 
202  for ( unsigned int i=0; i < fDim; i++ )
203  {
204  assert( fCoordErrors.empty() || &fCoordErrors[i].front() == fCoordErrorsPtr[i] );
205  }
206 
207  if ( fpTmpBinEdgeVector )
208  {
209  delete[] fpTmpBinEdgeVector;
210  fpTmpBinEdgeVector= nullptr;
211  }
212 
213  if ( fpTmpCoordErrorVector )
214  {
215  delete[] fpTmpCoordErrorVector;
216  fpTmpCoordErrorVector = nullptr;
217  }
218  }
219 
220  /**
221  copy constructors
222  */
223  BinData::BinData (const BinData & rhs) :
224  FitData()
225  {
226  *this = rhs;
227  }
228 
230  {
231  FitData::operator=( rhs );
232 
233  if ( fpTmpBinEdgeVector )
234  {
235  assert( Opt().fIntegral );
236 
237  delete[] fpTmpBinEdgeVector;
238  fpTmpBinEdgeVector= nullptr;
239  }
240 
241  if ( fpTmpCoordErrorVector )
242  {
243  delete[] fpTmpCoordErrorVector;
244  fpTmpCoordErrorVector = nullptr;
245  }
246 
247  fDataPtr = nullptr;
249 
250  fErrorType = rhs.fErrorType;
251  fRefVolume = rhs.fRefVolume;
252  fBinEdge = rhs.fBinEdge;
253 
254  if ( fWrapped )
255  {
256  fData.clear();
257  fCoordErrors.clear();
258  fDataError.clear();
259  fDataErrorHigh.clear();
260  fDataErrorLow.clear();
261 
262  fDataPtr = rhs.fDataPtr;
267  }
268  else
269  {
270  fData = rhs.fData;
271 
272  if ( !fData.empty() )
273  fDataPtr = &fData.front();
274 
276  fDataError = rhs.fDataError;
279 
280  if( ! fCoordErrors.empty() )
281  {
282  assert( kCoordError == fErrorType || kAsymError == fErrorType );
283  fCoordErrorsPtr.resize( fDim );
284 
285  for ( unsigned int i=0; i<fDim; i++ )
286  {
287  fCoordErrorsPtr[i] = fCoordErrors[i].empty() ? nullptr : &fCoordErrors[i].front();
288  }
289  }
290 
291  fDataError = rhs.fDataError;
294 
295  assert( fDataErrorLow.empty() == fDataErrorHigh.empty() );
296  assert( fDataErrorLow.empty() != fDataError.empty() || kNoError == fErrorType );
297 
298  if ( !fDataError.empty() )
299  {
300  assert( kValueError == fErrorType || kCoordError == fErrorType );
301  fDataErrorPtr = &fDataError.front();
302  }
303  else if ( !fDataErrorHigh.empty() && !fDataErrorLow.empty() )
304  {
305  assert( kAsymError == fErrorType );
307  fDataErrorLowPtr = &fDataErrorLow.front();
308  }
309  }
310 
311  fpTmpCoordErrorVector= new double[ fDim ];
312 
313  if ( Opt().fIntegral )
314  fpTmpBinEdgeVector = new double[ fDim ];
315 
316  return *this;
317  }
318 
319 
320  /**
321  preallocate a data set with given size , dimension and error type (to get the full point size)
322  If the data set already exists and it is having the compatible point size space for the new points
323  is created in the data sets, while if not compatible the old data are erased and new space of
324  new size is allocated.
325  (i.e if exists initialize is equivalent to a resize( NPoints() + maxpoints)
326  */
327 
328  void BinData::Append( unsigned int newPoints, unsigned int dim , ErrorType err )
329  {
330  assert( !fWrapped );
331  assert( fMaxPoints == 0 || fWrapped == fData.empty() );
332 
333  assert( kValueError == fErrorType || kCoordError == fErrorType ||
335  assert( fMaxPoints == 0 || fDataError.empty() || &fDataError.front() == fDataErrorPtr );
336  assert( fMaxPoints == 0 || fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
337  assert( fMaxPoints == 0 || fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
338  assert( fMaxPoints == 0 || fDataErrorLow.empty() == fDataErrorHigh.empty() );
339  assert( fMaxPoints == 0 || fData.empty() || &fData.front() == fDataPtr );
340 
341  FitData::Append( newPoints, dim );
342 
343  fErrorType = err;
344 
345  InitDataVector( );
346  InitializeErrors( );
347  }
348 
349  void BinData::Initialize( unsigned int newPoints, unsigned int dim, ErrorType err )
350  {
351  Append( newPoints, dim, err );
352  }
353 
354 
355 
356  /**
357  apply a Log transformation of the data values
358  can be used for example when fitting an exponential or gaussian
359  Transform the data in place need to copy if want to preserve original data
360  The data sets must not contain negative values. IN case it does,
361  an empty data set is returned
362  */
364  { // apply log transform on the bin data values
365 
366  if ( fWrapped )
367  {
368  UnWrap();
369  }
370 
371  if ( kNoError == fErrorType )
372  {
374  fDataErrorPtr = fDataError.empty() ? nullptr : &fDataError.front();
375  }
376 
377  for ( unsigned int i=0; i < fNPoints; i++ )
378  {
379  double val = fData[i];
380 
381  if ( val <= 0 )
382  {
383  MATH_ERROR_MSG("BinData::TransformLog","Some points have negative values - cannot apply a log transformation");
384  return *this;
385  }
386 
387  fData[i] = std::log( val );
388 
389  if( kNoError == fErrorType )
390  {
391  fDataError[i] = val;
392  }
393  else if ( kValueError == fErrorType )
394  {
395  fDataError[i]*= val;
396  }
397  else if ( kCoordError == fErrorType )
398  {
399  fDataError[i]/= val;
400  }
401  else if ( kAsymError == fErrorType )
402  {
403  fDataErrorHigh[i]/= val;
404  fDataErrorLow[i]/= val;
405  }
406  else
407  assert(false);
408  }
409 
410  if ( kNoError == fErrorType )
411  {
413  }
414 
415  return *this;
416  }
417 
418 
419  /**
420  add one dim data with only coordinate and values
421  */
422  void BinData::Add( double x, double y )
423  {
424  assert( kNoError == fErrorType );
425 
426  assert( !fData.empty() && fDataPtr );
427  assert( fDataErrorHigh.empty() && !fDataErrorHighPtr );
428  assert( fDataErrorLow.empty() && !fDataErrorLowPtr );
429  assert( fDataError.empty() && !fDataErrorPtr );
430  assert( fCoordErrors.empty() && fCoordErrorsPtr.empty() );
431 
432  fData[ fNPoints ] = y;
433 
434  FitData::Add( x );
435  fSumContent += y;
436  }
437 
438  /**
439  add one dim data with no error in the coordinate (x)
440  in this case store the inverse of the error in the value (y)
441  */
442  void BinData::Add( double x, double y, double ey )
443  {
444  assert( kValueError == fErrorType );
445  assert( !fData.empty() && fDataPtr );
446  assert( fDataErrorHigh.empty() && !fDataErrorHighPtr );
447  assert( fDataErrorLow.empty() && !fDataErrorLowPtr );
448  assert( !fDataError.empty() && fDataErrorPtr );
449  assert( fCoordErrors.empty() && fCoordErrorsPtr.empty() );
450 
451  fData[ fNPoints ] = y;
452  fDataError[ fNPoints ] = (ey != 0.0) ? 1.0/ey : 0.0;
453 
454  FitData::Add( x );
455  fSumContent += y;
456  if (y != 0 || ey != 1.0) fSumError2 += ey*ey;
457  // set the weight flag checking if error^2 != y
458  if (!fIsWeighted)
459  if (y != 0 && std::abs( ey*ey/y - 1.0) > 1.E-12) fIsWeighted = true;
460  }
461 
462  /**
463  add one dim data with error in the coordinate (x)
464  in this case store the value (y) error and not the inverse
465  */
466  void BinData::Add( double x, double y, double ex, double ey )
467  {
468  assert( kCoordError == fErrorType );
469  assert( !fData.empty() && fDataPtr );
470  assert( !fDataError.empty() && fDataErrorPtr );
471  assert( fDataErrorHigh.empty() && !fDataErrorHighPtr );
472  assert( fDataErrorLow.empty() && !fDataErrorLowPtr );
473  assert( !fCoordErrors.empty() && fCoordErrors.size() == 1 );
474  assert( !fCoordErrorsPtr.empty() && fCoordErrorsPtr.size() == 1 && fCoordErrorsPtr[0] );
475  assert( &fCoordErrors[0].front() == fCoordErrorsPtr[0] );
476 
477  fData[ fNPoints ] = y;
478  fCoordErrors[0][ fNPoints ] = ex;
479  fDataError[ fNPoints ] = ey;
480 
481  FitData::Add( x );
482  fSumContent += y;
483  if (y != 0 || ey != 1.0) fSumError2 += ey*ey;
484  // set the weight flag checking if error^2 != y
485  if (!fIsWeighted)
486  if (y != 0 && std::abs( ey*ey/y - 1.0) > 1.E-12) fIsWeighted = true;
487  }
488 
489  /**
490  add one dim data with error in the coordinate (x) and asymmetric errors in the value (y)
491  in this case store the y errors and not the inverse
492  */
493  void BinData::Add( double x, double y, double ex, double eyl, double eyh )
494  {
495  assert( kAsymError == fErrorType );
496  assert( !fData.empty() && fDataPtr );
497  assert( !fDataErrorHigh.empty() && fDataErrorHighPtr );
498  assert( !fDataErrorLow.empty() && fDataErrorLowPtr );
499  assert( fDataError.empty() && !fDataErrorPtr );
500  assert( !fCoordErrors.empty() && fCoordErrors.size() == 1 );
501  assert( !fCoordErrorsPtr.empty() && fCoordErrorsPtr.size() == 1 && fCoordErrorsPtr[0] );
502  assert( &fCoordErrors[0].front() == fCoordErrorsPtr[0] );
503 
504  fData[ fNPoints ] = y;
505  fCoordErrors[0][ fNPoints ] = ex;
506  fDataErrorHigh[ fNPoints ] = eyh;
507  fDataErrorLow[ fNPoints ] = eyl;
508 
509  FitData::Add( x );
510  fSumContent += y;
511  if (y != 0 || eyl != 1.0 || eyh != 1.0) fSumError2 += (eyl+eyh)*(eyl+eyh)/4;
512 
513  }
514 
515  /**
516  add multi-dim coordinate data with only value
517  */
518  void BinData::Add( const double* x, double val )
519  {
520  assert( kNoError == fErrorType );
521 
522  assert( !fData.empty() && fDataPtr );
523  assert( fDataErrorHigh.empty() && !fDataErrorHighPtr );
524  assert( fDataErrorLow.empty() && !fDataErrorLowPtr );
525  assert( fDataError.empty() && !fDataErrorPtr );
526  assert( fCoordErrors.empty() && fCoordErrorsPtr.empty() );
527 
528  fData[ fNPoints ] = val;
529 
530  FitData::Add( x );
531  fSumContent += val;
532  }
533 
534  /**
535  add multi-dim coordinate data with only error in value
536  The class stores internally the inverse of the error in this case
537  */
538  void BinData::Add( const double* x, double val, double eval )
539  {
540  assert( kValueError == fErrorType );
541  assert( !fData.empty() && fDataPtr );
542  assert( fDataErrorHigh.empty() && !fDataErrorHighPtr );
543  assert( fDataErrorLow.empty() && !fDataErrorLowPtr );
544  assert( !fDataError.empty() && fDataErrorPtr );
545  assert( fCoordErrors.empty() && fCoordErrorsPtr.empty() );
546 
547  fData[ fNPoints ] = val;
548  fDataError[ fNPoints ] = (eval != 0.0) ? 1.0/eval : 0.0;
549 
550  FitData::Add( x );
551  fSumContent += val;
552  if (val != 0 || eval != 1.0) fSumError2 += eval*eval;
553  if (!fIsWeighted)
554  if (val != 0 && std::abs( eval*eval/val - 1.0) > 1.E-12) fIsWeighted = true;
555  }
556 
557  /**
558  add multi-dim coordinate data with both error in coordinates and value
559  */
560  void BinData::Add( const double* x, double val, const double* ex, double eval )
561  {
562  assert( kCoordError == fErrorType );
563  assert( !fData.empty() && fDataPtr );
564  assert( !fDataError.empty() && fDataErrorPtr );
565  assert( fDataErrorHigh.empty() && !fDataErrorHighPtr );
566  assert( fDataErrorLow.empty() && !fDataErrorLowPtr );
567  assert( fCoordErrors.size() == fDim );
568  assert( fCoordErrorsPtr.size() == fDim );
569 
570  fData[ fNPoints ] = val;
571 
572  for( unsigned int i=0; i<fDim; i++ )
573  {
574  assert( &fCoordErrors[i].front() == fCoordErrorsPtr[i] );
575 
576  fCoordErrors[i][ fNPoints ] = ex[i];
577  }
578  // in this case we store the y error and not the inverse
579  fDataError[ fNPoints ] = eval;
580 
581  FitData::Add( x );
582  fSumContent += val;
583  if (val != 0 || eval != 1.0) fSumError2 += eval*eval;
584  if (!fIsWeighted)
585  if (val != 0 && std::abs( eval*eval/val - 1.0) > 1.E-12) fIsWeighted = true;
586  }
587 
588  /**
589  add multi-dim coordinate data with both error in coordinates and value
590  */
591  void BinData::Add( const double* x, double val, const double* ex, double elval, double ehval )
592  {
593  assert( kAsymError == fErrorType );
594 
595  assert( !fData.empty() && fDataPtr );
596  assert( !fDataErrorHigh.empty() && fDataErrorHighPtr );
597  assert( !fDataErrorLow.empty() && fDataErrorLowPtr );
598  assert( fDataError.empty() && !fDataErrorPtr );
599  assert( fCoordErrors.size() == fDim );
600  assert( fCoordErrorsPtr.size() == fDim );
601 
602  fData[ fNPoints ] = val;
603 
604  for( unsigned int i=0; i<fDim; i++ )
605  {
606  assert( &fCoordErrors[i].front() == fCoordErrorsPtr[i] );
607 
608  fCoordErrors[i][ fNPoints ] = ex[i];
609  }
610 
611  fDataErrorLow[ fNPoints ] = elval;
612  fDataErrorHigh[ fNPoints ] = ehval;
613 
614  FitData::Add( x );
615  fSumContent += val;
616  if (val != 0 || elval != 1.0 || ehval != 1.0 )
617  fSumError2 += (elval+ehval)*(elval+ehval)/4;
618  }
619 
620 
621  /**
622  add the bin width data, a pointer to an array with the bin upper edge information.
623  This is needed when fitting with integral options
624  The information is added for the previously inserted point.
625  BinData::Add must be called before
626  */
627  void BinData::AddBinUpEdge( const double* xup )
628  {
629  if ( fBinEdge.empty() )
630  InitBinEdge();
631 
632  assert( fBinEdge.size() == fDim );
633 
634  for ( unsigned int i=0; i<fDim; i++ )
635  {
636  fBinEdge[i].push_back( xup[i] );
637 
638  // check that is consistent with number of points added in the data
639  assert( fNPoints == fBinEdge[i].size() );
640  }
641 
642  // compute the bin volume
643  const double* xlow = Coords( fNPoints-1 );
644 
645  double binVolume = 1.0;
646  for ( unsigned int j = 0; j < fDim; j++ )
647  {
648  binVolume *= ( xup[j] - xlow[j] );
649  }
650 
651  // store the minimum bin volume found as reference for future normalizations
652  if ( fNPoints == 1 )
653  fRefVolume = binVolume;
654  else if ( binVolume < fRefVolume )
655  fRefVolume = binVolume;
656  }
657 
658 
660  {
662  fDataPtr = fData.empty() ? nullptr : &fData.front();
663  }
664 
666  {
667  assert( kValueError == fErrorType || kCoordError == fErrorType ||
669 
670  if ( fpTmpCoordErrorVector )
671  {
672  delete[] fpTmpCoordErrorVector;
673  fpTmpCoordErrorVector = nullptr;
674  }
675 
676  if ( kNoError == fErrorType )
677  {
678  fCoordErrors.clear();
679  fCoordErrorsPtr.clear();
680 
681  fDataErrorHigh.clear();
682  fDataErrorHighPtr = nullptr;
683 
684  fDataErrorLow.clear();
685  fDataErrorLowPtr = nullptr;
686 
687  fDataError.clear();
688  fDataErrorPtr = nullptr;
689 
690  return;
691  }
692 
694  {
695  fCoordErrorsPtr.resize( fDim );
696  fCoordErrors.resize( fDim );
697  for( unsigned int i=0; i < fDim; i++ )
698  {
700 
701  fCoordErrorsPtr[i] = fCoordErrors[i].empty() ? nullptr : &fCoordErrors[i].front();
702  }
703 
704  fpTmpCoordErrorVector = new double[fDim];
705  }
706  else
707  {
708  fCoordErrors.clear();
709  fCoordErrorsPtr.clear();
710  }
711 
713  {
715  fDataErrorPtr = fDataError.empty() ? nullptr : &fDataError.front();
716 
717  fDataErrorHigh.clear();
718  fDataErrorHighPtr = nullptr;
719  fDataErrorLow.clear();
720  fDataErrorLowPtr = nullptr;
721  }
722  else if ( fErrorType == kAsymError )
723  {
725  fDataErrorHighPtr = fDataErrorHigh.empty() ? nullptr : &fDataErrorHigh.front();
726 
728  fDataErrorLowPtr = fDataErrorLow.empty() ? nullptr : &fDataErrorLow.front();
729 
730  fDataError.clear();
731  fDataErrorPtr = nullptr;
732  }
733  else
734  {
735  assert(false);
736  }
737  }
738 
740  {
741  fBinEdge.resize( fDim );
742 
743  for( unsigned int i=0; i<fDim; i++ )
744  {
746  }
747 
748  if ( fpTmpBinEdgeVector )
749  {
750  delete[] fpTmpBinEdgeVector;
751  fpTmpBinEdgeVector = nullptr;
752  }
753 
754  fpTmpBinEdgeVector = new double[ fDim ];
755  }
756 
758  {
759  assert( fWrapped );
760  assert( kValueError == fErrorType || kCoordError == fErrorType ||
762  assert( fDataError.empty() || &fDataError.front() == fDataErrorPtr );
763  assert( fDataErrorHigh.empty() || &fDataErrorHigh.front() == fDataErrorHighPtr );
764  assert( fDataErrorLow.empty() || &fDataErrorLow.front() == fDataErrorLowPtr );
765  assert( fDataErrorLow.empty() == fDataErrorHigh.empty() );
766 
767  assert( fData.empty() );
768  assert( fDataPtr );
769 
770  unsigned vectorPadding = FitData::VectorPadding(fNPoints);
771  fData.resize(fNPoints + vectorPadding);
772  std::copy( fDataPtr, fDataPtr + fNPoints, fData.begin() );
773  fDataPtr = fData.empty() ? nullptr : &fData.front();
774 
775  for ( unsigned int i=0; i < fDim; i++ )
776  {
777  assert( fCoordErrorsPtr[i] );
778  assert( fCoordErrors.empty() || &fCoordErrors[i].front() == fCoordErrorsPtr[i] );
779  }
780 
782  {
783  assert( fDataError.empty() );
784  assert( fDataErrorPtr );
785 
786  fDataError.resize(fNPoints + vectorPadding);
787  std::copy(fDataErrorPtr, fDataErrorPtr + fNPoints + vectorPadding, fDataError.begin());
788  fDataErrorPtr = fDataError.empty() ? nullptr : &fDataError.front();
789  }
790 
791  if ( kValueError == fErrorType )
792  {
793  for ( unsigned int i=0; i < fNPoints; i++ )
794  {
795  fDataError[i] = 1.0 / fDataError[i];
796  }
797  }
798 
800  {
801  fCoordErrors.resize( fDim );
802  for( unsigned int i=0; i < fDim; i++ )
803  {
804  assert( fCoordErrorsPtr[i] );
805  fCoordErrors[i].resize(fNPoints + vectorPadding);
806  std::copy(fCoordErrorsPtr[i], fCoordErrorsPtr[i] + fNPoints + vectorPadding, fCoordErrors[i].begin());
807  fCoordErrorsPtr[i] = fCoordErrors[i].empty() ? nullptr : &fCoordErrors[i].front();
808  }
809 
810  if( kAsymError == fErrorType )
811  {
812  assert( fDataErrorHigh.empty() );
813  assert( fDataErrorLow.empty() );
814  assert( fDataErrorHighPtr && fDataErrorLowPtr );
815 
816  fDataErrorHigh.resize(fNPoints + vectorPadding);
817  fDataErrorLow.resize(fNPoints + vectorPadding);
818  std::copy(fDataErrorHighPtr, fDataErrorHighPtr + fNPoints + vectorPadding, fDataErrorHigh.begin());
819  std::copy(fDataErrorLowPtr, fDataErrorLowPtr + fNPoints + vectorPadding, fDataErrorLow.begin());
820  fDataErrorHighPtr = fDataErrorHigh.empty() ? nullptr : &fDataErrorHigh.front();
821  fDataErrorLowPtr = fDataErrorLow.empty() ? nullptr : &fDataErrorLow.front();
822  }
823  }
824 
825  FitData::UnWrap();
826  }
827 
829  unsigned int n = Size();
830  fSumContent = 0;
831  fSumError2 = 0;
832  if (fErrorType != kAsymError) {
833  for (unsigned int i = 0; i < n; ++i) {
834  double y = Value(i);
835  double err = Error(i);
836  fSumContent += y;
837  if (y != 0 || err != 1.0) fSumError2 += err*err;
838  }
839  }
840  else {
841  for (unsigned int i = 0; i < n; ++i) {
842  double y = Value(i);
843  fSumContent += y;
844  double elval,ehval = 0;
845  GetAsymError(i,elval,ehval);
846  if (y != 0 || elval != 1.0 || ehval != 1.0)
847  fSumError2 += (elval+ehval)*(elval+ehval)/4;
848  }
849  }
850  // set the weight flag
852  }
853 
854  } // end namespace Fit
855 
856 } // end namespace ROOT
void GetAsymError(unsigned int ipoint, double &lowError, double &highError) const
Definition: BinData.h:296
Returns the available number of logical cores.
Definition: StringConv.hxx:21
double * fpTmpBinEdgeVector
Definition: BinData.h:617
Base class for all the fit data types: Stores the coordinates and the DataOptions.
Definition: FitData.h:66
void InitDataVector()
Definition: BinData.cxx:659
const double * fDataPtr
Definition: BinData.h:596
STL namespace.
const double * fDataErrorPtr
Definition: BinData.h:606
void AddBinUpEdge(const double *xup)
add the bin width data, a pointer to an array with the bin upper edge information.
Definition: BinData.cxx:627
std::vector< const double *> fCoordErrorsPtr
Definition: BinData.h:599
const double * Coords(unsigned int ipoint) const
return a pointer to the coordinates data for the given fit point
Definition: FitData.h:246
double * fpTmpCoordErrorVector
Definition: BinData.h:612
ErrorType fErrorType
Definition: BinData.h:585
std::vector< double > fData
Stores the data values the same way as the coordinates.
Definition: BinData.h:595
std::vector< std::vector< double > > fBinEdge
Definition: BinData.h:614
Double_t x[n]
Definition: legend1.C:17
void Append(unsigned int newPoints, unsigned int dim=1)
Definition: FitData.cxx:248
double fSumError2
Definition: BinData.h:589
void Initialize(unsigned int newPoints, unsigned int dim=1, ErrorType err=kValueError)
Definition: BinData.cxx:349
double fSumContent
Definition: BinData.h:588
unsigned int Size() const
return number of fit points
Definition: FitData.h:303
double Error(unsigned int ipoint) const
Definition: BinData.h:251
#define MATH_ERROR_MSG(loc, str)
Definition: Error.h:82
DataOptions : simple structure holding the options on how the data are filled.
Definition: DataOptions.h:28
void InitializeErrors()
Definition: BinData.cxx:665
double fRefVolume
Definition: BinData.h:587
void Add(double x)
add one dim data with only coordinate and values
Definition: FitData.h:264
std::vector< double > fDataError
Definition: BinData.h:603
const DataOptions & Opt() const
access to options
Definition: FitData.h:319
std::vector< double > fDataErrorHigh
Definition: BinData.h:604
virtual ~BinData()
destructor
Definition: BinData.cxx:190
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:53
constexpr Double_t E()
Base of natural log: .
Definition: TMath.h:97
BinData(unsigned int maxpoints=0, unsigned int dim=1, ErrorType err=kValueError)
constructor from dimension of point and max number of points (to pre-allocate vector) Give a zero val...
Definition: BinData.cxx:26
static constexpr unsigned VectorPadding(const unsigned)
If VecCore is not defined, there is no vectorization available and the SIMD vector size will always b...
Definition: FitData.h:382
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:34
const double * fDataErrorLowPtr
Definition: BinData.h:608
void Add(double x, double y)
add one dim data with only coordinate and values
Definition: BinData.cxx:422
TFitResultPtr Fit(FitObject *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
Definition: HFitImpl.cxx:134
std::vector< double > fDataErrorLow
Definition: BinData.h:605
unsigned int fNPoints
Definition: FitData.h:395
std::vector< std::vector< double > > fCoordErrors
Definition: BinData.h:598
Double_t y[n]
Definition: legend1.C:17
Double_t ey[n]
Definition: legend1.C:17
BinData & operator=(const BinData &rhs)
Definition: BinData.cxx:229
BinData & LogTransform()
apply a Log transformation of the data values can be used for example when fitting an exponential or ...
Definition: BinData.cxx:363
double Value(unsigned int ipoint) const
return the value for the given fit point
Definition: BinData.h:217
FitData & operator=(const FitData &rhs)
Definition: FitData.cxx:216
void Append(unsigned int newPoints, unsigned int dim=1, ErrorType err=kValueError)
preallocate a data set with given size , dimension and error type (to get the full point size) If the...
Definition: BinData.cxx:328
unsigned int fDim
Definition: FitData.h:396
unsigned int fMaxPoints
Definition: FitData.h:394
const double * fDataErrorHighPtr
Definition: BinData.h:607
Double_t ex[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
double log(double)