// image: image to calibrate in wavelength direction
// id:    identified lines (from luciidentify)
// pars:  [1]: height of region around gauss to fit
//        [2]: half width of region around gauss to fit (to the left and right)
//        [3]: offset for gauss fit running in y-direction from bottom to top
//        [4]: order of polynomial to fit to lines (y-direction)
//        [5]: order of polynomial to fit to spectrum (x-direction)
//        [6]: sigma-factor for rejection
function lucicalx, image, id, pars {
    gaussheight = int(pars[1])
    gausshalfwidth = int(pars[2])
    gaussincrement = int(pars[3])
    polyordery = int(pars[4])
    polyorderx = int(pars[5])
    sigmarej = pars[6]

    imagewidth = naxis1(image)
    imageheight = naxis2(image)

    midgausspos = id[1,*]
    nrfoundgauss = naxis1(midgausspos)
    
    /* loop over found lines and estimate gauss-centers along y-axis
    the gauss_window is shifted as we move, we start from the center to the top,
    then from the center to the bottom */
    gausspos = fits(nrfoundgauss, imageheight)
    xgauss = [1:2*gausshalfwidth+1]
    yline = [1:imageheight]
    line = xgauss
    g = 1
    for g = 1, nrfoundgauss {
        // initial bounds for the gauss window
        left = midgausspos[g]-gausshalfwidth
        right = midgausspos[g]+gausshalfwidth
        
        //
        // move from the middle to the top
        //
        y = int(imageheight/2)-gaussincrement
        j = int(imageheight/2)
        tmpleft = left
        tmpright = right
        while (y <= imageheight-gaussheight) {
            // extract sub-longslit around gauss, median several lines for better S/N ratio
            i = 1
            for x = tmpleft, tmpright {
                line[i] = median(image[x, y:y+gaussheight])
                i++
            }

            // fit gauss to sub-longslit        
            maxpos = where(line==max(line))[1]
            estimate = [median(line), max(line)-median(line), maxpos, gausshalfwidth]  //offset, intensity, center, fwhm
            errors = xgauss * 0 + 1
            fit = gaussfit(xgauss, line, errors, estimate)
            gausspos[g, j] = tmpleft+fit[3]-1
// check if jump in fit[3] is too large (jumped to next line...)
            // check for curvature of gauss-line and move gauss_window accordingly
            halfdelta = (tmpright-tmpleft)/2+1
            if (maxpos != halfdelta) {
                tmpleft += maxpos-halfdelta
                tmpright += maxpos-halfdelta
            }

            yline[j] = y
            y += gaussincrement
            j++
        }
        jhigh = j-1

        //
        // move from the middle to the bottom
        //
        y = int(imageheight/2)-gaussincrement-gaussheight
        j = int(imageheight/2)-1
        tmpleft = left
        tmpright = right

        while (y > 0) {
            // extract sub-longslit around gauss, median several lines for better S/N ratio
            i = 1
            for x = tmpleft, tmpright {
                line[i] = median(image[x, y:y+gaussheight])
                i++
            }

            // fit gauss to sub-longslit
            maxpos = where(line==max(line))[1]
            estimate = [median(line), max(line)-median(line), maxpos, gausshalfwidth]  //offset, intensity, center, fwhm
            errors = xgauss * 0 + 1
            fit = gaussfit(xgauss, line, errors, estimate)
            gausspos[g, j] = tmpleft+fit[3]-1
            
            // check for curvature of gauss-line and move gauss_window accordingly
            halfdelta = (tmpright-tmpleft)/2+1
            if (maxpos != halfdelta) {
                tmpleft += maxpos-halfdelta
                tmpright += maxpos-halfdelta
            }

            yline[j] = y
            y -= gaussincrement
            j--
        }
        jlow = j+1
    } // end loop found lines

    // crop gausspos & yline
    gausspos = gausspos[*,jlow:jhigh]
    yline = yline[jlow:jhigh]

    /* now fit polynomials in y-direction to gauss centers */
    print "   Fitting polynomial (takes a while...)"
    
    xline=[1:imageheight]
    polyfitparsmatrix = fits(nrfoundgauss, polyordery+1)
    chisq = 1
    chi =[1:nrfoundgauss]
    for g = 1, nrfoundgauss {
        ggg = gausspos[g,*]
        yyy = yline
        polyfitpars = polyfitxy(yyy, ggg, polyordery, chisq)

        // rejection
        ff = ggg - poly(yline, polyfitpars[*,1])
        ggg[where(abs(ff) > sigmarej*meddev(ff))] = 1/0
        polyfitpars = polyfitxy(yyy, ggg, polyordery, chisq)
        polyfitparsmatrix[g,*] = polyfitpars[*,1]
        chi[g]=chisq
    }

    /* create calibration frame */
    lucicalx = fits(imagewidth, imageheight)
    xline = [1:imagewidth]
    ygauss = [1:nrfoundgauss]
    for y = 1, imageheight {
        for g = 1,nrfoundgauss {
            ygauss[g] = poly(y, polyfitparsmatrix[g,*])
        }
        cal = polyfitxy(ygauss, id[2,*], polyorderx)
        xcal = poly(xline, cal[*,1])
        lucicalx[*,y] = xcal
    }

    copyheader lucicalx, id

    print "FINISHED CALIBRATING IN X"
}
