Example #1
0
def make_toy_events(outdir, num_events, energy_range, spectral_index,
                    coszen_range, num_sets, first_set, aeff_energy_param,
                    aeff_coszen_param, reco_param, pid_param, pid_dist):
    """Make toy events and store to a file.

    Parameters
    ----------
    outdir : string
    num_events : int
    energy_range : 2-tuple of floats
    spectral_index : float
    coszen_range : 2-tuple of floats
    num_sets : int
    first_set : int
    aeff_energy_param : string
    aeff_coszen_param : string
    reco_param : string
    pid_param : string
    pid_dist : string

    Returns
    -------
    events : :class:`pisa.core.events.Events`

    """
    energy_range = sorted(energy_range)
    coszen_range = sorted(coszen_range)

    # Validation of args
    assert energy_range[0] > 0 and energy_range[1] < 1e9
    assert coszen_range[0] >= -1 and coszen_range[1] <= 1
    assert np.diff(energy_range)[0] > 0, str(energy_range)
    assert np.diff(coszen_range)[0] > 0, str(coszen_range)
    assert spectral_index >= 0, str(spectral_index)
    assert first_set >= 0, str(first_set)
    assert num_sets >= 1, str(first_set)

    # Make sure resources specified actually exist
    for arg in [aeff_energy_param, aeff_coszen_param, reco_param, pid_param]:
        find_resource(arg)

    mkdir(outdir, warn=False)

    set_indices = list(range(first_set, first_set + num_sets))

    # The following loop is for validation only
    for num, index in product(num_events, set_indices):
        mcgen_random_state(num_events=num, set_index=index)

    for num, set_index in product(num_events, set_indices):
        mcevts_fname = FNAME_TEMPLATE.format(
            file_type='events',
            detector='vlvnt',
            e_min=format_num(energy_range[0]),
            e_max=format_num(energy_range[1]),
            spectral_index=format_num(spectral_index,
                                      sigfigs=2,
                                      trailing_zeros=True),
            cz_min=format_num(coszen_range[0]),
            cz_max=format_num(coszen_range[1]),
            num_events=format_num(num, sigfigs=3, sci_thresh=(1, -1)),
            set_index=format_num(set_index, sci_thresh=(10, -10)),
            extension='hdf5')
        mcevts_fpath = os.path.join(outdir, mcevts_fname)
        if os.path.isfile(mcevts_fpath):
            logging.warn('File already exists, skipping: "%s"', mcevts_fpath)
            continue

        logging.info('Working on set "%s"', mcevts_fname)

        # TODO: pass filepaths / resource locations via command line args

        # Create a single random state object to pass from function to function
        random_state = mcgen_random_state(num_events=num, set_index=set_index)

        mc_events = generate_mc_events(
            num_events=num,
            energy_range=energy_range,
            coszen_range=coszen_range,
            spec_ind=spectral_index,
            aeff_energy_param_source=aeff_energy_param,
            aeff_coszen_param_source=aeff_coszen_param,
            random_state=random_state)
        populate_reco_observables(mc_events=mc_events,
                                  param_source=reco_param,
                                  random_state=random_state)
        populate_pid(mc_events=mc_events,
                     param_source=pid_param,
                     random_state=random_state,
                     dist=pid_dist)

        to_file(mc_events, mcevts_fpath)

        return mc_events
def formatter(mapping, key_only=False, fname=False):
    """Formatter for labels to go in plots and and filenames.

    Parameters
    ----------
    mapping : Mapping
    key_only : bool
    fname : bool

    """
    order = [
        'hash_val',
        'string',
        'depth_idx',
        'seed',
        'table_shape',
        'n_events',
        'ice_model',
        'tilt',
        'n_photons',
        'norm',
        'underflow',
        'overflow'
    ] # yapf: disable

    line_sep = '\n'

    if fname:
        for key in ('n_photons', 'norm', 'underflow', 'overflow'):
            order.remove(key)

    label_strs = []
    for key in order:
        if key not in mapping:
            continue

        if key_only:
            label_strs.append(key)
            continue

        if fname:
            sep = '_'
        else:
            sep = '='

        value = mapping[key]

        if key == 'n_photons':
            label_strs.append(
                '{}{}{}'.format(
                    key, sep, format_num(value, sigfigs=3, sci_thresh=(4, -3))
                )
            )

        elif key in ('depth_idx', 'seed', 'string', 'n_events', 'ice_model',
                     'tilt'):
            label_strs.append('{}{}{}'.format(key, sep, value))

        elif key == 'group_refractive_index':
            label_strs.append('n_grp{}{:.3f}'.format(sep, value))

        elif key == 'phase_refractive_index':
            label_strs.append('n_phs{}{:.3f}'.format(sep, value))

        elif key in ('table_shape', 'underflow', 'overflow'):
            if key == 'table_shape':
                name = 'shape'
            elif key == 'underflow':
                name = 'uflow'
            elif key == 'overflow':
                name = 'oflow'

            str_values = []
            for v in value:
                if float(v) == int(v):
                    str_values.append(format(int(np.round(v)), 'd'))
                else:
                    str_values.append(format_num(v, sigfigs=2, sci_thresh=(4, -3)))

            if fname:
                val_str = '_'.join(str_values)
                fmt = '{}'
            else:
                val_str = ', '.join(str_values)
                fmt = '({})'

            label_strs.append(('{}{}%s' % fmt).format(name, sep, val_str))

        elif key == 'hash_val':
            label_strs.append('hash{}{}'.format(sep, value))

        elif key == 'norm':
            label_strs.append(
                '{}{}{}'.format(
                    key, sep, format_num(value, sigfigs=3, sci_thresh=(4, -3))
                )
            )

    if not label_strs:
        return ''

    if fname:
        return '__'.join(label_strs)

    label_lines = [label_strs[0]]
    for label_str in label_strs[1:]:
        if len(label_lines[-1]) + len(label_str) > 120:
            label_lines.append(label_str)
        else:
            label_lines[-1] += ', ' + label_str

    return line_sep.join(label_lines)