def oversample_binning(coarse_bins, factor): """ Oversample bins by the given factor """ if is_linear(coarse_bins): logging.info('Oversampling linear output binning by factor %i.' %factor) fine_bins = np.linspace(coarse_bins[0], coarse_bins[-1], factor*(len(coarse_bins)-1)+1) elif is_logarithmic(coarse_bins): logging.info('Oversampling logarithmic output binning by factor %i.' %factor) fine_bins = np.logspace(np.log10(coarse_bins[0]), np.log10(coarse_bins[-1]), factor*(len(coarse_bins)-1)+1) else: logging.warn('Irregular binning detected! Evenly oversampling ' 'by factor %i'%factor) fine_bins = np.array([]) for i, upper_edge in enumerate(coarse_bins[1:]): fine_bins = np.append(fine_bins, np.linspace(coarse_bins[i], upper_edge, factor, endpoint=False)) return fine_bins
def _get_reco_kernels(self, flipback=True, e_reco_scale=None, cz_reco_scale=None, **kwargs): """ Use the parametrization functions to calculate the actual reco kernels (i.e. 4D histograms). If flipback==True, the zenith angle part that goes below the zenith will be mirrored back in. """ if all([hasattr(self, 'kernels'), e_reco_scale==1., cz_reco_scale==1.]): logging.info('Using existing kernels for reconstruction') return self.kernels logging.info('Creating parametrized reconstruction kernels') # get binning information evals, esizes = get_bin_centers(self.ebins), get_bin_sizes(self.ebins) czvals, czsizes = get_bin_centers(self.czbins), get_bin_sizes(self.czbins) czbins = self.czbins n_e, n_cz = len(evals), len(czvals) # prepare for folding back at lower edge if not is_linear(self.czbins): logging.warn("cos(zenith) bins have different " "sizes! Unable to fold around edge " "of histogram, will not do that.") flipback = False if flipback: czvals = np.append(czvals-(self.czbins[-1]-self.czbins[0]), czvals) czbins = np.append(czbins[:-1]-(self.czbins[-1]-self.czbins[0]), czbins) czsizes = np.append(czsizes, czsizes) # get properly scaled parametrization, initialize kernels parametrization = self.apply_reco_scales(e_reco_scale, cz_reco_scale) kernel_dict = {} for flavour in parametrization: kernel_dict[flavour] = {} for int_type in ['cc', 'nc']: logging.debug('Calculating parametrized reconstruction kernel for %s %s' %(flavour, int_type)) # create empty kernel kernel = np.zeros((n_e, n_cz, n_e, n_cz)) # quick handle to parametrization e_pars = parametrization[flavour][int_type]['energy'] cz_pars = parametrization[flavour][int_type]['coszen'] # loop over every bin in true (energy, coszen) for (i, j) in itertools.product(range(n_e), range(n_cz)): e_kern_cdf = double_gauss(self.ebins, loc1=e_pars['loc1'][i,j]+evals[i], width1=e_pars['width1'][i,j], loc2=e_pars['loc2'][i,j]+evals[i], width2=e_pars['width2'][i,j], fraction=e_pars['fraction'][i,j]) e_kern_int = np.sum(e_kern_cdf) offset = n_cz if flipback else 0 cz_kern_cdf = double_gauss(czbins, loc1=cz_pars['loc1'][i,j]+czvals[j+offset], width1=cz_pars['width1'][i,j], loc2=cz_pars['loc2'][i,j]+czvals[j+offset], width2=cz_pars['width2'][i,j], fraction=cz_pars['fraction'][i,j]) cz_kern_int = np.sum(cz_kern_cdf) if flipback: # fold back cz_kern_cdf = cz_kern_cdf[:len(czbins)/2][::-1] + cz_kern_cdf[len(czbins)/2:] kernel[i,j] = np.outer(e_kern_cdf, cz_kern_cdf) kernel_dict[flavour][int_type] = copy(kernel) kernel_dict['ebins'] = self.ebins kernel_dict['czbins'] = self.czbins return kernel_dict
def _get_reco_kernels(self, flipback=True, e_reco_scale=None, cz_reco_scale=None, **kwargs): """ Use the parametrization functions to calculate the actual reco kernels (i.e. 4D histograms). If flipback==True, the zenith angle part that goes below the zenith will be mirrored back in. """ if all([ hasattr(self, 'kernels'), e_reco_scale == 1., cz_reco_scale == 1. ]): logging.info('Using existing kernels for reconstruction') return self.kernels logging.info('Creating parametrized reconstruction kernels') # get binning information evals, esizes = get_bin_centers(self.ebins), get_bin_sizes(self.ebins) czvals, czsizes = get_bin_centers(self.czbins), get_bin_sizes( self.czbins) czbins = self.czbins n_e, n_cz = len(evals), len(czvals) # prepare for folding back at lower edge if not is_linear(self.czbins): logging.warn("cos(zenith) bins have different " "sizes! Unable to fold around edge " "of histogram, will not do that.") flipback = False if flipback: czvals = np.append(czvals - (self.czbins[-1] - self.czbins[0]), czvals) czbins = np.append( czbins[:-1] - (self.czbins[-1] - self.czbins[0]), czbins) czsizes = np.append(czsizes, czsizes) # get properly scaled parametrization, initialize kernels parametrization = self.apply_reco_scales(e_reco_scale, cz_reco_scale) kernel_dict = {} for flavour in parametrization: kernel_dict[flavour] = {} for int_type in ['cc', 'nc']: logging.debug( 'Calculating parametrized reconstruction kernel for %s %s' % (flavour, int_type)) # create empty kernel kernel = np.zeros((n_e, n_cz, n_e, n_cz)) # quick handle to parametrization e_pars = parametrization[flavour][int_type]['energy'] cz_pars = parametrization[flavour][int_type]['coszen'] # loop over every bin in true (energy, coszen) for (i, j) in itertools.product(range(n_e), range(n_cz)): e_kern_cdf = double_gauss( self.ebins, loc1=e_pars['loc1'][i, j] + evals[i], width1=e_pars['width1'][i, j], loc2=e_pars['loc2'][i, j] + evals[i], width2=e_pars['width2'][i, j], fraction=e_pars['fraction'][i, j]) e_kern_int = np.sum(e_kern_cdf) offset = n_cz if flipback else 0 cz_kern_cdf = double_gauss( czbins, loc1=cz_pars['loc1'][i, j] + czvals[j + offset], width1=cz_pars['width1'][i, j], loc2=cz_pars['loc2'][i, j] + czvals[j + offset], width2=cz_pars['width2'][i, j], fraction=cz_pars['fraction'][i, j]) cz_kern_int = np.sum(cz_kern_cdf) if flipback: # fold back cz_kern_cdf = cz_kern_cdf[:len(czbins) / 2][::-1] + cz_kern_cdf[ len(czbins) / 2:] kernel[i, j] = np.outer(e_kern_cdf, cz_kern_cdf) kernel_dict[flavour][int_type] = copy(kernel) kernel_dict['ebins'] = self.ebins kernel_dict['czbins'] = self.czbins return kernel_dict