Exemple #1
0
    def setup_function(self):

        # object for oscillation parameters
        self.osc_params = OscParams()

        # setup the layers
        #if self.params.earth_model.value is not None:
        earth_model = find_resource(self.params.earth_model.value)
        YeI = self.params.YeI.value.m_as('dimensionless')
        YeO = self.params.YeO.value.m_as('dimensionless')
        YeM = self.params.YeM.value.m_as('dimensionless')
        prop_height = self.params.prop_height.value.m_as('km')
        detector_depth = self.params.detector_depth.value.m_as('km')
        self.layers = Layers(earth_model, detector_depth, prop_height)
        self.layers.setElecFrac(YeI, YeO, YeM)

        # set the correct data mode
        self.data.data_specs = self.calc_specs

        # --- calculate the layers ---
        if self.calc_mode == 'binned':
            # speed up calculation by adding links
            # as layers don't care about flavour
            self.data.link_containers('nu', [
                'nue_cc', 'numu_cc', 'nutau_cc', 'nue_nc', 'numu_nc',
                'nutau_nc', 'nuebar_cc', 'numubar_cc', 'nutaubar_cc',
                'nuebar_nc', 'numubar_nc', 'nutaubar_nc'
            ])

        for container in self.data:
            self.layers.calcLayers(container['true_coszen'].get('host'))
            container['densities'] = self.layers.density.reshape(
                (container.size, self.layers.max_layers))
            container['distances'] = self.layers.distance.reshape(
                (container.size, self.layers.max_layers))

        # don't forget to un-link everything again
        self.data.unlink_containers()

        # --- setup empty arrays ---
        if self.calc_mode == 'binned':
            self.data.link_containers('nu', [
                'nue_cc', 'numu_cc', 'nutau_cc', 'nue_nc', 'numu_nc',
                'nutau_nc'
            ])
            self.data.link_containers('nubar', [
                'nuebar_cc', 'numubar_cc', 'nutaubar_cc', 'nuebar_nc',
                'numubar_nc', 'nutaubar_nc'
            ])
        for container in self.data:
            container['probability'] = np.empty((container.size, 3, 3),
                                                dtype=FTYPE)
        self.data.unlink_containers()

        # setup more empty arrays
        for container in self.data:
            container['prob_e'] = np.empty((container.size), dtype=FTYPE)
            container['prob_mu'] = np.empty((container.size), dtype=FTYPE)
Exemple #2
0
    def setup_function(self):

        # setup Earth model
        if self.params.earth_model.value is not None:
            earth_model = find_resource(self.params.earth_model.value)
            YeI = self.params.YeI.value.m_as('dimensionless')
            YeO = self.params.YeO.value.m_as('dimensionless')
            YeM = self.params.YeM.value.m_as('dimensionless')
        else:
            earth_model = None

        # setup the layers
        prop_height = self.params.prop_height.value.m_as('km')
        detector_depth = self.params.detector_depth.value.m_as('km')
        self.layers = Layers(earth_model, detector_depth, prop_height)
        if earth_model is not None:
            self.layers.setElecFrac(YeI, YeO, YeM)

        # set the correct data mode
        self.data.representation = self.calc_mode

        # --- calculate the layers ---
        if self.data.is_map:
            # speed up calculation by adding links
            # as layers don't care about flavour
            self.data.link_containers('nu', ['nue_cc', 'numu_cc', 'nutau_cc',
                                             'nue_nc', 'numu_nc', 'nutau_nc',
                                             'nuebar_cc', 'numubar_cc', 'nutaubar_cc',
                                             'nuebar_nc', 'numubar_nc', 'nutaubar_nc'])

        for container in self.data:
            if self.params.earth_model.value is not None:
                self.layers.calcLayers(container['true_coszen'])
                container['densities'] = self.layers.density.reshape((container.size, self.layers.max_layers))
                container['distances'] = self.layers.distance.reshape((container.size, self.layers.max_layers))
            else:
                self.layers.calcPathLength(container['true_coszen'])
                container['distances'] = self.layers.distance

        # don't forget to un-link everything again
        self.data.unlink_containers()

        # --- setup empty arrays ---
        if self.data.is_map:
            self.data.link_containers('nu', ['nue_cc', 'numu_cc', 'nutau_cc',
                                             'nue_nc', 'numu_nc', 'nutau_nc'])
            self.data.link_containers('nubar', ['nuebar_cc', 'numubar_cc', 'nutaubar_cc',
                                                'nuebar_nc', 'numubar_nc', 'nutaubar_nc'])
        for container in self.data:
            container['probability'] = np.empty((container.size, 3, 3), dtype=FTYPE)
        self.data.unlink_containers()

        # setup more empty arrays
        for container in self.data:
            container['prob_e'] = np.empty((container.size), dtype=FTYPE)
            container['prob_mu'] = np.empty((container.size), dtype=FTYPE)
Exemple #3
0
    def setup_function(self):
        import ROOT
        # setup the layers
        earth_model = find_resource(self.earth_model)
        self.layers = Layers(earth_model, self.detector_depth,
                             self.prop_height)
        # This is a bit hacky, but setting the electron density to 1.
        # gives us the total density of matter, which is what we want.
        self.layers.setElecFrac(1., 1., 1.)

        # setup cross-sections
        self.xsroot = ROOT.TFile(self.xsec_file)
        # set the correct data mode
        self.data.data_specs = self.calc_specs

        # --- calculate the layers ---
        if self.calc_mode == 'binned':
            # layers don't care about flavor
            self.data.link_containers('nu', [
                'nue_cc', 'numu_cc', 'nutau_cc', 'nue_nc', 'numu_nc',
                'nutau_nc', 'nuebar_cc', 'numubar_cc', 'nutaubar_cc',
                'nuebar_nc', 'numubar_nc', 'nutaubar_nc'
            ])

        for container in self.data:
            self.layers.calcLayers(container['true_coszen'].get(WHERE))
            container['densities'] = self.layers.density.reshape(
                (container.size, self.layers.max_layers))
            container['distances'] = self.layers.distance.reshape(
                (container.size, self.layers.max_layers))
            container['rho_int'] = np.empty((container.size), dtype=FTYPE)
        # don't forget to un-link everything again
        self.data.unlink_containers()

        # --- setup cross section and survival probability ---
        if self.calc_mode == 'binned':
            # The cross-sections do not depend on nc/cc, so we can at least link those containers
            self.data.link_containers('nue', ['nue_cc', 'nue_nc'])
            self.data.link_containers('nuebar', ['nuebar_cc', 'nuebar_nc'])
            self.data.link_containers('numu', ['numu_cc', 'numu_nc'])
            self.data.link_containers('numubar', ['numubar_cc', 'numubar_nc'])
            self.data.link_containers('nutau', ['nutau_cc', 'nutau_nc'])
            self.data.link_containers('nutaubar',
                                      ['nutaubar_cc', 'nutaubar_nc'])
        for container in self.data:
            container['xsection'] = np.empty((container.size), dtype=FTYPE)
            container['survival_prob'] = np.empty((container.size),
                                                  dtype=FTYPE)
        self.data.unlink_containers()
Exemple #4
0
    def setup_function(self):
        sys.path.append(self.globes_wrapper)
        import GLoBES
        ### you need to start GLoBES from the folder containing a dummy experiment
        # therefore we go to the folder, load GLoBES and then go back
        curdir = os.getcwd()
        os.chdir(self.globes_wrapper)
        self.globes_calc =  GLoBES.GLoBESCalculator("calc")
        os.chdir(curdir)
        self.globes_calc.InitSteriles(2)
        # object for oscillation parameters
        self.osc_params = OscParams()
        earth_model = find_resource(self.earth_model)
        prop_height = self.prop_height.m_as('km')
        detector_depth = self.detector_depth.m_as('km')
        self.layers = Layers(earth_model, detector_depth, prop_height)
        # The electron fractions are taken into account internally by GLoBES/SNU.
        # See the SNU patch for details. It uses the density to decide
        # whether it is in the core or in the mantle. Therefore, we just multiply by
        # one to give GLoBES the raw densities.
        self.layers.setElecFrac(1., 1., 1.)

        # set the correct data mode
        self.data.data_specs = self.calc_specs

        # --- calculate the layers ---
        if self.calc_mode == 'binned':
            # speed up calculation by adding links
            # as layers don't care about flavour
            self.data.link_containers('nu', ['nue_cc', 'numu_cc', 'nutau_cc',
                                             'nue_nc', 'numu_nc', 'nutau_nc',
                                             'nuebar_cc', 'numubar_cc', 'nutaubar_cc',
                                             'nuebar_nc', 'numubar_nc', 'nutaubar_nc'])

        for container in self.data:
            self.layers.calcLayers(container['true_coszen'].get('host'))
            container['densities'] = self.layers.density.reshape((container.size, self.layers.max_layers))
            container['distances'] = self.layers.distance.reshape((container.size, self.layers.max_layers))

        # don't forget to un-link everything again
        self.data.unlink_containers()

        # setup probability containers
        for container in self.data:
            container['prob_e'] = np.empty((container.size), dtype=FTYPE)
            container['prob_mu'] = np.empty((container.size), dtype=FTYPE)
            container['prob_nonsterile'] = np.empty((container.size), dtype=FTYPE)
Exemple #5
0
    def setup_function(self):

        earth_model = find_resource(self.earth_model)
        prop_height = self.prop_height
        detector_depth = self.detector_depth
        self.layers = Layers(earth_model, detector_depth, prop_height)
        # We must treat densities and electron fractions correctly here, so we set them
        # to 1 in the Layers module to get unweighted densities.
        self.layers.setElecFrac(1, 1, 1)

        nsq_units = nsq.Const()  # natural units for nusquids
        # Because we don't want to extrapolate, we check that all points at which we
        # want to evaluate probabilities are fully contained within the node specs. This
        # is of course not necessary in events mode.
        if isinstance(self.node_mode, MultiDimBinning) and not self.exact_mode:
            logging.debug("setting up nuSQuIDS nodes in binned mode")
            # we can prepare the calculator like this only in binned mode, see
            # compute_function for node_mode == "events"
            self.data.representation = self.calc_mode
            for container in self.data:
                for var in ["true_coszen", "true_energy"]:
                    unit = "dimensionless" if var == "true_coszen" else "GeV"
                    upper_bound = np.max(self.node_mode[var].bin_edges.m_as(unit))
                    lower_bound = np.min(self.node_mode[var].bin_edges.m_as(unit))
                    err_msg = (
                        "The outer edges of the node_mode must encompass "
                        "the entire range of calc_specs to avoid extrapolation"
                    )
                    if np.any(container[var] > upper_bound):
                        maxval = np.max(container[var])
                        raise ValueError(
                            err_msg + f"\nmax input: {maxval}, upper "
                            f"bound: {upper_bound}"
                        )
                    if np.any(container[var] < lower_bound):
                        minval = np.max(container[var])
                        raise ValueError(
                            err_msg + f"\nmin input: {minval}, lower "
                            f"bound: {lower_bound}"
                        )

            # Layers in nuSQuIDS are special: We need all the individual distances and
            # densities for the nodes to solve the interaction picture states, but on
            # the final calculation grid (or events) we only need the *total* traversed
            # distance. Because we are placing nodes at the bin edges rather than the
            # bin middle, this doesn't really fit with how containers store data, so we
            # are making arrays as variables that never go into the container.

            # These are stored because we need them later during interpolation
            self.coszen_node_mode = self.node_mode["true_coszen"].bin_edges.m_as(
                "dimensionless"
            )
            self.e_node_mode = self.node_mode["true_energy"].bin_edges.m_as("GeV")
            logging.debug(
                f"Setting up nodes at\n"
                f"cos_zen = \n{self.coszen_node_mode}\n"
                f"energy = \n{self.e_node_mode}\n"
            )
            # things are getting a bit meshy from here...
            self.e_mesh, self.cosz_mesh = np.meshgrid(
                self.e_node_mode, self.coszen_node_mode
            )
            e_nodes = self.e_mesh.ravel()
            coszen_nodes = self.cosz_mesh.ravel()

            # The lines below should not be necessary because we will always get at
            # least two numbers from the bin edges. However, if either energy or coszen
            # somehow was just a scalar, we would need to broadcast it out to the same
            # size. Keeping the code in here in case you want to use the stage in 1D.
            # convert lists to ndarrays and scalars to ndarrays with length 1
            e_nodes = np.atleast_1d(e_nodes)
            coszen_nodes = np.atleast_1d(coszen_nodes)
            # broadcast against each other and make a copy
            # (see https://numpy.org/doc/stable/reference/generated/numpy.broadcast_arrays.html)
            e_nodes, coszen_nodes = [
                np.array(a) for a in np.broadcast_arrays(e_nodes, coszen_nodes)
            ]

            assert len(e_nodes) == len(coszen_nodes)
            assert coszen_nodes.ndim == 1
            assert e_nodes.ndim == 1

            self.layers.calcLayers(coszen_nodes)
            distances = np.reshape(
                self.layers.distance, (len(e_nodes), self.layers.max_layers)
            )
            densities = np.reshape(
                self.layers.density, (len(e_nodes), self.layers.max_layers)
            )
            # HACK: We need the correct electron densities for each layer. We can
            # determine whether we are in the core or mantle based on the density.
            # Needless to say it isn't optimal to have these numbers hard-coded.
            ye = np.zeros_like(densities)
            ye[densities < 10] = self.YeM
            ye[(densities >= 10) & (densities < 13)] = self.YeO
            ye[densities >= 13] = self.YeI
            self.nus_layer = self.nusquids_layers_class(
                distances * nsq_units.km,
                densities,
                ye,
                e_nodes * nsq_units.GeV,
                self.num_neutrinos,
                nsq.NeutrinoType.both,
            )
            self.apply_prop_settings(self.nus_layer)

        # Now that we have our nusquids calculator set up on the node grid, we make
        # container output space for the probability output which may be on a finer grid
        # than the nodes or even working in events mode.
        self.data.representation = self.calc_mode

        # --- calculate the layers ---
        if isinstance(self.calc_mode, MultiDimBinning):
            # as layers don't care about flavour
            self.data.link_containers(
                "nu",
                [
                    "nue_cc",
                    "numu_cc",
                    "nutau_cc",
                    "nue_nc",
                    "numu_nc",
                    "nutau_nc",
                    "nuebar_cc",
                    "numubar_cc",
                    "nutaubar_cc",
                    "nuebar_nc",
                    "numubar_nc",
                    "nutaubar_nc",
                ],
            )

        # calculate the distance difference between minimum and maximum production
        # height, if applicable
        if self.avg_height:
            layers_min = Layers(
                earth_model,
                detector_depth,
                self.prop_height - self.prop_height_range / 2.0,
            )
            layers_min.setElecFrac(1, 1, 1)
            layers_max = Layers(
                earth_model,
                detector_depth,
                self.prop_height + self.prop_height_range / 2.0,
            )
            layers_max.setElecFrac(1, 1, 1)

        for container in self.data:
            self.layers.calcLayers(container["true_coszen"])
            distances = self.layers.distance.reshape((container.size, -1))
            tot_distances = np.sum(distances, axis=1)
            if self.avg_height:
                layers_min.calcLayers(container["true_coszen"])
                dists_min = layers_min.distance.reshape((container.size, -1))
                min_tot_dists = np.sum(dists_min, axis=1)

                layers_max.calcLayers(container["true_coszen"])
                dists_max = layers_max.distance.reshape((container.size, -1))
                max_tot_dists = np.sum(dists_max, axis=1)
                # nuSQuIDS assumes the original distance is the longest distance and
                # the averaging range is the difference between the minimum and maximum
                # distance.
                avg_ranges = max_tot_dists - min_tot_dists
                tot_distances = max_tot_dists
                assert np.all(avg_ranges > 0)
            # If the low-pass cutoff is zero, nusquids will not evaluate the filter.
            container["lowpass_cutoff"] = self.eval_lowpass_cutoff * np.ones(
                container.size
            )
            if not self.apply_lowpass_above_hor:
                container["lowpass_cutoff"] = np.where(
                    container["true_coszen"] >= 0, 0, container["lowpass_cutoff"]
                )
            if isinstance(self.node_mode, MultiDimBinning) and not self.exact_mode:
                # To project out probabilities we only need the *total* distance
                container["tot_distances"] = tot_distances
                if self.avg_height:
                    container["avg_ranges"] = avg_ranges
                else:
                    container["avg_ranges"] = np.zeros(container.size, dtype=FTYPE)
                if not self.apply_height_avg_below_hor:
                    container["avg_ranges"] = np.where(
                        container["true_coszen"] >= 0, container["avg_ranges"], 0.0
                    )
            elif self.node_mode == "events" or self.exact_mode:
                # in any other mode (events or exact) we store all densities and
                # distances in the container in calc_specs
                densities = self.layers.density.reshape((container.size, -1))
                container["densities"] = densities
                container["distances"] = distances

        self.data.unlink_containers()

        if isinstance(self.calc_mode, MultiDimBinning):
            self.data.link_containers("nue", ["nue_cc", "nue_nc"])
            self.data.link_containers("numu", ["numu_cc", "numu_nc"])
            self.data.link_containers("nutau", ["nutau_cc", "nutau_nc"])
            self.data.link_containers("nuebar", ["nuebar_cc", "nuebar_nc"])
            self.data.link_containers("numubar", ["numubar_cc", "numubar_nc"])
            self.data.link_containers("nutaubar", ["nutaubar_cc", "nutaubar_nc"])

        # setup more empty arrays
        for container in self.data:
            container["prob_e"] = np.empty((container.size), dtype=FTYPE)
            container["prob_mu"] = np.empty((container.size), dtype=FTYPE)
            if self.use_taus:
                container["prob_tau"] = np.empty((container.size), dtype=FTYPE)

        self.data.unlink_containers()

        if self.exact_mode:
            return

        # --- containers for interpolated states ---
        # This is not needed in exact mode
        if isinstance(self.calc_mode, MultiDimBinning):
            self.data.link_containers(
                "nu", ["nue_cc", "numu_cc", "nutau_cc", "nue_nc", "numu_nc", "nutau_nc"]
            )
            self.data.link_containers(
                "nubar",
                [
                    "nuebar_cc",
                    "numubar_cc",
                    "nutaubar_cc",
                    "nuebar_nc",
                    "numubar_nc",
                    "nutaubar_nc",
                ],
            )
        for container in self.data:
            container["interp_states_e"] = np.empty(
                (container.size, self.num_neutrinos ** 2),
                dtype=FTYPE,
            )
            container["interp_states_mu"] = np.empty(
                (container.size, self.num_neutrinos ** 2),
                dtype=FTYPE,
            )
            container["interp_states_tau"] = np.empty(
                (container.size, self.num_neutrinos ** 2),
                dtype=FTYPE,
            )
        self.data.unlink_containers()
        self.interpolation_warning_issued = False
Exemple #6
0
    def setup_function(self):

        earth_model = find_resource(self.earth_model)
        prop_height = self.prop_height
        detector_depth = self.detector_depth
        self.layers = Layers(earth_model, detector_depth, prop_height)
        self.layers.setElecFrac(self.YeI, self.YeO, self.YeM)

        nsq_units = nsq.Const()  # natural units for nusquids
        # Because we don't want to extrapolate, we check that all points at which we
        # want to evaluate probabilities are fully contained within the node specs. This
        # is of course not necessary in events mode.
        if self.node_mode == "binned" and not self.exact_mode:
            logging.debug("setting up nuSQuIDS nodes in binned mode")
            # we can prepare the calculator like this only in binned mode, see
            # compute_function for node_mode == "events"
            self.data.data_specs = self.calc_specs
            for container in self.data:
                for var in ["true_coszen", "true_energy"]:
                    upper_bound = np.max(self.node_specs[var].bin_edges)
                    lower_bound = np.min(self.node_specs[var].bin_edges)
                    err_msg = (
                        "The outer edges of the node_specs must encompass "
                        "the entire range of calc_specs to avoid extrapolation"
                    )
                    if np.any(container[var].get(WHERE) > upper_bound):
                        maxval = np.max(container[var].get(WHERE))
                        raise ValueError(err_msg +
                                         f"\nmax input: {maxval}, upper "
                                         f"bound: {upper_bound}")
                    if np.any(container[var].get(WHERE) < lower_bound):
                        minval = np.max(container[var].get(WHERE))
                        raise ValueError(err_msg +
                                         f"\nmin input: {minval}, lower "
                                         f"bound: {lower_bound}")

            # Layers in nuSQuIDS are special: We need all the individual distances and
            # densities for the nodes to solve the interaction picture states, but on
            # the final calculation grid (or events) we only need the *total* traversed
            # distance. Because we are placing nodes at the bin edges rather than the
            # bin middle, this doesn't really fit with how containers store data, so we
            # are making arrays as variables that never go into the container.

            # These are stored because we need them later during interpolation
            self.coszen_node_specs = self.node_specs[
                "true_coszen"].bin_edges.m_as("dimensionless")
            self.e_node_specs = self.node_specs["true_energy"].bin_edges.m_as(
                "GeV")
            logging.debug(f"Setting up nodes at\n"
                          f"cos_zen = \n{self.coszen_node_specs}\n"
                          f"energy = \n{self.e_node_specs}\n")
            # things are getting a bit meshy from here...
            self.e_mesh, self.cosz_mesh = np.meshgrid(self.e_node_specs,
                                                      self.coszen_node_specs)
            e_nodes = self.e_mesh.ravel()
            coszen_nodes = self.cosz_mesh.ravel()

            # The lines below should not be necessary because we will always get at
            # least two numbers from the bin edges. However, if either energy or coszen
            # somehow was just a scalar, we would need to broadcast it out to the same
            # size. Keeping the code in here in case you want to use the stage in 1D.
            # convert lists to ndarrays and scalars to ndarrays with length 1
            e_nodes = np.atleast_1d(e_nodes)
            coszen_nodes = np.atleast_1d(coszen_nodes)
            # broadcast against each other and make a copy
            # (see https://numpy.org/doc/stable/reference/generated/numpy.broadcast_arrays.html)
            e_nodes, coszen_nodes = [
                np.array(a)
                for a in np.broadcast_arrays(e_nodes, coszen_nodes)
            ]

            assert len(e_nodes) == len(coszen_nodes)
            assert coszen_nodes.ndim == 1
            assert e_nodes.ndim == 1

            self.layers.calcLayers(coszen_nodes)
            distances = np.reshape(self.layers.distance,
                                   (len(e_nodes), self.layers.max_layers))
            densities = np.reshape(self.layers.density,
                                   (len(e_nodes), self.layers.max_layers))
            # electron fraction is already included by multiplying the densities with
            # them in the Layers module, so we pass 1. to nuSQuIDS (unless energies are
            # very high, this should be equivalent).
            ye = np.broadcast_to(np.array([1.]),
                                 (len(e_nodes), self.layers.max_layers))
            self.nus_layer = nsq.nuSQUIDSLayers(
                distances * nsq_units.km,
                densities,
                ye,
                e_nodes * nsq_units.GeV,
                self.num_neutrinos,
                nsq.NeutrinoType.both,
            )
            self.apply_prop_settings(self.nus_layer)

        # Now that we have our nusquids calculator set up on the node grid, we make
        # container output space for the probability output which may be on a finer grid
        # than the nodes or even working in events mode.
        self.data.data_specs = self.calc_specs

        # --- calculate the layers ---
        if self.calc_mode == "binned":
            # as layers don't care about flavour
            self.data.link_containers("nu", [
                "nue_cc", "numu_cc", "nutau_cc", "nue_nc", "numu_nc",
                "nutau_nc", "nuebar_cc", "numubar_cc", "nutaubar_cc",
                "nuebar_nc", "numubar_nc", "nutaubar_nc"
            ])
        # calculate the distance difference between minimum and maximum production
        # height, if applicable
        if self.avg_height:
            layers_min = Layers(earth_model, detector_depth,
                                self.prop_height_min)
            layers_min.setElecFrac(self.YeI, self.YeO, self.YeM)
        for container in self.data:
            self.layers.calcLayers(container["true_coszen"].get("host"))
            distances = self.layers.distance.reshape(
                (container.size, self.layers.max_layers))
            tot_distances = np.sum(distances, axis=1)
            if self.avg_height:
                layers_min.calcLayers(container["true_coszen"].get("host"))
                dists_min = layers_min.distance.reshape(
                    (container.size, self.layers.max_layers))
                min_tot_dists = np.sum(dists_min, axis=1)
                # nuSQuIDS assumes the original distance is the longest distance and
                # the averaging range is the difference between the minimum and maximum
                # distance.
                avg_ranges = tot_distances - min_tot_dists
                assert np.all(avg_ranges > 0)
            if self.node_mode == "binned" and not self.exact_mode:
                # To project out probabilities we only need the *total* distance
                container["tot_distances"] = tot_distances
                # for the binned node_mode we already calculated layers above
                if self.avg_height:
                    container["avg_ranges"] = avg_ranges
            elif self.node_mode == "events" or self.exact_mode:
                # in any other mode (events or exact) we store all densities and
                # distances in the container in calc_specs
                densities = self.layers.density.reshape(
                    (container.size, self.layers.max_layers))
                container["densities"] = densities
                container["distances"] = distances

        self.data.unlink_containers()

        if self.calc_mode == "binned":
            self.data.link_containers("nue", ["nue_cc", "nue_nc"])
            self.data.link_containers("numu", ["numu_cc", "numu_nc"])
            self.data.link_containers("nutau", ["nutau_cc", "nutau_nc"])
            self.data.link_containers("nuebar", ["nuebar_cc", "nuebar_nc"])
            self.data.link_containers("numubar", ["numubar_cc", "numubar_nc"])
            self.data.link_containers("nutaubar",
                                      ["nutaubar_cc", "nutaubar_nc"])

        # setup more empty arrays
        for container in self.data:
            container["prob_e"] = np.empty((container.size), dtype=FTYPE)
            container["prob_mu"] = np.empty((container.size), dtype=FTYPE)
        self.data.unlink_containers()

        if self.exact_mode: return

        # --- containers for interpolated states ---
        # This is not needed in exact mode
        if self.calc_mode == "binned":
            self.data.link_containers("nu", [
                "nue_cc", "numu_cc", "nutau_cc", "nue_nc", "numu_nc",
                "nutau_nc"
            ])
            self.data.link_containers("nubar", [
                "nuebar_cc", "numubar_cc", "nutaubar_cc", "nuebar_nc",
                "numubar_nc", "nutaubar_nc"
            ])
        for container in self.data:
            container["interp_states_e"] = np.empty(
                (container.size, self.num_neutrinos**2),
                dtype=FTYPE,
            )
            container["interp_states_mu"] = np.empty(
                (container.size, self.num_neutrinos**2),
                dtype=FTYPE,
            )
        self.data.unlink_containers()
Exemple #7
0
    def setup_function(self):

        # object for oscillation parameters
        self.osc_params = OscParams()
        if self.reparam_mix_matrix:
            logging.debug(
                'Working with reparameterizated version of mixing matrix.')
        else:
            logging.debug(
                'Working with standard parameterization of mixing matrix.')
        if self.nsi_type == 'vacuum-like':
            logging.debug('Working in vacuum-like NSI parameterization.')
            self.nsi_params = VacuumLikeNSIParams()
        elif self.nsi_type == 'standard':
            logging.debug('Working in standard NSI parameterization.')
            self.nsi_params = StdNSIParams()

        # setup the layers
        #if self.params.earth_model.value is not None:
        earth_model = find_resource(self.params.earth_model.value)
        self.YeI = self.params.YeI.value.m_as('dimensionless')
        self.YeO = self.params.YeO.value.m_as('dimensionless')
        self.YeM = self.params.YeM.value.m_as('dimensionless')
        prop_height = self.params.prop_height.value.m_as('km')
        detector_depth = self.params.detector_depth.value.m_as('km')
        self.layers = Layers(earth_model, detector_depth, prop_height)
        self.layers.setElecFrac(self.YeI, self.YeO, self.YeM)

        # --- calculate the layers ---
        if self.is_map:
            # speed up calculation by adding links
            # as layers don't care about flavour
            self.data.link_containers('nu', [
                'nue_cc', 'numu_cc', 'nutau_cc', 'nue_nc', 'numu_nc',
                'nutau_nc', 'nuebar_cc', 'numubar_cc', 'nutaubar_cc',
                'nuebar_nc', 'numubar_nc', 'nutaubar_nc'
            ])

        for container in self.data:
            self.layers.calcLayers(container['true_coszen'])
            container['densities'] = self.layers.density.reshape(
                (container.size, self.layers.max_layers))
            container['distances'] = self.layers.distance.reshape(
                (container.size, self.layers.max_layers))

        # don't forget to un-link everything again
        self.data.unlink_containers()

        # --- setup empty arrays ---
        if self.is_map:
            self.data.link_containers('nu', [
                'nue_cc', 'numu_cc', 'nutau_cc', 'nue_nc', 'numu_nc',
                'nutau_nc'
            ])
            self.data.link_containers('nubar', [
                'nuebar_cc', 'numubar_cc', 'nutaubar_cc', 'nuebar_nc',
                'numubar_nc', 'nutaubar_nc'
            ])
        for container in self.data:
            container['probability'] = np.empty((container.size, 3, 3),
                                                dtype=FTYPE)
        self.data.unlink_containers()

        # setup more empty arrays
        for container in self.data:
            container['prob_e'] = np.empty((container.size), dtype=FTYPE)
            container['prob_mu'] = np.empty((container.size), dtype=FTYPE)