We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
fit.minos_contour parameter handling
While accesing the fit.minos_contour with my Spectral model with parameters(amplitude, reference, alpha and beta which corresponds to strings par_000_amplitude, par_001_alpha, par_002_beta) but with the minos_contour when I am passing the parameters it is taking strings(par_000_amplitude, par_001_reference, par_002_alpha, par_003_beta) which is giivng me the key error of parameter not found.
fit.minos_contour parameter handling
While accesing the fit.minos_contour with my Spectral model with parameters(amplitude, reference, alpha and beta which corresponds to strings par_000_amplitude, par_001_alpha, par_002_beta) but with the minos_contour when I am passing the parameters it is taking strings(par_000_amplitude, par_001_reference, par_002_alpha, par_003_beta) which is giivng me the key error of parameter not found.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gammapy/utils/fitting/iminuit.py`
Content:
```
1 # Licensed under a 3-clause BSD style license - see LICENSE.rst
2 """iminuit fitting functions."""
3 import logging
4 import numpy as np
5 from .likelihood import Likelihood
6 
7 __all__ = ["optimize_iminuit", "covariance_iminuit", "confidence_iminuit", "mncontour"]
8 
9 log = logging.getLogger(__name__)
10 
11 
12 class MinuitLikelihood(Likelihood):
13     """Likelihood function interface for iminuit."""
14 
15     def fcn(self, *factors):
16         self.parameters.set_parameter_factors(factors)
17         return self.function()
18 
19 
20 def optimize_iminuit(parameters, function, **kwargs):
21     """iminuit optimization
22 
23     Parameters
24     ----------
25     parameters : `~gammapy.utils.modeling.Parameters`
26         Parameters with starting values
27     function : callable
28         Likelihood function
29     **kwargs : dict
30         Options passed to `iminuit.Minuit` constructor. If there is an entry 'migrad_opts', those options
31         will be passed to `iminuit.Minuit.migrad()`.
32 
33     Returns
34     -------
35     result : (factors, info, optimizer)
36         Tuple containing the best fit factors, some info and the optimizer instance.
37     """
38     from iminuit import Minuit
39 
40     # In Gammapy, we have the factor 2 in the likelihood function
41     # This means `errordef=1` in the Minuit interface is correct
42     kwargs.setdefault("errordef", 1)
43     kwargs.setdefault("print_level", 0)
44     kwargs.update(make_minuit_par_kwargs(parameters))
45 
46     minuit_func = MinuitLikelihood(function, parameters)
47 
48     kwargs = kwargs.copy()
49     migrad_opts = kwargs.pop("migrad_opts", {})
50     minuit = Minuit(minuit_func.fcn, **kwargs)
51     minuit.migrad(**migrad_opts)
52 
53     factors = minuit.args
54     info = {
55         "success": minuit.migrad_ok(),
56         "nfev": minuit.get_num_call_fcn(),
57         "message": _get_message(minuit),
58     }
59     optimizer = minuit
60 
61     return factors, info, optimizer
62 
63 
64 def covariance_iminuit(minuit):
65     # TODO: add minuit.hesse() call once we have better tests
66 
67     message, success = "Hesse terminated successfully.", True
68     try:
69         covariance_factors = minuit.np_covariance()
70     except (TypeError, RuntimeError):
71         N = len(minuit.args)
72         covariance_factors = np.nan * np.ones((N, N))
73         message, success = "Hesse failed", False
74     return covariance_factors, {"success": success, "message": message}
75 
76 
77 def confidence_iminuit(minuit, parameters, parameter, sigma, maxcall=0):
78     # TODO: this is ugly - design something better for translating to MINUIT parameter names.
79     # Maybe a wrapper class MinuitParameters?
80     parameter = parameters[parameter]
81     idx = parameters.free_parameters.index(parameter)
82     var = _make_parname(idx, parameter)
83 
84     message, success = "Minos terminated successfully.", True
85     try:
86         result = minuit.minos(var=var, sigma=sigma, maxcall=maxcall)
87         info = result[var]
88     except RuntimeError as error:
89         message, success = str(error), False
90         info = {"is_valid": False, "lower": np.nan, "upper": np.nan, "nfcn": 0}
91 
92     return {
93         "success": success,
94         "message": message,
95         "errp": info["upper"],
96         "errn": -info["lower"],
97         "nfev": info["nfcn"],
98     }
99 
100 
101 def mncontour(minuit, parameters, x, y, numpoints, sigma):
102     idx = parameters._get_idx(x)
103     x = _make_parname(idx, parameters[idx])
104 
105     idx = parameters._get_idx(y)
106     y = _make_parname(idx, parameters[idx])
107 
108     x_info, y_info, contour = minuit.mncontour(x, y, numpoints, sigma)
109     contour = np.array(contour)
110 
111     success = x_info["is_valid"] and y_info["is_valid"]
112 
113     return {
114         "success": success,
115         "x": contour[:, 0],
116         "y": contour[:, 1],
117         "x_info": x_info,
118         "y_info": y_info,
119     }
120 
121 
122 # this code is copied from https://github.com/iminuit/iminuit/blob/master/iminuit/_minimize.py#L95
123 def _get_message(m):
124     message = "Optimization terminated successfully."
125     success = m.migrad_ok()
126     if not success:
127         message = "Optimization failed."
128         fmin = m.get_fmin()
129         if fmin.has_reached_call_limit:
130             message += " Call limit was reached."
131         if fmin.is_above_max_edm:
132             message += " Estimated distance to minimum too large."
133     return message
134 
135 
136 def _make_parnames(parameters):
137     return [_make_parname(idx, par) for idx, par in enumerate(parameters)]
138 
139 
140 def _make_parname(idx, par):
141     return "par_{:03d}_{}".format(idx, par.name)
142 
143 
144 def make_minuit_par_kwargs(parameters):
145     """Create *Parameter Keyword Arguments* for the `Minuit` constructor.
146 
147     See: http://iminuit.readthedocs.io/en/latest/api.html#iminuit.Minuit
148     """
149     names = _make_parnames(parameters.free_parameters)
150     kwargs = {"forced_parameters": names}
151 
152     for name, par in zip(names, parameters.free_parameters):
153         kwargs[name] = par.factor
154 
155         min_ = None if np.isnan(par.factor_min) else par.factor_min
156         max_ = None if np.isnan(par.factor_max) else par.factor_max
157         kwargs["limit_{}".format(name)] = (min_, max_)
158 
159         if parameters.covariance is not None:
160             error = parameters.error(par) / par.scale
161         elif parameters.apply_autoscale:
162             error = 1
163         else:
164             error = 1
165             log.warning(
166                 "Neither covariance matrix set nor auto-scaling of parameters activated."
167                 "Assuming stepsize of 1, which could lead to convergence problems of the "
168                 "Minuit optimizer."
169             )
170 
171         kwargs["error_{}".format(name)] = error
172 
173     return kwargs
174
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gammapy/utils/fitting/iminuit.py b/gammapy/utils/fitting/iminuit.py
--- a/gammapy/utils/fitting/iminuit.py
+++ b/gammapy/utils/fitting/iminuit.py
@@ -99,11 +99,13 @@
 
 
 def mncontour(minuit, parameters, x, y, numpoints, sigma):
-    idx = parameters._get_idx(x)
-    x = _make_parname(idx, parameters[idx])
+    par_x = parameters[x]
+    idx_x = parameters.free_parameters.index(par_x)
+    x = _make_parname(idx_x, par_x)
 
-    idx = parameters._get_idx(y)
-    y = _make_parname(idx, parameters[idx])
+    par_y = parameters[y]
+    idx_y = parameters.free_parameters.index(par_y)
+    y = _make_parname(idx_y, par_y)
 
     x_info, y_info, contour = minuit.mncontour(x, y, numpoints, sigma)
     contour = np.array(contour)

{"golden_diff": "diff --git a/gammapy/utils/fitting/iminuit.py b/gammapy/utils/fitting/iminuit.py\n--- a/gammapy/utils/fitting/iminuit.py\n+++ b/gammapy/utils/fitting/iminuit.py\n@@ -99,11 +99,13 @@\n \n \n def mncontour(minuit, parameters, x, y, numpoints, sigma):\n-    idx = parameters._get_idx(x)\n-    x = _make_parname(idx, parameters[idx])\n+    par_x = parameters[x]\n+    idx_x = parameters.free_parameters.index(par_x)\n+    x = _make_parname(idx_x, par_x)\n \n-    idx = parameters._get_idx(y)\n-    y = _make_parname(idx, parameters[idx])\n+    par_y = parameters[y]\n+    idx_y = parameters.free_parameters.index(par_y)\n+    y = _make_parname(idx_y, par_y)\n \n     x_info, y_info, contour = minuit.mncontour(x, y, numpoints, sigma)\n     contour = np.array(contour)\n", "issue": "fit.minos_contour parameter handling\nWhile accesing the fit.minos_contour with my Spectral model with parameters(amplitude, reference, alpha and beta which corresponds to strings par_000_amplitude, par_001_alpha, par_002_beta) but with the minos_contour when I am passing the parameters it is taking strings(par_000_amplitude, par_001_reference, par_002_alpha, par_003_beta) which is giivng me the key error of parameter not found.\nfit.minos_contour parameter handling\nWhile accesing the fit.minos_contour with my Spectral model with parameters(amplitude, reference, alpha and beta which corresponds to strings par_000_amplitude, par_001_alpha, par_002_beta) but with the minos_contour when I am passing the parameters it is taking strings(par_000_amplitude, par_001_reference, par_002_alpha, par_003_beta) which is giivng me the key error of parameter not found.\n", "before_files": [{"content": "# Licensed under a 3-clause BSD style license - see LICENSE.rst\n\"\"\"iminuit fitting functions.\"\"\"\nimport logging\nimport numpy as np\nfrom .likelihood import Likelihood\n\n__all__ = [\"optimize_iminuit\", \"covariance_iminuit\", \"confidence_iminuit\", \"mncontour\"]\n\nlog = logging.getLogger(__name__)\n\n\nclass MinuitLikelihood(Likelihood):\n    \"\"\"Likelihood function interface for iminuit.\"\"\"\n\n    def fcn(self, *factors):\n        self.parameters.set_parameter_factors(factors)\n        return self.function()\n\n\ndef optimize_iminuit(parameters, function, **kwargs):\n    \"\"\"iminuit optimization\n\n    Parameters\n    ----------\n    parameters : `~gammapy.utils.modeling.Parameters`\n        Parameters with starting values\n    function : callable\n        Likelihood function\n    **kwargs : dict\n        Options passed to `iminuit.Minuit` constructor. If there is an entry 'migrad_opts', those options\n        will be passed to `iminuit.Minuit.migrad()`.\n\n    Returns\n    -------\n    result : (factors, info, optimizer)\n        Tuple containing the best fit factors, some info and the optimizer instance.\n    \"\"\"\n    from iminuit import Minuit\n\n    # In Gammapy, we have the factor 2 in the likelihood function\n    # This means `errordef=1` in the Minuit interface is correct\n    kwargs.setdefault(\"errordef\", 1)\n    kwargs.setdefault(\"print_level\", 0)\n    kwargs.update(make_minuit_par_kwargs(parameters))\n\n    minuit_func = MinuitLikelihood(function, parameters)\n\n    kwargs = kwargs.copy()\n    migrad_opts = kwargs.pop(\"migrad_opts\", {})\n    minuit = Minuit(minuit_func.fcn, **kwargs)\n    minuit.migrad(**migrad_opts)\n\n    factors = minuit.args\n    info = {\n        \"success\": minuit.migrad_ok(),\n        \"nfev\": minuit.get_num_call_fcn(),\n        \"message\": _get_message(minuit),\n    }\n    optimizer = minuit\n\n    return factors, info, optimizer\n\n\ndef covariance_iminuit(minuit):\n    # TODO: add minuit.hesse() call once we have better tests\n\n    message, success = \"Hesse terminated successfully.\", True\n    try:\n        covariance_factors = minuit.np_covariance()\n    except (TypeError, RuntimeError):\n        N = len(minuit.args)\n        covariance_factors = np.nan * np.ones((N, N))\n        message, success = \"Hesse failed\", False\n    return covariance_factors, {\"success\": success, \"message\": message}\n\n\ndef confidence_iminuit(minuit, parameters, parameter, sigma, maxcall=0):\n    # TODO: this is ugly - design something better for translating to MINUIT parameter names.\n    # Maybe a wrapper class MinuitParameters?\n    parameter = parameters[parameter]\n    idx = parameters.free_parameters.index(parameter)\n    var = _make_parname(idx, parameter)\n\n    message, success = \"Minos terminated successfully.\", True\n    try:\n        result = minuit.minos(var=var, sigma=sigma, maxcall=maxcall)\n        info = result[var]\n    except RuntimeError as error:\n        message, success = str(error), False\n        info = {\"is_valid\": False, \"lower\": np.nan, \"upper\": np.nan, \"nfcn\": 0}\n\n    return {\n        \"success\": success,\n        \"message\": message,\n        \"errp\": info[\"upper\"],\n        \"errn\": -info[\"lower\"],\n        \"nfev\": info[\"nfcn\"],\n    }\n\n\ndef mncontour(minuit, parameters, x, y, numpoints, sigma):\n    idx = parameters._get_idx(x)\n    x = _make_parname(idx, parameters[idx])\n\n    idx = parameters._get_idx(y)\n    y = _make_parname(idx, parameters[idx])\n\n    x_info, y_info, contour = minuit.mncontour(x, y, numpoints, sigma)\n    contour = np.array(contour)\n\n    success = x_info[\"is_valid\"] and y_info[\"is_valid\"]\n\n    return {\n        \"success\": success,\n        \"x\": contour[:, 0],\n        \"y\": contour[:, 1],\n        \"x_info\": x_info,\n        \"y_info\": y_info,\n    }\n\n\n# this code is copied from https://github.com/iminuit/iminuit/blob/master/iminuit/_minimize.py#L95\ndef _get_message(m):\n    message = \"Optimization terminated successfully.\"\n    success = m.migrad_ok()\n    if not success:\n        message = \"Optimization failed.\"\n        fmin = m.get_fmin()\n        if fmin.has_reached_call_limit:\n            message += \" Call limit was reached.\"\n        if fmin.is_above_max_edm:\n            message += \" Estimated distance to minimum too large.\"\n    return message\n\n\ndef _make_parnames(parameters):\n    return [_make_parname(idx, par) for idx, par in enumerate(parameters)]\n\n\ndef _make_parname(idx, par):\n    return \"par_{:03d}_{}\".format(idx, par.name)\n\n\ndef make_minuit_par_kwargs(parameters):\n    \"\"\"Create *Parameter Keyword Arguments* for the `Minuit` constructor.\n\n    See: http://iminuit.readthedocs.io/en/latest/api.html#iminuit.Minuit\n    \"\"\"\n    names = _make_parnames(parameters.free_parameters)\n    kwargs = {\"forced_parameters\": names}\n\n    for name, par in zip(names, parameters.free_parameters):\n        kwargs[name] = par.factor\n\n        min_ = None if np.isnan(par.factor_min) else par.factor_min\n        max_ = None if np.isnan(par.factor_max) else par.factor_max\n        kwargs[\"limit_{}\".format(name)] = (min_, max_)\n\n        if parameters.covariance is not None:\n            error = parameters.error(par) / par.scale\n        elif parameters.apply_autoscale:\n            error = 1\n        else:\n            error = 1\n            log.warning(\n                \"Neither covariance matrix set nor auto-scaling of parameters activated.\"\n                \"Assuming stepsize of 1, which could lead to convergence problems of the \"\n                \"Minuit optimizer.\"\n            )\n\n        kwargs[\"error_{}\".format(name)] = error\n\n    return kwargs\n", "path": "gammapy/utils/fitting/iminuit.py"}], "after_files": [{"content": "# Licensed under a 3-clause BSD style license - see LICENSE.rst\n\"\"\"iminuit fitting functions.\"\"\"\nimport logging\nimport numpy as np\nfrom .likelihood import Likelihood\n\n__all__ = [\"optimize_iminuit\", \"covariance_iminuit\", \"confidence_iminuit\", \"mncontour\"]\n\nlog = logging.getLogger(__name__)\n\n\nclass MinuitLikelihood(Likelihood):\n    \"\"\"Likelihood function interface for iminuit.\"\"\"\n\n    def fcn(self, *factors):\n        self.parameters.set_parameter_factors(factors)\n        return self.function()\n\n\ndef optimize_iminuit(parameters, function, **kwargs):\n    \"\"\"iminuit optimization\n\n    Parameters\n    ----------\n    parameters : `~gammapy.utils.modeling.Parameters`\n        Parameters with starting values\n    function : callable\n        Likelihood function\n    **kwargs : dict\n        Options passed to `iminuit.Minuit` constructor. If there is an entry 'migrad_opts', those options\n        will be passed to `iminuit.Minuit.migrad()`.\n\n    Returns\n    -------\n    result : (factors, info, optimizer)\n        Tuple containing the best fit factors, some info and the optimizer instance.\n    \"\"\"\n    from iminuit import Minuit\n\n    # In Gammapy, we have the factor 2 in the likelihood function\n    # This means `errordef=1` in the Minuit interface is correct\n    kwargs.setdefault(\"errordef\", 1)\n    kwargs.setdefault(\"print_level\", 0)\n    kwargs.update(make_minuit_par_kwargs(parameters))\n\n    minuit_func = MinuitLikelihood(function, parameters)\n\n    kwargs = kwargs.copy()\n    migrad_opts = kwargs.pop(\"migrad_opts\", {})\n    minuit = Minuit(minuit_func.fcn, **kwargs)\n    minuit.migrad(**migrad_opts)\n\n    factors = minuit.args\n    info = {\n        \"success\": minuit.migrad_ok(),\n        \"nfev\": minuit.get_num_call_fcn(),\n        \"message\": _get_message(minuit),\n    }\n    optimizer = minuit\n\n    return factors, info, optimizer\n\n\ndef covariance_iminuit(minuit):\n    # TODO: add minuit.hesse() call once we have better tests\n\n    message, success = \"Hesse terminated successfully.\", True\n    try:\n        covariance_factors = minuit.np_covariance()\n    except (TypeError, RuntimeError):\n        N = len(minuit.args)\n        covariance_factors = np.nan * np.ones((N, N))\n        message, success = \"Hesse failed\", False\n    return covariance_factors, {\"success\": success, \"message\": message}\n\n\ndef confidence_iminuit(minuit, parameters, parameter, sigma, maxcall=0):\n    # TODO: this is ugly - design something better for translating to MINUIT parameter names.\n    # Maybe a wrapper class MinuitParameters?\n    parameter = parameters[parameter]\n    idx = parameters.free_parameters.index(parameter)\n    var = _make_parname(idx, parameter)\n\n    message, success = \"Minos terminated successfully.\", True\n    try:\n        result = minuit.minos(var=var, sigma=sigma, maxcall=maxcall)\n        info = result[var]\n    except RuntimeError as error:\n        message, success = str(error), False\n        info = {\"is_valid\": False, \"lower\": np.nan, \"upper\": np.nan, \"nfcn\": 0}\n\n    return {\n        \"success\": success,\n        \"message\": message,\n        \"errp\": info[\"upper\"],\n        \"errn\": -info[\"lower\"],\n        \"nfev\": info[\"nfcn\"],\n    }\n\n\ndef mncontour(minuit, parameters, x, y, numpoints, sigma):\n    par_x = parameters[x]\n    idx_x = parameters.free_parameters.index(par_x)\n    x = _make_parname(idx_x, par_x)\n\n    par_y = parameters[y]\n    idx_y = parameters.free_parameters.index(par_y)\n    y = _make_parname(idx_y, par_y)\n\n    x_info, y_info, contour = minuit.mncontour(x, y, numpoints, sigma)\n    contour = np.array(contour)\n\n    success = x_info[\"is_valid\"] and y_info[\"is_valid\"]\n\n    return {\n        \"success\": success,\n        \"x\": contour[:, 0],\n        \"y\": contour[:, 1],\n        \"x_info\": x_info,\n        \"y_info\": y_info,\n    }\n\n\n# this code is copied from https://github.com/iminuit/iminuit/blob/master/iminuit/_minimize.py#L95\ndef _get_message(m):\n    message = \"Optimization terminated successfully.\"\n    success = m.migrad_ok()\n    if not success:\n        message = \"Optimization failed.\"\n        fmin = m.get_fmin()\n        if fmin.has_reached_call_limit:\n            message += \" Call limit was reached.\"\n        if fmin.is_above_max_edm:\n            message += \" Estimated distance to minimum too large.\"\n    return message\n\n\ndef _make_parnames(parameters):\n    return [_make_parname(idx, par) for idx, par in enumerate(parameters)]\n\n\ndef _make_parname(idx, par):\n    return \"par_{:03d}_{}\".format(idx, par.name)\n\n\ndef make_minuit_par_kwargs(parameters):\n    \"\"\"Create *Parameter Keyword Arguments* for the `Minuit` constructor.\n\n    See: http://iminuit.readthedocs.io/en/latest/api.html#iminuit.Minuit\n    \"\"\"\n    names = _make_parnames(parameters.free_parameters)\n    kwargs = {\"forced_parameters\": names}\n\n    for name, par in zip(names, parameters.free_parameters):\n        kwargs[name] = par.factor\n\n        min_ = None if np.isnan(par.factor_min) else par.factor_min\n        max_ = None if np.isnan(par.factor_max) else par.factor_max\n        kwargs[\"limit_{}\".format(name)] = (min_, max_)\n\n        if parameters.covariance is not None:\n            error = parameters.error(par) / par.scale\n        elif parameters.apply_autoscale:\n            error = 1\n        else:\n            error = 1\n            log.warning(\n                \"Neither covariance matrix set nor auto-scaling of parameters activated.\"\n                \"Assuming stepsize of 1, which could lead to convergence problems of the \"\n                \"Minuit optimizer.\"\n            )\n\n        kwargs[\"error_{}\".format(name)] = error\n\n    return kwargs\n", "path": "gammapy/utils/fitting/iminuit.py"}]}