示例#1
0
//Assemble the vectors of parameter/observable names needed
void SumPDF::MakePrototypes( PhaseSpaceBoundary * InputBoundary )
{
	//Make sure the ratio of the two PDFs is included
	vector<string> secondParameterSet = secondPDF->GetPrototypeParameterSet();
	secondParameterSet.push_back(fractionName);

	//Make the prototype parameter set
	prototypeParameterSet = StringProcessing::CombineUniques( firstPDF->GetPrototypeParameterSet(), secondParameterSet );

	//Make the prototype data point
	vector<string> firstObservables = firstPDF->GetPrototypeDataPoint();
	vector<string> secondObservables = secondPDF->GetPrototypeDataPoint();
	prototypeDataPoint = StringProcessing::CombineUniques( firstObservables, secondObservables );

	//Make the do not integrate list
	doNotIntegrateList = StringProcessing::CombineUniques( firstPDF->GetDoNotIntegrateList(), secondPDF->GetDoNotIntegrateList() );

	//Make the correctionss to the integrals for observables unused by only one PDF
	vector<string>::iterator observableIterator;
	IConstraint * inputConstraint;
	firstIntegralCorrection = 1.0;
	secondIntegralCorrection = 1.0;
	bool doIntegrate=false;
	for ( observableIterator = firstObservables.begin(); observableIterator != firstObservables.end(); ++observableIterator )
	{
		if ( StringProcessing::VectorContains( &secondObservables, &(*observableIterator) ) == -1 )
		{
			//The first PDF uses this observable, the second doesn't
			inputConstraint = InputBoundary->GetConstraint( *observableIterator );
			doIntegrate = ( StringProcessing::VectorContains( &doNotIntegrateList, &(*observableIterator) ) == -1 );

			//Update this integral correction
			if ( !inputConstraint->IsDiscrete() && doIntegrate )
			{
				secondIntegralCorrection *= ( inputConstraint->GetMaximum() - inputConstraint->GetMinimum() );
			}
		}
	}
	for ( observableIterator = secondObservables.begin(); observableIterator != secondObservables.end(); ++observableIterator )
	{
		if ( StringProcessing::VectorContains( &firstObservables, &(*observableIterator) ) == -1 )
		{
			//The second PDF uses this observable, the first doesn't
			inputConstraint = InputBoundary->GetConstraint( *observableIterator );
			doIntegrate = ( StringProcessing::VectorContains( &doNotIntegrateList, &(*observableIterator) ) == -1 );

			//Update this integral correction
			if ( !inputConstraint->IsDiscrete() && doIntegrate )
			{
				firstIntegralCorrection *= ( inputConstraint->GetMaximum() - inputConstraint->GetMinimum() );
			}
		}
	}
}
示例#2
0
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;
}
// 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) ;
}
//.................................
// 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;
}
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 ;
}
double RapidFitIntegrator::MultiDimentionIntegral( IPDF* functionToWrap, AdaptiveIntegratorMultiDim* multiDimensionIntegrator, const DataPoint * NewDataPoint, const PhaseSpaceBoundary * NewBoundary,
		ComponentRef* componentIndex, vector<string> doIntegrate, vector<string> dontIntegrate, bool haveTestedIntegral, DebugClass* debug )
{
	(void) haveTestedIntegral;
	//Make arrays of the observable ranges to integrate over
	double* minima = new double[ doIntegrate.size() ];
	double* maxima = new double[ doIntegrate.size() ];

	for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex )
	{
		IConstraint * newConstraint = NULL;
		try
		{
			newConstraint = NewBoundary->GetConstraint( doIntegrate[observableIndex] );
		}
		catch(...)
		{
			cerr << "RapidFitIntegrator: Could NOT find required Constraint " << doIntegrate[observableIndex] << " in Data PhaseSpaceBoundary" << endl;
			cerr << "RapidFitIntegrator: Please Fix this by Adding the Constraint to your PhaseSpace for PDF: " << functionToWrap->GetLabel() << endl;
			cerr << endl;
			exit(-8737);
		}
		minima[observableIndex] = (double)newConstraint->GetMinimum();
		maxima[observableIndex] = (double)newConstraint->GetMaximum();
	}

	//Do a 2-15D integration

	vector<double> minima_v, maxima_v;
	for( unsigned int i=0; i< doIntegrate.size(); ++i )
	{
		minima_v.push_back( minima[i] );
		maxima_v.push_back( maxima[i] );
	}

	IntegratorFunction* quickFunction = new IntegratorFunction( functionToWrap, NewDataPoint, doIntegrate, dontIntegrate, NewBoundary, componentIndex, minima_v, maxima_v );
	if( debug != NULL ) quickFunction->SetDebug( debug );

	multiDimensionIntegrator->SetFunction( *quickFunction );

	double output =  multiDimensionIntegrator->Integral( minima, maxima );

	delete[] minima; delete[] maxima;
	delete quickFunction;

	return output;
}
double RapidFitIntegrator::OneDimentionIntegral( IPDF* functionToWrap, IntegratorOneDim * oneDimensionIntegrator, const DataPoint * NewDataPoint, const PhaseSpaceBoundary * NewBoundary,
		ComponentRef* componentIndex, vector<string> doIntegrate, vector<string> dontIntegrate, bool haveTestedIntegral, DebugClass* debug )
{
	(void) haveTestedIntegral;
	IntegratorFunction* quickFunction = new IntegratorFunction( functionToWrap, NewDataPoint, doIntegrate, dontIntegrate, NewBoundary, componentIndex );
	if( debug != NULL )
	{
		quickFunction->SetDebug( debug );
		if( debug->DebugThisClass( "RapidFitIntegrator" ) )
		{
			cout << "RapidFitIntegrator: 1D Setting Up Constraints" << endl;
		}
	}
	//cout << "here" << endl;
	//Find the observable range to integrate over
	IConstraint * newConstraint = NULL;
	try
	{
		newConstraint = NewBoundary->GetConstraint( doIntegrate[0] );
	}
	catch(...)
	{
		cerr << "RapidFitIntegrator: Could NOT find required Constraint " << doIntegrate[0] << " in Data PhaseSpaceBoundary" << endl;
		cerr << "RapidFitIntegrator: Please Fix this by Adding the Constraint to your PhaseSpace for PDF: " << functionToWrap->GetLabel() << endl;
		cerr << endl;
		exit(-8737);
	}
	//IConstraint * newConstraint = NewBoundary->GetConstraint( doIntegrate[0] );
	double minimum = newConstraint->GetMinimum();
	double maximum = newConstraint->GetMaximum();

	//cout << "here2" << endl;
	//cout << "1D Integration" << endl;
	//Do a 1D integration
	oneDimensionIntegrator->SetFunction(*quickFunction);

	//cout << "Performing 1DInt" << endl;
	double output = oneDimensionIntegrator->Integral( minimum, maximum );
	//cout << output << endl;

	//cout << "here3" << endl;
	delete quickFunction;

	return output;
}
// 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;
}
示例#9
0
	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 RapidFitIntegrator::PseudoRandomNumberIntegralThreaded( IPDF* functionToWrap, const DataPoint * NewDataPoint, const PhaseSpaceBoundary * NewBoundary,
		ComponentRef* componentIndex, vector<string> doIntegrate, vector<string> dontIntegrate, unsigned int num_threads, unsigned int GSLFixedPoints, DebugClass* debug )
{
#ifdef __RAPIDFIT_USE_GSL

	(void) dontIntegrate;
	/*
	   cout << endl << "Using: " << num_threads << endl;
	   cout << "Do:" << endl;
	   for( unsigned int i=0; i< doIntegrate.size();++i )
	   {
	   cout << doIntegrate[i] << endl;
	   }
	   cout << "Dont:" << endl;
	   for( unsigned int i=0; i< dontIntegrate.size();++i )
	   {
	   cout << dontIntegrate[i] << endl;
	   }
	   */

	//Make arrays of the observable ranges to integrate over
	double* minima = new double[ doIntegrate.size() ];
	double* maxima = new double[ doIntegrate.size() ];

	if( debug != NULL )
	{
		if( debug->DebugThisClass( "RapidFitIntegrator" ) )
		{
			cout << "RapidFitIntegrator: Starting to use GSL PseudoRandomNumberThreaded :D" << endl;
		}
	}

	for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex )
	{
		IConstraint * newConstraint = NULL;
		try
		{
			newConstraint = NewBoundary->GetConstraint( doIntegrate[observableIndex] );
		}
		catch(...)
		{
			cerr << "RapidFitIntegrator: Could NOT find required Constraint " << doIntegrate[observableIndex] << " in Data PhaseSpaceBoundary" << endl;
			cerr << "RapidFitIntegrator: Please Fix this by Adding the Constraint to your PhaseSpace for PDF: " << functionToWrap->GetLabel() << endl;
			cerr << endl;
			exit(-8737);
		}
		minima[observableIndex] = (double)newConstraint->GetMinimum();
		maxima[observableIndex] = (double)newConstraint->GetMaximum();
	}

	if( debug != NULL )
	{
		if( debug->DebugThisClass( "RapidFitIntegrator" ) )
		{
			cout << "RapidFitIntegrator: Doing GSL stuff..." << endl;
		}
	}

	vector<double> minima_v, maxima_v;
	for( unsigned int i=0; i< doIntegrate.size(); ++i )
	{
		minima_v.push_back( minima[i] );
		maxima_v.push_back( maxima[i] );
	}

	//	the whole new/delete here is because I'm too lazy to lookup how to cast away the const from a pointer...

	DataPoint* templateDataPoint = new DataPoint( *NewDataPoint );

	vector<DataPoint*> doEval_points = RapidFitIntegrator::getGSLIntegrationPoints( GSLFixedPoints, maxima_v, minima_v, templateDataPoint, doIntegrate );

	delete templateDataPoint;

	PhaseSpaceBoundary* thisBound = new PhaseSpaceBoundary( *NewBoundary );

	IDataSet* thisDataSet = new MemoryDataSet( thisBound, doEval_points );

	delete thisBound;

	ThreadingConfig* thisConfig = new ThreadingConfig();
	thisConfig->numThreads = num_threads;
	thisConfig->MultiThreadingInstance = "pthreads";
	thisConfig->wantedComponent = new ComponentRef( *componentIndex );

	vector<double>* thisSet = MultiThreadedFunctions::ParallelEvaulate( functionToWrap, thisDataSet, thisConfig );

	delete[] minima;
	delete[] maxima;
	delete thisConfig->wantedComponent;
	delete thisConfig;

	double result=0.;
	for( unsigned int i=0; i< thisSet->size(); ++i )	result+=thisSet->at( i );

	delete thisSet;

	double factor=1.;
	for( unsigned int i=0; i< (unsigned)doIntegrate.size(); ++i )
	{
		factor *= maxima[i]-minima[i];
	}

	result /= ( (double)doEval_points.size() / factor );

	return result;
#else
	(void) functionToWrap; (void) NewDataPoint; (void) NewBoundary; (void) componentIndex; (void) doIntegrate; (void) dontIntegrate; (void) num_threads;
	return -99999.;
#endif
}
double RapidFitIntegrator::PseudoRandomNumberIntegral( IPDF* functionToWrap, const DataPoint * NewDataPoint, const PhaseSpaceBoundary * NewBoundary,
		ComponentRef* componentIndex, vector<string> doIntegrate, vector<string> dontIntegrate, unsigned int GSLFixedPoints )
{
#ifdef __RAPIDFIT_USE_GSL

	//Make arrays of the observable ranges to integrate over
	double* minima = new double[ doIntegrate.size() ];
	double* maxima = new double[ doIntegrate.size() ];

	for (unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex )
	{
		IConstraint * newConstraint = NULL;
		try
		{
			newConstraint = NewBoundary->GetConstraint( doIntegrate[observableIndex] );
		}
		catch(...)
		{
			cerr << "RapidFitIntegrator: Could NOT find required Constraint " << doIntegrate[observableIndex] << " in Data PhaseSpaceBoundary" << endl;
			cerr << "RapidFitIntegrator: Please Fix this by Adding the Constraint to your PhaseSpace for PDF: " << functionToWrap->GetLabel() << endl;
			cerr << endl;
			exit(-8737);
		}
		minima[observableIndex] = (double)newConstraint->GetMinimum();
		maxima[observableIndex] = (double)newConstraint->GetMaximum();
	}

	unsigned int npoint = GSLFixedPoints;
	vector<double> * integrationPoints = new std::vector<double>[doIntegrate.size()];

	//gsl_qrng * q = gsl_qrng_alloc( gsl_qrng_sobol, (unsigned)(doIntegrate.size()) );
	gsl_qrng * q = gsl_qrng_alloc( gsl_qrng_niederreiter_2, (unsigned)(doIntegrate.size()) );
	for (unsigned int i = 0; i < npoint; i++)
	{
		double v[doIntegrate.size()];
		gsl_qrng_get(q, v);
		for ( unsigned int j = 0; j < doIntegrate.size(); j++)
		{
			integrationPoints[j].push_back(v[j]);
		}
	}
	gsl_qrng_free(q);

	vector<double> minima_v, maxima_v;
	for( unsigned int i=0; i< doIntegrate.size(); ++i )
	{
		minima_v.push_back( minima[i] );
		maxima_v.push_back( maxima[i] );
	}
	IntegratorFunction* quickFunction = new IntegratorFunction( functionToWrap, NewDataPoint, doIntegrate, dontIntegrate, NewBoundary, componentIndex, minima_v, maxima_v );

	//cout << endl;
	double result = 0.;
	for (unsigned int i = 0; i < integrationPoints[0].size(); ++i)
	{
		double* point = new double[ doIntegrate.size() ];
		for ( unsigned int j = 0; j < doIntegrate.size(); j++)
		{
			//cout << doIntegrate[j] << " " << maxima[j] << " " << minima[j] << " " << integrationPoints[j][i] << endl;
			point[j] = integrationPoints[j][i]*(maxima[j]-minima[j])+minima[j];
		}
		//cout << i << "\r" << flush;
		result += quickFunction->DoEval( point );
		delete[] point;
	}
	double factor=1.;
	for( unsigned int i=0; i< (unsigned)doIntegrate.size(); ++i )
	{
		factor *= maxima[i]-minima[i];
	}
	result /= ( (double)integrationPoints[0].size() / factor );

	//cout << "GSL :D" << endl;

	delete[] minima; delete[] maxima;
	//delete[] integrationPoints;
	delete quickFunction;
	return result;
#else
	(void) functionToWrap; (void) NewDataPoint; (void) NewBoundary; (void) componentIndex; (void) doIntegrate; (void) dontIntegrate;
	return -1.;
#endif
}
示例#12
0
double RapidFitIntegrator::PseudoRandomNumberIntegralThreaded( IPDF* functionToWrap, const DataPoint * NewDataPoint, const PhaseSpaceBoundary * NewBoundary,
		ComponentRef* componentIndex, vector<string> doIntegrate, vector<string> dontIntegrate, unsigned int num_threads, unsigned int GSLFixedPoints )
{
#ifdef __RAPIDFIT_USE_GSL

	(void) dontIntegrate;
	/*
	   cout << endl << "Using: " << num_threads << endl;
	   cout << "Do:" << endl;
	   for( unsigned int i=0; i< doIntegrate.size();++i )
	   {
	   cout << doIntegrate[i] << endl;
	   }
	   cout << "Dont:" << endl;
	   for( unsigned int i=0; i< dontIntegrate.size();++i )
	   {
	   cout << dontIntegrate[i] << endl;
	   }
	 */

	//Make arrays of the observable ranges to integrate over
	double* minima = new double[ doIntegrate.size() ];
	double* maxima = new double[ doIntegrate.size() ];

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << "RapidFitIntegrator: Starting to use GSL PseudoRandomNumberThreaded :D" << endl;
		//for( unsigned int i=0; i< doIntegrate.size(); ++i ) cout << doIntegrate[i] << "\t";
		//cout << endl;
		//for( unsigned int i=0; i< dontIntegrate.size(); ++i ) cout << dontIntegrate[i] << "\t";
		//cout << endl;
		cout << "Component: " << componentIndex << endl;
		if( componentIndex != NULL ) cout << componentIndex->getComponentName() << endl;
	}

	for( unsigned int observableIndex = 0; observableIndex < doIntegrate.size(); ++observableIndex )
	{
		IConstraint * newConstraint = NULL;
		try
		{
			newConstraint = NewBoundary->GetConstraint( doIntegrate[observableIndex] );
		}
		catch(...)
		{
			cerr << "RapidFitIntegrator: Could NOT find required Constraint " << doIntegrate[observableIndex] << " in Data PhaseSpaceBoundary" << endl;
			cerr << "RapidFitIntegrator: Please Fix this by Adding the Constraint to your PhaseSpace for PDF: " << functionToWrap->GetLabel() << endl;
			cerr << endl;
			exit(-8737);
		}
		minima[observableIndex] = (double)newConstraint->GetMinimum();
		maxima[observableIndex] = (double)newConstraint->GetMaximum();
	}

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << "RapidFitIntegrator: Doing GSL stuff..." << endl;
	}

	vector<double> minima_v, maxima_v;
	for( unsigned int i=0; i< doIntegrate.size(); ++i )
	{
		minima_v.push_back( minima[i] );
		maxima_v.push_back( maxima[i] );
	}

	//	the whole new/delete here is because I'm too lazy to lookup how to cast away the const from a pointer...

	DataPoint* templateDataPoint = new DataPoint( *NewDataPoint );

	PhaseSpaceBoundary* thisBound = new PhaseSpaceBoundary( *NewBoundary );

	vector<DataPoint*> doEval_points = RapidFitIntegrator::getGSLIntegrationPoints( GSLFixedPoints, maxima_v, minima_v, templateDataPoint, doIntegrate, thisBound );

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << "RapidFitIntegrator:: " << doEval_points.size() << " GSL Points" << endl;
	}

	delete templateDataPoint;

	IDataSet* thisDataSet = new MemoryDataSet( thisBound, doEval_points );

	delete thisBound;

	ThreadingConfig* thisConfig = new ThreadingConfig();
	thisConfig->numThreads = num_threads;
	thisConfig->MultiThreadingInstance = "pthreads";

	if( componentIndex != NULL ) thisConfig->wantedComponent = new ComponentRef( *componentIndex );
	else thisConfig->wantedComponent = NULL;

	//	thisDataSet->GetDataPoint( 0 )->Print();

	//	cout << functionToWrap->GetName() << "\t0:\t" << functionToWrap->Evaluate( thisDataSet->GetDataPoint( 0 ) ) << endl;

	//	cout << functionToWrap->GetName() << "\t100:\t" << functionToWrap->Evaluate( thisDataSet->GetDataPoint( 100 ) ) << endl;

	//	if( componentIndex != NULL ) cout << functionToWrap->GetName() << "\t" << thisConfig->wantedComponent->getComponentName() << ":\t" << functionToWrap->EvaluateComponent( thisDataSet->GetDataPoint( 0 ), thisConfig->wantedComponent ) << endl;

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << "RapidFitIntegrator:: " << thisDataSet->GetDataNumber() << "  " << functionToWrap->GetLabel() << "  th: " << num_threads << endl;
		thisDataSet->GetDataPoint( 0 )->Print();
	}

	vector<double>* thisSet = MultiThreadedFunctions::ParallelEvaluate( functionToWrap, thisDataSet, thisConfig );

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << "RapidFitIntegrator:: Finished Eval" << endl;
	}

	delete thisDataSet;

	//	DebugClass::Dump2TTree( DebugClass::GetUniqueROOTFileName(), *thisSet );

	if( thisConfig->wantedComponent != NULL ) delete thisConfig->wantedComponent;
	delete thisConfig;

	double number_points = (double)GSLFixedPoints;

	double result=0.;
	double thisNum=0.;
	sort( thisSet->begin(), thisSet->end() );
	for( unsigned int i=0; i< thisSet->size(); ++i )
	{
		thisNum=thisSet->at( i );
		if( ( !std::isnan(thisNum) && fabs(thisNum)<DBL_MAX ) && ( !std::isinf(thisNum) ) )
		{
			result+=thisNum;
		}
		else// if( std::isnan(thisNum) || std::isinf(thisNum) )
		{
			--number_points;
		}
	}

	//cout << result << endl;

	double factor=1.;
	for( unsigned int i=0; i< (unsigned)doIntegrate.size(); ++i )
	{
		double diff = maxima[i]-minima[i];
		//cout << factor << "\t\t" << diff << endl;
		if( fabs( diff ) > 1E-99 ) factor *= diff;
	}

	//cout << factor << endl;

	//cout << GSLFixedPoints << endl;

	//cout << doEval_points.size() << endl;

	//cout << thisSet->size() << endl;

	result /= ( number_points / factor );

	//cout << result << endl;

	delete thisSet;

	delete[] minima;
	delete[] maxima;

	//cout << result << endl;

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << result << endl;
	}

	return result;
#else
	(void) functionToWrap; (void) NewDataPoint; (void) NewBoundary; (void) componentIndex; (void) doIntegrate; (void) dontIntegrate; (void) num_threads;
	return -99999.;
#endif
}
示例#13
0
double RapidFitIntegrator::OneDimentionIntegral( IPDF* functionToWrap, IntegratorOneDim * oneDimensionIntegrator, const DataPoint * NewDataPoint, const PhaseSpaceBoundary * NewBoundary,
		ComponentRef* componentIndex, vector<string> doIntegrate, vector<string> dontIntegrate )
{
	//NewDataPoint->Print();

	(void) oneDimensionIntegrator;

	IntegratorFunction* quickFunction = new IntegratorFunction( functionToWrap, NewDataPoint, doIntegrate, dontIntegrate, NewBoundary, componentIndex );
	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) )
	{
		cout << "RapidFitIntegrator: 1D Setting Up Constraints" << endl;
	}
	//cout << "here" << endl;
	//Find the observable range to integrate over
	IConstraint * newConstraint = NULL;
	try
	{
		newConstraint = NewBoundary->GetConstraint( doIntegrate[0] );
	}
	catch(...)
	{
		cerr << "RapidFitIntegrator: Could NOT find required Constraint " << doIntegrate[0] << " in Data PhaseSpaceBoundary" << endl;
		cerr << "RapidFitIntegrator: Please Fix this by Adding the Constraint to your PhaseSpace for PDF: " << functionToWrap->GetLabel() << endl;
		cerr << endl;
		exit(-8737);
	}
	//IConstraint * newConstraint = NewBoundary->GetConstraint( doIntegrate[0] );
	double minimum = newConstraint->GetMinimum();
	double maximum = newConstraint->GetMaximum();

	unsigned int n_eval = 10000;
	double step = (maximum-minimum)/((double)n_eval);

	vector<DataPoint*> thesePoints;

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) ) cout << "RapidFitIntegrator:: Constructing Points" << endl;

	for( unsigned int i=0; i< n_eval; ++i )
	{
		double thisPoint = minimum+step*((double)i);
		thesePoints.push_back( new DataPoint( *NewDataPoint ) );
		thesePoints[i]->SetObservable( doIntegrate[0], thisPoint, "noUnitsHere" );
	}

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) ) cout << "RapidFitIntegrator:: Evaluating Points" << endl;

	vector<double> evals;
	for( unsigned int i=0; i< n_eval; ++i )
	{
		try{
			evals.push_back( functionToWrap->Evaluate( thesePoints[i] ) );
		}
		catch(...)
		{
			evals.push_back( 0. );
			--n_eval;
		}
	}

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) ) cout << "RapidFitIntegrator:: Sorting Results" << endl;

	sort( evals.begin(), evals.end() );

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) ) cout << "RapidFitIntegrator:: Adding Results" << endl;

	double output=0.;
	for( unsigned int i=0; i< evals.size(); ++i )
	{
		output+= evals[i];
	}

	//cout << output << endl;
	//cout << maximum-minimum << endl;
	//cout << n_eval << endl;

	double factor = maximum-minimum;
	output /= ( ((double)n_eval) / factor );

	//cout << "1D:" << output << endl;

	//cout << "here3" << endl;
	delete quickFunction;

	if( DebugClass::DebugThisClass( "RapidFitIntegrator" ) ) cout << "RapidFitIntegrator:: Returning Integral" << endl;

	return output;
}
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 ;
}
示例#15
0
//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;
}