<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def calc_fwhm_moffat(self, arr1d, medv=None, moffat_fn=None):
 """FWHM calculation on a 1D array by using least square fitting of a Moffat function on the data. arr1d is a 1D array cut in either X or Y direction on the object. """

        if moffat_fn is None:
            moffat_fn = self.moffat

        N = len(arr1d)
        X = np.array(list(range(N)))
        Y = arr1d
        # Fitting works more reliably if we do the following
        # a. subtract sky background
        if medv is None:
            medv = get_median(Y)
        Y = Y - medv
        maxv = Y.max()
        # b. clamp to 0..max (of the sky subtracted field)
        Y = Y.clip(0, maxv)

        # Fit a moffat
        p0 = [0, N - 1, 2, maxv]              # Inital guess
        # Distance to the target function
        errfunc = lambda p, x, y: moffat_fn(x, p) - y  # noqa
        # Least square fit to the gaussian
        with self.lock:
            # NOTE: without this mutex, optimize.leastsq causes a fatal error
            # sometimes--it appears not to be thread safe.
            # The error is:
            # "SystemError: null argument to internal routine"
            # "Fatal Python error: GC object already tracked"
            p1, success = optimize.leastsq(errfunc, p0[:], args=(X, Y))

        if not success:
            raise IQCalcError("FWHM moffat fitting failed")

        mu, width, power, maxv = p1
        width = np.abs(width)
        self.logger.debug("mu=%f width=%f power=%f maxv=%f" % (
            mu, width, power, maxv))

        fwhm = 2.0 * width * np.sqrt(2.0 ** (1.0 / power) - 1.0)

        # some routines choke on numpy values and need "pure" Python floats
        # e.g. when marshalling through a remote procedure interface
        fwhm = float(fwhm)
        mu = float(mu)
        width = float(width)
        power = float(power)
        maxv = float(maxv)

        res = Bunch.Bunch(fwhm=fwhm, mu=mu, width=width, power=power,
                          maxv=maxv, fit_fn=moffat_fn,
                          fit_args=[mu, width, power, maxv])
        return res