Using NUISMIN
Support for tuning generator parameters is also included in NUISANCE through an interface with the ROOT minimiser libraries. Note for nuismin to be built ROOT must be built with minuit and mathmore: see here.
Example: MiniBooNE Mode Tuning
In the following example we will perform a simple tuning of MAQE to MiniBooNE CCQE data, recreating the MiniBooNE puzzle in NUISANCE.
Writing a card file
If nuismin is successfully built it can be used by specifying some RW parameters as free in the card file, listing appropriate limits for the dials and step sizes alongside its definition. When run such a card file will vary all free parameters until the likelihood calculated through comparison to listed datasets (see nuiscomp for details on specifying datasets) is minimised.
simpletuning.card :
# Specify RW dials genie_parameter MaCCQE 0.0 -3.0 3.0 1.0 FREE norm_parameter MiniBooNE_CCQE_XSec_1DQ2_nu_norm 1.0 0.5 4.0 0.1 FREE # Load MiniBooNE CCQE Sample sample MiniBooNE_CCQE_XSec_1DQ2_nu GENIE:gntp.genie.file.root
Lets review what is in this card file before we run it. At the start we specify the MaCCQE and MiniBooNE_CCQE_XSec_1DQ2_nu_norm parameters should be varied until a best fit likelihood is found. MaCCQE is a RW parameter listed in $GENIE/src/ReWeight/GSyst.h, any RW dials given in the supported generators NUISANCE can have access to by specifying its name. MiniBooNE_CCQE_XSec_1DQ2_nu_norm is a total normalisation parameter which allows us to float the normalisation of the MC we provide to the data freely (similar to a floating total flux normalisation).
Limits of -3.0 to 3.0 sigma and a step size of 1.0 are applied to MaCCQE. Limits of 0.5 to 4.0 and a step size of 0.1 are applied to MiniBooNE_CCQE_XSec_1DQ2_nu_norm. The starting values for MaCCQE and MiniBooNE_CCQE_XSec_1DQ2_nu_norm are set to 0.0 respectively. Both parameters are set to FREE in this example, but in one of the later examples we will show that specific dials can be set to fixed chosen values using "FIX" in this option instead.
Finally we list the datasets that should be used to create a likelihood. Only one, the MiniBooNE CCQE data, is used here. But it is also possible to list multiple 'sample' lines, so that their likelihoods are added together (assuming no correlations) to form a larger joint likelihood.
Running this fit is then as simple as the following command
Running nuismin
Now that we have written out card file we can run it like so
$ nuismin -c simpletuning.card -o simpletuning.root
This will run the nuisance minimiser with default options and try to find a best fit by varying both parameters. Careful, this could take a while!
Whilst we wait for this to run, lets go through what is going on under the hood. When we pass a card file to minimiser, first it sets up each of the dataset comparisons previously discussed in the nuiscomp example. Then it parses the reweight parameters specified and sets up a ROOT minimiser instance. nuismin then runs through a list of 'Routines' which are used to run the minimisation. The best fit results from each routine are passed into the next routine so it is possible to string together a long list of possible minimisations if you are trying to tune a model using a particularly complicated likelihood surface. By default nuismin runs the following routine: Migrad,FixAtLim?,Migrad Which will try and find a minimum, check if any parameters are near a limit and if they are fix them at that limit, then rerun the Migrad from this point. It is possible however to override this default using the "-f" flag and passing a comma seperated list of fit commands.
Some examples of fit commands are given below, with usage examples given later on.
- Migrad :
- Combined :
- Simplex :
- FixAtLim? :
Okay, back to tuning. When a tuning is ran, the ROOT minimiser will request a likelihood from the NUISANCE JointFCN class given a specific parameter set. The JointFCN is in simple terms just a wrapper that creates all the different data-MC comparisons, and returns a summed likelihood. When this request is made, the JointFCN resets all the MC histograms in NUISANCE, then begins to loop through each of the event samples. For each signal event it calculates an event weight given the specific parameter set that has been chosen and fills this into the MC histograms to produce updated predictions. Once all events have been looped over a prediction is generated for each dataset and a likelihood is returned.
This process is repeated for each iteration of the fit, so if Minuit has to calculate the likelihood 600 times, the event loop also has to be ran 600 times. As a result minimisations can sometimes take days, depending on how many events are being ran, so the best thing to do is leave your job running and come back this example when it has finished.
If your minimisation has finished you should see a Minimisation Complete output and the root file can be opened. Contained in this file are the same histograms we discussed in the NuisComp? usage example, but this time the MC predictions are the best fit predictions obtained from the fit. Alongside these histograms the following are saved:
- fit_dials : Histogram showing the best fit parameter results and their errors
- correlation : Correlation matrix for the best fit parameter set obtained from the last Minuit call