Exemple #1
0
def plot_posterior_params(frames, template_settings, plot_llh=True,
                          plot_param_info=True, pbins=20, mctrue=False,
                          **kwargs):
    """Plot posterior parameter distributions, and related data"""

    good_columns = get_free_params(
        select_hierarchy(template_settings, normal_hierarchy=True)).keys()

    #good_columns = [col for col in frames[0].columns
    #                if col not in ['hypo','mctrue']]
    if plot_llh: good_columns.append('llh')
    print "good_columns: \n",good_columns

    max_plots_per_fig = 4
    nfigs = (len(good_columns)-1)/max_plots_per_fig + 1
    logging.info("len(good_cols): %d, nfigs: %d"%(len(good_columns),nfigs))

    figs = []
    fig_names = []
    colors = ['b','r','g','k','c','m']
    for frame in frames:
        ifig = 0
        true_key = frame['mctrue'][0]
        hypo_key = frame['hypo'][0]

        for icol,col_name in enumerate(good_columns):
            column = frame[col_name]
            # Create new fig if needed:
            if (icol%max_plots_per_fig) == 0:
                ifig += 1
                fig = plt.figure(figsize=(10,10))
                fig_names.append(true_key+"_"+hypo_key+"_"+str(ifig)+".png")
                figs.append(fig)
                fig.suptitle('Posteriors for %s, %s'%(true_key,hypo_key))
                             #fontsize='large')

            # Why is this not adding subplot?...
            subplot = (icol%max_plots_per_fig + 1)
            color = 'k' if plot_param_info else colors[icol%len(colors)]

            plot_column(
                true_key, hypo_key, subplot, column, template_settings,
                color,plot_param_info=plot_param_info,pbins=pbins,
                mctrue=mctrue)

    return figs,fig_names
Exemple #2
0
def createStepList(params, true_normal, grid_settings):
    """
    No matter how many params are listed as free, force only theta23 to be free.
    """

    new_params = fixAllButTheta23(params)

    free_params = select_hierarchy(get_free_params(new_params),
                                   normal_hierarchy=true_normal)
    fixed_params = select_hierarchy(get_fixed_params(new_params),
                                    normal_hierarchy=true_normal)
    calc_steps(free_params, grid_settings['steps'])

    # Form list from all parameters that holds a list of (name,step) tuples.

    steplist = free_params['theta23']['steps']

    return steplist
Exemple #3
0
def createStepList(params,true_normal,grid_settings):
    """
    No matter how many params are listed as free, force only theta23 to be free.
    """

    new_params = fixAllButTheta23(params)

    free_params = select_hierarchy(get_free_params(new_params),
                                   normal_hierarchy=true_normal)
    fixed_params = select_hierarchy(get_fixed_params(new_params),
                                    normal_hierarchy=true_normal)
    calc_steps(free_params, grid_settings['steps'])

    # Form list from all parameters that holds a list of (name,step) tuples.

    steplist = free_params['theta23']['steps']

    return steplist
Exemple #4
0
def get_fisher_matrices(template_settings, grid_settings, IMH=True, NMH=False, dump_all_stages=False,
		        save_templates=False, outdir=None):
  '''
  Main function that runs the Fisher analysis for the chosen hierarchy(ies) (inverted by default).

  Returns a dictionary of Fisher matrices, in the format:
  {'IMH': {'cscd': [...],
          'trck': [...],
          'comb': [...],
          },
  'NMH': {'cscd': [...],
          'trck': [...],
          'comb': [...],
         }
  }

  If save_templates=True and no hierarchy is given, only fiducial templates will be written out;
  if one is given, then the templates used to obtain the gradients will be written out in
  addition.
  '''
  if outdir is None and (save_templates or dump_all_stages):
    logging.info("No output directory specified. Will save templates to current working directory.")
    outdir = os.getcwd()

  profile.info("start initializing")

  # Get the parameters
  params = template_settings['params']
  bins = template_settings['binning']

  # Artifically add the hierarchy parameter to the list of parameters
  # The method get_hierarchy_gradients below will know how to deal with it
  params['hierarchy_nh'] = { "value": 1., "range": [0.,1.],
                           "fixed": False, "prior": None}
  params['hierarchy_ih'] = { "value": 0., "range": [0.,1.],
                           "fixed": False, "prior": None}

  chosen_data = []
  if IMH:
    chosen_data.append(('IMH',False))
    logging.info("Fisher matrix will be built for IMH.")
  if NMH:
    chosen_data.append(('NMH',True))
    logging.info("Fisher matrix will be built for NMH.")
  if chosen_data == []:
    # In this case, only the fiducial maps (for both hierarchies) will be written
    logging.info("No Fisher matrices will be built.")

  # There is no sense in performing any of the following steps if no Fisher matrices are to be built
  # and no templates are to be saved.
  if chosen_data!=[] or dump_all_stages or save_templates:

    # Initialise return dict to hold Fisher matrices
    fisher = { data_tag:{'cscd':[],'trck':[],'comb':[]} for data_tag, data_normal in chosen_data }

    # Get a template maker with the settings used to initialize
    template_maker = TemplateMaker(get_values(params),**bins)

    profile.info("stop initializing\n")

    # Generate fiducial templates for both hierarchies (needed for partial derivatives
    # w.r.t. hierarchy parameter)
    fiducial_maps = {}
    for hierarchy in ['NMH','IMH']:

      logging.info("Generating fiducial templates for %s."%hierarchy)

      # Get the fiducial parameter values corresponding to this hierarchy
      fiducial_params = select_hierarchy(params,normal_hierarchy=(hierarchy=='NMH'))

      # Generate fiducial maps, either all of them or only the ultimate one
      profile.info("start template calculation")
      with Timer() as t:
        fid_maps = template_maker.get_template(get_values(fiducial_params),
                                               return_stages=dump_all_stages)
      profile.info("==> elapsed time for template: %s sec"%t.secs)

      fiducial_maps[hierarchy] = fid_maps[4] if dump_all_stages else fid_maps

      # save fiducial map(s)
      # all stages
      if dump_all_stages:
        stage_names = ("0_unoscillated_flux","1_oscillated_flux","2_oscillated_counts","3_reco","4_pid")
        stage_maps = {}
        for stage in xrange(0,len(fid_maps)):
          stage_maps[stage_names[stage]] = fid_maps[stage]
        logging.info("Writing fiducial maps (all stages) for %s to %s."%(hierarchy,outdir))
        to_json(stage_maps,os.path.join(outdir,"fid_map_"+hierarchy+".json"))
      # only the final stage
      elif save_templates:
        logging.info("Writing fiducial map (final stage) for %s to %s."%(hierarchy,outdir))
        to_json(fiducial_maps[hierarchy],os.path.join(outdir,"fid_map_"+hierarchy+".json"))

    # Get_gradients and get_hierarchy_gradients will both (temporarily)
    # store the templates used to generate the gradient maps
    store_dir = outdir if save_templates else tempfile.gettempdir()

    # Calculate Fisher matrices for the user-defined cases (NHM true and/or IMH true)
    for data_tag, data_normal in chosen_data:

      logging.info("Running Fisher analysis for %s."%(data_tag))

      # The fiducial params are selected from the hierarchy case that does NOT match
      # the data, as we are varying from this model to find the 'best fit'
      fiducial_params = select_hierarchy(params,not data_normal)

      # Get the free parameters (i.e. those for which the gradients should be calculated)
      free_params = select_hierarchy(get_free_params(params),not data_normal)
      gradient_maps = {}
      for param in free_params.keys():
        # Special treatment for the hierarchy parameter
        if param=='hierarchy':
          gradient_maps[param] = get_hierarchy_gradients(data_tag,
						     fiducial_maps,
						     fiducial_params,
						     grid_settings,
						     store_dir,
						     )
        else:
          gradient_maps[param] = get_gradients(data_tag,
					   param,
                                           template_maker,
                                           fiducial_params,
                                           grid_settings,
                                           store_dir
                                           )

      logging.info("Building Fisher matrix for %s."%(data_tag))

      # Build Fisher matrices for the given hierarchy
      fisher[data_tag] = build_fisher_matrix(gradient_maps,fiducial_maps['IMH'] if data_normal else fiducial_maps['NMH'],fiducial_params)

      # If Fisher matrices exist for both channels, add the matrices to obtain the combined one.
      if len(fisher[data_tag].keys()) > 1:
        fisher[data_tag]['comb'] = FisherMatrix(matrix=np.array([f.matrix for f in fisher[data_tag].itervalues()]).sum(axis=0),
                                              parameters=gradient_maps.keys(),  #order is important here!
                                              best_fits=[fiducial_params[par]['value'] for par in gradient_maps.keys()],
                                              priors=[fiducial_params[par]['prior'] for par in gradient_maps.keys()],
                                              )
    return fisher

  else:
    logging.info("Nothing to be done.")
    return {}
Exemple #5
0
def find_max_llh_bfgs(fmap, template_maker, params, bfgs_settings, save_steps=False,
                      normal_hierarchy=None, check_octant=False):
    """
    Finds the template (and free systematic params) that maximize
    likelihood that the data came from the chosen template of true
    params, using the limited memory BFGS algorithm subject to bounds
    (l_bfgs_b).

    returns a dictionary of llh data and best fit params, in the format:
      {'llh': [...],
       'param1': [...],
       'param2': [...],
       ...}
    where 'param1', 'param2', ... are the free params varied by
    optimizer, and they hold a list of all the values tested in
    optimizer algorithm, unless save_steps is False, in which case
    they are one element in length-the best fit params and best fit llh.
    """

    # Get params dict which will be optimized (free_params) and which
    # won't be (fixed_params) but are still needed for get_template()
    fixed_params = get_fixed_params(select_hierarchy(params,normal_hierarchy))
    free_params = get_free_params(select_hierarchy(params,normal_hierarchy))

    if len(free_params) == 0:
        logging.warn("NO FREE PARAMS, returning LLH")
        true_template = template_maker.get_template(get_values(fixed_params))
        channel = params['channel']['value']
        true_fmap = flatten_map(true_template,chan=channel)
        return {'llh': [-get_binwise_llh(fmap,true_fmap)]}

    init_vals = get_param_values(free_params)
    scales = get_param_scales(free_params)
    bounds = get_param_bounds(free_params)
    priors = get_param_priors(free_params)
    names  = sorted(free_params.keys())

    # Scale init-vals and bounds to work with bfgs opt:
    init_vals = np.array(init_vals)*np.array(scales)
    bounds = [bounds[i]*scales[i] for i in range(len(bounds))]

    opt_steps_dict = {key:[] for key in names}
    opt_steps_dict['llh'] = []

    const_args = (names,scales,fmap,fixed_params,template_maker,opt_steps_dict,priors)

    display_optimizer_settings(free_params, names, init_vals, bounds, priors,
                               bfgs_settings)

    best_fit_vals,llh,dict_flags = opt.fmin_l_bfgs_b(
        llh_bfgs, init_vals, args=const_args, approx_grad=True, iprint=0,
        bounds=bounds, **get_values(bfgs_settings))

    # If needed, run optimizer again, checking for second octant solution:
    if check_octant and ('theta23' in free_params.keys()):
        physics.info("Checking alternative octant solution")
        old_th23_val = free_params['theta23']['value']
        delta = np.pi - old_th23_val
        free_params['theta23']['value'] = np.pi + delta
        init_vals = get_param_values(free_params)

        const_args = (names,scales,fmap,fixed_params,template_maker,opt_steps_dict,priors)
        display_optimizer_settings(free_params, names, init_vals, bounds, priors,
                                   bfgs_settings)
        alt_fit_vals,alt_llh,alt_dict_flags = opt.fmin_l_bfgs_b(
            llh_bfgs, init_vals, args=const_args, approx_grad=True, iprint=0,
            bounds=bounds, **get_values(bfgs_settings))

        # Alternative octant solution is optimal:
        if alt_llh < llh:
            best_fit_vals = alt_fit_vals
            llh = alt_llh
            dict_flags = alt_dict_flags


    best_fit_params = { name: value for name, value in zip(names, best_fit_vals) }

    #Report best fit
    physics.info('Found best LLH = %.2f in %d calls at:'
        %(llh,dict_flags['funcalls']))
    for name, val in best_fit_params.items():
        physics.info('  %20s = %6.4f'%(name,val))

    #Report any warnings if there are
    lvl = logging.WARN if (dict_flags['warnflag'] != 0) else logging.DEBUG
    for name, val in dict_flags.items():
        physics.log(lvl," %s : %s"%(name,val))

    if not save_steps:
        # Do not store the extra history of opt steps:
        for key in opt_steps_dict.keys():
            opt_steps_dict[key] = [opt_steps_dict[key][-1]]

    return opt_steps_dict
Exemple #6
0
def find_max_grid(fmap,
                  template_maker,
                  params,
                  grid_settings,
                  save_steps=True,
                  normal_hierarchy=True):
    '''
    Finds the template (and free systematic params) that maximize
    likelihood that the data came from the chosen template of true
    params, using a brute force grid scan over the whole parameter space.

    returns a dictionary of llh data and best fit params, in the format:
      {'llh': [...],
       'param1': [...],
       'param2': [...],
       ...}
    where 'param1', 'param2', ... are the free params that are varied in the
    scan. If save_steps is False, all lists only contain the best-fit parameters
    and llh values.
    '''

    #print "NOW INSIDE find_max_grid:"
    #print "After fixing to their true values, params dict is now: "
    #for key in params.keys():
    #    try: print "  >>param: %s value: %s"%(key,str(params[key]['best']))
    #    except: continue

    # Get params dict which will be optimized (free_params) and which
    # won't be (fixed_params) but are still needed for get_template()
    fixed_params = get_fixed_params(select_hierarchy(params, normal_hierarchy))
    free_params = get_free_params(select_hierarchy(params, normal_hierarchy))

    # Obtain just the priors
    priors = get_param_priors(free_params)

    # Calculate steps [(prior,value),...] for all free parameters
    calc_steps(free_params, grid_settings['steps'])

    # Build a list from all parameters that holds a list of (name, step) tuples
    steplist = [[(name, step) for step in param['steps']]
                for name, param in sorted(free_params.items())]

    # Prepare to store all the steps
    steps = {key: [] for key in free_params.keys()}
    steps['llh'] = []

    # Iterate over the cartesian product
    for pos in product(*steplist):

        # Get a dict with all parameter values at this position
        # including the fixed parameters
        template_params = dict(list(pos) + get_values(fixed_params).items())

        #print "   >> NOW IN LOOP: "
        #for key in template_params.keys():
        #    try: print "  >>param: %s value: %s"%(key,str(template_params[key]['value']))
        #    except: continue

        # Now get true template
        tprofile.info('start template calculation')
        true_template = template_maker.get_template(template_params)
        tprofile.info('stop template calculation')
        true_fmap = flatten_map(true_template)

        # and calculate the likelihood
        llh = -get_binwise_llh(fmap, true_fmap)

        # get sorted vals to match with priors
        vals = [v for k, v in sorted(pos)]
        llh -= sum([prior.llh(val) for val, prior in zip(vals, priors)])

        # Save all values to steps and report
        steps['llh'].append(llh)
        physics.debug("LLH is %.2f at: " % llh)
        for key, val in pos:
            steps[key].append(val)
            physics.debug(" %20s = %6.4f" % (key, val))

    # Find best fit value
    maxllh = min(steps['llh'])
    maxpos = steps['llh'].index(maxllh)

    # Report best fit
    physics.info('Found best LLH = %.2f in %d calls at:' %
                 (maxllh, len(steps['llh'])))
    for name, vals in steps.items():
        physics.info('  %20s = %6.4f' % (name, vals[maxpos]))

        # only save this maximum if asked for
        if not save_steps:
            steps[name] = vals[maxpos]

    return steps
Exemple #7
0
def find_max_llh_bfgs(fmap, template_maker, params, bfgs_settings, save_steps=False, normal_hierarchy=True):
    """
    Finds the template (and free systematic params) that maximize
    likelihood that the data came from the chosen template of true
    params, using the limited memory BFGS algorithm subject to bounds
    (l_bfgs_b).

    returns a dictionary of llh data and best fit params, in the format:
      {'llh': [...],
       'param1': [...],
       'param2': [...],
       ...}
    where 'param1', 'param2', ... are the free params varied by
    optimizer, and they hold a list of all the values tested in
    optimizer algorithm, unless save_steps is False, in which case
    they are one element in length-the best fit params and best fit llh.
    """

    # Get params dict which will be optimized (free_params) and which
    # won't be (fixed_params) but are still needed for get_template()
    fixed_params = get_fixed_params(select_hierarchy(params, normal_hierarchy))
    free_params = get_free_params(select_hierarchy(params, normal_hierarchy))

    init_vals = get_param_values(free_params)
    scales = get_param_scales(free_params)
    bounds = get_param_bounds(free_params)
    priors = get_param_priors(free_params)
    names = sorted(free_params.keys())

    # Scale init-vals and bounds to work with bfgs opt:
    init_vals = np.array(init_vals) * np.array(scales)
    bounds = [bounds[i] * scales[i] for i in range(len(bounds))]

    opt_steps_dict = {key: [] for key in names}
    opt_steps_dict["llh"] = []

    const_args = (names, scales, fmap, fixed_params, template_maker, opt_steps_dict, priors)

    physics.info("%d parameters to be optimized" % len(free_params))
    for name, init, (down, up), (prior, best) in zip(names, init_vals, bounds, priors):
        physics.info(
            ("%20s : init = %6.4f, bounds = [%6.4f,%6.4f], " "best = %6.4f, prior = " + ("%6.4f" if prior else "%s"))
            % (name, init, up, down, best, prior)
        )

    physics.debug("Optimizer settings:")
    for key, item in bfgs_settings.items():
        physics.debug("  %s -> `%s` = %.2e" % (item["desc"], key, item["value"]))

    best_fit_vals, llh, dict_flags = opt.fmin_l_bfgs_b(
        llh_bfgs, init_vals, args=const_args, approx_grad=True, iprint=0, bounds=bounds, **get_values(bfgs_settings)
    )

    best_fit_params = {name: value for name, value in zip(names, best_fit_vals)}

    # Report best fit
    physics.info("Found best LLH = %.2f in %d calls at:" % (llh, dict_flags["funcalls"]))
    for name, val in best_fit_params.items():
        physics.info("  %20s = %6.4f" % (name, val))

    # Report any warnings if there are
    lvl = logging.WARN if (dict_flags["warnflag"] != 0) else logging.DEBUG
    for name, val in dict_flags.items():
        physics.log(lvl, " %s : %s" % (name, val))

    if not save_steps:
        # Do not store the extra history of opt steps:
        for key in opt_steps_dict.keys():
            opt_steps_dict[key] = [opt_steps_dict[key][-1]]

    return opt_steps_dict
Exemple #8
0
def get_fisher_matrices(template_settings,
                        grid_settings,
                        IMH=True,
                        NMH=False,
                        dump_all_stages=False,
                        save_templates=False,
                        outdir=None):
    '''
  Main function that runs the Fisher analysis for the chosen hierarchy(ies) (inverted by default).

  Returns a dictionary of Fisher matrices, in the format:
  {'IMH': {'cscd': [...],
          'trck': [...],
          'comb': [...],
          },
  'NMH': {'cscd': [...],
          'trck': [...],
          'comb': [...],
         }
  }

  If save_templates=True and no hierarchy is given, only fiducial templates will be written out;
  if one is given, then the templates used to obtain the gradients will be written out in
  addition.
  '''
    if outdir is None and (save_templates or dump_all_stages):
        logging.info(
            "No output directory specified. Will save templates to current working directory."
        )
        outdir = os.getcwd()

    tprofile.info("start initializing")

    # Get the parameters
    params = template_settings['params']
    bins = template_settings['binning']

    # Artifically add the hierarchy parameter to the list of parameters
    # The method get_hierarchy_gradients below will know how to deal with it
    params['hierarchy_nh'] = {
        "value": 1.,
        "range": [0., 1.],
        "fixed": False,
        "prior": None
    }
    params['hierarchy_ih'] = {
        "value": 0.,
        "range": [0., 1.],
        "fixed": False,
        "prior": None
    }

    chosen_data = []
    if IMH:
        chosen_data.append(('IMH', False))
        logging.info("Fisher matrix will be built for IMH.")
    if NMH:
        chosen_data.append(('NMH', True))
        logging.info("Fisher matrix will be built for NMH.")
    if chosen_data == []:
        # In this case, only the fiducial maps (for both hierarchies) will be written
        logging.info("No Fisher matrices will be built.")

    # There is no sense in performing any of the following steps if no Fisher matrices are to be built
    # and no templates are to be saved.
    if chosen_data != [] or dump_all_stages or save_templates:

        # Initialise return dict to hold Fisher matrices
        fisher = {
            data_tag: {
                'cscd': [],
                'trck': [],
                'comb': []
            }
            for data_tag, data_normal in chosen_data
        }

        # Get a template maker with the settings used to initialize
        template_maker = TemplateMaker(get_values(params), **bins)

        tprofile.info("stop initializing\n")

        # Generate fiducial templates for both hierarchies (needed for partial derivatives
        # w.r.t. hierarchy parameter)
        fiducial_maps = {}
        for hierarchy in ['NMH', 'IMH']:

            logging.info("Generating fiducial templates for %s." % hierarchy)

            # Get the fiducial parameter values corresponding to this hierarchy
            fiducial_params = select_hierarchy(
                params, normal_hierarchy=(hierarchy == 'NMH'))

            # Generate fiducial maps, either all of them or only the ultimate one
            tprofile.info("start template calculation")
            with Timer() as t:
                fid_maps = template_maker.get_template(
                    get_values(fiducial_params), return_stages=dump_all_stages)
            tprofile.info("==> elapsed time for template: %s sec" % t.secs)

            fiducial_maps[
                hierarchy] = fid_maps[4] if dump_all_stages else fid_maps

            # save fiducial map(s)
            # all stages
            if dump_all_stages:
                stage_names = ("0_unoscillated_flux", "1_oscillated_flux",
                               "2_oscillated_counts", "3_reco", "4_pid")
                stage_maps = {}
                for stage in xrange(0, len(fid_maps)):
                    stage_maps[stage_names[stage]] = fid_maps[stage]
                logging.info(
                    "Writing fiducial maps (all stages) for %s to %s." %
                    (hierarchy, outdir))
                to_json(stage_maps,
                        os.path.join(outdir, "fid_map_" + hierarchy + ".json"))
            # only the final stage
            elif save_templates:
                logging.info(
                    "Writing fiducial map (final stage) for %s to %s." %
                    (hierarchy, outdir))
                to_json(fiducial_maps[hierarchy],
                        os.path.join(outdir, "fid_map_" + hierarchy + ".json"))

        # Get_gradients and get_hierarchy_gradients will both (temporarily)
        # store the templates used to generate the gradient maps
        store_dir = outdir if save_templates else tempfile.gettempdir()

        # Calculate Fisher matrices for the user-defined cases (NHM true and/or IMH true)
        for data_tag, data_normal in chosen_data:

            logging.info("Running Fisher analysis for %s." % (data_tag))

            # The fiducial params are selected from the hierarchy case that does NOT match
            # the data, as we are varying from this model to find the 'best fit'
            fiducial_params = select_hierarchy(params, not data_normal)

            # Get the free parameters (i.e. those for which the gradients should be calculated)
            free_params = select_hierarchy(get_free_params(params),
                                           not data_normal)
            gradient_maps = {}
            for param in free_params.keys():
                # Special treatment for the hierarchy parameter
                if param == 'hierarchy':
                    gradient_maps[param] = get_hierarchy_gradients(
                        data_tag=data_tag,
                        fiducial_maps=fiducial_maps,
                        fiducial_params=fiducial_params,
                        grid_settings=grid_settings,
                        store_dir=store_dir)
                else:
                    gradient_maps[param] = get_gradients(
                        data_tag=data_tag,
                        param=param,
                        template_maker=template_maker,
                        fiducial_params=fiducial_params,
                        grid_settings=grid_settings,
                        store_dir=store_dir)

            logging.info("Building Fisher matrix for %s." % (data_tag))

            # Build Fisher matrices for the given hierarchy
            fisher[data_tag] = build_fisher_matrix(
                gradient_maps=gradient_maps,
                fiducial_map=fiducial_maps['IMH']
                if data_normal else fiducial_maps['NMH'],
                template_settings=fiducial_params)

            # If Fisher matrices exist for both channels, add the matrices to obtain
            # the combined one.
            if len(fisher[data_tag].keys()) > 1:
                fisher[data_tag]['comb'] = FisherMatrix(
                    matrix=np.array([
                        f.matrix for f in fisher[data_tag].itervalues()
                    ]).sum(axis=0),
                    parameters=gradient_maps.keys(),  #order is important here!
                    best_fits=[
                        fiducial_params[par]['value']
                        for par in gradient_maps.keys()
                    ],
                    priors=[
                        Prior.from_param(fiducial_params[par])
                        for par in gradient_maps.keys()
                    ],
                )
        return fisher

    else:
        logging.info("Nothing to be done.")
        return {}
Exemple #9
0
params = template_settings['params']

mctrue_types = [('true_NMH', True), ('true_IMH', False)]

results = {}
# Store for future checking:
results['template_settings'] = template_settings
results['minimizer_settings'] = minimizer_settings
results['grid_settings'] = grid_settings

for true_tag, true_normal in mctrue_types:
    results[true_tag] = {}
    result = {}
    steplist = createStepList(params, true_normal, grid_settings)

    free_params = select_hierarchy(get_free_params(params),
                                   normal_hierarchy=true_normal)

    # Set up the arrays to store the true/fit values in:
    for key in free_params.keys():
        result['true_' + key] = []
        result['fit_' + key] = []
    result['asimov_data'] = []

    # This will actually only iterate over theta23 (for now), changing
    # the asimov data set:
    for step in steplist:

        print "Running at asimov parameters: %s" % step
        asimov_params = get_values(getAsimovParams(params, true_normal, step))
        asimov_data_set = get_asimov_fmap(template_maker,
Exemple #10
0
def find_max_llh_bfgs(fmap,
                      template_maker,
                      params,
                      bfgs_settings,
                      save_steps=False,
                      normal_hierarchy=None,
                      check_octant=False):
    """
    Finds the template (and free systematic params) that maximize
    likelihood that the data came from the chosen template of true
    params, using the limited memory BFGS algorithm subject to bounds
    (l_bfgs_b).

    returns a dictionary of llh data and best fit params, in the format:
      {'llh': [...],
       'param1': [...],
       'param2': [...],
       ...}
    where 'param1', 'param2', ... are the free params varied by
    optimizer, and they hold a list of all the values tested in
    optimizer algorithm, unless save_steps is False, in which case
    they are one element in length-the best fit params and best fit llh.
    """

    # Get params dict which will be optimized (free_params) and which
    # won't be (fixed_params) but are still needed for get_template()
    fixed_params = get_fixed_params(select_hierarchy(params, normal_hierarchy))
    free_params = get_free_params(select_hierarchy(params, normal_hierarchy))

    if len(free_params) == 0:
        logging.warn("NO FREE PARAMS, returning LLH")
        true_template = template_maker.get_template(get_values(fixed_params))
        channel = params['channel']['value']
        true_fmap = flatten_map(true_template, chan=channel)
        return {'llh': [-get_binwise_llh(fmap, true_fmap)]}

    init_vals = get_param_values(free_params)
    scales = get_param_scales(free_params)
    bounds = get_param_bounds(free_params)
    priors = get_param_priors(free_params)
    names = sorted(free_params.keys())

    # Scale init-vals and bounds to work with bfgs opt:
    init_vals = np.array(init_vals) * np.array(scales)
    bounds = [bounds[i] * scales[i] for i in range(len(bounds))]

    opt_steps_dict = {key: [] for key in names}
    opt_steps_dict['llh'] = []

    const_args = (names, scales, fmap, fixed_params, template_maker,
                  opt_steps_dict, priors)

    display_optimizer_settings(free_params, names, init_vals, bounds, priors,
                               bfgs_settings)

    best_fit_vals, llh, dict_flags = opt.fmin_l_bfgs_b(
        llh_bfgs,
        init_vals,
        args=const_args,
        approx_grad=True,
        iprint=0,
        bounds=bounds,
        **get_values(bfgs_settings))

    # If needed, run optimizer again, checking for second octant solution:
    if check_octant and ('theta23' in free_params.keys()):
        physics.info("Checking alternative octant solution")
        old_th23_val = free_params['theta23']['value']
        delta = np.pi - old_th23_val
        free_params['theta23']['value'] = np.pi + delta
        init_vals = get_param_values(free_params)

        const_args = (names, scales, fmap, fixed_params, template_maker,
                      opt_steps_dict, priors)
        display_optimizer_settings(free_params, names, init_vals, bounds,
                                   priors, bfgs_settings)
        alt_fit_vals, alt_llh, alt_dict_flags = opt.fmin_l_bfgs_b(
            llh_bfgs,
            init_vals,
            args=const_args,
            approx_grad=True,
            iprint=0,
            bounds=bounds,
            **get_values(bfgs_settings))

        # Alternative octant solution is optimal:
        if alt_llh < llh:
            best_fit_vals = alt_fit_vals
            llh = alt_llh
            dict_flags = alt_dict_flags

    best_fit_params = {
        name: value
        for name, value in zip(names, best_fit_vals)
    }

    #Report best fit
    physics.info('Found best LLH = %.2f in %d calls at:' %
                 (llh, dict_flags['funcalls']))
    for name, val in best_fit_params.items():
        physics.info('  %20s = %6.4f' % (name, val))

    #Report any warnings if there are
    lvl = logging.WARN if (dict_flags['warnflag'] != 0) else logging.DEBUG
    for name, val in dict_flags.items():
        physics.log(lvl, " %s : %s" % (name, val))

    if not save_steps:
        # Do not store the extra history of opt steps:
        for key in opt_steps_dict.keys():
            opt_steps_dict[key] = [opt_steps_dict[key][-1]]

    return opt_steps_dict
Exemple #11
0
def find_max_grid(fmap,template_maker,params,grid_settings,save_steps=True,
                                                     normal_hierarchy=True):
    '''
    Finds the template (and free systematic params) that maximize
    likelihood that the data came from the chosen template of true
    params, using a brute force grid scan over the whole parameter space.

    returns a dictionary of llh data and best fit params, in the format:
      {'llh': [...],
       'param1': [...],
       'param2': [...],
       ...}
    where 'param1', 'param2', ... are the free params that are varied in the
    scan. If save_steps is False, all lists only contain the best-fit parameters
    and llh values.
    '''

    #print "NOW INSIDE find_max_grid:"
    #print "After fixing to their true values, params dict is now: "
    #for key in params.keys():
    #    try: print "  >>param: %s value: %s"%(key,str(params[key]['best']))
    #    except: continue


    # Get params dict which will be optimized (free_params) and which
    # won't be (fixed_params) but are still needed for get_template()
    fixed_params = get_fixed_params(select_hierarchy(params,normal_hierarchy))
    free_params = get_free_params(select_hierarchy(params,normal_hierarchy))

    #Obtain just the priors
    priors = get_param_priors(free_params)

    #Calculate steps for all free parameters
    calc_steps(free_params, grid_settings['steps'])

    #Build a list from all parameters that holds a list of (name, step) tuples
    steplist = [ [(name,step) for step in param['steps']] for name, param in sorted(free_params.items())]

    #Prepare to store all the steps
    steps = {key:[] for key in free_params.keys()}
    steps['llh'] = []

    #Iterate over the cartesian product
    for pos in product(*steplist):

        #Get a dict with all parameter values at this position
        #including the fixed parameters
        template_params = dict(list(pos) + get_values(fixed_params).items())

        #print "   >> NOW IN LOOP: "
        #for key in template_params.keys():
        #    try: print "  >>param: %s value: %s"%(key,str(template_params[key]['value']))
        #    except: continue

        # Now get true template
        profile.info('start template calculation')
        true_template = template_maker.get_template(template_params)
        profile.info('stop template calculation')
        true_fmap = flatten_map(true_template)

        #and calculate the likelihood
        llh = -get_binwise_llh(fmap,true_fmap)

        #get sorted vals to match with priors
        vals = [ v for k,v in sorted(pos) ]
        llh -= sum([ get_prior_llh(vals,sigma,value) for (vals,(sigma,value)) in zip(vals,priors)])

        # Save all values to steps and report
        steps['llh'].append(llh)
        physics.debug("LLH is %.2f at: "%llh)
        for key, val in pos:
            steps[key].append(val)
            physics.debug(" %20s = %6.4f" %(key, val))

    #Find best fit value
    maxllh = min(steps['llh'])
    maxpos = steps['llh'].index(maxllh)

    #Report best fit
    physics.info('Found best LLH = %.2f in %d calls at:'
                 %(maxllh,len(steps['llh'])))
    for name, vals in steps.items():
        physics.info('  %20s = %6.4f'%(name,vals[maxpos]))

        #only save this maximum if asked for
        if not save_steps:
            steps[name]=vals[maxpos]

    return steps
Exemple #12
0
params = template_settings['params']

mctrue_types = [('true_NMH',True),('true_IMH',False)]

results = {}
# Store for future checking:
results['template_settings'] = template_settings
results['minimizer_settings'] = minimizer_settings
results['grid_settings'] = grid_settings

for true_tag, true_normal in mctrue_types:
    results[true_tag] = {}
    result = {}
    steplist = createStepList(params,true_normal,grid_settings)

    free_params = select_hierarchy(get_free_params(params),
                                   normal_hierarchy=true_normal)

    # Set up the arrays to store the true/fit values in:
    for key in free_params.keys():
        result['true_'+key] = []
        result['fit_'+key] = []
    result['asimov_data'] = []

    # This will actually only iterate over theta23 (for now), changing
    # the asimov data set:
    for step in steplist:

        print "Running at asimov parameters: %s"%step
        asimov_params = get_values(getAsimovParams(params,true_normal,step))
        asimov_data_set = get_asimov_fmap(