HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hparticlerunningmean.cc
Go to the documentation of this file.
1 //_HADES_CLASS_DESCRIPTION
2 ////////////////////////////////////////////////////////////////////////////////
3 // Calculate running mean of a distribution of integer values e.g. multiplicities.
4 // calculate the sigma (RMS) of the distribution.
5 // A cutoff at a maximum value is defined as mean value plus sigma * a scaling factor.
6 // A minimum value can be specified as well (default = 1).
7 // If the mean value gets below 1, the cutoff value is calculated by (minimum value + 1) + scaling factor*(sigma=1)
8 // instead of mean value + sigma* scaling factor.
9 // This allows for recovery from large sets with input values of 0 (e.g. sparks).
10 // It accounts as well for the fact that input values are integer (0 or 1 or 2 ...), thus cutoff values must be > 1.
11 // The array size used for averaging can be specified in initParam (default = 2000).
12 // The values of the distribution have to be >= 0
13 // add an offset if the original distibution extends to negative values
14 // W. Koenig April 2015
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 #include "hparticlerunningmean.h"
18 #include "TMath.h"
19 #include "TRandom.h"
20 #include <iostream>
21 using namespace std;
22 
24 
25 Float_t HParticleRunningMeanI::calcMean(Int_t val)
26 {
27  // calculate new mean and new sigma by replacing old point by actual one.
28 
29  if(val < fmin) {
30  fvalid = kFALSE;
31  return fmean;
32  }
33 
34  if(val <= fmax || fn < fminEvts) {
35  fmax = Int_t(max(fmean +fscaleFacSigma*fsigma + 0.5F,fmaxMin));
36  fvalid = kTRUE;
37  fSum += val - fnPoints[findex];
38  fSum2 += val*val - fnPoints[findex]*fnPoints[findex];
39  fnPoints[findex] = val;
40  if(++findex >= fnMax) findex = 0;
41  fmean = Float_t(fSum)/Float_t(fn);
42  fsigma = sqrt(float(fSum2)/float(fn) - fmean*fmean);
43  if(fn < fnMax) ++fn;
44  } else {
45  fvalid = kFALSE;
46  }
47  return fmean;
48 };
49 
50 Int_t HParticleRunningMeanI::initParam(const Int_t maxEvents, const Int_t minEvents,
51  const Float_t scaleFacSigma, const Float_t initMean, const Float_t initSigma, const Int_t min)
52 {
53  // Reset moving average, clear multiplicity array,
54  // Set minimum number of events to generate a valid multiplicity mean value
55  // Set default scaling factor (mean + factor * sigma) to maximum multiplicity (in order to reject monsters from calculating mean)
56 
57 
58  fnMax = maxEvents; // number of selected events which are used to calculate mean multiplicity
59  if(fnPoints != NULL) delete[] fnPoints;
60  fnPoints = new Int_t[fnMax];
61  reset(kFALSE);
62  if(minEvents <= fnMax) fminEvts = minEvents; //minimum events for valid mean value
63  else fminEvts = fnMax;
64  fscaleFacSigma = scaleFacSigma; // scaling from mean multiplicity to max multiplicity (excluding outliers)
65  fmin = max(min,0);
66  fmaxMin = (fmin + 1.0F) + fscaleFacSigma + 0.5F;
67  fvalid = kFALSE;
68  fmax = fmaxMin;
69  initialMean = initMean;
70  initialSigma = initSigma;
71  setInitialMean(initialMean, initialSigma) ;
72  return fnMax; // returns array size used for running mean
73 };
74 
75 Int_t HParticleRunningMeanI::setInitialMean( const Float_t initMean, const Float_t initSigma)
76 {
77  // create a set of initial mean values filling first 'fminEvts'
78  // multiplicity array members. returns number of initialized multiplicity
79  // array members (= fminEvts set in 'initParam' before
80  if(initMean==-999999 || initSigma==-999999) return 0;
81  initialMean = initMean;
82  initialSigma = initSigma;
83  Float_t initialWidth = initSigma*sqrt(12.0F); // width of a box-like distribution
84  if(initialWidth < 1.0F) initialWidth = 1.0F; // minimum needed to get correct mean for integers
85  for (findex = 0; findex < fminEvts; ++findex) {
86  fnPoints[findex] = Int_t(initMean + (gRandom->Uniform()-0.5F)*initialWidth + 0.5F);
87  fSum += fnPoints[findex];
88  fSum2 += fnPoints[findex]*fnPoints[findex]; // quadratic sum needed for sigma distribution
89  };
90  fn = fminEvts;
91  fmean = Float_t(fSum)/Float_t(fn);
92  fsigma= sqrt(Float_t(fSum2)/Float_t(fn) - fmean*fmean);
93  fmax = Int_t (max(fmean + fscaleFacSigma * initSigma + 0.5F,fmaxMin));
94 
95  return fn;
96 };
97 
99 {
100  //clear multiplicity sum, multiplicity array, reset findex counter
101  for (Int_t i = 0; i < fnMax; ++i) fnPoints[i] = 0;
102  fSum = 0;
103  fSum2 = 0;
104  fn = 1; //starts with 1, runs up while multiplicityPoints array is filled and stays constant after fnMax is reached
105  findex = 0; //running findex pointing to the last entry in the list of multiplicity points
106  fmean = 0.0F;
107  fsigma = 0.0F;
108  if(full)setInitialMean(initialMean,initialSigma) ;
109 };
110 
112 {
113  // returns true if event no > fminEvts (reliable mean) and
114  // last val < fmax (no outlier)
115  return (fn >= fminEvts) && fvalid;
116 };
void reset(Bool_t full=kTRUE)
Int_t initParam(const Int_t Max=2000, const Int_t minEvents=100, const Float_t scaleFacSigma=sqrt(12.0F), const Float_t initMean=-999999, const Float_t initSigma=-999999, const Int_t min=1)
Int_t setInitialMean(const Float_t initialMean, const Float_t initialSigma)
ClassImp(HParticleRunningMeanI) Float_t HParticleRunningMeanI