def fit_spectrum(spectrum, lineshapes, params, amps, bounds, ampbounds,
                 centers, rIDs, box_width, error_flag, verb=True, **kw):
    pbest = [[]] * len(params)
    pbest_err = [[]] * len(params)
    abest = [[]] * len(params)
    abest_err = [[]] * len(params)
    iers = [[]] * len(params)
    shape = spectrum.shape

    ls_classes = []
    for l in lineshapes:
        if isinstance(l, str):
            ls_classes.append(ls_str2class(l))
        else:
            ls_classes.append(l)

    cIDs = set(rIDs)    # region values to loop over

    for cID in cIDs:
        cpeaks = [i for i, v in enumerate(rIDs) if v == cID]

        # select the parameter
        cparams = [params[i] for i in cpeaks]
        camps = [amps[i] for i in cpeaks]
        cbounds = [bounds[i] for i in cpeaks]
        campbounds = [ampbounds[i] for i in cpeaks]
        ccenters = [centers[i] for i in cpeaks]

        # find the box edges
        bcenters = np.round(np.array(ccenters).astype('int'))
        bmin = bcenters - box_width
        bmax = bcenters + box_width + 1

        # correct for spectrum edges
        for i in range(len(shape)):
            bmin[:, i][np.where(bmin[:, i] < 0)] = 0
        for i, v in enumerate(shape):
            bmax[:, i][np.where(bmax[:, i] > v)] = v

        # find the region limits
        rmin = edge = np.array(bmin).min(0)
        rmax = np.array(bmax).max(0)

        # cut the spectrum
        s = tuple([slice(mn, mx) for mn, mx in zip(rmin, rmax)])
        region = spectrum[s]

        # add edge to the box limits
        ebmin = bmin - edge
        ebmax = bmax - edge

        # create the weight mask array
        wmask = np.zeros(region.shape, dtype='bool')
        for bmn, bmx in zip(ebmin, ebmax):
            s = tuple([slice(mn, mx) for mn, mx in zip(bmn, bmx)])
            wmask[s] = True

        # add edges to the initial parameters
        ecparams = [[ls.add_edge(p, (mn, mx)) for ls, mn, mx, p in
                    zip(ls_classes, rmin, rmax, g)] for g in cparams]

        # TODO make this better...
        ecbounds = [[zip(*[ls.add_edge(b, (mn, mx)) for b in zip(*db)])
                    for ls, mn, mx, db in zip(ls_classes, rmin, rmax, pb)]
                    for pb in cbounds]

        # fit the region
        t = fit_NDregion(region, ls_classes, ecparams, camps, ecbounds,
                         campbounds, wmask, error_flag, **kw)
        if error_flag:
            ecpbest, acbest, ecpbest_err, acbest_err, ier = t
            cpbest_err = [[ls.remove_edge(p, (mn, mx)) for ls, mn, mx, p in
                          zip(ls_classes, rmin, rmax, g)] for g in ecpbest_err]
        else:
            ecpbest, acbest, ier = t

        # remove edges from best fit parameters
        cpbest = [[ls.remove_edge(p, (mn, mx)) for ls, mn, mx, p in
                   zip(ls_classes, rmin, rmax, g)] for g in ecpbest]

        if verb:
            print("-----------------------")
            print("cID:", cID, "ier:", ier, "Peaks fit", cpeaks)
            print("fit parameters:", cpbest)
            print("fit amplitudes", acbest)

        for i, pb, ab in zip(cpeaks, cpbest, acbest):
            pbest[i] = pb
            abest[i] = ab
            iers[i] = ier

        if error_flag:
            for i, pb, ab in zip(cpeaks, cpbest_err, acbest_err):
                pbest_err[i] = pb
                abest_err[i] = ab

    if error_flag is False:
        return pbest, abest, iers

    return pbest, abest, pbest_err, abest_err, iers
Watchdog timer function. 
dataset/ETHPy150Open jjhelmus/nmrglue/nmrglue/analysis/linesh.py/fit_spectrum--crossover with--dataset/ETHPy150Open calston/tensor/tensor/service.py/TensorService.sourceWatchdog