Implement Parameter scan attributes
@@ -7,6 +7,7 @@ import logging
import numpy as np
from astropy import units as u
from gammapy.utils.table import table_from_row_data
+from gammapy.utils.interpolation import interpolation_scale
__all__ = ["Parameter", "Parameters"]
@@ -65,6 +66,19 @@ class Parameter:
Maximum (sometimes used in fitting)
frozen : bool, optional
Frozen? (used in fitting)
+ error : float
+ Parameter error
+ scan_min : float or int
+ Minimum value for the parameter scan.
+ scan_max : float or int
+ Minimum value for the parameter scan.
+ scan_n_values: int
+ Number of values to be used fo the parameter scan.
+ scan_values: `numpy.array`
+ Scan values
+ interp : {"lin", "sqrt", "log"}
+ Scaling to use for the scan.
+
"""
def __init__(
@@ -77,6 +91,11 @@ class Parameter:
max=np.nan,
frozen=False,
error=0,
+ scan_min=2,
+ scan_max=2,
+ scan_n_values=11,
+ scan_values=None,
+ interp="lin",
):
self.name = name
self._link_label_io = None
@@ -97,6 +116,12 @@ class Parameter:
self.factor = value
self.unit = unit
+ self.scan_min = scan_min
+ self.scan_max = scan_max
+ self.scan_values = scan_values
+ self.scan_n_values = scan_n_values
+ self.interp = interp
+
def __get__(self, instance, owner):
if instance is None:
return self
@@ -240,6 +265,48 @@ class Parameter:
self.value = val.value
self.unit = val.unit
+ @property
+ def scan_min(self):
+ """Stat scan min"""
+ if isinstance(self._scan_min, int):
+ return self.value - self.error * self._scan_min
+
+ return self._scan_min
+
+ @property
+ def scan_max(self):
+ """Stat scan max"""
+ if isinstance(self._scan_max, int):
+ return self.value + self.error * self._scan_max
+
+ return self._scan_max
+
+ @scan_min.setter
+ def scan_min(self, value):
+ """Stat scan min setter"""
+ self._scan_min = value
+
+ @scan_max.setter
+ def scan_max(self, value):
+ """Stat scan max setter"""
+ self._scan_max = value
+
+ @property
+ def scan_values(self):
+ """Stat scan values (`~numpy.ndarray`)"""
+ if self._scan_values is None:
+ scale = interpolation_scale(self.interp)
+ parmin, parmax = scale([self.scan_min, self.scan_max])
+ values = np.linspace(parmin, parmax, self.scan_n_values)
+ return scale.inverse(values)
+
+ return self._scan_values
+
+ @scan_values.setter
+ def scan_values(self, values):
+ """Set scan values"""
+ self._scan_values = values
+
def check_limits(self):
"""Emit a warning or error if value is outside the min/max range"""
if not self.frozen:
