Telluric-Fitter icon indicating copy to clipboard operation
Telluric-Fitter copied to clipboard

Speed up TelFit for low resolution spectra

Open kgullikson88 opened this issue 9 years ago • 1 comments

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.

kgullikson88 avatar Jan 22 '16 19:01 kgullikson88

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!

  1. 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)
    
  2. 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)
    
  3. 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): ")
    
  4. Make sure you tell TelFit to fit resolution now: fitter.FitVariable({'resolution': 8000})

Let me know if that works for you!

kgullikson88 avatar Jan 25 '16 16:01 kgullikson88