Numpy-Vectorized Python Local Models
NumPy-vectorized Python local models for XSPEC.
Decorate a local model function with vectorized() to have XSPEC hand it
zero-copy numpy arrays -- views over XSPEC's own storage -- instead of Python
tuples and lists. A vectorized model can be an order of magnitude faster than
the classic interface because it avoids boxing every array element into a Python
float and lets the model body use numpy array operations.
The calling convention is identical to a classic addPyMod / lmod model
except for the argument types:
engs(nE+1 bin edges) andparamsarrive as read-only numpy arrays;
flux(and the optionalfluxErr) arrive as writable numpy arrays that must be filled IN PLACE -- assign withflux[:] = ..., never rebindflux = .... Rebinding discards the result, exactly as it does for the classic list interface.
Example:
import xspec
import numpy as np
@xspec.vectorized
def myModel(engs, params, flux):
de = engs[1:] - engs[:-1]
flux[:] = params[0] * de
parInfo = ('norm "" 1.0 0.0 0.0 1e6 1e6 0.01',)
xspec.AllModels.addPyMod(myModel, parInfo, 'add')
The model function may take 3, 4, or 5 positional arguments
(engs, params, flux[, fluxErr[, spectrumNumber]]) -- the same convention as
a classic Python model. A model that takes fluxErr fills it in place; if it
leaves it untouched, XSPEC reports no error array. spectrumNumber is passed
as a plain int.
- xspec.vectorized(func)
Mark a Python local model function as numpy-vectorized.
Returns a wrapper -- with the same positional arity as func -- that XSPEC recognizes (via the
_xspec_vectorizedattribute) as wanting numpy-array arguments over its internal buffers. See the module docstring for the calling convention.The wrapper is a thin adapter: it reinterprets each incoming
memoryviewas a numpy array withnumpy.frombuffer()(zero copy; dtype defaults to float64) and forwards to func. Fillingflux/fluxErrin place therefore writes straight back into XSPEC's storage.