//Set the function parameters bool NormalisedSumPDF::SetPhysicsParameters( ParameterSet * NewParameterSet ) { PhysicsParameter * newFraction = NewParameterSet->GetPhysicsParameter(fractionName); if ( newFraction->GetUnit() == "NameNotFoundError" ) { cerr << "Parameter \"" << (string)fractionName << "\" expected but not found" << endl; return false; } else { double newFractionValue = newFraction->GetValue(); //Stupidity check if ( newFractionValue > 1.0 || newFractionValue < 0.0 ) { //cerr << "Requested impossible fraction: " << newFractionValue << endl; //return false; } else { firstFraction = newFractionValue; firstPDF->UpdatePhysicsParameters( NewParameterSet ); secondPDF->UpdatePhysicsParameters( NewParameterSet ); bool output = allParameters.SetPhysicsParameters( NewParameterSet ); return output; } } return false; }
//Use Migrad to minimise the given function void FumiliWrapper::Minimise() { ParameterSet * newParameters = RapidFunction->GetParameterSet(); vector<string> allNames = newParameters->GetAllNames(); // int numParams = allNames.size(); /* // Fill a vector of doubles for each set of physics parameters that you // want to sample. What about case where Apara_sq + Aperp_sq > 1? vector< vector<double> > positions; PhysicsBottle* bottle = NewFunction->GetPhysicsBottle(); ParameterSet* parameters = bottle->GetParameterSet(); vector<string> names = parameters->GetAllNames(); double nsteps = 1; for( int k = 0; k < names.size(); ++k) { for( int j = 0; j < nsteps; ++j) { vector<double> tempPos; for( int i = 0; i < names.size(); ++i ) { double value; if ( i != k ) { value = parameters->GetPhysicsParameter(names[i])->GetValue(); } else { double min = parameters->GetPhysicsParameter(names[i])->GetMinimum(); double max = parameters->GetPhysicsParameter(names[i])->GetMaximum(); double step = (max - min)/nsteps; value = min + j * step; } tempPos.push_back(value); } positions.push_back(tempPos); } } */ // Fill a vector of doubles for each set of observables vector< vector<double> > positions; PhysicsBottle* bottle = RapidFunction->GetPhysicsBottle(); PhaseSpaceBoundary* boundary = bottle->GetResultDataSet(0)->GetBoundary(); vector<string> names = boundary->GetAllNames(); vector<double> observableSteps; int nsteps = 10; // Could make this faster... for ( int step = 0; step < nsteps; ++step) { vector<double> tempPos; for( unsigned int observable = 0; observable < names.size(); ++observable ) { if ( !boundary->GetConstraint(names[observable])->IsDiscrete() ) { double min = boundary->GetConstraint(names[observable])->GetMinimum(); double max = boundary->GetConstraint(names[observable])->GetMinimum(); double delta = (max - min)/nsteps; double position = min + step*delta; tempPos.push_back( position ); } else { double value = boundary->GetConstraint(names[observable])->CreateObservable()->GetValue(); tempPos.push_back( value ); } } positions.push_back(tempPos); } // Now, get the FumiliFCNBase function which will be passed to the Fumili minimiser FumiliStandardMaximumLikelihoodFCN fumFCN( *function, positions ); // Setup the minimiser MnFumiliMinimize fumili( fumFCN, *( function->GetMnUserParameters() ), (unsigned)Quality);//MINUIT_QUALITY); // Do the minimisation FunctionMinimum minimum = fumili( (unsigned)maxSteps, bestTolerance );//(int)MAXIMUM_MINIMISATION_STEPS, FINAL_GRADIENT_TOLERANCE ); // Once we have the FunctionMinimum, code same as in other Wrappers //Create the fit results const MnUserParameters * minimisedParameters = &minimum.UserParameters(); ResultParameterSet * fittedParameters = new ResultParameterSet( allNames ); for ( unsigned int nameIndex = 0; nameIndex < allNames.size(); ++nameIndex) { string parameterName = allNames[nameIndex]; PhysicsParameter * oldParameter = newParameters->GetPhysicsParameter( parameterName ); double parameterValue = minimisedParameters->Value( parameterName.c_str() ); double parameterError = minimisedParameters->Error( parameterName.c_str() ); fittedParameters->SetResultParameter( parameterName, parameterValue, oldParameter->GetOriginalValue(), parameterError, -oldParameter->GetMinimum(), oldParameter->GetMaximum(), oldParameter->GetType(), oldParameter->GetUnit() ); } int fitStatus; if ( !minimum.HasCovariance() ) { fitStatus = 0; } else if ( !minimum.HasAccurateCovar() ) { fitStatus = 1; } else if ( minimum.HasMadePosDefCovar() ) { fitStatus = 2; } else { fitStatus = 3; } PhysicsBottle* newBottle = RapidFunction->GetPhysicsBottle(); fitResult = new FitResult( minimum.Fval(), fittedParameters, fitStatus, newBottle ); }