ParameterSet* VectoredFeldmanCousins::getParameterSet( ParameterSet* inputSet, ResultParameterSet* inputResult ) { // Model 1 nuisence parameters are not changed if( nuisenceModel == 0 ) { return new ParameterSet( *inputSet ); } // Model 2 nuisence parameters are varied within 1 sigma of their true value else if( nuisenceModel == 1 ) { ParameterSet* tempSet = new ParameterSet( *inputSet ); vector<string> all_params = tempSet->GetAllNames(); for( vector<string>::iterator param_i = all_params.begin(); param_i != all_params.end(); ++param_i ) { PhysicsParameter* thisParameter = tempSet->GetPhysicsParameter( *param_i ); ResultParameter* thisResult = inputResult->GetResultParameter( *param_i ); if( thisParameter->GetType() != "Fixed" && !thisResult->GetScanStatus() ) { TRandom3* rand_gen = RapidFitRandom::GetRandomFunction(); double new_value = rand_gen->Gaus( thisResult->GetValue(), thisResult->GetError() ); thisParameter->SetBlindedValue( new_value ); thisParameter->SetStepSize( thisResult->GetError() ); } } return tempSet; } else { cout << endl << "\t\tUNKNOWN NUICENCE MODEL, NOT DOING ANTYTHING!!!!" << endl << endl; nuisenceModel = 0; return this->getParameterSet( inputSet, inputResult ); } }
//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 ); }
// Interface for internal calls void ScanStudies::DoScan( MinimiserConfiguration * MinimiserConfig, FitFunctionConfiguration * FunctionConfig, ParameterSet* BottleParameters, vector< PDFWithData* > BottleData, vector< ConstraintFunction* > BottleConstraints, ScanParam* Wanted_Param, FitResultVector* output_interface, int OutputLevel, bool forceContinue ) { FunctionConfig->SetIntegratorTest( false ); double uplim = Wanted_Param->GetMax(); double lolim = Wanted_Param->GetMin(); double npoints = Wanted_Param->GetPoints(); string scanName = Wanted_Param->GetName(); // cout << "Performing Scan for the parameter " << scanName << endl ; // Get a pointer to the physics parameter to be scanned and fix it // CAREFUL: this must be reset as it was at the end. PhysicsParameter* scanParameter = NULL; try{ scanParameter = BottleParameters->GetPhysicsParameter(scanName); } catch(...) { cerr << "Couldn't find Parameter: " << scanName << ". Can NOT perform scan!" << endl << endl; exit(3763); } double originalValue = scanParameter->GetBlindedValue(); string originalType = scanParameter->GetType(); if( originalType == "Fixed" && fabs(uplim-lolim) < 1E-5 ) { cerr << "Cannot Run a scan Using Parameter: " << scanName << endl; exit(3764); } scanParameter->SetType( "Fixed" ) ; BottleParameters->FloatedFirst(); scanParameter = BottleParameters->GetPhysicsParameter(scanName); // Need to set up a loop , fixing the scan parameter at each point double deltaScan=0.; for( int si=0; si<int(npoints); ++si) { cout << "\n\nSINGLE SCAN NUMBER\t\t" << si+1 << "\t\tOF\t\t" <<int(npoints)<< endl<<endl; // Set scan parameter value if( int(npoints)!=1 ) deltaScan = (uplim-lolim) / (npoints-1.) ; else deltaScan=0; double scanVal = lolim+deltaScan*si; // The FitFunction has the ability to change the content of the input ParameterSet by definition as it isn't defined as const scanParameter = BottleParameters->GetPhysicsParameter(scanName); scanParameter->SetBlindedValue( scanVal ) ; cout << "Fitting at:\t" << scanName << "=" << setw(6) << scanVal << setw(6) << " " << "StepSize: " << deltaScan << endl; output_interface->StartStopwatch(); FitResult* scanStepResult=NULL; //BottleParameters->Print(); try{ // Use the SafeFit as this always returns something when a PDF has been written to throw not exit // Do a scan point fit //BottleParameters->Print(); scanStepResult = FitAssembler::DoSafeFit( MinimiserConfig, FunctionConfig, BottleParameters, BottleData, BottleConstraints, forceContinue, OutputLevel ); } catch( int e ) { cerr << "Caught Scan Error: " << e << endl; exit(-987); } catch( ... ) { cerr << "Caught Unknown Scan Error" << endl; exit(-986); } int retries = 0; int left_right = 1; int wiggle_step_num = 0; double scanVal_orig = scanVal; double wiggle_step_size = deltaScan/20.; while( scanStepResult->GetFitStatus() != 3 ) { if( retries != 1 ) { cout << "\n\t\t\tRETRYING FIT" << endl; scanVal = scanVal_orig; ++retries; } else { if( int(wiggle_step_num/2)*2 == wiggle_step_num ) // Even { left_right = 1; } else // Odd { left_right = -1; } // remember 0/2 and 1/2 are both 0 as an integer scanVal = scanVal_orig + (double)left_right * wiggle_step_size * (double)int((wiggle_step_num)/2 + 1); cout << "\tStepping to: " << scanVal << " Retrying!" << endl; ++wiggle_step_num; } // Perform 10 steps either side of minima with 20th of the step size // when more than 10 steps either side have strayed into next point on the scan // This 'wiggle is only done in 1D here if( wiggle_step_num >= 20 ) break; scanParameter->SetBlindedValue( scanVal ) ; output_interface->StartStopwatch(); scanStepResult = FitAssembler::DoSafeFit( MinimiserConfig, FunctionConfig, BottleParameters, BottleData, BottleConstraints, forceContinue, OutputLevel ); } cout << "Fit Finished!\n" <<endl; // THIS IS ALWAYS TRUE BY DEFINITION OF THE SCAN string name = Wanted_Param->GetName(); string type = BottleParameters->GetPhysicsParameter( name )->GetType(); string unit = BottleParameters->GetPhysicsParameter( name )->GetUnit(); scanStepResult->GetResultParameterSet()->SetResultParameter( name, scanVal, scanVal, 0., scanVal, scanVal, type, unit ); vector<string> Fixed_List = BottleParameters->GetAllFixedNames(); vector<string> Fit_List = scanStepResult->GetResultParameterSet()->GetAllNames(); for( unsigned short int i=0; i < Fixed_List.size() ; ++i ) { bool found=false; for( unsigned short int j=0; j < Fit_List.size(); ++j ) { if( Fit_List[j] == Fixed_List[i] ) { found = true; } } if( !found ) { string fixed_type = BottleParameters->GetPhysicsParameter( Fixed_List[i] )->GetType(); string fixed_unit = BottleParameters->GetPhysicsParameter( Fixed_List[i] )->GetUnit(); double fixed_value = BottleParameters->GetPhysicsParameter( Fixed_List[i] )->GetValue(); scanStepResult->GetResultParameterSet()->ForceNewResultParameter( Fixed_List[i], fixed_value, fixed_value, 0., fixed_value, fixed_value, fixed_type, fixed_unit ); } } scanStepResult->GetResultParameterSet()->GetResultParameter( scanName )->SetScanStatus( true ); ResultFormatter::ReviewOutput( scanStepResult ); output_interface->AddFitResult( scanStepResult ); } // Reset the parameter as it was scanParameter = BottleParameters->GetPhysicsParameter(scanName); scanParameter->SetType( originalType ) ; scanParameter->SetBlindedValue( originalValue ) ; }
// Interface for internal calls void ScanStudies::DoScan2D( MinimiserConfiguration * MinimiserConfig, FitFunctionConfiguration * FunctionConfig, ParameterSet* BottleParameters, vector< PDFWithData* > BottleData, vector< ConstraintFunction* > BottleConstraints, pair<ScanParam*, ScanParam*> Param_Set, vector<FitResultVector*>* output_interface, int OutputLevel, bool forceContinue ) { FunctionConfig->SetIntegratorTest( false ); // vector<string> namez = BottleParameters->GetAllNames(); vector<string> result_names = BottleParameters->GetAllNames(); double uplim = Param_Set.first->GetMax(); double lolim = Param_Set.first->GetMin(); double npoints = Param_Set.first->GetPoints(); string scanName = Param_Set.first->GetName(); string scanName2 = Param_Set.second->GetName(); // Get a pointer to the physics parameter to be scanned and fix it // CAREFUL: this must be reset as it was at the end. PhysicsParameter* scanParameter = NULL; try{ scanParameter = BottleParameters->GetPhysicsParameter(scanName); } catch(...) { cerr << "Couldn't find Parameter: " << scanName << ". Can NOT perform scan!" << endl << endl; exit(3763); } double originalValue = scanParameter->GetBlindedValue( ); string originalType = scanParameter->GetType( ); if( originalType == "Fixed" && fabs(uplim-lolim) < 1E-5 ) { cerr << "Cannot Run a scan Using Parameter: " << scanName << endl << endl; exit(3764); } scanParameter->SetType( "Fixed" ); // Need to set up a loop , fixing the scan parameter at each point double deltaScan=0.; if( int(npoints) !=1 ) deltaScan = (uplim-lolim) / (npoints-1.) ; else deltaScan=0.; for( int si=0; si < int(npoints); ++si ) { cout << "\n\n2DSCAN OUTER NUMBER\t\t" << si+1 << "\t\tOF\t\t" << int(npoints) <<endl<<endl; FitResultVector* Returnable_Result = new FitResultVector( result_names ); // Set scan parameter value double scanVal = lolim + si*deltaScan; cout << "Fitting at:\t" << scanName << "=" << setw(6) << scanVal << setw(6) << " " << "StepSize: " << deltaScan << endl; // The FitFunction has the ability to change the content of the input ParameterSet by definition as it isn't defined as const scanParameter = BottleParameters->GetPhysicsParameter(scanName); scanParameter->SetBlindedValue( scanVal ); // Do a scan point fit ScanStudies::DoScan( MinimiserConfig, FunctionConfig, BottleParameters, BottleData, BottleConstraints, Param_Set.second, Returnable_Result, OutputLevel, forceContinue ); // // // Would be nice to add an additional wiggle here for the 2D as this would improve things at the usual cost // // // THIS IS ALWAYS TRUE BY DEFINITION OF THE SCAN string name = Param_Set.first->GetName(); string type = BottleParameters->GetPhysicsParameter( name )->GetType(); string unit = BottleParameters->GetPhysicsParameter( name )->GetUnit(); for( short int i=0; i < Returnable_Result->NumberResults(); ++i ) { Returnable_Result->GetFitResult( i )->GetResultParameterSet()->SetResultParameter( name, scanVal, scanVal, 0., scanVal, scanVal, type, unit ); Returnable_Result->GetFitResult( i )->GetResultParameterSet()->GetResultParameter( scanName )->SetScanStatus( true ); } output_interface->push_back( Returnable_Result ); } //Reset the parameter as it was scanParameter = BottleParameters->GetPhysicsParameter(scanName); scanParameter->SetType( originalType ) ; scanParameter->SetBlindedValue( originalValue ) ; }