def test_compound_bounding_box(): model = models.Gaussian1D() truth = models.Gaussian1D() bbox1 = CompoundBoundingBox.validate(model, { (1, ): (-1, 0), (2, ): (0, 1) }, selector_args=[('x', False)]) bbox2 = CompoundBoundingBox.validate(model, { (-0.5, ): (-1, 0), (0.5, ): (0, 1) }, selector_args=[('x', False)]) # Using with_bounding_box to pass a selector model.bounding_box = bbox1 assert model(-0.5) == truth(-0.5) assert model(-0.5, with_bounding_box=(1, )) == truth(-0.5) assert np.isnan(model(-0.5, with_bounding_box=(2, ))) assert model(0.5) == truth(0.5) assert model(0.5, with_bounding_box=(2, )) == truth(0.5) assert np.isnan(model(0.5, with_bounding_box=(1, ))) # Using argument value to pass bounding_box model.bounding_box = bbox2 assert model(-0.5) == truth(-0.5) assert model(-0.5, with_bounding_box=True) == truth(-0.5) assert model(0.5) == truth(0.5) assert model(0.5, with_bounding_box=True) == truth(0.5) with pytest.raises(RuntimeError): model(0, with_bounding_box=True) model1 = models.Gaussian1D() truth1 = models.Gaussian1D() model2 = models.Const1D(2) truth2 = models.Const1D(2) model = model1 + model2 truth = truth1 + truth2 assert isinstance(model, CompoundModel) model.bounding_box = bbox1 assert model(-0.5) == truth(-0.5) assert model(-0.5, with_bounding_box=1) == truth(-0.5) assert np.isnan(model(-0.5, with_bounding_box=(2, ))) assert model(0.5) == truth(0.5) assert model(0.5, with_bounding_box=2) == truth(0.5) assert np.isnan(model(0.5, with_bounding_box=(1, ))) model.bounding_box = bbox2 assert model(-0.5) == truth(-0.5) assert model(-0.5, with_bounding_box=True) == truth(-0.5) assert model(0.5) == truth(0.5) assert model(0.5, with_bounding_box=True) == truth(0.5) with pytest.raises(RuntimeError): model(0, with_bounding_box=True)
def test_compound_bounding_box(): trans3 = models.Shift(10) & models.Scale(2) & models.Shift(-1) pipeline = [('detector', trans3), ('sky', None)] w = wcs.WCS(pipeline) cbb = { 1: ((-1, 10), (6, 15)), 2: ((-1, 5), (3, 17)), 3: ((-3, 7), (1, 27)), } if new_bbox: # Test attaching a valid bounding box (ignoring input 'x') w.attach_compound_bounding_box(cbb, [('x',)]) from astropy.modeling.bounding_box import CompoundBoundingBox cbb = CompoundBoundingBox.validate(trans3, cbb, selector_args=[('x',)], order='F') assert w.bounding_box == cbb assert w.bounding_box is trans3.bounding_box # Test evaluating assert_allclose(w(13, 2, 1), (np.nan, np.nan, np.nan)) assert_allclose(w(13, 2, 2), (np.nan, np.nan, np.nan)) assert_allclose(w(13, 0, 3), (np.nan, np.nan, np.nan)) # No bounding box for selector with pytest.raises(RuntimeError): w(13, 13, 4) # Test attaching a invalid bounding box (not ignoring input 'x') with pytest.raises(ValueError): w.attach_compound_bounding_box(cbb, [('x', False)]) else: with pytest.raises(NotImplementedError) as err: w.attach_compound_bounding_box(cbb, [('x',)]) assert str(err.value) == 'Compound bounding box is not supported for your version of astropy' # Test that bounding_box with quantities can be assigned and evaluates trans = models.Shift(10 * u .pix) & models.Shift(2 * u.pix) pipeline = [('detector', trans), ('sky', None)] w = wcs.WCS(pipeline) cbb = { 1 * u.pix: (1 * u.pix, 5 * u.pix), 2 * u.pix: (2 * u.pix, 6 * u.pix) } if new_bbox: w.attach_compound_bounding_box(cbb, [('x1',)]) from astropy.modeling.bounding_box import CompoundBoundingBox cbb = CompoundBoundingBox.validate(trans, cbb, selector_args=[('x1',)], order='F') assert w.bounding_box == cbb assert w.bounding_box is trans.bounding_box assert_allclose(w(-1*u.pix, 1*u.pix), (np.nan, np.nan)) assert_allclose(w(7*u.pix, 2*u.pix), (np.nan, np.nan)) else: with pytest.raises(NotImplementedError) as err: w.attach_compound_bounding_box(cbb, [('x1',)])
def test_get_bounding_box(): model = models.Const2D(2) # No with_bbox assert model.get_bounding_box(False) is None # No bounding_box with pytest.raises(NotImplementedError): model.bounding_box assert model.get_bounding_box(True) is None # Normal bounding_box model.bounding_box = ((0, 1), (0, 1)) assert not isinstance(model.bounding_box, CompoundBoundingBox) assert model.get_bounding_box(True) == ((0, 1), (0, 1)) # CompoundBoundingBox with no removal bbox = CompoundBoundingBox.validate(model, {(1,): ((-1, 0), (-1, 0)), (2,): ((0, 1), (0, 1))}, selector_args=[('y', False)]) model.bounding_box = bbox assert isinstance(model.bounding_box, CompoundBoundingBox) # Get using argument not with_bbox assert model.get_bounding_box(True) == bbox # Get using with_bbox not argument assert model.get_bounding_box((1,)) == ((-1, 0), (-1, 0)) assert model.get_bounding_box((2,)) == ((0, 1), (0, 1))
def test_compound_model_copy_with_compound_bounding_box(): model = models.Shift(1) & models.Shift(2) & models.Identity(1) model.inputs = ('x', 'y', 'slit_id') bbox = {(0,): ((-0.5, 1047.5), (-0.5, 2047.5)), (1,): ((-0.5, 3047.5), (-0.5, 4047.5)), } cbbox = CompoundBoundingBox.validate(model, bbox, selector_args=[('slit_id', True)], order='F') # No cbbox model_copy = model.copy() assert id(model_copy) != id(model) assert model_copy.get_bounding_box() == model.get_bounding_box() == None # with cbbox model.bounding_box = cbbox model_copy = model.copy() assert id(model_copy) != id(model) assert id(model_copy.bounding_box) != id(model.bounding_box) assert model_copy.bounding_box.selector_args == model.bounding_box.selector_args assert id(model_copy.bounding_box.selector_args) != id(model.bounding_box.selector_args) for selector, bbox in model.bounding_box.bounding_boxes.items(): for index, interval in bbox.intervals.items(): interval_copy = model_copy.bounding_box.bounding_boxes[selector].intervals[index] assert interval == interval_copy assert id(interval) != interval_copy # add model to compound model model1 = model | models.Identity(3) model_copy = model1.copy() assert id(model_copy) != id(model1) assert model_copy.get_bounding_box() == model1.get_bounding_box() == None
def _from_tree_base_transform_members(cls, model, node, ctx): if 'name' in node: model.name = node['name'] if "inputs" in node: model.inputs = tuple(node["inputs"]) if "outputs" in node: model.outputs = tuple(node["outputs"]) if 'bounding_box' in node: model.bounding_box = node['bounding_box'] elif 'selector_args' in node: cbbox_keys = [tuple(key) for key in node['cbbox_keys']] bbox_dict = dict(zip(cbbox_keys, node['cbbox_values'])) selector_args = node['selector_args'] model.bounding_box = CompoundBoundingBox.validate(model, bbox_dict, selector_args) param_and_model_constraints = {} for constraint in ['fixed', 'bounds']: if constraint in node: param_and_model_constraints[constraint] = node[constraint] model._initialize_constraints(param_and_model_constraints) if "input_units_equivalencies" in node: # this still writes eqs. for compound, but operates on each sub model if not isinstance(model, CompoundModel): model.input_units_equivalencies = node['input_units_equivalencies'] yield model if 'inverse' in node: model.inverse = node['inverse']
def niriss_bounding_box(input_model): bbox = {(order, ): _niriss_order_bounding_box(input_model, order) for order in [1, 2, 3]} model = input_model.meta.wcs.forward_transform return CompoundBoundingBox.validate(model, bbox, slice_args=[('spectral_order', True)], order='F')
def test_compound_bounding_box_pass_with_ignored(): model = models.Shift(1) & models.Shift(2) & models.Identity(1) model.inputs = ('x', 'y', 'slit_id') bbox = {(0,): (-0.5, 1047.5), (1,): (-0.5, 2047.5), } cbbox = CompoundBoundingBox.validate(model, bbox, selector_args=[('slit_id', True)], ignored=['y'], order='F') model.bounding_box = cbbox model = models.Shift(1) & models.Shift(2) & models.Identity(1) model.inputs = ('x', 'y', 'slit_id') bind_compound_bounding_box(model, bbox, selector_args=[('slit_id', True)], ignored=['y'], order='F') assert model.bounding_box == cbbox
def _from_tree_base_transform_members(cls, model, node, ctx): if 'name' in node: model.name = node['name'] if "inputs" in node: if model.n_inputs == 1: model.inputs = (node["inputs"], ) else: model.inputs = tuple(node["inputs"]) if "outputs" in node: if model.n_outputs == 1: model.outputs = (node["outputs"], ) else: model.outputs = tuple(node["outputs"]) if 'bounding_box' in node: model.bounding_box = node['bounding_box'] elif 'selector_args' in node: cbbox_keys = [tuple(key) for key in node['cbbox_keys']] bbox_dict = dict(zip(cbbox_keys, node['cbbox_values'])) selector_args = node['selector_args'] model.bounding_box = CompoundBoundingBox.validate( model, bbox_dict, selector_args) param_and_model_constraints = {} for constraint in ['fixed', 'bounds']: if constraint in node: param_and_model_constraints[constraint] = node[constraint] model._initialize_constraints(param_and_model_constraints) yield model if 'inverse' in node: model.inverse = node['inverse']