Telluric-Fitter
Telluric-Fitter copied to clipboard
Speed up TelFit for low resolution spectra
I am starting this issue in response to an email I received about telfit taking over an hour to fit a R~8000 optical spectrum after applying the changes suggested in the FAQ. It turns out that most of the time is spent in FittingUtilities.ReduceResolution2
.
The reason it is slow is because part of the likelihood evaluation for the abundances involves finding a best-fit resolution. TelFit does it this way because it keeps things a bit more stable (there is a large degeneracy between resolution and every abundance parameter). The problem is that it then degrades the spectrum about ~20 times to find the best resolution for the current trial abundance. The easiest way to speed up the fit would be to make the resolution fit happen as part of the abundance fit instead of inside it. When only fitting one or two abundances at a time, it should be safe; that said, watch out for bad fits.
Here is a way to update the code to do this. I have not tested this at all, so there might be other things that need doing!
-
Remove the code near lines 700 (shown below). This code is setting up for doing an initial guess resolution; we are going to make resolution be a fitted parameter and so this is the only time the spectrum gets degraded in resolution.
if (resolution - 10 < self.resolution_bounds[0] or resolution + 10 > self.resolution_bounds[1]): resolution = np.mean(self.resolution_bounds)
-
Make sure the code immediately below this uses the
ReduceResolution2
function. That was part of setting the code up for fitting low resolution spectra, but I added this step for completeness.model = FittingUtilities.ReduceResolution2(model, resolution)
-
Now, we need to remove the code that has it do a resolution fit within the likelihood evaluation. That is near line 780 and looks like this:
#Fit instrumental resolution done = False while not done: done = True if 'gauss' in self.resolution_fit_mode.lower() or min(model.y) > 0.95: model, resolution = self.FitResolution(data.copy(), model_original.copy(), resolution) elif "svd" in self.resolution_fit_mode.lower(): model, self.broadstuff = self.Broaden2(data.copy(), model_original.copy(), full_output=True) else: done = False print("Resolution fit mode set to an invalid value: %s" % self.resolution_fit_mode) self.resolution_fit_mode = raw_input("Enter a valid mode (SVD or guass): ")
-
Make sure you tell TelFit to fit resolution now:
fitter.FitVariable({'resolution': 8000})
Let me know if that works for you!