double Bd2JpsiKstar_sWave::Normalisation(DataPoint * measurement, PhaseSpaceBoundary * boundary) { double returnValue; IConstraint * timeBound = boundary->GetConstraint(timeconstraintName); time = measurement->GetObservable( timeName )->GetValue(); KstarFlavour = measurement->GetObservable( KstarFlavourName )->GetValue(); if ( timeBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on time not provided" << endl; return -1.; } else { tlo = timeBound->GetMinimum(); thi = timeBound->GetMaximum(); } if(timeRes1Frac >= 0.9999) { // Set the member variable for time resolution to the first value and calculate timeRes = timeRes1; returnValue = buildCompositePDFdenominator(); } else { // Set the member variable for time resolution to the first value and calculate timeRes = timeRes1; double val1 = buildCompositePDFdenominator(); // Set the member variable for time resolution to the second value and calculate timeRes = timeRes2; double val2 = buildCompositePDFdenominator(); //return timeRes1Frac*val1 + (1. - timeRes1Frac)*val2; returnValue = timeRes1Frac*val1 + (1. - timeRes1Frac)*val2; } if( (returnValue <= 0.) || std::isnan(returnValue) ) { cout << " Bd2JpsiKstar_sWave::Normalisation() returns <=0 or nan " << endl ; cout << " AT " << Aperp_sq ; cout << " AP " << Apara_sq ; cout << " A0 " << Azero_sq; cout << " As " << As_sq; cout << " Dperp " << delta_perp; cout << " Dpara " << delta_para; cout << " Ds " << delta_s << endl; cout << " gamma " << gamma << endl; exit(1) ; } return returnValue; }
//................................. // Calculate the PDF normalisation double Bs2DsPiBkg_withTimeRes::Normalisation(PhaseSpaceBoundary * boundary) { double tmin = 0.; double tmax = 0.; IConstraint * timeBound = boundary->GetConstraint(timeconstraintName); if ( timeBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on time not provided" << endl; return -1.; } else { tmin = timeBound->GetMinimum(); tmax = timeBound->GetMaximum(); } // Parameters double timeRes = allParameters.GetPhysicsParameter( timeResName )->GetValue(); double lifetimeBd = allParameters.GetPhysicsParameter( lifetimeBdName )->GetValue(); double gammaBd = 1. / lifetimeBd ; double val = Mathematics::ExpInt( tmin, tmax, gammaBd, timeRes ) ; return val; }
// int(1/(sigmaPr*sqrt(2*Pi))*exp(-(time)^2/(2*sigmaPr*sigmaPr)),time=tmin..tmax); // 1/2 1/2 // 2 tmin 2 tmax // -1/2 erf(---------) + 1/2 erf(---------) // 2 sigmaPr 2 sigmaPr double Bs2JpsiPhiPromptBkg_tripleGaussian::Normalisation(PhaseSpaceBoundary * boundary) { double tmin = 0.; double tmax = 0.; IConstraint * timeBound = boundary->GetConstraint(timeconstraintName); if ( timeBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on time not provided" << endl; exit(1) ; } else { tmin = timeBound->GetMinimum(); tmax = timeBound->GetMaximum(); } //Extract parameters double sigmaPr1 = allParameters.GetPhysicsParameter( sigmaPr1Name )->GetValue(); double sigmaPr2 = allParameters.GetPhysicsParameter( sigmaPr2Name )->GetValue(); double sigmaPr3 = allParameters.GetPhysicsParameter( sigmaPr3Name )->GetValue(); double frac1 = allParameters.GetPhysicsParameter( frac_sigmaPr1Name )->GetValue(); double frac23 = allParameters.GetPhysicsParameter( frac_sigmaPr23Name )->GetValue(); //Reality checks if( sigmaPr1 <= 0. ) {cout << "Bs2JpsiPhiPromptBkg_tripleGaussian::Normalisation() : sigmaPr1 < 0 : " << sigmaPr1 << endl ;exit(1); } if( sigmaPr2 <= 0. ) {cout << "Bs2JpsiPhiPromptBkg_tripleGaussian::Normalisation() : sigmaPr2 < 0 : " << sigmaPr2 << endl ; exit(1); } if( sigmaPr3 <= 0. ) {cout << "Bs2JpsiPhiPromptBkg_tripleGaussian::Normalisation() : sigmaPr3 < 0 : " << sigmaPr3 << endl ; exit(1); } double val1 = 0.5 * ( erf( tmax/(sqrt(2.)*sigmaPr1) ) - erf( tmin/(sqrt(2.)*sigmaPr1 )) ); double val2 = 0.5 * ( erf( tmax/(sqrt(2.)*sigmaPr2) ) - erf( tmin/(sqrt(2.)*sigmaPr2 )) ); double val3 = 0.5 * ( erf( tmax/(sqrt(2.)*sigmaPr3) ) - erf( tmin/(sqrt(2.)*sigmaPr3 )) ); return frac1*val1 + (1.-frac1)*(frac23*val2 + (1.-frac23)*val3) ; }
double Bs2JpsiPhi_mistagObservable_alt::Normalisation(DataPoint * measurement, PhaseSpaceBoundary * boundary) { // Get observables into member variables t = measurement->GetObservable( timeName )->GetValue() - timeOffset; ctheta_tr = measurement->GetObservable( cosThetaName )->GetValue(); phi_tr = measurement->GetObservable( phiName )->GetValue(); ctheta_1 = measurement->GetObservable( cosPsiName )->GetValue(); tagFraction = measurement->GetObservable( mistagName )->GetValue(); //tagFraction= 0.5; //PELC // Get time boundaries into member variables IConstraint * timeBound = boundary->GetConstraint("time"); if ( timeBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on time not provided" << endl; return 0; } else { tlo = timeBound->GetMinimum(); thi = timeBound->GetMaximum(); } // Recalculate cached values if Physics parameters have changed // Must do this for each of the two resolutions. //PELC // I dont think you can cache any more as normalisation depends upon the mistag which now changes per event. if( true /*! normalisationCacheValid*/ ) { for( tag = -1; tag <= 1; tag ++ ) { resolution = resolution1 ; normalisationCacheValueRes1[tag+1] = this->diffXsecNorm1( ); resolution = resolution2 ; normalisationCacheValueRes2[tag+1] = this->diffXsecNorm1( ); } normalisationCacheValid = true ; } // Return normalisation value according to tag tag = (int)measurement->GetObservable( tagName )->GetValue(); double returnValue = resolution1Fraction*normalisationCacheValueRes1[tag+1] + (1. - resolution1Fraction)*normalisationCacheValueRes2[tag+1] ; if( (returnValue <= 0.) || isnan(returnValue) ) { cout << " Bs2JpsiPhi_mistagObservable_alt::Normalisation() returns <=0 or nan " << endl ; cout << " gamma " << gamma() ; cout << " gl " << gamma_l() ; cout << " gh " << gamma_h() ; cout << " AT " << AT() ; cout << " AP " << AP() ; cout << " A0 " << A0() ; exit(1) ; } return returnValue ; }
// int(1/(sigmaPr*sqrt(2*Pi))*exp(-(time)^2/(2*sigmaPr*sigmaPr)),time=tmin..tmax); // 1/2 1/2 // 2 tmin 2 tmax // -1/2 erf(---------) + 1/2 erf(---------) // 2 sigmaPr 2 sigmaPr double Bs2JpsiPhiPromptBkg_withTimeRes::Normalisation(PhaseSpaceBoundary * boundary) { double tmin = 0.; double tmax = 0.; IConstraint * timeBound = boundary->GetConstraint( timeconstraintName ); if ( timeBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on time not provided" << endl; return -1.; } else { tmin = timeBound->GetMinimum(); tmax = timeBound->GetMaximum(); } double sigmaPr = allParameters.GetPhysicsParameter( sigmaPrName )->GetValue(); double val = 0.5 * ( erf( tmax/(sqrt(2.)*sigmaPr) ) - erf( tmin/(sqrt(2.)*sigmaPr )) ); return val; }
void copyPhaseSpaceBoundary( PhaseSpaceBoundary * newBoundary, PhaseSpaceBoundary * oldBoundary ) { vector<string> names = oldBoundary->GetAllNames(); vector<string>::iterator nameIter = names.begin(); vector<double> values; double min, max; string unit; for ( ; nameIter != names.end(); ++nameIter ) { IConstraint * constraint = oldBoundary->GetConstraint( *nameIter ); unit = constraint->GetUnit(); if ( constraint->IsDiscrete() ) { values = constraint->GetValues(); newBoundary->SetConstraint( *nameIter, values, unit ); } else { min = constraint->GetMinimum(); max = constraint->GetMaximum(); newBoundary->SetConstraint( *nameIter, min, max, unit ); } } }
double Bs2JpsiPhi_SignalAlt_MO_v4::Normalisation(DataPoint * measurement, PhaseSpaceBoundary * boundary) { if( _numericIntegralForce ) return -1. ; // Get observables into member variables tag = (int)measurement->GetObservable( tagName )->GetValue(); _mistag = measurement->GetObservable( mistagName )->GetValue() ; if( useEventResolution() ) eventResolution = measurement->GetObservable( eventResolutionName )->GetValue(); // Get time boundaries into member variables IConstraint * timeBound = boundary->GetConstraint( timeName ); if ( timeBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on time not provided" << endl; return 0; } else { tlo = timeBound->GetMinimum(); thi = timeBound->GetMaximum(); } //*** This is what will be returned.*** //How it is calcualted depends upon how resolution is treated double returnValue=0 ; // If we are going to use event-by-event resolution, then all the caching is irrelevant and will be bypassed. // You cant cache either untagged or tagged since the resolution will change from event to event and affect the normalisation. if( useEventResolution() ) { if( resolutionScale <=0. ) resolution = 0. ; else resolution = eventResolution * resolutionScale ; returnValue = this->diffXsecCompositeNorm1( 0 ); } //We are not going to use event by event resolution so we can use all the caching machinery else { //First job for any new set of parameters is to Cache the time integrals if( ! timeIntegralCacheValid ) { CacheTimeIntegrals() ; timeIntegralCacheValid = true ; // if( ! useEventResolution() ) timeIntegralCacheValid = true ; } //If this is an untagged event and the result has been cached, then it can be used // Otherwise must calculate the normalisation if( (tag==0) && normalisationCacheValid ) { returnValue = normalisationCacheUntagged ; } //So we need to calculate the normalisation else { if( resolutionScale <= 0. ) { resolution = 0. ; returnValue = this->diffXsecCompositeNorm1( 0 ); } else { double val1=0. , val2=0., val3=0. ; double resolution1Fraction = 1. - resolution2Fraction - resolution3Fraction ; if(resolution1Fraction > 0 ) { resolution = resolution1 * resolutionScale ; val1 = this->diffXsecCompositeNorm1( 1 ); } if(resolution2Fraction > 0 ) { resolution = resolution2 * resolutionScale ; val2 = this->diffXsecCompositeNorm1( 2 ); } if(resolution3Fraction > 0 ) { resolution = resolution3 * resolutionScale ; val3 = this->diffXsecCompositeNorm1( 3 ); } returnValue = resolution1Fraction*val1 + resolution2Fraction*val2 + resolution3Fraction*val3 ; } } // If this is an untagged event then the normaisation is invariant and so can be cached //if( (tag==0) && !normalisationCacheValid && !useEventResolution() ) { if( (tag==0) && !normalisationCacheValid ) { normalisationCacheUntagged = returnValue ; normalisationCacheValid = true ; } } // Conditions to throw exception bool c1 = std::isnan(returnValue) ; bool c2 = (returnValue <= 0.) ; if( DEBUGFLAG && (c1 || c2 ) ) { this->DebugPrint( " Bs2JpsiPhi_SignalAlt_MO_v4::Normalisation() returns <=0 or nan :" , returnValue ) ; if( std::isnan(returnValue) ) throw( 23 ); if( returnValue <= 0. ) throw( 823 ); } return returnValue ; }
//Constructor with correct argument MakeFoam::MakeFoam( IPDF * InputPDF, PhaseSpaceBoundary * InputBoundary, DataPoint * InputPoint ) : finishedCells(), centerPoints(), centerValues(), cellIntegrals(), integratePDF(InputPDF) { //Make the container to hold the possible cells queue<PhaseSpaceBoundary*> possibleCells; PhaseSpaceBoundary* firstCell = InputBoundary; possibleCells.push(firstCell); //Make a list of observables to integrate over vector<string> doIntegrate, dontIntegrate; vector<string> pdfDontIntegrate = InputPDF->GetDoNotIntegrateList(); StatisticsFunctions::DoDontIntegrateLists( InputPDF, InputBoundary, &(pdfDontIntegrate), doIntegrate, dontIntegrate ); //Continue until all possible cells have been examined while ( !possibleCells.empty() ) { //Remove the next possible cell PhaseSpaceBoundary* currentCell = possibleCells.front(); possibleCells.pop(); //Set up the histogram storage vector< vector<double> > histogramBinHeights, histogramBinMiddles, histogramBinMaxes; double normalisation = 0.0; for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { vector<double> binHeights, binMiddles, binMaxes; IConstraint * temporaryConstraint = currentCell->GetConstraint( doIntegrate[observableIndex] ); double minimum = temporaryConstraint->GetMinimum(); double delta = ( temporaryConstraint->GetMaximum() - minimum ) / (double)HISTOGRAM_BINS; //Loop over bins for (int binIndex = 0; binIndex < HISTOGRAM_BINS; ++binIndex ) { binHeights.push_back(0.0); binMiddles.push_back( minimum + ( delta * ( binIndex + 0.5 ) ) ); binMaxes.push_back( minimum + ( delta * ( binIndex + 1.0 ) ) ); } histogramBinHeights.push_back(binHeights); histogramBinMiddles.push_back(binMiddles); histogramBinMaxes.push_back(binMaxes); } //MC sample the cell, make projections, sort of for (int sampleIndex = 0; sampleIndex < MAXIMUM_SAMPLES; ++sampleIndex ) { //Create a data point within the current cell DataPoint samplePoint( InputPoint->GetAllNames() ); for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { //Generate random values to explore integrable observables IConstraint * temporaryConstraint = currentCell->GetConstraint( doIntegrate[observableIndex] ); samplePoint.SetObservable( doIntegrate[observableIndex], temporaryConstraint->CreateObservable() ); } for (unsigned int observableIndex = 0; observableIndex < dontIntegrate.size(); ++observableIndex ) { //Use given values for unintegrable observables Observable * temporaryObservable = new Observable( *(InputPoint->GetObservable( dontIntegrate[observableIndex] )) ); samplePoint.SetObservable( dontIntegrate[observableIndex], temporaryObservable ); delete temporaryObservable; } //Evaluate the function at this point double sampleValue = InputPDF->Evaluate( &samplePoint ); normalisation += sampleValue; //Populate the histogram for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { double observableValue = samplePoint.GetObservable( doIntegrate[observableIndex] )->GetValue(); for ( int binIndex = 0; binIndex < HISTOGRAM_BINS; ++binIndex ) { if ( observableValue < histogramBinMaxes[observableIndex][unsigned(binIndex)] ) { histogramBinHeights[observableIndex][unsigned(binIndex)] += sampleValue; break; } } } } //Normalise the histograms for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { for ( int binIndex = 0; binIndex < HISTOGRAM_BINS; ++binIndex ) { histogramBinHeights[observableIndex][unsigned(binIndex)] /= normalisation; } } //Find the maximum gradient vector<double> midPoints; string maximumGradientObservable, unit; double maximumGradient=0.; double lowPoint=0.; double splitPoint=0.; double highPoint=0.; for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { //Find the size of the cell in this observable IConstraint * temporaryConstraint = currentCell->GetConstraint( doIntegrate[observableIndex] ); double cellMaximum = temporaryConstraint->GetMaximum(); double cellMinimum = temporaryConstraint->GetMinimum(); //Store the mid point double observableMiddle = cellMinimum + ( ( cellMaximum - cellMinimum ) / 2.0 ); midPoints.push_back(observableMiddle); for ( int binIndex = 1; binIndex < HISTOGRAM_BINS; ++binIndex ) { double gradient = abs( histogramBinHeights[observableIndex][ unsigned(binIndex - 1) ] - histogramBinHeights[observableIndex][unsigned(binIndex)] ); //Update maximum if ( ( observableIndex == 0 && binIndex == 1 ) || gradient > maximumGradient ) { maximumGradient = gradient; maximumGradientObservable = doIntegrate[observableIndex]; unit = temporaryConstraint->GetUnit(); highPoint = cellMaximum; splitPoint = ( histogramBinMiddles[observableIndex][ unsigned(binIndex - 1) ] + histogramBinMiddles[observableIndex][unsigned(binIndex)] ) / 2.0; lowPoint = cellMinimum; } } } //If the maximum gradient is within tolerance, the cell is finished if ( maximumGradient < MAXIMUM_GRADIENT_TOLERANCE ) { //Store the finished cell finishedCells.push_back(currentCell); //Create a data point at the center of the current cell DataPoint* cellCenter = new DataPoint( InputPoint->GetAllNames() ); for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { //Use the mid points for the integrable values Observable * temporaryObservable = cellCenter->GetObservable( doIntegrate[observableIndex] ); Observable* temporaryObservable2 = new Observable( temporaryObservable->GetName(), midPoints[observableIndex], temporaryObservable->GetUnit() ); cellCenter->SetObservable( doIntegrate[observableIndex], temporaryObservable2 ); delete temporaryObservable2; } for (unsigned int observableIndex = 0; observableIndex < dontIntegrate.size(); ++observableIndex ) { //Use given values for unintegrable observables Observable * temporaryObservable = new Observable( *(InputPoint->GetObservable( dontIntegrate[observableIndex] )) ); cellCenter->SetObservable( dontIntegrate[observableIndex], temporaryObservable ); delete temporaryObservable; } //Store the center point centerPoints.push_back(cellCenter); } else { //Create two cells to replace the current cell PhaseSpaceBoundary* daughterCell1 = new PhaseSpaceBoundary( currentCell->GetAllNames() ); PhaseSpaceBoundary* daughterCell2 = new PhaseSpaceBoundary( currentCell->GetAllNames() ); for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { IConstraint * temporaryConstraint = currentCell->GetConstraint( doIntegrate[observableIndex] ); if ( doIntegrate[observableIndex] == maximumGradientObservable ) { //Split the cells on the observable with the greatest gradient daughterCell1->SetConstraint( doIntegrate[observableIndex], lowPoint, splitPoint, unit ); daughterCell2->SetConstraint( doIntegrate[observableIndex], splitPoint, highPoint, unit ); } else { //Copy the continuous constraint (if it can be integrated, it must be continuous) daughterCell1->SetConstraint( doIntegrate[observableIndex], temporaryConstraint->GetMinimum(), temporaryConstraint->GetMaximum(), temporaryConstraint->GetUnit() ); daughterCell2->SetConstraint( doIntegrate[observableIndex], temporaryConstraint->GetMinimum(), temporaryConstraint->GetMaximum(), temporaryConstraint->GetUnit() ); } } for (unsigned int observableIndex = 0; observableIndex < dontIntegrate.size(); ++observableIndex ) { IConstraint * temporaryConstraint = currentCell->GetConstraint( dontIntegrate[observableIndex] ); if ( temporaryConstraint->IsDiscrete() ) { //Copy the discrete constraint daughterCell1->SetConstraint( dontIntegrate[observableIndex], temporaryConstraint->GetValues(), temporaryConstraint->GetUnit() ); daughterCell2->SetConstraint( dontIntegrate[observableIndex], temporaryConstraint->GetValues(), temporaryConstraint->GetUnit() ); } else { //Copy the continuous constraint daughterCell1->SetConstraint( dontIntegrate[observableIndex], temporaryConstraint->GetMinimum(), temporaryConstraint->GetMaximum(), temporaryConstraint->GetUnit() ); daughterCell2->SetConstraint( dontIntegrate[observableIndex], temporaryConstraint->GetMinimum(), temporaryConstraint->GetMaximum(), temporaryConstraint->GetUnit() ); } } //Add the two new cells to the possibles possibleCells.push(daughterCell1); possibleCells.push(daughterCell2); } //Make sure you don't exceed the maximum number of cells if ( int(finishedCells.size() + possibleCells.size()) >= MAXIMUM_CELLS ) { cout << "MakeFoam warning: maximum cells reached with " << possibleCells.size() << " unexplored" << endl; //Dump out any possible cells into finished, without any further examination while ( !possibleCells.empty() ) { //Move the cell from "possible" to "finished" PhaseSpaceBoundary* temporaryCell = possibleCells.front(); possibleCells.pop(); finishedCells.push_back(temporaryCell); //Create a data point at the center of the current cell DataPoint* cellCenter = new DataPoint( InputPoint->GetAllNames() ); for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex ) { //Calculate the cell mid point IConstraint * temporaryConstraint = temporaryCell->GetConstraint( doIntegrate[observableIndex] ); double midPoint = temporaryConstraint->GetMinimum() + ( ( temporaryConstraint->GetMaximum() - temporaryConstraint->GetMinimum() ) / 2 ); //Use the mid points for the integrable values Observable * temporaryObservable = cellCenter->GetObservable( doIntegrate[observableIndex] ); Observable* temporaryObservable2 = new Observable( temporaryObservable->GetName(), midPoint, temporaryObservable->GetUnit() ); cellCenter->SetObservable( doIntegrate[observableIndex], temporaryObservable2 ); delete temporaryObservable2; } for (unsigned int observableIndex = 0; observableIndex < dontIntegrate.size(); ++observableIndex ) { //Use given values for unintegrable observables Observable * temporaryObservable = new Observable( *(InputPoint->GetObservable( dontIntegrate[observableIndex] )) ); cellCenter->SetObservable( dontIntegrate[observableIndex], temporaryObservable ); delete temporaryObservable; } //Store the center point centerPoints.push_back(cellCenter); } //Exit the foam loop break; } } //Now all the cells have been made! //Make a numerical integrator for the function RapidFitIntegrator cellIntegrator( InputPDF, true ); //Find the function value at the center of each cell, and the integral of the function over the cell for (unsigned int cellIndex = 0; cellIndex < finishedCells.size(); ++cellIndex ) { //Integrate the cell double integral = cellIntegrator.Integral( InputPoint, finishedCells[cellIndex] ); cellIntegrals.push_back(integral); //Evaluate the function at the center of the cell double value = InputPDF->Evaluate( centerPoints[cellIndex] ); centerValues.push_back(value); } }
double Bs2DsPi_lowmassbkg_updated::Normalisation(PhaseSpaceBoundary * boundary) { double mhigh, mlow, sum ; IConstraint * massBound = boundary->GetConstraint( constraint_massName ); if ( massBound->GetUnit() == "NameNotFoundError" ) { cerr << "Bound on mass not provided in Bs2DsPi_lowmassbkg_updated" << endl; return 1.0 ; } else { mlow = massBound->GetMinimum(); mhigh = massBound->GetMaximum(); } double histo_max=histo->GetXaxis()->GetBinUpEdge(nxbins); double histo_min=histo->GetXaxis()->GetBinLowEdge(1); double histo_range = histo_max - histo_min; double bin_width = histo_range / nxbins; int nbin_low =1; int nbin_high = nxbins; bool c0 = (mlow>mhigh) ; bool c1 = (mhigh>histo_max) || (mlow<histo_min) ; if ( c0 || c1 ) { cerr << "Mass boundaries aren't withing the background histogram range in Bs2DsPi_lowmassbkg_updated" << endl; exit(1) ; } for( nbin_low=1; nbin_low <= nxbins; ++nbin_low ) { if( histo->GetXaxis()->GetBinLowEdge(nbin_low) > mlow ) break ; } nbin_low--; for( nbin_high=nxbins; nbin_high >= 1; --nbin_high ) { if( histo->GetXaxis()->GetBinUpEdge(nbin_high) < mhigh ) break ; } nbin_high++; //cout << "mlow occurs in bin" << nbin_low << endl; //cout << "mhigh occurs in bin" << nbin_high << endl; sum = 0; for(int i = nbin_low; i <= nbin_high; ++i){ double bin_content = histo->GetBinContent(i); sum += (int) bin_content; //cout << "loop " << i << ", "; } //cout << "number of bins " << nxbins << endl; //cout << "sum of bins looped " << sum << endl; //cout << "histo range " << histo_range << endl; //cout << "bin_width " << bin_width << endl; //cout << "total number enteries in histo " << total_num_entries << endl; //cout << "end normalisation " << endl; double value = (sum * bin_width) / total_num_entries; //cout << "return " << value << endl; return value; }