def eval_integrated(self, pars, modelfunc, data_grid, eval_grid, **kwargs): """Rebin the model onto a grid with low and high bins. Parameters ---------- pars : list of numbers The parameters for the model. modelfunc : callable The model to evaluate. It is called as `modelfunc(pars, lo, hi, **kwargs)` data_grid : (sequence of numbers, sequence of numbers) The grid on which to return the values, as low and high edges. eval_grid : (sequence of numbers, sequence of numbers) The grid on which to evaluate the model, as low and high edges. kwargs Any arguments to be sent to modelfunc. Returns ------- model : ndarray The model values matching the data_grid bins. """ y = modelfunc(pars, eval_grid[0], eval_grid[1], **kwargs) return rebin(y, eval_grid[0], eval_grid[1], data_grid[0], data_grid[1])
def test_rebin_partial_overlap(): """Does rebin handle the case when the output grid is > input? This only tests the easy case (when the model evaluates to 0 for the missing range), but is added whilst investigating #722 (the handling of regrid for integrated 1D models). It is intended to show the problem in #722 comes from the regrid code, not the rebin routine. """ # Truth is Box1D evaluated with xlow=3 xhi=5 ampl=4 evaluated # on the integrated bin defined by arange(1, 7, 0.5). # # However, the model is evaluated on the grid arange(2.1, 6, 0.5) # and then rebinned onto the requested grid. So, the edge bins # are partially filled. # xdataspace = numpy.arange(1, 7, 0.5) xdlo, xdhi = xdataspace[:-1], xdataspace[1:] xgrid = numpy.arange(2.1, 6, 0.5) xglo, xghi = xgrid[:-1], xgrid[1:] # Manually calculated ygrid = numpy.asarray([0, 0.4, 2, 2, 2, 1.6, 0]) yans = _utils.rebin(ygrid, xglo, xghi, xdlo, xdhi) # Manually calculated yexp = numpy.asarray([0, 0, 0, 0.32, 1.68, 2, 2, 1.68, 0.32, 0, 0]) assert yans == pytest.approx(yexp)
def test_rebin(): """ used sherpa (python2) as oracle """ y0 = [1, 3, 4, 10, 0] x0lo = [0, 2, 4, 6, 8] x0hi = [2, 4, 6, 8, 10] x1lo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] x1hi = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] expected = [0.5, 0.5, 1.5, 1.5, 2., 2., 5., 5., 0., 0.] assert_array_equal(expected, _utils.rebin(y0, x0lo, x0hi, x1lo, x1hi))
def _evaluate(self, data_space, pars, modelfunc, **kwargs): # Evaluate the model on the user-defined grid and then interpolate/rebin # onto the desired grid. This is based on sherpa.models.TableModel # but is simplified as we do not provide a fold method. kwargs[ 'integrate'] = self.integrate # Not really sure I need this, but let's be safe evaluation_space = self.evaluation_space if not data_space in evaluation_space: warnings.warn( "evaluation space does not contain the requested space. Sherpa will join the two spaces." ) evaluation_space = evaluation_space.join(data_space) # I don't like the string of IFs, but it might be more expressive this way in this specific case. # If the data space is integrated and the model's integrate flag is set to True, then evaluate the model # on the evaluation space and then rebin onto the data space. # If the data space is integrated but the model's integrate flas is set to False, then evaluate the model # on the midpoint grid (note: we are passing the midpoint grid to force Sherpa to treat this as not integrated. # If we passed two arrays we'd fall in a edge case and Sherpa would evaluate the model at the edge of the bin. # If the data space is not integrated then simply evaluate the model on the grid and then interpolate # to match the data space. if data_space.is_integrated: if self.integrate: # This should be the most common case y = modelfunc(pars, evaluation_space.grid[0], evaluation_space.grid[1], **kwargs) return rebin(y, evaluation_space.grid[0], evaluation_space.grid[1], data_space.grid[0], data_space.grid[1]) else: # The integrate flag is set to false, so just evaluate the model # and then interpolate using the grids midpoints. y = modelfunc(pars, evaluation_space.midpoint_grid, **kwargs) return interpolate(data_space.midpoint_grid, evaluation_space.midpoint_grid, y, function=self.method) else: y = modelfunc(pars, evaluation_space.grid[0], **kwargs) return interpolate(data_space.midpoint_grid, evaluation_space.midpoint_grid, y, function=self.method)
def _evaluate(self, data_space, pars, modelfunc, **kwargs): # Evaluate the model on the user-defined grid and then interpolate/rebin # onto the desired grid. This is based on sherpa.models.TableModel # but is simplified as we do not provide a fold method. kwargs['integrate'] = self.integrate # Not really sure I need this, but let's be safe evaluation_space = self.evaluation_space if not data_space in evaluation_space: warnings.warn("evaluation space does not contain the requested space. Sherpa will join the two spaces.") evaluation_space = evaluation_space.join(data_space) # I don't like the string of IFs, but it might be more expressive this way in this specific case. # If the data space is integrated and the model's integrate flag is set to True, then evaluate the model # on the evaluation space and then rebin onto the data space. # If the data space is integrated but the model's integrate flas is set to False, then evaluate the model # on the midpoint grid (note: we are passing the midpoint grid to force Sherpa to treat this as not integrated. # If we passed two arrays we'd fall in a edge case and Sherpa would evaluate the model at the edge of the bin. # If the data space is not integrated then simply evaluate the model on the grid and then interpolate # to match the data space. if data_space.is_integrated: if self.integrate: # This should be the most common case y = modelfunc(pars, evaluation_space.grid[0], evaluation_space.grid[1], **kwargs) return rebin(y, evaluation_space.grid[0], evaluation_space.grid[1], data_space.grid[0], data_space.grid[1]) else: # The integrate flag is set to false, so just evaluate the model # and then interpolate using the grids midpoints. y = modelfunc(pars, evaluation_space.midpoint_grid, **kwargs) return interpolate(data_space.midpoint_grid, evaluation_space.midpoint_grid, y, function=self.method) else: y = modelfunc(pars, evaluation_space.grid, **kwargs) return interpolate(data_space.midpoint_grid, evaluation_space.midpoint_grid, y, function=self.method)