コード例 #1
0
ファイル: genie.py プロジェクト: terliuk/pisa
    def get_combined_xsec(fpath, ver=None):
        """Load the cross-section values from a ROOT file and instantiate a
        CombinedSpline object."""
        # NOTE: ROOT import here as it is optional but still want to import
        # module for e.g. building docs
        import ROOT

        fpath = find_resource(fpath)
        logging.info('Loading GENIE ROOT cross-section file %s', fpath)

        # Name of neutrino flavours in the ROOT file.
        flavs = ('nu_e', 'nu_mu', 'nu_tau', 'nu_e_bar', 'nu_mu_bar',
                 'nu_tau_bar')

        rfile = ROOT.TFile.Open(fpath, 'read')  # pylint: disable=no-member
        xsec_splines = FlavIntData()
        for flav in flavs:
            for int_ in ALL_NUINT_TYPES:
                xsec_splines[flav, int_] = {}
                for part in ('O16', 'H1'):
                    str_repr = flav + '_' + part + '/' + 'tot_' + str(int_)
                    xsec_splines[flav + str(int_)][part] = \
                        ROOT.gDirectory.Get(str_repr) # pylint: disable=no-member
        rfile.Close()

        def eval_spl(spline,
                     binning,
                     out_units=ureg.m**2,
                     x_energy_scale=1,
                     **kwargs):
            init_names = ['true_energy']
            init_units = [ureg.GeV]

            if set(binning.names) != set(init_names):
                raise ValueError('Input binning names {0} does not match '
                                 'instantiation binning names '
                                 '{1}'.format(binning.names, init_names))

            if set(map(str, binning.units)) != set(map(str, init_units)):
                for name in init_names:
                    binning[name].to(init_units)

            bin_centers = [x.m for x in binning.weighted_centers][0]

            nu_O16, nu_H1 = [], []
            for e_val in bin_centers:
                nu_O16.append(spline['O16'].Eval(e_val))
                nu_H1.append(spline['H1'].Eval(e_val))

            nu_O16, nu_H1 = map(np.array, (nu_O16, nu_H1))
            nu_xsec = ((0.8879 * nu_O16) +
                       (0.1121 * nu_H1)) * 1E-38 * ureg.cm**2

            nu_xsec_hist = nu_xsec.to(out_units).magnitude
            return Map(hist=nu_xsec_hist, binning=binning, **kwargs)

        def validate_spl(binning):
            if np.all(binning.true_energy.midpoints.m > 1E3):
                raise ValueError('Energy value {0} out of range in array '
                                 '{0}'.format(binning.true_energy))

        inXSec = []
        for flav in flavs:
            for int_ in ALL_NUINT_TYPES:
                flavint = NuFlavInt(flav + str(int_))
                xsec = Spline(name=str(flavint),
                              spline=xsec_splines[flavint],
                              eval_spl=eval_spl,
                              validate_spl=validate_spl)
                inXSec.append(xsec)

        return CombinedSpline(inXSec, interactions=True, ver=ver)
コード例 #2
0
ファイル: events.py プロジェクト: terliuk/pisa
def test_Events():
    """Unit tests for Events class"""
    from pisa.utils.flavInt import NuFlavInt
    # Instantiate empty object
    events = Events()

    # Instantiate from PISA events HDF5 file
    events = Events(
        'events/events__vlvnt__toy_1_to_80GeV_spidx1.0_cz-1_to_1_1e2evts_set0__unjoined__with_fluxes_honda-2015-spl-solmin-aa.hdf5'
    )

    # Apply a simple cut
    events = events.applyCut('(true_coszen <= 0.5) & (true_energy <= 70)')
    for fi in events.flavints:
        assert np.max(events[fi]['true_coszen']) <= 0.5
        assert np.max(events[fi]['true_energy']) <= 70

    # Apply an "inbounds" cut via a OneDimBinning
    true_e_binning = OneDimBinning(name='true_energy',
                                   num_bins=80,
                                   is_log=True,
                                   domain=[10, 60] * ureg.GeV)
    events = events.keepInbounds(true_e_binning)
    for fi in events.flavints:
        assert np.min(events[fi]['true_energy']) >= 10
        assert np.max(events[fi]['true_energy']) <= 60

    # Apply an "inbounds" cut via a MultiDimBinning
    true_e_binning = OneDimBinning(name='true_energy',
                                   num_bins=80,
                                   is_log=True,
                                   domain=[20, 50] * ureg.GeV)
    true_cz_binning = OneDimBinning(name='true_coszen',
                                    num_bins=40,
                                    is_lin=True,
                                    domain=[-0.8, 0])
    mdb = MultiDimBinning([true_e_binning, true_cz_binning])
    events = events.keepInbounds(mdb)
    for fi in events.flavints:
        assert np.min(events[fi]['true_energy']) >= 20
        assert np.max(events[fi]['true_energy']) <= 50
        assert np.min(events[fi]['true_coszen']) >= -0.8
        assert np.max(events[fi]['true_coszen']) <= 0

    # Now try to apply a cut that fails on one flav/int (since the field will
    # be missing) and make sure that the cut did not get applied anywhere in
    # the end (i.e., it is rolled back)
    sub_evts = events['nutaunc']
    sub_evts.pop('true_energy')
    events['nutaunc'] = sub_evts
    try:
        events = events.applyCut('(true_energy >= 30) & (true_energy <= 40)')
    except Exception:
        pass
    else:
        raise Exception('Should not have been able to apply the cut!')
    for fi in events.flavints:
        if fi == NuFlavInt('nutaunc'):
            continue
        assert np.min(events[fi]['true_energy']) < 30

    logging.info(
        '<< PASS : test_Events >> (note:'
        ' "[   ERROR] Events object is in an inconsistent state. Reverting cut'
        ' for all flavInts." message above **is expected**.)')
コード例 #3
0
ファイル: genie.py プロジェクト: terliuk/pisa
    def _compute_nominal_transforms(self):
        """Compute cross-section transforms."""
        logging.info('Updating xsec.genie cross-section histograms...')

        self.load_xsec_splines()
        livetime = self._ev_param(self.params['livetime'].value)
        ice_p = self._ev_param(self.params['ice_p'].value)
        fid_vol = self._ev_param(self.params['fid_vol'].value)
        mr_h20 = self._ev_param(self.params['mr_h20'].value)
        x_energy_scale = self.params['x_energy_scale'].value

        input_binning = self.input_binning

        ebins = input_binning.true_energy
        for idx, name in enumerate(input_binning.names):
            if 'true_energy' in name:
                e_idx = idx

        xsec_transforms = {}
        for flav in self.input_names:
            for int_ in ALL_NUINT_TYPES:
                flavint = flav + '_' + str(int_)
                logging.debug('Obtaining cross-sections for %s', flavint)
                xsec_map = self.xsec.get_map(flavint,
                                             MultiDimBinning([ebins]),
                                             x_energy_scale=x_energy_scale)

                def func(idx):
                    if idx == e_idx:
                        return xsec_map.hist
                    return tuple(range(input_binning.shape[idx]))

                num_dims = input_binning.num_dims
                xsec_trns = np.meshgrid(*map(func, range(num_dims)),
                                        indexing='ij')[e_idx]
                xsec_trns *= (livetime * fid_vol * (ice_p / mr_h20) *
                              (6.022140857e+23 / ureg.mol))
                xsec_transforms[NuFlavInt(flavint)] = xsec_trns

        nominal_transforms = []
        for flavint_group in self.transform_groups:
            flav_names = [str(flav) for flav in flavint_group.flavs]
            for input_name in self.input_names:
                if input_name not in flav_names:
                    continue

                xform_array = []
                for flavint in flavint_group.flavints:
                    if flavint in xsec_transforms:
                        xform_array.append(xsec_transforms[flavint])
                xform_array = reduce(add, xform_array)

                xform = BinnedTensorTransform(
                    input_names=input_name,
                    output_name=str(flavint_group),
                    input_binning=input_binning,
                    output_binning=self.output_binning,
                    xform_array=xform_array)
                nominal_transforms.append(xform)

        return TransformSet(transforms=nominal_transforms)