36 ClassImp(RooStats::SamplingDistribution);
38 using namespace RooStats;
43 SamplingDistribution::SamplingDistribution(
const char *name,
const char *title,
44 std::vector<Double_t>& samplingDist,
const char * varName) :
47 fSamplingDist = samplingDist;
52 fSampleWeights.resize(fSamplingDist.size(),1.0) ;
60 SamplingDistribution::SamplingDistribution(
const char *name,
const char *title,
61 std::vector<Double_t>& samplingDist, std::vector<Double_t>& sampleWeights,
const char * varName) :
64 fSamplingDist = samplingDist;
65 fSampleWeights = sampleWeights;
75 SamplingDistribution::SamplingDistribution(
const char *name,
const char *title,
const char * varName) :
93 SamplingDistribution::SamplingDistribution(
97 const char * _columnName,
99 ) : TNamed(name, title) {
103 if( dataSet.numEntries() == 0 || !dataSet.get()->first() ) {
104 if( varName ) fVarName = varName;
108 TString columnName( _columnName );
110 if( !columnName.Length() ) {
111 columnName.Form(
"%s_TS0", name );
112 if( !dataSet.get()->find(columnName) ) {
113 columnName = dataSet.get()->first()->GetName();
119 fVarName = (*dataSet.get())[columnName].GetTitle();
124 for(Int_t i=0; i < dataSet.numEntries(); i++) {
125 fSamplingDist.push_back(dataSet.get(i)->getRealValue(columnName));
126 fSampleWeights.push_back(dataSet.weight());
134 SamplingDistribution::SamplingDistribution( ) :
135 TNamed(
"SamplingDistribution_DefaultName",
"SamplingDistribution")
142 SamplingDistribution::~SamplingDistribution()
144 fSamplingDist.clear();
145 fSampleWeights.clear();
153 void SamplingDistribution::Add(
const SamplingDistribution* other)
157 std::vector<double> newSamplingDist = other->fSamplingDist;
158 std::vector<double> newSampleWeights = other->fSampleWeights;
164 fSamplingDist.reserve(fSamplingDist.size()+newSamplingDist.size());
165 fSampleWeights.reserve(fSampleWeights.size()+newSampleWeights.size());
168 for(
unsigned int i=0; i<newSamplingDist.size(); ++i){
169 fSamplingDist.push_back(newSamplingDist[i]);
170 fSampleWeights.push_back(newSampleWeights[i]);
174 if(GetVarName().Length() == 0 && other->GetVarName().Length() > 0)
175 fVarName = other->GetVarName();
177 if(strlen(GetName()) == 0 && strlen(other->GetName()) > 0)
178 SetName(other->GetName());
179 if(strlen(GetTitle()) == 0 && strlen(other->GetTitle()) > 0)
180 SetTitle(other->GetTitle());
188 Double_t SamplingDistribution::Integral(Double_t low, Double_t high, Bool_t normalize, Bool_t lowClosed, Bool_t
192 return IntegralAndError(error, low,high, normalize, lowClosed, highClosed);
200 void SamplingDistribution::SortValues()
const {
202 unsigned int n = fSamplingDist.size();
203 std::vector<unsigned int> index(n);
204 TMath::SortItr(fSamplingDist.begin(), fSamplingDist.end(), index.begin(), false );
207 fSumW = std::vector<double>( n );
208 fSumW2 = std::vector<double>( n );
210 std::vector<double> sortedDist( n);
211 std::vector<double> sortedWeights( n);
213 for(
unsigned int i=0; i <n; i++) {
214 unsigned int j = index[i];
216 fSumW[i] += fSumW[i-1];
217 fSumW2[i] += fSumW2[i-1];
219 fSumW[i] += fSampleWeights[j];
220 fSumW2[i] += fSampleWeights[j]*fSampleWeights[j];
222 sortedDist[i] = fSamplingDist[ j] ;
223 sortedWeights[i] = fSampleWeights[ j] ;
227 fSamplingDist = sortedDist;
228 fSampleWeights = sortedWeights;
238 Double_t SamplingDistribution::IntegralAndError(Double_t & error, Double_t low, Double_t high, Bool_t normalize, Bool_t lowClosed, Bool_t
241 int n = fSamplingDist.size();
243 error = numeric_limits<Double_t>::infinity();
247 if (
int(fSumW.size()) != n)
256 indexLow = std::lower_bound( fSamplingDist.begin(), fSamplingDist.end() , low) - fSamplingDist.begin() -1;
260 indexLow = std::upper_bound( fSamplingDist.begin(), fSamplingDist.end() , low) - fSamplingDist.begin() - 1;
265 indexHigh = std::upper_bound( fSamplingDist.begin(), fSamplingDist.end() , high) - fSamplingDist.begin() -1;
268 indexHigh = std::lower_bound( fSamplingDist.begin(), fSamplingDist.end() , high) - fSamplingDist.begin() -1;
273 assert(indexLow < n && indexHigh < n);
278 if (indexHigh >= 0) {
279 sum = fSumW[indexHigh];
280 sum2 = fSumW2[indexHigh];
283 sum -= fSumW[indexLow];
284 sum2 -= fSumW2[indexLow];
290 double norm = fSumW.back();
291 double norm2 = fSumW2.back();
297 error = std::sqrt( sum2 * (1. - 2. * sum) + norm2 * sum * sum ) / norm;
300 error = std::sqrt(sum2);
310 Double_t SamplingDistribution::CDF(Double_t x)
const {
311 return Integral(-RooNumber::infinity(), x, kTRUE, kTRUE, kTRUE);
317 Double_t SamplingDistribution::InverseCDF(Double_t pvalue)
320 return InverseCDF(pvalue,0,dummy);
326 Double_t SamplingDistribution::InverseCDF(Double_t pvalue,
327 Double_t sigmaVariation,
328 Double_t& inverseWithVariation)
330 if (fSumW.size() != fSamplingDist.size())
333 if (!TMath::AreEqualRel(fSumW.back(), fSumW2.back(), 1.E-6) )
334 Warning(
"InverseCDF",
"Estimation of Quantiles (InverseCDF) for weighted events is not yet supported");
349 int nominal = (
unsigned int) (pvalue*fSamplingDist.size());
352 inverseWithVariation = -1.*RooNumber::infinity();
353 return -1.*RooNumber::infinity();
355 else if(nominal >= (Int_t)fSamplingDist.size()-1 ) {
356 inverseWithVariation = RooNumber::infinity();
357 return RooNumber::infinity();
359 else if(pvalue < 0.5){
360 int delta = (int)(sigmaVariation*sqrt(1.0*nominal));
361 int variation = nominal+delta;
363 if(variation>=(Int_t)fSamplingDist.size()-1)
364 inverseWithVariation = RooNumber::infinity();
365 else if(variation<=0)
366 inverseWithVariation = -1.*RooNumber::infinity();
368 inverseWithVariation = fSamplingDist[ variation ];
370 return fSamplingDist[nominal];
372 else if(pvalue >= 0.5){
373 int delta = (int)(sigmaVariation*sqrt(1.0*fSamplingDist.size()- nominal));
374 int variation = nominal+delta;
377 if(variation>=(Int_t)fSamplingDist.size()-1)
378 inverseWithVariation = RooNumber::infinity();
380 else if(variation<=0)
381 inverseWithVariation = -1.*RooNumber::infinity();
383 inverseWithVariation = fSamplingDist[ variation+1 ];
392 return fSamplingDist[nominal+1];
395 std::cout <<
"problem in SamplingDistribution::InverseCDF" << std::endl;
397 inverseWithVariation = RooNumber::infinity();
398 return RooNumber::infinity();
406 Double_t SamplingDistribution::InverseCDFInterpolate(Double_t pvalue)
408 if (fSumW.size() != fSamplingDist.size())
411 if (!TMath::AreEqualRel(fSumW.back(), fSumW2.back(), 1.E-6) )
412 Warning(
"InverseCDFInterpolate",
"Estimation of Quantiles (InverseCDF) for weighted events is not yet supported.");
415 int nominal = (
unsigned int) (pvalue*fSamplingDist.size());
418 return -1.*RooNumber::infinity();
420 if(nominal >= (Int_t)fSamplingDist.size()-1 ) {
421 return RooNumber::infinity();
423 Double_t upperX = fSamplingDist[nominal+1];
424 Double_t upperY = ((Double_t) (nominal+1))/fSamplingDist.size();
425 Double_t lowerX = fSamplingDist[nominal];
426 Double_t lowerY = ((Double_t) nominal)/fSamplingDist.size();
430 return (upperX-lowerX)/(upperY-lowerY)*(pvalue-lowerY)+lowerX;