Repository: karllark/dust_extinction

Issue:
Add reasonable bounds for FM90
Work on MW and SMC has resulted in reasonable default bounds for the FM90 shape model.  Should be added to the definition of this model.  Can always be overridden.

Code snippet with values:
 ```
   fm90_init.C1.bounds = (-2.0, 3.0)
    fm90_init.C2.bounds = (-0.1, 1.0)
    fm90_init.C3.bounds = (0.0, 2.5)
    fm90_init.C4.bounds = (0.0, 1.0)
    fm90_init.xo.bounds = (4.5, 4.9)
    fm90_init.gamma.bounds = (0.6, 1.5)
```

Discussion:

Patch:
diff --git a/dust_extinction/shapes.py b/dust_extinction/shapes.py
index 3ae5b8e..33f3cee 100644
--- a/dust_extinction/shapes.py
+++ b/dust_extinction/shapes.py
@@ -233,12 +233,13 @@ class FM90(Fittable1DModel):
     n_inputs = 1
     n_outputs = 1
 
-    C1 = Parameter(description="linear term: y-intercept", default=0.10)
-    C2 = Parameter(description="linear term: slope", default=0.70)
-    C3 = Parameter(description="bump: amplitude", default=3.23)
-    C4 = Parameter(description="FUV rise: amplitude", default=0.41)
-    xo = Parameter(description="bump: centroid", default=4.60, min=0.0)
-    gamma = Parameter(description="bump: width", default=0.99, min=0.0)
+    # bounds based on Gordon et al. (2024) results
+    C1 = Parameter(description="linear term: y-intercept", default=0.10, bounds=(-10.0, 5.0))
+    C2 = Parameter(description="linear term: slope", default=0.70, bounds=(-0.1, 5.0))
+    C3 = Parameter(description="bump: amplitude", default=3.23, bounds=(-1.0, 6.0))
+    C4 = Parameter(description="FUV rise: amplitude", default=0.41, bounds=(-0.5, 1.5))
+    xo = Parameter(description="bump: centroid", default=4.59, bounds=(4.5, 4.9))
+    gamma = Parameter(description="bump: width", default=0.95, bounds=(0.6, 1.7))
 
     x_range = x_range_FM90
 
@@ -400,12 +401,13 @@ class FM90_B3(Fittable1DModel):
     n_inputs = 1
     n_outputs = 1
 
-    C1 = Parameter(description="linear term: y-intercept", default=0.10)
-    C2 = Parameter(description="linear term: slope", default=0.70)
-    B3 = Parameter(description="bump: amplitude", default=3.23)
-    C4 = Parameter(description="FUV rise: amplitude", default=0.41)
-    xo = Parameter(description="bump: centroid", default=4.60, min=0.0)
-    gamma = Parameter(description="bump: width", default=0.99, min=0.0)
+    # bounds based on Gordon et al. (2024) results
+    C1 = Parameter(description="linear term: y-intercept", default=0.10, bounds=(-10.0, 5.0))
+    C2 = Parameter(description="linear term: slope", default=0.70, bounds=(-0.1, 5.0))
+    B3 = Parameter(description="bump: amplitude", default=3.23, bounds=(-1.0, 6.0))
+    C4 = Parameter(description="FUV rise: amplitude", default=0.41, bounds=(-0.5, 1.5))
+    xo = Parameter(description="bump: centroid", default=4.59, bounds=(4.5, 4.9))
+    gamma = Parameter(description="bump: width", default=0.95, bounds=(0.6, 1.7))
 
     x_range = x_range_FM90
 


Test patch:
diff --git a/dust_extinction/tests/test_fm90.py b/dust_extinction/tests/test_fm90.py
index a7c04b2..30dd842 100644
--- a/dust_extinction/tests/test_fm90.py
+++ b/dust_extinction/tests/test_fm90.py
@@ -16,18 +16,10 @@ def get_elvebv_cor_vals():
     x = x / u.micron
 
     # correct values
-    cor_vals = np.array(
-        [
-            2.9829317,
-            4.1215415,
-            6.4135842,
-            5.6574243,
-            4.7573250,
-            5.4905843,
-            9.2853567,
-            12.462238,
-        ]
-    )
+    # fmt: off
+    cor_vals = np.array([2.995507, 4.187955, 6.70251, 5.723752, 4.757428,
+                         5.490276, 9.285265, 12.462183])
+    # fmt: on
 
     return (x, cor_vals)
 
@@ -93,15 +85,9 @@ def test_FM90_fitting():
         g03_fit.gamma.value,
     ]
 
-    good_vals = np.array(
-        [
-            -0.958016797002,
-            1.0109751831,
-            2.96430606652,
-            0.313137860902,
-            4.59996300532,
-            0.99000982258,
-        ]
-    )
+    # fmt: off
+    good_vals = np.array([-0.941674, 1.013711, 2.725373, 0.301217,
+                          4.589078, 0.948576])
+    # fmt: on
 
-    np.testing.assert_allclose(good_vals, fit_vals)
+    np.testing.assert_allclose(good_vals, fit_vals, rtol=1e-5)